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