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