xref: /illumos-gate/usr/src/uts/common/fs/proc/prvnops.c (revision d2a70789f056fc6c9ce3ab047b52126d80b0e3da)
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 (c) 2014, Joyent, Inc. All rights reserved.
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)	/* can't O_CREAT nonexistent files */
3432 			error = EACCES;		/* unwriteable directories */
3433 	} else {
3434 		if (excl == EXCL)			/* O_EXCL */
3435 			error = EEXIST;
3436 		else if (vap->va_mask & AT_SIZE) {	/* O_TRUNC */
3437 			vnode_t *vp = *vpp;
3438 			uint_t mask;
3439 
3440 			if (vp->v_type == VDIR)
3441 				error = EISDIR;
3442 			else if (vp->v_type != VPROC ||
3443 			    VTOP(vp)->pr_type != PR_FD)
3444 				error = EACCES;
3445 			else {		/* /proc/<pid>/fd/<n> */
3446 				vp = VTOP(vp)->pr_realvp;
3447 				mask = vap->va_mask;
3448 				vap->va_mask = AT_SIZE;
3449 				error = VOP_SETATTR(vp, vap, 0, cr, ct);
3450 				vap->va_mask = mask;
3451 			}
3452 		}
3453 		if (error) {
3454 			VN_RELE(*vpp);
3455 			*vpp = NULL;
3456 		}
3457 	}
3458 	return (error);
3459 }
3460 
3461 /* ARGSUSED */
3462 static vnode_t *
3463 pr_lookup_notdir(vnode_t *dp, char *comp)
3464 {
3465 	return (NULL);
3466 }
3467 
3468 /*
3469  * Find or construct a process vnode for the given pid.
3470  */
3471 static vnode_t *
3472 pr_lookup_procdir(vnode_t *dp, char *comp)
3473 {
3474 	pid_t pid;
3475 	prnode_t *pnp;
3476 	prcommon_t *pcp;
3477 	vnode_t *vp;
3478 	proc_t *p;
3479 	int c;
3480 
3481 	ASSERT(VTOP(dp)->pr_type == PR_PROCDIR);
3482 
3483 	if (strcmp(comp, "self") == 0) {
3484 		pnp = prgetnode(dp, PR_SELF);
3485 		return (PTOV(pnp));
3486 	} else {
3487 		pid = 0;
3488 		while ((c = *comp++) != '\0') {
3489 			if (c < '0' || c > '9')
3490 				return (NULL);
3491 			pid = 10*pid + c - '0';
3492 			if (pid > maxpid)
3493 				return (NULL);
3494 		}
3495 	}
3496 
3497 	pnp = prgetnode(dp, PR_PIDDIR);
3498 
3499 	mutex_enter(&pidlock);
3500 	if ((p = prfind(pid)) == NULL || p->p_stat == SIDL) {
3501 		mutex_exit(&pidlock);
3502 		prfreenode(pnp);
3503 		return (NULL);
3504 	}
3505 	ASSERT(p->p_stat != 0);
3506 
3507 	/* NOTE: we're holding pidlock across the policy call. */
3508 	if (secpolicy_basic_procinfo(CRED(), p, curproc) != 0) {
3509 		mutex_exit(&pidlock);
3510 		prfreenode(pnp);
3511 		return (NULL);
3512 	}
3513 
3514 	mutex_enter(&p->p_lock);
3515 	mutex_exit(&pidlock);
3516 
3517 	/*
3518 	 * If a process vnode already exists and it is not invalid
3519 	 * and it was created by the current process and it belongs
3520 	 * to the same /proc mount point as our parent vnode, then
3521 	 * just use it and discard the newly-allocated prnode.
3522 	 */
3523 	for (vp = p->p_trace; vp != NULL; vp = VTOP(vp)->pr_next) {
3524 		if (!(VTOP(VTOP(vp)->pr_pidfile)->pr_flags & PR_INVAL) &&
3525 		    VTOP(vp)->pr_owner == curproc &&
3526 		    vp->v_vfsp == dp->v_vfsp) {
3527 			ASSERT(!(VTOP(vp)->pr_flags & PR_INVAL));
3528 			VN_HOLD(vp);
3529 			prfreenode(pnp);
3530 			mutex_exit(&p->p_lock);
3531 			return (vp);
3532 		}
3533 	}
3534 	pnp->pr_owner = curproc;
3535 
3536 	/*
3537 	 * prgetnode() initialized most of the prnode.
3538 	 * Finish the job.
3539 	 */
3540 	pcp = pnp->pr_common;	/* the newly-allocated prcommon struct */
3541 	if ((vp = p->p_trace) != NULL) {
3542 		/* discard the new prcommon and use the existing prcommon */
3543 		prfreecommon(pcp);
3544 		pcp = VTOP(vp)->pr_common;
3545 		mutex_enter(&pcp->prc_mutex);
3546 		ASSERT(pcp->prc_refcnt > 0);
3547 		pcp->prc_refcnt++;
3548 		mutex_exit(&pcp->prc_mutex);
3549 		pnp->pr_common = pcp;
3550 	} else {
3551 		/* initialize the new prcommon struct */
3552 		if ((p->p_flag & SSYS) || p->p_as == &kas)
3553 			pcp->prc_flags |= PRC_SYS;
3554 		if (p->p_stat == SZOMB)
3555 			pcp->prc_flags |= PRC_DESTROY;
3556 		pcp->prc_proc = p;
3557 		pcp->prc_datamodel = p->p_model;
3558 		pcp->prc_pid = p->p_pid;
3559 		pcp->prc_slot = p->p_slot;
3560 	}
3561 	pnp->pr_pcommon = pcp;
3562 	pnp->pr_parent = dp;
3563 	VN_HOLD(dp);
3564 	/*
3565 	 * Link in the old, invalid directory vnode so we
3566 	 * can later determine the last close of the file.
3567 	 */
3568 	pnp->pr_next = p->p_trace;
3569 	p->p_trace = dp = PTOV(pnp);
3570 
3571 	/*
3572 	 * Kludge for old /proc: initialize the PR_PIDFILE as well.
3573 	 */
3574 	vp = pnp->pr_pidfile;
3575 	pnp = VTOP(vp);
3576 	pnp->pr_ino = ptoi(pcp->prc_pid);
3577 	pnp->pr_common = pcp;
3578 	pnp->pr_pcommon = pcp;
3579 	pnp->pr_parent = dp;
3580 	pnp->pr_next = p->p_plist;
3581 	p->p_plist = vp;
3582 
3583 	mutex_exit(&p->p_lock);
3584 	return (dp);
3585 }
3586 
3587 static vnode_t *
3588 pr_lookup_piddir(vnode_t *dp, char *comp)
3589 {
3590 	prnode_t *dpnp = VTOP(dp);
3591 	vnode_t *vp;
3592 	prnode_t *pnp;
3593 	proc_t *p;
3594 	user_t *up;
3595 	prdirent_t *dirp;
3596 	int i;
3597 	enum prnodetype type;
3598 
3599 	ASSERT(dpnp->pr_type == PR_PIDDIR);
3600 
3601 	for (i = 0; i < NPIDDIRFILES; i++) {
3602 		/* Skip "." and ".." */
3603 		dirp = &piddir[i+2];
3604 		if (strcmp(comp, dirp->d_name) == 0)
3605 			break;
3606 	}
3607 
3608 	if (i >= NPIDDIRFILES)
3609 		return (NULL);
3610 
3611 	type = (int)dirp->d_ino;
3612 	pnp = prgetnode(dp, type);
3613 
3614 	p = pr_p_lock(dpnp);
3615 	mutex_exit(&pr_pidlock);
3616 	if (p == NULL) {
3617 		prfreenode(pnp);
3618 		return (NULL);
3619 	}
3620 	if (dpnp->pr_pcommon->prc_flags & PRC_DESTROY) {
3621 		switch (type) {
3622 		case PR_PSINFO:
3623 		case PR_USAGE:
3624 			break;
3625 		default:
3626 			prunlock(dpnp);
3627 			prfreenode(pnp);
3628 			return (NULL);
3629 		}
3630 	}
3631 
3632 	switch (type) {
3633 	case PR_CURDIR:
3634 	case PR_ROOTDIR:
3635 		up = PTOU(p);
3636 		vp = (type == PR_CURDIR)? up->u_cdir :
3637 		    (up->u_rdir? up->u_rdir : rootdir);
3638 
3639 		if (vp == NULL) {	/* can't happen? */
3640 			prunlock(dpnp);
3641 			prfreenode(pnp);
3642 			return (NULL);
3643 		}
3644 		/*
3645 		 * Fill in the prnode so future references will
3646 		 * be able to find the underlying object's vnode.
3647 		 */
3648 		VN_HOLD(vp);
3649 		pnp->pr_realvp = vp;
3650 		break;
3651 	default:
3652 		break;
3653 	}
3654 
3655 	mutex_enter(&dpnp->pr_mutex);
3656 
3657 	if ((vp = dpnp->pr_files[i]) != NULL &&
3658 	    !(VTOP(vp)->pr_flags & PR_INVAL)) {
3659 		VN_HOLD(vp);
3660 		mutex_exit(&dpnp->pr_mutex);
3661 		prunlock(dpnp);
3662 		prfreenode(pnp);
3663 		return (vp);
3664 	}
3665 
3666 	/*
3667 	 * prgetnode() initialized most of the prnode.
3668 	 * Finish the job.
3669 	 */
3670 	pnp->pr_common = dpnp->pr_common;
3671 	pnp->pr_pcommon = dpnp->pr_pcommon;
3672 	pnp->pr_parent = dp;
3673 	VN_HOLD(dp);
3674 	pnp->pr_index = i;
3675 
3676 	dpnp->pr_files[i] = vp = PTOV(pnp);
3677 
3678 	/*
3679 	 * Link new vnode into list of all /proc vnodes for the process.
3680 	 */
3681 	if (vp->v_type == VPROC) {
3682 		pnp->pr_next = p->p_plist;
3683 		p->p_plist = vp;
3684 	}
3685 	mutex_exit(&dpnp->pr_mutex);
3686 	prunlock(dpnp);
3687 	return (vp);
3688 }
3689 
3690 static vnode_t *
3691 pr_lookup_objectdir(vnode_t *dp, char *comp)
3692 {
3693 	prnode_t *dpnp = VTOP(dp);
3694 	prnode_t *pnp;
3695 	proc_t *p;
3696 	struct seg *seg;
3697 	struct as *as;
3698 	vnode_t *vp;
3699 	vattr_t vattr;
3700 
3701 	ASSERT(dpnp->pr_type == PR_OBJECTDIR);
3702 
3703 	pnp = prgetnode(dp, PR_OBJECT);
3704 
3705 	if (prlock(dpnp, ZNO) != 0) {
3706 		prfreenode(pnp);
3707 		return (NULL);
3708 	}
3709 	p = dpnp->pr_common->prc_proc;
3710 	if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
3711 		prunlock(dpnp);
3712 		prfreenode(pnp);
3713 		return (NULL);
3714 	}
3715 
3716 	/*
3717 	 * We drop p_lock before grabbing the address space lock
3718 	 * in order to avoid a deadlock with the clock thread.
3719 	 * The process will not disappear and its address space
3720 	 * will not change because it is marked P_PR_LOCK.
3721 	 */
3722 	mutex_exit(&p->p_lock);
3723 	AS_LOCK_ENTER(as, RW_READER);
3724 	if ((seg = AS_SEGFIRST(as)) == NULL) {
3725 		vp = NULL;
3726 		goto out;
3727 	}
3728 	if (strcmp(comp, "a.out") == 0) {
3729 		vp = p->p_exec;
3730 		goto out;
3731 	}
3732 	do {
3733 		/*
3734 		 * Manufacture a filename for the "object" directory.
3735 		 */
3736 		vattr.va_mask = AT_FSID|AT_NODEID;
3737 		if (seg->s_ops == &segvn_ops &&
3738 		    SEGOP_GETVP(seg, seg->s_base, &vp) == 0 &&
3739 		    vp != NULL && vp->v_type == VREG &&
3740 		    VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
3741 			char name[64];
3742 
3743 			if (vp == p->p_exec)	/* "a.out" */
3744 				continue;
3745 			pr_object_name(name, vp, &vattr);
3746 			if (strcmp(name, comp) == 0)
3747 				goto out;
3748 		}
3749 	} while ((seg = AS_SEGNEXT(as, seg)) != NULL);
3750 
3751 	vp = NULL;
3752 out:
3753 	if (vp != NULL) {
3754 		VN_HOLD(vp);
3755 	}
3756 	AS_LOCK_EXIT(as);
3757 	mutex_enter(&p->p_lock);
3758 	prunlock(dpnp);
3759 
3760 	if (vp == NULL)
3761 		prfreenode(pnp);
3762 	else {
3763 		/*
3764 		 * Fill in the prnode so future references will
3765 		 * be able to find the underlying object's vnode.
3766 		 * Don't link this prnode into the list of all
3767 		 * prnodes for the process; this is a one-use node.
3768 		 * Its use is entirely to catch and fail opens for writing.
3769 		 */
3770 		pnp->pr_realvp = vp;
3771 		vp = PTOV(pnp);
3772 	}
3773 
3774 	return (vp);
3775 }
3776 
3777 /*
3778  * Find or construct an lwp vnode for the given lwpid.
3779  */
3780 static vnode_t *
3781 pr_lookup_lwpdir(vnode_t *dp, char *comp)
3782 {
3783 	id_t tid;	/* same type as t->t_tid */
3784 	int want_agent;
3785 	prnode_t *dpnp = VTOP(dp);
3786 	prnode_t *pnp;
3787 	prcommon_t *pcp;
3788 	vnode_t *vp;
3789 	proc_t *p;
3790 	kthread_t *t;
3791 	lwpdir_t *ldp;
3792 	lwpent_t *lep;
3793 	int tslot;
3794 	int c;
3795 
3796 	ASSERT(dpnp->pr_type == PR_LWPDIR);
3797 
3798 	tid = 0;
3799 	if (strcmp(comp, "agent") == 0)
3800 		want_agent = 1;
3801 	else {
3802 		want_agent = 0;
3803 		while ((c = *comp++) != '\0') {
3804 			id_t otid;
3805 
3806 			if (c < '0' || c > '9')
3807 				return (NULL);
3808 			otid = tid;
3809 			tid = 10*tid + c - '0';
3810 			if (tid/10 != otid)	/* integer overflow */
3811 				return (NULL);
3812 		}
3813 	}
3814 
3815 	pnp = prgetnode(dp, PR_LWPIDDIR);
3816 
3817 	p = pr_p_lock(dpnp);
3818 	mutex_exit(&pr_pidlock);
3819 	if (p == NULL) {
3820 		prfreenode(pnp);
3821 		return (NULL);
3822 	}
3823 
3824 	if (want_agent) {
3825 		if ((t = p->p_agenttp) == NULL)
3826 			lep = NULL;
3827 		else {
3828 			tid = t->t_tid;
3829 			tslot = t->t_dslot;
3830 			lep = p->p_lwpdir[tslot].ld_entry;
3831 		}
3832 	} else {
3833 		if ((ldp = lwp_hash_lookup(p, tid)) == NULL)
3834 			lep = NULL;
3835 		else {
3836 			tslot = (int)(ldp - p->p_lwpdir);
3837 			lep = ldp->ld_entry;
3838 		}
3839 	}
3840 
3841 	if (lep == NULL) {
3842 		prunlock(dpnp);
3843 		prfreenode(pnp);
3844 		return (NULL);
3845 	}
3846 
3847 	/*
3848 	 * If an lwp vnode already exists and it is not invalid
3849 	 * and it was created by the current process and it belongs
3850 	 * to the same /proc mount point as our parent vnode, then
3851 	 * just use it and discard the newly-allocated prnode.
3852 	 */
3853 	for (vp = lep->le_trace; vp != NULL; vp = VTOP(vp)->pr_next) {
3854 		if (!(VTOP(vp)->pr_flags & PR_INVAL) &&
3855 		    VTOP(vp)->pr_owner == curproc &&
3856 		    vp->v_vfsp == dp->v_vfsp) {
3857 			VN_HOLD(vp);
3858 			prunlock(dpnp);
3859 			prfreenode(pnp);
3860 			return (vp);
3861 		}
3862 	}
3863 	pnp->pr_owner = curproc;
3864 
3865 	/*
3866 	 * prgetnode() initialized most of the prnode.
3867 	 * Finish the job.
3868 	 */
3869 	pcp = pnp->pr_common;	/* the newly-allocated prcommon struct */
3870 	if ((vp = lep->le_trace) != NULL) {
3871 		/* discard the new prcommon and use the existing prcommon */
3872 		prfreecommon(pcp);
3873 		pcp = VTOP(vp)->pr_common;
3874 		mutex_enter(&pcp->prc_mutex);
3875 		ASSERT(pcp->prc_refcnt > 0);
3876 		pcp->prc_refcnt++;
3877 		mutex_exit(&pcp->prc_mutex);
3878 		pnp->pr_common = pcp;
3879 	} else {
3880 		/* initialize the new prcommon struct */
3881 		pcp->prc_flags |= PRC_LWP;
3882 		if ((p->p_flag & SSYS) || p->p_as == &kas)
3883 			pcp->prc_flags |= PRC_SYS;
3884 		if ((t = lep->le_thread) == NULL)
3885 			pcp->prc_flags |= PRC_DESTROY;
3886 		pcp->prc_proc = p;
3887 		pcp->prc_datamodel = dpnp->pr_pcommon->prc_datamodel;
3888 		pcp->prc_pid = p->p_pid;
3889 		pcp->prc_slot = p->p_slot;
3890 		pcp->prc_thread = t;
3891 		pcp->prc_tid = tid;
3892 		pcp->prc_tslot = tslot;
3893 	}
3894 	pnp->pr_pcommon = dpnp->pr_pcommon;
3895 	pnp->pr_parent = dp;
3896 	VN_HOLD(dp);
3897 	/*
3898 	 * Link in the old, invalid directory vnode so we
3899 	 * can later determine the last close of the file.
3900 	 */
3901 	pnp->pr_next = lep->le_trace;
3902 	lep->le_trace = vp = PTOV(pnp);
3903 	prunlock(dpnp);
3904 	return (vp);
3905 }
3906 
3907 static vnode_t *
3908 pr_lookup_lwpiddir(vnode_t *dp, char *comp)
3909 {
3910 	prnode_t *dpnp = VTOP(dp);
3911 	vnode_t *vp;
3912 	prnode_t *pnp;
3913 	proc_t *p;
3914 	prdirent_t *dirp;
3915 	int i;
3916 	enum prnodetype type;
3917 
3918 	ASSERT(dpnp->pr_type == PR_LWPIDDIR);
3919 
3920 	for (i = 0; i < NLWPIDDIRFILES; i++) {
3921 		/* Skip "." and ".." */
3922 		dirp = &lwpiddir[i+2];
3923 		if (strcmp(comp, dirp->d_name) == 0)
3924 			break;
3925 	}
3926 
3927 	if (i >= NLWPIDDIRFILES)
3928 		return (NULL);
3929 
3930 	type = (int)dirp->d_ino;
3931 	pnp = prgetnode(dp, type);
3932 
3933 	p = pr_p_lock(dpnp);
3934 	mutex_exit(&pr_pidlock);
3935 	if (p == NULL) {
3936 		prfreenode(pnp);
3937 		return (NULL);
3938 	}
3939 	if (dpnp->pr_common->prc_flags & PRC_DESTROY) {
3940 		/*
3941 		 * Only the lwpsinfo file is present for zombie lwps.
3942 		 * Nothing is present if the lwp has been reaped.
3943 		 */
3944 		if (dpnp->pr_common->prc_tslot == -1 ||
3945 		    type != PR_LWPSINFO) {
3946 			prunlock(dpnp);
3947 			prfreenode(pnp);
3948 			return (NULL);
3949 		}
3950 	}
3951 
3952 #if defined(__sparc)
3953 	/* the asrs file exists only for sparc v9 _LP64 processes */
3954 	if (type == PR_ASRS && p->p_model != DATAMODEL_LP64) {
3955 		prunlock(dpnp);
3956 		prfreenode(pnp);
3957 		return (NULL);
3958 	}
3959 #endif
3960 
3961 	mutex_enter(&dpnp->pr_mutex);
3962 
3963 	if ((vp = dpnp->pr_files[i]) != NULL &&
3964 	    !(VTOP(vp)->pr_flags & PR_INVAL)) {
3965 		VN_HOLD(vp);
3966 		mutex_exit(&dpnp->pr_mutex);
3967 		prunlock(dpnp);
3968 		prfreenode(pnp);
3969 		return (vp);
3970 	}
3971 
3972 	/*
3973 	 * prgetnode() initialized most of the prnode.
3974 	 * Finish the job.
3975 	 */
3976 	pnp->pr_common = dpnp->pr_common;
3977 	pnp->pr_pcommon = dpnp->pr_pcommon;
3978 	pnp->pr_parent = dp;
3979 	VN_HOLD(dp);
3980 	pnp->pr_index = i;
3981 
3982 	dpnp->pr_files[i] = vp = PTOV(pnp);
3983 
3984 	/*
3985 	 * Link new vnode into list of all /proc vnodes for the process.
3986 	 */
3987 	if (vp->v_type == VPROC) {
3988 		pnp->pr_next = p->p_plist;
3989 		p->p_plist = vp;
3990 	}
3991 	mutex_exit(&dpnp->pr_mutex);
3992 	prunlock(dpnp);
3993 	return (vp);
3994 }
3995 
3996 /*
3997  * Lookup one of the process's open files.
3998  */
3999 static vnode_t *
4000 pr_lookup_fddir(vnode_t *dp, char *comp)
4001 {
4002 	prnode_t *dpnp = VTOP(dp);
4003 	prnode_t *pnp;
4004 	vnode_t *vp = NULL;
4005 	proc_t *p;
4006 	file_t *fp;
4007 	uint_t fd;
4008 	int c;
4009 	uf_entry_t *ufp;
4010 	uf_info_t *fip;
4011 
4012 	ASSERT(dpnp->pr_type == PR_FDDIR);
4013 
4014 	fd = 0;
4015 	while ((c = *comp++) != '\0') {
4016 		int ofd;
4017 		if (c < '0' || c > '9')
4018 			return (NULL);
4019 		ofd = fd;
4020 		fd = 10*fd + c - '0';
4021 		if (fd/10 != ofd)	/* integer overflow */
4022 			return (NULL);
4023 	}
4024 
4025 	pnp = prgetnode(dp, PR_FD);
4026 
4027 	if (prlock(dpnp, ZNO) != 0) {
4028 		prfreenode(pnp);
4029 		return (NULL);
4030 	}
4031 	p = dpnp->pr_common->prc_proc;
4032 	if ((p->p_flag & SSYS) || p->p_as == &kas) {
4033 		prunlock(dpnp);
4034 		prfreenode(pnp);
4035 		return (NULL);
4036 	}
4037 
4038 	fip = P_FINFO(p);
4039 	mutex_exit(&p->p_lock);
4040 	mutex_enter(&fip->fi_lock);
4041 	if (fd < fip->fi_nfiles) {
4042 		UF_ENTER(ufp, fip, fd);
4043 		if ((fp = ufp->uf_file) != NULL) {
4044 			pnp->pr_mode = 07111;
4045 			if (fp->f_flag & FREAD)
4046 				pnp->pr_mode |= 0444;
4047 			if (fp->f_flag & FWRITE)
4048 				pnp->pr_mode |= 0222;
4049 			vp = fp->f_vnode;
4050 			VN_HOLD(vp);
4051 		}
4052 		UF_EXIT(ufp);
4053 	}
4054 	mutex_exit(&fip->fi_lock);
4055 	mutex_enter(&p->p_lock);
4056 	prunlock(dpnp);
4057 
4058 	if (vp == NULL)
4059 		prfreenode(pnp);
4060 	else {
4061 		/*
4062 		 * Fill in the prnode so future references will
4063 		 * be able to find the underlying object's vnode.
4064 		 * Don't link this prnode into the list of all
4065 		 * prnodes for the process; this is a one-use node.
4066 		 */
4067 		pnp->pr_realvp = vp;
4068 		pnp->pr_parent = dp;		/* needed for prlookup */
4069 		VN_HOLD(dp);
4070 		vp = PTOV(pnp);
4071 		if (pnp->pr_realvp->v_type == VDIR)
4072 			vp->v_type = VDIR;
4073 	}
4074 
4075 	return (vp);
4076 }
4077 
4078 static vnode_t *
4079 pr_lookup_pathdir(vnode_t *dp, char *comp)
4080 {
4081 	prnode_t *dpnp = VTOP(dp);
4082 	prnode_t *pnp;
4083 	vnode_t *vp = NULL;
4084 	proc_t *p;
4085 	uint_t fd, flags = 0;
4086 	int c;
4087 	uf_entry_t *ufp;
4088 	uf_info_t *fip;
4089 	enum { NAME_FD, NAME_OBJECT, NAME_ROOT, NAME_CWD, NAME_UNKNOWN } type;
4090 	char *tmp;
4091 	int idx;
4092 	struct seg *seg;
4093 	struct as *as = NULL;
4094 	vattr_t vattr;
4095 
4096 	ASSERT(dpnp->pr_type == PR_PATHDIR);
4097 
4098 	/*
4099 	 * First, check if this is a numeric entry, in which case we have a
4100 	 * file descriptor.
4101 	 */
4102 	fd = 0;
4103 	type = NAME_FD;
4104 	tmp = comp;
4105 	while ((c = *tmp++) != '\0') {
4106 		int ofd;
4107 		if (c < '0' || c > '9') {
4108 			type = NAME_UNKNOWN;
4109 			break;
4110 		}
4111 		ofd = fd;
4112 		fd = 10*fd + c - '0';
4113 		if (fd/10 != ofd) {	/* integer overflow */
4114 			type = NAME_UNKNOWN;
4115 			break;
4116 		}
4117 	}
4118 
4119 	/*
4120 	 * Next, see if it is one of the special values {root, cwd}.
4121 	 */
4122 	if (type == NAME_UNKNOWN) {
4123 		if (strcmp(comp, "root") == 0)
4124 			type = NAME_ROOT;
4125 		else if (strcmp(comp, "cwd") == 0)
4126 			type = NAME_CWD;
4127 	}
4128 
4129 	/*
4130 	 * Grab the necessary data from the process
4131 	 */
4132 	if (prlock(dpnp, ZNO) != 0)
4133 		return (NULL);
4134 	p = dpnp->pr_common->prc_proc;
4135 
4136 	fip = P_FINFO(p);
4137 
4138 	switch (type) {
4139 	case NAME_ROOT:
4140 		if ((vp = PTOU(p)->u_rdir) == NULL)
4141 			vp = p->p_zone->zone_rootvp;
4142 		VN_HOLD(vp);
4143 		break;
4144 	case NAME_CWD:
4145 		vp = PTOU(p)->u_cdir;
4146 		VN_HOLD(vp);
4147 		break;
4148 	default:
4149 		if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
4150 			prunlock(dpnp);
4151 			return (NULL);
4152 		}
4153 	}
4154 	mutex_exit(&p->p_lock);
4155 
4156 	/*
4157 	 * Determine if this is an object entry
4158 	 */
4159 	if (type == NAME_UNKNOWN) {
4160 		/*
4161 		 * Start with the inode index immediately after the number of
4162 		 * files.
4163 		 */
4164 		mutex_enter(&fip->fi_lock);
4165 		idx = fip->fi_nfiles + 4;
4166 		mutex_exit(&fip->fi_lock);
4167 
4168 		if (strcmp(comp, "a.out") == 0) {
4169 			if (p->p_execdir != NULL) {
4170 				vp = p->p_execdir;
4171 				VN_HOLD(vp);
4172 				type = NAME_OBJECT;
4173 				flags |= PR_AOUT;
4174 			} else {
4175 				vp = p->p_exec;
4176 				VN_HOLD(vp);
4177 				type = NAME_OBJECT;
4178 			}
4179 		} else {
4180 			AS_LOCK_ENTER(as, RW_READER);
4181 			if ((seg = AS_SEGFIRST(as)) != NULL) {
4182 				do {
4183 					/*
4184 					 * Manufacture a filename for the
4185 					 * "object" directory.
4186 					 */
4187 					vattr.va_mask = AT_FSID|AT_NODEID;
4188 					if (seg->s_ops == &segvn_ops &&
4189 					    SEGOP_GETVP(seg, seg->s_base, &vp)
4190 					    == 0 &&
4191 					    vp != NULL && vp->v_type == VREG &&
4192 					    VOP_GETATTR(vp, &vattr, 0, CRED(),
4193 					    NULL) == 0) {
4194 						char name[64];
4195 
4196 						if (vp == p->p_exec)
4197 							continue;
4198 						idx++;
4199 						pr_object_name(name, vp,
4200 						    &vattr);
4201 						if (strcmp(name, comp) == 0)
4202 							break;
4203 					}
4204 				} while ((seg = AS_SEGNEXT(as, seg)) != NULL);
4205 			}
4206 
4207 			if (seg == NULL) {
4208 				vp = NULL;
4209 			} else {
4210 				VN_HOLD(vp);
4211 				type = NAME_OBJECT;
4212 			}
4213 
4214 			AS_LOCK_EXIT(as);
4215 		}
4216 	}
4217 
4218 
4219 	switch (type) {
4220 	case NAME_FD:
4221 		mutex_enter(&fip->fi_lock);
4222 		if (fd < fip->fi_nfiles) {
4223 			UF_ENTER(ufp, fip, fd);
4224 			if (ufp->uf_file != NULL) {
4225 				vp = ufp->uf_file->f_vnode;
4226 				VN_HOLD(vp);
4227 			}
4228 			UF_EXIT(ufp);
4229 		}
4230 		mutex_exit(&fip->fi_lock);
4231 		idx = fd + 4;
4232 		break;
4233 	case NAME_ROOT:
4234 		idx = 2;
4235 		break;
4236 	case NAME_CWD:
4237 		idx = 3;
4238 		break;
4239 	case NAME_OBJECT:
4240 	case NAME_UNKNOWN:
4241 		/* Nothing to do */
4242 		break;
4243 	}
4244 
4245 	mutex_enter(&p->p_lock);
4246 	prunlock(dpnp);
4247 
4248 	if (vp != NULL) {
4249 		pnp = prgetnode(dp, PR_PATH);
4250 
4251 		pnp->pr_flags |= flags;
4252 		pnp->pr_common = dpnp->pr_common;
4253 		pnp->pr_pcommon = dpnp->pr_pcommon;
4254 		pnp->pr_realvp = vp;
4255 		pnp->pr_parent = dp;		/* needed for prlookup */
4256 		pnp->pr_ino = pmkino(idx, dpnp->pr_common->prc_slot, PR_PATH);
4257 		VN_HOLD(dp);
4258 		vp = PTOV(pnp);
4259 		vp->v_type = VLNK;
4260 	}
4261 
4262 	return (vp);
4263 }
4264 
4265 /*
4266  * Look up one of the process's active templates.
4267  */
4268 static vnode_t *
4269 pr_lookup_tmpldir(vnode_t *dp, char *comp)
4270 {
4271 	prnode_t *dpnp = VTOP(dp);
4272 	prnode_t *pnp;
4273 	vnode_t *vp = NULL;
4274 	proc_t *p;
4275 	int i;
4276 
4277 	ASSERT(dpnp->pr_type == PR_TMPLDIR);
4278 
4279 	for (i = 0; i < ct_ntypes; i++)
4280 		if (strcmp(comp, ct_types[i]->ct_type_name) == 0)
4281 			break;
4282 	if (i == ct_ntypes)
4283 		return (NULL);
4284 
4285 	pnp = prgetnode(dp, PR_TMPL);
4286 
4287 	if (prlock(dpnp, ZNO) != 0) {
4288 		prfreenode(pnp);
4289 		return (NULL);
4290 	}
4291 	p = dpnp->pr_common->prc_proc;
4292 	if ((p->p_flag & SSYS) || p->p_as == &kas ||
4293 	    (dpnp->pr_common->prc_flags & (PRC_DESTROY | PRC_LWP)) != PRC_LWP) {
4294 		prunlock(dpnp);
4295 		prfreenode(pnp);
4296 		return (NULL);
4297 	}
4298 	if (ttolwp(dpnp->pr_common->prc_thread)->lwp_ct_active[i] != NULL) {
4299 		pnp->pr_common = dpnp->pr_common;
4300 		pnp->pr_pcommon = dpnp->pr_pcommon;
4301 		pnp->pr_parent = dp;
4302 		pnp->pr_cttype = i;
4303 		VN_HOLD(dp);
4304 		vp = PTOV(pnp);
4305 	} else {
4306 		prfreenode(pnp);
4307 	}
4308 	prunlock(dpnp);
4309 
4310 	return (vp);
4311 }
4312 
4313 /*
4314  * Look up one of the contracts owned by the process.
4315  */
4316 static vnode_t *
4317 pr_lookup_ctdir(vnode_t *dp, char *comp)
4318 {
4319 	prnode_t *dpnp = VTOP(dp);
4320 	prnode_t *pnp;
4321 	vnode_t *vp = NULL;
4322 	proc_t *p;
4323 	id_t id = 0;
4324 	contract_t *ct;
4325 	int c;
4326 
4327 	ASSERT(dpnp->pr_type == PR_CTDIR);
4328 
4329 	while ((c = *comp++) != '\0') {
4330 		id_t oid;
4331 		if (c < '0' || c > '9')
4332 			return (NULL);
4333 		oid = id;
4334 		id = 10 * id + c - '0';
4335 		if (id / 10 != oid)	/* integer overflow */
4336 			return (NULL);
4337 	}
4338 
4339 	/*
4340 	 * Search all contracts; we'll filter below.
4341 	 */
4342 	ct = contract_ptr(id, GLOBAL_ZONEUNIQID);
4343 	if (ct == NULL)
4344 		return (NULL);
4345 
4346 	pnp = prgetnode(dp, PR_CT);
4347 
4348 	if (prlock(dpnp, ZNO) != 0) {
4349 		prfreenode(pnp);
4350 		contract_rele(ct);
4351 		return (NULL);
4352 	}
4353 	p = dpnp->pr_common->prc_proc;
4354 	/*
4355 	 * We only allow lookups of contracts owned by this process, or,
4356 	 * if we are zsched and this is a zone's procfs, contracts on
4357 	 * stuff in the zone which are held by processes or contracts
4358 	 * outside the zone.  (see logic in contract_status_common)
4359 	 */
4360 	if ((ct->ct_owner != p) &&
4361 	    !(p == VTOZONE(dp)->zone_zsched && ct->ct_state < CTS_ORPHAN &&
4362 	    VTOZONE(dp)->zone_uniqid == contract_getzuniqid(ct) &&
4363 	    VTOZONE(dp)->zone_uniqid != GLOBAL_ZONEUNIQID &&
4364 	    ct->ct_czuniqid == GLOBAL_ZONEUNIQID)) {
4365 		prunlock(dpnp);
4366 		prfreenode(pnp);
4367 		contract_rele(ct);
4368 		return (NULL);
4369 	}
4370 	pnp->pr_common = dpnp->pr_common;
4371 	pnp->pr_pcommon = dpnp->pr_pcommon;
4372 	pnp->pr_contract = ct;
4373 	pnp->pr_parent = dp;
4374 	pnp->pr_ino = pmkino(id, pnp->pr_common->prc_slot, PR_CT);
4375 	VN_HOLD(dp);
4376 	prunlock(dpnp);
4377 	vp = PTOV(pnp);
4378 
4379 	return (vp);
4380 }
4381 
4382 /*
4383  * Construct an lwp vnode for the old /proc interface.
4384  * We stand on our head to make the /proc plumbing correct.
4385  */
4386 vnode_t *
4387 prlwpnode(prnode_t *pnp, uint_t tid)
4388 {
4389 	char comp[12];
4390 	vnode_t *dp;
4391 	vnode_t *vp;
4392 	prcommon_t *pcp;
4393 	proc_t *p;
4394 
4395 	/*
4396 	 * Lookup the /proc/<pid>/lwp/<lwpid> directory vnode.
4397 	 */
4398 	if (pnp->pr_type == PR_PIDFILE) {
4399 		dp = pnp->pr_parent;		/* /proc/<pid> */
4400 		VN_HOLD(dp);
4401 		vp = pr_lookup_piddir(dp, "lwp");
4402 		VN_RELE(dp);
4403 		if ((dp = vp) == NULL)		/* /proc/<pid>/lwp */
4404 			return (NULL);
4405 	} else if (pnp->pr_type == PR_LWPIDFILE) {
4406 		dp = pnp->pr_parent;		/* /proc/<pid>/lwp/<lwpid> */
4407 		dp = VTOP(dp)->pr_parent;	/* /proc/<pid>/lwp */
4408 		VN_HOLD(dp);
4409 	} else {
4410 		return (NULL);
4411 	}
4412 
4413 	(void) pr_u32tos(tid, comp, sizeof (comp));
4414 	vp = pr_lookup_lwpdir(dp, comp);
4415 	VN_RELE(dp);
4416 	if ((dp = vp) == NULL)
4417 		return (NULL);
4418 
4419 	pnp = prgetnode(dp, PR_LWPIDFILE);
4420 	vp = PTOV(pnp);
4421 
4422 	/*
4423 	 * prgetnode() initialized most of the prnode.
4424 	 * Finish the job.
4425 	 */
4426 	pcp = VTOP(dp)->pr_common;
4427 	pnp->pr_ino = ptoi(pcp->prc_pid);
4428 	pnp->pr_common = pcp;
4429 	pnp->pr_pcommon = VTOP(dp)->pr_pcommon;
4430 	pnp->pr_parent = dp;
4431 	/*
4432 	 * Link new vnode into list of all /proc vnodes for the process.
4433 	 */
4434 	p = pr_p_lock(pnp);
4435 	mutex_exit(&pr_pidlock);
4436 	if (p == NULL) {
4437 		VN_RELE(dp);
4438 		prfreenode(pnp);
4439 		vp = NULL;
4440 	} else if (pcp->prc_thread == NULL) {
4441 		prunlock(pnp);
4442 		VN_RELE(dp);
4443 		prfreenode(pnp);
4444 		vp = NULL;
4445 	} else {
4446 		pnp->pr_next = p->p_plist;
4447 		p->p_plist = vp;
4448 		prunlock(pnp);
4449 	}
4450 
4451 	return (vp);
4452 }
4453 
4454 #if defined(DEBUG)
4455 
4456 static	uint32_t nprnode;
4457 static	uint32_t nprcommon;
4458 
4459 #define	INCREMENT(x)	atomic_inc_32(&x);
4460 #define	DECREMENT(x)	atomic_dec_32(&x);
4461 
4462 #else
4463 
4464 #define	INCREMENT(x)
4465 #define	DECREMENT(x)
4466 
4467 #endif	/* DEBUG */
4468 
4469 /*
4470  * New /proc vnode required; allocate it and fill in most of the fields.
4471  */
4472 prnode_t *
4473 prgetnode(vnode_t *dp, prnodetype_t type)
4474 {
4475 	prnode_t *pnp;
4476 	prcommon_t *pcp;
4477 	vnode_t *vp;
4478 	ulong_t nfiles;
4479 
4480 	INCREMENT(nprnode);
4481 	pnp = kmem_zalloc(sizeof (prnode_t), KM_SLEEP);
4482 
4483 	mutex_init(&pnp->pr_mutex, NULL, MUTEX_DEFAULT, NULL);
4484 	pnp->pr_type = type;
4485 
4486 	pnp->pr_vnode = vn_alloc(KM_SLEEP);
4487 
4488 	vp = PTOV(pnp);
4489 	vp->v_flag = VNOCACHE|VNOMAP|VNOSWAP|VNOMOUNT;
4490 	vn_setops(vp, prvnodeops);
4491 	vp->v_vfsp = dp->v_vfsp;
4492 	vp->v_type = VPROC;
4493 	vp->v_data = (caddr_t)pnp;
4494 
4495 	switch (type) {
4496 	case PR_PIDDIR:
4497 	case PR_LWPIDDIR:
4498 		/*
4499 		 * We need a prcommon and a files array for each of these.
4500 		 */
4501 		INCREMENT(nprcommon);
4502 
4503 		pcp = kmem_zalloc(sizeof (prcommon_t), KM_SLEEP);
4504 		pcp->prc_refcnt = 1;
4505 		pnp->pr_common = pcp;
4506 		mutex_init(&pcp->prc_mutex, NULL, MUTEX_DEFAULT, NULL);
4507 		cv_init(&pcp->prc_wait, NULL, CV_DEFAULT, NULL);
4508 
4509 		nfiles = (type == PR_PIDDIR)? NPIDDIRFILES : NLWPIDDIRFILES;
4510 		pnp->pr_files =
4511 		    kmem_zalloc(nfiles * sizeof (vnode_t *), KM_SLEEP);
4512 
4513 		vp->v_type = VDIR;
4514 		/*
4515 		 * Mode should be read-search by all, but we cannot so long
4516 		 * as we must support compatibility mode with old /proc.
4517 		 * Make /proc/<pid> be read by owner only, search by all.
4518 		 * Make /proc/<pid>/lwp/<lwpid> read-search by all.  Also,
4519 		 * set VDIROPEN on /proc/<pid> so it can be opened for writing.
4520 		 */
4521 		if (type == PR_PIDDIR) {
4522 			/* kludge for old /proc interface */
4523 			prnode_t *xpnp = prgetnode(dp, PR_PIDFILE);
4524 			pnp->pr_pidfile = PTOV(xpnp);
4525 			pnp->pr_mode = 0511;
4526 			vp->v_flag |= VDIROPEN;
4527 		} else {
4528 			pnp->pr_mode = 0555;
4529 		}
4530 
4531 		break;
4532 
4533 	case PR_CURDIR:
4534 	case PR_ROOTDIR:
4535 	case PR_FDDIR:
4536 	case PR_OBJECTDIR:
4537 	case PR_PATHDIR:
4538 	case PR_CTDIR:
4539 	case PR_TMPLDIR:
4540 		vp->v_type = VDIR;
4541 		pnp->pr_mode = 0500;	/* read-search by owner only */
4542 		break;
4543 
4544 	case PR_CT:
4545 		vp->v_type = VLNK;
4546 		pnp->pr_mode = 0500;	/* read-search by owner only */
4547 		break;
4548 
4549 	case PR_PATH:
4550 	case PR_SELF:
4551 		vp->v_type = VLNK;
4552 		pnp->pr_mode = 0777;
4553 		break;
4554 
4555 	case PR_LWPDIR:
4556 		vp->v_type = VDIR;
4557 		pnp->pr_mode = 0555;	/* read-search by all */
4558 		break;
4559 
4560 	case PR_AS:
4561 	case PR_TMPL:
4562 		pnp->pr_mode = 0600;	/* read-write by owner only */
4563 		break;
4564 
4565 	case PR_CTL:
4566 	case PR_LWPCTL:
4567 		pnp->pr_mode = 0200;	/* write-only by owner only */
4568 		break;
4569 
4570 	case PR_PIDFILE:
4571 	case PR_LWPIDFILE:
4572 		pnp->pr_mode = 0600;	/* read-write by owner only */
4573 		break;
4574 
4575 	case PR_PSINFO:
4576 	case PR_LPSINFO:
4577 	case PR_LWPSINFO:
4578 	case PR_USAGE:
4579 	case PR_LUSAGE:
4580 	case PR_LWPUSAGE:
4581 		pnp->pr_mode = 0444;	/* read-only by all */
4582 		break;
4583 
4584 	default:
4585 		pnp->pr_mode = 0400;	/* read-only by owner only */
4586 		break;
4587 	}
4588 	vn_exists(vp);
4589 	return (pnp);
4590 }
4591 
4592 /*
4593  * Free the storage obtained from prgetnode().
4594  */
4595 void
4596 prfreenode(prnode_t *pnp)
4597 {
4598 	vnode_t *vp;
4599 	ulong_t nfiles;
4600 
4601 	vn_invalid(PTOV(pnp));
4602 	vn_free(PTOV(pnp));
4603 	mutex_destroy(&pnp->pr_mutex);
4604 
4605 	switch (pnp->pr_type) {
4606 	case PR_PIDDIR:
4607 		/* kludge for old /proc interface */
4608 		if (pnp->pr_pidfile != NULL) {
4609 			prfreenode(VTOP(pnp->pr_pidfile));
4610 			pnp->pr_pidfile = NULL;
4611 		}
4612 		/* FALLTHROUGH */
4613 	case PR_LWPIDDIR:
4614 		/*
4615 		 * We allocated a prcommon and a files array for each of these.
4616 		 */
4617 		prfreecommon(pnp->pr_common);
4618 		nfiles = (pnp->pr_type == PR_PIDDIR)?
4619 		    NPIDDIRFILES : NLWPIDDIRFILES;
4620 		kmem_free(pnp->pr_files, nfiles * sizeof (vnode_t *));
4621 		break;
4622 	default:
4623 		break;
4624 	}
4625 	/*
4626 	 * If there is an underlying vnode, be sure
4627 	 * to release it after freeing the prnode.
4628 	 */
4629 	vp = pnp->pr_realvp;
4630 	kmem_free(pnp, sizeof (*pnp));
4631 	DECREMENT(nprnode);
4632 	if (vp != NULL) {
4633 		VN_RELE(vp);
4634 	}
4635 }
4636 
4637 /*
4638  * Free a prcommon structure, if the reference count reaches zero.
4639  */
4640 static void
4641 prfreecommon(prcommon_t *pcp)
4642 {
4643 	mutex_enter(&pcp->prc_mutex);
4644 	ASSERT(pcp->prc_refcnt > 0);
4645 	if (--pcp->prc_refcnt != 0)
4646 		mutex_exit(&pcp->prc_mutex);
4647 	else {
4648 		mutex_exit(&pcp->prc_mutex);
4649 		ASSERT(pcp->prc_pollhead.ph_list == NULL);
4650 		ASSERT(pcp->prc_refcnt == 0);
4651 		ASSERT(pcp->prc_selfopens == 0 && pcp->prc_writers == 0);
4652 		mutex_destroy(&pcp->prc_mutex);
4653 		cv_destroy(&pcp->prc_wait);
4654 		kmem_free(pcp, sizeof (prcommon_t));
4655 		DECREMENT(nprcommon);
4656 	}
4657 }
4658 
4659 /*
4660  * Array of readdir functions, indexed by /proc file type.
4661  */
4662 static int pr_readdir_notdir(), pr_readdir_procdir(), pr_readdir_piddir(),
4663 	pr_readdir_objectdir(), pr_readdir_lwpdir(), pr_readdir_lwpiddir(),
4664 	pr_readdir_fddir(), pr_readdir_pathdir(), pr_readdir_tmpldir(),
4665 	pr_readdir_ctdir();
4666 
4667 static int (*pr_readdir_function[PR_NFILES])() = {
4668 	pr_readdir_procdir,	/* /proc				*/
4669 	pr_readdir_notdir,	/* /proc/self				*/
4670 	pr_readdir_piddir,	/* /proc/<pid>				*/
4671 	pr_readdir_notdir,	/* /proc/<pid>/as			*/
4672 	pr_readdir_notdir,	/* /proc/<pid>/ctl			*/
4673 	pr_readdir_notdir,	/* /proc/<pid>/status			*/
4674 	pr_readdir_notdir,	/* /proc/<pid>/lstatus			*/
4675 	pr_readdir_notdir,	/* /proc/<pid>/psinfo			*/
4676 	pr_readdir_notdir,	/* /proc/<pid>/lpsinfo			*/
4677 	pr_readdir_notdir,	/* /proc/<pid>/map			*/
4678 	pr_readdir_notdir,	/* /proc/<pid>/rmap			*/
4679 	pr_readdir_notdir,	/* /proc/<pid>/xmap			*/
4680 	pr_readdir_notdir,	/* /proc/<pid>/cred			*/
4681 	pr_readdir_notdir,	/* /proc/<pid>/sigact			*/
4682 	pr_readdir_notdir,	/* /proc/<pid>/auxv			*/
4683 #if defined(__x86)
4684 	pr_readdir_notdir,	/* /proc/<pid>/ldt			*/
4685 #endif
4686 	pr_readdir_notdir,	/* /proc/<pid>/usage			*/
4687 	pr_readdir_notdir,	/* /proc/<pid>/lusage			*/
4688 	pr_readdir_notdir,	/* /proc/<pid>/pagedata			*/
4689 	pr_readdir_notdir,	/* /proc/<pid>/watch			*/
4690 	pr_readdir_notdir,	/* /proc/<pid>/cwd			*/
4691 	pr_readdir_notdir,	/* /proc/<pid>/root			*/
4692 	pr_readdir_fddir,	/* /proc/<pid>/fd			*/
4693 	pr_readdir_notdir,	/* /proc/<pid>/fd/nn			*/
4694 	pr_readdir_objectdir,	/* /proc/<pid>/object			*/
4695 	pr_readdir_notdir,	/* /proc/<pid>/object/xxx		*/
4696 	pr_readdir_lwpdir,	/* /proc/<pid>/lwp			*/
4697 	pr_readdir_lwpiddir,	/* /proc/<pid>/lwp/<lwpid>		*/
4698 	pr_readdir_notdir,	/* /proc/<pid>/lwp/<lwpid>/lwpctl	*/
4699 	pr_readdir_notdir,	/* /proc/<pid>/lwp/<lwpid>/lwpstatus	*/
4700 	pr_readdir_notdir,	/* /proc/<pid>/lwp/<lwpid>/lwpsinfo	*/
4701 	pr_readdir_notdir,	/* /proc/<pid>/lwp/<lwpid>/lwpusage	*/
4702 	pr_readdir_notdir,	/* /proc/<pid>/lwp/<lwpid>/xregs	*/
4703 	pr_readdir_tmpldir,	/* /proc/<pid>/lwp/<lwpid>/templates	*/
4704 	pr_readdir_notdir,	/* /proc/<pid>/lwp/<lwpid>/templates/<id> */
4705 	pr_readdir_notdir,	/* /proc/<pid>/lwp/<lwpid>/spymaster	*/
4706 #if defined(__sparc)
4707 	pr_readdir_notdir,	/* /proc/<pid>/lwp/<lwpid>/gwindows	*/
4708 	pr_readdir_notdir,	/* /proc/<pid>/lwp/<lwpid>/asrs		*/
4709 #endif
4710 	pr_readdir_notdir,	/* /proc/<pid>/priv			*/
4711 	pr_readdir_pathdir,	/* /proc/<pid>/path			*/
4712 	pr_readdir_notdir,	/* /proc/<pid>/path/xxx			*/
4713 	pr_readdir_ctdir,	/* /proc/<pid>/contracts		*/
4714 	pr_readdir_notdir,	/* /proc/<pid>/contracts/<ctid>		*/
4715 	pr_readdir_notdir,	/* /proc/<pid>/secflags			*/
4716 	pr_readdir_notdir,	/* old process file			*/
4717 	pr_readdir_notdir,	/* old lwp file				*/
4718 	pr_readdir_notdir,	/* old pagedata file			*/
4719 };
4720 
4721 /* ARGSUSED */
4722 static int
4723 prreaddir(vnode_t *vp, uio_t *uiop, cred_t *cr, int *eofp,
4724     caller_context_t *ct, int flags)
4725 {
4726 	prnode_t *pnp = VTOP(vp);
4727 
4728 	ASSERT(pnp->pr_type < PR_NFILES);
4729 
4730 	/* XXX - Do we need to pass ct and flags? */
4731 	return (pr_readdir_function[pnp->pr_type](pnp, uiop, eofp));
4732 }
4733 
4734 /* ARGSUSED */
4735 static int
4736 pr_readdir_notdir(prnode_t *pnp, uio_t *uiop, int *eofp)
4737 {
4738 	return (ENOTDIR);
4739 }
4740 
4741 /* ARGSUSED */
4742 static int
4743 pr_readdir_procdir(prnode_t *pnp, uio_t *uiop, int *eofp)
4744 {
4745 	zoneid_t zoneid;
4746 	gfs_readdir_state_t gstate;
4747 	int error, eof = 0;
4748 	offset_t n;
4749 
4750 	ASSERT(pnp->pr_type == PR_PROCDIR);
4751 
4752 	zoneid = VTOZONE(PTOV(pnp))->zone_id;
4753 
4754 	if ((error = gfs_readdir_init(&gstate, PNSIZ, PRSDSIZE, uiop,
4755 	    PRROOTINO, PRROOTINO, 0)) != 0)
4756 		return (error);
4757 
4758 	/*
4759 	 * Loop until user's request is satisfied or until all processes
4760 	 * have been examined.
4761 	 */
4762 	while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
4763 		uint_t pid;
4764 		int pslot;
4765 		proc_t *p;
4766 
4767 		/*
4768 		 * Find next entry.  Skip processes not visible where
4769 		 * this /proc was mounted.
4770 		 */
4771 		mutex_enter(&pidlock);
4772 		while (n < v.v_proc &&
4773 		    ((p = pid_entry(n)) == NULL || p->p_stat == SIDL ||
4774 		    (zoneid != GLOBAL_ZONEID && p->p_zone->zone_id != zoneid) ||
4775 		    secpolicy_basic_procinfo(CRED(), p, curproc) != 0))
4776 			n++;
4777 
4778 		/*
4779 		 * Stop when entire proc table has been examined.
4780 		 */
4781 		if (n >= v.v_proc) {
4782 			mutex_exit(&pidlock);
4783 			eof = 1;
4784 			break;
4785 		}
4786 
4787 		ASSERT(p->p_stat != 0);
4788 		pid = p->p_pid;
4789 		pslot = p->p_slot;
4790 		mutex_exit(&pidlock);
4791 		error = gfs_readdir_emitn(&gstate, uiop, n,
4792 		    pmkino(0, pslot, PR_PIDDIR), pid);
4793 		if (error)
4794 			break;
4795 	}
4796 
4797 	return (gfs_readdir_fini(&gstate, error, eofp, eof));
4798 }
4799 
4800 /* ARGSUSED */
4801 static int
4802 pr_readdir_piddir(prnode_t *pnp, uio_t *uiop, int *eofp)
4803 {
4804 	int zombie = ((pnp->pr_pcommon->prc_flags & PRC_DESTROY) != 0);
4805 	prdirent_t dirent;
4806 	prdirent_t *dirp;
4807 	offset_t off;
4808 	int error;
4809 
4810 	ASSERT(pnp->pr_type == PR_PIDDIR);
4811 
4812 	if (uiop->uio_offset < 0 ||
4813 	    uiop->uio_offset % sizeof (prdirent_t) != 0 ||
4814 	    uiop->uio_resid < sizeof (prdirent_t))
4815 		return (EINVAL);
4816 	if (pnp->pr_pcommon->prc_proc == NULL)
4817 		return (ENOENT);
4818 	if (uiop->uio_offset >= sizeof (piddir))
4819 		goto out;
4820 
4821 	/*
4822 	 * Loop until user's request is satisfied, omitting some
4823 	 * files along the way if the process is a zombie.
4824 	 */
4825 	for (dirp = &piddir[uiop->uio_offset / sizeof (prdirent_t)];
4826 	    uiop->uio_resid >= sizeof (prdirent_t) &&
4827 	    dirp < &piddir[NPIDDIRFILES+2];
4828 	    uiop->uio_offset = off + sizeof (prdirent_t), dirp++) {
4829 		off = uiop->uio_offset;
4830 		if (zombie) {
4831 			switch (dirp->d_ino) {
4832 			case PR_PIDDIR:
4833 			case PR_PROCDIR:
4834 			case PR_PSINFO:
4835 			case PR_USAGE:
4836 				break;
4837 			default:
4838 				continue;
4839 			}
4840 		}
4841 		bcopy(dirp, &dirent, sizeof (prdirent_t));
4842 		if (dirent.d_ino == PR_PROCDIR)
4843 			dirent.d_ino = PRROOTINO;
4844 		else
4845 			dirent.d_ino = pmkino(0, pnp->pr_pcommon->prc_slot,
4846 			    dirent.d_ino);
4847 		if ((error = uiomove((caddr_t)&dirent, sizeof (prdirent_t),
4848 		    UIO_READ, uiop)) != 0)
4849 			return (error);
4850 	}
4851 out:
4852 	if (eofp)
4853 		*eofp = (uiop->uio_offset >= sizeof (piddir));
4854 	return (0);
4855 }
4856 
4857 static void
4858 rebuild_objdir(struct as *as)
4859 {
4860 	struct seg *seg;
4861 	vnode_t *vp;
4862 	vattr_t vattr;
4863 	vnode_t **dir;
4864 	ulong_t nalloc;
4865 	ulong_t nentries;
4866 	int i, j;
4867 	ulong_t nold, nnew;
4868 
4869 	ASSERT(AS_WRITE_HELD(as));
4870 
4871 	if (as->a_updatedir == 0 && as->a_objectdir != NULL)
4872 		return;
4873 	as->a_updatedir = 0;
4874 
4875 	if ((nalloc = avl_numnodes(&as->a_segtree)) == 0 ||
4876 	    (seg = AS_SEGFIRST(as)) == NULL)	/* can't happen? */
4877 		return;
4878 
4879 	/*
4880 	 * Allocate space for the new object directory.
4881 	 * (This is usually about two times too many entries.)
4882 	 */
4883 	nalloc = (nalloc + 0xf) & ~0xf;		/* multiple of 16 */
4884 	dir = kmem_zalloc(nalloc * sizeof (vnode_t *), KM_SLEEP);
4885 
4886 	/* fill in the new directory with desired entries */
4887 	nentries = 0;
4888 	do {
4889 		vattr.va_mask = AT_FSID|AT_NODEID;
4890 		if (seg->s_ops == &segvn_ops &&
4891 		    SEGOP_GETVP(seg, seg->s_base, &vp) == 0 &&
4892 		    vp != NULL && vp->v_type == VREG &&
4893 		    VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
4894 			for (i = 0; i < nentries; i++)
4895 				if (vp == dir[i])
4896 					break;
4897 			if (i == nentries) {
4898 				ASSERT(nentries < nalloc);
4899 				dir[nentries++] = vp;
4900 			}
4901 		}
4902 	} while ((seg = AS_SEGNEXT(as, seg)) != NULL);
4903 
4904 	if (as->a_objectdir == NULL) {	/* first time */
4905 		as->a_objectdir = dir;
4906 		as->a_sizedir = nalloc;
4907 		return;
4908 	}
4909 
4910 	/*
4911 	 * Null out all of the defunct entries in the old directory.
4912 	 */
4913 	nold = 0;
4914 	nnew = nentries;
4915 	for (i = 0; i < as->a_sizedir; i++) {
4916 		if ((vp = as->a_objectdir[i]) != NULL) {
4917 			for (j = 0; j < nentries; j++) {
4918 				if (vp == dir[j]) {
4919 					dir[j] = NULL;
4920 					nnew--;
4921 					break;
4922 				}
4923 			}
4924 			if (j == nentries)
4925 				as->a_objectdir[i] = NULL;
4926 			else
4927 				nold++;
4928 		}
4929 	}
4930 
4931 	if (nold + nnew > as->a_sizedir) {
4932 		/*
4933 		 * Reallocate the old directory to have enough
4934 		 * space for the old and new entries combined.
4935 		 * Round up to the next multiple of 16.
4936 		 */
4937 		ulong_t newsize = (nold + nnew + 0xf) & ~0xf;
4938 		vnode_t **newdir = kmem_zalloc(newsize * sizeof (vnode_t *),
4939 		    KM_SLEEP);
4940 		bcopy(as->a_objectdir, newdir,
4941 		    as->a_sizedir * sizeof (vnode_t *));
4942 		kmem_free(as->a_objectdir, as->a_sizedir * sizeof (vnode_t *));
4943 		as->a_objectdir = newdir;
4944 		as->a_sizedir = newsize;
4945 	}
4946 
4947 	/*
4948 	 * Move all new entries to the old directory and
4949 	 * deallocate the space used by the new directory.
4950 	 */
4951 	if (nnew) {
4952 		for (i = 0, j = 0; i < nentries; i++) {
4953 			if ((vp = dir[i]) == NULL)
4954 				continue;
4955 			for (; j < as->a_sizedir; j++) {
4956 				if (as->a_objectdir[j] != NULL)
4957 					continue;
4958 				as->a_objectdir[j++] = vp;
4959 				break;
4960 			}
4961 		}
4962 	}
4963 	kmem_free(dir, nalloc * sizeof (vnode_t *));
4964 }
4965 
4966 /*
4967  * Return the vnode from a slot in the process's object directory.
4968  * The caller must have locked the process's address space.
4969  * The only caller is below, in pr_readdir_objectdir().
4970  */
4971 static vnode_t *
4972 obj_entry(struct as *as, int slot)
4973 {
4974 	ASSERT(AS_LOCK_HELD(as));
4975 	if (as->a_objectdir == NULL)
4976 		return (NULL);
4977 	ASSERT(slot < as->a_sizedir);
4978 	return (as->a_objectdir[slot]);
4979 }
4980 
4981 /* ARGSUSED */
4982 static int
4983 pr_readdir_objectdir(prnode_t *pnp, uio_t *uiop, int *eofp)
4984 {
4985 	gfs_readdir_state_t gstate;
4986 	int error, eof = 0;
4987 	offset_t n;
4988 	int pslot;
4989 	size_t objdirsize;
4990 	proc_t *p;
4991 	struct as *as;
4992 	vnode_t *vp;
4993 
4994 	ASSERT(pnp->pr_type == PR_OBJECTDIR);
4995 
4996 	if ((error = prlock(pnp, ZNO)) != 0)
4997 		return (error);
4998 	p = pnp->pr_common->prc_proc;
4999 	pslot = p->p_slot;
5000 
5001 	/*
5002 	 * We drop p_lock before grabbing the address space lock
5003 	 * in order to avoid a deadlock with the clock thread.
5004 	 * The process will not disappear and its address space
5005 	 * will not change because it is marked P_PR_LOCK.
5006 	 */
5007 	mutex_exit(&p->p_lock);
5008 
5009 	if ((error = gfs_readdir_init(&gstate, 64, PRSDSIZE, uiop,
5010 	    pmkino(0, pslot, PR_PIDDIR),
5011 	    pmkino(0, pslot, PR_OBJECTDIR), 0)) != 0) {
5012 		mutex_enter(&p->p_lock);
5013 		prunlock(pnp);
5014 		return (error);
5015 	}
5016 
5017 	if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
5018 		as = NULL;
5019 		objdirsize = 0;
5020 	}
5021 
5022 	/*
5023 	 * Loop until user's request is satisfied or until
5024 	 * all mapped objects have been examined. Cannot hold
5025 	 * the address space lock for the following call as
5026 	 * gfs_readdir_pred() utimately causes a call to uiomove().
5027 	 */
5028 	while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5029 		vattr_t vattr;
5030 		char str[64];
5031 
5032 		/*
5033 		 * Set the correct size of the directory just
5034 		 * in case the process has changed it's address
5035 		 * space via mmap/munmap calls.
5036 		 */
5037 		if (as != NULL) {
5038 			AS_LOCK_ENTER(as, RW_WRITER);
5039 			if (as->a_updatedir)
5040 				rebuild_objdir(as);
5041 			objdirsize = as->a_sizedir;
5042 		}
5043 
5044 		/*
5045 		 * Find next object.
5046 		 */
5047 		vattr.va_mask = AT_FSID | AT_NODEID;
5048 		while (n < objdirsize && (((vp = obj_entry(as, n)) == NULL) ||
5049 		    (VOP_GETATTR(vp, &vattr, 0, CRED(), NULL)
5050 		    != 0))) {
5051 			vattr.va_mask = AT_FSID | AT_NODEID;
5052 			n++;
5053 		}
5054 
5055 		if (as != NULL)
5056 			AS_LOCK_EXIT(as);
5057 
5058 		/*
5059 		 * Stop when all objects have been reported.
5060 		 */
5061 		if (n >= objdirsize) {
5062 			eof = 1;
5063 			break;
5064 		}
5065 
5066 		if (vp == p->p_exec)
5067 			(void) strcpy(str, "a.out");
5068 		else
5069 			pr_object_name(str, vp, &vattr);
5070 
5071 		error = gfs_readdir_emit(&gstate, uiop, n, vattr.va_nodeid,
5072 		    str, 0);
5073 
5074 		if (error)
5075 			break;
5076 	}
5077 
5078 	mutex_enter(&p->p_lock);
5079 	prunlock(pnp);
5080 
5081 	return (gfs_readdir_fini(&gstate, error, eofp, eof));
5082 }
5083 
5084 /* ARGSUSED */
5085 static int
5086 pr_readdir_lwpdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5087 {
5088 	gfs_readdir_state_t gstate;
5089 	int error, eof = 0;
5090 	offset_t tslot;
5091 	proc_t *p;
5092 	int pslot;
5093 	lwpdir_t *lwpdir;
5094 	int lwpdirsize;
5095 
5096 	ASSERT(pnp->pr_type == PR_LWPDIR);
5097 
5098 	p = pr_p_lock(pnp);
5099 	mutex_exit(&pr_pidlock);
5100 	if (p == NULL)
5101 		return (ENOENT);
5102 	ASSERT(p == pnp->pr_common->prc_proc);
5103 	pslot = p->p_slot;
5104 	lwpdir = p->p_lwpdir;
5105 	lwpdirsize = p->p_lwpdir_sz;
5106 
5107 	/*
5108 	 * Drop p->p_lock so we can safely do uiomove().
5109 	 * The lwp directory will not change because
5110 	 * we have the process locked with P_PR_LOCK.
5111 	 */
5112 	mutex_exit(&p->p_lock);
5113 
5114 
5115 	if ((error = gfs_readdir_init(&gstate, PLNSIZ, PRSDSIZE, uiop,
5116 	    pmkino(0, pslot, PR_PIDDIR),
5117 	    pmkino(0, pslot, PR_LWPDIR), 0)) != 0) {
5118 		mutex_enter(&p->p_lock);
5119 		prunlock(pnp);
5120 		return (error);
5121 	}
5122 
5123 	/*
5124 	 * Loop until user's request is satisfied or until all lwps
5125 	 * have been examined.
5126 	 */
5127 	while ((error = gfs_readdir_pred(&gstate, uiop, &tslot)) == 0) {
5128 		lwpent_t *lep;
5129 		uint_t tid;
5130 
5131 		/*
5132 		 * Find next LWP.
5133 		 */
5134 		while (tslot < lwpdirsize &&
5135 		    ((lep = lwpdir[tslot].ld_entry) == NULL))
5136 			tslot++;
5137 		/*
5138 		 * Stop when all lwps have been reported.
5139 		 */
5140 		if (tslot >= lwpdirsize) {
5141 			eof = 1;
5142 			break;
5143 		}
5144 
5145 		tid = lep->le_lwpid;
5146 		error = gfs_readdir_emitn(&gstate, uiop, tslot,
5147 		    pmkino(tslot, pslot, PR_LWPIDDIR), tid);
5148 		if (error)
5149 			break;
5150 	}
5151 
5152 	mutex_enter(&p->p_lock);
5153 	prunlock(pnp);
5154 
5155 	return (gfs_readdir_fini(&gstate, error, eofp, eof));
5156 }
5157 
5158 /* ARGSUSED */
5159 static int
5160 pr_readdir_lwpiddir(prnode_t *pnp, uio_t *uiop, int *eofp)
5161 {
5162 	prcommon_t *pcp = pnp->pr_common;
5163 	int zombie = ((pcp->prc_flags & PRC_DESTROY) != 0);
5164 	prdirent_t dirent;
5165 	prdirent_t *dirp;
5166 	offset_t off;
5167 	int error;
5168 	int pslot;
5169 	int tslot;
5170 
5171 	ASSERT(pnp->pr_type == PR_LWPIDDIR);
5172 
5173 	if (uiop->uio_offset < 0 ||
5174 	    uiop->uio_offset % sizeof (prdirent_t) != 0 ||
5175 	    uiop->uio_resid < sizeof (prdirent_t))
5176 		return (EINVAL);
5177 	if (pcp->prc_proc == NULL || pcp->prc_tslot == -1)
5178 		return (ENOENT);
5179 	if (uiop->uio_offset >= sizeof (lwpiddir))
5180 		goto out;
5181 
5182 	/*
5183 	 * Loop until user's request is satisfied, omitting some files
5184 	 * along the way if the lwp is a zombie and also depending
5185 	 * on the data model of the process.
5186 	 */
5187 	pslot = pcp->prc_slot;
5188 	tslot = pcp->prc_tslot;
5189 	for (dirp = &lwpiddir[uiop->uio_offset / sizeof (prdirent_t)];
5190 	    uiop->uio_resid >= sizeof (prdirent_t) &&
5191 	    dirp < &lwpiddir[NLWPIDDIRFILES+2];
5192 	    uiop->uio_offset = off + sizeof (prdirent_t), dirp++) {
5193 		off = uiop->uio_offset;
5194 		if (zombie) {
5195 			switch (dirp->d_ino) {
5196 			case PR_LWPIDDIR:
5197 			case PR_LWPDIR:
5198 			case PR_LWPSINFO:
5199 				break;
5200 			default:
5201 				continue;
5202 			}
5203 		}
5204 #if defined(__sparc)
5205 		/* the asrs file exists only for sparc v9 _LP64 processes */
5206 		if (dirp->d_ino == PR_ASRS &&
5207 		    pcp->prc_datamodel != DATAMODEL_LP64)
5208 			continue;
5209 #endif
5210 		bcopy(dirp, &dirent, sizeof (prdirent_t));
5211 		if (dirent.d_ino == PR_LWPDIR)
5212 			dirent.d_ino = pmkino(0, pslot, dirp->d_ino);
5213 		else
5214 			dirent.d_ino = pmkino(tslot, pslot, dirp->d_ino);
5215 		if ((error = uiomove((caddr_t)&dirent, sizeof (prdirent_t),
5216 		    UIO_READ, uiop)) != 0)
5217 			return (error);
5218 	}
5219 out:
5220 	if (eofp)
5221 		*eofp = (uiop->uio_offset >= sizeof (lwpiddir));
5222 	return (0);
5223 }
5224 
5225 /* ARGSUSED */
5226 static int
5227 pr_readdir_fddir(prnode_t *pnp, uio_t *uiop, int *eofp)
5228 {
5229 	gfs_readdir_state_t gstate;
5230 	int error, eof = 0;
5231 	offset_t n;
5232 	proc_t *p;
5233 	int pslot;
5234 	int fddirsize;
5235 	uf_info_t *fip;
5236 
5237 	ASSERT(pnp->pr_type == PR_FDDIR);
5238 
5239 	if ((error = prlock(pnp, ZNO)) != 0)
5240 		return (error);
5241 	p = pnp->pr_common->prc_proc;
5242 	pslot = p->p_slot;
5243 	fip = P_FINFO(p);
5244 	mutex_exit(&p->p_lock);
5245 
5246 	if ((error = gfs_readdir_init(&gstate, PLNSIZ, PRSDSIZE, uiop,
5247 	    pmkino(0, pslot, PR_PIDDIR), pmkino(0, pslot, PR_FDDIR), 0)) != 0) {
5248 		mutex_enter(&p->p_lock);
5249 		prunlock(pnp);
5250 		return (error);
5251 	}
5252 
5253 	mutex_enter(&fip->fi_lock);
5254 	if ((p->p_flag & SSYS) || p->p_as == &kas)
5255 		fddirsize = 0;
5256 	else
5257 		fddirsize = fip->fi_nfiles;
5258 
5259 	/*
5260 	 * Loop until user's request is satisfied or until
5261 	 * all file descriptors have been examined.
5262 	 */
5263 	while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5264 		/*
5265 		 * Find next fd.
5266 		 */
5267 		while (n < fddirsize && fip->fi_list[n].uf_file == NULL)
5268 			n++;
5269 		/*
5270 		 * Stop when all fds have been reported.
5271 		 */
5272 		if (n >= fddirsize) {
5273 			eof = 1;
5274 			break;
5275 		}
5276 
5277 		error = gfs_readdir_emitn(&gstate, uiop, n,
5278 		    pmkino(n, pslot, PR_FD), n);
5279 		if (error)
5280 			break;
5281 	}
5282 
5283 	mutex_exit(&fip->fi_lock);
5284 	mutex_enter(&p->p_lock);
5285 	prunlock(pnp);
5286 
5287 	return (gfs_readdir_fini(&gstate, error, eofp, eof));
5288 }
5289 
5290 /* ARGSUSED */
5291 static int
5292 pr_readdir_pathdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5293 {
5294 	longlong_t bp[DIRENT64_RECLEN(64) / sizeof (longlong_t)];
5295 	dirent64_t *dirent = (dirent64_t *)bp;
5296 	int reclen;
5297 	ssize_t oresid;
5298 	offset_t off, idx;
5299 	int error = 0;
5300 	proc_t *p;
5301 	int fd, obj;
5302 	int pslot;
5303 	int fddirsize;
5304 	uf_info_t *fip;
5305 	struct as *as = NULL;
5306 	size_t objdirsize;
5307 	vattr_t vattr;
5308 	vnode_t *vp;
5309 
5310 	ASSERT(pnp->pr_type == PR_PATHDIR);
5311 
5312 	if (uiop->uio_offset < 0 ||
5313 	    uiop->uio_resid <= 0 ||
5314 	    (uiop->uio_offset % PRSDSIZE) != 0)
5315 		return (EINVAL);
5316 	oresid = uiop->uio_resid;
5317 	bzero(bp, sizeof (bp));
5318 
5319 	if ((error = prlock(pnp, ZNO)) != 0)
5320 		return (error);
5321 	p = pnp->pr_common->prc_proc;
5322 	fip = P_FINFO(p);
5323 	pslot = p->p_slot;
5324 	mutex_exit(&p->p_lock);
5325 
5326 	if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
5327 		as = NULL;
5328 		objdirsize = 0;
5329 	} else {
5330 		AS_LOCK_ENTER(as, RW_WRITER);
5331 		if (as->a_updatedir)
5332 			rebuild_objdir(as);
5333 		objdirsize = as->a_sizedir;
5334 		AS_LOCK_EXIT(as);
5335 		as = NULL;
5336 	}
5337 
5338 	mutex_enter(&fip->fi_lock);
5339 	if ((p->p_flag & SSYS) || p->p_as == &kas)
5340 		fddirsize = 0;
5341 	else
5342 		fddirsize = fip->fi_nfiles;
5343 
5344 	for (; uiop->uio_resid > 0; uiop->uio_offset = off + PRSDSIZE) {
5345 		/*
5346 		 * There are 4 special files in the path directory: ".", "..",
5347 		 * "root", and "cwd".  We handle those specially here.
5348 		 */
5349 		off = uiop->uio_offset;
5350 		idx = off / PRSDSIZE;
5351 		if (off == 0) {				/* "." */
5352 			dirent->d_ino = pmkino(0, pslot, PR_PATHDIR);
5353 			dirent->d_name[0] = '.';
5354 			dirent->d_name[1] = '\0';
5355 			reclen = DIRENT64_RECLEN(1);
5356 		} else if (idx == 1) {			/* ".." */
5357 			dirent->d_ino = pmkino(0, pslot, PR_PIDDIR);
5358 			dirent->d_name[0] = '.';
5359 			dirent->d_name[1] = '.';
5360 			dirent->d_name[2] = '\0';
5361 			reclen = DIRENT64_RECLEN(2);
5362 		} else if (idx == 2) {			/* "root" */
5363 			dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5364 			(void) strcpy(dirent->d_name, "root");
5365 			reclen = DIRENT64_RECLEN(4);
5366 		} else if (idx == 3) {			/* "cwd" */
5367 			dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5368 			(void) strcpy(dirent->d_name, "cwd");
5369 			reclen = DIRENT64_RECLEN(3);
5370 		} else if (idx < 4 + fddirsize) {
5371 			/*
5372 			 * In this case, we have one of the file descriptors.
5373 			 */
5374 			fd = idx - 4;
5375 			if (fip->fi_list[fd].uf_file == NULL)
5376 				continue;
5377 			dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5378 			(void) pr_u32tos(fd, dirent->d_name, PLNSIZ+1);
5379 			reclen = DIRENT64_RECLEN(PLNSIZ);
5380 		} else if (idx < 4 + fddirsize + objdirsize) {
5381 			if (fip != NULL) {
5382 				mutex_exit(&fip->fi_lock);
5383 				fip = NULL;
5384 			}
5385 
5386 			/*
5387 			 * We drop p_lock before grabbing the address space lock
5388 			 * in order to avoid a deadlock with the clock thread.
5389 			 * The process will not disappear and its address space
5390 			 * will not change because it is marked P_PR_LOCK.
5391 			 */
5392 			if (as == NULL) {
5393 				as = p->p_as;
5394 				AS_LOCK_ENTER(as, RW_WRITER);
5395 			}
5396 
5397 			if (as->a_updatedir) {
5398 				rebuild_objdir(as);
5399 				objdirsize = as->a_sizedir;
5400 			}
5401 
5402 			obj = idx - 4 - fddirsize;
5403 			if ((vp = obj_entry(as, obj)) == NULL)
5404 				continue;
5405 			vattr.va_mask = AT_FSID|AT_NODEID;
5406 			if (VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) != 0)
5407 				continue;
5408 			if (vp == p->p_exec)
5409 				(void) strcpy(dirent->d_name, "a.out");
5410 			else
5411 				pr_object_name(dirent->d_name, vp, &vattr);
5412 			dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5413 			reclen = DIRENT64_RECLEN(strlen(dirent->d_name));
5414 		} else {
5415 			break;
5416 		}
5417 
5418 		dirent->d_off = uiop->uio_offset + PRSDSIZE;
5419 		dirent->d_reclen = (ushort_t)reclen;
5420 		if (reclen > uiop->uio_resid) {
5421 			/*
5422 			 * Error if no entries have been returned yet.
5423 			 */
5424 			if (uiop->uio_resid == oresid)
5425 				error = EINVAL;
5426 			break;
5427 		}
5428 		/*
5429 		 * Drop the address space lock to do the uiomove().
5430 		 */
5431 		if (as != NULL)
5432 			AS_LOCK_EXIT(as);
5433 
5434 		error = uiomove((caddr_t)dirent, reclen, UIO_READ, uiop);
5435 		if (as != NULL)
5436 			AS_LOCK_ENTER(as, RW_WRITER);
5437 
5438 		if (error)
5439 			break;
5440 	}
5441 
5442 	if (error == 0 && eofp)
5443 		*eofp = (uiop->uio_offset >= (fddirsize + 2) * PRSDSIZE);
5444 
5445 	if (fip != NULL)
5446 		mutex_exit(&fip->fi_lock);
5447 	if (as != NULL)
5448 		AS_LOCK_EXIT(as);
5449 	mutex_enter(&p->p_lock);
5450 	prunlock(pnp);
5451 	return (error);
5452 }
5453 
5454 static int
5455 pr_readdir_tmpldir(prnode_t *pnp, uio_t *uiop, int *eofp)
5456 {
5457 	proc_t *p;
5458 	int pslot, tslot;
5459 	gfs_readdir_state_t gstate;
5460 	int error, eof = 0;
5461 	offset_t n;
5462 
5463 	ASSERT(pnp->pr_type == PR_TMPLDIR);
5464 
5465 	if ((error = prlock(pnp, ZNO)) != 0)
5466 		return (error);
5467 	p = pnp->pr_common->prc_proc;
5468 	pslot = pnp->pr_common->prc_slot;
5469 	tslot = pnp->pr_common->prc_tslot;
5470 	mutex_exit(&p->p_lock);
5471 
5472 	if ((error = gfs_readdir_init(&gstate, PRDIRSIZE, PRSDSIZE, uiop,
5473 	    pmkino(tslot, pslot, PR_LWPDIR),
5474 	    pmkino(tslot, pslot, PR_TMPLDIR), 0)) != 0) {
5475 		mutex_enter(&p->p_lock);
5476 		prunlock(pnp);
5477 		return (error);
5478 	}
5479 
5480 	while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5481 		/*
5482 		 * Check for an active template.  Reading a directory's
5483 		 * contents is already racy, so we don't bother taking
5484 		 * any locks.
5485 		 */
5486 		while (n < ct_ntypes &&
5487 		    pnp->pr_common->prc_thread->t_lwp->lwp_ct_active[n] == NULL)
5488 			n++;
5489 		/*
5490 		 * Stop when all types have been reported.
5491 		 */
5492 		if (n >= ct_ntypes) {
5493 			eof = 1;
5494 			break;
5495 		}
5496 		/*
5497 		 * The pmkino invocation below will need to be updated
5498 		 * when we create our fifth contract type.
5499 		 */
5500 		ASSERT(ct_ntypes <= 4);
5501 		error = gfs_readdir_emit(&gstate, uiop, n,
5502 		    pmkino((tslot << 2) | n, pslot, PR_TMPL),
5503 		    ct_types[n]->ct_type_name, 0);
5504 		if (error)
5505 			break;
5506 	}
5507 
5508 	mutex_enter(&p->p_lock);
5509 	prunlock(pnp);
5510 
5511 	return (gfs_readdir_fini(&gstate, error, eofp, eof));
5512 }
5513 
5514 static int
5515 pr_readdir_ctdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5516 {
5517 	proc_t *p;
5518 	int pslot;
5519 	gfs_readdir_state_t gstate;
5520 	int error, eof = 0;
5521 	offset_t n;
5522 	uint64_t zid;
5523 
5524 	ASSERT(pnp->pr_type == PR_CTDIR);
5525 
5526 	if ((error = prlock(pnp, ZNO)) != 0)
5527 		return (error);
5528 	p = pnp->pr_common->prc_proc;
5529 	pslot = p->p_slot;
5530 	mutex_exit(&p->p_lock);
5531 
5532 	if ((error = gfs_readdir_init(&gstate, PRDIRSIZE, PRSDSIZE, uiop,
5533 	    pmkino(0, pslot, PR_PIDDIR), pmkino(0, pslot, PR_CTDIR), 0)) != 0) {
5534 		mutex_enter(&p->p_lock);
5535 		prunlock(pnp);
5536 		return (error);
5537 	}
5538 
5539 	zid = VTOZONE(pnp->pr_vnode)->zone_uniqid;
5540 	while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5541 		id_t next = contract_plookup(p, n, zid);
5542 		if (next == -1) {
5543 			eof = 1;
5544 			break;
5545 		}
5546 		error = gfs_readdir_emitn(&gstate, uiop, next,
5547 		    pmkino(next, pslot, PR_CT), next);
5548 		if (error)
5549 			break;
5550 	}
5551 
5552 	mutex_enter(&p->p_lock);
5553 	prunlock(pnp);
5554 
5555 	return (gfs_readdir_fini(&gstate, error, eofp, eof));
5556 }
5557 
5558 /* ARGSUSED */
5559 static int
5560 prfsync(vnode_t *vp, int syncflag, cred_t *cr, caller_context_t *ct)
5561 {
5562 	return (0);
5563 }
5564 
5565 /*
5566  * Utility: remove a /proc vnode from a linked list, threaded through pr_next.
5567  */
5568 static void
5569 pr_list_unlink(vnode_t *pvp, vnode_t **listp)
5570 {
5571 	vnode_t *vp;
5572 	prnode_t *pnp;
5573 
5574 	while ((vp = *listp) != NULL) {
5575 		pnp = VTOP(vp);
5576 		if (vp == pvp) {
5577 			*listp = pnp->pr_next;
5578 			pnp->pr_next = NULL;
5579 			break;
5580 		}
5581 		listp = &pnp->pr_next;
5582 	}
5583 }
5584 
5585 /* ARGSUSED */
5586 static void
5587 prinactive(vnode_t *vp, cred_t *cr, caller_context_t *ct)
5588 {
5589 	prnode_t *pnp = VTOP(vp);
5590 	prnodetype_t type = pnp->pr_type;
5591 	proc_t *p;
5592 	vnode_t *dp;
5593 	vnode_t *ovp = NULL;
5594 	prnode_t *opnp = NULL;
5595 
5596 	switch (type) {
5597 	case PR_OBJECT:
5598 	case PR_FD:
5599 	case PR_SELF:
5600 	case PR_PATH:
5601 		/* These are not linked into the usual lists */
5602 		ASSERT(vp->v_count == 1);
5603 		if ((dp = pnp->pr_parent) != NULL)
5604 			VN_RELE(dp);
5605 		prfreenode(pnp);
5606 		return;
5607 	default:
5608 		break;
5609 	}
5610 
5611 	mutex_enter(&pr_pidlock);
5612 	if (pnp->pr_pcommon == NULL)
5613 		p = NULL;
5614 	else if ((p = pnp->pr_pcommon->prc_proc) != NULL)
5615 		mutex_enter(&p->p_lock);
5616 	mutex_enter(&vp->v_lock);
5617 
5618 	if (type == PR_PROCDIR || vp->v_count > 1) {
5619 		vp->v_count--;
5620 		mutex_exit(&vp->v_lock);
5621 		if (p != NULL)
5622 			mutex_exit(&p->p_lock);
5623 		mutex_exit(&pr_pidlock);
5624 		return;
5625 	}
5626 
5627 	if ((dp = pnp->pr_parent) != NULL) {
5628 		prnode_t *dpnp;
5629 
5630 		switch (type) {
5631 		case PR_PIDFILE:
5632 		case PR_LWPIDFILE:
5633 		case PR_OPAGEDATA:
5634 			break;
5635 		default:
5636 			dpnp = VTOP(dp);
5637 			mutex_enter(&dpnp->pr_mutex);
5638 			if (dpnp->pr_files != NULL &&
5639 			    dpnp->pr_files[pnp->pr_index] == vp)
5640 				dpnp->pr_files[pnp->pr_index] = NULL;
5641 			mutex_exit(&dpnp->pr_mutex);
5642 			break;
5643 		}
5644 		pnp->pr_parent = NULL;
5645 	}
5646 
5647 	ASSERT(vp->v_count == 1);
5648 
5649 	/*
5650 	 * If we allocated an old /proc/pid node, free it too.
5651 	 */
5652 	if (pnp->pr_pidfile != NULL) {
5653 		ASSERT(type == PR_PIDDIR);
5654 		ovp = pnp->pr_pidfile;
5655 		opnp = VTOP(ovp);
5656 		ASSERT(opnp->pr_type == PR_PIDFILE);
5657 		pnp->pr_pidfile = NULL;
5658 	}
5659 
5660 	mutex_exit(&pr_pidlock);
5661 
5662 	if (p != NULL) {
5663 		/*
5664 		 * Remove the vnodes from the lists of
5665 		 * /proc vnodes for the process.
5666 		 */
5667 		int slot;
5668 
5669 		switch (type) {
5670 		case PR_PIDDIR:
5671 			pr_list_unlink(vp, &p->p_trace);
5672 			break;
5673 		case PR_LWPIDDIR:
5674 			if ((slot = pnp->pr_common->prc_tslot) != -1) {
5675 				lwpent_t *lep = p->p_lwpdir[slot].ld_entry;
5676 				pr_list_unlink(vp, &lep->le_trace);
5677 			}
5678 			break;
5679 		default:
5680 			pr_list_unlink(vp, &p->p_plist);
5681 			break;
5682 		}
5683 		if (ovp != NULL)
5684 			pr_list_unlink(ovp, &p->p_plist);
5685 		mutex_exit(&p->p_lock);
5686 	}
5687 
5688 	mutex_exit(&vp->v_lock);
5689 
5690 	if (type == PR_CT && pnp->pr_contract != NULL) {
5691 		contract_rele(pnp->pr_contract);
5692 		pnp->pr_contract = NULL;
5693 	}
5694 
5695 	if (opnp != NULL)
5696 		prfreenode(opnp);
5697 	prfreenode(pnp);
5698 	if (dp != NULL) {
5699 		VN_RELE(dp);
5700 	}
5701 }
5702 
5703 /* ARGSUSED */
5704 static int
5705 prseek(vnode_t *vp, offset_t ooff, offset_t *noffp, caller_context_t *ct)
5706 {
5707 	return (0);
5708 }
5709 
5710 /*
5711  * We use the p_execdir member of proc_t to expand the %d token in core file
5712  * paths (the directory path for the executable that dumped core; see
5713  * coreadm(1M) for details). We'd like gcore(1) to be able to expand %d in
5714  * the same way as core dumping from the kernel, but there's no convenient
5715  * and comprehensible way to export the path name for p_execdir. To solve
5716  * this, we try to find the actual path to the executable that was used. In
5717  * pr_lookup_pathdir(), we mark the a.out path name vnode with the PR_AOUT
5718  * flag, and use that here to indicate that more work is needed beyond the
5719  * call to vnodetopath().
5720  */
5721 static int
5722 prreadlink_lookup(prnode_t *pnp, char *buf, size_t size, cred_t *cr)
5723 {
5724 	proc_t *p;
5725 	vnode_t *vp, *execvp, *vrootp;
5726 	int ret;
5727 	size_t len;
5728 	dirent64_t *dp;
5729 	size_t dlen = DIRENT64_RECLEN(MAXPATHLEN);
5730 	char *dbuf;
5731 
5732 	p = curproc;
5733 	mutex_enter(&p->p_lock);
5734 	if ((vrootp = PTOU(p)->u_rdir) == NULL)
5735 		vrootp = rootdir;
5736 	VN_HOLD(vrootp);
5737 	mutex_exit(&p->p_lock);
5738 
5739 	ret = vnodetopath(vrootp, pnp->pr_realvp, buf, size, cr);
5740 
5741 	/*
5742 	 * If PR_AOUT isn't set, then we looked up the path for the vnode;
5743 	 * otherwise, we looked up the path for (what we believe to be) the
5744 	 * containing directory.
5745 	 */
5746 	if ((pnp->pr_flags & PR_AOUT) == 0) {
5747 		VN_RELE(vrootp);
5748 		return (ret);
5749 	}
5750 
5751 	/*
5752 	 * Fail if there's a problem locking the process. This will only
5753 	 * occur if the process is changing so the information we would
5754 	 * report would already be invalid.
5755 	 */
5756 	if (prlock(pnp, ZNO) != 0) {
5757 		VN_RELE(vrootp);
5758 		return (EIO);
5759 	}
5760 
5761 	p = pnp->pr_common->prc_proc;
5762 	mutex_exit(&p->p_lock);
5763 
5764 	execvp = p->p_exec;
5765 	VN_HOLD(execvp);
5766 
5767 	/*
5768 	 * If our initial lookup of the directory failed, fall back to
5769 	 * the path name information for p_exec.
5770 	 */
5771 	if (ret != 0) {
5772 		mutex_enter(&p->p_lock);
5773 		prunlock(pnp);
5774 		ret = vnodetopath(vrootp, execvp, buf, size, cr);
5775 		VN_RELE(execvp);
5776 		VN_RELE(vrootp);
5777 		return (ret);
5778 	}
5779 
5780 	len = strlen(buf);
5781 
5782 	/*
5783 	 * We use u_comm as a guess for the last component of the full
5784 	 * executable path name. If there isn't going to be enough space
5785 	 * we fall back to using the p_exec so that we can have _an_
5786 	 * answer even if it's not perfect.
5787 	 */
5788 	if (strlen(PTOU(p)->u_comm) + len + 1 < size) {
5789 		buf[len] = '/';
5790 		(void) strcpy(buf + len + 1, PTOU(p)->u_comm);
5791 		mutex_enter(&p->p_lock);
5792 		prunlock(pnp);
5793 
5794 		/*
5795 		 * Do a forward lookup of our u_comm guess.
5796 		 */
5797 		if (lookupnameat(buf + len + 1, UIO_SYSSPACE, FOLLOW, NULLVPP,
5798 		    &vp, pnp->pr_realvp) == 0) {
5799 			if (vn_compare(vp, execvp)) {
5800 				VN_RELE(vp);
5801 				VN_RELE(execvp);
5802 				VN_RELE(vrootp);
5803 				return (0);
5804 			}
5805 
5806 			VN_RELE(vp);
5807 		}
5808 	} else {
5809 		mutex_enter(&p->p_lock);
5810 		prunlock(pnp);
5811 	}
5812 
5813 	dbuf = kmem_alloc(dlen, KM_SLEEP);
5814 
5815 	/*
5816 	 * Try to find a matching vnode by iterating through the directory's
5817 	 * entries. If that fails, fall back to the path information for
5818 	 * p_exec.
5819 	 */
5820 	if ((ret = dirfindvp(vrootp, pnp->pr_realvp, execvp, cr, dbuf,
5821 	    dlen, &dp)) == 0 && strlen(dp->d_name) + len + 1 < size) {
5822 		buf[len] = '/';
5823 		(void) strcpy(buf + len + 1, dp->d_name);
5824 	} else {
5825 		ret = vnodetopath(vrootp, execvp, buf, size, cr);
5826 	}
5827 
5828 	kmem_free(dbuf, dlen);
5829 	VN_RELE(execvp);
5830 	VN_RELE(vrootp);
5831 
5832 	return (ret);
5833 }
5834 
5835 /* ARGSUSED */
5836 static int
5837 prreadlink(vnode_t *vp, uio_t *uiop, cred_t *cr, caller_context_t *ctp)
5838 {
5839 	prnode_t *pnp = VTOP(vp);
5840 	char *buf;
5841 	int ret = EINVAL;
5842 	char idbuf[16];
5843 	int length, rlength;
5844 	contract_t *ct;
5845 
5846 	switch (pnp->pr_type) {
5847 	case PR_SELF:
5848 		(void) snprintf(idbuf, sizeof (idbuf), "%d", curproc->p_pid);
5849 		ret = uiomove(idbuf, strlen(idbuf), UIO_READ, uiop);
5850 		break;
5851 	case PR_OBJECT:
5852 	case PR_FD:
5853 	case PR_CURDIR:
5854 	case PR_ROOTDIR:
5855 		if (pnp->pr_realvp->v_type == VDIR)
5856 			ret = 0;
5857 		break;
5858 	case PR_PATH:
5859 		buf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
5860 
5861 		if ((ret = prreadlink_lookup(pnp, buf, MAXPATHLEN, cr)) == 0)
5862 			ret = uiomove(buf, strlen(buf), UIO_READ, uiop);
5863 
5864 		kmem_free(buf, MAXPATHLEN);
5865 		break;
5866 	case PR_CT:
5867 		ASSERT(pnp->pr_contract != NULL);
5868 		ct = pnp->pr_contract;
5869 		length = sizeof (CTFS_ROOT "//") + sizeof (idbuf) +
5870 		    strlen(ct->ct_type->ct_type_name);
5871 		buf = kmem_alloc(length, KM_SLEEP);
5872 		rlength = snprintf(buf, length, CTFS_ROOT "/%s/%d",
5873 		    ct->ct_type->ct_type_name, ct->ct_id);
5874 		ASSERT(rlength < length);
5875 		ret = uiomove(buf, rlength, UIO_READ, uiop);
5876 		kmem_free(buf, length);
5877 		break;
5878 	default:
5879 		break;
5880 	}
5881 
5882 	return (ret);
5883 }
5884 
5885 /*ARGSUSED2*/
5886 static int
5887 prcmp(vnode_t *vp1, vnode_t *vp2, caller_context_t *ct)
5888 {
5889 	prnode_t *pp1, *pp2;
5890 
5891 	if (vp1 == vp2)
5892 		return (1);
5893 
5894 	if (!vn_matchops(vp1, prvnodeops) || !vn_matchops(vp2, prvnodeops))
5895 		return (0);
5896 
5897 	pp1 = VTOP(vp1);
5898 	pp2 = VTOP(vp2);
5899 
5900 	if (pp1->pr_type != pp2->pr_type)
5901 		return (0);
5902 	if (pp1->pr_type == PR_PROCDIR)
5903 		return (1);
5904 	if (pp1->pr_ino || pp2->pr_ino)
5905 		return (pp2->pr_ino == pp1->pr_ino);
5906 
5907 	if (pp1->pr_common == NULL || pp2->pr_common == NULL)
5908 		return (0);
5909 
5910 	return (pp1->pr_common->prc_slot == pp2->pr_common->prc_slot &&
5911 	    pp1->pr_common->prc_tslot == pp2->pr_common->prc_tslot);
5912 }
5913 
5914 static int
5915 prrealvp(vnode_t *vp, vnode_t **vpp, caller_context_t *ct)
5916 {
5917 	vnode_t *rvp;
5918 
5919 	if ((rvp = VTOP(vp)->pr_realvp) != NULL) {
5920 		vp = rvp;
5921 		if (VOP_REALVP(vp, &rvp, ct) == 0)
5922 			vp = rvp;
5923 	}
5924 
5925 	*vpp = vp;
5926 	return (0);
5927 }
5928 
5929 /*
5930  * Return the answer requested to poll().
5931  * POLLIN, POLLRDNORM, and POLLOUT are recognized as in fs_poll().
5932  * In addition, these have special meaning for /proc files:
5933  *	POLLPRI		process or lwp stopped on an event of interest
5934  *	POLLERR		/proc file descriptor is invalid
5935  *	POLLHUP		process or lwp has terminated
5936  */
5937 /*ARGSUSED5*/
5938 static int
5939 prpoll(vnode_t *vp, short events, int anyyet, short *reventsp,
5940     pollhead_t **phpp, caller_context_t *ct)
5941 {
5942 	prnode_t *pnp = VTOP(vp);
5943 	prcommon_t *pcp = pnp->pr_common;
5944 	pollhead_t *php = &pcp->prc_pollhead;
5945 	proc_t *p;
5946 	short revents;
5947 	int error;
5948 	int lockstate;
5949 
5950 	ASSERT(pnp->pr_type < PR_NFILES);
5951 
5952 	/*
5953 	 * Support for old /proc interface.
5954 	 */
5955 	if (pnp->pr_pidfile != NULL) {
5956 		vp = pnp->pr_pidfile;
5957 		pnp = VTOP(vp);
5958 		ASSERT(pnp->pr_type == PR_PIDFILE);
5959 		ASSERT(pnp->pr_common == pcp);
5960 	}
5961 
5962 	*reventsp = revents = 0;
5963 	*phpp = (pollhead_t *)NULL;
5964 
5965 	if (vp->v_type == VDIR) {
5966 		*reventsp |= POLLNVAL;
5967 		return (0);
5968 	}
5969 
5970 	/* avoid deadlock with prnotify() */
5971 	if (pollunlock(&lockstate) != 0) {
5972 		*reventsp = POLLNVAL;
5973 		return (0);
5974 	}
5975 
5976 	if ((error = prlock(pnp, ZNO)) != 0) {
5977 		pollrelock(lockstate);
5978 		switch (error) {
5979 		case ENOENT:		/* process or lwp died */
5980 			*reventsp = POLLHUP;
5981 			error = 0;
5982 			break;
5983 		case EAGAIN:		/* invalidated */
5984 			*reventsp = POLLERR;
5985 			error = 0;
5986 			break;
5987 		}
5988 		return (error);
5989 	}
5990 
5991 	/*
5992 	 * We have the process marked locked (P_PR_LOCK) and we are holding
5993 	 * its p->p_lock.  We want to unmark the process but retain
5994 	 * exclusive control w.r.t. other /proc controlling processes
5995 	 * before reacquiring the polling locks.
5996 	 *
5997 	 * prunmark() does this for us.  It unmarks the process
5998 	 * but retains p->p_lock so we still have exclusive control.
5999 	 * We will drop p->p_lock at the end to relinquish control.
6000 	 *
6001 	 * We cannot call prunlock() at the end to relinquish control
6002 	 * because prunlock(), like prunmark(), may drop and reacquire
6003 	 * p->p_lock and that would lead to a lock order violation
6004 	 * w.r.t. the polling locks we are about to reacquire.
6005 	 */
6006 	p = pcp->prc_proc;
6007 	ASSERT(p != NULL);
6008 	prunmark(p);
6009 
6010 	pollrelock(lockstate);		/* reacquire dropped poll locks */
6011 
6012 	if ((p->p_flag & SSYS) || p->p_as == &kas)
6013 		revents = POLLNVAL;
6014 	else {
6015 		short ev;
6016 
6017 		if ((ev = (events & (POLLIN|POLLRDNORM))) != 0)
6018 			revents |= ev;
6019 		/*
6020 		 * POLLWRNORM (same as POLLOUT) really should not be
6021 		 * used to indicate that the process or lwp stopped.
6022 		 * However, USL chose to use POLLWRNORM rather than
6023 		 * POLLPRI to indicate this, so we just accept either
6024 		 * requested event to indicate stopped.  (grr...)
6025 		 */
6026 		if ((ev = (events & (POLLPRI|POLLOUT|POLLWRNORM))) != 0) {
6027 			kthread_t *t;
6028 
6029 			if (pcp->prc_flags & PRC_LWP) {
6030 				t = pcp->prc_thread;
6031 				ASSERT(t != NULL);
6032 				thread_lock(t);
6033 			} else {
6034 				t = prchoose(p);	/* returns locked t */
6035 				ASSERT(t != NULL);
6036 			}
6037 
6038 			if (ISTOPPED(t) || VSTOPPED(t))
6039 				revents |= ev;
6040 			thread_unlock(t);
6041 		}
6042 	}
6043 
6044 	*reventsp = revents;
6045 	if ((!anyyet && revents == 0) || (events & POLLET)) {
6046 		/*
6047 		 * Arrange to wake up the polling lwp when
6048 		 * the target process/lwp stops or terminates
6049 		 * or when the file descriptor becomes invalid.
6050 		 */
6051 		pcp->prc_flags |= PRC_POLL;
6052 		*phpp = php;
6053 	}
6054 	mutex_exit(&p->p_lock);
6055 	return (0);
6056 }
6057 
6058 /* in prioctl.c */
6059 extern int prioctl(vnode_t *, int, intptr_t, int, cred_t *, int *,
6060 	caller_context_t *);
6061 
6062 /*
6063  * /proc vnode operations vector
6064  */
6065 const fs_operation_def_t pr_vnodeops_template[] = {
6066 	VOPNAME_OPEN,		{ .vop_open = propen },
6067 	VOPNAME_CLOSE,		{ .vop_close = prclose },
6068 	VOPNAME_READ,		{ .vop_read = prread },
6069 	VOPNAME_WRITE,		{ .vop_write = prwrite },
6070 	VOPNAME_IOCTL,		{ .vop_ioctl = prioctl },
6071 	VOPNAME_GETATTR,	{ .vop_getattr = prgetattr },
6072 	VOPNAME_ACCESS,		{ .vop_access = praccess },
6073 	VOPNAME_LOOKUP,		{ .vop_lookup = prlookup },
6074 	VOPNAME_CREATE,		{ .vop_create = prcreate },
6075 	VOPNAME_READDIR,	{ .vop_readdir = prreaddir },
6076 	VOPNAME_READLINK,	{ .vop_readlink = prreadlink },
6077 	VOPNAME_FSYNC,		{ .vop_fsync = prfsync },
6078 	VOPNAME_INACTIVE,	{ .vop_inactive = prinactive },
6079 	VOPNAME_SEEK,		{ .vop_seek = prseek },
6080 	VOPNAME_CMP,		{ .vop_cmp = prcmp },
6081 	VOPNAME_FRLOCK,		{ .error = fs_error },
6082 	VOPNAME_REALVP,		{ .vop_realvp = prrealvp },
6083 	VOPNAME_POLL,		{ .vop_poll = prpoll },
6084 	VOPNAME_DISPOSE,	{ .error = fs_error },
6085 	VOPNAME_SHRLOCK,	{ .error = fs_error },
6086 	NULL,			NULL
6087 };
6088