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