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