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