xref: /illumos-gate/usr/src/uts/common/fs/proc/prvnops.c (revision cd277642e0bdc71a7f57c550df1279b0c091d6e2)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Copyright 2016 Joyent, Inc.
25  */
26 
27 /*	Copyright (c) 1984,	 1986, 1987, 1988, 1989 AT&T	*/
28 /*	  All Rights Reserved  	*/
29 
30 #include <sys/types.h>
31 #include <sys/param.h>
32 #include <sys/time.h>
33 #include <sys/cred.h>
34 #include <sys/policy.h>
35 #include <sys/debug.h>
36 #include <sys/dirent.h>
37 #include <sys/errno.h>
38 #include <sys/file.h>
39 #include <sys/inline.h>
40 #include <sys/kmem.h>
41 #include <sys/pathname.h>
42 #include <sys/proc.h>
43 #include <sys/brand.h>
44 #include <sys/signal.h>
45 #include <sys/stat.h>
46 #include <sys/sysmacros.h>
47 #include <sys/systm.h>
48 #include <sys/zone.h>
49 #include <sys/uio.h>
50 #include <sys/var.h>
51 #include <sys/mode.h>
52 #include <sys/poll.h>
53 #include <sys/user.h>
54 #include <sys/vfs.h>
55 #include <sys/vfs_opreg.h>
56 #include <sys/gfs.h>
57 #include <sys/vnode.h>
58 #include <sys/fault.h>
59 #include <sys/syscall.h>
60 #include <sys/procfs.h>
61 #include <sys/atomic.h>
62 #include <sys/cmn_err.h>
63 #include <sys/contract_impl.h>
64 #include <sys/ctfs.h>
65 #include <sys/avl.h>
66 #include <fs/fs_subr.h>
67 #include <vm/rm.h>
68 #include <vm/as.h>
69 #include <vm/seg.h>
70 #include <vm/seg_vn.h>
71 #include <vm/hat.h>
72 #include <fs/proc/prdata.h>
73 #if defined(__sparc)
74 #include <sys/regset.h>
75 #endif
76 #if defined(__x86)
77 #include <sys/sysi86.h>
78 #endif
79 
80 /*
81  * Created by prinit.
82  */
83 vnodeops_t *prvnodeops;
84 
85 /*
86  * Directory characteristics (patterned after the s5 file system).
87  */
88 #define	PRROOTINO	2
89 
90 #define	PRDIRSIZE	14
91 struct prdirect {
92 	ushort_t	d_ino;
93 	char		d_name[PRDIRSIZE];
94 };
95 
96 #define	PRSDSIZE	(sizeof (struct prdirect))
97 
98 /*
99  * Directory characteristics.
100  */
101 typedef struct prdirent {
102 	ino64_t		d_ino;		/* "inode number" of entry */
103 	off64_t		d_off;		/* offset of disk directory entry */
104 	unsigned short	d_reclen;	/* length of this record */
105 	char		d_name[14];	/* name of file */
106 } prdirent_t;
107 
108 /*
109  * Contents of a /proc/<pid> directory.
110  * Reuse d_ino field for the /proc file type.
111  */
112 static prdirent_t piddir[] = {
113 	{ PR_PIDDIR,	 1 * sizeof (prdirent_t), sizeof (prdirent_t),
114 		"." },
115 	{ PR_PROCDIR,	 2 * sizeof (prdirent_t), sizeof (prdirent_t),
116 		".." },
117 	{ PR_AS,	 3 * sizeof (prdirent_t), sizeof (prdirent_t),
118 		"as" },
119 	{ PR_CTL,	 4 * sizeof (prdirent_t), sizeof (prdirent_t),
120 		"ctl" },
121 	{ PR_STATUS,	 5 * sizeof (prdirent_t), sizeof (prdirent_t),
122 		"status" },
123 	{ PR_LSTATUS,	 6 * sizeof (prdirent_t), sizeof (prdirent_t),
124 		"lstatus" },
125 	{ PR_PSINFO,	 7 * sizeof (prdirent_t), sizeof (prdirent_t),
126 		"psinfo" },
127 	{ PR_LPSINFO,	 8 * sizeof (prdirent_t), sizeof (prdirent_t),
128 		"lpsinfo" },
129 	{ PR_MAP,	 9 * sizeof (prdirent_t), sizeof (prdirent_t),
130 		"map" },
131 	{ PR_RMAP,	10 * sizeof (prdirent_t), sizeof (prdirent_t),
132 		"rmap" },
133 	{ PR_XMAP,	11 * sizeof (prdirent_t), sizeof (prdirent_t),
134 		"xmap" },
135 	{ PR_CRED,	12 * sizeof (prdirent_t), sizeof (prdirent_t),
136 		"cred" },
137 	{ PR_SIGACT,	13 * sizeof (prdirent_t), sizeof (prdirent_t),
138 		"sigact" },
139 	{ PR_AUXV,	14 * sizeof (prdirent_t), sizeof (prdirent_t),
140 		"auxv" },
141 	{ PR_USAGE,	15 * sizeof (prdirent_t), sizeof (prdirent_t),
142 		"usage" },
143 	{ PR_LUSAGE,	16 * sizeof (prdirent_t), sizeof (prdirent_t),
144 		"lusage" },
145 	{ PR_PAGEDATA,	17 * sizeof (prdirent_t), sizeof (prdirent_t),
146 		"pagedata" },
147 	{ PR_WATCH,	18 * sizeof (prdirent_t), sizeof (prdirent_t),
148 		"watch" },
149 	{ PR_CURDIR,	19 * sizeof (prdirent_t), sizeof (prdirent_t),
150 		"cwd" },
151 	{ PR_ROOTDIR,	20 * sizeof (prdirent_t), sizeof (prdirent_t),
152 		"root" },
153 	{ PR_FDDIR,	21 * sizeof (prdirent_t), sizeof (prdirent_t),
154 		"fd" },
155 	{ PR_OBJECTDIR,	22 * sizeof (prdirent_t), sizeof (prdirent_t),
156 		"object" },
157 	{ PR_LWPDIR,	23 * sizeof (prdirent_t), sizeof (prdirent_t),
158 		"lwp" },
159 	{ PR_PRIV,	24 * sizeof (prdirent_t), sizeof (prdirent_t),
160 		"priv" },
161 	{ PR_PATHDIR,	25 * sizeof (prdirent_t), sizeof (prdirent_t),
162 		"path" },
163 	{ PR_CTDIR,	26 * sizeof (prdirent_t), sizeof (prdirent_t),
164 		"contracts" },
165 	{ PR_SECFLAGS,	27 * sizeof (prdirent_t), sizeof (prdirent_t),
166 		"secflags" },
167 #if defined(__x86)
168 	{ PR_LDT,	28 * sizeof (prdirent_t), sizeof (prdirent_t),
169 		"ldt" },
170 #endif
171 };
172 
173 #define	NPIDDIRFILES	(sizeof (piddir) / sizeof (piddir[0]) - 2)
174 
175 /*
176  * Contents of a /proc/<pid>/lwp/<lwpid> directory.
177  */
178 static prdirent_t lwpiddir[] = {
179 	{ PR_LWPIDDIR,	 1 * sizeof (prdirent_t), sizeof (prdirent_t),
180 		"." },
181 	{ PR_LWPDIR,	 2 * sizeof (prdirent_t), sizeof (prdirent_t),
182 		".." },
183 	{ PR_LWPCTL,	 3 * sizeof (prdirent_t), sizeof (prdirent_t),
184 		"lwpctl" },
185 	{ PR_LWPSTATUS,	 4 * sizeof (prdirent_t), sizeof (prdirent_t),
186 		"lwpstatus" },
187 	{ PR_LWPSINFO,	 5 * sizeof (prdirent_t), sizeof (prdirent_t),
188 		"lwpsinfo" },
189 	{ PR_LWPUSAGE,	 6 * sizeof (prdirent_t), sizeof (prdirent_t),
190 		"lwpusage" },
191 	{ PR_XREGS,	 7 * sizeof (prdirent_t), sizeof (prdirent_t),
192 		"xregs" },
193 	{ PR_TMPLDIR,	 8 * sizeof (prdirent_t), sizeof (prdirent_t),
194 		"templates" },
195 	{ PR_SPYMASTER,	 9 * sizeof (prdirent_t), sizeof (prdirent_t),
196 		"spymaster" },
197 #if defined(__sparc)
198 	{ PR_GWINDOWS,	10 * sizeof (prdirent_t), sizeof (prdirent_t),
199 		"gwindows" },
200 	{ PR_ASRS,	11 * sizeof (prdirent_t), sizeof (prdirent_t),
201 		"asrs" },
202 #endif
203 };
204 
205 #define	NLWPIDDIRFILES	(sizeof (lwpiddir) / sizeof (lwpiddir[0]) - 2)
206 
207 /*
208  * Span of entries in the array files (lstatus, lpsinfo, lusage).
209  * We make the span larger than the size of the structure on purpose,
210  * to make sure that programs cannot use the structure size by mistake.
211  * Align _ILP32 structures at 8 bytes, _LP64 structures at 16 bytes.
212  */
213 #ifdef _LP64
214 #define	LSPAN(type)	(round16(sizeof (type)) + 16)
215 #define	LSPAN32(type)	(round8(sizeof (type)) + 8)
216 #else
217 #define	LSPAN(type)	(round8(sizeof (type)) + 8)
218 #endif
219 
220 static void rebuild_objdir(struct as *);
221 static void prfreecommon(prcommon_t *);
222 static int praccess(vnode_t *, int, int, cred_t *, caller_context_t *);
223 
224 static int
225 propen(vnode_t **vpp, int flag, cred_t *cr, caller_context_t *ct)
226 {
227 	vnode_t *vp = *vpp;
228 	prnode_t *pnp = VTOP(vp);
229 	prcommon_t *pcp = pnp->pr_pcommon;
230 	prnodetype_t type = pnp->pr_type;
231 	vnode_t *rvp;
232 	vtype_t vtype;
233 	proc_t *p;
234 	int error = 0;
235 	prnode_t *npnp = NULL;
236 
237 	/*
238 	 * Nothing to do for the /proc directory itself.
239 	 */
240 	if (type == PR_PROCDIR)
241 		return (0);
242 
243 	/*
244 	 * If we are opening an underlying mapped object, reject opens
245 	 * for writing regardless of the objects's access modes.
246 	 * If we are opening a file in the /proc/pid/fd directory,
247 	 * reject the open for any but a regular file or directory.
248 	 * Just do it if we are opening the current or root directory.
249 	 */
250 	switch (type) {
251 	case PR_OBJECT:
252 	case PR_FD:
253 	case PR_CURDIR:
254 	case PR_ROOTDIR:
255 		rvp = pnp->pr_realvp;
256 		vtype = rvp->v_type;
257 		if ((type == PR_OBJECT && (flag & FWRITE)) ||
258 		    (type == PR_FD && vtype != VREG && vtype != VDIR))
259 			error = EACCES;
260 		else {
261 			/*
262 			 * Need to hold rvp since VOP_OPEN() may release it.
263 			 */
264 			VN_HOLD(rvp);
265 			error = VOP_OPEN(&rvp, flag, cr, ct);
266 			if (error) {
267 				VN_RELE(rvp);
268 			} else {
269 				*vpp = rvp;
270 				VN_RELE(vp);
271 			}
272 		}
273 		return (error);
274 	default:
275 		break;
276 	}
277 
278 	/*
279 	 * If we are opening the pagedata file, allocate a prnode now
280 	 * to avoid calling kmem_alloc() while holding p->p_lock.
281 	 */
282 	if (type == PR_PAGEDATA || type == PR_OPAGEDATA)
283 		npnp = prgetnode(vp, type);
284 
285 	/*
286 	 * If the process exists, lock it now.
287 	 * Otherwise we have a race condition with prclose().
288 	 */
289 	p = pr_p_lock(pnp);
290 	mutex_exit(&pr_pidlock);
291 	if (p == NULL) {
292 		if (npnp != NULL)
293 			prfreenode(npnp);
294 		return (ENOENT);
295 	}
296 	ASSERT(p == pcp->prc_proc);
297 	ASSERT(p->p_proc_flag & P_PR_LOCK);
298 
299 	/*
300 	 * Maintain a count of opens for write.  Allow exactly one
301 	 * O_WRITE|O_EXCL request and fail subsequent ones.
302 	 * Don't fail opens of old (bletch!) /proc lwp files.
303 	 * Special case for open by the process itself:
304 	 * Always allow the open by self and discount this
305 	 * open for other opens for writing.
306 	 */
307 	if (flag & FWRITE) {
308 		if (p == curproc) {
309 			pcp->prc_selfopens++;
310 			pnp->pr_flags |= PR_ISSELF;
311 		} else if (type == PR_LWPIDFILE) {
312 			/* EMPTY */;
313 		} else if (flag & FEXCL) {
314 			if (pcp->prc_writers > pcp->prc_selfopens) {
315 				error = EBUSY;
316 				goto out;
317 			}
318 			/* semantic for old /proc interface */
319 			if (type == PR_PIDDIR)
320 				pcp->prc_flags |= PRC_EXCL;
321 		} else if (pcp->prc_flags & PRC_EXCL) {
322 			ASSERT(pcp->prc_writers > pcp->prc_selfopens);
323 			error = secpolicy_proc_excl_open(cr);
324 			if (error)
325 				goto out;
326 		}
327 		pcp->prc_writers++;
328 		/*
329 		 * The vnode may have become invalid between the
330 		 * VOP_LOOKUP() of the /proc vnode and the VOP_OPEN().
331 		 * If so, do now what prinvalidate() should have done.
332 		 */
333 		if ((pnp->pr_flags & PR_INVAL) ||
334 		    (type == PR_PIDDIR &&
335 		    (VTOP(pnp->pr_pidfile)->pr_flags & PR_INVAL))) {
336 			if (p != curproc)
337 				pcp->prc_selfopens++;
338 			ASSERT(pcp->prc_selfopens <= pcp->prc_writers);
339 			if (pcp->prc_selfopens == pcp->prc_writers)
340 				pcp->prc_flags &= ~PRC_EXCL;
341 		}
342 	}
343 
344 	/*
345 	 * If this is a large file open, indicate that in our flags -- some
346 	 * procfs structures are not off_t-neutral (e.g., priovec_t), and
347 	 * the open will need to be differentiated where 32-bit processes
348 	 * pass these structures across the user/kernel boundary.
349 	 */
350 	if (flag & FOFFMAX)
351 		pnp->pr_flags |= PR_OFFMAX;
352 
353 	/*
354 	 * Do file-specific things.
355 	 */
356 	switch (type) {
357 	default:
358 		break;
359 	case PR_PAGEDATA:
360 	case PR_OPAGEDATA:
361 		/*
362 		 * Enable data collection for page data file;
363 		 * get unique id from the hat layer.
364 		 */
365 		{
366 			int id;
367 
368 			/*
369 			 * Drop p->p_lock to call hat_startstat()
370 			 */
371 			mutex_exit(&p->p_lock);
372 			if ((p->p_flag & SSYS) || p->p_as == &kas ||
373 			    (id = hat_startstat(p->p_as)) == -1) {
374 				mutex_enter(&p->p_lock);
375 				error = ENOMEM;
376 			} else if (pnp->pr_hatid == 0) {
377 				mutex_enter(&p->p_lock);
378 				pnp->pr_hatid = (uint_t)id;
379 			} else {
380 				mutex_enter(&p->p_lock);
381 				/*
382 				 * Use our newly allocated prnode.
383 				 */
384 				npnp->pr_hatid = (uint_t)id;
385 				/*
386 				 * prgetnode() initialized most of the prnode.
387 				 * Duplicate the remainder.
388 				 */
389 				npnp->pr_ino = pnp->pr_ino;
390 				npnp->pr_common = pnp->pr_common;
391 				npnp->pr_pcommon = pnp->pr_pcommon;
392 				npnp->pr_parent = pnp->pr_parent;
393 				VN_HOLD(npnp->pr_parent);
394 				npnp->pr_index = pnp->pr_index;
395 
396 				npnp->pr_next = p->p_plist;
397 				p->p_plist = PTOV(npnp);
398 
399 				VN_RELE(PTOV(pnp));
400 				pnp = npnp;
401 				npnp = NULL;
402 				*vpp = PTOV(pnp);
403 			}
404 		}
405 		break;
406 	}
407 
408 out:
409 	prunlock(pnp);
410 
411 	if (npnp != NULL)
412 		prfreenode(npnp);
413 	return (error);
414 }
415 
416 /* ARGSUSED */
417 static int
418 prclose(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr,
419     caller_context_t *ct)
420 {
421 	prnode_t *pnp = VTOP(vp);
422 	prcommon_t *pcp = pnp->pr_pcommon;
423 	prnodetype_t type = pnp->pr_type;
424 	proc_t *p;
425 	kthread_t *t;
426 	user_t *up;
427 
428 	/*
429 	 * Nothing to do for the /proc directory itself.
430 	 */
431 	if (type == PR_PROCDIR)
432 		return (0);
433 
434 	ASSERT(type != PR_OBJECT && type != PR_FD &&
435 	    type != PR_CURDIR && type != PR_ROOTDIR);
436 
437 	/*
438 	 * If the process exists, lock it now.
439 	 * Otherwise we have a race condition with propen().
440 	 * Hold pr_pidlock across the reference to prc_selfopens,
441 	 * and prc_writers in case there is no process anymore,
442 	 * to cover the case of concurrent calls to prclose()
443 	 * after the process has been reaped by freeproc().
444 	 */
445 	p = pr_p_lock(pnp);
446 
447 	/*
448 	 * There is nothing more to do until the last close of
449 	 * the file table entry except to clear the pr_owner
450 	 * field of the prnode and notify any waiters
451 	 * (their file descriptor may have just been closed).
452 	 */
453 	if (count > 1) {
454 		mutex_exit(&pr_pidlock);
455 		if (pnp->pr_owner == curproc && !fisopen(vp))
456 			pnp->pr_owner = NULL;
457 		if (p != NULL) {
458 			prnotify(vp);
459 			prunlock(pnp);
460 		}
461 		return (0);
462 	}
463 
464 	/*
465 	 * Decrement the count of self-opens for writing.
466 	 * Decrement the total count of opens for writing.
467 	 * Cancel exclusive opens when only self-opens remain.
468 	 */
469 	if (flag & FWRITE) {
470 		/*
471 		 * prc_selfopens also contains the count of
472 		 * invalid writers.  See prinvalidate().
473 		 */
474 		if ((pnp->pr_flags & (PR_ISSELF|PR_INVAL)) ||
475 		    (type == PR_PIDDIR &&
476 		    (VTOP(pnp->pr_pidfile)->pr_flags & PR_INVAL))) {
477 			ASSERT(pcp->prc_selfopens != 0);
478 			--pcp->prc_selfopens;
479 		}
480 		ASSERT(pcp->prc_writers != 0);
481 		if (--pcp->prc_writers == pcp->prc_selfopens)
482 			pcp->prc_flags &= ~PRC_EXCL;
483 	}
484 	ASSERT(pcp->prc_writers >= pcp->prc_selfopens);
485 	mutex_exit(&pr_pidlock);
486 	if (pnp->pr_owner == curproc && !fisopen(vp))
487 		pnp->pr_owner = NULL;
488 
489 	/*
490 	 * If there is no process, there is nothing more to do.
491 	 */
492 	if (p == NULL)
493 		return (0);
494 
495 	ASSERT(p == pcp->prc_proc);
496 	prnotify(vp);	/* notify waiters */
497 
498 	/*
499 	 * Do file-specific things.
500 	 */
501 	switch (type) {
502 	default:
503 		break;
504 	case PR_PAGEDATA:
505 	case PR_OPAGEDATA:
506 		/*
507 		 * This is a page data file.
508 		 * Free the hat level statistics.
509 		 * Drop p->p_lock before calling hat_freestat().
510 		 */
511 		mutex_exit(&p->p_lock);
512 		if (p->p_as != &kas && pnp->pr_hatid != 0)
513 			hat_freestat(p->p_as, pnp->pr_hatid);
514 		mutex_enter(&p->p_lock);
515 		pnp->pr_hatid = 0;
516 		break;
517 	}
518 
519 	/*
520 	 * On last close of all writable file descriptors,
521 	 * perform run-on-last-close and/or kill-on-last-close logic.
522 	 * Can't do this is the /proc agent lwp still exists.
523 	 */
524 	if (pcp->prc_writers == 0 &&
525 	    p->p_agenttp == NULL &&
526 	    !(pcp->prc_flags & PRC_DESTROY) &&
527 	    p->p_stat != SZOMB &&
528 	    (p->p_proc_flag & (P_PR_RUNLCL|P_PR_KILLCL))) {
529 		int killproc;
530 
531 		/*
532 		 * Cancel any watchpoints currently in effect.
533 		 * The process might disappear during this operation.
534 		 */
535 		if (pr_cancel_watch(pnp) == NULL)
536 			return (0);
537 		/*
538 		 * If any tracing flags are set, clear them.
539 		 */
540 		if (p->p_proc_flag & P_PR_TRACE) {
541 			up = PTOU(p);
542 			premptyset(&up->u_entrymask);
543 			premptyset(&up->u_exitmask);
544 			up->u_systrap = 0;
545 		}
546 		premptyset(&p->p_sigmask);
547 		premptyset(&p->p_fltmask);
548 		killproc = (p->p_proc_flag & P_PR_KILLCL);
549 		p->p_proc_flag &= ~(P_PR_RUNLCL|P_PR_KILLCL|P_PR_TRACE);
550 		/*
551 		 * Cancel any outstanding single-step requests.
552 		 */
553 		if ((t = p->p_tlist) != NULL) {
554 			/*
555 			 * Drop p_lock because prnostep() touches the stack.
556 			 * The loop is safe because the process is P_PR_LOCK'd.
557 			 */
558 			mutex_exit(&p->p_lock);
559 			do {
560 				prnostep(ttolwp(t));
561 			} while ((t = t->t_forw) != p->p_tlist);
562 			mutex_enter(&p->p_lock);
563 		}
564 		/*
565 		 * Set runnable all lwps stopped by /proc.
566 		 */
567 		if (killproc)
568 			sigtoproc(p, NULL, SIGKILL);
569 		else
570 			allsetrun(p);
571 	}
572 
573 	prunlock(pnp);
574 	return (0);
575 }
576 
577 /*
578  * Array of read functions, indexed by /proc file type.
579  */
580 static int pr_read_inval(), pr_read_as(), pr_read_status(),
581 	pr_read_lstatus(), pr_read_psinfo(), pr_read_lpsinfo(),
582 	pr_read_map(), pr_read_rmap(), pr_read_xmap(),
583 	pr_read_cred(), pr_read_sigact(), pr_read_auxv(),
584 #if defined(__x86)
585 	pr_read_ldt(),
586 #endif
587 	pr_read_usage(), pr_read_lusage(), pr_read_pagedata(),
588 	pr_read_watch(), pr_read_lwpstatus(), pr_read_lwpsinfo(),
589 	pr_read_lwpusage(), pr_read_xregs(), pr_read_priv(),
590 	pr_read_spymaster(), pr_read_secflags(),
591 #if defined(__sparc)
592 	pr_read_gwindows(), pr_read_asrs(),
593 #endif
594 	pr_read_piddir(), pr_read_pidfile(), pr_read_opagedata();
595 
596 static int (*pr_read_function[PR_NFILES])() = {
597 	pr_read_inval,		/* /proc				*/
598 	pr_read_inval,		/* /proc/self				*/
599 	pr_read_piddir,		/* /proc/<pid> (old /proc read())	*/
600 	pr_read_as,		/* /proc/<pid>/as			*/
601 	pr_read_inval,		/* /proc/<pid>/ctl			*/
602 	pr_read_status,		/* /proc/<pid>/status			*/
603 	pr_read_lstatus,	/* /proc/<pid>/lstatus			*/
604 	pr_read_psinfo,		/* /proc/<pid>/psinfo			*/
605 	pr_read_lpsinfo,	/* /proc/<pid>/lpsinfo			*/
606 	pr_read_map,		/* /proc/<pid>/map			*/
607 	pr_read_rmap,		/* /proc/<pid>/rmap			*/
608 	pr_read_xmap,		/* /proc/<pid>/xmap			*/
609 	pr_read_cred,		/* /proc/<pid>/cred			*/
610 	pr_read_sigact,		/* /proc/<pid>/sigact			*/
611 	pr_read_auxv,		/* /proc/<pid>/auxv			*/
612 #if defined(__x86)
613 	pr_read_ldt,		/* /proc/<pid>/ldt			*/
614 #endif
615 	pr_read_usage,		/* /proc/<pid>/usage			*/
616 	pr_read_lusage,		/* /proc/<pid>/lusage			*/
617 	pr_read_pagedata,	/* /proc/<pid>/pagedata			*/
618 	pr_read_watch,		/* /proc/<pid>/watch			*/
619 	pr_read_inval,		/* /proc/<pid>/cwd			*/
620 	pr_read_inval,		/* /proc/<pid>/root			*/
621 	pr_read_inval,		/* /proc/<pid>/fd			*/
622 	pr_read_inval,		/* /proc/<pid>/fd/nn			*/
623 	pr_read_inval,		/* /proc/<pid>/object			*/
624 	pr_read_inval,		/* /proc/<pid>/object/xxx		*/
625 	pr_read_inval,		/* /proc/<pid>/lwp			*/
626 	pr_read_inval,		/* /proc/<pid>/lwp/<lwpid>		*/
627 	pr_read_inval,		/* /proc/<pid>/lwp/<lwpid>/lwpctl	*/
628 	pr_read_lwpstatus,	/* /proc/<pid>/lwp/<lwpid>/lwpstatus	*/
629 	pr_read_lwpsinfo,	/* /proc/<pid>/lwp/<lwpid>/lwpsinfo	*/
630 	pr_read_lwpusage,	/* /proc/<pid>/lwp/<lwpid>/lwpusage	*/
631 	pr_read_xregs,		/* /proc/<pid>/lwp/<lwpid>/xregs	*/
632 	pr_read_inval,		/* /proc/<pid>/lwp/<lwpid>/templates	*/
633 	pr_read_inval,		/* /proc/<pid>/lwp/<lwpid>/templates/<id> */
634 	pr_read_spymaster,	/* /proc/<pid>/lwp/<lwpid>/spymaster	*/
635 #if defined(__sparc)
636 	pr_read_gwindows,	/* /proc/<pid>/lwp/<lwpid>/gwindows	*/
637 	pr_read_asrs,		/* /proc/<pid>/lwp/<lwpid>/asrs		*/
638 #endif
639 	pr_read_priv,		/* /proc/<pid>/priv			*/
640 	pr_read_inval,		/* /proc/<pid>/path			*/
641 	pr_read_inval,		/* /proc/<pid>/path/xxx			*/
642 	pr_read_inval,		/* /proc/<pid>/contracts		*/
643 	pr_read_inval,		/* /proc/<pid>/contracts/<ctid>		*/
644 	pr_read_secflags,	/* /proc/<pid>/secflags			*/
645 	pr_read_pidfile,	/* old process file			*/
646 	pr_read_pidfile,	/* old lwp file				*/
647 	pr_read_opagedata,	/* old pagedata file			*/
648 };
649 
650 /* ARGSUSED */
651 static int
652 pr_read_inval(prnode_t *pnp, uio_t *uiop)
653 {
654 	/*
655 	 * No read() on any /proc directory, use getdents(2) instead.
656 	 * Cannot read a control file either.
657 	 * An underlying mapped object file cannot get here.
658 	 */
659 	return (EINVAL);
660 }
661 
662 static int
663 pr_uioread(void *base, long count, uio_t *uiop)
664 {
665 	int error = 0;
666 
667 	ASSERT(count >= 0);
668 	count -= uiop->uio_offset;
669 	if (count > 0 && uiop->uio_offset >= 0) {
670 		error = uiomove((char *)base + uiop->uio_offset,
671 		    count, UIO_READ, uiop);
672 	}
673 
674 	return (error);
675 }
676 
677 static int
678 pr_read_as(prnode_t *pnp, uio_t *uiop)
679 {
680 	int error;
681 
682 	ASSERT(pnp->pr_type == PR_AS);
683 
684 	if ((error = prlock(pnp, ZNO)) == 0) {
685 		proc_t *p = pnp->pr_common->prc_proc;
686 		struct as *as = p->p_as;
687 
688 		/*
689 		 * /proc I/O cannot be done to a system process.
690 		 * A 32-bit process cannot read a 64-bit process.
691 		 */
692 		if ((p->p_flag & SSYS) || as == &kas) {
693 			error = 0;
694 #ifdef _SYSCALL32_IMPL
695 		} else if (curproc->p_model == DATAMODEL_ILP32 &&
696 		    PROCESS_NOT_32BIT(p)) {
697 			error = EOVERFLOW;
698 #endif
699 		} else {
700 			/*
701 			 * We don't hold p_lock over an i/o operation because
702 			 * that could lead to deadlock with the clock thread.
703 			 */
704 			mutex_exit(&p->p_lock);
705 			error = prusrio(p, UIO_READ, uiop, 0);
706 			mutex_enter(&p->p_lock);
707 		}
708 		prunlock(pnp);
709 	}
710 
711 	return (error);
712 }
713 
714 static int
715 pr_read_status(prnode_t *pnp, uio_t *uiop)
716 {
717 	pstatus_t *sp;
718 	int error;
719 
720 	ASSERT(pnp->pr_type == PR_STATUS);
721 
722 	/*
723 	 * We kmem_alloc() the pstatus structure because
724 	 * it is so big it might blow the kernel stack.
725 	 */
726 	sp = kmem_alloc(sizeof (*sp), KM_SLEEP);
727 	if ((error = prlock(pnp, ZNO)) == 0) {
728 		prgetstatus(pnp->pr_common->prc_proc, sp, VTOZONE(PTOV(pnp)));
729 		prunlock(pnp);
730 		error = pr_uioread(sp, sizeof (*sp), uiop);
731 	}
732 	kmem_free(sp, sizeof (*sp));
733 	return (error);
734 }
735 
736 static int
737 pr_read_lstatus(prnode_t *pnp, uio_t *uiop)
738 {
739 	proc_t *p;
740 	kthread_t *t;
741 	lwpdir_t *ldp;
742 	size_t size;
743 	prheader_t *php;
744 	lwpstatus_t *sp;
745 	int error;
746 	int nlwp;
747 	int i;
748 
749 	ASSERT(pnp->pr_type == PR_LSTATUS);
750 
751 	if ((error = prlock(pnp, ZNO)) != 0)
752 		return (error);
753 	p = pnp->pr_common->prc_proc;
754 	nlwp = p->p_lwpcnt;
755 	size = sizeof (prheader_t) + nlwp * LSPAN(lwpstatus_t);
756 
757 	/* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
758 	mutex_exit(&p->p_lock);
759 	php = kmem_zalloc(size, KM_SLEEP);
760 	mutex_enter(&p->p_lock);
761 	/* p->p_lwpcnt can't change while process is locked */
762 	ASSERT(nlwp == p->p_lwpcnt);
763 
764 	php->pr_nent = nlwp;
765 	php->pr_entsize = LSPAN(lwpstatus_t);
766 
767 	sp = (lwpstatus_t *)(php + 1);
768 	for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
769 		if (ldp->ld_entry == NULL ||
770 		    (t = ldp->ld_entry->le_thread) == NULL)
771 			continue;
772 		prgetlwpstatus(t, sp, VTOZONE(PTOV(pnp)));
773 		sp = (lwpstatus_t *)((caddr_t)sp + LSPAN(lwpstatus_t));
774 	}
775 	prunlock(pnp);
776 
777 	error = pr_uioread(php, size, uiop);
778 	kmem_free(php, size);
779 	return (error);
780 }
781 
782 static int
783 pr_read_psinfo(prnode_t *pnp, uio_t *uiop)
784 {
785 	psinfo_t psinfo;
786 	proc_t *p;
787 	int error = 0;
788 
789 	ASSERT(pnp->pr_type == PR_PSINFO);
790 
791 	/*
792 	 * We don't want the full treatment of prlock(pnp) here.
793 	 * This file is world-readable and never goes invalid.
794 	 * It doesn't matter if we are in the middle of an exec().
795 	 */
796 	p = pr_p_lock(pnp);
797 	mutex_exit(&pr_pidlock);
798 	if (p == NULL)
799 		error = ENOENT;
800 	else {
801 		ASSERT(p == pnp->pr_common->prc_proc);
802 		prgetpsinfo(p, &psinfo);
803 		prunlock(pnp);
804 		error = pr_uioread(&psinfo, sizeof (psinfo), uiop);
805 	}
806 	return (error);
807 }
808 
809 static int
810 pr_read_lpsinfo(prnode_t *pnp, uio_t *uiop)
811 {
812 	proc_t *p;
813 	kthread_t *t;
814 	lwpdir_t *ldp;
815 	lwpent_t *lep;
816 	size_t size;
817 	prheader_t *php;
818 	lwpsinfo_t *sp;
819 	int error;
820 	int nlwp;
821 	int i;
822 
823 	ASSERT(pnp->pr_type == PR_LPSINFO);
824 
825 	/*
826 	 * We don't want the full treatment of prlock(pnp) here.
827 	 * This file is world-readable and never goes invalid.
828 	 * It doesn't matter if we are in the middle of an exec().
829 	 */
830 	p = pr_p_lock(pnp);
831 	mutex_exit(&pr_pidlock);
832 	if (p == NULL)
833 		return (ENOENT);
834 	ASSERT(p == pnp->pr_common->prc_proc);
835 	if ((nlwp = p->p_lwpcnt + p->p_zombcnt) == 0) {
836 		prunlock(pnp);
837 		return (ENOENT);
838 	}
839 	size = sizeof (prheader_t) + nlwp * LSPAN(lwpsinfo_t);
840 
841 	/* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
842 	mutex_exit(&p->p_lock);
843 	php = kmem_zalloc(size, KM_SLEEP);
844 	mutex_enter(&p->p_lock);
845 	/* p->p_lwpcnt can't change while process is locked */
846 	ASSERT(nlwp == p->p_lwpcnt + p->p_zombcnt);
847 
848 	php->pr_nent = nlwp;
849 	php->pr_entsize = LSPAN(lwpsinfo_t);
850 
851 	sp = (lwpsinfo_t *)(php + 1);
852 	for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
853 		if ((lep = ldp->ld_entry) == NULL)
854 			continue;
855 		if ((t = lep->le_thread) != NULL)
856 			prgetlwpsinfo(t, sp);
857 		else {
858 			bzero(sp, sizeof (*sp));
859 			sp->pr_lwpid = lep->le_lwpid;
860 			sp->pr_state = SZOMB;
861 			sp->pr_sname = 'Z';
862 			sp->pr_start.tv_sec = lep->le_start;
863 			sp->pr_bindpro = PBIND_NONE;
864 			sp->pr_bindpset = PS_NONE;
865 		}
866 		sp = (lwpsinfo_t *)((caddr_t)sp + LSPAN(lwpsinfo_t));
867 	}
868 	prunlock(pnp);
869 
870 	error = pr_uioread(php, size, uiop);
871 	kmem_free(php, size);
872 	return (error);
873 }
874 
875 static int
876 pr_read_map_common(prnode_t *pnp, uio_t *uiop, prnodetype_t type)
877 {
878 	proc_t *p;
879 	struct as *as;
880 	list_t iolhead;
881 	int error;
882 
883 readmap_common:
884 	if ((error = prlock(pnp, ZNO)) != 0)
885 		return (error);
886 
887 	p = pnp->pr_common->prc_proc;
888 	as = p->p_as;
889 
890 	if ((p->p_flag & SSYS) || as == &kas) {
891 		prunlock(pnp);
892 		return (0);
893 	}
894 
895 	if (!AS_LOCK_TRYENTER(as, RW_WRITER)) {
896 		prunlock(pnp);
897 		delay(1);
898 		goto readmap_common;
899 	}
900 	mutex_exit(&p->p_lock);
901 
902 	switch (type) {
903 	case PR_XMAP:
904 		error = prgetxmap(p, &iolhead);
905 		break;
906 	case PR_RMAP:
907 		error = prgetmap(p, 1, &iolhead);
908 		break;
909 	case PR_MAP:
910 		error = prgetmap(p, 0, &iolhead);
911 		break;
912 	}
913 
914 	AS_LOCK_EXIT(as);
915 	mutex_enter(&p->p_lock);
916 	prunlock(pnp);
917 
918 	error = pr_iol_uiomove_and_free(&iolhead, uiop, error);
919 
920 	return (error);
921 }
922 
923 static int
924 pr_read_map(prnode_t *pnp, uio_t *uiop)
925 {
926 	ASSERT(pnp->pr_type == PR_MAP);
927 	return (pr_read_map_common(pnp, uiop, pnp->pr_type));
928 }
929 
930 static int
931 pr_read_rmap(prnode_t *pnp, uio_t *uiop)
932 {
933 	ASSERT(pnp->pr_type == PR_RMAP);
934 	return (pr_read_map_common(pnp, uiop, pnp->pr_type));
935 }
936 
937 static int
938 pr_read_xmap(prnode_t *pnp, uio_t *uiop)
939 {
940 	ASSERT(pnp->pr_type == PR_XMAP);
941 	return (pr_read_map_common(pnp, uiop, pnp->pr_type));
942 }
943 
944 static int
945 pr_read_cred(prnode_t *pnp, uio_t *uiop)
946 {
947 	proc_t *p;
948 	prcred_t *pcrp;
949 	int error;
950 	size_t count;
951 
952 	ASSERT(pnp->pr_type == PR_CRED);
953 
954 	/*
955 	 * We kmem_alloc() the prcred_t structure because
956 	 * the number of supplementary groups is variable.
957 	 */
958 	pcrp =
959 	    kmem_alloc(sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1),
960 	    KM_SLEEP);
961 
962 	if ((error = prlock(pnp, ZNO)) != 0)
963 		goto out;
964 	p = pnp->pr_common->prc_proc;
965 	ASSERT(p != NULL);
966 
967 	prgetcred(p, pcrp);
968 	prunlock(pnp);
969 
970 	count = sizeof (prcred_t);
971 	if (pcrp->pr_ngroups > 1)
972 		count += sizeof (gid_t) * (pcrp->pr_ngroups - 1);
973 	error = pr_uioread(pcrp, count, uiop);
974 out:
975 	kmem_free(pcrp, sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1));
976 	return (error);
977 }
978 
979 static int
980 pr_read_priv(prnode_t *pnp, uio_t *uiop)
981 {
982 	proc_t *p;
983 	size_t psize = prgetprivsize();
984 	prpriv_t *ppriv = kmem_alloc(psize, KM_SLEEP);
985 	int error;
986 
987 	ASSERT(pnp->pr_type == PR_PRIV);
988 
989 	if ((error = prlock(pnp, ZNO)) != 0)
990 		goto out;
991 	p = pnp->pr_common->prc_proc;
992 	ASSERT(p != NULL);
993 
994 	prgetpriv(p, ppriv);
995 	prunlock(pnp);
996 
997 	error = pr_uioread(ppriv, psize, uiop);
998 out:
999 	kmem_free(ppriv, psize);
1000 	return (error);
1001 }
1002 
1003 static int
1004 pr_read_sigact(prnode_t *pnp, uio_t *uiop)
1005 {
1006 	int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
1007 	proc_t *p;
1008 	struct sigaction *sap;
1009 	int sig;
1010 	int error;
1011 	user_t *up;
1012 
1013 	ASSERT(pnp->pr_type == PR_SIGACT);
1014 
1015 	/*
1016 	 * We kmem_alloc() the sigaction array because
1017 	 * it is so big it might blow the kernel stack.
1018 	 */
1019 	sap = kmem_alloc((nsig-1) * sizeof (struct sigaction), KM_SLEEP);
1020 
1021 	if ((error = prlock(pnp, ZNO)) != 0)
1022 		goto out;
1023 	p = pnp->pr_common->prc_proc;
1024 	ASSERT(p != NULL);
1025 
1026 	if (uiop->uio_offset >= (nsig-1)*sizeof (struct sigaction)) {
1027 		prunlock(pnp);
1028 		goto out;
1029 	}
1030 
1031 	up = PTOU(p);
1032 	for (sig = 1; sig < nsig; sig++)
1033 		prgetaction(p, up, sig, &sap[sig-1]);
1034 	prunlock(pnp);
1035 
1036 	error = pr_uioread(sap, (nsig - 1) * sizeof (struct sigaction), uiop);
1037 out:
1038 	kmem_free(sap, (nsig-1) * sizeof (struct sigaction));
1039 	return (error);
1040 }
1041 
1042 static int
1043 pr_read_auxv(prnode_t *pnp, uio_t *uiop)
1044 {
1045 	auxv_t auxv[__KERN_NAUXV_IMPL];
1046 	proc_t *p;
1047 	user_t *up;
1048 	int error;
1049 
1050 	ASSERT(pnp->pr_type == PR_AUXV);
1051 
1052 	if ((error = prlock(pnp, ZNO)) != 0)
1053 		return (error);
1054 
1055 	if (uiop->uio_offset >= sizeof (auxv)) {
1056 		prunlock(pnp);
1057 		return (0);
1058 	}
1059 
1060 	p = pnp->pr_common->prc_proc;
1061 	up = PTOU(p);
1062 	bcopy(up->u_auxv, auxv, sizeof (auxv));
1063 	prunlock(pnp);
1064 
1065 	return (pr_uioread(auxv, sizeof (auxv), uiop));
1066 }
1067 
1068 #if defined(__x86)
1069 /*
1070  * XX64
1071  *	This is almost certainly broken for the amd64 kernel, because
1072  *	we have two kinds of LDT structures to export -- one for compatibility
1073  *	mode, and one for long mode, sigh.
1074  *
1075  * 	For now lets just have a ldt of size 0 for 64-bit processes.
1076  */
1077 static int
1078 pr_read_ldt(prnode_t *pnp, uio_t *uiop)
1079 {
1080 	proc_t *p;
1081 	struct ssd *ssd;
1082 	size_t size;
1083 	int error;
1084 
1085 	ASSERT(pnp->pr_type == PR_LDT);
1086 
1087 	if ((error = prlock(pnp, ZNO)) != 0)
1088 		return (error);
1089 	p = pnp->pr_common->prc_proc;
1090 
1091 	mutex_exit(&p->p_lock);
1092 	mutex_enter(&p->p_ldtlock);
1093 	size = prnldt(p) * sizeof (struct ssd);
1094 	if (uiop->uio_offset >= size) {
1095 		mutex_exit(&p->p_ldtlock);
1096 		mutex_enter(&p->p_lock);
1097 		prunlock(pnp);
1098 		return (0);
1099 	}
1100 
1101 	ssd = kmem_alloc(size, KM_SLEEP);
1102 	prgetldt(p, ssd);
1103 	mutex_exit(&p->p_ldtlock);
1104 	mutex_enter(&p->p_lock);
1105 	prunlock(pnp);
1106 
1107 	error = pr_uioread(ssd, size, uiop);
1108 	kmem_free(ssd, size);
1109 	return (error);
1110 }
1111 #endif	/* __x86 */
1112 
1113 static int
1114 pr_read_usage(prnode_t *pnp, uio_t *uiop)
1115 {
1116 	prhusage_t *pup;
1117 	prusage_t *upup;
1118 	proc_t *p;
1119 	kthread_t *t;
1120 	int error;
1121 
1122 	ASSERT(pnp->pr_type == PR_USAGE);
1123 
1124 	/* allocate now, before locking the process */
1125 	pup = kmem_zalloc(sizeof (*pup), KM_SLEEP);
1126 	upup = kmem_alloc(sizeof (*upup), KM_SLEEP);
1127 
1128 	/*
1129 	 * We don't want the full treatment of prlock(pnp) here.
1130 	 * This file is world-readable and never goes invalid.
1131 	 * It doesn't matter if we are in the middle of an exec().
1132 	 */
1133 	p = pr_p_lock(pnp);
1134 	mutex_exit(&pr_pidlock);
1135 	if (p == NULL) {
1136 		error = ENOENT;
1137 		goto out;
1138 	}
1139 	ASSERT(p == pnp->pr_common->prc_proc);
1140 
1141 	if (uiop->uio_offset >= sizeof (prusage_t)) {
1142 		prunlock(pnp);
1143 		error = 0;
1144 		goto out;
1145 	}
1146 
1147 	pup->pr_tstamp = gethrtime();
1148 
1149 	pup->pr_count  = p->p_defunct;
1150 	pup->pr_create = p->p_mstart;
1151 	pup->pr_term   = p->p_mterm;
1152 
1153 	pup->pr_rtime    = p->p_mlreal;
1154 	pup->pr_utime    = p->p_acct[LMS_USER];
1155 	pup->pr_stime    = p->p_acct[LMS_SYSTEM];
1156 	pup->pr_ttime    = p->p_acct[LMS_TRAP];
1157 	pup->pr_tftime   = p->p_acct[LMS_TFAULT];
1158 	pup->pr_dftime   = p->p_acct[LMS_DFAULT];
1159 	pup->pr_kftime   = p->p_acct[LMS_KFAULT];
1160 	pup->pr_ltime    = p->p_acct[LMS_USER_LOCK];
1161 	pup->pr_slptime  = p->p_acct[LMS_SLEEP];
1162 	pup->pr_wtime    = p->p_acct[LMS_WAIT_CPU];
1163 	pup->pr_stoptime = p->p_acct[LMS_STOPPED];
1164 
1165 	pup->pr_minf  = p->p_ru.minflt;
1166 	pup->pr_majf  = p->p_ru.majflt;
1167 	pup->pr_nswap = p->p_ru.nswap;
1168 	pup->pr_inblk = p->p_ru.inblock;
1169 	pup->pr_oublk = p->p_ru.oublock;
1170 	pup->pr_msnd  = p->p_ru.msgsnd;
1171 	pup->pr_mrcv  = p->p_ru.msgrcv;
1172 	pup->pr_sigs  = p->p_ru.nsignals;
1173 	pup->pr_vctx  = p->p_ru.nvcsw;
1174 	pup->pr_ictx  = p->p_ru.nivcsw;
1175 	pup->pr_sysc  = p->p_ru.sysc;
1176 	pup->pr_ioch  = p->p_ru.ioch;
1177 
1178 	/*
1179 	 * Add the usage information for each active lwp.
1180 	 */
1181 	if ((t = p->p_tlist) != NULL &&
1182 	    !(pnp->pr_pcommon->prc_flags & PRC_DESTROY)) {
1183 		do {
1184 			if (t->t_proc_flag & TP_LWPEXIT)
1185 				continue;
1186 			pup->pr_count++;
1187 			praddusage(t, pup);
1188 		} while ((t = t->t_forw) != p->p_tlist);
1189 	}
1190 
1191 	prunlock(pnp);
1192 
1193 	prcvtusage(pup, upup);
1194 
1195 	error = pr_uioread(upup, sizeof (prusage_t), uiop);
1196 out:
1197 	kmem_free(pup, sizeof (*pup));
1198 	kmem_free(upup, sizeof (*upup));
1199 	return (error);
1200 }
1201 
1202 static int
1203 pr_read_lusage(prnode_t *pnp, uio_t *uiop)
1204 {
1205 	int nlwp;
1206 	prhusage_t *pup;
1207 	prheader_t *php;
1208 	prusage_t *upup;
1209 	size_t size;
1210 	hrtime_t curtime;
1211 	proc_t *p;
1212 	kthread_t *t;
1213 	lwpdir_t *ldp;
1214 	int error;
1215 	int i;
1216 
1217 	ASSERT(pnp->pr_type == PR_LUSAGE);
1218 
1219 	/*
1220 	 * We don't want the full treatment of prlock(pnp) here.
1221 	 * This file is world-readable and never goes invalid.
1222 	 * It doesn't matter if we are in the middle of an exec().
1223 	 */
1224 	p = pr_p_lock(pnp);
1225 	mutex_exit(&pr_pidlock);
1226 	if (p == NULL)
1227 		return (ENOENT);
1228 	ASSERT(p == pnp->pr_common->prc_proc);
1229 	if ((nlwp = p->p_lwpcnt) == 0) {
1230 		prunlock(pnp);
1231 		return (ENOENT);
1232 	}
1233 
1234 	size = sizeof (prheader_t) + (nlwp + 1) * LSPAN(prusage_t);
1235 	if (uiop->uio_offset >= size) {
1236 		prunlock(pnp);
1237 		return (0);
1238 	}
1239 
1240 	/* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1241 	mutex_exit(&p->p_lock);
1242 	pup = kmem_zalloc(size + sizeof (prhusage_t), KM_SLEEP);
1243 	mutex_enter(&p->p_lock);
1244 	/* p->p_lwpcnt can't change while process is locked */
1245 	ASSERT(nlwp == p->p_lwpcnt);
1246 
1247 	php = (prheader_t *)(pup + 1);
1248 	upup = (prusage_t *)(php + 1);
1249 
1250 	php->pr_nent = nlwp + 1;
1251 	php->pr_entsize = LSPAN(prusage_t);
1252 
1253 	curtime = gethrtime();
1254 
1255 	/*
1256 	 * First the summation over defunct lwps.
1257 	 */
1258 	pup->pr_count  = p->p_defunct;
1259 	pup->pr_tstamp = curtime;
1260 	pup->pr_create = p->p_mstart;
1261 	pup->pr_term   = p->p_mterm;
1262 
1263 	pup->pr_rtime    = p->p_mlreal;
1264 	pup->pr_utime    = p->p_acct[LMS_USER];
1265 	pup->pr_stime    = p->p_acct[LMS_SYSTEM];
1266 	pup->pr_ttime    = p->p_acct[LMS_TRAP];
1267 	pup->pr_tftime   = p->p_acct[LMS_TFAULT];
1268 	pup->pr_dftime   = p->p_acct[LMS_DFAULT];
1269 	pup->pr_kftime   = p->p_acct[LMS_KFAULT];
1270 	pup->pr_ltime    = p->p_acct[LMS_USER_LOCK];
1271 	pup->pr_slptime  = p->p_acct[LMS_SLEEP];
1272 	pup->pr_wtime    = p->p_acct[LMS_WAIT_CPU];
1273 	pup->pr_stoptime = p->p_acct[LMS_STOPPED];
1274 
1275 	pup->pr_minf  = p->p_ru.minflt;
1276 	pup->pr_majf  = p->p_ru.majflt;
1277 	pup->pr_nswap = p->p_ru.nswap;
1278 	pup->pr_inblk = p->p_ru.inblock;
1279 	pup->pr_oublk = p->p_ru.oublock;
1280 	pup->pr_msnd  = p->p_ru.msgsnd;
1281 	pup->pr_mrcv  = p->p_ru.msgrcv;
1282 	pup->pr_sigs  = p->p_ru.nsignals;
1283 	pup->pr_vctx  = p->p_ru.nvcsw;
1284 	pup->pr_ictx  = p->p_ru.nivcsw;
1285 	pup->pr_sysc  = p->p_ru.sysc;
1286 	pup->pr_ioch  = p->p_ru.ioch;
1287 
1288 	prcvtusage(pup, upup);
1289 
1290 	/*
1291 	 * Fill one prusage struct for each active lwp.
1292 	 */
1293 	for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
1294 		if (ldp->ld_entry == NULL ||
1295 		    (t = ldp->ld_entry->le_thread) == NULL)
1296 			continue;
1297 		ASSERT(!(t->t_proc_flag & TP_LWPEXIT));
1298 		ASSERT(nlwp > 0);
1299 		--nlwp;
1300 		upup = (prusage_t *)((caddr_t)upup + LSPAN(prusage_t));
1301 		prgetusage(t, pup);
1302 		prcvtusage(pup, upup);
1303 	}
1304 	ASSERT(nlwp == 0);
1305 
1306 	prunlock(pnp);
1307 
1308 	error = pr_uioread(php, size, uiop);
1309 	kmem_free(pup, size + sizeof (prhusage_t));
1310 	return (error);
1311 }
1312 
1313 static int
1314 pr_read_pagedata(prnode_t *pnp, uio_t *uiop)
1315 {
1316 	proc_t *p;
1317 	int error;
1318 
1319 	ASSERT(pnp->pr_type == PR_PAGEDATA);
1320 
1321 	if ((error = prlock(pnp, ZNO)) != 0)
1322 		return (error);
1323 
1324 	p = pnp->pr_common->prc_proc;
1325 	if ((p->p_flag & SSYS) || p->p_as == &kas) {
1326 		prunlock(pnp);
1327 		return (0);
1328 	}
1329 
1330 	mutex_exit(&p->p_lock);
1331 	error = prpdread(p, pnp->pr_hatid, uiop);
1332 	mutex_enter(&p->p_lock);
1333 
1334 	prunlock(pnp);
1335 	return (error);
1336 }
1337 
1338 static int
1339 pr_read_opagedata(prnode_t *pnp, uio_t *uiop)
1340 {
1341 	proc_t *p;
1342 	struct as *as;
1343 	int error;
1344 
1345 	ASSERT(pnp->pr_type == PR_OPAGEDATA);
1346 
1347 	if ((error = prlock(pnp, ZNO)) != 0)
1348 		return (error);
1349 
1350 	p = pnp->pr_common->prc_proc;
1351 	as = p->p_as;
1352 	if ((p->p_flag & SSYS) || as == &kas) {
1353 		prunlock(pnp);
1354 		return (0);
1355 	}
1356 
1357 	mutex_exit(&p->p_lock);
1358 	error = oprpdread(as, pnp->pr_hatid, uiop);
1359 	mutex_enter(&p->p_lock);
1360 
1361 	prunlock(pnp);
1362 	return (error);
1363 }
1364 
1365 static int
1366 pr_read_watch(prnode_t *pnp, uio_t *uiop)
1367 {
1368 	proc_t *p;
1369 	int error;
1370 	prwatch_t *Bpwp;
1371 	size_t size;
1372 	prwatch_t *pwp;
1373 	int nwarea;
1374 	struct watched_area *pwarea;
1375 
1376 	ASSERT(pnp->pr_type == PR_WATCH);
1377 
1378 	if ((error = prlock(pnp, ZNO)) != 0)
1379 		return (error);
1380 
1381 	p = pnp->pr_common->prc_proc;
1382 	nwarea = avl_numnodes(&p->p_warea);
1383 	size = nwarea * sizeof (prwatch_t);
1384 	if (uiop->uio_offset >= size) {
1385 		prunlock(pnp);
1386 		return (0);
1387 	}
1388 
1389 	/* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1390 	mutex_exit(&p->p_lock);
1391 	Bpwp = pwp = kmem_zalloc(size, KM_SLEEP);
1392 	mutex_enter(&p->p_lock);
1393 	/* p->p_nwarea can't change while process is locked */
1394 	ASSERT(nwarea == avl_numnodes(&p->p_warea));
1395 
1396 	/* gather the watched areas */
1397 	for (pwarea = avl_first(&p->p_warea); pwarea != NULL;
1398 	    pwarea = AVL_NEXT(&p->p_warea, pwarea), pwp++) {
1399 		pwp->pr_vaddr = (uintptr_t)pwarea->wa_vaddr;
1400 		pwp->pr_size = pwarea->wa_eaddr - pwarea->wa_vaddr;
1401 		pwp->pr_wflags = (int)pwarea->wa_flags;
1402 	}
1403 
1404 	prunlock(pnp);
1405 
1406 	error = pr_uioread(Bpwp, size, uiop);
1407 	kmem_free(Bpwp, size);
1408 	return (error);
1409 }
1410 
1411 static int
1412 pr_read_lwpstatus(prnode_t *pnp, uio_t *uiop)
1413 {
1414 	lwpstatus_t *sp;
1415 	int error;
1416 
1417 	ASSERT(pnp->pr_type == PR_LWPSTATUS);
1418 
1419 	/*
1420 	 * We kmem_alloc() the lwpstatus structure because
1421 	 * it is so big it might blow the kernel stack.
1422 	 */
1423 	sp = kmem_alloc(sizeof (*sp), KM_SLEEP);
1424 
1425 	if ((error = prlock(pnp, ZNO)) != 0)
1426 		goto out;
1427 
1428 	if (uiop->uio_offset >= sizeof (*sp)) {
1429 		prunlock(pnp);
1430 		goto out;
1431 	}
1432 
1433 	prgetlwpstatus(pnp->pr_common->prc_thread, sp, VTOZONE(PTOV(pnp)));
1434 	prunlock(pnp);
1435 
1436 	error = pr_uioread(sp, sizeof (*sp), uiop);
1437 out:
1438 	kmem_free(sp, sizeof (*sp));
1439 	return (error);
1440 }
1441 
1442 static int
1443 pr_read_lwpsinfo(prnode_t *pnp, uio_t *uiop)
1444 {
1445 	lwpsinfo_t lwpsinfo;
1446 	proc_t *p;
1447 	kthread_t *t;
1448 	lwpent_t *lep;
1449 
1450 	ASSERT(pnp->pr_type == PR_LWPSINFO);
1451 
1452 	/*
1453 	 * We don't want the full treatment of prlock(pnp) here.
1454 	 * This file is world-readable and never goes invalid.
1455 	 * It doesn't matter if we are in the middle of an exec().
1456 	 */
1457 	p = pr_p_lock(pnp);
1458 	mutex_exit(&pr_pidlock);
1459 	if (p == NULL)
1460 		return (ENOENT);
1461 	ASSERT(p == pnp->pr_common->prc_proc);
1462 	if (pnp->pr_common->prc_tslot == -1) {
1463 		prunlock(pnp);
1464 		return (ENOENT);
1465 	}
1466 
1467 	if (uiop->uio_offset >= sizeof (lwpsinfo)) {
1468 		prunlock(pnp);
1469 		return (0);
1470 	}
1471 
1472 	if ((t = pnp->pr_common->prc_thread) != NULL)
1473 		prgetlwpsinfo(t, &lwpsinfo);
1474 	else {
1475 		lep = p->p_lwpdir[pnp->pr_common->prc_tslot].ld_entry;
1476 		bzero(&lwpsinfo, sizeof (lwpsinfo));
1477 		lwpsinfo.pr_lwpid = lep->le_lwpid;
1478 		lwpsinfo.pr_state = SZOMB;
1479 		lwpsinfo.pr_sname = 'Z';
1480 		lwpsinfo.pr_start.tv_sec = lep->le_start;
1481 		lwpsinfo.pr_bindpro = PBIND_NONE;
1482 		lwpsinfo.pr_bindpset = PS_NONE;
1483 	}
1484 	prunlock(pnp);
1485 
1486 	return (pr_uioread(&lwpsinfo, sizeof (lwpsinfo), uiop));
1487 }
1488 
1489 static int
1490 pr_read_lwpusage(prnode_t *pnp, uio_t *uiop)
1491 {
1492 	prhusage_t *pup;
1493 	prusage_t *upup;
1494 	proc_t *p;
1495 	int error;
1496 
1497 	ASSERT(pnp->pr_type == PR_LWPUSAGE);
1498 
1499 	/* allocate now, before locking the process */
1500 	pup = kmem_zalloc(sizeof (*pup), KM_SLEEP);
1501 	upup = kmem_alloc(sizeof (*upup), KM_SLEEP);
1502 
1503 	/*
1504 	 * We don't want the full treatment of prlock(pnp) here.
1505 	 * This file is world-readable and never goes invalid.
1506 	 * It doesn't matter if we are in the middle of an exec().
1507 	 */
1508 	p = pr_p_lock(pnp);
1509 	mutex_exit(&pr_pidlock);
1510 	if (p == NULL) {
1511 		error = ENOENT;
1512 		goto out;
1513 	}
1514 	ASSERT(p == pnp->pr_common->prc_proc);
1515 	if (pnp->pr_common->prc_thread == NULL) {
1516 		prunlock(pnp);
1517 		error = ENOENT;
1518 		goto out;
1519 	}
1520 	if (uiop->uio_offset >= sizeof (prusage_t)) {
1521 		prunlock(pnp);
1522 		error = 0;
1523 		goto out;
1524 	}
1525 
1526 	pup->pr_tstamp = gethrtime();
1527 	prgetusage(pnp->pr_common->prc_thread, pup);
1528 
1529 	prunlock(pnp);
1530 
1531 	prcvtusage(pup, upup);
1532 
1533 	error = pr_uioread(upup, sizeof (prusage_t), uiop);
1534 out:
1535 	kmem_free(pup, sizeof (*pup));
1536 	kmem_free(upup, sizeof (*upup));
1537 	return (error);
1538 }
1539 
1540 /* ARGSUSED */
1541 static int
1542 pr_read_xregs(prnode_t *pnp, uio_t *uiop)
1543 {
1544 #if defined(__sparc)
1545 	proc_t *p;
1546 	kthread_t *t;
1547 	int error;
1548 	char *xreg;
1549 	size_t size;
1550 
1551 	ASSERT(pnp->pr_type == PR_XREGS);
1552 
1553 	xreg = kmem_zalloc(sizeof (prxregset_t), KM_SLEEP);
1554 
1555 	if ((error = prlock(pnp, ZNO)) != 0)
1556 		goto out;
1557 
1558 	p = pnp->pr_common->prc_proc;
1559 	t = pnp->pr_common->prc_thread;
1560 
1561 	size = prhasx(p)? prgetprxregsize(p) : 0;
1562 	if (uiop->uio_offset >= size) {
1563 		prunlock(pnp);
1564 		goto out;
1565 	}
1566 
1567 	/* drop p->p_lock while (possibly) touching the stack */
1568 	mutex_exit(&p->p_lock);
1569 	prgetprxregs(ttolwp(t), xreg);
1570 	mutex_enter(&p->p_lock);
1571 	prunlock(pnp);
1572 
1573 	error = pr_uioread(xreg, size, uiop);
1574 out:
1575 	kmem_free(xreg, sizeof (prxregset_t));
1576 	return (error);
1577 #else
1578 	return (0);
1579 #endif
1580 }
1581 
1582 static int
1583 pr_read_spymaster(prnode_t *pnp, uio_t *uiop)
1584 {
1585 	psinfo_t psinfo;
1586 	int error;
1587 	klwp_t *lwp;
1588 
1589 	ASSERT(pnp->pr_type == PR_SPYMASTER);
1590 
1591 	if ((error = prlock(pnp, ZNO)) != 0)
1592 		return (error);
1593 
1594 	lwp = pnp->pr_common->prc_thread->t_lwp;
1595 
1596 	if (lwp->lwp_spymaster == NULL) {
1597 		prunlock(pnp);
1598 		return (0);
1599 	}
1600 
1601 	bcopy(lwp->lwp_spymaster, &psinfo, sizeof (psinfo_t));
1602 	prunlock(pnp);
1603 
1604 	return (pr_uioread(&psinfo, sizeof (psinfo), uiop));
1605 }
1606 
1607 static int
1608 pr_read_secflags(prnode_t *pnp, uio_t *uiop)
1609 {
1610 	prsecflags_t ret;
1611 	int error;
1612 	proc_t *p;
1613 
1614 	ASSERT(pnp->pr_type == PR_SECFLAGS);
1615 
1616 	if ((error = prlock(pnp, ZNO)) != 0)
1617 		return (error);
1618 
1619 	p = pnp->pr_common->prc_proc;
1620 	prgetsecflags(p, &ret);
1621 	prunlock(pnp);
1622 
1623 	return (pr_uioread(&ret, sizeof (ret), uiop));
1624 }
1625 
1626 #if defined(__sparc)
1627 
1628 static int
1629 pr_read_gwindows(prnode_t *pnp, uio_t *uiop)
1630 {
1631 	proc_t *p;
1632 	kthread_t *t;
1633 	gwindows_t *gwp;
1634 	int error;
1635 	size_t size;
1636 
1637 	ASSERT(pnp->pr_type == PR_GWINDOWS);
1638 
1639 	gwp = kmem_zalloc(sizeof (gwindows_t), KM_SLEEP);
1640 
1641 	if ((error = prlock(pnp, ZNO)) != 0)
1642 		goto out;
1643 
1644 	p = pnp->pr_common->prc_proc;
1645 	t = pnp->pr_common->prc_thread;
1646 
1647 	/*
1648 	 * Drop p->p_lock while touching the stack.
1649 	 * The P_PR_LOCK flag prevents the lwp from
1650 	 * disappearing while we do this.
1651 	 */
1652 	mutex_exit(&p->p_lock);
1653 	if ((size = prnwindows(ttolwp(t))) != 0)
1654 		size = sizeof (gwindows_t) -
1655 		    (SPARC_MAXREGWINDOW - size) * sizeof (struct rwindow);
1656 	if (uiop->uio_offset >= size) {
1657 		mutex_enter(&p->p_lock);
1658 		prunlock(pnp);
1659 		goto out;
1660 	}
1661 	prgetwindows(ttolwp(t), gwp);
1662 	mutex_enter(&p->p_lock);
1663 	prunlock(pnp);
1664 
1665 	error = pr_uioread(gwp, size, uiop);
1666 out:
1667 	kmem_free(gwp, sizeof (gwindows_t));
1668 	return (error);
1669 }
1670 
1671 /* ARGSUSED */
1672 static int
1673 pr_read_asrs(prnode_t *pnp, uio_t *uiop)
1674 {
1675 	int error;
1676 
1677 	ASSERT(pnp->pr_type == PR_ASRS);
1678 
1679 	/* the asrs file exists only for sparc v9 _LP64 processes */
1680 	if ((error = prlock(pnp, ZNO)) == 0) {
1681 		proc_t *p = pnp->pr_common->prc_proc;
1682 		kthread_t *t = pnp->pr_common->prc_thread;
1683 		asrset_t asrset;
1684 
1685 		if (p->p_model != DATAMODEL_LP64 ||
1686 		    uiop->uio_offset >= sizeof (asrset_t)) {
1687 			prunlock(pnp);
1688 			return (0);
1689 		}
1690 
1691 		/*
1692 		 * Drop p->p_lock while touching the stack.
1693 		 * The P_PR_LOCK flag prevents the lwp from
1694 		 * disappearing while we do this.
1695 		 */
1696 		mutex_exit(&p->p_lock);
1697 		prgetasregs(ttolwp(t), asrset);
1698 		mutex_enter(&p->p_lock);
1699 		prunlock(pnp);
1700 
1701 		error = pr_uioread(&asrset[0], sizeof (asrset_t), uiop);
1702 	}
1703 
1704 	return (error);
1705 }
1706 
1707 #endif	/* __sparc */
1708 
1709 static int
1710 pr_read_piddir(prnode_t *pnp, uio_t *uiop)
1711 {
1712 	ASSERT(pnp->pr_type == PR_PIDDIR);
1713 	ASSERT(pnp->pr_pidfile != NULL);
1714 
1715 	/* use the underlying PR_PIDFILE to read the process */
1716 	pnp = VTOP(pnp->pr_pidfile);
1717 	ASSERT(pnp->pr_type == PR_PIDFILE);
1718 
1719 	return (pr_read_pidfile(pnp, uiop));
1720 }
1721 
1722 static int
1723 pr_read_pidfile(prnode_t *pnp, uio_t *uiop)
1724 {
1725 	int error;
1726 
1727 	ASSERT(pnp->pr_type == PR_PIDFILE || pnp->pr_type == PR_LWPIDFILE);
1728 
1729 	if ((error = prlock(pnp, ZNO)) == 0) {
1730 		proc_t *p = pnp->pr_common->prc_proc;
1731 		struct as *as = p->p_as;
1732 
1733 		if ((p->p_flag & SSYS) || as == &kas) {
1734 			/*
1735 			 * /proc I/O cannot be done to a system process.
1736 			 */
1737 			error = EIO;	/* old /proc semantics */
1738 		} else {
1739 			/*
1740 			 * We drop p_lock because we don't want to hold
1741 			 * it over an I/O operation because that could
1742 			 * lead to deadlock with the clock thread.
1743 			 * The process will not disappear and its address
1744 			 * space will not change because it is marked P_PR_LOCK.
1745 			 */
1746 			mutex_exit(&p->p_lock);
1747 			error = prusrio(p, UIO_READ, uiop, 1);
1748 			mutex_enter(&p->p_lock);
1749 		}
1750 		prunlock(pnp);
1751 	}
1752 
1753 	return (error);
1754 }
1755 
1756 #ifdef _SYSCALL32_IMPL
1757 
1758 /*
1759  * Array of ILP32 read functions, indexed by /proc file type.
1760  */
1761 static int pr_read_status_32(),
1762 	pr_read_lstatus_32(), pr_read_psinfo_32(), pr_read_lpsinfo_32(),
1763 	pr_read_map_32(), pr_read_rmap_32(), pr_read_xmap_32(),
1764 	pr_read_sigact_32(), pr_read_auxv_32(),
1765 	pr_read_usage_32(), pr_read_lusage_32(), pr_read_pagedata_32(),
1766 	pr_read_watch_32(), pr_read_lwpstatus_32(), pr_read_lwpsinfo_32(),
1767 	pr_read_lwpusage_32(), pr_read_spymaster_32(),
1768 #if defined(__sparc)
1769 	pr_read_gwindows_32(),
1770 #endif
1771 	pr_read_opagedata_32();
1772 
1773 static int (*pr_read_function_32[PR_NFILES])() = {
1774 	pr_read_inval,		/* /proc				*/
1775 	pr_read_inval,		/* /proc/self				*/
1776 	pr_read_piddir,		/* /proc/<pid> (old /proc read())	*/
1777 	pr_read_as,		/* /proc/<pid>/as			*/
1778 	pr_read_inval,		/* /proc/<pid>/ctl			*/
1779 	pr_read_status_32,	/* /proc/<pid>/status			*/
1780 	pr_read_lstatus_32,	/* /proc/<pid>/lstatus			*/
1781 	pr_read_psinfo_32,	/* /proc/<pid>/psinfo			*/
1782 	pr_read_lpsinfo_32,	/* /proc/<pid>/lpsinfo			*/
1783 	pr_read_map_32,		/* /proc/<pid>/map			*/
1784 	pr_read_rmap_32,	/* /proc/<pid>/rmap			*/
1785 	pr_read_xmap_32,	/* /proc/<pid>/xmap			*/
1786 	pr_read_cred,		/* /proc/<pid>/cred			*/
1787 	pr_read_sigact_32,	/* /proc/<pid>/sigact			*/
1788 	pr_read_auxv_32,	/* /proc/<pid>/auxv			*/
1789 #if defined(__x86)
1790 	pr_read_ldt,		/* /proc/<pid>/ldt			*/
1791 #endif
1792 	pr_read_usage_32,	/* /proc/<pid>/usage			*/
1793 	pr_read_lusage_32,	/* /proc/<pid>/lusage			*/
1794 	pr_read_pagedata_32,	/* /proc/<pid>/pagedata			*/
1795 	pr_read_watch_32,	/* /proc/<pid>/watch			*/
1796 	pr_read_inval,		/* /proc/<pid>/cwd			*/
1797 	pr_read_inval,		/* /proc/<pid>/root			*/
1798 	pr_read_inval,		/* /proc/<pid>/fd			*/
1799 	pr_read_inval,		/* /proc/<pid>/fd/nn			*/
1800 	pr_read_inval,		/* /proc/<pid>/object			*/
1801 	pr_read_inval,		/* /proc/<pid>/object/xxx		*/
1802 	pr_read_inval,		/* /proc/<pid>/lwp			*/
1803 	pr_read_inval,		/* /proc/<pid>/lwp/<lwpid>		*/
1804 	pr_read_inval,		/* /proc/<pid>/lwp/<lwpid>/lwpctl	*/
1805 	pr_read_lwpstatus_32,	/* /proc/<pid>/lwp/<lwpid>/lwpstatus	*/
1806 	pr_read_lwpsinfo_32,	/* /proc/<pid>/lwp/<lwpid>/lwpsinfo	*/
1807 	pr_read_lwpusage_32,	/* /proc/<pid>/lwp/<lwpid>/lwpusage	*/
1808 	pr_read_xregs,		/* /proc/<pid>/lwp/<lwpid>/xregs	*/
1809 	pr_read_inval,		/* /proc/<pid>/lwp/<lwpid>/templates	*/
1810 	pr_read_inval,		/* /proc/<pid>/lwp/<lwpid>/templates/<id> */
1811 	pr_read_spymaster_32,	/* /proc/<pid>/lwp/<lwpid>/spymaster	*/
1812 #if defined(__sparc)
1813 	pr_read_gwindows_32,	/* /proc/<pid>/lwp/<lwpid>/gwindows	*/
1814 	pr_read_asrs,		/* /proc/<pid>/lwp/<lwpid>/asrs		*/
1815 #endif
1816 	pr_read_priv,		/* /proc/<pid>/priv			*/
1817 	pr_read_inval,		/* /proc/<pid>/path			*/
1818 	pr_read_inval,		/* /proc/<pid>/path/xxx			*/
1819 	pr_read_inval,		/* /proc/<pid>/contracts		*/
1820 	pr_read_inval,		/* /proc/<pid>/contracts/<ctid>		*/
1821 	pr_read_secflags,	/* /proc/<pid>/secflags			*/
1822 	pr_read_pidfile,	/* old process file			*/
1823 	pr_read_pidfile,	/* old lwp file				*/
1824 	pr_read_opagedata_32,	/* old pagedata file			*/
1825 };
1826 
1827 static int
1828 pr_read_status_32(prnode_t *pnp, uio_t *uiop)
1829 {
1830 	pstatus32_t *sp;
1831 	proc_t *p;
1832 	int error;
1833 
1834 	ASSERT(pnp->pr_type == PR_STATUS);
1835 
1836 	/*
1837 	 * We kmem_alloc() the pstatus structure because
1838 	 * it is so big it might blow the kernel stack.
1839 	 */
1840 	sp = kmem_alloc(sizeof (*sp), KM_SLEEP);
1841 	if ((error = prlock(pnp, ZNO)) == 0) {
1842 		/*
1843 		 * A 32-bit process cannot get the status of a 64-bit process.
1844 		 * The fields for the 64-bit quantities are not large enough.
1845 		 */
1846 		p = pnp->pr_common->prc_proc;
1847 		if (PROCESS_NOT_32BIT(p)) {
1848 			prunlock(pnp);
1849 			error = EOVERFLOW;
1850 		} else {
1851 			prgetstatus32(pnp->pr_common->prc_proc, sp,
1852 			    VTOZONE(PTOV(pnp)));
1853 			prunlock(pnp);
1854 			error = pr_uioread(sp, sizeof (*sp), uiop);
1855 		}
1856 	}
1857 	kmem_free((caddr_t)sp, sizeof (*sp));
1858 	return (error);
1859 }
1860 
1861 static int
1862 pr_read_lstatus_32(prnode_t *pnp, uio_t *uiop)
1863 {
1864 	proc_t *p;
1865 	kthread_t *t;
1866 	lwpdir_t *ldp;
1867 	size_t size;
1868 	prheader32_t *php;
1869 	lwpstatus32_t *sp;
1870 	int error;
1871 	int nlwp;
1872 	int i;
1873 
1874 	ASSERT(pnp->pr_type == PR_LSTATUS);
1875 
1876 	if ((error = prlock(pnp, ZNO)) != 0)
1877 		return (error);
1878 	p = pnp->pr_common->prc_proc;
1879 	/*
1880 	 * A 32-bit process cannot get the status of a 64-bit process.
1881 	 * The fields for the 64-bit quantities are not large enough.
1882 	 */
1883 	if (PROCESS_NOT_32BIT(p)) {
1884 		prunlock(pnp);
1885 		return (EOVERFLOW);
1886 	}
1887 	nlwp = p->p_lwpcnt;
1888 	size = sizeof (prheader32_t) + nlwp * LSPAN32(lwpstatus32_t);
1889 
1890 	/* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1891 	mutex_exit(&p->p_lock);
1892 	php = kmem_zalloc(size, KM_SLEEP);
1893 	mutex_enter(&p->p_lock);
1894 	/* p->p_lwpcnt can't change while process is locked */
1895 	ASSERT(nlwp == p->p_lwpcnt);
1896 
1897 	php->pr_nent = nlwp;
1898 	php->pr_entsize = LSPAN32(lwpstatus32_t);
1899 
1900 	sp = (lwpstatus32_t *)(php + 1);
1901 	for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
1902 		if (ldp->ld_entry == NULL ||
1903 		    (t = ldp->ld_entry->le_thread) == NULL)
1904 			continue;
1905 		prgetlwpstatus32(t, sp, VTOZONE(PTOV(pnp)));
1906 		sp = (lwpstatus32_t *)((caddr_t)sp + LSPAN32(lwpstatus32_t));
1907 	}
1908 	prunlock(pnp);
1909 
1910 	error = pr_uioread(php, size, uiop);
1911 	kmem_free(php, size);
1912 	return (error);
1913 }
1914 
1915 static int
1916 pr_read_psinfo_32(prnode_t *pnp, uio_t *uiop)
1917 {
1918 	psinfo32_t psinfo;
1919 	proc_t *p;
1920 	int error = 0;
1921 
1922 	ASSERT(pnp->pr_type == PR_PSINFO);
1923 
1924 	/*
1925 	 * We don't want the full treatment of prlock(pnp) here.
1926 	 * This file is world-readable and never goes invalid.
1927 	 * It doesn't matter if we are in the middle of an exec().
1928 	 */
1929 	p = pr_p_lock(pnp);
1930 	mutex_exit(&pr_pidlock);
1931 	if (p == NULL)
1932 		error = ENOENT;
1933 	else {
1934 		ASSERT(p == pnp->pr_common->prc_proc);
1935 		prgetpsinfo32(p, &psinfo);
1936 		prunlock(pnp);
1937 		error = pr_uioread(&psinfo, sizeof (psinfo), uiop);
1938 	}
1939 	return (error);
1940 }
1941 
1942 static int
1943 pr_read_lpsinfo_32(prnode_t *pnp, uio_t *uiop)
1944 {
1945 	proc_t *p;
1946 	kthread_t *t;
1947 	lwpdir_t *ldp;
1948 	lwpent_t *lep;
1949 	size_t size;
1950 	prheader32_t *php;
1951 	lwpsinfo32_t *sp;
1952 	int error;
1953 	int nlwp;
1954 	int i;
1955 
1956 	ASSERT(pnp->pr_type == PR_LPSINFO);
1957 
1958 	/*
1959 	 * We don't want the full treatment of prlock(pnp) here.
1960 	 * This file is world-readable and never goes invalid.
1961 	 * It doesn't matter if we are in the middle of an exec().
1962 	 */
1963 	p = pr_p_lock(pnp);
1964 	mutex_exit(&pr_pidlock);
1965 	if (p == NULL)
1966 		return (ENOENT);
1967 	ASSERT(p == pnp->pr_common->prc_proc);
1968 	if ((nlwp = p->p_lwpcnt + p->p_zombcnt) == 0) {
1969 		prunlock(pnp);
1970 		return (ENOENT);
1971 	}
1972 	size = sizeof (prheader32_t) + nlwp * LSPAN32(lwpsinfo32_t);
1973 
1974 	/* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1975 	mutex_exit(&p->p_lock);
1976 	php = kmem_zalloc(size, KM_SLEEP);
1977 	mutex_enter(&p->p_lock);
1978 	/* p->p_lwpcnt can't change while process is locked */
1979 	ASSERT(nlwp == p->p_lwpcnt + p->p_zombcnt);
1980 
1981 	php->pr_nent = nlwp;
1982 	php->pr_entsize = LSPAN32(lwpsinfo32_t);
1983 
1984 	sp = (lwpsinfo32_t *)(php + 1);
1985 	for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
1986 		if ((lep = ldp->ld_entry) == NULL)
1987 			continue;
1988 		if ((t = lep->le_thread) != NULL)
1989 			prgetlwpsinfo32(t, sp);
1990 		else {
1991 			bzero(sp, sizeof (*sp));
1992 			sp->pr_lwpid = lep->le_lwpid;
1993 			sp->pr_state = SZOMB;
1994 			sp->pr_sname = 'Z';
1995 			sp->pr_start.tv_sec = (time32_t)lep->le_start;
1996 		}
1997 		sp = (lwpsinfo32_t *)((caddr_t)sp + LSPAN32(lwpsinfo32_t));
1998 	}
1999 	prunlock(pnp);
2000 
2001 	error = pr_uioread(php, size, uiop);
2002 	kmem_free(php, size);
2003 	return (error);
2004 }
2005 
2006 static int
2007 pr_read_map_common_32(prnode_t *pnp, uio_t *uiop, prnodetype_t type)
2008 {
2009 	proc_t *p;
2010 	struct as *as;
2011 	list_t	iolhead;
2012 	int error;
2013 
2014 readmap32_common:
2015 	if ((error = prlock(pnp, ZNO)) != 0)
2016 		return (error);
2017 
2018 	p = pnp->pr_common->prc_proc;
2019 	as = p->p_as;
2020 
2021 	if ((p->p_flag & SSYS) || as == &kas) {
2022 		prunlock(pnp);
2023 		return (0);
2024 	}
2025 
2026 	if (PROCESS_NOT_32BIT(p)) {
2027 		prunlock(pnp);
2028 		return (EOVERFLOW);
2029 	}
2030 
2031 	if (!AS_LOCK_TRYENTER(as, RW_WRITER)) {
2032 		prunlock(pnp);
2033 		delay(1);
2034 		goto readmap32_common;
2035 	}
2036 	mutex_exit(&p->p_lock);
2037 
2038 	switch (type) {
2039 	case PR_XMAP:
2040 		error = prgetxmap32(p, &iolhead);
2041 		break;
2042 	case PR_RMAP:
2043 		error = prgetmap32(p, 1, &iolhead);
2044 		break;
2045 	case PR_MAP:
2046 		error = prgetmap32(p, 0, &iolhead);
2047 		break;
2048 	}
2049 	AS_LOCK_EXIT(as);
2050 	mutex_enter(&p->p_lock);
2051 	prunlock(pnp);
2052 
2053 	error = pr_iol_uiomove_and_free(&iolhead, uiop, error);
2054 
2055 	return (error);
2056 }
2057 
2058 static int
2059 pr_read_map_32(prnode_t *pnp, uio_t *uiop)
2060 {
2061 	ASSERT(pnp->pr_type == PR_MAP);
2062 	return (pr_read_map_common_32(pnp, uiop, pnp->pr_type));
2063 }
2064 
2065 static int
2066 pr_read_rmap_32(prnode_t *pnp, uio_t *uiop)
2067 {
2068 	ASSERT(pnp->pr_type == PR_RMAP);
2069 	return (pr_read_map_common_32(pnp, uiop, pnp->pr_type));
2070 }
2071 
2072 static int
2073 pr_read_xmap_32(prnode_t *pnp, uio_t *uiop)
2074 {
2075 	ASSERT(pnp->pr_type == PR_XMAP);
2076 	return (pr_read_map_common_32(pnp, uiop, pnp->pr_type));
2077 }
2078 
2079 static int
2080 pr_read_sigact_32(prnode_t *pnp, uio_t *uiop)
2081 {
2082 	int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
2083 	proc_t *p;
2084 	struct sigaction32 *sap;
2085 	int sig;
2086 	int error;
2087 	user_t *up;
2088 
2089 	ASSERT(pnp->pr_type == PR_SIGACT);
2090 
2091 	/*
2092 	 * We kmem_alloc() the sigaction32 array because
2093 	 * it is so big it might blow the kernel stack.
2094 	 */
2095 	sap = kmem_alloc((nsig-1) * sizeof (struct sigaction32), KM_SLEEP);
2096 
2097 	if ((error = prlock(pnp, ZNO)) != 0)
2098 		goto out;
2099 	p = pnp->pr_common->prc_proc;
2100 
2101 	if (PROCESS_NOT_32BIT(p)) {
2102 		prunlock(pnp);
2103 		error = EOVERFLOW;
2104 		goto out;
2105 	}
2106 
2107 	if (uiop->uio_offset >= (nsig-1) * sizeof (struct sigaction32)) {
2108 		prunlock(pnp);
2109 		goto out;
2110 	}
2111 
2112 	up = PTOU(p);
2113 	for (sig = 1; sig < nsig; sig++)
2114 		prgetaction32(p, up, sig, &sap[sig-1]);
2115 	prunlock(pnp);
2116 
2117 	error = pr_uioread(sap, (nsig - 1) * sizeof (struct sigaction32), uiop);
2118 out:
2119 	kmem_free(sap, (nsig-1) * sizeof (struct sigaction32));
2120 	return (error);
2121 }
2122 
2123 static int
2124 pr_read_auxv_32(prnode_t *pnp, uio_t *uiop)
2125 {
2126 	auxv32_t auxv[__KERN_NAUXV_IMPL];
2127 	proc_t *p;
2128 	user_t *up;
2129 	int error;
2130 	int i;
2131 
2132 	ASSERT(pnp->pr_type == PR_AUXV);
2133 
2134 	if ((error = prlock(pnp, ZNO)) != 0)
2135 		return (error);
2136 	p = pnp->pr_common->prc_proc;
2137 
2138 	if (PROCESS_NOT_32BIT(p)) {
2139 		prunlock(pnp);
2140 		return (EOVERFLOW);
2141 	}
2142 
2143 	if (uiop->uio_offset >= sizeof (auxv)) {
2144 		prunlock(pnp);
2145 		return (0);
2146 	}
2147 
2148 	up = PTOU(p);
2149 	for (i = 0; i < __KERN_NAUXV_IMPL; i++) {
2150 		auxv[i].a_type = (int32_t)up->u_auxv[i].a_type;
2151 		auxv[i].a_un.a_val = (int32_t)up->u_auxv[i].a_un.a_val;
2152 	}
2153 	prunlock(pnp);
2154 
2155 	return (pr_uioread(auxv, sizeof (auxv), uiop));
2156 }
2157 
2158 static int
2159 pr_read_usage_32(prnode_t *pnp, uio_t *uiop)
2160 {
2161 	prhusage_t *pup;
2162 	prusage32_t *upup;
2163 	proc_t *p;
2164 	kthread_t *t;
2165 	int error;
2166 
2167 	ASSERT(pnp->pr_type == PR_USAGE);
2168 
2169 	/* allocate now, before locking the process */
2170 	pup = kmem_zalloc(sizeof (*pup), KM_SLEEP);
2171 	upup = kmem_alloc(sizeof (*upup), KM_SLEEP);
2172 
2173 	/*
2174 	 * We don't want the full treatment of prlock(pnp) here.
2175 	 * This file is world-readable and never goes invalid.
2176 	 * It doesn't matter if we are in the middle of an exec().
2177 	 */
2178 	p = pr_p_lock(pnp);
2179 	mutex_exit(&pr_pidlock);
2180 	if (p == NULL) {
2181 		error = ENOENT;
2182 		goto out;
2183 	}
2184 	ASSERT(p == pnp->pr_common->prc_proc);
2185 
2186 	if (uiop->uio_offset >= sizeof (prusage32_t)) {
2187 		prunlock(pnp);
2188 		error = 0;
2189 		goto out;
2190 	}
2191 
2192 	pup->pr_tstamp = gethrtime();
2193 
2194 	pup->pr_count  = p->p_defunct;
2195 	pup->pr_create = p->p_mstart;
2196 	pup->pr_term   = p->p_mterm;
2197 
2198 	pup->pr_rtime    = p->p_mlreal;
2199 	pup->pr_utime    = p->p_acct[LMS_USER];
2200 	pup->pr_stime    = p->p_acct[LMS_SYSTEM];
2201 	pup->pr_ttime    = p->p_acct[LMS_TRAP];
2202 	pup->pr_tftime   = p->p_acct[LMS_TFAULT];
2203 	pup->pr_dftime   = p->p_acct[LMS_DFAULT];
2204 	pup->pr_kftime   = p->p_acct[LMS_KFAULT];
2205 	pup->pr_ltime    = p->p_acct[LMS_USER_LOCK];
2206 	pup->pr_slptime  = p->p_acct[LMS_SLEEP];
2207 	pup->pr_wtime    = p->p_acct[LMS_WAIT_CPU];
2208 	pup->pr_stoptime = p->p_acct[LMS_STOPPED];
2209 
2210 	pup->pr_minf  = p->p_ru.minflt;
2211 	pup->pr_majf  = p->p_ru.majflt;
2212 	pup->pr_nswap = p->p_ru.nswap;
2213 	pup->pr_inblk = p->p_ru.inblock;
2214 	pup->pr_oublk = p->p_ru.oublock;
2215 	pup->pr_msnd  = p->p_ru.msgsnd;
2216 	pup->pr_mrcv  = p->p_ru.msgrcv;
2217 	pup->pr_sigs  = p->p_ru.nsignals;
2218 	pup->pr_vctx  = p->p_ru.nvcsw;
2219 	pup->pr_ictx  = p->p_ru.nivcsw;
2220 	pup->pr_sysc  = p->p_ru.sysc;
2221 	pup->pr_ioch  = p->p_ru.ioch;
2222 
2223 	/*
2224 	 * Add the usage information for each active lwp.
2225 	 */
2226 	if ((t = p->p_tlist) != NULL &&
2227 	    !(pnp->pr_pcommon->prc_flags & PRC_DESTROY)) {
2228 		do {
2229 			if (t->t_proc_flag & TP_LWPEXIT)
2230 				continue;
2231 			pup->pr_count++;
2232 			praddusage(t, pup);
2233 		} while ((t = t->t_forw) != p->p_tlist);
2234 	}
2235 
2236 	prunlock(pnp);
2237 
2238 	prcvtusage32(pup, upup);
2239 
2240 	error = pr_uioread(upup, sizeof (prusage32_t), uiop);
2241 out:
2242 	kmem_free(pup, sizeof (*pup));
2243 	kmem_free(upup, sizeof (*upup));
2244 	return (error);
2245 }
2246 
2247 static int
2248 pr_read_lusage_32(prnode_t *pnp, uio_t *uiop)
2249 {
2250 	int nlwp;
2251 	prhusage_t *pup;
2252 	prheader32_t *php;
2253 	prusage32_t *upup;
2254 	size_t size;
2255 	hrtime_t curtime;
2256 	proc_t *p;
2257 	kthread_t *t;
2258 	lwpdir_t *ldp;
2259 	int error;
2260 	int i;
2261 
2262 	ASSERT(pnp->pr_type == PR_LUSAGE);
2263 
2264 	/*
2265 	 * We don't want the full treatment of prlock(pnp) here.
2266 	 * This file is world-readable and never goes invalid.
2267 	 * It doesn't matter if we are in the middle of an exec().
2268 	 */
2269 	p = pr_p_lock(pnp);
2270 	mutex_exit(&pr_pidlock);
2271 	if (p == NULL)
2272 		return (ENOENT);
2273 	ASSERT(p == pnp->pr_common->prc_proc);
2274 	if ((nlwp = p->p_lwpcnt) == 0) {
2275 		prunlock(pnp);
2276 		return (ENOENT);
2277 	}
2278 
2279 	size = sizeof (prheader32_t) + (nlwp + 1) * LSPAN32(prusage32_t);
2280 	if (uiop->uio_offset >= size) {
2281 		prunlock(pnp);
2282 		return (0);
2283 	}
2284 
2285 	/* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
2286 	mutex_exit(&p->p_lock);
2287 	pup = kmem_zalloc(size + sizeof (prhusage_t), KM_SLEEP);
2288 	mutex_enter(&p->p_lock);
2289 	/* p->p_lwpcnt can't change while process is locked */
2290 	ASSERT(nlwp == p->p_lwpcnt);
2291 
2292 	php = (prheader32_t *)(pup + 1);
2293 	upup = (prusage32_t *)(php + 1);
2294 
2295 	php->pr_nent = nlwp + 1;
2296 	php->pr_entsize = LSPAN32(prusage32_t);
2297 
2298 	curtime = gethrtime();
2299 
2300 	/*
2301 	 * First the summation over defunct lwps.
2302 	 */
2303 	pup->pr_count  = p->p_defunct;
2304 	pup->pr_tstamp = curtime;
2305 	pup->pr_create = p->p_mstart;
2306 	pup->pr_term   = p->p_mterm;
2307 
2308 	pup->pr_rtime    = p->p_mlreal;
2309 	pup->pr_utime    = p->p_acct[LMS_USER];
2310 	pup->pr_stime    = p->p_acct[LMS_SYSTEM];
2311 	pup->pr_ttime    = p->p_acct[LMS_TRAP];
2312 	pup->pr_tftime   = p->p_acct[LMS_TFAULT];
2313 	pup->pr_dftime   = p->p_acct[LMS_DFAULT];
2314 	pup->pr_kftime   = p->p_acct[LMS_KFAULT];
2315 	pup->pr_ltime    = p->p_acct[LMS_USER_LOCK];
2316 	pup->pr_slptime  = p->p_acct[LMS_SLEEP];
2317 	pup->pr_wtime    = p->p_acct[LMS_WAIT_CPU];
2318 	pup->pr_stoptime = p->p_acct[LMS_STOPPED];
2319 
2320 	pup->pr_minf  = p->p_ru.minflt;
2321 	pup->pr_majf  = p->p_ru.majflt;
2322 	pup->pr_nswap = p->p_ru.nswap;
2323 	pup->pr_inblk = p->p_ru.inblock;
2324 	pup->pr_oublk = p->p_ru.oublock;
2325 	pup->pr_msnd  = p->p_ru.msgsnd;
2326 	pup->pr_mrcv  = p->p_ru.msgrcv;
2327 	pup->pr_sigs  = p->p_ru.nsignals;
2328 	pup->pr_vctx  = p->p_ru.nvcsw;
2329 	pup->pr_ictx  = p->p_ru.nivcsw;
2330 	pup->pr_sysc  = p->p_ru.sysc;
2331 	pup->pr_ioch  = p->p_ru.ioch;
2332 
2333 	prcvtusage32(pup, upup);
2334 
2335 	/*
2336 	 * Fill one prusage struct for each active lwp.
2337 	 */
2338 	for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
2339 		if (ldp->ld_entry == NULL ||
2340 		    (t = ldp->ld_entry->le_thread) == NULL)
2341 			continue;
2342 		ASSERT(!(t->t_proc_flag & TP_LWPEXIT));
2343 		ASSERT(nlwp > 0);
2344 		--nlwp;
2345 		upup = (prusage32_t *)
2346 		    ((caddr_t)upup + LSPAN32(prusage32_t));
2347 		prgetusage(t, pup);
2348 		prcvtusage32(pup, upup);
2349 	}
2350 	ASSERT(nlwp == 0);
2351 
2352 	prunlock(pnp);
2353 
2354 	error = pr_uioread(php, size, uiop);
2355 	kmem_free(pup, size + sizeof (prhusage_t));
2356 	return (error);
2357 }
2358 
2359 static int
2360 pr_read_pagedata_32(prnode_t *pnp, uio_t *uiop)
2361 {
2362 	proc_t *p;
2363 	int error;
2364 
2365 	ASSERT(pnp->pr_type == PR_PAGEDATA);
2366 
2367 	if ((error = prlock(pnp, ZNO)) != 0)
2368 		return (error);
2369 
2370 	p = pnp->pr_common->prc_proc;
2371 	if ((p->p_flag & SSYS) || p->p_as == &kas) {
2372 		prunlock(pnp);
2373 		return (0);
2374 	}
2375 
2376 	if (PROCESS_NOT_32BIT(p)) {
2377 		prunlock(pnp);
2378 		return (EOVERFLOW);
2379 	}
2380 
2381 	mutex_exit(&p->p_lock);
2382 	error = prpdread32(p, pnp->pr_hatid, uiop);
2383 	mutex_enter(&p->p_lock);
2384 
2385 	prunlock(pnp);
2386 	return (error);
2387 }
2388 
2389 static int
2390 pr_read_opagedata_32(prnode_t *pnp, uio_t *uiop)
2391 {
2392 	proc_t *p;
2393 	struct as *as;
2394 	int error;
2395 
2396 	ASSERT(pnp->pr_type == PR_OPAGEDATA);
2397 
2398 	if ((error = prlock(pnp, ZNO)) != 0)
2399 		return (error);
2400 
2401 	p = pnp->pr_common->prc_proc;
2402 	as = p->p_as;
2403 
2404 	if ((p->p_flag & SSYS) || as == &kas) {
2405 		prunlock(pnp);
2406 		return (0);
2407 	}
2408 
2409 	if (PROCESS_NOT_32BIT(p)) {
2410 		prunlock(pnp);
2411 		return (EOVERFLOW);
2412 	}
2413 
2414 	mutex_exit(&p->p_lock);
2415 	error = oprpdread32(as, pnp->pr_hatid, uiop);
2416 	mutex_enter(&p->p_lock);
2417 
2418 	prunlock(pnp);
2419 	return (error);
2420 }
2421 
2422 static int
2423 pr_read_watch_32(prnode_t *pnp, uio_t *uiop)
2424 {
2425 	proc_t *p;
2426 	int error;
2427 	prwatch32_t *Bpwp;
2428 	size_t size;
2429 	prwatch32_t *pwp;
2430 	int nwarea;
2431 	struct watched_area *pwarea;
2432 
2433 	ASSERT(pnp->pr_type == PR_WATCH);
2434 
2435 	if ((error = prlock(pnp, ZNO)) != 0)
2436 		return (error);
2437 
2438 	p = pnp->pr_common->prc_proc;
2439 	if (PROCESS_NOT_32BIT(p)) {
2440 		prunlock(pnp);
2441 		return (EOVERFLOW);
2442 	}
2443 	nwarea = avl_numnodes(&p->p_warea);
2444 	size = nwarea * sizeof (prwatch32_t);
2445 	if (uiop->uio_offset >= size) {
2446 		prunlock(pnp);
2447 		return (0);
2448 	}
2449 
2450 	/* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
2451 	mutex_exit(&p->p_lock);
2452 	Bpwp = pwp = kmem_zalloc(size, KM_SLEEP);
2453 	mutex_enter(&p->p_lock);
2454 	/* p->p_nwarea can't change while process is locked */
2455 	ASSERT(nwarea == avl_numnodes(&p->p_warea));
2456 
2457 	/* gather the watched areas */
2458 	for (pwarea = avl_first(&p->p_warea); pwarea != NULL;
2459 	    pwarea = AVL_NEXT(&p->p_warea, pwarea), pwp++) {
2460 		pwp->pr_vaddr = (caddr32_t)(uintptr_t)pwarea->wa_vaddr;
2461 		pwp->pr_size = (size32_t)(pwarea->wa_eaddr - pwarea->wa_vaddr);
2462 		pwp->pr_wflags = (int)pwarea->wa_flags;
2463 	}
2464 
2465 	prunlock(pnp);
2466 
2467 	error = pr_uioread(Bpwp, size, uiop);
2468 	kmem_free(Bpwp, size);
2469 	return (error);
2470 }
2471 
2472 static int
2473 pr_read_lwpstatus_32(prnode_t *pnp, uio_t *uiop)
2474 {
2475 	lwpstatus32_t *sp;
2476 	proc_t *p;
2477 	int error;
2478 
2479 	ASSERT(pnp->pr_type == PR_LWPSTATUS);
2480 
2481 	/*
2482 	 * We kmem_alloc() the lwpstatus structure because
2483 	 * it is so big it might blow the kernel stack.
2484 	 */
2485 	sp = kmem_alloc(sizeof (*sp), KM_SLEEP);
2486 
2487 	if ((error = prlock(pnp, ZNO)) != 0)
2488 		goto out;
2489 
2490 	/*
2491 	 * A 32-bit process cannot get the status of a 64-bit process.
2492 	 * The fields for the 64-bit quantities are not large enough.
2493 	 */
2494 	p = pnp->pr_common->prc_proc;
2495 	if (PROCESS_NOT_32BIT(p)) {
2496 		prunlock(pnp);
2497 		error = EOVERFLOW;
2498 		goto out;
2499 	}
2500 
2501 	if (uiop->uio_offset >= sizeof (*sp)) {
2502 		prunlock(pnp);
2503 		goto out;
2504 	}
2505 
2506 	prgetlwpstatus32(pnp->pr_common->prc_thread, sp, VTOZONE(PTOV(pnp)));
2507 	prunlock(pnp);
2508 
2509 	error = pr_uioread(sp, sizeof (*sp), uiop);
2510 out:
2511 	kmem_free(sp, sizeof (*sp));
2512 	return (error);
2513 }
2514 
2515 static int
2516 pr_read_lwpsinfo_32(prnode_t *pnp, uio_t *uiop)
2517 {
2518 	lwpsinfo32_t lwpsinfo;
2519 	proc_t *p;
2520 	kthread_t *t;
2521 	lwpent_t *lep;
2522 
2523 	ASSERT(pnp->pr_type == PR_LWPSINFO);
2524 
2525 	/*
2526 	 * We don't want the full treatment of prlock(pnp) here.
2527 	 * This file is world-readable and never goes invalid.
2528 	 * It doesn't matter if we are in the middle of an exec().
2529 	 */
2530 	p = pr_p_lock(pnp);
2531 	mutex_exit(&pr_pidlock);
2532 	if (p == NULL)
2533 		return (ENOENT);
2534 	ASSERT(p == pnp->pr_common->prc_proc);
2535 	if (pnp->pr_common->prc_tslot == -1) {
2536 		prunlock(pnp);
2537 		return (ENOENT);
2538 	}
2539 
2540 	if (uiop->uio_offset >= sizeof (lwpsinfo)) {
2541 		prunlock(pnp);
2542 		return (0);
2543 	}
2544 
2545 	if ((t = pnp->pr_common->prc_thread) != NULL)
2546 		prgetlwpsinfo32(t, &lwpsinfo);
2547 	else {
2548 		lep = p->p_lwpdir[pnp->pr_common->prc_tslot].ld_entry;
2549 		bzero(&lwpsinfo, sizeof (lwpsinfo));
2550 		lwpsinfo.pr_lwpid = lep->le_lwpid;
2551 		lwpsinfo.pr_state = SZOMB;
2552 		lwpsinfo.pr_sname = 'Z';
2553 		lwpsinfo.pr_start.tv_sec = (time32_t)lep->le_start;
2554 	}
2555 	prunlock(pnp);
2556 
2557 	return (pr_uioread(&lwpsinfo, sizeof (lwpsinfo), uiop));
2558 }
2559 
2560 static int
2561 pr_read_lwpusage_32(prnode_t *pnp, uio_t *uiop)
2562 {
2563 	prhusage_t *pup;
2564 	prusage32_t *upup;
2565 	proc_t *p;
2566 	int error;
2567 
2568 	ASSERT(pnp->pr_type == PR_LWPUSAGE);
2569 
2570 	/* allocate now, before locking the process */
2571 	pup = kmem_zalloc(sizeof (*pup), KM_SLEEP);
2572 	upup = kmem_alloc(sizeof (*upup), KM_SLEEP);
2573 
2574 	/*
2575 	 * We don't want the full treatment of prlock(pnp) here.
2576 	 * This file is world-readable and never goes invalid.
2577 	 * It doesn't matter if we are in the middle of an exec().
2578 	 */
2579 	p = pr_p_lock(pnp);
2580 	mutex_exit(&pr_pidlock);
2581 	if (p == NULL) {
2582 		error = ENOENT;
2583 		goto out;
2584 	}
2585 	ASSERT(p == pnp->pr_common->prc_proc);
2586 	if (pnp->pr_common->prc_thread == NULL) {
2587 		prunlock(pnp);
2588 		error = ENOENT;
2589 		goto out;
2590 	}
2591 	if (uiop->uio_offset >= sizeof (prusage32_t)) {
2592 		prunlock(pnp);
2593 		error = 0;
2594 		goto out;
2595 	}
2596 
2597 	pup->pr_tstamp = gethrtime();
2598 	prgetusage(pnp->pr_common->prc_thread, pup);
2599 
2600 	prunlock(pnp);
2601 
2602 	prcvtusage32(pup, upup);
2603 
2604 	error = pr_uioread(upup, sizeof (prusage32_t), uiop);
2605 out:
2606 	kmem_free(pup, sizeof (*pup));
2607 	kmem_free(upup, sizeof (*upup));
2608 	return (error);
2609 }
2610 
2611 static int
2612 pr_read_spymaster_32(prnode_t *pnp, uio_t *uiop)
2613 {
2614 	psinfo32_t psinfo;
2615 	int error;
2616 	klwp_t *lwp;
2617 
2618 	ASSERT(pnp->pr_type == PR_SPYMASTER);
2619 
2620 	if ((error = prlock(pnp, ZNO)) != 0)
2621 		return (error);
2622 
2623 	lwp = pnp->pr_common->prc_thread->t_lwp;
2624 
2625 	if (lwp->lwp_spymaster == NULL) {
2626 		prunlock(pnp);
2627 		return (0);
2628 	}
2629 
2630 	psinfo_kto32(lwp->lwp_spymaster, &psinfo);
2631 	prunlock(pnp);
2632 
2633 	return (pr_uioread(&psinfo, sizeof (psinfo), uiop));
2634 }
2635 
2636 #if defined(__sparc)
2637 static int
2638 pr_read_gwindows_32(prnode_t *pnp, uio_t *uiop)
2639 {
2640 	proc_t *p;
2641 	kthread_t *t;
2642 	gwindows32_t *gwp;
2643 	int error;
2644 	size_t size;
2645 
2646 	ASSERT(pnp->pr_type == PR_GWINDOWS);
2647 
2648 	gwp = kmem_zalloc(sizeof (gwindows32_t), KM_SLEEP);
2649 
2650 	if ((error = prlock(pnp, ZNO)) != 0)
2651 		goto out;
2652 
2653 	p = pnp->pr_common->prc_proc;
2654 	t = pnp->pr_common->prc_thread;
2655 
2656 	if (PROCESS_NOT_32BIT(p)) {
2657 		prunlock(pnp);
2658 		error = EOVERFLOW;
2659 		goto out;
2660 	}
2661 
2662 	/*
2663 	 * Drop p->p_lock while touching the stack.
2664 	 * The P_PR_LOCK flag prevents the lwp from
2665 	 * disappearing while we do this.
2666 	 */
2667 	mutex_exit(&p->p_lock);
2668 	if ((size = prnwindows(ttolwp(t))) != 0)
2669 		size = sizeof (gwindows32_t) -
2670 		    (SPARC_MAXREGWINDOW - size) * sizeof (struct rwindow32);
2671 	if (uiop->uio_offset >= size) {
2672 		mutex_enter(&p->p_lock);
2673 		prunlock(pnp);
2674 		goto out;
2675 	}
2676 	prgetwindows32(ttolwp(t), gwp);
2677 	mutex_enter(&p->p_lock);
2678 	prunlock(pnp);
2679 
2680 	error = pr_uioread(gwp, size, uiop);
2681 out:
2682 	kmem_free(gwp, sizeof (gwindows32_t));
2683 	return (error);
2684 }
2685 #endif	/* __sparc */
2686 
2687 #endif	/* _SYSCALL32_IMPL */
2688 
2689 /* ARGSUSED */
2690 static int
2691 prread(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct)
2692 {
2693 	prnode_t *pnp = VTOP(vp);
2694 
2695 	ASSERT(pnp->pr_type < PR_NFILES);
2696 
2697 #ifdef _SYSCALL32_IMPL
2698 	/*
2699 	 * What is read from the /proc files depends on the data
2700 	 * model of the caller.  An LP64 process will see LP64
2701 	 * data.  An ILP32 process will see ILP32 data.
2702 	 */
2703 	if (curproc->p_model == DATAMODEL_LP64)
2704 		return (pr_read_function[pnp->pr_type](pnp, uiop));
2705 	else
2706 		return (pr_read_function_32[pnp->pr_type](pnp, uiop));
2707 #else
2708 	return (pr_read_function[pnp->pr_type](pnp, uiop));
2709 #endif
2710 }
2711 
2712 /* ARGSUSED */
2713 static int
2714 prwrite(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct)
2715 {
2716 	prnode_t *pnp = VTOP(vp);
2717 	int old = 0;
2718 	int error;
2719 	ssize_t resid;
2720 
2721 	ASSERT(pnp->pr_type < PR_NFILES);
2722 
2723 	/*
2724 	 * Only a handful of /proc files are writable, enumerate them here.
2725 	 */
2726 	switch (pnp->pr_type) {
2727 	case PR_PIDDIR:		/* directory write()s: visceral revulsion. */
2728 		ASSERT(pnp->pr_pidfile != NULL);
2729 		/* use the underlying PR_PIDFILE to write the process */
2730 		vp = pnp->pr_pidfile;
2731 		pnp = VTOP(vp);
2732 		ASSERT(pnp->pr_type == PR_PIDFILE);
2733 		/* FALLTHROUGH */
2734 	case PR_PIDFILE:
2735 	case PR_LWPIDFILE:
2736 		old = 1;
2737 		/* FALLTHROUGH */
2738 	case PR_AS:
2739 		if ((error = prlock(pnp, ZNO)) == 0) {
2740 			proc_t *p = pnp->pr_common->prc_proc;
2741 			struct as *as = p->p_as;
2742 
2743 			if ((p->p_flag & SSYS) || as == &kas) {
2744 				/*
2745 				 * /proc I/O cannot be done to a system process.
2746 				 */
2747 				error = EIO;
2748 #ifdef _SYSCALL32_IMPL
2749 			} else if (curproc->p_model == DATAMODEL_ILP32 &&
2750 			    PROCESS_NOT_32BIT(p)) {
2751 				error = EOVERFLOW;
2752 #endif
2753 			} else {
2754 				/*
2755 				 * See comments above (pr_read_pidfile)
2756 				 * about this locking dance.
2757 				 */
2758 				mutex_exit(&p->p_lock);
2759 				error = prusrio(p, UIO_WRITE, uiop, old);
2760 				mutex_enter(&p->p_lock);
2761 			}
2762 			prunlock(pnp);
2763 		}
2764 		return (error);
2765 
2766 	case PR_CTL:
2767 	case PR_LWPCTL:
2768 		resid = uiop->uio_resid;
2769 		/*
2770 		 * Perform the action on the control file
2771 		 * by passing curthreads credentials
2772 		 * and not target process's credentials.
2773 		 */
2774 #ifdef _SYSCALL32_IMPL
2775 		if (curproc->p_model == DATAMODEL_ILP32)
2776 			error = prwritectl32(vp, uiop, CRED());
2777 		else
2778 			error = prwritectl(vp, uiop, CRED());
2779 #else
2780 		error = prwritectl(vp, uiop, CRED());
2781 #endif
2782 		/*
2783 		 * This hack makes sure that the EINTR is passed
2784 		 * all the way back to the caller's write() call.
2785 		 */
2786 		if (error == EINTR)
2787 			uiop->uio_resid = resid;
2788 		return (error);
2789 
2790 	default:
2791 		return ((vp->v_type == VDIR)? EISDIR : EBADF);
2792 	}
2793 	/* NOTREACHED */
2794 }
2795 
2796 static int
2797 prgetattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
2798     caller_context_t *ct)
2799 {
2800 	prnode_t *pnp = VTOP(vp);
2801 	prnodetype_t type = pnp->pr_type;
2802 	prcommon_t *pcp;
2803 	proc_t *p;
2804 	struct as *as;
2805 	int error;
2806 	vnode_t *rvp;
2807 	timestruc_t now;
2808 	extern uint_t nproc;
2809 	int ngroups;
2810 	int nsig;
2811 
2812 	/*
2813 	 * This ugly bit of code allows us to keep both versions of this
2814 	 * function from the same source.
2815 	 */
2816 #ifdef _LP64
2817 	int iam32bit = (curproc->p_model == DATAMODEL_ILP32);
2818 #define	PR_OBJSIZE(obj32, obj64)	\
2819 	(iam32bit ? sizeof (obj32) : sizeof (obj64))
2820 #define	PR_OBJSPAN(obj32, obj64)	\
2821 	(iam32bit ? LSPAN32(obj32) : LSPAN(obj64))
2822 #else
2823 #define	PR_OBJSIZE(obj32, obj64)	\
2824 	(sizeof (obj64))
2825 #define	PR_OBJSPAN(obj32, obj64)	\
2826 	(LSPAN(obj64))
2827 #endif
2828 
2829 	/*
2830 	 * Return all the attributes.  Should be refined
2831 	 * so that it returns only those asked for.
2832 	 * Most of this is complete fakery anyway.
2833 	 */
2834 
2835 	/*
2836 	 * For files in the /proc/<pid>/object directory,
2837 	 * return the attributes of the underlying object.
2838 	 * For files in the /proc/<pid>/fd directory,
2839 	 * return the attributes of the underlying file, but
2840 	 * make it look inaccessible if it is not a regular file.
2841 	 * Make directories look like symlinks.
2842 	 */
2843 	switch (type) {
2844 	case PR_CURDIR:
2845 	case PR_ROOTDIR:
2846 		if (!(flags & ATTR_REAL))
2847 			break;
2848 		/* restrict full knowledge of the attributes to owner or root */
2849 		if ((error = praccess(vp, 0, 0, cr, ct)) != 0)
2850 			return (error);
2851 		/* FALLTHROUGH */
2852 	case PR_OBJECT:
2853 	case PR_FD:
2854 		rvp = pnp->pr_realvp;
2855 		error = VOP_GETATTR(rvp, vap, flags, cr, ct);
2856 		if (error)
2857 			return (error);
2858 		if (type == PR_FD) {
2859 			if (rvp->v_type != VREG && rvp->v_type != VDIR)
2860 				vap->va_mode = 0;
2861 			else
2862 				vap->va_mode &= pnp->pr_mode;
2863 		}
2864 		if (type == PR_OBJECT)
2865 			vap->va_mode &= 07555;
2866 		if (rvp->v_type == VDIR && !(flags & ATTR_REAL)) {
2867 			vap->va_type = VLNK;
2868 			vap->va_size = 0;
2869 			vap->va_nlink = 1;
2870 		}
2871 		return (0);
2872 	default:
2873 		break;
2874 	}
2875 
2876 	bzero(vap, sizeof (*vap));
2877 	/*
2878 	 * Large Files: Internally proc now uses VPROC to indicate
2879 	 * a proc file. Since we have been returning VREG through
2880 	 * VOP_GETATTR() until now, we continue to do this so as
2881 	 * not to break apps depending on this return value.
2882 	 */
2883 	vap->va_type = (vp->v_type == VPROC) ? VREG : vp->v_type;
2884 	vap->va_mode = pnp->pr_mode;
2885 	vap->va_fsid = vp->v_vfsp->vfs_dev;
2886 	vap->va_blksize = DEV_BSIZE;
2887 	vap->va_rdev = 0;
2888 	vap->va_seq = 0;
2889 
2890 	if (type == PR_PROCDIR) {
2891 		vap->va_uid = 0;
2892 		vap->va_gid = 0;
2893 		vap->va_nlink = nproc + 2;
2894 		vap->va_nodeid = (ino64_t)PRROOTINO;
2895 		gethrestime(&now);
2896 		vap->va_atime = vap->va_mtime = vap->va_ctime = now;
2897 		vap->va_size = (v.v_proc + 2) * PRSDSIZE;
2898 		vap->va_nblocks = btod(vap->va_size);
2899 		return (0);
2900 	}
2901 
2902 	/*
2903 	 * /proc/<pid>/self is a symbolic link, and has no prcommon member
2904 	 */
2905 	if (type == PR_SELF) {
2906 		vap->va_uid = crgetruid(CRED());
2907 		vap->va_gid = crgetrgid(CRED());
2908 		vap->va_nodeid = (ino64_t)PR_SELF;
2909 		gethrestime(&now);
2910 		vap->va_atime = vap->va_mtime = vap->va_ctime = now;
2911 		vap->va_nlink = 1;
2912 		vap->va_type = VLNK;
2913 		vap->va_size = 0;
2914 		return (0);
2915 	}
2916 
2917 	p = pr_p_lock(pnp);
2918 	mutex_exit(&pr_pidlock);
2919 	if (p == NULL)
2920 		return (ENOENT);
2921 	pcp = pnp->pr_common;
2922 
2923 	mutex_enter(&p->p_crlock);
2924 	vap->va_uid = crgetruid(p->p_cred);
2925 	vap->va_gid = crgetrgid(p->p_cred);
2926 	mutex_exit(&p->p_crlock);
2927 
2928 	vap->va_nlink = 1;
2929 	vap->va_nodeid = pnp->pr_ino? pnp->pr_ino :
2930 	    pmkino(pcp->prc_tslot, pcp->prc_slot, pnp->pr_type);
2931 	if ((pcp->prc_flags & PRC_LWP) && pcp->prc_tslot != -1) {
2932 		vap->va_atime.tv_sec = vap->va_mtime.tv_sec =
2933 		    vap->va_ctime.tv_sec =
2934 		    p->p_lwpdir[pcp->prc_tslot].ld_entry->le_start;
2935 		vap->va_atime.tv_nsec = vap->va_mtime.tv_nsec =
2936 		    vap->va_ctime.tv_nsec = 0;
2937 	} else {
2938 		user_t *up = PTOU(p);
2939 		vap->va_atime.tv_sec = vap->va_mtime.tv_sec =
2940 		    vap->va_ctime.tv_sec = up->u_start.tv_sec;
2941 		vap->va_atime.tv_nsec = vap->va_mtime.tv_nsec =
2942 		    vap->va_ctime.tv_nsec = up->u_start.tv_nsec;
2943 	}
2944 
2945 	switch (type) {
2946 	case PR_PIDDIR:
2947 		/* va_nlink: count 'lwp', 'object' and 'fd' directory links */
2948 		vap->va_nlink = 5;
2949 		vap->va_size = sizeof (piddir);
2950 		break;
2951 	case PR_OBJECTDIR:
2952 		if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
2953 			vap->va_size = 2 * PRSDSIZE;
2954 		else {
2955 			mutex_exit(&p->p_lock);
2956 			AS_LOCK_ENTER(as, RW_WRITER);
2957 			if (as->a_updatedir)
2958 				rebuild_objdir(as);
2959 			vap->va_size = (as->a_sizedir + 2) * PRSDSIZE;
2960 			AS_LOCK_EXIT(as);
2961 			mutex_enter(&p->p_lock);
2962 		}
2963 		vap->va_nlink = 2;
2964 		break;
2965 	case PR_PATHDIR:
2966 		if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
2967 			vap->va_size = (P_FINFO(p)->fi_nfiles + 4) * PRSDSIZE;
2968 		else {
2969 			mutex_exit(&p->p_lock);
2970 			AS_LOCK_ENTER(as, RW_WRITER);
2971 			if (as->a_updatedir)
2972 				rebuild_objdir(as);
2973 			vap->va_size = (as->a_sizedir + 4 +
2974 			    P_FINFO(p)->fi_nfiles) * PRSDSIZE;
2975 			AS_LOCK_EXIT(as);
2976 			mutex_enter(&p->p_lock);
2977 		}
2978 		vap->va_nlink = 2;
2979 		break;
2980 	case PR_PATH:
2981 	case PR_CURDIR:
2982 	case PR_ROOTDIR:
2983 	case PR_CT:
2984 		vap->va_type = VLNK;
2985 		vap->va_size = 0;
2986 		break;
2987 	case PR_FDDIR:
2988 		vap->va_nlink = 2;
2989 		vap->va_size = (P_FINFO(p)->fi_nfiles + 2) * PRSDSIZE;
2990 		break;
2991 	case PR_LWPDIR:
2992 		/*
2993 		 * va_nlink: count each lwp as a directory link.
2994 		 * va_size: size of p_lwpdir + 2
2995 		 */
2996 		vap->va_nlink = p->p_lwpcnt + p->p_zombcnt + 2;
2997 		vap->va_size = (p->p_lwpdir_sz + 2) * PRSDSIZE;
2998 		break;
2999 	case PR_LWPIDDIR:
3000 		vap->va_nlink = 2;
3001 		vap->va_size = sizeof (lwpiddir);
3002 		break;
3003 	case PR_CTDIR:
3004 		vap->va_nlink = 2;
3005 		vap->va_size = (avl_numnodes(&p->p_ct_held) + 2) * PRSDSIZE;
3006 		break;
3007 	case PR_TMPLDIR:
3008 		vap->va_nlink = 2;
3009 		vap->va_size = (ct_ntypes + 2) * PRSDSIZE;
3010 		break;
3011 	case PR_AS:
3012 	case PR_PIDFILE:
3013 	case PR_LWPIDFILE:
3014 		if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3015 			vap->va_size = 0;
3016 		else
3017 			vap->va_size = as->a_resvsize;
3018 		break;
3019 	case PR_STATUS:
3020 		vap->va_size = PR_OBJSIZE(pstatus32_t, pstatus_t);
3021 		break;
3022 	case PR_LSTATUS:
3023 		vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3024 		    p->p_lwpcnt * PR_OBJSPAN(lwpstatus32_t, lwpstatus_t);
3025 		break;
3026 	case PR_PSINFO:
3027 		vap->va_size = PR_OBJSIZE(psinfo32_t, psinfo_t);
3028 		break;
3029 	case PR_LPSINFO:
3030 		vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3031 		    (p->p_lwpcnt + p->p_zombcnt) *
3032 		    PR_OBJSPAN(lwpsinfo32_t, lwpsinfo_t);
3033 		break;
3034 	case PR_MAP:
3035 	case PR_RMAP:
3036 	case PR_XMAP:
3037 		if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3038 			vap->va_size = 0;
3039 		else {
3040 			mutex_exit(&p->p_lock);
3041 			AS_LOCK_ENTER(as, RW_WRITER);
3042 			if (type == PR_MAP)
3043 				vap->va_mtime = as->a_updatetime;
3044 			if (type == PR_XMAP)
3045 				vap->va_size = prnsegs(as, 0) *
3046 				    PR_OBJSIZE(prxmap32_t, prxmap_t);
3047 			else
3048 				vap->va_size = prnsegs(as, type == PR_RMAP) *
3049 				    PR_OBJSIZE(prmap32_t, prmap_t);
3050 			AS_LOCK_EXIT(as);
3051 			mutex_enter(&p->p_lock);
3052 		}
3053 		break;
3054 	case PR_CRED:
3055 		mutex_enter(&p->p_crlock);
3056 		vap->va_size = sizeof (prcred_t);
3057 		ngroups = crgetngroups(p->p_cred);
3058 		if (ngroups > 1)
3059 			vap->va_size += (ngroups - 1) * sizeof (gid_t);
3060 		mutex_exit(&p->p_crlock);
3061 		break;
3062 	case PR_PRIV:
3063 		vap->va_size = prgetprivsize();
3064 		break;
3065 	case PR_SECFLAGS:
3066 		vap->va_size = sizeof (prsecflags_t);
3067 		break;
3068 	case PR_SIGACT:
3069 		nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
3070 		vap->va_size = (nsig-1) *
3071 		    PR_OBJSIZE(struct sigaction32, struct sigaction);
3072 		break;
3073 	case PR_AUXV:
3074 		vap->va_size = __KERN_NAUXV_IMPL * PR_OBJSIZE(auxv32_t, auxv_t);
3075 		break;
3076 #if defined(__x86)
3077 	case PR_LDT:
3078 		mutex_exit(&p->p_lock);
3079 		mutex_enter(&p->p_ldtlock);
3080 		vap->va_size = prnldt(p) * sizeof (struct ssd);
3081 		mutex_exit(&p->p_ldtlock);
3082 		mutex_enter(&p->p_lock);
3083 		break;
3084 #endif
3085 	case PR_USAGE:
3086 		vap->va_size = PR_OBJSIZE(prusage32_t, prusage_t);
3087 		break;
3088 	case PR_LUSAGE:
3089 		vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3090 		    (p->p_lwpcnt + 1) * PR_OBJSPAN(prusage32_t, prusage_t);
3091 		break;
3092 	case PR_PAGEDATA:
3093 		if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3094 			vap->va_size = 0;
3095 		else {
3096 			/*
3097 			 * We can drop p->p_lock before grabbing the
3098 			 * address space lock because p->p_as will not
3099 			 * change while the process is marked P_PR_LOCK.
3100 			 */
3101 			mutex_exit(&p->p_lock);
3102 			AS_LOCK_ENTER(as, RW_WRITER);
3103 #ifdef _LP64
3104 			vap->va_size = iam32bit?
3105 			    prpdsize32(as) : prpdsize(as);
3106 #else
3107 			vap->va_size = prpdsize(as);
3108 #endif
3109 			AS_LOCK_EXIT(as);
3110 			mutex_enter(&p->p_lock);
3111 		}
3112 		break;
3113 	case PR_OPAGEDATA:
3114 		if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3115 			vap->va_size = 0;
3116 		else {
3117 			mutex_exit(&p->p_lock);
3118 			AS_LOCK_ENTER(as, RW_WRITER);
3119 #ifdef _LP64
3120 			vap->va_size = iam32bit?
3121 			    oprpdsize32(as) : oprpdsize(as);
3122 #else
3123 			vap->va_size = oprpdsize(as);
3124 #endif
3125 			AS_LOCK_EXIT(as);
3126 			mutex_enter(&p->p_lock);
3127 		}
3128 		break;
3129 	case PR_WATCH:
3130 		vap->va_size = avl_numnodes(&p->p_warea) *
3131 		    PR_OBJSIZE(prwatch32_t, prwatch_t);
3132 		break;
3133 	case PR_LWPSTATUS:
3134 		vap->va_size = PR_OBJSIZE(lwpstatus32_t, lwpstatus_t);
3135 		break;
3136 	case PR_LWPSINFO:
3137 		vap->va_size = PR_OBJSIZE(lwpsinfo32_t, lwpsinfo_t);
3138 		break;
3139 	case PR_LWPUSAGE:
3140 		vap->va_size = PR_OBJSIZE(prusage32_t, prusage_t);
3141 		break;
3142 	case PR_XREGS:
3143 		if (prhasx(p))
3144 			vap->va_size = prgetprxregsize(p);
3145 		else
3146 			vap->va_size = 0;
3147 		break;
3148 	case PR_SPYMASTER:
3149 		if (pnp->pr_common->prc_thread->t_lwp->lwp_spymaster != NULL) {
3150 			vap->va_size = PR_OBJSIZE(psinfo32_t, psinfo_t);
3151 		} else {
3152 			vap->va_size = 0;
3153 		}
3154 		break;
3155 #if defined(__sparc)
3156 	case PR_GWINDOWS:
3157 	{
3158 		kthread_t *t;
3159 		int n;
3160 
3161 		/*
3162 		 * If there is no lwp then just make the size zero.
3163 		 * This can happen if the lwp exits between the VOP_LOOKUP()
3164 		 * of the /proc/<pid>/lwp/<lwpid>/gwindows file and the
3165 		 * VOP_GETATTR() of the resulting vnode.
3166 		 */
3167 		if ((t = pcp->prc_thread) == NULL) {
3168 			vap->va_size = 0;
3169 			break;
3170 		}
3171 		/*
3172 		 * Drop p->p_lock while touching the stack.
3173 		 * The P_PR_LOCK flag prevents the lwp from
3174 		 * disappearing while we do this.
3175 		 */
3176 		mutex_exit(&p->p_lock);
3177 		if ((n = prnwindows(ttolwp(t))) == 0)
3178 			vap->va_size = 0;
3179 		else
3180 			vap->va_size = PR_OBJSIZE(gwindows32_t, gwindows_t) -
3181 			    (SPARC_MAXREGWINDOW - n) *
3182 			    PR_OBJSIZE(struct rwindow32, struct rwindow);
3183 		mutex_enter(&p->p_lock);
3184 		break;
3185 	}
3186 	case PR_ASRS:
3187 #ifdef _LP64
3188 		if (p->p_model == DATAMODEL_LP64)
3189 			vap->va_size = sizeof (asrset_t);
3190 		else
3191 #endif
3192 			vap->va_size = 0;
3193 		break;
3194 #endif
3195 	case PR_CTL:
3196 	case PR_LWPCTL:
3197 	default:
3198 		vap->va_size = 0;
3199 		break;
3200 	}
3201 
3202 	prunlock(pnp);
3203 	vap->va_nblocks = (fsblkcnt64_t)btod(vap->va_size);
3204 	return (0);
3205 }
3206 
3207 static int
3208 praccess(vnode_t *vp, int mode, int flags, cred_t *cr, caller_context_t *ct)
3209 {
3210 	prnode_t *pnp = VTOP(vp);
3211 	prnodetype_t type = pnp->pr_type;
3212 	int vmode;
3213 	vtype_t vtype;
3214 	proc_t *p;
3215 	int error = 0;
3216 	vnode_t *rvp;
3217 	vnode_t *xvp;
3218 
3219 	if ((mode & VWRITE) && vn_is_readonly(vp))
3220 		return (EROFS);
3221 
3222 	switch (type) {
3223 	case PR_PROCDIR:
3224 		break;
3225 
3226 	case PR_OBJECT:
3227 	case PR_FD:
3228 		/*
3229 		 * Disallow write access to the underlying objects.
3230 		 * Disallow access to underlying non-regular-file fds.
3231 		 * Disallow access to fds with other than existing open modes.
3232 		 */
3233 		rvp = pnp->pr_realvp;
3234 		vtype = rvp->v_type;
3235 		vmode = pnp->pr_mode;
3236 		if ((type == PR_OBJECT && (mode & VWRITE)) ||
3237 		    (type == PR_FD && vtype != VREG && vtype != VDIR) ||
3238 		    (type == PR_FD && (vmode & mode) != mode &&
3239 		    secpolicy_proc_access(cr) != 0))
3240 			return (EACCES);
3241 		return (VOP_ACCESS(rvp, mode, flags, cr, ct));
3242 
3243 	case PR_PSINFO:		/* these files can be read by anyone */
3244 	case PR_LPSINFO:
3245 	case PR_LWPSINFO:
3246 	case PR_LWPDIR:
3247 	case PR_LWPIDDIR:
3248 	case PR_USAGE:
3249 	case PR_LUSAGE:
3250 	case PR_LWPUSAGE:
3251 		p = pr_p_lock(pnp);
3252 		mutex_exit(&pr_pidlock);
3253 		if (p == NULL)
3254 			return (ENOENT);
3255 		prunlock(pnp);
3256 		break;
3257 
3258 	default:
3259 		/*
3260 		 * Except for the world-readable files above,
3261 		 * only /proc/pid exists if the process is a zombie.
3262 		 */
3263 		if ((error = prlock(pnp,
3264 		    (type == PR_PIDDIR)? ZYES : ZNO)) != 0)
3265 			return (error);
3266 		p = pnp->pr_common->prc_proc;
3267 		if (p != curproc)
3268 			error = priv_proc_cred_perm(cr, p, NULL, mode);
3269 
3270 		if (error != 0 || p == curproc || (p->p_flag & SSYS) ||
3271 		    p->p_as == &kas || (xvp = p->p_exec) == NULL) {
3272 			prunlock(pnp);
3273 		} else {
3274 			/*
3275 			 * Determine if the process's executable is readable.
3276 			 * We have to drop p->p_lock before the secpolicy
3277 			 * and VOP operation.
3278 			 */
3279 			VN_HOLD(xvp);
3280 			prunlock(pnp);
3281 			if (secpolicy_proc_access(cr) != 0)
3282 				error = VOP_ACCESS(xvp, VREAD, 0, cr, ct);
3283 			VN_RELE(xvp);
3284 		}
3285 		if (error)
3286 			return (error);
3287 		break;
3288 	}
3289 
3290 	if (type == PR_CURDIR || type == PR_ROOTDIR) {
3291 		/*
3292 		 * Final access check on the underlying directory vnode.
3293 		 */
3294 		return (VOP_ACCESS(pnp->pr_realvp, mode, flags, cr, ct));
3295 	}
3296 
3297 	/*
3298 	 * Visceral revulsion:  For compatibility with old /proc,
3299 	 * allow the /proc/<pid> directory to be opened for writing.
3300 	 */
3301 	vmode = pnp->pr_mode;
3302 	if (type == PR_PIDDIR)
3303 		vmode |= VWRITE;
3304 	if ((vmode & mode) != mode)
3305 		error = secpolicy_proc_access(cr);
3306 	return (error);
3307 }
3308 
3309 /*
3310  * Array of lookup functions, indexed by /proc file type.
3311  */
3312 static vnode_t *pr_lookup_notdir(), *pr_lookup_procdir(), *pr_lookup_piddir(),
3313 	*pr_lookup_objectdir(), *pr_lookup_lwpdir(), *pr_lookup_lwpiddir(),
3314 	*pr_lookup_fddir(), *pr_lookup_pathdir(), *pr_lookup_tmpldir(),
3315 	*pr_lookup_ctdir();
3316 
3317 static vnode_t *(*pr_lookup_function[PR_NFILES])() = {
3318 	pr_lookup_procdir,	/* /proc				*/
3319 	pr_lookup_notdir,	/* /proc/self				*/
3320 	pr_lookup_piddir,	/* /proc/<pid>				*/
3321 	pr_lookup_notdir,	/* /proc/<pid>/as			*/
3322 	pr_lookup_notdir,	/* /proc/<pid>/ctl			*/
3323 	pr_lookup_notdir,	/* /proc/<pid>/status			*/
3324 	pr_lookup_notdir,	/* /proc/<pid>/lstatus			*/
3325 	pr_lookup_notdir,	/* /proc/<pid>/psinfo			*/
3326 	pr_lookup_notdir,	/* /proc/<pid>/lpsinfo			*/
3327 	pr_lookup_notdir,	/* /proc/<pid>/map			*/
3328 	pr_lookup_notdir,	/* /proc/<pid>/rmap			*/
3329 	pr_lookup_notdir,	/* /proc/<pid>/xmap			*/
3330 	pr_lookup_notdir,	/* /proc/<pid>/cred			*/
3331 	pr_lookup_notdir,	/* /proc/<pid>/sigact			*/
3332 	pr_lookup_notdir,	/* /proc/<pid>/auxv			*/
3333 #if defined(__x86)
3334 	pr_lookup_notdir,	/* /proc/<pid>/ldt			*/
3335 #endif
3336 	pr_lookup_notdir,	/* /proc/<pid>/usage			*/
3337 	pr_lookup_notdir,	/* /proc/<pid>/lusage			*/
3338 	pr_lookup_notdir,	/* /proc/<pid>/pagedata			*/
3339 	pr_lookup_notdir,	/* /proc/<pid>/watch			*/
3340 	pr_lookup_notdir,	/* /proc/<pid>/cwd			*/
3341 	pr_lookup_notdir,	/* /proc/<pid>/root			*/
3342 	pr_lookup_fddir,	/* /proc/<pid>/fd			*/
3343 	pr_lookup_notdir,	/* /proc/<pid>/fd/nn			*/
3344 	pr_lookup_objectdir,	/* /proc/<pid>/object			*/
3345 	pr_lookup_notdir,	/* /proc/<pid>/object/xxx		*/
3346 	pr_lookup_lwpdir,	/* /proc/<pid>/lwp			*/
3347 	pr_lookup_lwpiddir,	/* /proc/<pid>/lwp/<lwpid>		*/
3348 	pr_lookup_notdir,	/* /proc/<pid>/lwp/<lwpid>/lwpctl	*/
3349 	pr_lookup_notdir,	/* /proc/<pid>/lwp/<lwpid>/lwpstatus	*/
3350 	pr_lookup_notdir,	/* /proc/<pid>/lwp/<lwpid>/lwpsinfo	*/
3351 	pr_lookup_notdir,	/* /proc/<pid>/lwp/<lwpid>/lwpusage	*/
3352 	pr_lookup_notdir,	/* /proc/<pid>/lwp/<lwpid>/xregs	*/
3353 	pr_lookup_tmpldir,	/* /proc/<pid>/lwp/<lwpid>/templates	*/
3354 	pr_lookup_notdir,	/* /proc/<pid>/lwp/<lwpid>/templates/<id> */
3355 	pr_lookup_notdir,	/* /proc/<pid>/lwp/<lwpid>/spymaster	*/
3356 #if defined(__sparc)
3357 	pr_lookup_notdir,	/* /proc/<pid>/lwp/<lwpid>/gwindows	*/
3358 	pr_lookup_notdir,	/* /proc/<pid>/lwp/<lwpid>/asrs		*/
3359 #endif
3360 	pr_lookup_notdir,	/* /proc/<pid>/priv			*/
3361 	pr_lookup_pathdir,	/* /proc/<pid>/path			*/
3362 	pr_lookup_notdir,	/* /proc/<pid>/path/xxx			*/
3363 	pr_lookup_ctdir,	/* /proc/<pid>/contracts		*/
3364 	pr_lookup_notdir,	/* /proc/<pid>/contracts/<ctid>		*/
3365 	pr_lookup_notdir,	/* /proc/<pid>/secflags			*/
3366 	pr_lookup_notdir,	/* old process file			*/
3367 	pr_lookup_notdir,	/* old lwp file				*/
3368 	pr_lookup_notdir,	/* old pagedata file			*/
3369 };
3370 
3371 static int
3372 prlookup(vnode_t *dp, char *comp, vnode_t **vpp, pathname_t *pathp,
3373     int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct,
3374     int *direntflags, pathname_t *realpnp)
3375 {
3376 	prnode_t *pnp = VTOP(dp);
3377 	prnodetype_t type = pnp->pr_type;
3378 	int error;
3379 
3380 	ASSERT(dp->v_type == VDIR);
3381 	ASSERT(type < PR_NFILES);
3382 
3383 	if (type != PR_PROCDIR && strcmp(comp, "..") == 0) {
3384 		VN_HOLD(pnp->pr_parent);
3385 		*vpp = pnp->pr_parent;
3386 		return (0);
3387 	}
3388 
3389 	if (*comp == '\0' ||
3390 	    strcmp(comp, ".") == 0 || strcmp(comp, "..") == 0) {
3391 		VN_HOLD(dp);
3392 		*vpp = dp;
3393 		return (0);
3394 	}
3395 
3396 	switch (type) {
3397 	case PR_CURDIR:
3398 	case PR_ROOTDIR:
3399 		/* restrict lookup permission to owner or root */
3400 		if ((error = praccess(dp, VEXEC, 0, cr, ct)) != 0)
3401 			return (error);
3402 		/* FALLTHROUGH */
3403 	case PR_FD:
3404 		dp = pnp->pr_realvp;
3405 		return (VOP_LOOKUP(dp, comp, vpp, pathp, flags, rdir, cr, ct,
3406 		    direntflags, realpnp));
3407 	default:
3408 		break;
3409 	}
3410 
3411 	if ((type == PR_OBJECTDIR || type == PR_FDDIR || type == PR_PATHDIR) &&
3412 	    (error = praccess(dp, VEXEC, 0, cr, ct)) != 0)
3413 		return (error);
3414 
3415 	/* XXX - Do we need to pass ct, direntflags, or realpnp? */
3416 	*vpp = (pr_lookup_function[type](dp, comp));
3417 
3418 	return ((*vpp == NULL) ? ENOENT : 0);
3419 }
3420 
3421 /* ARGSUSED */
3422 static int
3423 prcreate(vnode_t *dp, char *comp, vattr_t *vap, vcexcl_t excl,
3424     int mode, vnode_t **vpp, cred_t *cr, int flag, caller_context_t *ct,
3425     vsecattr_t *vsecp)
3426 {
3427 	int error;
3428 
3429 	if ((error = prlookup(dp, comp, vpp, NULL, 0, NULL, cr,
3430 	    ct, NULL, NULL)) != 0) {
3431 		if (error == ENOENT) {
3432 			/* One can't O_CREAT nonexistent files in /proc. */
3433 			error = EACCES;
3434 		}
3435 		return (error);
3436 	}
3437 
3438 	if (excl == EXCL) {
3439 		/* Disallow the O_EXCL case */
3440 		error = EEXIST;
3441 	} else if ((error = praccess(*vpp, mode, 0, cr, ct)) == 0) {
3442 		/* Before proceeding, handle O_TRUNC if necessary. */
3443 		if (vap->va_mask & AT_SIZE) {
3444 			vnode_t *vp = *vpp;
3445 
3446 			if (vp->v_type == VDIR) {
3447 				/* Only allow O_TRUNC on files */
3448 				error = EISDIR;
3449 			} else if (vp->v_type != VPROC ||
3450 			    VTOP(vp)->pr_type != PR_FD) {
3451 				/*
3452 				 * Disallow for files outside of the
3453 				 * /proc/<pid>/fd/<n> entries
3454 				 */
3455 				error = EACCES;
3456 			} else {
3457 				uint_t mask;
3458 
3459 				vp = VTOP(vp)->pr_realvp;
3460 				mask = vap->va_mask;
3461 				vap->va_mask = AT_SIZE;
3462 				error = VOP_SETATTR(vp, vap, 0, cr, ct);
3463 				vap->va_mask = mask;
3464 			}
3465 		}
3466 	}
3467 
3468 	if (error) {
3469 		VN_RELE(*vpp);
3470 		*vpp = NULL;
3471 	}
3472 	return (error);
3473 }
3474 
3475 /* ARGSUSED */
3476 static vnode_t *
3477 pr_lookup_notdir(vnode_t *dp, char *comp)
3478 {
3479 	return (NULL);
3480 }
3481 
3482 /*
3483  * Find or construct a process vnode for the given pid.
3484  */
3485 static vnode_t *
3486 pr_lookup_procdir(vnode_t *dp, char *comp)
3487 {
3488 	pid_t pid;
3489 	prnode_t *pnp;
3490 	prcommon_t *pcp;
3491 	vnode_t *vp;
3492 	proc_t *p;
3493 	int c;
3494 
3495 	ASSERT(VTOP(dp)->pr_type == PR_PROCDIR);
3496 
3497 	if (strcmp(comp, "self") == 0) {
3498 		pnp = prgetnode(dp, PR_SELF);
3499 		return (PTOV(pnp));
3500 	} else {
3501 		pid = 0;
3502 		while ((c = *comp++) != '\0') {
3503 			if (c < '0' || c > '9')
3504 				return (NULL);
3505 			pid = 10*pid + c - '0';
3506 			if (pid > maxpid)
3507 				return (NULL);
3508 		}
3509 	}
3510 
3511 	pnp = prgetnode(dp, PR_PIDDIR);
3512 
3513 	mutex_enter(&pidlock);
3514 	if ((p = prfind(pid)) == NULL || p->p_stat == SIDL) {
3515 		mutex_exit(&pidlock);
3516 		prfreenode(pnp);
3517 		return (NULL);
3518 	}
3519 	ASSERT(p->p_stat != 0);
3520 
3521 	/* NOTE: we're holding pidlock across the policy call. */
3522 	if (secpolicy_basic_procinfo(CRED(), p, curproc) != 0) {
3523 		mutex_exit(&pidlock);
3524 		prfreenode(pnp);
3525 		return (NULL);
3526 	}
3527 
3528 	mutex_enter(&p->p_lock);
3529 	mutex_exit(&pidlock);
3530 
3531 	/*
3532 	 * If a process vnode already exists and it is not invalid
3533 	 * and it was created by the current process and it belongs
3534 	 * to the same /proc mount point as our parent vnode, then
3535 	 * just use it and discard the newly-allocated prnode.
3536 	 */
3537 	for (vp = p->p_trace; vp != NULL; vp = VTOP(vp)->pr_next) {
3538 		if (!(VTOP(VTOP(vp)->pr_pidfile)->pr_flags & PR_INVAL) &&
3539 		    VTOP(vp)->pr_owner == curproc &&
3540 		    vp->v_vfsp == dp->v_vfsp) {
3541 			ASSERT(!(VTOP(vp)->pr_flags & PR_INVAL));
3542 			VN_HOLD(vp);
3543 			prfreenode(pnp);
3544 			mutex_exit(&p->p_lock);
3545 			return (vp);
3546 		}
3547 	}
3548 	pnp->pr_owner = curproc;
3549 
3550 	/*
3551 	 * prgetnode() initialized most of the prnode.
3552 	 * Finish the job.
3553 	 */
3554 	pcp = pnp->pr_common;	/* the newly-allocated prcommon struct */
3555 	if ((vp = p->p_trace) != NULL) {
3556 		/* discard the new prcommon and use the existing prcommon */
3557 		prfreecommon(pcp);
3558 		pcp = VTOP(vp)->pr_common;
3559 		mutex_enter(&pcp->prc_mutex);
3560 		ASSERT(pcp->prc_refcnt > 0);
3561 		pcp->prc_refcnt++;
3562 		mutex_exit(&pcp->prc_mutex);
3563 		pnp->pr_common = pcp;
3564 	} else {
3565 		/* initialize the new prcommon struct */
3566 		if ((p->p_flag & SSYS) || p->p_as == &kas)
3567 			pcp->prc_flags |= PRC_SYS;
3568 		if (p->p_stat == SZOMB)
3569 			pcp->prc_flags |= PRC_DESTROY;
3570 		pcp->prc_proc = p;
3571 		pcp->prc_datamodel = p->p_model;
3572 		pcp->prc_pid = p->p_pid;
3573 		pcp->prc_slot = p->p_slot;
3574 	}
3575 	pnp->pr_pcommon = pcp;
3576 	pnp->pr_parent = dp;
3577 	VN_HOLD(dp);
3578 	/*
3579 	 * Link in the old, invalid directory vnode so we
3580 	 * can later determine the last close of the file.
3581 	 */
3582 	pnp->pr_next = p->p_trace;
3583 	p->p_trace = dp = PTOV(pnp);
3584 
3585 	/*
3586 	 * Kludge for old /proc: initialize the PR_PIDFILE as well.
3587 	 */
3588 	vp = pnp->pr_pidfile;
3589 	pnp = VTOP(vp);
3590 	pnp->pr_ino = ptoi(pcp->prc_pid);
3591 	pnp->pr_common = pcp;
3592 	pnp->pr_pcommon = pcp;
3593 	pnp->pr_parent = dp;
3594 	pnp->pr_next = p->p_plist;
3595 	p->p_plist = vp;
3596 
3597 	mutex_exit(&p->p_lock);
3598 	return (dp);
3599 }
3600 
3601 static vnode_t *
3602 pr_lookup_piddir(vnode_t *dp, char *comp)
3603 {
3604 	prnode_t *dpnp = VTOP(dp);
3605 	vnode_t *vp;
3606 	prnode_t *pnp;
3607 	proc_t *p;
3608 	user_t *up;
3609 	prdirent_t *dirp;
3610 	int i;
3611 	enum prnodetype type;
3612 
3613 	ASSERT(dpnp->pr_type == PR_PIDDIR);
3614 
3615 	for (i = 0; i < NPIDDIRFILES; i++) {
3616 		/* Skip "." and ".." */
3617 		dirp = &piddir[i+2];
3618 		if (strcmp(comp, dirp->d_name) == 0)
3619 			break;
3620 	}
3621 
3622 	if (i >= NPIDDIRFILES)
3623 		return (NULL);
3624 
3625 	type = (int)dirp->d_ino;
3626 	pnp = prgetnode(dp, type);
3627 
3628 	p = pr_p_lock(dpnp);
3629 	mutex_exit(&pr_pidlock);
3630 	if (p == NULL) {
3631 		prfreenode(pnp);
3632 		return (NULL);
3633 	}
3634 	if (dpnp->pr_pcommon->prc_flags & PRC_DESTROY) {
3635 		switch (type) {
3636 		case PR_PSINFO:
3637 		case PR_USAGE:
3638 			break;
3639 		default:
3640 			prunlock(dpnp);
3641 			prfreenode(pnp);
3642 			return (NULL);
3643 		}
3644 	}
3645 
3646 	switch (type) {
3647 	case PR_CURDIR:
3648 	case PR_ROOTDIR:
3649 		up = PTOU(p);
3650 		vp = (type == PR_CURDIR)? up->u_cdir :
3651 		    (up->u_rdir? up->u_rdir : rootdir);
3652 
3653 		if (vp == NULL) {	/* can't happen? */
3654 			prunlock(dpnp);
3655 			prfreenode(pnp);
3656 			return (NULL);
3657 		}
3658 		/*
3659 		 * Fill in the prnode so future references will
3660 		 * be able to find the underlying object's vnode.
3661 		 */
3662 		VN_HOLD(vp);
3663 		pnp->pr_realvp = vp;
3664 		break;
3665 	default:
3666 		break;
3667 	}
3668 
3669 	mutex_enter(&dpnp->pr_mutex);
3670 
3671 	if ((vp = dpnp->pr_files[i]) != NULL &&
3672 	    !(VTOP(vp)->pr_flags & PR_INVAL)) {
3673 		VN_HOLD(vp);
3674 		mutex_exit(&dpnp->pr_mutex);
3675 		prunlock(dpnp);
3676 		prfreenode(pnp);
3677 		return (vp);
3678 	}
3679 
3680 	/*
3681 	 * prgetnode() initialized most of the prnode.
3682 	 * Finish the job.
3683 	 */
3684 	pnp->pr_common = dpnp->pr_common;
3685 	pnp->pr_pcommon = dpnp->pr_pcommon;
3686 	pnp->pr_parent = dp;
3687 	VN_HOLD(dp);
3688 	pnp->pr_index = i;
3689 
3690 	dpnp->pr_files[i] = vp = PTOV(pnp);
3691 
3692 	/*
3693 	 * Link new vnode into list of all /proc vnodes for the process.
3694 	 */
3695 	if (vp->v_type == VPROC) {
3696 		pnp->pr_next = p->p_plist;
3697 		p->p_plist = vp;
3698 	}
3699 	mutex_exit(&dpnp->pr_mutex);
3700 	prunlock(dpnp);
3701 	return (vp);
3702 }
3703 
3704 static vnode_t *
3705 pr_lookup_objectdir(vnode_t *dp, char *comp)
3706 {
3707 	prnode_t *dpnp = VTOP(dp);
3708 	prnode_t *pnp;
3709 	proc_t *p;
3710 	struct seg *seg;
3711 	struct as *as;
3712 	vnode_t *vp;
3713 	vattr_t vattr;
3714 
3715 	ASSERT(dpnp->pr_type == PR_OBJECTDIR);
3716 
3717 	pnp = prgetnode(dp, PR_OBJECT);
3718 
3719 	if (prlock(dpnp, ZNO) != 0) {
3720 		prfreenode(pnp);
3721 		return (NULL);
3722 	}
3723 	p = dpnp->pr_common->prc_proc;
3724 	if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
3725 		prunlock(dpnp);
3726 		prfreenode(pnp);
3727 		return (NULL);
3728 	}
3729 
3730 	/*
3731 	 * We drop p_lock before grabbing the address space lock
3732 	 * in order to avoid a deadlock with the clock thread.
3733 	 * The process will not disappear and its address space
3734 	 * will not change because it is marked P_PR_LOCK.
3735 	 */
3736 	mutex_exit(&p->p_lock);
3737 	AS_LOCK_ENTER(as, RW_READER);
3738 	if ((seg = AS_SEGFIRST(as)) == NULL) {
3739 		vp = NULL;
3740 		goto out;
3741 	}
3742 	if (strcmp(comp, "a.out") == 0) {
3743 		vp = p->p_exec;
3744 		goto out;
3745 	}
3746 	do {
3747 		/*
3748 		 * Manufacture a filename for the "object" directory.
3749 		 */
3750 		vattr.va_mask = AT_FSID|AT_NODEID;
3751 		if (seg->s_ops == &segvn_ops &&
3752 		    SEGOP_GETVP(seg, seg->s_base, &vp) == 0 &&
3753 		    vp != NULL && vp->v_type == VREG &&
3754 		    VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
3755 			char name[64];
3756 
3757 			if (vp == p->p_exec)	/* "a.out" */
3758 				continue;
3759 			pr_object_name(name, vp, &vattr);
3760 			if (strcmp(name, comp) == 0)
3761 				goto out;
3762 		}
3763 	} while ((seg = AS_SEGNEXT(as, seg)) != NULL);
3764 
3765 	vp = NULL;
3766 out:
3767 	if (vp != NULL) {
3768 		VN_HOLD(vp);
3769 	}
3770 	AS_LOCK_EXIT(as);
3771 	mutex_enter(&p->p_lock);
3772 	prunlock(dpnp);
3773 
3774 	if (vp == NULL)
3775 		prfreenode(pnp);
3776 	else {
3777 		/*
3778 		 * Fill in the prnode so future references will
3779 		 * be able to find the underlying object's vnode.
3780 		 * Don't link this prnode into the list of all
3781 		 * prnodes for the process; this is a one-use node.
3782 		 * Its use is entirely to catch and fail opens for writing.
3783 		 */
3784 		pnp->pr_realvp = vp;
3785 		vp = PTOV(pnp);
3786 	}
3787 
3788 	return (vp);
3789 }
3790 
3791 /*
3792  * Find or construct an lwp vnode for the given lwpid.
3793  */
3794 static vnode_t *
3795 pr_lookup_lwpdir(vnode_t *dp, char *comp)
3796 {
3797 	id_t tid;	/* same type as t->t_tid */
3798 	int want_agent;
3799 	prnode_t *dpnp = VTOP(dp);
3800 	prnode_t *pnp;
3801 	prcommon_t *pcp;
3802 	vnode_t *vp;
3803 	proc_t *p;
3804 	kthread_t *t;
3805 	lwpdir_t *ldp;
3806 	lwpent_t *lep;
3807 	int tslot;
3808 	int c;
3809 
3810 	ASSERT(dpnp->pr_type == PR_LWPDIR);
3811 
3812 	tid = 0;
3813 	if (strcmp(comp, "agent") == 0)
3814 		want_agent = 1;
3815 	else {
3816 		want_agent = 0;
3817 		while ((c = *comp++) != '\0') {
3818 			id_t otid;
3819 
3820 			if (c < '0' || c > '9')
3821 				return (NULL);
3822 			otid = tid;
3823 			tid = 10*tid + c - '0';
3824 			if (tid/10 != otid)	/* integer overflow */
3825 				return (NULL);
3826 		}
3827 	}
3828 
3829 	pnp = prgetnode(dp, PR_LWPIDDIR);
3830 
3831 	p = pr_p_lock(dpnp);
3832 	mutex_exit(&pr_pidlock);
3833 	if (p == NULL) {
3834 		prfreenode(pnp);
3835 		return (NULL);
3836 	}
3837 
3838 	if (want_agent) {
3839 		if ((t = p->p_agenttp) == NULL)
3840 			lep = NULL;
3841 		else {
3842 			tid = t->t_tid;
3843 			tslot = t->t_dslot;
3844 			lep = p->p_lwpdir[tslot].ld_entry;
3845 		}
3846 	} else {
3847 		if ((ldp = lwp_hash_lookup(p, tid)) == NULL)
3848 			lep = NULL;
3849 		else {
3850 			tslot = (int)(ldp - p->p_lwpdir);
3851 			lep = ldp->ld_entry;
3852 		}
3853 	}
3854 
3855 	if (lep == NULL) {
3856 		prunlock(dpnp);
3857 		prfreenode(pnp);
3858 		return (NULL);
3859 	}
3860 
3861 	/*
3862 	 * If an lwp vnode already exists and it is not invalid
3863 	 * and it was created by the current process and it belongs
3864 	 * to the same /proc mount point as our parent vnode, then
3865 	 * just use it and discard the newly-allocated prnode.
3866 	 */
3867 	for (vp = lep->le_trace; vp != NULL; vp = VTOP(vp)->pr_next) {
3868 		if (!(VTOP(vp)->pr_flags & PR_INVAL) &&
3869 		    VTOP(vp)->pr_owner == curproc &&
3870 		    vp->v_vfsp == dp->v_vfsp) {
3871 			VN_HOLD(vp);
3872 			prunlock(dpnp);
3873 			prfreenode(pnp);
3874 			return (vp);
3875 		}
3876 	}
3877 	pnp->pr_owner = curproc;
3878 
3879 	/*
3880 	 * prgetnode() initialized most of the prnode.
3881 	 * Finish the job.
3882 	 */
3883 	pcp = pnp->pr_common;	/* the newly-allocated prcommon struct */
3884 	if ((vp = lep->le_trace) != NULL) {
3885 		/* discard the new prcommon and use the existing prcommon */
3886 		prfreecommon(pcp);
3887 		pcp = VTOP(vp)->pr_common;
3888 		mutex_enter(&pcp->prc_mutex);
3889 		ASSERT(pcp->prc_refcnt > 0);
3890 		pcp->prc_refcnt++;
3891 		mutex_exit(&pcp->prc_mutex);
3892 		pnp->pr_common = pcp;
3893 	} else {
3894 		/* initialize the new prcommon struct */
3895 		pcp->prc_flags |= PRC_LWP;
3896 		if ((p->p_flag & SSYS) || p->p_as == &kas)
3897 			pcp->prc_flags |= PRC_SYS;
3898 		if ((t = lep->le_thread) == NULL)
3899 			pcp->prc_flags |= PRC_DESTROY;
3900 		pcp->prc_proc = p;
3901 		pcp->prc_datamodel = dpnp->pr_pcommon->prc_datamodel;
3902 		pcp->prc_pid = p->p_pid;
3903 		pcp->prc_slot = p->p_slot;
3904 		pcp->prc_thread = t;
3905 		pcp->prc_tid = tid;
3906 		pcp->prc_tslot = tslot;
3907 	}
3908 	pnp->pr_pcommon = dpnp->pr_pcommon;
3909 	pnp->pr_parent = dp;
3910 	VN_HOLD(dp);
3911 	/*
3912 	 * Link in the old, invalid directory vnode so we
3913 	 * can later determine the last close of the file.
3914 	 */
3915 	pnp->pr_next = lep->le_trace;
3916 	lep->le_trace = vp = PTOV(pnp);
3917 	prunlock(dpnp);
3918 	return (vp);
3919 }
3920 
3921 static vnode_t *
3922 pr_lookup_lwpiddir(vnode_t *dp, char *comp)
3923 {
3924 	prnode_t *dpnp = VTOP(dp);
3925 	vnode_t *vp;
3926 	prnode_t *pnp;
3927 	proc_t *p;
3928 	prdirent_t *dirp;
3929 	int i;
3930 	enum prnodetype type;
3931 
3932 	ASSERT(dpnp->pr_type == PR_LWPIDDIR);
3933 
3934 	for (i = 0; i < NLWPIDDIRFILES; i++) {
3935 		/* Skip "." and ".." */
3936 		dirp = &lwpiddir[i+2];
3937 		if (strcmp(comp, dirp->d_name) == 0)
3938 			break;
3939 	}
3940 
3941 	if (i >= NLWPIDDIRFILES)
3942 		return (NULL);
3943 
3944 	type = (int)dirp->d_ino;
3945 	pnp = prgetnode(dp, type);
3946 
3947 	p = pr_p_lock(dpnp);
3948 	mutex_exit(&pr_pidlock);
3949 	if (p == NULL) {
3950 		prfreenode(pnp);
3951 		return (NULL);
3952 	}
3953 	if (dpnp->pr_common->prc_flags & PRC_DESTROY) {
3954 		/*
3955 		 * Only the lwpsinfo file is present for zombie lwps.
3956 		 * Nothing is present if the lwp has been reaped.
3957 		 */
3958 		if (dpnp->pr_common->prc_tslot == -1 ||
3959 		    type != PR_LWPSINFO) {
3960 			prunlock(dpnp);
3961 			prfreenode(pnp);
3962 			return (NULL);
3963 		}
3964 	}
3965 
3966 #if defined(__sparc)
3967 	/* the asrs file exists only for sparc v9 _LP64 processes */
3968 	if (type == PR_ASRS && p->p_model != DATAMODEL_LP64) {
3969 		prunlock(dpnp);
3970 		prfreenode(pnp);
3971 		return (NULL);
3972 	}
3973 #endif
3974 
3975 	mutex_enter(&dpnp->pr_mutex);
3976 
3977 	if ((vp = dpnp->pr_files[i]) != NULL &&
3978 	    !(VTOP(vp)->pr_flags & PR_INVAL)) {
3979 		VN_HOLD(vp);
3980 		mutex_exit(&dpnp->pr_mutex);
3981 		prunlock(dpnp);
3982 		prfreenode(pnp);
3983 		return (vp);
3984 	}
3985 
3986 	/*
3987 	 * prgetnode() initialized most of the prnode.
3988 	 * Finish the job.
3989 	 */
3990 	pnp->pr_common = dpnp->pr_common;
3991 	pnp->pr_pcommon = dpnp->pr_pcommon;
3992 	pnp->pr_parent = dp;
3993 	VN_HOLD(dp);
3994 	pnp->pr_index = i;
3995 
3996 	dpnp->pr_files[i] = vp = PTOV(pnp);
3997 
3998 	/*
3999 	 * Link new vnode into list of all /proc vnodes for the process.
4000 	 */
4001 	if (vp->v_type == VPROC) {
4002 		pnp->pr_next = p->p_plist;
4003 		p->p_plist = vp;
4004 	}
4005 	mutex_exit(&dpnp->pr_mutex);
4006 	prunlock(dpnp);
4007 	return (vp);
4008 }
4009 
4010 /*
4011  * Lookup one of the process's open files.
4012  */
4013 static vnode_t *
4014 pr_lookup_fddir(vnode_t *dp, char *comp)
4015 {
4016 	prnode_t *dpnp = VTOP(dp);
4017 	prnode_t *pnp;
4018 	vnode_t *vp = NULL;
4019 	proc_t *p;
4020 	file_t *fp;
4021 	uint_t fd;
4022 	int c;
4023 	uf_entry_t *ufp;
4024 	uf_info_t *fip;
4025 
4026 	ASSERT(dpnp->pr_type == PR_FDDIR);
4027 
4028 	fd = 0;
4029 	while ((c = *comp++) != '\0') {
4030 		int ofd;
4031 		if (c < '0' || c > '9')
4032 			return (NULL);
4033 		ofd = fd;
4034 		fd = 10*fd + c - '0';
4035 		if (fd/10 != ofd)	/* integer overflow */
4036 			return (NULL);
4037 	}
4038 
4039 	pnp = prgetnode(dp, PR_FD);
4040 
4041 	if (prlock(dpnp, ZNO) != 0) {
4042 		prfreenode(pnp);
4043 		return (NULL);
4044 	}
4045 	p = dpnp->pr_common->prc_proc;
4046 	if ((p->p_flag & SSYS) || p->p_as == &kas) {
4047 		prunlock(dpnp);
4048 		prfreenode(pnp);
4049 		return (NULL);
4050 	}
4051 
4052 	fip = P_FINFO(p);
4053 	mutex_exit(&p->p_lock);
4054 	mutex_enter(&fip->fi_lock);
4055 	if (fd < fip->fi_nfiles) {
4056 		UF_ENTER(ufp, fip, fd);
4057 		if ((fp = ufp->uf_file) != NULL) {
4058 			pnp->pr_mode = 07111;
4059 			if (fp->f_flag & FREAD)
4060 				pnp->pr_mode |= 0444;
4061 			if (fp->f_flag & FWRITE)
4062 				pnp->pr_mode |= 0222;
4063 			vp = fp->f_vnode;
4064 			VN_HOLD(vp);
4065 		}
4066 		UF_EXIT(ufp);
4067 	}
4068 	mutex_exit(&fip->fi_lock);
4069 	mutex_enter(&p->p_lock);
4070 	prunlock(dpnp);
4071 
4072 	if (vp == NULL)
4073 		prfreenode(pnp);
4074 	else {
4075 		/*
4076 		 * Fill in the prnode so future references will
4077 		 * be able to find the underlying object's vnode.
4078 		 * Don't link this prnode into the list of all
4079 		 * prnodes for the process; this is a one-use node.
4080 		 */
4081 		pnp->pr_realvp = vp;
4082 		pnp->pr_parent = dp;		/* needed for prlookup */
4083 		VN_HOLD(dp);
4084 		vp = PTOV(pnp);
4085 		if (pnp->pr_realvp->v_type == VDIR)
4086 			vp->v_type = VDIR;
4087 	}
4088 
4089 	return (vp);
4090 }
4091 
4092 static vnode_t *
4093 pr_lookup_pathdir(vnode_t *dp, char *comp)
4094 {
4095 	prnode_t *dpnp = VTOP(dp);
4096 	prnode_t *pnp;
4097 	vnode_t *vp = NULL;
4098 	proc_t *p;
4099 	uint_t fd, flags = 0;
4100 	int c;
4101 	uf_entry_t *ufp;
4102 	uf_info_t *fip;
4103 	enum { NAME_FD, NAME_OBJECT, NAME_ROOT, NAME_CWD, NAME_UNKNOWN } type;
4104 	char *tmp;
4105 	int idx;
4106 	struct seg *seg;
4107 	struct as *as = NULL;
4108 	vattr_t vattr;
4109 
4110 	ASSERT(dpnp->pr_type == PR_PATHDIR);
4111 
4112 	/*
4113 	 * First, check if this is a numeric entry, in which case we have a
4114 	 * file descriptor.
4115 	 */
4116 	fd = 0;
4117 	type = NAME_FD;
4118 	tmp = comp;
4119 	while ((c = *tmp++) != '\0') {
4120 		int ofd;
4121 		if (c < '0' || c > '9') {
4122 			type = NAME_UNKNOWN;
4123 			break;
4124 		}
4125 		ofd = fd;
4126 		fd = 10*fd + c - '0';
4127 		if (fd/10 != ofd) {	/* integer overflow */
4128 			type = NAME_UNKNOWN;
4129 			break;
4130 		}
4131 	}
4132 
4133 	/*
4134 	 * Next, see if it is one of the special values {root, cwd}.
4135 	 */
4136 	if (type == NAME_UNKNOWN) {
4137 		if (strcmp(comp, "root") == 0)
4138 			type = NAME_ROOT;
4139 		else if (strcmp(comp, "cwd") == 0)
4140 			type = NAME_CWD;
4141 	}
4142 
4143 	/*
4144 	 * Grab the necessary data from the process
4145 	 */
4146 	if (prlock(dpnp, ZNO) != 0)
4147 		return (NULL);
4148 	p = dpnp->pr_common->prc_proc;
4149 
4150 	fip = P_FINFO(p);
4151 
4152 	switch (type) {
4153 	case NAME_ROOT:
4154 		if ((vp = PTOU(p)->u_rdir) == NULL)
4155 			vp = p->p_zone->zone_rootvp;
4156 		VN_HOLD(vp);
4157 		break;
4158 	case NAME_CWD:
4159 		vp = PTOU(p)->u_cdir;
4160 		VN_HOLD(vp);
4161 		break;
4162 	default:
4163 		if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
4164 			prunlock(dpnp);
4165 			return (NULL);
4166 		}
4167 	}
4168 	mutex_exit(&p->p_lock);
4169 
4170 	/*
4171 	 * Determine if this is an object entry
4172 	 */
4173 	if (type == NAME_UNKNOWN) {
4174 		/*
4175 		 * Start with the inode index immediately after the number of
4176 		 * files.
4177 		 */
4178 		mutex_enter(&fip->fi_lock);
4179 		idx = fip->fi_nfiles + 4;
4180 		mutex_exit(&fip->fi_lock);
4181 
4182 		if (strcmp(comp, "a.out") == 0) {
4183 			if (p->p_execdir != NULL) {
4184 				vp = p->p_execdir;
4185 				VN_HOLD(vp);
4186 				type = NAME_OBJECT;
4187 				flags |= PR_AOUT;
4188 			} else {
4189 				vp = p->p_exec;
4190 				VN_HOLD(vp);
4191 				type = NAME_OBJECT;
4192 			}
4193 		} else {
4194 			AS_LOCK_ENTER(as, RW_READER);
4195 			if ((seg = AS_SEGFIRST(as)) != NULL) {
4196 				do {
4197 					/*
4198 					 * Manufacture a filename for the
4199 					 * "object" directory.
4200 					 */
4201 					vattr.va_mask = AT_FSID|AT_NODEID;
4202 					if (seg->s_ops == &segvn_ops &&
4203 					    SEGOP_GETVP(seg, seg->s_base, &vp)
4204 					    == 0 &&
4205 					    vp != NULL && vp->v_type == VREG &&
4206 					    VOP_GETATTR(vp, &vattr, 0, CRED(),
4207 					    NULL) == 0) {
4208 						char name[64];
4209 
4210 						if (vp == p->p_exec)
4211 							continue;
4212 						idx++;
4213 						pr_object_name(name, vp,
4214 						    &vattr);
4215 						if (strcmp(name, comp) == 0)
4216 							break;
4217 					}
4218 				} while ((seg = AS_SEGNEXT(as, seg)) != NULL);
4219 			}
4220 
4221 			if (seg == NULL) {
4222 				vp = NULL;
4223 			} else {
4224 				VN_HOLD(vp);
4225 				type = NAME_OBJECT;
4226 			}
4227 
4228 			AS_LOCK_EXIT(as);
4229 		}
4230 	}
4231 
4232 
4233 	switch (type) {
4234 	case NAME_FD:
4235 		mutex_enter(&fip->fi_lock);
4236 		if (fd < fip->fi_nfiles) {
4237 			UF_ENTER(ufp, fip, fd);
4238 			if (ufp->uf_file != NULL) {
4239 				vp = ufp->uf_file->f_vnode;
4240 				VN_HOLD(vp);
4241 			}
4242 			UF_EXIT(ufp);
4243 		}
4244 		mutex_exit(&fip->fi_lock);
4245 		idx = fd + 4;
4246 		break;
4247 	case NAME_ROOT:
4248 		idx = 2;
4249 		break;
4250 	case NAME_CWD:
4251 		idx = 3;
4252 		break;
4253 	case NAME_OBJECT:
4254 	case NAME_UNKNOWN:
4255 		/* Nothing to do */
4256 		break;
4257 	}
4258 
4259 	mutex_enter(&p->p_lock);
4260 	prunlock(dpnp);
4261 
4262 	if (vp != NULL) {
4263 		pnp = prgetnode(dp, PR_PATH);
4264 
4265 		pnp->pr_flags |= flags;
4266 		pnp->pr_common = dpnp->pr_common;
4267 		pnp->pr_pcommon = dpnp->pr_pcommon;
4268 		pnp->pr_realvp = vp;
4269 		pnp->pr_parent = dp;		/* needed for prlookup */
4270 		pnp->pr_ino = pmkino(idx, dpnp->pr_common->prc_slot, PR_PATH);
4271 		VN_HOLD(dp);
4272 		vp = PTOV(pnp);
4273 		vp->v_type = VLNK;
4274 	}
4275 
4276 	return (vp);
4277 }
4278 
4279 /*
4280  * Look up one of the process's active templates.
4281  */
4282 static vnode_t *
4283 pr_lookup_tmpldir(vnode_t *dp, char *comp)
4284 {
4285 	prnode_t *dpnp = VTOP(dp);
4286 	prnode_t *pnp;
4287 	vnode_t *vp = NULL;
4288 	proc_t *p;
4289 	int i;
4290 
4291 	ASSERT(dpnp->pr_type == PR_TMPLDIR);
4292 
4293 	for (i = 0; i < ct_ntypes; i++)
4294 		if (strcmp(comp, ct_types[i]->ct_type_name) == 0)
4295 			break;
4296 	if (i == ct_ntypes)
4297 		return (NULL);
4298 
4299 	pnp = prgetnode(dp, PR_TMPL);
4300 
4301 	if (prlock(dpnp, ZNO) != 0) {
4302 		prfreenode(pnp);
4303 		return (NULL);
4304 	}
4305 	p = dpnp->pr_common->prc_proc;
4306 	if ((p->p_flag & SSYS) || p->p_as == &kas ||
4307 	    (dpnp->pr_common->prc_flags & (PRC_DESTROY | PRC_LWP)) != PRC_LWP) {
4308 		prunlock(dpnp);
4309 		prfreenode(pnp);
4310 		return (NULL);
4311 	}
4312 	if (ttolwp(dpnp->pr_common->prc_thread)->lwp_ct_active[i] != NULL) {
4313 		pnp->pr_common = dpnp->pr_common;
4314 		pnp->pr_pcommon = dpnp->pr_pcommon;
4315 		pnp->pr_parent = dp;
4316 		pnp->pr_cttype = i;
4317 		VN_HOLD(dp);
4318 		vp = PTOV(pnp);
4319 	} else {
4320 		prfreenode(pnp);
4321 	}
4322 	prunlock(dpnp);
4323 
4324 	return (vp);
4325 }
4326 
4327 /*
4328  * Look up one of the contracts owned by the process.
4329  */
4330 static vnode_t *
4331 pr_lookup_ctdir(vnode_t *dp, char *comp)
4332 {
4333 	prnode_t *dpnp = VTOP(dp);
4334 	prnode_t *pnp;
4335 	vnode_t *vp = NULL;
4336 	proc_t *p;
4337 	id_t id = 0;
4338 	contract_t *ct;
4339 	int c;
4340 
4341 	ASSERT(dpnp->pr_type == PR_CTDIR);
4342 
4343 	while ((c = *comp++) != '\0') {
4344 		id_t oid;
4345 		if (c < '0' || c > '9')
4346 			return (NULL);
4347 		oid = id;
4348 		id = 10 * id + c - '0';
4349 		if (id / 10 != oid)	/* integer overflow */
4350 			return (NULL);
4351 	}
4352 
4353 	/*
4354 	 * Search all contracts; we'll filter below.
4355 	 */
4356 	ct = contract_ptr(id, GLOBAL_ZONEUNIQID);
4357 	if (ct == NULL)
4358 		return (NULL);
4359 
4360 	pnp = prgetnode(dp, PR_CT);
4361 
4362 	if (prlock(dpnp, ZNO) != 0) {
4363 		prfreenode(pnp);
4364 		contract_rele(ct);
4365 		return (NULL);
4366 	}
4367 	p = dpnp->pr_common->prc_proc;
4368 	/*
4369 	 * We only allow lookups of contracts owned by this process, or,
4370 	 * if we are zsched and this is a zone's procfs, contracts on
4371 	 * stuff in the zone which are held by processes or contracts
4372 	 * outside the zone.  (see logic in contract_status_common)
4373 	 */
4374 	if ((ct->ct_owner != p) &&
4375 	    !(p == VTOZONE(dp)->zone_zsched && ct->ct_state < CTS_ORPHAN &&
4376 	    VTOZONE(dp)->zone_uniqid == contract_getzuniqid(ct) &&
4377 	    VTOZONE(dp)->zone_uniqid != GLOBAL_ZONEUNIQID &&
4378 	    ct->ct_czuniqid == GLOBAL_ZONEUNIQID)) {
4379 		prunlock(dpnp);
4380 		prfreenode(pnp);
4381 		contract_rele(ct);
4382 		return (NULL);
4383 	}
4384 	pnp->pr_common = dpnp->pr_common;
4385 	pnp->pr_pcommon = dpnp->pr_pcommon;
4386 	pnp->pr_contract = ct;
4387 	pnp->pr_parent = dp;
4388 	pnp->pr_ino = pmkino(id, pnp->pr_common->prc_slot, PR_CT);
4389 	VN_HOLD(dp);
4390 	prunlock(dpnp);
4391 	vp = PTOV(pnp);
4392 
4393 	return (vp);
4394 }
4395 
4396 /*
4397  * Construct an lwp vnode for the old /proc interface.
4398  * We stand on our head to make the /proc plumbing correct.
4399  */
4400 vnode_t *
4401 prlwpnode(prnode_t *pnp, uint_t tid)
4402 {
4403 	char comp[12];
4404 	vnode_t *dp;
4405 	vnode_t *vp;
4406 	prcommon_t *pcp;
4407 	proc_t *p;
4408 
4409 	/*
4410 	 * Lookup the /proc/<pid>/lwp/<lwpid> directory vnode.
4411 	 */
4412 	if (pnp->pr_type == PR_PIDFILE) {
4413 		dp = pnp->pr_parent;		/* /proc/<pid> */
4414 		VN_HOLD(dp);
4415 		vp = pr_lookup_piddir(dp, "lwp");
4416 		VN_RELE(dp);
4417 		if ((dp = vp) == NULL)		/* /proc/<pid>/lwp */
4418 			return (NULL);
4419 	} else if (pnp->pr_type == PR_LWPIDFILE) {
4420 		dp = pnp->pr_parent;		/* /proc/<pid>/lwp/<lwpid> */
4421 		dp = VTOP(dp)->pr_parent;	/* /proc/<pid>/lwp */
4422 		VN_HOLD(dp);
4423 	} else {
4424 		return (NULL);
4425 	}
4426 
4427 	(void) pr_u32tos(tid, comp, sizeof (comp));
4428 	vp = pr_lookup_lwpdir(dp, comp);
4429 	VN_RELE(dp);
4430 	if ((dp = vp) == NULL)
4431 		return (NULL);
4432 
4433 	pnp = prgetnode(dp, PR_LWPIDFILE);
4434 	vp = PTOV(pnp);
4435 
4436 	/*
4437 	 * prgetnode() initialized most of the prnode.
4438 	 * Finish the job.
4439 	 */
4440 	pcp = VTOP(dp)->pr_common;
4441 	pnp->pr_ino = ptoi(pcp->prc_pid);
4442 	pnp->pr_common = pcp;
4443 	pnp->pr_pcommon = VTOP(dp)->pr_pcommon;
4444 	pnp->pr_parent = dp;
4445 	/*
4446 	 * Link new vnode into list of all /proc vnodes for the process.
4447 	 */
4448 	p = pr_p_lock(pnp);
4449 	mutex_exit(&pr_pidlock);
4450 	if (p == NULL) {
4451 		VN_RELE(dp);
4452 		prfreenode(pnp);
4453 		vp = NULL;
4454 	} else if (pcp->prc_thread == NULL) {
4455 		prunlock(pnp);
4456 		VN_RELE(dp);
4457 		prfreenode(pnp);
4458 		vp = NULL;
4459 	} else {
4460 		pnp->pr_next = p->p_plist;
4461 		p->p_plist = vp;
4462 		prunlock(pnp);
4463 	}
4464 
4465 	return (vp);
4466 }
4467 
4468 #if defined(DEBUG)
4469 
4470 static	uint32_t nprnode;
4471 static	uint32_t nprcommon;
4472 
4473 #define	INCREMENT(x)	atomic_inc_32(&x);
4474 #define	DECREMENT(x)	atomic_dec_32(&x);
4475 
4476 #else
4477 
4478 #define	INCREMENT(x)
4479 #define	DECREMENT(x)
4480 
4481 #endif	/* DEBUG */
4482 
4483 /*
4484  * New /proc vnode required; allocate it and fill in most of the fields.
4485  */
4486 prnode_t *
4487 prgetnode(vnode_t *dp, prnodetype_t type)
4488 {
4489 	prnode_t *pnp;
4490 	prcommon_t *pcp;
4491 	vnode_t *vp;
4492 	ulong_t nfiles;
4493 
4494 	INCREMENT(nprnode);
4495 	pnp = kmem_zalloc(sizeof (prnode_t), KM_SLEEP);
4496 
4497 	mutex_init(&pnp->pr_mutex, NULL, MUTEX_DEFAULT, NULL);
4498 	pnp->pr_type = type;
4499 
4500 	pnp->pr_vnode = vn_alloc(KM_SLEEP);
4501 
4502 	vp = PTOV(pnp);
4503 	vp->v_flag = VNOCACHE|VNOMAP|VNOSWAP|VNOMOUNT;
4504 	vn_setops(vp, prvnodeops);
4505 	vp->v_vfsp = dp->v_vfsp;
4506 	vp->v_type = VPROC;
4507 	vp->v_data = (caddr_t)pnp;
4508 
4509 	switch (type) {
4510 	case PR_PIDDIR:
4511 	case PR_LWPIDDIR:
4512 		/*
4513 		 * We need a prcommon and a files array for each of these.
4514 		 */
4515 		INCREMENT(nprcommon);
4516 
4517 		pcp = kmem_zalloc(sizeof (prcommon_t), KM_SLEEP);
4518 		pcp->prc_refcnt = 1;
4519 		pnp->pr_common = pcp;
4520 		mutex_init(&pcp->prc_mutex, NULL, MUTEX_DEFAULT, NULL);
4521 		cv_init(&pcp->prc_wait, NULL, CV_DEFAULT, NULL);
4522 
4523 		nfiles = (type == PR_PIDDIR)? NPIDDIRFILES : NLWPIDDIRFILES;
4524 		pnp->pr_files =
4525 		    kmem_zalloc(nfiles * sizeof (vnode_t *), KM_SLEEP);
4526 
4527 		vp->v_type = VDIR;
4528 		/*
4529 		 * Mode should be read-search by all, but we cannot so long
4530 		 * as we must support compatibility mode with old /proc.
4531 		 * Make /proc/<pid> be read by owner only, search by all.
4532 		 * Make /proc/<pid>/lwp/<lwpid> read-search by all.  Also,
4533 		 * set VDIROPEN on /proc/<pid> so it can be opened for writing.
4534 		 */
4535 		if (type == PR_PIDDIR) {
4536 			/* kludge for old /proc interface */
4537 			prnode_t *xpnp = prgetnode(dp, PR_PIDFILE);
4538 			pnp->pr_pidfile = PTOV(xpnp);
4539 			pnp->pr_mode = 0511;
4540 			vp->v_flag |= VDIROPEN;
4541 		} else {
4542 			pnp->pr_mode = 0555;
4543 		}
4544 
4545 		break;
4546 
4547 	case PR_CURDIR:
4548 	case PR_ROOTDIR:
4549 	case PR_FDDIR:
4550 	case PR_OBJECTDIR:
4551 	case PR_PATHDIR:
4552 	case PR_CTDIR:
4553 	case PR_TMPLDIR:
4554 		vp->v_type = VDIR;
4555 		pnp->pr_mode = 0500;	/* read-search by owner only */
4556 		break;
4557 
4558 	case PR_CT:
4559 		vp->v_type = VLNK;
4560 		pnp->pr_mode = 0500;	/* read-search by owner only */
4561 		break;
4562 
4563 	case PR_PATH:
4564 	case PR_SELF:
4565 		vp->v_type = VLNK;
4566 		pnp->pr_mode = 0777;
4567 		break;
4568 
4569 	case PR_LWPDIR:
4570 		vp->v_type = VDIR;
4571 		pnp->pr_mode = 0555;	/* read-search by all */
4572 		break;
4573 
4574 	case PR_AS:
4575 	case PR_TMPL:
4576 		pnp->pr_mode = 0600;	/* read-write by owner only */
4577 		break;
4578 
4579 	case PR_CTL:
4580 	case PR_LWPCTL:
4581 		pnp->pr_mode = 0200;	/* write-only by owner only */
4582 		break;
4583 
4584 	case PR_PIDFILE:
4585 	case PR_LWPIDFILE:
4586 		pnp->pr_mode = 0600;	/* read-write by owner only */
4587 		break;
4588 
4589 	case PR_PSINFO:
4590 	case PR_LPSINFO:
4591 	case PR_LWPSINFO:
4592 	case PR_USAGE:
4593 	case PR_LUSAGE:
4594 	case PR_LWPUSAGE:
4595 		pnp->pr_mode = 0444;	/* read-only by all */
4596 		break;
4597 
4598 	default:
4599 		pnp->pr_mode = 0400;	/* read-only by owner only */
4600 		break;
4601 	}
4602 	vn_exists(vp);
4603 	return (pnp);
4604 }
4605 
4606 /*
4607  * Free the storage obtained from prgetnode().
4608  */
4609 void
4610 prfreenode(prnode_t *pnp)
4611 {
4612 	vnode_t *vp;
4613 	ulong_t nfiles;
4614 
4615 	vn_invalid(PTOV(pnp));
4616 	vn_free(PTOV(pnp));
4617 	mutex_destroy(&pnp->pr_mutex);
4618 
4619 	switch (pnp->pr_type) {
4620 	case PR_PIDDIR:
4621 		/* kludge for old /proc interface */
4622 		if (pnp->pr_pidfile != NULL) {
4623 			prfreenode(VTOP(pnp->pr_pidfile));
4624 			pnp->pr_pidfile = NULL;
4625 		}
4626 		/* FALLTHROUGH */
4627 	case PR_LWPIDDIR:
4628 		/*
4629 		 * We allocated a prcommon and a files array for each of these.
4630 		 */
4631 		prfreecommon(pnp->pr_common);
4632 		nfiles = (pnp->pr_type == PR_PIDDIR)?
4633 		    NPIDDIRFILES : NLWPIDDIRFILES;
4634 		kmem_free(pnp->pr_files, nfiles * sizeof (vnode_t *));
4635 		break;
4636 	default:
4637 		break;
4638 	}
4639 	/*
4640 	 * If there is an underlying vnode, be sure
4641 	 * to release it after freeing the prnode.
4642 	 */
4643 	vp = pnp->pr_realvp;
4644 	kmem_free(pnp, sizeof (*pnp));
4645 	DECREMENT(nprnode);
4646 	if (vp != NULL) {
4647 		VN_RELE(vp);
4648 	}
4649 }
4650 
4651 /*
4652  * Free a prcommon structure, if the reference count reaches zero.
4653  */
4654 static void
4655 prfreecommon(prcommon_t *pcp)
4656 {
4657 	mutex_enter(&pcp->prc_mutex);
4658 	ASSERT(pcp->prc_refcnt > 0);
4659 	if (--pcp->prc_refcnt != 0)
4660 		mutex_exit(&pcp->prc_mutex);
4661 	else {
4662 		mutex_exit(&pcp->prc_mutex);
4663 		ASSERT(pcp->prc_pollhead.ph_list == NULL);
4664 		ASSERT(pcp->prc_refcnt == 0);
4665 		ASSERT(pcp->prc_selfopens == 0 && pcp->prc_writers == 0);
4666 		mutex_destroy(&pcp->prc_mutex);
4667 		cv_destroy(&pcp->prc_wait);
4668 		kmem_free(pcp, sizeof (prcommon_t));
4669 		DECREMENT(nprcommon);
4670 	}
4671 }
4672 
4673 /*
4674  * Array of readdir functions, indexed by /proc file type.
4675  */
4676 static int pr_readdir_notdir(), pr_readdir_procdir(), pr_readdir_piddir(),
4677 	pr_readdir_objectdir(), pr_readdir_lwpdir(), pr_readdir_lwpiddir(),
4678 	pr_readdir_fddir(), pr_readdir_pathdir(), pr_readdir_tmpldir(),
4679 	pr_readdir_ctdir();
4680 
4681 static int (*pr_readdir_function[PR_NFILES])() = {
4682 	pr_readdir_procdir,	/* /proc				*/
4683 	pr_readdir_notdir,	/* /proc/self				*/
4684 	pr_readdir_piddir,	/* /proc/<pid>				*/
4685 	pr_readdir_notdir,	/* /proc/<pid>/as			*/
4686 	pr_readdir_notdir,	/* /proc/<pid>/ctl			*/
4687 	pr_readdir_notdir,	/* /proc/<pid>/status			*/
4688 	pr_readdir_notdir,	/* /proc/<pid>/lstatus			*/
4689 	pr_readdir_notdir,	/* /proc/<pid>/psinfo			*/
4690 	pr_readdir_notdir,	/* /proc/<pid>/lpsinfo			*/
4691 	pr_readdir_notdir,	/* /proc/<pid>/map			*/
4692 	pr_readdir_notdir,	/* /proc/<pid>/rmap			*/
4693 	pr_readdir_notdir,	/* /proc/<pid>/xmap			*/
4694 	pr_readdir_notdir,	/* /proc/<pid>/cred			*/
4695 	pr_readdir_notdir,	/* /proc/<pid>/sigact			*/
4696 	pr_readdir_notdir,	/* /proc/<pid>/auxv			*/
4697 #if defined(__x86)
4698 	pr_readdir_notdir,	/* /proc/<pid>/ldt			*/
4699 #endif
4700 	pr_readdir_notdir,	/* /proc/<pid>/usage			*/
4701 	pr_readdir_notdir,	/* /proc/<pid>/lusage			*/
4702 	pr_readdir_notdir,	/* /proc/<pid>/pagedata			*/
4703 	pr_readdir_notdir,	/* /proc/<pid>/watch			*/
4704 	pr_readdir_notdir,	/* /proc/<pid>/cwd			*/
4705 	pr_readdir_notdir,	/* /proc/<pid>/root			*/
4706 	pr_readdir_fddir,	/* /proc/<pid>/fd			*/
4707 	pr_readdir_notdir,	/* /proc/<pid>/fd/nn			*/
4708 	pr_readdir_objectdir,	/* /proc/<pid>/object			*/
4709 	pr_readdir_notdir,	/* /proc/<pid>/object/xxx		*/
4710 	pr_readdir_lwpdir,	/* /proc/<pid>/lwp			*/
4711 	pr_readdir_lwpiddir,	/* /proc/<pid>/lwp/<lwpid>		*/
4712 	pr_readdir_notdir,	/* /proc/<pid>/lwp/<lwpid>/lwpctl	*/
4713 	pr_readdir_notdir,	/* /proc/<pid>/lwp/<lwpid>/lwpstatus	*/
4714 	pr_readdir_notdir,	/* /proc/<pid>/lwp/<lwpid>/lwpsinfo	*/
4715 	pr_readdir_notdir,	/* /proc/<pid>/lwp/<lwpid>/lwpusage	*/
4716 	pr_readdir_notdir,	/* /proc/<pid>/lwp/<lwpid>/xregs	*/
4717 	pr_readdir_tmpldir,	/* /proc/<pid>/lwp/<lwpid>/templates	*/
4718 	pr_readdir_notdir,	/* /proc/<pid>/lwp/<lwpid>/templates/<id> */
4719 	pr_readdir_notdir,	/* /proc/<pid>/lwp/<lwpid>/spymaster	*/
4720 #if defined(__sparc)
4721 	pr_readdir_notdir,	/* /proc/<pid>/lwp/<lwpid>/gwindows	*/
4722 	pr_readdir_notdir,	/* /proc/<pid>/lwp/<lwpid>/asrs		*/
4723 #endif
4724 	pr_readdir_notdir,	/* /proc/<pid>/priv			*/
4725 	pr_readdir_pathdir,	/* /proc/<pid>/path			*/
4726 	pr_readdir_notdir,	/* /proc/<pid>/path/xxx			*/
4727 	pr_readdir_ctdir,	/* /proc/<pid>/contracts		*/
4728 	pr_readdir_notdir,	/* /proc/<pid>/contracts/<ctid>		*/
4729 	pr_readdir_notdir,	/* /proc/<pid>/secflags			*/
4730 	pr_readdir_notdir,	/* old process file			*/
4731 	pr_readdir_notdir,	/* old lwp file				*/
4732 	pr_readdir_notdir,	/* old pagedata file			*/
4733 };
4734 
4735 /* ARGSUSED */
4736 static int
4737 prreaddir(vnode_t *vp, uio_t *uiop, cred_t *cr, int *eofp,
4738     caller_context_t *ct, int flags)
4739 {
4740 	prnode_t *pnp = VTOP(vp);
4741 
4742 	ASSERT(pnp->pr_type < PR_NFILES);
4743 
4744 	/* XXX - Do we need to pass ct and flags? */
4745 	return (pr_readdir_function[pnp->pr_type](pnp, uiop, eofp));
4746 }
4747 
4748 /* ARGSUSED */
4749 static int
4750 pr_readdir_notdir(prnode_t *pnp, uio_t *uiop, int *eofp)
4751 {
4752 	return (ENOTDIR);
4753 }
4754 
4755 /* ARGSUSED */
4756 static int
4757 pr_readdir_procdir(prnode_t *pnp, uio_t *uiop, int *eofp)
4758 {
4759 	zoneid_t zoneid;
4760 	gfs_readdir_state_t gstate;
4761 	int error, eof = 0;
4762 	offset_t n;
4763 
4764 	ASSERT(pnp->pr_type == PR_PROCDIR);
4765 
4766 	zoneid = VTOZONE(PTOV(pnp))->zone_id;
4767 
4768 	if ((error = gfs_readdir_init(&gstate, PNSIZ, PRSDSIZE, uiop,
4769 	    PRROOTINO, PRROOTINO, 0)) != 0)
4770 		return (error);
4771 
4772 	/*
4773 	 * Loop until user's request is satisfied or until all processes
4774 	 * have been examined.
4775 	 */
4776 	while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
4777 		uint_t pid;
4778 		int pslot;
4779 		proc_t *p;
4780 
4781 		/*
4782 		 * Find next entry.  Skip processes not visible where
4783 		 * this /proc was mounted.
4784 		 */
4785 		mutex_enter(&pidlock);
4786 		while (n < v.v_proc &&
4787 		    ((p = pid_entry(n)) == NULL || p->p_stat == SIDL ||
4788 		    (zoneid != GLOBAL_ZONEID && p->p_zone->zone_id != zoneid) ||
4789 		    secpolicy_basic_procinfo(CRED(), p, curproc) != 0))
4790 			n++;
4791 
4792 		/*
4793 		 * Stop when entire proc table has been examined.
4794 		 */
4795 		if (n >= v.v_proc) {
4796 			mutex_exit(&pidlock);
4797 			eof = 1;
4798 			break;
4799 		}
4800 
4801 		ASSERT(p->p_stat != 0);
4802 		pid = p->p_pid;
4803 		pslot = p->p_slot;
4804 		mutex_exit(&pidlock);
4805 		error = gfs_readdir_emitn(&gstate, uiop, n,
4806 		    pmkino(0, pslot, PR_PIDDIR), pid);
4807 		if (error)
4808 			break;
4809 	}
4810 
4811 	return (gfs_readdir_fini(&gstate, error, eofp, eof));
4812 }
4813 
4814 /* ARGSUSED */
4815 static int
4816 pr_readdir_piddir(prnode_t *pnp, uio_t *uiop, int *eofp)
4817 {
4818 	int zombie = ((pnp->pr_pcommon->prc_flags & PRC_DESTROY) != 0);
4819 	prdirent_t dirent;
4820 	prdirent_t *dirp;
4821 	offset_t off;
4822 	int error;
4823 
4824 	ASSERT(pnp->pr_type == PR_PIDDIR);
4825 
4826 	if (uiop->uio_offset < 0 ||
4827 	    uiop->uio_offset % sizeof (prdirent_t) != 0 ||
4828 	    uiop->uio_resid < sizeof (prdirent_t))
4829 		return (EINVAL);
4830 	if (pnp->pr_pcommon->prc_proc == NULL)
4831 		return (ENOENT);
4832 	if (uiop->uio_offset >= sizeof (piddir))
4833 		goto out;
4834 
4835 	/*
4836 	 * Loop until user's request is satisfied, omitting some
4837 	 * files along the way if the process is a zombie.
4838 	 */
4839 	for (dirp = &piddir[uiop->uio_offset / sizeof (prdirent_t)];
4840 	    uiop->uio_resid >= sizeof (prdirent_t) &&
4841 	    dirp < &piddir[NPIDDIRFILES+2];
4842 	    uiop->uio_offset = off + sizeof (prdirent_t), dirp++) {
4843 		off = uiop->uio_offset;
4844 		if (zombie) {
4845 			switch (dirp->d_ino) {
4846 			case PR_PIDDIR:
4847 			case PR_PROCDIR:
4848 			case PR_PSINFO:
4849 			case PR_USAGE:
4850 				break;
4851 			default:
4852 				continue;
4853 			}
4854 		}
4855 		bcopy(dirp, &dirent, sizeof (prdirent_t));
4856 		if (dirent.d_ino == PR_PROCDIR)
4857 			dirent.d_ino = PRROOTINO;
4858 		else
4859 			dirent.d_ino = pmkino(0, pnp->pr_pcommon->prc_slot,
4860 			    dirent.d_ino);
4861 		if ((error = uiomove((caddr_t)&dirent, sizeof (prdirent_t),
4862 		    UIO_READ, uiop)) != 0)
4863 			return (error);
4864 	}
4865 out:
4866 	if (eofp)
4867 		*eofp = (uiop->uio_offset >= sizeof (piddir));
4868 	return (0);
4869 }
4870 
4871 static void
4872 rebuild_objdir(struct as *as)
4873 {
4874 	struct seg *seg;
4875 	vnode_t *vp;
4876 	vattr_t vattr;
4877 	vnode_t **dir;
4878 	ulong_t nalloc;
4879 	ulong_t nentries;
4880 	int i, j;
4881 	ulong_t nold, nnew;
4882 
4883 	ASSERT(AS_WRITE_HELD(as));
4884 
4885 	if (as->a_updatedir == 0 && as->a_objectdir != NULL)
4886 		return;
4887 	as->a_updatedir = 0;
4888 
4889 	if ((nalloc = avl_numnodes(&as->a_segtree)) == 0 ||
4890 	    (seg = AS_SEGFIRST(as)) == NULL)	/* can't happen? */
4891 		return;
4892 
4893 	/*
4894 	 * Allocate space for the new object directory.
4895 	 * (This is usually about two times too many entries.)
4896 	 */
4897 	nalloc = (nalloc + 0xf) & ~0xf;		/* multiple of 16 */
4898 	dir = kmem_zalloc(nalloc * sizeof (vnode_t *), KM_SLEEP);
4899 
4900 	/* fill in the new directory with desired entries */
4901 	nentries = 0;
4902 	do {
4903 		vattr.va_mask = AT_FSID|AT_NODEID;
4904 		if (seg->s_ops == &segvn_ops &&
4905 		    SEGOP_GETVP(seg, seg->s_base, &vp) == 0 &&
4906 		    vp != NULL && vp->v_type == VREG &&
4907 		    VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
4908 			for (i = 0; i < nentries; i++)
4909 				if (vp == dir[i])
4910 					break;
4911 			if (i == nentries) {
4912 				ASSERT(nentries < nalloc);
4913 				dir[nentries++] = vp;
4914 			}
4915 		}
4916 	} while ((seg = AS_SEGNEXT(as, seg)) != NULL);
4917 
4918 	if (as->a_objectdir == NULL) {	/* first time */
4919 		as->a_objectdir = dir;
4920 		as->a_sizedir = nalloc;
4921 		return;
4922 	}
4923 
4924 	/*
4925 	 * Null out all of the defunct entries in the old directory.
4926 	 */
4927 	nold = 0;
4928 	nnew = nentries;
4929 	for (i = 0; i < as->a_sizedir; i++) {
4930 		if ((vp = as->a_objectdir[i]) != NULL) {
4931 			for (j = 0; j < nentries; j++) {
4932 				if (vp == dir[j]) {
4933 					dir[j] = NULL;
4934 					nnew--;
4935 					break;
4936 				}
4937 			}
4938 			if (j == nentries)
4939 				as->a_objectdir[i] = NULL;
4940 			else
4941 				nold++;
4942 		}
4943 	}
4944 
4945 	if (nold + nnew > as->a_sizedir) {
4946 		/*
4947 		 * Reallocate the old directory to have enough
4948 		 * space for the old and new entries combined.
4949 		 * Round up to the next multiple of 16.
4950 		 */
4951 		ulong_t newsize = (nold + nnew + 0xf) & ~0xf;
4952 		vnode_t **newdir = kmem_zalloc(newsize * sizeof (vnode_t *),
4953 		    KM_SLEEP);
4954 		bcopy(as->a_objectdir, newdir,
4955 		    as->a_sizedir * sizeof (vnode_t *));
4956 		kmem_free(as->a_objectdir, as->a_sizedir * sizeof (vnode_t *));
4957 		as->a_objectdir = newdir;
4958 		as->a_sizedir = newsize;
4959 	}
4960 
4961 	/*
4962 	 * Move all new entries to the old directory and
4963 	 * deallocate the space used by the new directory.
4964 	 */
4965 	if (nnew) {
4966 		for (i = 0, j = 0; i < nentries; i++) {
4967 			if ((vp = dir[i]) == NULL)
4968 				continue;
4969 			for (; j < as->a_sizedir; j++) {
4970 				if (as->a_objectdir[j] != NULL)
4971 					continue;
4972 				as->a_objectdir[j++] = vp;
4973 				break;
4974 			}
4975 		}
4976 	}
4977 	kmem_free(dir, nalloc * sizeof (vnode_t *));
4978 }
4979 
4980 /*
4981  * Return the vnode from a slot in the process's object directory.
4982  * The caller must have locked the process's address space.
4983  * The only caller is below, in pr_readdir_objectdir().
4984  */
4985 static vnode_t *
4986 obj_entry(struct as *as, int slot)
4987 {
4988 	ASSERT(AS_LOCK_HELD(as));
4989 	if (as->a_objectdir == NULL)
4990 		return (NULL);
4991 	ASSERT(slot < as->a_sizedir);
4992 	return (as->a_objectdir[slot]);
4993 }
4994 
4995 /* ARGSUSED */
4996 static int
4997 pr_readdir_objectdir(prnode_t *pnp, uio_t *uiop, int *eofp)
4998 {
4999 	gfs_readdir_state_t gstate;
5000 	int error, eof = 0;
5001 	offset_t n;
5002 	int pslot;
5003 	size_t objdirsize;
5004 	proc_t *p;
5005 	struct as *as;
5006 	vnode_t *vp;
5007 
5008 	ASSERT(pnp->pr_type == PR_OBJECTDIR);
5009 
5010 	if ((error = prlock(pnp, ZNO)) != 0)
5011 		return (error);
5012 	p = pnp->pr_common->prc_proc;
5013 	pslot = p->p_slot;
5014 
5015 	/*
5016 	 * We drop p_lock before grabbing the address space lock
5017 	 * in order to avoid a deadlock with the clock thread.
5018 	 * The process will not disappear and its address space
5019 	 * will not change because it is marked P_PR_LOCK.
5020 	 */
5021 	mutex_exit(&p->p_lock);
5022 
5023 	if ((error = gfs_readdir_init(&gstate, 64, PRSDSIZE, uiop,
5024 	    pmkino(0, pslot, PR_PIDDIR),
5025 	    pmkino(0, pslot, PR_OBJECTDIR), 0)) != 0) {
5026 		mutex_enter(&p->p_lock);
5027 		prunlock(pnp);
5028 		return (error);
5029 	}
5030 
5031 	if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
5032 		as = NULL;
5033 		objdirsize = 0;
5034 	}
5035 
5036 	/*
5037 	 * Loop until user's request is satisfied or until
5038 	 * all mapped objects have been examined. Cannot hold
5039 	 * the address space lock for the following call as
5040 	 * gfs_readdir_pred() utimately causes a call to uiomove().
5041 	 */
5042 	while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5043 		vattr_t vattr;
5044 		char str[64];
5045 
5046 		/*
5047 		 * Set the correct size of the directory just
5048 		 * in case the process has changed it's address
5049 		 * space via mmap/munmap calls.
5050 		 */
5051 		if (as != NULL) {
5052 			AS_LOCK_ENTER(as, RW_WRITER);
5053 			if (as->a_updatedir)
5054 				rebuild_objdir(as);
5055 			objdirsize = as->a_sizedir;
5056 		}
5057 
5058 		/*
5059 		 * Find next object.
5060 		 */
5061 		vattr.va_mask = AT_FSID | AT_NODEID;
5062 		while (n < objdirsize && (((vp = obj_entry(as, n)) == NULL) ||
5063 		    (VOP_GETATTR(vp, &vattr, 0, CRED(), NULL)
5064 		    != 0))) {
5065 			vattr.va_mask = AT_FSID | AT_NODEID;
5066 			n++;
5067 		}
5068 
5069 		if (as != NULL)
5070 			AS_LOCK_EXIT(as);
5071 
5072 		/*
5073 		 * Stop when all objects have been reported.
5074 		 */
5075 		if (n >= objdirsize) {
5076 			eof = 1;
5077 			break;
5078 		}
5079 
5080 		if (vp == p->p_exec)
5081 			(void) strcpy(str, "a.out");
5082 		else
5083 			pr_object_name(str, vp, &vattr);
5084 
5085 		error = gfs_readdir_emit(&gstate, uiop, n, vattr.va_nodeid,
5086 		    str, 0);
5087 
5088 		if (error)
5089 			break;
5090 	}
5091 
5092 	mutex_enter(&p->p_lock);
5093 	prunlock(pnp);
5094 
5095 	return (gfs_readdir_fini(&gstate, error, eofp, eof));
5096 }
5097 
5098 /* ARGSUSED */
5099 static int
5100 pr_readdir_lwpdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5101 {
5102 	gfs_readdir_state_t gstate;
5103 	int error, eof = 0;
5104 	offset_t tslot;
5105 	proc_t *p;
5106 	int pslot;
5107 	lwpdir_t *lwpdir;
5108 	int lwpdirsize;
5109 
5110 	ASSERT(pnp->pr_type == PR_LWPDIR);
5111 
5112 	p = pr_p_lock(pnp);
5113 	mutex_exit(&pr_pidlock);
5114 	if (p == NULL)
5115 		return (ENOENT);
5116 	ASSERT(p == pnp->pr_common->prc_proc);
5117 	pslot = p->p_slot;
5118 	lwpdir = p->p_lwpdir;
5119 	lwpdirsize = p->p_lwpdir_sz;
5120 
5121 	/*
5122 	 * Drop p->p_lock so we can safely do uiomove().
5123 	 * The lwp directory will not change because
5124 	 * we have the process locked with P_PR_LOCK.
5125 	 */
5126 	mutex_exit(&p->p_lock);
5127 
5128 
5129 	if ((error = gfs_readdir_init(&gstate, PLNSIZ, PRSDSIZE, uiop,
5130 	    pmkino(0, pslot, PR_PIDDIR),
5131 	    pmkino(0, pslot, PR_LWPDIR), 0)) != 0) {
5132 		mutex_enter(&p->p_lock);
5133 		prunlock(pnp);
5134 		return (error);
5135 	}
5136 
5137 	/*
5138 	 * Loop until user's request is satisfied or until all lwps
5139 	 * have been examined.
5140 	 */
5141 	while ((error = gfs_readdir_pred(&gstate, uiop, &tslot)) == 0) {
5142 		lwpent_t *lep;
5143 		uint_t tid;
5144 
5145 		/*
5146 		 * Find next LWP.
5147 		 */
5148 		while (tslot < lwpdirsize &&
5149 		    ((lep = lwpdir[tslot].ld_entry) == NULL))
5150 			tslot++;
5151 		/*
5152 		 * Stop when all lwps have been reported.
5153 		 */
5154 		if (tslot >= lwpdirsize) {
5155 			eof = 1;
5156 			break;
5157 		}
5158 
5159 		tid = lep->le_lwpid;
5160 		error = gfs_readdir_emitn(&gstate, uiop, tslot,
5161 		    pmkino(tslot, pslot, PR_LWPIDDIR), tid);
5162 		if (error)
5163 			break;
5164 	}
5165 
5166 	mutex_enter(&p->p_lock);
5167 	prunlock(pnp);
5168 
5169 	return (gfs_readdir_fini(&gstate, error, eofp, eof));
5170 }
5171 
5172 /* ARGSUSED */
5173 static int
5174 pr_readdir_lwpiddir(prnode_t *pnp, uio_t *uiop, int *eofp)
5175 {
5176 	prcommon_t *pcp = pnp->pr_common;
5177 	int zombie = ((pcp->prc_flags & PRC_DESTROY) != 0);
5178 	prdirent_t dirent;
5179 	prdirent_t *dirp;
5180 	offset_t off;
5181 	int error;
5182 	int pslot;
5183 	int tslot;
5184 
5185 	ASSERT(pnp->pr_type == PR_LWPIDDIR);
5186 
5187 	if (uiop->uio_offset < 0 ||
5188 	    uiop->uio_offset % sizeof (prdirent_t) != 0 ||
5189 	    uiop->uio_resid < sizeof (prdirent_t))
5190 		return (EINVAL);
5191 	if (pcp->prc_proc == NULL || pcp->prc_tslot == -1)
5192 		return (ENOENT);
5193 	if (uiop->uio_offset >= sizeof (lwpiddir))
5194 		goto out;
5195 
5196 	/*
5197 	 * Loop until user's request is satisfied, omitting some files
5198 	 * along the way if the lwp is a zombie and also depending
5199 	 * on the data model of the process.
5200 	 */
5201 	pslot = pcp->prc_slot;
5202 	tslot = pcp->prc_tslot;
5203 	for (dirp = &lwpiddir[uiop->uio_offset / sizeof (prdirent_t)];
5204 	    uiop->uio_resid >= sizeof (prdirent_t) &&
5205 	    dirp < &lwpiddir[NLWPIDDIRFILES+2];
5206 	    uiop->uio_offset = off + sizeof (prdirent_t), dirp++) {
5207 		off = uiop->uio_offset;
5208 		if (zombie) {
5209 			switch (dirp->d_ino) {
5210 			case PR_LWPIDDIR:
5211 			case PR_LWPDIR:
5212 			case PR_LWPSINFO:
5213 				break;
5214 			default:
5215 				continue;
5216 			}
5217 		}
5218 #if defined(__sparc)
5219 		/* the asrs file exists only for sparc v9 _LP64 processes */
5220 		if (dirp->d_ino == PR_ASRS &&
5221 		    pcp->prc_datamodel != DATAMODEL_LP64)
5222 			continue;
5223 #endif
5224 		bcopy(dirp, &dirent, sizeof (prdirent_t));
5225 		if (dirent.d_ino == PR_LWPDIR)
5226 			dirent.d_ino = pmkino(0, pslot, dirp->d_ino);
5227 		else
5228 			dirent.d_ino = pmkino(tslot, pslot, dirp->d_ino);
5229 		if ((error = uiomove((caddr_t)&dirent, sizeof (prdirent_t),
5230 		    UIO_READ, uiop)) != 0)
5231 			return (error);
5232 	}
5233 out:
5234 	if (eofp)
5235 		*eofp = (uiop->uio_offset >= sizeof (lwpiddir));
5236 	return (0);
5237 }
5238 
5239 /* ARGSUSED */
5240 static int
5241 pr_readdir_fddir(prnode_t *pnp, uio_t *uiop, int *eofp)
5242 {
5243 	gfs_readdir_state_t gstate;
5244 	int error, eof = 0;
5245 	offset_t n;
5246 	proc_t *p;
5247 	int pslot;
5248 	int fddirsize;
5249 	uf_info_t *fip;
5250 
5251 	ASSERT(pnp->pr_type == PR_FDDIR);
5252 
5253 	if ((error = prlock(pnp, ZNO)) != 0)
5254 		return (error);
5255 	p = pnp->pr_common->prc_proc;
5256 	pslot = p->p_slot;
5257 	fip = P_FINFO(p);
5258 	mutex_exit(&p->p_lock);
5259 
5260 	if ((error = gfs_readdir_init(&gstate, PLNSIZ, PRSDSIZE, uiop,
5261 	    pmkino(0, pslot, PR_PIDDIR), pmkino(0, pslot, PR_FDDIR), 0)) != 0) {
5262 		mutex_enter(&p->p_lock);
5263 		prunlock(pnp);
5264 		return (error);
5265 	}
5266 
5267 	mutex_enter(&fip->fi_lock);
5268 	if ((p->p_flag & SSYS) || p->p_as == &kas)
5269 		fddirsize = 0;
5270 	else
5271 		fddirsize = fip->fi_nfiles;
5272 
5273 	/*
5274 	 * Loop until user's request is satisfied or until
5275 	 * all file descriptors have been examined.
5276 	 */
5277 	while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5278 		/*
5279 		 * Find next fd.
5280 		 */
5281 		while (n < fddirsize && fip->fi_list[n].uf_file == NULL)
5282 			n++;
5283 		/*
5284 		 * Stop when all fds have been reported.
5285 		 */
5286 		if (n >= fddirsize) {
5287 			eof = 1;
5288 			break;
5289 		}
5290 
5291 		error = gfs_readdir_emitn(&gstate, uiop, n,
5292 		    pmkino(n, pslot, PR_FD), n);
5293 		if (error)
5294 			break;
5295 	}
5296 
5297 	mutex_exit(&fip->fi_lock);
5298 	mutex_enter(&p->p_lock);
5299 	prunlock(pnp);
5300 
5301 	return (gfs_readdir_fini(&gstate, error, eofp, eof));
5302 }
5303 
5304 /* ARGSUSED */
5305 static int
5306 pr_readdir_pathdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5307 {
5308 	longlong_t bp[DIRENT64_RECLEN(64) / sizeof (longlong_t)];
5309 	dirent64_t *dirent = (dirent64_t *)bp;
5310 	int reclen;
5311 	ssize_t oresid;
5312 	offset_t off, idx;
5313 	int error = 0;
5314 	proc_t *p;
5315 	int fd, obj;
5316 	int pslot;
5317 	int fddirsize;
5318 	uf_info_t *fip;
5319 	struct as *as = NULL;
5320 	size_t objdirsize;
5321 	vattr_t vattr;
5322 	vnode_t *vp;
5323 
5324 	ASSERT(pnp->pr_type == PR_PATHDIR);
5325 
5326 	if (uiop->uio_offset < 0 ||
5327 	    uiop->uio_resid <= 0 ||
5328 	    (uiop->uio_offset % PRSDSIZE) != 0)
5329 		return (EINVAL);
5330 	oresid = uiop->uio_resid;
5331 	bzero(bp, sizeof (bp));
5332 
5333 	if ((error = prlock(pnp, ZNO)) != 0)
5334 		return (error);
5335 	p = pnp->pr_common->prc_proc;
5336 	fip = P_FINFO(p);
5337 	pslot = p->p_slot;
5338 	mutex_exit(&p->p_lock);
5339 
5340 	if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
5341 		as = NULL;
5342 		objdirsize = 0;
5343 	} else {
5344 		AS_LOCK_ENTER(as, RW_WRITER);
5345 		if (as->a_updatedir)
5346 			rebuild_objdir(as);
5347 		objdirsize = as->a_sizedir;
5348 		AS_LOCK_EXIT(as);
5349 		as = NULL;
5350 	}
5351 
5352 	mutex_enter(&fip->fi_lock);
5353 	if ((p->p_flag & SSYS) || p->p_as == &kas)
5354 		fddirsize = 0;
5355 	else
5356 		fddirsize = fip->fi_nfiles;
5357 
5358 	for (; uiop->uio_resid > 0; uiop->uio_offset = off + PRSDSIZE) {
5359 		/*
5360 		 * There are 4 special files in the path directory: ".", "..",
5361 		 * "root", and "cwd".  We handle those specially here.
5362 		 */
5363 		off = uiop->uio_offset;
5364 		idx = off / PRSDSIZE;
5365 		if (off == 0) {				/* "." */
5366 			dirent->d_ino = pmkino(0, pslot, PR_PATHDIR);
5367 			dirent->d_name[0] = '.';
5368 			dirent->d_name[1] = '\0';
5369 			reclen = DIRENT64_RECLEN(1);
5370 		} else if (idx == 1) {			/* ".." */
5371 			dirent->d_ino = pmkino(0, pslot, PR_PIDDIR);
5372 			dirent->d_name[0] = '.';
5373 			dirent->d_name[1] = '.';
5374 			dirent->d_name[2] = '\0';
5375 			reclen = DIRENT64_RECLEN(2);
5376 		} else if (idx == 2) {			/* "root" */
5377 			dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5378 			(void) strcpy(dirent->d_name, "root");
5379 			reclen = DIRENT64_RECLEN(4);
5380 		} else if (idx == 3) {			/* "cwd" */
5381 			dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5382 			(void) strcpy(dirent->d_name, "cwd");
5383 			reclen = DIRENT64_RECLEN(3);
5384 		} else if (idx < 4 + fddirsize) {
5385 			/*
5386 			 * In this case, we have one of the file descriptors.
5387 			 */
5388 			fd = idx - 4;
5389 			if (fip->fi_list[fd].uf_file == NULL)
5390 				continue;
5391 			dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5392 			(void) pr_u32tos(fd, dirent->d_name, PLNSIZ+1);
5393 			reclen = DIRENT64_RECLEN(PLNSIZ);
5394 		} else if (idx < 4 + fddirsize + objdirsize) {
5395 			if (fip != NULL) {
5396 				mutex_exit(&fip->fi_lock);
5397 				fip = NULL;
5398 			}
5399 
5400 			/*
5401 			 * We drop p_lock before grabbing the address space lock
5402 			 * in order to avoid a deadlock with the clock thread.
5403 			 * The process will not disappear and its address space
5404 			 * will not change because it is marked P_PR_LOCK.
5405 			 */
5406 			if (as == NULL) {
5407 				as = p->p_as;
5408 				AS_LOCK_ENTER(as, RW_WRITER);
5409 			}
5410 
5411 			if (as->a_updatedir) {
5412 				rebuild_objdir(as);
5413 				objdirsize = as->a_sizedir;
5414 			}
5415 
5416 			obj = idx - 4 - fddirsize;
5417 			if ((vp = obj_entry(as, obj)) == NULL)
5418 				continue;
5419 			vattr.va_mask = AT_FSID|AT_NODEID;
5420 			if (VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) != 0)
5421 				continue;
5422 			if (vp == p->p_exec)
5423 				(void) strcpy(dirent->d_name, "a.out");
5424 			else
5425 				pr_object_name(dirent->d_name, vp, &vattr);
5426 			dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5427 			reclen = DIRENT64_RECLEN(strlen(dirent->d_name));
5428 		} else {
5429 			break;
5430 		}
5431 
5432 		dirent->d_off = uiop->uio_offset + PRSDSIZE;
5433 		dirent->d_reclen = (ushort_t)reclen;
5434 		if (reclen > uiop->uio_resid) {
5435 			/*
5436 			 * Error if no entries have been returned yet.
5437 			 */
5438 			if (uiop->uio_resid == oresid)
5439 				error = EINVAL;
5440 			break;
5441 		}
5442 		/*
5443 		 * Drop the address space lock to do the uiomove().
5444 		 */
5445 		if (as != NULL)
5446 			AS_LOCK_EXIT(as);
5447 
5448 		error = uiomove((caddr_t)dirent, reclen, UIO_READ, uiop);
5449 		if (as != NULL)
5450 			AS_LOCK_ENTER(as, RW_WRITER);
5451 
5452 		if (error)
5453 			break;
5454 	}
5455 
5456 	if (error == 0 && eofp)
5457 		*eofp = (uiop->uio_offset >= (fddirsize + 2) * PRSDSIZE);
5458 
5459 	if (fip != NULL)
5460 		mutex_exit(&fip->fi_lock);
5461 	if (as != NULL)
5462 		AS_LOCK_EXIT(as);
5463 	mutex_enter(&p->p_lock);
5464 	prunlock(pnp);
5465 	return (error);
5466 }
5467 
5468 static int
5469 pr_readdir_tmpldir(prnode_t *pnp, uio_t *uiop, int *eofp)
5470 {
5471 	proc_t *p;
5472 	int pslot, tslot;
5473 	gfs_readdir_state_t gstate;
5474 	int error, eof = 0;
5475 	offset_t n;
5476 
5477 	ASSERT(pnp->pr_type == PR_TMPLDIR);
5478 
5479 	if ((error = prlock(pnp, ZNO)) != 0)
5480 		return (error);
5481 	p = pnp->pr_common->prc_proc;
5482 	pslot = pnp->pr_common->prc_slot;
5483 	tslot = pnp->pr_common->prc_tslot;
5484 	mutex_exit(&p->p_lock);
5485 
5486 	if ((error = gfs_readdir_init(&gstate, PRDIRSIZE, PRSDSIZE, uiop,
5487 	    pmkino(tslot, pslot, PR_LWPDIR),
5488 	    pmkino(tslot, pslot, PR_TMPLDIR), 0)) != 0) {
5489 		mutex_enter(&p->p_lock);
5490 		prunlock(pnp);
5491 		return (error);
5492 	}
5493 
5494 	while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5495 		/*
5496 		 * Check for an active template.  Reading a directory's
5497 		 * contents is already racy, so we don't bother taking
5498 		 * any locks.
5499 		 */
5500 		while (n < ct_ntypes &&
5501 		    pnp->pr_common->prc_thread->t_lwp->lwp_ct_active[n] == NULL)
5502 			n++;
5503 		/*
5504 		 * Stop when all types have been reported.
5505 		 */
5506 		if (n >= ct_ntypes) {
5507 			eof = 1;
5508 			break;
5509 		}
5510 		/*
5511 		 * The pmkino invocation below will need to be updated
5512 		 * when we create our fifth contract type.
5513 		 */
5514 		ASSERT(ct_ntypes <= 4);
5515 		error = gfs_readdir_emit(&gstate, uiop, n,
5516 		    pmkino((tslot << 2) | n, pslot, PR_TMPL),
5517 		    ct_types[n]->ct_type_name, 0);
5518 		if (error)
5519 			break;
5520 	}
5521 
5522 	mutex_enter(&p->p_lock);
5523 	prunlock(pnp);
5524 
5525 	return (gfs_readdir_fini(&gstate, error, eofp, eof));
5526 }
5527 
5528 static int
5529 pr_readdir_ctdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5530 {
5531 	proc_t *p;
5532 	int pslot;
5533 	gfs_readdir_state_t gstate;
5534 	int error, eof = 0;
5535 	offset_t n;
5536 	uint64_t zid;
5537 
5538 	ASSERT(pnp->pr_type == PR_CTDIR);
5539 
5540 	if ((error = prlock(pnp, ZNO)) != 0)
5541 		return (error);
5542 	p = pnp->pr_common->prc_proc;
5543 	pslot = p->p_slot;
5544 	mutex_exit(&p->p_lock);
5545 
5546 	if ((error = gfs_readdir_init(&gstate, PRDIRSIZE, PRSDSIZE, uiop,
5547 	    pmkino(0, pslot, PR_PIDDIR), pmkino(0, pslot, PR_CTDIR), 0)) != 0) {
5548 		mutex_enter(&p->p_lock);
5549 		prunlock(pnp);
5550 		return (error);
5551 	}
5552 
5553 	zid = VTOZONE(pnp->pr_vnode)->zone_uniqid;
5554 	while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5555 		id_t next = contract_plookup(p, n, zid);
5556 		if (next == -1) {
5557 			eof = 1;
5558 			break;
5559 		}
5560 		error = gfs_readdir_emitn(&gstate, uiop, next,
5561 		    pmkino(next, pslot, PR_CT), next);
5562 		if (error)
5563 			break;
5564 	}
5565 
5566 	mutex_enter(&p->p_lock);
5567 	prunlock(pnp);
5568 
5569 	return (gfs_readdir_fini(&gstate, error, eofp, eof));
5570 }
5571 
5572 /* ARGSUSED */
5573 static int
5574 prfsync(vnode_t *vp, int syncflag, cred_t *cr, caller_context_t *ct)
5575 {
5576 	return (0);
5577 }
5578 
5579 /*
5580  * Utility: remove a /proc vnode from a linked list, threaded through pr_next.
5581  */
5582 static void
5583 pr_list_unlink(vnode_t *pvp, vnode_t **listp)
5584 {
5585 	vnode_t *vp;
5586 	prnode_t *pnp;
5587 
5588 	while ((vp = *listp) != NULL) {
5589 		pnp = VTOP(vp);
5590 		if (vp == pvp) {
5591 			*listp = pnp->pr_next;
5592 			pnp->pr_next = NULL;
5593 			break;
5594 		}
5595 		listp = &pnp->pr_next;
5596 	}
5597 }
5598 
5599 /* ARGSUSED */
5600 static void
5601 prinactive(vnode_t *vp, cred_t *cr, caller_context_t *ct)
5602 {
5603 	prnode_t *pnp = VTOP(vp);
5604 	prnodetype_t type = pnp->pr_type;
5605 	proc_t *p;
5606 	vnode_t *dp;
5607 	vnode_t *ovp = NULL;
5608 	prnode_t *opnp = NULL;
5609 
5610 	switch (type) {
5611 	case PR_OBJECT:
5612 	case PR_FD:
5613 	case PR_SELF:
5614 	case PR_PATH:
5615 		/* These are not linked into the usual lists */
5616 		ASSERT(vp->v_count == 1);
5617 		if ((dp = pnp->pr_parent) != NULL)
5618 			VN_RELE(dp);
5619 		prfreenode(pnp);
5620 		return;
5621 	default:
5622 		break;
5623 	}
5624 
5625 	mutex_enter(&pr_pidlock);
5626 	if (pnp->pr_pcommon == NULL)
5627 		p = NULL;
5628 	else if ((p = pnp->pr_pcommon->prc_proc) != NULL)
5629 		mutex_enter(&p->p_lock);
5630 	mutex_enter(&vp->v_lock);
5631 
5632 	if (type == PR_PROCDIR || vp->v_count > 1) {
5633 		vp->v_count--;
5634 		mutex_exit(&vp->v_lock);
5635 		if (p != NULL)
5636 			mutex_exit(&p->p_lock);
5637 		mutex_exit(&pr_pidlock);
5638 		return;
5639 	}
5640 
5641 	if ((dp = pnp->pr_parent) != NULL) {
5642 		prnode_t *dpnp;
5643 
5644 		switch (type) {
5645 		case PR_PIDFILE:
5646 		case PR_LWPIDFILE:
5647 		case PR_OPAGEDATA:
5648 			break;
5649 		default:
5650 			dpnp = VTOP(dp);
5651 			mutex_enter(&dpnp->pr_mutex);
5652 			if (dpnp->pr_files != NULL &&
5653 			    dpnp->pr_files[pnp->pr_index] == vp)
5654 				dpnp->pr_files[pnp->pr_index] = NULL;
5655 			mutex_exit(&dpnp->pr_mutex);
5656 			break;
5657 		}
5658 		pnp->pr_parent = NULL;
5659 	}
5660 
5661 	ASSERT(vp->v_count == 1);
5662 
5663 	/*
5664 	 * If we allocated an old /proc/pid node, free it too.
5665 	 */
5666 	if (pnp->pr_pidfile != NULL) {
5667 		ASSERT(type == PR_PIDDIR);
5668 		ovp = pnp->pr_pidfile;
5669 		opnp = VTOP(ovp);
5670 		ASSERT(opnp->pr_type == PR_PIDFILE);
5671 		pnp->pr_pidfile = NULL;
5672 	}
5673 
5674 	mutex_exit(&pr_pidlock);
5675 
5676 	if (p != NULL) {
5677 		/*
5678 		 * Remove the vnodes from the lists of
5679 		 * /proc vnodes for the process.
5680 		 */
5681 		int slot;
5682 
5683 		switch (type) {
5684 		case PR_PIDDIR:
5685 			pr_list_unlink(vp, &p->p_trace);
5686 			break;
5687 		case PR_LWPIDDIR:
5688 			if ((slot = pnp->pr_common->prc_tslot) != -1) {
5689 				lwpent_t *lep = p->p_lwpdir[slot].ld_entry;
5690 				pr_list_unlink(vp, &lep->le_trace);
5691 			}
5692 			break;
5693 		default:
5694 			pr_list_unlink(vp, &p->p_plist);
5695 			break;
5696 		}
5697 		if (ovp != NULL)
5698 			pr_list_unlink(ovp, &p->p_plist);
5699 		mutex_exit(&p->p_lock);
5700 	}
5701 
5702 	mutex_exit(&vp->v_lock);
5703 
5704 	if (type == PR_CT && pnp->pr_contract != NULL) {
5705 		contract_rele(pnp->pr_contract);
5706 		pnp->pr_contract = NULL;
5707 	}
5708 
5709 	if (opnp != NULL)
5710 		prfreenode(opnp);
5711 	prfreenode(pnp);
5712 	if (dp != NULL) {
5713 		VN_RELE(dp);
5714 	}
5715 }
5716 
5717 /* ARGSUSED */
5718 static int
5719 prseek(vnode_t *vp, offset_t ooff, offset_t *noffp, caller_context_t *ct)
5720 {
5721 	return (0);
5722 }
5723 
5724 /*
5725  * We use the p_execdir member of proc_t to expand the %d token in core file
5726  * paths (the directory path for the executable that dumped core; see
5727  * coreadm(1M) for details). We'd like gcore(1) to be able to expand %d in
5728  * the same way as core dumping from the kernel, but there's no convenient
5729  * and comprehensible way to export the path name for p_execdir. To solve
5730  * this, we try to find the actual path to the executable that was used. In
5731  * pr_lookup_pathdir(), we mark the a.out path name vnode with the PR_AOUT
5732  * flag, and use that here to indicate that more work is needed beyond the
5733  * call to vnodetopath().
5734  */
5735 static int
5736 prreadlink_lookup(prnode_t *pnp, char *buf, size_t size, cred_t *cr)
5737 {
5738 	proc_t *p;
5739 	vnode_t *vp, *execvp, *vrootp;
5740 	int ret;
5741 	size_t len;
5742 	dirent64_t *dp;
5743 	size_t dlen = DIRENT64_RECLEN(MAXPATHLEN);
5744 	char *dbuf;
5745 
5746 	p = curproc;
5747 	mutex_enter(&p->p_lock);
5748 	if ((vrootp = PTOU(p)->u_rdir) == NULL)
5749 		vrootp = rootdir;
5750 	VN_HOLD(vrootp);
5751 	mutex_exit(&p->p_lock);
5752 
5753 	ret = vnodetopath(vrootp, pnp->pr_realvp, buf, size, cr);
5754 
5755 	/*
5756 	 * If PR_AOUT isn't set, then we looked up the path for the vnode;
5757 	 * otherwise, we looked up the path for (what we believe to be) the
5758 	 * containing directory.
5759 	 */
5760 	if ((pnp->pr_flags & PR_AOUT) == 0) {
5761 		VN_RELE(vrootp);
5762 		return (ret);
5763 	}
5764 
5765 	/*
5766 	 * Fail if there's a problem locking the process. This will only
5767 	 * occur if the process is changing so the information we would
5768 	 * report would already be invalid.
5769 	 */
5770 	if (prlock(pnp, ZNO) != 0) {
5771 		VN_RELE(vrootp);
5772 		return (EIO);
5773 	}
5774 
5775 	p = pnp->pr_common->prc_proc;
5776 	mutex_exit(&p->p_lock);
5777 
5778 	execvp = p->p_exec;
5779 	VN_HOLD(execvp);
5780 
5781 	/*
5782 	 * If our initial lookup of the directory failed, fall back to
5783 	 * the path name information for p_exec.
5784 	 */
5785 	if (ret != 0) {
5786 		mutex_enter(&p->p_lock);
5787 		prunlock(pnp);
5788 		ret = vnodetopath(vrootp, execvp, buf, size, cr);
5789 		VN_RELE(execvp);
5790 		VN_RELE(vrootp);
5791 		return (ret);
5792 	}
5793 
5794 	len = strlen(buf);
5795 
5796 	/*
5797 	 * We use u_comm as a guess for the last component of the full
5798 	 * executable path name. If there isn't going to be enough space
5799 	 * we fall back to using the p_exec so that we can have _an_
5800 	 * answer even if it's not perfect.
5801 	 */
5802 	if (strlen(PTOU(p)->u_comm) + len + 1 < size) {
5803 		buf[len] = '/';
5804 		(void) strcpy(buf + len + 1, PTOU(p)->u_comm);
5805 		mutex_enter(&p->p_lock);
5806 		prunlock(pnp);
5807 
5808 		/*
5809 		 * Do a forward lookup of our u_comm guess.
5810 		 */
5811 		if (lookupnameat(buf + len + 1, UIO_SYSSPACE, FOLLOW, NULLVPP,
5812 		    &vp, pnp->pr_realvp) == 0) {
5813 			if (vn_compare(vp, execvp)) {
5814 				VN_RELE(vp);
5815 				VN_RELE(execvp);
5816 				VN_RELE(vrootp);
5817 				return (0);
5818 			}
5819 
5820 			VN_RELE(vp);
5821 		}
5822 	} else {
5823 		mutex_enter(&p->p_lock);
5824 		prunlock(pnp);
5825 	}
5826 
5827 	dbuf = kmem_alloc(dlen, KM_SLEEP);
5828 
5829 	/*
5830 	 * Try to find a matching vnode by iterating through the directory's
5831 	 * entries. If that fails, fall back to the path information for
5832 	 * p_exec.
5833 	 */
5834 	if ((ret = dirfindvp(vrootp, pnp->pr_realvp, execvp, cr, dbuf,
5835 	    dlen, &dp)) == 0 && strlen(dp->d_name) + len + 1 < size) {
5836 		buf[len] = '/';
5837 		(void) strcpy(buf + len + 1, dp->d_name);
5838 	} else {
5839 		ret = vnodetopath(vrootp, execvp, buf, size, cr);
5840 	}
5841 
5842 	kmem_free(dbuf, dlen);
5843 	VN_RELE(execvp);
5844 	VN_RELE(vrootp);
5845 
5846 	return (ret);
5847 }
5848 
5849 /* ARGSUSED */
5850 static int
5851 prreadlink(vnode_t *vp, uio_t *uiop, cred_t *cr, caller_context_t *ctp)
5852 {
5853 	prnode_t *pnp = VTOP(vp);
5854 	char *buf;
5855 	int ret = EINVAL;
5856 	char idbuf[16];
5857 	int length, rlength;
5858 	contract_t *ct;
5859 
5860 	switch (pnp->pr_type) {
5861 	case PR_SELF:
5862 		(void) snprintf(idbuf, sizeof (idbuf), "%d", curproc->p_pid);
5863 		ret = uiomove(idbuf, strlen(idbuf), UIO_READ, uiop);
5864 		break;
5865 	case PR_OBJECT:
5866 	case PR_FD:
5867 	case PR_CURDIR:
5868 	case PR_ROOTDIR:
5869 		if (pnp->pr_realvp->v_type == VDIR)
5870 			ret = 0;
5871 		break;
5872 	case PR_PATH:
5873 		buf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
5874 
5875 		if ((ret = prreadlink_lookup(pnp, buf, MAXPATHLEN, cr)) == 0)
5876 			ret = uiomove(buf, strlen(buf), UIO_READ, uiop);
5877 
5878 		kmem_free(buf, MAXPATHLEN);
5879 		break;
5880 	case PR_CT:
5881 		ASSERT(pnp->pr_contract != NULL);
5882 		ct = pnp->pr_contract;
5883 		length = sizeof (CTFS_ROOT "//") + sizeof (idbuf) +
5884 		    strlen(ct->ct_type->ct_type_name);
5885 		buf = kmem_alloc(length, KM_SLEEP);
5886 		rlength = snprintf(buf, length, CTFS_ROOT "/%s/%d",
5887 		    ct->ct_type->ct_type_name, ct->ct_id);
5888 		ASSERT(rlength < length);
5889 		ret = uiomove(buf, rlength, UIO_READ, uiop);
5890 		kmem_free(buf, length);
5891 		break;
5892 	default:
5893 		break;
5894 	}
5895 
5896 	return (ret);
5897 }
5898 
5899 /*ARGSUSED2*/
5900 static int
5901 prcmp(vnode_t *vp1, vnode_t *vp2, caller_context_t *ct)
5902 {
5903 	prnode_t *pp1, *pp2;
5904 
5905 	if (vp1 == vp2)
5906 		return (1);
5907 
5908 	if (!vn_matchops(vp1, prvnodeops) || !vn_matchops(vp2, prvnodeops))
5909 		return (0);
5910 
5911 	pp1 = VTOP(vp1);
5912 	pp2 = VTOP(vp2);
5913 
5914 	if (pp1->pr_type != pp2->pr_type)
5915 		return (0);
5916 	if (pp1->pr_type == PR_PROCDIR)
5917 		return (1);
5918 	if (pp1->pr_ino || pp2->pr_ino)
5919 		return (pp2->pr_ino == pp1->pr_ino);
5920 
5921 	if (pp1->pr_common == NULL || pp2->pr_common == NULL)
5922 		return (0);
5923 
5924 	return (pp1->pr_common->prc_slot == pp2->pr_common->prc_slot &&
5925 	    pp1->pr_common->prc_tslot == pp2->pr_common->prc_tslot);
5926 }
5927 
5928 static int
5929 prrealvp(vnode_t *vp, vnode_t **vpp, caller_context_t *ct)
5930 {
5931 	vnode_t *rvp;
5932 
5933 	if ((rvp = VTOP(vp)->pr_realvp) != NULL) {
5934 		vp = rvp;
5935 		if (VOP_REALVP(vp, &rvp, ct) == 0)
5936 			vp = rvp;
5937 	}
5938 
5939 	*vpp = vp;
5940 	return (0);
5941 }
5942 
5943 /*
5944  * Return the answer requested to poll().
5945  * POLLIN, POLLRDNORM, and POLLOUT are recognized as in fs_poll().
5946  * In addition, these have special meaning for /proc files:
5947  *	POLLPRI		process or lwp stopped on an event of interest
5948  *	POLLERR		/proc file descriptor is invalid
5949  *	POLLHUP		process or lwp has terminated
5950  */
5951 /*ARGSUSED5*/
5952 static int
5953 prpoll(vnode_t *vp, short events, int anyyet, short *reventsp,
5954     pollhead_t **phpp, caller_context_t *ct)
5955 {
5956 	prnode_t *pnp = VTOP(vp);
5957 	prcommon_t *pcp = pnp->pr_common;
5958 	pollhead_t *php = &pcp->prc_pollhead;
5959 	proc_t *p;
5960 	short revents;
5961 	int error;
5962 	int lockstate;
5963 
5964 	ASSERT(pnp->pr_type < PR_NFILES);
5965 
5966 	/*
5967 	 * Support for old /proc interface.
5968 	 */
5969 	if (pnp->pr_pidfile != NULL) {
5970 		vp = pnp->pr_pidfile;
5971 		pnp = VTOP(vp);
5972 		ASSERT(pnp->pr_type == PR_PIDFILE);
5973 		ASSERT(pnp->pr_common == pcp);
5974 	}
5975 
5976 	*reventsp = revents = 0;
5977 	*phpp = (pollhead_t *)NULL;
5978 
5979 	if (vp->v_type == VDIR) {
5980 		*reventsp |= POLLNVAL;
5981 		return (0);
5982 	}
5983 
5984 	/* avoid deadlock with prnotify() */
5985 	if (pollunlock(&lockstate) != 0) {
5986 		*reventsp = POLLNVAL;
5987 		return (0);
5988 	}
5989 
5990 	if ((error = prlock(pnp, ZNO)) != 0) {
5991 		pollrelock(lockstate);
5992 		switch (error) {
5993 		case ENOENT:		/* process or lwp died */
5994 			*reventsp = POLLHUP;
5995 			error = 0;
5996 			break;
5997 		case EAGAIN:		/* invalidated */
5998 			*reventsp = POLLERR;
5999 			error = 0;
6000 			break;
6001 		}
6002 		return (error);
6003 	}
6004 
6005 	/*
6006 	 * We have the process marked locked (P_PR_LOCK) and we are holding
6007 	 * its p->p_lock.  We want to unmark the process but retain
6008 	 * exclusive control w.r.t. other /proc controlling processes
6009 	 * before reacquiring the polling locks.
6010 	 *
6011 	 * prunmark() does this for us.  It unmarks the process
6012 	 * but retains p->p_lock so we still have exclusive control.
6013 	 * We will drop p->p_lock at the end to relinquish control.
6014 	 *
6015 	 * We cannot call prunlock() at the end to relinquish control
6016 	 * because prunlock(), like prunmark(), may drop and reacquire
6017 	 * p->p_lock and that would lead to a lock order violation
6018 	 * w.r.t. the polling locks we are about to reacquire.
6019 	 */
6020 	p = pcp->prc_proc;
6021 	ASSERT(p != NULL);
6022 	prunmark(p);
6023 
6024 	pollrelock(lockstate);		/* reacquire dropped poll locks */
6025 
6026 	if ((p->p_flag & SSYS) || p->p_as == &kas)
6027 		revents = POLLNVAL;
6028 	else {
6029 		short ev;
6030 
6031 		if ((ev = (events & (POLLIN|POLLRDNORM))) != 0)
6032 			revents |= ev;
6033 		/*
6034 		 * POLLWRNORM (same as POLLOUT) really should not be
6035 		 * used to indicate that the process or lwp stopped.
6036 		 * However, USL chose to use POLLWRNORM rather than
6037 		 * POLLPRI to indicate this, so we just accept either
6038 		 * requested event to indicate stopped.  (grr...)
6039 		 */
6040 		if ((ev = (events & (POLLPRI|POLLOUT|POLLWRNORM))) != 0) {
6041 			kthread_t *t;
6042 
6043 			if (pcp->prc_flags & PRC_LWP) {
6044 				t = pcp->prc_thread;
6045 				ASSERT(t != NULL);
6046 				thread_lock(t);
6047 			} else {
6048 				t = prchoose(p);	/* returns locked t */
6049 				ASSERT(t != NULL);
6050 			}
6051 
6052 			if (ISTOPPED(t) || VSTOPPED(t))
6053 				revents |= ev;
6054 			thread_unlock(t);
6055 		}
6056 	}
6057 
6058 	*reventsp = revents;
6059 	if ((!anyyet && revents == 0) || (events & POLLET)) {
6060 		/*
6061 		 * Arrange to wake up the polling lwp when
6062 		 * the target process/lwp stops or terminates
6063 		 * or when the file descriptor becomes invalid.
6064 		 */
6065 		pcp->prc_flags |= PRC_POLL;
6066 		*phpp = php;
6067 	}
6068 	mutex_exit(&p->p_lock);
6069 	return (0);
6070 }
6071 
6072 /* in prioctl.c */
6073 extern int prioctl(vnode_t *, int, intptr_t, int, cred_t *, int *,
6074 	caller_context_t *);
6075 
6076 /*
6077  * /proc vnode operations vector
6078  */
6079 const fs_operation_def_t pr_vnodeops_template[] = {
6080 	VOPNAME_OPEN,		{ .vop_open = propen },
6081 	VOPNAME_CLOSE,		{ .vop_close = prclose },
6082 	VOPNAME_READ,		{ .vop_read = prread },
6083 	VOPNAME_WRITE,		{ .vop_write = prwrite },
6084 	VOPNAME_IOCTL,		{ .vop_ioctl = prioctl },
6085 	VOPNAME_GETATTR,	{ .vop_getattr = prgetattr },
6086 	VOPNAME_ACCESS,		{ .vop_access = praccess },
6087 	VOPNAME_LOOKUP,		{ .vop_lookup = prlookup },
6088 	VOPNAME_CREATE,		{ .vop_create = prcreate },
6089 	VOPNAME_READDIR,	{ .vop_readdir = prreaddir },
6090 	VOPNAME_READLINK,	{ .vop_readlink = prreadlink },
6091 	VOPNAME_FSYNC,		{ .vop_fsync = prfsync },
6092 	VOPNAME_INACTIVE,	{ .vop_inactive = prinactive },
6093 	VOPNAME_SEEK,		{ .vop_seek = prseek },
6094 	VOPNAME_CMP,		{ .vop_cmp = prcmp },
6095 	VOPNAME_FRLOCK,		{ .error = fs_error },
6096 	VOPNAME_REALVP,		{ .vop_realvp = prrealvp },
6097 	VOPNAME_POLL,		{ .vop_poll = prpoll },
6098 	VOPNAME_DISPOSE,	{ .error = fs_error },
6099 	VOPNAME_SHRLOCK,	{ .error = fs_error },
6100 	NULL,			NULL
6101 };
6102