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