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