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