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