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