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