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