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