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