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