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