xref: /illumos-gate/usr/src/uts/common/fs/proc/prsubr.c (revision f343451914d0efaf2d6fc84d8818a16246b223dc)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
25  * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
26  */
27 
28 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
29 /*	  All Rights Reserved	*/
30 
31 #include <sys/types.h>
32 #include <sys/t_lock.h>
33 #include <sys/param.h>
34 #include <sys/cmn_err.h>
35 #include <sys/cred.h>
36 #include <sys/priv.h>
37 #include <sys/debug.h>
38 #include <sys/errno.h>
39 #include <sys/inline.h>
40 #include <sys/kmem.h>
41 #include <sys/mman.h>
42 #include <sys/proc.h>
43 #include <sys/brand.h>
44 #include <sys/sobject.h>
45 #include <sys/sysmacros.h>
46 #include <sys/systm.h>
47 #include <sys/uio.h>
48 #include <sys/var.h>
49 #include <sys/vfs.h>
50 #include <sys/vnode.h>
51 #include <sys/session.h>
52 #include <sys/pcb.h>
53 #include <sys/signal.h>
54 #include <sys/user.h>
55 #include <sys/disp.h>
56 #include <sys/class.h>
57 #include <sys/ts.h>
58 #include <sys/bitmap.h>
59 #include <sys/poll.h>
60 #include <sys/shm_impl.h>
61 #include <sys/fault.h>
62 #include <sys/syscall.h>
63 #include <sys/procfs.h>
64 #include <sys/processor.h>
65 #include <sys/cpuvar.h>
66 #include <sys/copyops.h>
67 #include <sys/time.h>
68 #include <sys/msacct.h>
69 #include <sys/flock_impl.h>
70 #include <sys/stropts.h>
71 #include <sys/strsubr.h>
72 #include <sys/pathname.h>
73 #include <sys/mode.h>
74 #include <sys/socketvar.h>
75 #include <sys/autoconf.h>
76 #include <sys/dtrace.h>
77 #include <sys/timod.h>
78 #include <sys/fs/namenode.h>
79 #include <netinet/udp.h>
80 #include <netinet/tcp.h>
81 #include <inet/cc.h>
82 #include <vm/as.h>
83 #include <vm/rm.h>
84 #include <vm/seg.h>
85 #include <vm/seg_vn.h>
86 #include <vm/seg_dev.h>
87 #include <vm/seg_spt.h>
88 #include <vm/page.h>
89 #include <sys/vmparam.h>
90 #include <sys/swap.h>
91 #include <fs/proc/prdata.h>
92 #include <sys/task.h>
93 #include <sys/project.h>
94 #include <sys/contract_impl.h>
95 #include <sys/contract/process.h>
96 #include <sys/contract/process_impl.h>
97 #include <sys/schedctl.h>
98 #include <sys/pool.h>
99 #include <sys/zone.h>
100 #include <sys/atomic.h>
101 #include <sys/sdt.h>
102 
103 #define	MAX_ITERS_SPIN	5
104 
105 typedef struct prpagev {
106 	uint_t *pg_protv;	/* vector of page permissions */
107 	char *pg_incore;	/* vector of incore flags */
108 	size_t pg_npages;	/* number of pages in protv and incore */
109 	ulong_t pg_pnbase;	/* pn within segment of first protv element */
110 } prpagev_t;
111 
112 size_t pagev_lim = 256 * 1024;	/* limit on number of pages in prpagev_t */
113 
114 extern struct seg_ops segdev_ops;	/* needs a header file */
115 extern struct seg_ops segspt_shmops;	/* needs a header file */
116 
117 static	int	set_watched_page(proc_t *, caddr_t, caddr_t, ulong_t, ulong_t);
118 static	void	clear_watched_page(proc_t *, caddr_t, caddr_t, ulong_t);
119 
120 /*
121  * Choose an lwp from the complete set of lwps for the process.
122  * This is called for any operation applied to the process
123  * file descriptor that requires an lwp to operate upon.
124  *
125  * Returns a pointer to the thread for the selected LWP,
126  * and with the dispatcher lock held for the thread.
127  *
128  * The algorithm for choosing an lwp is critical for /proc semantics;
129  * don't touch this code unless you know all of the implications.
130  */
131 kthread_t *
132 prchoose(proc_t *p)
133 {
134 	kthread_t *t;
135 	kthread_t *t_onproc = NULL;	/* running on processor */
136 	kthread_t *t_run = NULL;	/* runnable, on disp queue */
137 	kthread_t *t_sleep = NULL;	/* sleeping */
138 	kthread_t *t_hold = NULL;	/* sleeping, performing hold */
139 	kthread_t *t_susp = NULL;	/* suspended stop */
140 	kthread_t *t_jstop = NULL;	/* jobcontrol stop, w/o directed stop */
141 	kthread_t *t_jdstop = NULL;	/* jobcontrol stop with directed stop */
142 	kthread_t *t_req = NULL;	/* requested stop */
143 	kthread_t *t_istop = NULL;	/* event-of-interest stop */
144 	kthread_t *t_dtrace = NULL;	/* DTrace stop */
145 
146 	ASSERT(MUTEX_HELD(&p->p_lock));
147 
148 	/*
149 	 * If the agent lwp exists, it takes precedence over all others.
150 	 */
151 	if ((t = p->p_agenttp) != NULL) {
152 		thread_lock(t);
153 		return (t);
154 	}
155 
156 	if ((t = p->p_tlist) == NULL)	/* start at the head of the list */
157 		return (t);
158 	do {		/* for eacn lwp in the process */
159 		if (VSTOPPED(t)) {	/* virtually stopped */
160 			if (t_req == NULL)
161 				t_req = t;
162 			continue;
163 		}
164 
165 		thread_lock(t);		/* make sure thread is in good state */
166 		switch (t->t_state) {
167 		default:
168 			panic("prchoose: bad thread state %d, thread 0x%p",
169 			    t->t_state, (void *)t);
170 			/*NOTREACHED*/
171 		case TS_SLEEP:
172 			/* this is filthy */
173 			if (t->t_wchan == (caddr_t)&p->p_holdlwps &&
174 			    t->t_wchan0 == NULL) {
175 				if (t_hold == NULL)
176 					t_hold = t;
177 			} else {
178 				if (t_sleep == NULL)
179 					t_sleep = t;
180 			}
181 			break;
182 		case TS_RUN:
183 		case TS_WAIT:
184 			if (t_run == NULL)
185 				t_run = t;
186 			break;
187 		case TS_ONPROC:
188 			if (t_onproc == NULL)
189 				t_onproc = t;
190 			break;
191 		case TS_ZOMB:		/* last possible choice */
192 			break;
193 		case TS_STOPPED:
194 			switch (t->t_whystop) {
195 			case PR_SUSPENDED:
196 				if (t_susp == NULL)
197 					t_susp = t;
198 				break;
199 			case PR_JOBCONTROL:
200 				if (t->t_proc_flag & TP_PRSTOP) {
201 					if (t_jdstop == NULL)
202 						t_jdstop = t;
203 				} else {
204 					if (t_jstop == NULL)
205 						t_jstop = t;
206 				}
207 				break;
208 			case PR_REQUESTED:
209 				if (t->t_dtrace_stop && t_dtrace == NULL)
210 					t_dtrace = t;
211 				else if (t_req == NULL)
212 					t_req = t;
213 				break;
214 			case PR_SYSENTRY:
215 			case PR_SYSEXIT:
216 			case PR_SIGNALLED:
217 			case PR_FAULTED:
218 				/*
219 				 * Make an lwp calling exit() be the
220 				 * last lwp seen in the process.
221 				 */
222 				if (t_istop == NULL ||
223 				    (t_istop->t_whystop == PR_SYSENTRY &&
224 				    t_istop->t_whatstop == SYS_exit))
225 					t_istop = t;
226 				break;
227 			case PR_CHECKPOINT:	/* can't happen? */
228 				break;
229 			default:
230 				panic("prchoose: bad t_whystop %d, thread 0x%p",
231 				    t->t_whystop, (void *)t);
232 				/*NOTREACHED*/
233 			}
234 			break;
235 		}
236 		thread_unlock(t);
237 	} while ((t = t->t_forw) != p->p_tlist);
238 
239 	if (t_onproc)
240 		t = t_onproc;
241 	else if (t_run)
242 		t = t_run;
243 	else if (t_sleep)
244 		t = t_sleep;
245 	else if (t_jstop)
246 		t = t_jstop;
247 	else if (t_jdstop)
248 		t = t_jdstop;
249 	else if (t_istop)
250 		t = t_istop;
251 	else if (t_dtrace)
252 		t = t_dtrace;
253 	else if (t_req)
254 		t = t_req;
255 	else if (t_hold)
256 		t = t_hold;
257 	else if (t_susp)
258 		t = t_susp;
259 	else			/* TS_ZOMB */
260 		t = p->p_tlist;
261 
262 	if (t != NULL)
263 		thread_lock(t);
264 	return (t);
265 }
266 
267 /*
268  * Wakeup anyone sleeping on the /proc vnode for the process/lwp to stop.
269  * Also call pollwakeup() if any lwps are waiting in poll() for POLLPRI
270  * on the /proc file descriptor.  Called from stop() when a traced
271  * process stops on an event of interest.  Also called from exit()
272  * and prinvalidate() to indicate POLLHUP and POLLERR respectively.
273  */
274 void
275 prnotify(struct vnode *vp)
276 {
277 	prcommon_t *pcp = VTOP(vp)->pr_common;
278 
279 	mutex_enter(&pcp->prc_mutex);
280 	cv_broadcast(&pcp->prc_wait);
281 	mutex_exit(&pcp->prc_mutex);
282 	if (pcp->prc_flags & PRC_POLL) {
283 		/*
284 		 * We call pollwakeup() with POLLHUP to ensure that
285 		 * the pollers are awakened even if they are polling
286 		 * for nothing (i.e., waiting for the process to exit).
287 		 * This enables the use of the PRC_POLL flag for optimization
288 		 * (we can turn off PRC_POLL only if we know no pollers remain).
289 		 */
290 		pcp->prc_flags &= ~PRC_POLL;
291 		pollwakeup(&pcp->prc_pollhead, POLLHUP);
292 	}
293 }
294 
295 /* called immediately below, in prfree() */
296 static void
297 prfreenotify(vnode_t *vp)
298 {
299 	prnode_t *pnp;
300 	prcommon_t *pcp;
301 
302 	while (vp != NULL) {
303 		pnp = VTOP(vp);
304 		pcp = pnp->pr_common;
305 		ASSERT(pcp->prc_thread == NULL);
306 		pcp->prc_proc = NULL;
307 		/*
308 		 * We can't call prnotify() here because we are holding
309 		 * pidlock.  We assert that there is no need to.
310 		 */
311 		mutex_enter(&pcp->prc_mutex);
312 		cv_broadcast(&pcp->prc_wait);
313 		mutex_exit(&pcp->prc_mutex);
314 		ASSERT(!(pcp->prc_flags & PRC_POLL));
315 
316 		vp = pnp->pr_next;
317 		pnp->pr_next = NULL;
318 	}
319 }
320 
321 /*
322  * Called from a hook in freeproc() when a traced process is removed
323  * from the process table.  The proc-table pointers of all associated
324  * /proc vnodes are cleared to indicate that the process has gone away.
325  */
326 void
327 prfree(proc_t *p)
328 {
329 	uint_t slot = p->p_slot;
330 
331 	ASSERT(MUTEX_HELD(&pidlock));
332 
333 	/*
334 	 * Block the process against /proc so it can be freed.
335 	 * It cannot be freed while locked by some controlling process.
336 	 * Lock ordering:
337 	 *	pidlock -> pr_pidlock -> p->p_lock -> pcp->prc_mutex
338 	 */
339 	mutex_enter(&pr_pidlock);	/* protects pcp->prc_proc */
340 	mutex_enter(&p->p_lock);
341 	while (p->p_proc_flag & P_PR_LOCK) {
342 		mutex_exit(&pr_pidlock);
343 		cv_wait(&pr_pid_cv[slot], &p->p_lock);
344 		mutex_exit(&p->p_lock);
345 		mutex_enter(&pr_pidlock);
346 		mutex_enter(&p->p_lock);
347 	}
348 
349 	ASSERT(p->p_tlist == NULL);
350 
351 	prfreenotify(p->p_plist);
352 	p->p_plist = NULL;
353 
354 	prfreenotify(p->p_trace);
355 	p->p_trace = NULL;
356 
357 	/*
358 	 * We broadcast to wake up everyone waiting for this process.
359 	 * No one can reach this process from this point on.
360 	 */
361 	cv_broadcast(&pr_pid_cv[slot]);
362 
363 	mutex_exit(&p->p_lock);
364 	mutex_exit(&pr_pidlock);
365 }
366 
367 /*
368  * Called from a hook in exit() when a traced process is becoming a zombie.
369  */
370 void
371 prexit(proc_t *p)
372 {
373 	ASSERT(MUTEX_HELD(&p->p_lock));
374 
375 	if (pr_watch_active(p)) {
376 		pr_free_watchpoints(p);
377 		watch_disable(curthread);
378 	}
379 	/* pr_free_watched_pages() is called in exit(), after dropping p_lock */
380 	if (p->p_trace) {
381 		VTOP(p->p_trace)->pr_common->prc_flags |= PRC_DESTROY;
382 		prnotify(p->p_trace);
383 	}
384 	cv_broadcast(&pr_pid_cv[p->p_slot]);	/* pauselwps() */
385 }
386 
387 /*
388  * Called when a thread calls lwp_exit().
389  */
390 void
391 prlwpexit(kthread_t *t)
392 {
393 	vnode_t *vp;
394 	prnode_t *pnp;
395 	prcommon_t *pcp;
396 	proc_t *p = ttoproc(t);
397 	lwpent_t *lep = p->p_lwpdir[t->t_dslot].ld_entry;
398 
399 	ASSERT(t == curthread);
400 	ASSERT(MUTEX_HELD(&p->p_lock));
401 
402 	/*
403 	 * The process must be blocked against /proc to do this safely.
404 	 * The lwp must not disappear while the process is marked P_PR_LOCK.
405 	 * It is the caller's responsibility to have called prbarrier(p).
406 	 */
407 	ASSERT(!(p->p_proc_flag & P_PR_LOCK));
408 
409 	for (vp = p->p_plist; vp != NULL; vp = pnp->pr_next) {
410 		pnp = VTOP(vp);
411 		pcp = pnp->pr_common;
412 		if (pcp->prc_thread == t) {
413 			pcp->prc_thread = NULL;
414 			pcp->prc_flags |= PRC_DESTROY;
415 		}
416 	}
417 
418 	for (vp = lep->le_trace; vp != NULL; vp = pnp->pr_next) {
419 		pnp = VTOP(vp);
420 		pcp = pnp->pr_common;
421 		pcp->prc_thread = NULL;
422 		pcp->prc_flags |= PRC_DESTROY;
423 		prnotify(vp);
424 	}
425 
426 	if (p->p_trace)
427 		prnotify(p->p_trace);
428 }
429 
430 /*
431  * Called when a zombie thread is joined or when a
432  * detached lwp exits.  Called from lwp_hash_out().
433  */
434 void
435 prlwpfree(proc_t *p, lwpent_t *lep)
436 {
437 	vnode_t *vp;
438 	prnode_t *pnp;
439 	prcommon_t *pcp;
440 
441 	ASSERT(MUTEX_HELD(&p->p_lock));
442 
443 	/*
444 	 * The process must be blocked against /proc to do this safely.
445 	 * The lwp must not disappear while the process is marked P_PR_LOCK.
446 	 * It is the caller's responsibility to have called prbarrier(p).
447 	 */
448 	ASSERT(!(p->p_proc_flag & P_PR_LOCK));
449 
450 	vp = lep->le_trace;
451 	lep->le_trace = NULL;
452 	while (vp) {
453 		prnotify(vp);
454 		pnp = VTOP(vp);
455 		pcp = pnp->pr_common;
456 		ASSERT(pcp->prc_thread == NULL &&
457 		    (pcp->prc_flags & PRC_DESTROY));
458 		pcp->prc_tslot = -1;
459 		vp = pnp->pr_next;
460 		pnp->pr_next = NULL;
461 	}
462 
463 	if (p->p_trace)
464 		prnotify(p->p_trace);
465 }
466 
467 /*
468  * Called from a hook in exec() when a thread starts exec().
469  */
470 void
471 prexecstart(void)
472 {
473 	proc_t *p = ttoproc(curthread);
474 	klwp_t *lwp = ttolwp(curthread);
475 
476 	/*
477 	 * The P_PR_EXEC flag blocks /proc operations for
478 	 * the duration of the exec().
479 	 * We can't start exec() while the process is
480 	 * locked by /proc, so we call prbarrier().
481 	 * lwp_nostop keeps the process from being stopped
482 	 * via job control for the duration of the exec().
483 	 */
484 
485 	ASSERT(MUTEX_HELD(&p->p_lock));
486 	prbarrier(p);
487 	lwp->lwp_nostop++;
488 	p->p_proc_flag |= P_PR_EXEC;
489 }
490 
491 /*
492  * Called from a hook in exec() when a thread finishes exec().
493  * The thread may or may not have succeeded.  Some other thread
494  * may have beat it to the punch.
495  */
496 void
497 prexecend(void)
498 {
499 	proc_t *p = ttoproc(curthread);
500 	klwp_t *lwp = ttolwp(curthread);
501 	vnode_t *vp;
502 	prnode_t *pnp;
503 	prcommon_t *pcp;
504 	model_t model = p->p_model;
505 	id_t tid = curthread->t_tid;
506 	int tslot = curthread->t_dslot;
507 
508 	ASSERT(MUTEX_HELD(&p->p_lock));
509 
510 	lwp->lwp_nostop--;
511 	if (p->p_flag & SEXITLWPS) {
512 		/*
513 		 * We are on our way to exiting because some
514 		 * other thread beat us in the race to exec().
515 		 * Don't clear the P_PR_EXEC flag in this case.
516 		 */
517 		return;
518 	}
519 
520 	/*
521 	 * Wake up anyone waiting in /proc for the process to complete exec().
522 	 */
523 	p->p_proc_flag &= ~P_PR_EXEC;
524 	if ((vp = p->p_trace) != NULL) {
525 		pcp = VTOP(vp)->pr_common;
526 		mutex_enter(&pcp->prc_mutex);
527 		cv_broadcast(&pcp->prc_wait);
528 		mutex_exit(&pcp->prc_mutex);
529 		for (; vp != NULL; vp = pnp->pr_next) {
530 			pnp = VTOP(vp);
531 			pnp->pr_common->prc_datamodel = model;
532 		}
533 	}
534 	if ((vp = p->p_lwpdir[tslot].ld_entry->le_trace) != NULL) {
535 		/*
536 		 * We dealt with the process common above.
537 		 */
538 		ASSERT(p->p_trace != NULL);
539 		pcp = VTOP(vp)->pr_common;
540 		mutex_enter(&pcp->prc_mutex);
541 		cv_broadcast(&pcp->prc_wait);
542 		mutex_exit(&pcp->prc_mutex);
543 		for (; vp != NULL; vp = pnp->pr_next) {
544 			pnp = VTOP(vp);
545 			pcp = pnp->pr_common;
546 			pcp->prc_datamodel = model;
547 			pcp->prc_tid = tid;
548 			pcp->prc_tslot = tslot;
549 		}
550 	}
551 }
552 
553 /*
554  * Called from a hook in relvm() just before freeing the address space.
555  * We free all the watched areas now.
556  */
557 void
558 prrelvm(void)
559 {
560 	proc_t *p = ttoproc(curthread);
561 
562 	mutex_enter(&p->p_lock);
563 	prbarrier(p);	/* block all other /proc operations */
564 	if (pr_watch_active(p)) {
565 		pr_free_watchpoints(p);
566 		watch_disable(curthread);
567 	}
568 	mutex_exit(&p->p_lock);
569 	pr_free_watched_pages(p);
570 }
571 
572 /*
573  * Called from hooks in exec-related code when a traced process
574  * attempts to exec(2) a setuid/setgid program or an unreadable
575  * file.  Rather than fail the exec we invalidate the associated
576  * /proc vnodes so that subsequent attempts to use them will fail.
577  *
578  * All /proc vnodes, except directory vnodes, are retained on a linked
579  * list (rooted at p_plist in the process structure) until last close.
580  *
581  * A controlling process must re-open the /proc files in order to
582  * regain control.
583  */
584 void
585 prinvalidate(struct user *up)
586 {
587 	kthread_t *t = curthread;
588 	proc_t *p = ttoproc(t);
589 	vnode_t *vp;
590 	prnode_t *pnp;
591 	int writers = 0;
592 
593 	mutex_enter(&p->p_lock);
594 	prbarrier(p);	/* block all other /proc operations */
595 
596 	/*
597 	 * At this moment, there can be only one lwp in the process.
598 	 */
599 	ASSERT(p->p_lwpcnt == 1 && p->p_zombcnt == 0);
600 
601 	/*
602 	 * Invalidate any currently active /proc vnodes.
603 	 */
604 	for (vp = p->p_plist; vp != NULL; vp = pnp->pr_next) {
605 		pnp = VTOP(vp);
606 		switch (pnp->pr_type) {
607 		case PR_PSINFO:		/* these files can read by anyone */
608 		case PR_LPSINFO:
609 		case PR_LWPSINFO:
610 		case PR_LWPDIR:
611 		case PR_LWPIDDIR:
612 		case PR_USAGE:
613 		case PR_LUSAGE:
614 		case PR_LWPUSAGE:
615 			break;
616 		default:
617 			pnp->pr_flags |= PR_INVAL;
618 			break;
619 		}
620 	}
621 	/*
622 	 * Wake up anyone waiting for the process or lwp.
623 	 * p->p_trace is guaranteed to be non-NULL if there
624 	 * are any open /proc files for this process.
625 	 */
626 	if ((vp = p->p_trace) != NULL) {
627 		prcommon_t *pcp = VTOP(vp)->pr_pcommon;
628 
629 		prnotify(vp);
630 		/*
631 		 * Are there any writers?
632 		 */
633 		if ((writers = pcp->prc_writers) != 0) {
634 			/*
635 			 * Clear the exclusive open flag (old /proc interface).
636 			 * Set prc_selfopens equal to prc_writers so that
637 			 * the next O_EXCL|O_WRITE open will succeed
638 			 * even with existing (though invalid) writers.
639 			 * prclose() must decrement prc_selfopens when
640 			 * the invalid files are closed.
641 			 */
642 			pcp->prc_flags &= ~PRC_EXCL;
643 			ASSERT(pcp->prc_selfopens <= writers);
644 			pcp->prc_selfopens = writers;
645 		}
646 	}
647 	vp = p->p_lwpdir[t->t_dslot].ld_entry->le_trace;
648 	while (vp != NULL) {
649 		/*
650 		 * We should not invalidate the lwpiddir vnodes,
651 		 * but the necessities of maintaining the old
652 		 * ioctl()-based version of /proc require it.
653 		 */
654 		pnp = VTOP(vp);
655 		pnp->pr_flags |= PR_INVAL;
656 		prnotify(vp);
657 		vp = pnp->pr_next;
658 	}
659 
660 	/*
661 	 * If any tracing flags are in effect and any vnodes are open for
662 	 * writing then set the requested-stop and run-on-last-close flags.
663 	 * Otherwise, clear all tracing flags.
664 	 */
665 	t->t_proc_flag &= ~TP_PAUSE;
666 	if ((p->p_proc_flag & P_PR_TRACE) && writers) {
667 		t->t_proc_flag |= TP_PRSTOP;
668 		aston(t);		/* so ISSIG will see the flag */
669 		p->p_proc_flag |= P_PR_RUNLCL;
670 	} else {
671 		premptyset(&up->u_entrymask);		/* syscalls */
672 		premptyset(&up->u_exitmask);
673 		up->u_systrap = 0;
674 		premptyset(&p->p_sigmask);		/* signals */
675 		premptyset(&p->p_fltmask);		/* faults */
676 		t->t_proc_flag &= ~(TP_PRSTOP|TP_PRVSTOP|TP_STOPPING);
677 		p->p_proc_flag &= ~(P_PR_RUNLCL|P_PR_KILLCL|P_PR_TRACE);
678 		prnostep(ttolwp(t));
679 	}
680 
681 	mutex_exit(&p->p_lock);
682 }
683 
684 /*
685  * Acquire the controlled process's p_lock and mark it P_PR_LOCK.
686  * Return with pr_pidlock held in all cases.
687  * Return with p_lock held if the the process still exists.
688  * Return value is the process pointer if the process still exists, else NULL.
689  * If we lock the process, give ourself kernel priority to avoid deadlocks;
690  * this is undone in prunlock().
691  */
692 proc_t *
693 pr_p_lock(prnode_t *pnp)
694 {
695 	proc_t *p;
696 	prcommon_t *pcp;
697 
698 	mutex_enter(&pr_pidlock);
699 	if ((pcp = pnp->pr_pcommon) == NULL || (p = pcp->prc_proc) == NULL)
700 		return (NULL);
701 	mutex_enter(&p->p_lock);
702 	while (p->p_proc_flag & P_PR_LOCK) {
703 		/*
704 		 * This cv/mutex pair is persistent even if
705 		 * the process disappears while we sleep.
706 		 */
707 		kcondvar_t *cv = &pr_pid_cv[p->p_slot];
708 		kmutex_t *mp = &p->p_lock;
709 
710 		mutex_exit(&pr_pidlock);
711 		cv_wait(cv, mp);
712 		mutex_exit(mp);
713 		mutex_enter(&pr_pidlock);
714 		if (pcp->prc_proc == NULL)
715 			return (NULL);
716 		ASSERT(p == pcp->prc_proc);
717 		mutex_enter(&p->p_lock);
718 	}
719 	p->p_proc_flag |= P_PR_LOCK;
720 	return (p);
721 }
722 
723 /*
724  * Lock the target process by setting P_PR_LOCK and grabbing p->p_lock.
725  * This prevents any lwp of the process from disappearing and
726  * blocks most operations that a process can perform on itself.
727  * Returns 0 on success, a non-zero error number on failure.
728  *
729  * 'zdisp' is ZYES or ZNO to indicate whether prlock() should succeed when
730  * the subject process is a zombie (ZYES) or fail for zombies (ZNO).
731  *
732  * error returns:
733  *	ENOENT: process or lwp has disappeared or process is exiting
734  *		(or has become a zombie and zdisp == ZNO).
735  *	EAGAIN: procfs vnode has become invalid.
736  *	EINTR:  signal arrived while waiting for exec to complete.
737  */
738 int
739 prlock(prnode_t *pnp, int zdisp)
740 {
741 	prcommon_t *pcp;
742 	proc_t *p;
743 
744 again:
745 	pcp = pnp->pr_common;
746 	p = pr_p_lock(pnp);
747 	mutex_exit(&pr_pidlock);
748 
749 	/*
750 	 * Return ENOENT immediately if there is no process.
751 	 */
752 	if (p == NULL)
753 		return (ENOENT);
754 
755 	ASSERT(p == pcp->prc_proc && p->p_stat != 0 && p->p_stat != SIDL);
756 
757 	/*
758 	 * Return ENOENT if process entered zombie state or is exiting
759 	 * and the 'zdisp' flag is set to ZNO indicating not to lock zombies.
760 	 */
761 	if (zdisp == ZNO &&
762 	    ((pcp->prc_flags & PRC_DESTROY) || (p->p_flag & SEXITING))) {
763 		prunlock(pnp);
764 		return (ENOENT);
765 	}
766 
767 	/*
768 	 * If lwp-specific, check to see if lwp has disappeared.
769 	 */
770 	if (pcp->prc_flags & PRC_LWP) {
771 		if ((zdisp == ZNO && (pcp->prc_flags & PRC_DESTROY)) ||
772 		    pcp->prc_tslot == -1) {
773 			prunlock(pnp);
774 			return (ENOENT);
775 		}
776 	}
777 
778 	/*
779 	 * Return EAGAIN if we have encountered a security violation.
780 	 * (The process exec'd a set-id or unreadable executable file.)
781 	 */
782 	if (pnp->pr_flags & PR_INVAL) {
783 		prunlock(pnp);
784 		return (EAGAIN);
785 	}
786 
787 	/*
788 	 * If process is undergoing an exec(), wait for
789 	 * completion and then start all over again.
790 	 */
791 	if (p->p_proc_flag & P_PR_EXEC) {
792 		pcp = pnp->pr_pcommon;	/* Put on the correct sleep queue */
793 		mutex_enter(&pcp->prc_mutex);
794 		prunlock(pnp);
795 		if (!cv_wait_sig(&pcp->prc_wait, &pcp->prc_mutex)) {
796 			mutex_exit(&pcp->prc_mutex);
797 			return (EINTR);
798 		}
799 		mutex_exit(&pcp->prc_mutex);
800 		goto again;
801 	}
802 
803 	/*
804 	 * We return holding p->p_lock.
805 	 */
806 	return (0);
807 }
808 
809 /*
810  * Undo prlock() and pr_p_lock().
811  * p->p_lock is still held; pr_pidlock is no longer held.
812  *
813  * prunmark() drops the P_PR_LOCK flag and wakes up another thread,
814  * if any, waiting for the flag to be dropped; it retains p->p_lock.
815  *
816  * prunlock() calls prunmark() and then drops p->p_lock.
817  */
818 void
819 prunmark(proc_t *p)
820 {
821 	ASSERT(p->p_proc_flag & P_PR_LOCK);
822 	ASSERT(MUTEX_HELD(&p->p_lock));
823 
824 	cv_signal(&pr_pid_cv[p->p_slot]);
825 	p->p_proc_flag &= ~P_PR_LOCK;
826 }
827 
828 void
829 prunlock(prnode_t *pnp)
830 {
831 	prcommon_t *pcp = pnp->pr_common;
832 	proc_t *p = pcp->prc_proc;
833 
834 	/*
835 	 * If we (or someone) gave it a SIGKILL, and it is not
836 	 * already a zombie, set it running unconditionally.
837 	 */
838 	if ((p->p_flag & SKILLED) &&
839 	    !(p->p_flag & SEXITING) &&
840 	    !(pcp->prc_flags & PRC_DESTROY) &&
841 	    !((pcp->prc_flags & PRC_LWP) && pcp->prc_tslot == -1))
842 		(void) pr_setrun(pnp, 0);
843 	prunmark(p);
844 	mutex_exit(&p->p_lock);
845 }
846 
847 /*
848  * Called while holding p->p_lock to delay until the process is unlocked.
849  * We enter holding p->p_lock; p->p_lock is dropped and reacquired.
850  * The process cannot become locked again until p->p_lock is dropped.
851  */
852 void
853 prbarrier(proc_t *p)
854 {
855 	ASSERT(MUTEX_HELD(&p->p_lock));
856 
857 	if (p->p_proc_flag & P_PR_LOCK) {
858 		/* The process is locked; delay until not locked */
859 		uint_t slot = p->p_slot;
860 
861 		while (p->p_proc_flag & P_PR_LOCK)
862 			cv_wait(&pr_pid_cv[slot], &p->p_lock);
863 		cv_signal(&pr_pid_cv[slot]);
864 	}
865 }
866 
867 /*
868  * Return process/lwp status.
869  * The u-block is mapped in by this routine and unmapped at the end.
870  */
871 void
872 prgetstatus(proc_t *p, pstatus_t *sp, zone_t *zp)
873 {
874 	kthread_t *t;
875 
876 	ASSERT(MUTEX_HELD(&p->p_lock));
877 
878 	t = prchoose(p);	/* returns locked thread */
879 	ASSERT(t != NULL);
880 	thread_unlock(t);
881 
882 	/* just bzero the process part, prgetlwpstatus() does the rest */
883 	bzero(sp, sizeof (pstatus_t) - sizeof (lwpstatus_t));
884 	sp->pr_nlwp = p->p_lwpcnt;
885 	sp->pr_nzomb = p->p_zombcnt;
886 	prassignset(&sp->pr_sigpend, &p->p_sig);
887 	sp->pr_brkbase = (uintptr_t)p->p_brkbase;
888 	sp->pr_brksize = p->p_brksize;
889 	sp->pr_stkbase = (uintptr_t)prgetstackbase(p);
890 	sp->pr_stksize = p->p_stksize;
891 	sp->pr_pid = p->p_pid;
892 	if (curproc->p_zone->zone_id != GLOBAL_ZONEID &&
893 	    (p->p_flag & SZONETOP)) {
894 		ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID);
895 		/*
896 		 * Inside local zones, fake zsched's pid as parent pids for
897 		 * processes which reference processes outside of the zone.
898 		 */
899 		sp->pr_ppid = curproc->p_zone->zone_zsched->p_pid;
900 	} else {
901 		sp->pr_ppid = p->p_ppid;
902 	}
903 	sp->pr_pgid  = p->p_pgrp;
904 	sp->pr_sid   = p->p_sessp->s_sid;
905 	sp->pr_taskid = p->p_task->tk_tkid;
906 	sp->pr_projid = p->p_task->tk_proj->kpj_id;
907 	sp->pr_zoneid = p->p_zone->zone_id;
908 	hrt2ts(mstate_aggr_state(p, LMS_USER), &sp->pr_utime);
909 	hrt2ts(mstate_aggr_state(p, LMS_SYSTEM), &sp->pr_stime);
910 	TICK_TO_TIMESTRUC(p->p_cutime, &sp->pr_cutime);
911 	TICK_TO_TIMESTRUC(p->p_cstime, &sp->pr_cstime);
912 	prassignset(&sp->pr_sigtrace, &p->p_sigmask);
913 	prassignset(&sp->pr_flttrace, &p->p_fltmask);
914 	prassignset(&sp->pr_sysentry, &PTOU(p)->u_entrymask);
915 	prassignset(&sp->pr_sysexit, &PTOU(p)->u_exitmask);
916 	switch (p->p_model) {
917 	case DATAMODEL_ILP32:
918 		sp->pr_dmodel = PR_MODEL_ILP32;
919 		break;
920 	case DATAMODEL_LP64:
921 		sp->pr_dmodel = PR_MODEL_LP64;
922 		break;
923 	}
924 	if (p->p_agenttp)
925 		sp->pr_agentid = p->p_agenttp->t_tid;
926 
927 	/* get the chosen lwp's status */
928 	prgetlwpstatus(t, &sp->pr_lwp, zp);
929 
930 	/* replicate the flags */
931 	sp->pr_flags = sp->pr_lwp.pr_flags;
932 }
933 
934 /*
935  * Query mask of held signals for a given thread.
936  *
937  * This makes use of schedctl_sigblock() to query if userspace has requested
938  * that all maskable signals be held.  While it would be tempting to call
939  * schedctl_finish_sigblock() and apply that update to t->t_hold, it cannot be
940  * done safely without the risk of racing with the thread under consideration.
941  */
942 void
943 prgethold(kthread_t *t, sigset_t *sp)
944 {
945 	k_sigset_t set;
946 
947 	if (schedctl_sigblock(t)) {
948 		set.__sigbits[0] = FILLSET0 & ~CANTMASK0;
949 		set.__sigbits[1] = FILLSET1 & ~CANTMASK1;
950 		set.__sigbits[2] = FILLSET2 & ~CANTMASK2;
951 	} else {
952 		set = t->t_hold;
953 	}
954 	sigktou(&set, sp);
955 }
956 
957 #ifdef _SYSCALL32_IMPL
958 void
959 prgetlwpstatus32(kthread_t *t, lwpstatus32_t *sp, zone_t *zp)
960 {
961 	proc_t *p = ttoproc(t);
962 	klwp_t *lwp = ttolwp(t);
963 	struct mstate *ms = &lwp->lwp_mstate;
964 	hrtime_t usr, sys;
965 	int flags;
966 	ulong_t instr;
967 
968 	ASSERT(MUTEX_HELD(&p->p_lock));
969 
970 	bzero(sp, sizeof (*sp));
971 	flags = 0L;
972 	if (t->t_state == TS_STOPPED) {
973 		flags |= PR_STOPPED;
974 		if ((t->t_schedflag & TS_PSTART) == 0)
975 			flags |= PR_ISTOP;
976 	} else if (VSTOPPED(t)) {
977 		flags |= PR_STOPPED|PR_ISTOP;
978 	}
979 	if (!(flags & PR_ISTOP) && (t->t_proc_flag & TP_PRSTOP))
980 		flags |= PR_DSTOP;
981 	if (lwp->lwp_asleep)
982 		flags |= PR_ASLEEP;
983 	if (t == p->p_agenttp)
984 		flags |= PR_AGENT;
985 	if (!(t->t_proc_flag & TP_TWAIT))
986 		flags |= PR_DETACH;
987 	if (t->t_proc_flag & TP_DAEMON)
988 		flags |= PR_DAEMON;
989 	if (p->p_proc_flag & P_PR_FORK)
990 		flags |= PR_FORK;
991 	if (p->p_proc_flag & P_PR_RUNLCL)
992 		flags |= PR_RLC;
993 	if (p->p_proc_flag & P_PR_KILLCL)
994 		flags |= PR_KLC;
995 	if (p->p_proc_flag & P_PR_ASYNC)
996 		flags |= PR_ASYNC;
997 	if (p->p_proc_flag & P_PR_BPTADJ)
998 		flags |= PR_BPTADJ;
999 	if (p->p_proc_flag & P_PR_PTRACE)
1000 		flags |= PR_PTRACE;
1001 	if (p->p_flag & SMSACCT)
1002 		flags |= PR_MSACCT;
1003 	if (p->p_flag & SMSFORK)
1004 		flags |= PR_MSFORK;
1005 	if (p->p_flag & SVFWAIT)
1006 		flags |= PR_VFORKP;
1007 	sp->pr_flags = flags;
1008 	if (VSTOPPED(t)) {
1009 		sp->pr_why   = PR_REQUESTED;
1010 		sp->pr_what  = 0;
1011 	} else {
1012 		sp->pr_why   = t->t_whystop;
1013 		sp->pr_what  = t->t_whatstop;
1014 	}
1015 	sp->pr_lwpid = t->t_tid;
1016 	sp->pr_cursig  = lwp->lwp_cursig;
1017 	prassignset(&sp->pr_lwppend, &t->t_sig);
1018 	prgethold(t, &sp->pr_lwphold);
1019 	if (t->t_whystop == PR_FAULTED) {
1020 		siginfo_kto32(&lwp->lwp_siginfo, &sp->pr_info);
1021 		if (t->t_whatstop == FLTPAGE)
1022 			sp->pr_info.si_addr =
1023 			    (caddr32_t)(uintptr_t)lwp->lwp_siginfo.si_addr;
1024 	} else if (lwp->lwp_curinfo)
1025 		siginfo_kto32(&lwp->lwp_curinfo->sq_info, &sp->pr_info);
1026 	if (SI_FROMUSER(&lwp->lwp_siginfo) && zp->zone_id != GLOBAL_ZONEID &&
1027 	    sp->pr_info.si_zoneid != zp->zone_id) {
1028 		sp->pr_info.si_pid = zp->zone_zsched->p_pid;
1029 		sp->pr_info.si_uid = 0;
1030 		sp->pr_info.si_ctid = -1;
1031 		sp->pr_info.si_zoneid = zp->zone_id;
1032 	}
1033 	sp->pr_altstack.ss_sp =
1034 	    (caddr32_t)(uintptr_t)lwp->lwp_sigaltstack.ss_sp;
1035 	sp->pr_altstack.ss_size = (size32_t)lwp->lwp_sigaltstack.ss_size;
1036 	sp->pr_altstack.ss_flags = (int32_t)lwp->lwp_sigaltstack.ss_flags;
1037 	prgetaction32(p, PTOU(p), lwp->lwp_cursig, &sp->pr_action);
1038 	sp->pr_oldcontext = (caddr32_t)lwp->lwp_oldcontext;
1039 	sp->pr_ustack = (caddr32_t)lwp->lwp_ustack;
1040 	(void) strncpy(sp->pr_clname, sclass[t->t_cid].cl_name,
1041 	    sizeof (sp->pr_clname) - 1);
1042 	if (flags & PR_STOPPED)
1043 		hrt2ts32(t->t_stoptime, &sp->pr_tstamp);
1044 	usr = ms->ms_acct[LMS_USER];
1045 	sys = ms->ms_acct[LMS_SYSTEM] + ms->ms_acct[LMS_TRAP];
1046 	scalehrtime(&usr);
1047 	scalehrtime(&sys);
1048 	hrt2ts32(usr, &sp->pr_utime);
1049 	hrt2ts32(sys, &sp->pr_stime);
1050 
1051 	/*
1052 	 * Fetch the current instruction, if not a system process.
1053 	 * We don't attempt this unless the lwp is stopped.
1054 	 */
1055 	if ((p->p_flag & SSYS) || p->p_as == &kas)
1056 		sp->pr_flags |= (PR_ISSYS|PR_PCINVAL);
1057 	else if (!(flags & PR_STOPPED))
1058 		sp->pr_flags |= PR_PCINVAL;
1059 	else if (!prfetchinstr(lwp, &instr))
1060 		sp->pr_flags |= PR_PCINVAL;
1061 	else
1062 		sp->pr_instr = (uint32_t)instr;
1063 
1064 	/*
1065 	 * Drop p_lock while touching the lwp's stack.
1066 	 */
1067 	mutex_exit(&p->p_lock);
1068 	if (prisstep(lwp))
1069 		sp->pr_flags |= PR_STEP;
1070 	if ((flags & (PR_STOPPED|PR_ASLEEP)) && t->t_sysnum) {
1071 		int i;
1072 
1073 		sp->pr_syscall = get_syscall32_args(lwp,
1074 		    (int *)sp->pr_sysarg, &i);
1075 		sp->pr_nsysarg = (ushort_t)i;
1076 	}
1077 	if ((flags & PR_STOPPED) || t == curthread)
1078 		prgetprregs32(lwp, sp->pr_reg);
1079 	if ((t->t_state == TS_STOPPED && t->t_whystop == PR_SYSEXIT) ||
1080 	    (flags & PR_VFORKP)) {
1081 		long r1, r2;
1082 		user_t *up;
1083 		auxv_t *auxp;
1084 		int i;
1085 
1086 		sp->pr_errno = prgetrvals(lwp, &r1, &r2);
1087 		if (sp->pr_errno == 0) {
1088 			sp->pr_rval1 = (int32_t)r1;
1089 			sp->pr_rval2 = (int32_t)r2;
1090 			sp->pr_errpriv = PRIV_NONE;
1091 		} else
1092 			sp->pr_errpriv = lwp->lwp_badpriv;
1093 
1094 		if (t->t_sysnum == SYS_execve) {
1095 			up = PTOU(p);
1096 			sp->pr_sysarg[0] = 0;
1097 			sp->pr_sysarg[1] = (caddr32_t)up->u_argv;
1098 			sp->pr_sysarg[2] = (caddr32_t)up->u_envp;
1099 			for (i = 0, auxp = up->u_auxv;
1100 			    i < sizeof (up->u_auxv) / sizeof (up->u_auxv[0]);
1101 			    i++, auxp++) {
1102 				if (auxp->a_type == AT_SUN_EXECNAME) {
1103 					sp->pr_sysarg[0] =
1104 					    (caddr32_t)
1105 					    (uintptr_t)auxp->a_un.a_ptr;
1106 					break;
1107 				}
1108 			}
1109 		}
1110 	}
1111 	if (prhasfp())
1112 		prgetprfpregs32(lwp, &sp->pr_fpreg);
1113 	mutex_enter(&p->p_lock);
1114 }
1115 
1116 void
1117 prgetstatus32(proc_t *p, pstatus32_t *sp, zone_t *zp)
1118 {
1119 	kthread_t *t;
1120 
1121 	ASSERT(MUTEX_HELD(&p->p_lock));
1122 
1123 	t = prchoose(p);	/* returns locked thread */
1124 	ASSERT(t != NULL);
1125 	thread_unlock(t);
1126 
1127 	/* just bzero the process part, prgetlwpstatus32() does the rest */
1128 	bzero(sp, sizeof (pstatus32_t) - sizeof (lwpstatus32_t));
1129 	sp->pr_nlwp = p->p_lwpcnt;
1130 	sp->pr_nzomb = p->p_zombcnt;
1131 	prassignset(&sp->pr_sigpend, &p->p_sig);
1132 	sp->pr_brkbase = (uint32_t)(uintptr_t)p->p_brkbase;
1133 	sp->pr_brksize = (uint32_t)p->p_brksize;
1134 	sp->pr_stkbase = (uint32_t)(uintptr_t)prgetstackbase(p);
1135 	sp->pr_stksize = (uint32_t)p->p_stksize;
1136 	sp->pr_pid   = p->p_pid;
1137 	if (curproc->p_zone->zone_id != GLOBAL_ZONEID &&
1138 	    (p->p_flag & SZONETOP)) {
1139 		ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID);
1140 		/*
1141 		 * Inside local zones, fake zsched's pid as parent pids for
1142 		 * processes which reference processes outside of the zone.
1143 		 */
1144 		sp->pr_ppid = curproc->p_zone->zone_zsched->p_pid;
1145 	} else {
1146 		sp->pr_ppid = p->p_ppid;
1147 	}
1148 	sp->pr_pgid  = p->p_pgrp;
1149 	sp->pr_sid   = p->p_sessp->s_sid;
1150 	sp->pr_taskid = p->p_task->tk_tkid;
1151 	sp->pr_projid = p->p_task->tk_proj->kpj_id;
1152 	sp->pr_zoneid = p->p_zone->zone_id;
1153 	hrt2ts32(mstate_aggr_state(p, LMS_USER), &sp->pr_utime);
1154 	hrt2ts32(mstate_aggr_state(p, LMS_SYSTEM), &sp->pr_stime);
1155 	TICK_TO_TIMESTRUC32(p->p_cutime, &sp->pr_cutime);
1156 	TICK_TO_TIMESTRUC32(p->p_cstime, &sp->pr_cstime);
1157 	prassignset(&sp->pr_sigtrace, &p->p_sigmask);
1158 	prassignset(&sp->pr_flttrace, &p->p_fltmask);
1159 	prassignset(&sp->pr_sysentry, &PTOU(p)->u_entrymask);
1160 	prassignset(&sp->pr_sysexit, &PTOU(p)->u_exitmask);
1161 	switch (p->p_model) {
1162 	case DATAMODEL_ILP32:
1163 		sp->pr_dmodel = PR_MODEL_ILP32;
1164 		break;
1165 	case DATAMODEL_LP64:
1166 		sp->pr_dmodel = PR_MODEL_LP64;
1167 		break;
1168 	}
1169 	if (p->p_agenttp)
1170 		sp->pr_agentid = p->p_agenttp->t_tid;
1171 
1172 	/* get the chosen lwp's status */
1173 	prgetlwpstatus32(t, &sp->pr_lwp, zp);
1174 
1175 	/* replicate the flags */
1176 	sp->pr_flags = sp->pr_lwp.pr_flags;
1177 }
1178 #endif	/* _SYSCALL32_IMPL */
1179 
1180 /*
1181  * Return lwp status.
1182  */
1183 void
1184 prgetlwpstatus(kthread_t *t, lwpstatus_t *sp, zone_t *zp)
1185 {
1186 	proc_t *p = ttoproc(t);
1187 	klwp_t *lwp = ttolwp(t);
1188 	struct mstate *ms = &lwp->lwp_mstate;
1189 	hrtime_t usr, sys;
1190 	int flags;
1191 	ulong_t instr;
1192 
1193 	ASSERT(MUTEX_HELD(&p->p_lock));
1194 
1195 	bzero(sp, sizeof (*sp));
1196 	flags = 0L;
1197 	if (t->t_state == TS_STOPPED) {
1198 		flags |= PR_STOPPED;
1199 		if ((t->t_schedflag & TS_PSTART) == 0)
1200 			flags |= PR_ISTOP;
1201 	} else if (VSTOPPED(t)) {
1202 		flags |= PR_STOPPED|PR_ISTOP;
1203 	}
1204 	if (!(flags & PR_ISTOP) && (t->t_proc_flag & TP_PRSTOP))
1205 		flags |= PR_DSTOP;
1206 	if (lwp->lwp_asleep)
1207 		flags |= PR_ASLEEP;
1208 	if (t == p->p_agenttp)
1209 		flags |= PR_AGENT;
1210 	if (!(t->t_proc_flag & TP_TWAIT))
1211 		flags |= PR_DETACH;
1212 	if (t->t_proc_flag & TP_DAEMON)
1213 		flags |= PR_DAEMON;
1214 	if (p->p_proc_flag & P_PR_FORK)
1215 		flags |= PR_FORK;
1216 	if (p->p_proc_flag & P_PR_RUNLCL)
1217 		flags |= PR_RLC;
1218 	if (p->p_proc_flag & P_PR_KILLCL)
1219 		flags |= PR_KLC;
1220 	if (p->p_proc_flag & P_PR_ASYNC)
1221 		flags |= PR_ASYNC;
1222 	if (p->p_proc_flag & P_PR_BPTADJ)
1223 		flags |= PR_BPTADJ;
1224 	if (p->p_proc_flag & P_PR_PTRACE)
1225 		flags |= PR_PTRACE;
1226 	if (p->p_flag & SMSACCT)
1227 		flags |= PR_MSACCT;
1228 	if (p->p_flag & SMSFORK)
1229 		flags |= PR_MSFORK;
1230 	if (p->p_flag & SVFWAIT)
1231 		flags |= PR_VFORKP;
1232 	if (p->p_pgidp->pid_pgorphaned)
1233 		flags |= PR_ORPHAN;
1234 	if (p->p_pidflag & CLDNOSIGCHLD)
1235 		flags |= PR_NOSIGCHLD;
1236 	if (p->p_pidflag & CLDWAITPID)
1237 		flags |= PR_WAITPID;
1238 	sp->pr_flags = flags;
1239 	if (VSTOPPED(t)) {
1240 		sp->pr_why   = PR_REQUESTED;
1241 		sp->pr_what  = 0;
1242 	} else {
1243 		sp->pr_why   = t->t_whystop;
1244 		sp->pr_what  = t->t_whatstop;
1245 	}
1246 	sp->pr_lwpid = t->t_tid;
1247 	sp->pr_cursig  = lwp->lwp_cursig;
1248 	prassignset(&sp->pr_lwppend, &t->t_sig);
1249 	prgethold(t, &sp->pr_lwphold);
1250 	if (t->t_whystop == PR_FAULTED)
1251 		bcopy(&lwp->lwp_siginfo,
1252 		    &sp->pr_info, sizeof (k_siginfo_t));
1253 	else if (lwp->lwp_curinfo)
1254 		bcopy(&lwp->lwp_curinfo->sq_info,
1255 		    &sp->pr_info, sizeof (k_siginfo_t));
1256 	if (SI_FROMUSER(&lwp->lwp_siginfo) && zp->zone_id != GLOBAL_ZONEID &&
1257 	    sp->pr_info.si_zoneid != zp->zone_id) {
1258 		sp->pr_info.si_pid = zp->zone_zsched->p_pid;
1259 		sp->pr_info.si_uid = 0;
1260 		sp->pr_info.si_ctid = -1;
1261 		sp->pr_info.si_zoneid = zp->zone_id;
1262 	}
1263 	sp->pr_altstack = lwp->lwp_sigaltstack;
1264 	prgetaction(p, PTOU(p), lwp->lwp_cursig, &sp->pr_action);
1265 	sp->pr_oldcontext = (uintptr_t)lwp->lwp_oldcontext;
1266 	sp->pr_ustack = lwp->lwp_ustack;
1267 	(void) strncpy(sp->pr_clname, sclass[t->t_cid].cl_name,
1268 	    sizeof (sp->pr_clname) - 1);
1269 	if (flags & PR_STOPPED)
1270 		hrt2ts(t->t_stoptime, &sp->pr_tstamp);
1271 	usr = ms->ms_acct[LMS_USER];
1272 	sys = ms->ms_acct[LMS_SYSTEM] + ms->ms_acct[LMS_TRAP];
1273 	scalehrtime(&usr);
1274 	scalehrtime(&sys);
1275 	hrt2ts(usr, &sp->pr_utime);
1276 	hrt2ts(sys, &sp->pr_stime);
1277 
1278 	/*
1279 	 * Fetch the current instruction, if not a system process.
1280 	 * We don't attempt this unless the lwp is stopped.
1281 	 */
1282 	if ((p->p_flag & SSYS) || p->p_as == &kas)
1283 		sp->pr_flags |= (PR_ISSYS|PR_PCINVAL);
1284 	else if (!(flags & PR_STOPPED))
1285 		sp->pr_flags |= PR_PCINVAL;
1286 	else if (!prfetchinstr(lwp, &instr))
1287 		sp->pr_flags |= PR_PCINVAL;
1288 	else
1289 		sp->pr_instr = instr;
1290 
1291 	/*
1292 	 * Drop p_lock while touching the lwp's stack.
1293 	 */
1294 	mutex_exit(&p->p_lock);
1295 	if (prisstep(lwp))
1296 		sp->pr_flags |= PR_STEP;
1297 	if ((flags & (PR_STOPPED|PR_ASLEEP)) && t->t_sysnum) {
1298 		int i;
1299 
1300 		sp->pr_syscall = get_syscall_args(lwp,
1301 		    (long *)sp->pr_sysarg, &i);
1302 		sp->pr_nsysarg = (ushort_t)i;
1303 	}
1304 	if ((flags & PR_STOPPED) || t == curthread)
1305 		prgetprregs(lwp, sp->pr_reg);
1306 	if ((t->t_state == TS_STOPPED && t->t_whystop == PR_SYSEXIT) ||
1307 	    (flags & PR_VFORKP)) {
1308 		user_t *up;
1309 		auxv_t *auxp;
1310 		int i;
1311 
1312 		sp->pr_errno = prgetrvals(lwp, &sp->pr_rval1, &sp->pr_rval2);
1313 		if (sp->pr_errno == 0)
1314 			sp->pr_errpriv = PRIV_NONE;
1315 		else
1316 			sp->pr_errpriv = lwp->lwp_badpriv;
1317 
1318 		if (t->t_sysnum == SYS_execve) {
1319 			up = PTOU(p);
1320 			sp->pr_sysarg[0] = 0;
1321 			sp->pr_sysarg[1] = (uintptr_t)up->u_argv;
1322 			sp->pr_sysarg[2] = (uintptr_t)up->u_envp;
1323 			for (i = 0, auxp = up->u_auxv;
1324 			    i < sizeof (up->u_auxv) / sizeof (up->u_auxv[0]);
1325 			    i++, auxp++) {
1326 				if (auxp->a_type == AT_SUN_EXECNAME) {
1327 					sp->pr_sysarg[0] =
1328 					    (uintptr_t)auxp->a_un.a_ptr;
1329 					break;
1330 				}
1331 			}
1332 		}
1333 	}
1334 	if (prhasfp())
1335 		prgetprfpregs(lwp, &sp->pr_fpreg);
1336 	mutex_enter(&p->p_lock);
1337 }
1338 
1339 /*
1340  * Get the sigaction structure for the specified signal.  The u-block
1341  * must already have been mapped in by the caller.
1342  */
1343 void
1344 prgetaction(proc_t *p, user_t *up, uint_t sig, struct sigaction *sp)
1345 {
1346 	int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
1347 
1348 	bzero(sp, sizeof (*sp));
1349 
1350 	if (sig != 0 && (unsigned)sig < nsig) {
1351 		sp->sa_handler = up->u_signal[sig-1];
1352 		prassignset(&sp->sa_mask, &up->u_sigmask[sig-1]);
1353 		if (sigismember(&up->u_sigonstack, sig))
1354 			sp->sa_flags |= SA_ONSTACK;
1355 		if (sigismember(&up->u_sigresethand, sig))
1356 			sp->sa_flags |= SA_RESETHAND;
1357 		if (sigismember(&up->u_sigrestart, sig))
1358 			sp->sa_flags |= SA_RESTART;
1359 		if (sigismember(&p->p_siginfo, sig))
1360 			sp->sa_flags |= SA_SIGINFO;
1361 		if (sigismember(&up->u_signodefer, sig))
1362 			sp->sa_flags |= SA_NODEFER;
1363 		if (sig == SIGCLD) {
1364 			if (p->p_flag & SNOWAIT)
1365 				sp->sa_flags |= SA_NOCLDWAIT;
1366 			if ((p->p_flag & SJCTL) == 0)
1367 				sp->sa_flags |= SA_NOCLDSTOP;
1368 		}
1369 	}
1370 }
1371 
1372 #ifdef _SYSCALL32_IMPL
1373 void
1374 prgetaction32(proc_t *p, user_t *up, uint_t sig, struct sigaction32 *sp)
1375 {
1376 	int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
1377 
1378 	bzero(sp, sizeof (*sp));
1379 
1380 	if (sig != 0 && (unsigned)sig < nsig) {
1381 		sp->sa_handler = (caddr32_t)(uintptr_t)up->u_signal[sig-1];
1382 		prassignset(&sp->sa_mask, &up->u_sigmask[sig-1]);
1383 		if (sigismember(&up->u_sigonstack, sig))
1384 			sp->sa_flags |= SA_ONSTACK;
1385 		if (sigismember(&up->u_sigresethand, sig))
1386 			sp->sa_flags |= SA_RESETHAND;
1387 		if (sigismember(&up->u_sigrestart, sig))
1388 			sp->sa_flags |= SA_RESTART;
1389 		if (sigismember(&p->p_siginfo, sig))
1390 			sp->sa_flags |= SA_SIGINFO;
1391 		if (sigismember(&up->u_signodefer, sig))
1392 			sp->sa_flags |= SA_NODEFER;
1393 		if (sig == SIGCLD) {
1394 			if (p->p_flag & SNOWAIT)
1395 				sp->sa_flags |= SA_NOCLDWAIT;
1396 			if ((p->p_flag & SJCTL) == 0)
1397 				sp->sa_flags |= SA_NOCLDSTOP;
1398 		}
1399 	}
1400 }
1401 #endif	/* _SYSCALL32_IMPL */
1402 
1403 /*
1404  * Count the number of segments in this process's address space.
1405  */
1406 int
1407 prnsegs(struct as *as, int reserved)
1408 {
1409 	int n = 0;
1410 	struct seg *seg;
1411 
1412 	ASSERT(as != &kas && AS_WRITE_HELD(as));
1413 
1414 	for (seg = AS_SEGFIRST(as); seg != NULL; seg = AS_SEGNEXT(as, seg)) {
1415 		caddr_t eaddr = seg->s_base + pr_getsegsize(seg, reserved);
1416 		caddr_t saddr, naddr;
1417 		void *tmp = NULL;
1418 
1419 		if ((seg->s_flags & S_HOLE) != 0) {
1420 			continue;
1421 		}
1422 
1423 		for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
1424 			(void) pr_getprot(seg, reserved, &tmp,
1425 			    &saddr, &naddr, eaddr);
1426 			if (saddr != naddr)
1427 				n++;
1428 		}
1429 
1430 		ASSERT(tmp == NULL);
1431 	}
1432 
1433 	return (n);
1434 }
1435 
1436 /*
1437  * Convert uint32_t to decimal string w/o leading zeros.
1438  * Add trailing null characters if 'len' is greater than string length.
1439  * Return the string length.
1440  */
1441 int
1442 pr_u32tos(uint32_t n, char *s, int len)
1443 {
1444 	char cbuf[11];		/* 32-bit unsigned integer fits in 10 digits */
1445 	char *cp = cbuf;
1446 	char *end = s + len;
1447 
1448 	do {
1449 		*cp++ = (char)(n % 10 + '0');
1450 		n /= 10;
1451 	} while (n);
1452 
1453 	len = (int)(cp - cbuf);
1454 
1455 	do {
1456 		*s++ = *--cp;
1457 	} while (cp > cbuf);
1458 
1459 	while (s < end)		/* optional pad */
1460 		*s++ = '\0';
1461 
1462 	return (len);
1463 }
1464 
1465 /*
1466  * Convert uint64_t to decimal string w/o leading zeros.
1467  * Return the string length.
1468  */
1469 static int
1470 pr_u64tos(uint64_t n, char *s)
1471 {
1472 	char cbuf[21];		/* 64-bit unsigned integer fits in 20 digits */
1473 	char *cp = cbuf;
1474 	int len;
1475 
1476 	do {
1477 		*cp++ = (char)(n % 10 + '0');
1478 		n /= 10;
1479 	} while (n);
1480 
1481 	len = (int)(cp - cbuf);
1482 
1483 	do {
1484 		*s++ = *--cp;
1485 	} while (cp > cbuf);
1486 
1487 	return (len);
1488 }
1489 
1490 file_t *
1491 pr_getf(proc_t *p, uint_t fd, short *flag)
1492 {
1493 	uf_entry_t *ufp;
1494 	uf_info_t *fip;
1495 	file_t *fp;
1496 
1497 	ASSERT(MUTEX_HELD(&p->p_lock) && (p->p_proc_flag & P_PR_LOCK));
1498 
1499 	fip = P_FINFO(p);
1500 
1501 	if (fd >= fip->fi_nfiles)
1502 		return (NULL);
1503 
1504 	mutex_exit(&p->p_lock);
1505 	mutex_enter(&fip->fi_lock);
1506 	UF_ENTER(ufp, fip, fd);
1507 	if ((fp = ufp->uf_file) != NULL && fp->f_count > 0) {
1508 		if (flag != NULL)
1509 			*flag = ufp->uf_flag;
1510 		ufp->uf_refcnt++;
1511 	} else {
1512 		fp = NULL;
1513 	}
1514 	UF_EXIT(ufp);
1515 	mutex_exit(&fip->fi_lock);
1516 	mutex_enter(&p->p_lock);
1517 
1518 	return (fp);
1519 }
1520 
1521 void
1522 pr_releasef(proc_t *p, uint_t fd)
1523 {
1524 	uf_entry_t *ufp;
1525 	uf_info_t *fip;
1526 
1527 	ASSERT(MUTEX_HELD(&p->p_lock) && (p->p_proc_flag & P_PR_LOCK));
1528 
1529 	fip = P_FINFO(p);
1530 
1531 	mutex_exit(&p->p_lock);
1532 	mutex_enter(&fip->fi_lock);
1533 	UF_ENTER(ufp, fip, fd);
1534 	ASSERT3U(ufp->uf_refcnt, >, 0);
1535 	ufp->uf_refcnt--;
1536 	UF_EXIT(ufp);
1537 	mutex_exit(&fip->fi_lock);
1538 	mutex_enter(&p->p_lock);
1539 }
1540 
1541 void
1542 pr_object_name(char *name, vnode_t *vp, struct vattr *vattr)
1543 {
1544 	char *s = name;
1545 	struct vfs *vfsp;
1546 	struct vfssw *vfsswp;
1547 
1548 	if ((vfsp = vp->v_vfsp) != NULL &&
1549 	    ((vfsswp = vfssw + vfsp->vfs_fstype), vfsswp->vsw_name) &&
1550 	    *vfsswp->vsw_name) {
1551 		(void) strcpy(s, vfsswp->vsw_name);
1552 		s += strlen(s);
1553 		*s++ = '.';
1554 	}
1555 	s += pr_u32tos(getmajor(vattr->va_fsid), s, 0);
1556 	*s++ = '.';
1557 	s += pr_u32tos(getminor(vattr->va_fsid), s, 0);
1558 	*s++ = '.';
1559 	s += pr_u64tos(vattr->va_nodeid, s);
1560 	*s++ = '\0';
1561 }
1562 
1563 struct seg *
1564 break_seg(proc_t *p)
1565 {
1566 	caddr_t addr = p->p_brkbase;
1567 	struct seg *seg;
1568 	struct vnode *vp;
1569 
1570 	if (p->p_brksize != 0)
1571 		addr += p->p_brksize - 1;
1572 	seg = as_segat(p->p_as, addr);
1573 	if (seg != NULL && seg->s_ops == &segvn_ops &&
1574 	    (SEGOP_GETVP(seg, seg->s_base, &vp) != 0 || vp == NULL))
1575 		return (seg);
1576 	return (NULL);
1577 }
1578 
1579 /*
1580  * Implementation of service functions to handle procfs generic chained
1581  * copyout buffers.
1582  */
1583 typedef struct pr_iobuf_list {
1584 	list_node_t	piol_link;	/* buffer linkage */
1585 	size_t		piol_size;	/* total size (header + data) */
1586 	size_t		piol_usedsize;	/* amount to copy out from this buf */
1587 } piol_t;
1588 
1589 #define	MAPSIZE	(64 * 1024)
1590 #define	PIOL_DATABUF(iol)	((void *)(&(iol)[1]))
1591 
1592 void
1593 pr_iol_initlist(list_t *iolhead, size_t itemsize, int n)
1594 {
1595 	piol_t	*iol;
1596 	size_t	initial_size = MIN(1, n) * itemsize;
1597 
1598 	list_create(iolhead, sizeof (piol_t), offsetof(piol_t, piol_link));
1599 
1600 	ASSERT(list_head(iolhead) == NULL);
1601 	ASSERT(itemsize < MAPSIZE - sizeof (*iol));
1602 	ASSERT(initial_size > 0);
1603 
1604 	/*
1605 	 * Someone creating chained copyout buffers may ask for less than
1606 	 * MAPSIZE if the amount of data to be buffered is known to be
1607 	 * smaller than that.
1608 	 * But in order to prevent involuntary self-denial of service,
1609 	 * the requested input size is clamped at MAPSIZE.
1610 	 */
1611 	initial_size = MIN(MAPSIZE, initial_size + sizeof (*iol));
1612 	iol = kmem_alloc(initial_size, KM_SLEEP);
1613 	list_insert_head(iolhead, iol);
1614 	iol->piol_usedsize = 0;
1615 	iol->piol_size = initial_size;
1616 }
1617 
1618 void *
1619 pr_iol_newbuf(list_t *iolhead, size_t itemsize)
1620 {
1621 	piol_t	*iol;
1622 	char	*new;
1623 
1624 	ASSERT(itemsize < MAPSIZE - sizeof (*iol));
1625 	ASSERT(list_head(iolhead) != NULL);
1626 
1627 	iol = (piol_t *)list_tail(iolhead);
1628 
1629 	if (iol->piol_size <
1630 	    iol->piol_usedsize + sizeof (*iol) + itemsize) {
1631 		/*
1632 		 * Out of space in the current buffer. Allocate more.
1633 		 */
1634 		piol_t *newiol;
1635 
1636 		newiol = kmem_alloc(MAPSIZE, KM_SLEEP);
1637 		newiol->piol_size = MAPSIZE;
1638 		newiol->piol_usedsize = 0;
1639 
1640 		list_insert_after(iolhead, iol, newiol);
1641 		iol = list_next(iolhead, iol);
1642 		ASSERT(iol == newiol);
1643 	}
1644 	new = (char *)PIOL_DATABUF(iol) + iol->piol_usedsize;
1645 	iol->piol_usedsize += itemsize;
1646 	bzero(new, itemsize);
1647 	return (new);
1648 }
1649 
1650 void
1651 pr_iol_freelist(list_t *iolhead)
1652 {
1653 	piol_t	*iol;
1654 
1655 	while ((iol = list_head(iolhead)) != NULL) {
1656 		list_remove(iolhead, iol);
1657 		kmem_free(iol, iol->piol_size);
1658 	}
1659 	list_destroy(iolhead);
1660 }
1661 
1662 int
1663 pr_iol_copyout_and_free(list_t *iolhead, caddr_t *tgt, int errin)
1664 {
1665 	int error = errin;
1666 	piol_t	*iol;
1667 
1668 	while ((iol = list_head(iolhead)) != NULL) {
1669 		list_remove(iolhead, iol);
1670 		if (!error) {
1671 			if (copyout(PIOL_DATABUF(iol), *tgt,
1672 			    iol->piol_usedsize))
1673 				error = EFAULT;
1674 			*tgt += iol->piol_usedsize;
1675 		}
1676 		kmem_free(iol, iol->piol_size);
1677 	}
1678 	list_destroy(iolhead);
1679 
1680 	return (error);
1681 }
1682 
1683 int
1684 pr_iol_uiomove_and_free(list_t *iolhead, uio_t *uiop, int errin)
1685 {
1686 	offset_t	off = uiop->uio_offset;
1687 	char		*base;
1688 	size_t		size;
1689 	piol_t		*iol;
1690 	int		error = errin;
1691 
1692 	while ((iol = list_head(iolhead)) != NULL) {
1693 		list_remove(iolhead, iol);
1694 		base = PIOL_DATABUF(iol);
1695 		size = iol->piol_usedsize;
1696 		if (off <= size && error == 0 && uiop->uio_resid > 0)
1697 			error = uiomove(base + off, size - off,
1698 			    UIO_READ, uiop);
1699 		off = MAX(0, off - (offset_t)size);
1700 		kmem_free(iol, iol->piol_size);
1701 	}
1702 	list_destroy(iolhead);
1703 
1704 	return (error);
1705 }
1706 
1707 /*
1708  * Return an array of structures with memory map information.
1709  * We allocate here; the caller must deallocate.
1710  */
1711 int
1712 prgetmap(proc_t *p, int reserved, list_t *iolhead)
1713 {
1714 	struct as *as = p->p_as;
1715 	prmap_t *mp;
1716 	struct seg *seg;
1717 	struct seg *brkseg, *stkseg;
1718 	struct vnode *vp;
1719 	struct vattr vattr;
1720 	uint_t prot;
1721 
1722 	ASSERT(as != &kas && AS_WRITE_HELD(as));
1723 
1724 	/*
1725 	 * Request an initial buffer size that doesn't waste memory
1726 	 * if the address space has only a small number of segments.
1727 	 */
1728 	pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree));
1729 
1730 	if ((seg = AS_SEGFIRST(as)) == NULL)
1731 		return (0);
1732 
1733 	brkseg = break_seg(p);
1734 	stkseg = as_segat(as, prgetstackbase(p));
1735 
1736 	do {
1737 		caddr_t eaddr = seg->s_base + pr_getsegsize(seg, reserved);
1738 		caddr_t saddr, naddr;
1739 		void *tmp = NULL;
1740 
1741 		if ((seg->s_flags & S_HOLE) != 0) {
1742 			continue;
1743 		}
1744 
1745 		for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
1746 			prot = pr_getprot(seg, reserved, &tmp,
1747 			    &saddr, &naddr, eaddr);
1748 			if (saddr == naddr)
1749 				continue;
1750 
1751 			mp = pr_iol_newbuf(iolhead, sizeof (*mp));
1752 
1753 			mp->pr_vaddr = (uintptr_t)saddr;
1754 			mp->pr_size = naddr - saddr;
1755 			mp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
1756 			mp->pr_mflags = 0;
1757 			if (prot & PROT_READ)
1758 				mp->pr_mflags |= MA_READ;
1759 			if (prot & PROT_WRITE)
1760 				mp->pr_mflags |= MA_WRITE;
1761 			if (prot & PROT_EXEC)
1762 				mp->pr_mflags |= MA_EXEC;
1763 			if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
1764 				mp->pr_mflags |= MA_SHARED;
1765 			if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
1766 				mp->pr_mflags |= MA_NORESERVE;
1767 			if (seg->s_ops == &segspt_shmops ||
1768 			    (seg->s_ops == &segvn_ops &&
1769 			    (SEGOP_GETVP(seg, saddr, &vp) != 0 || vp == NULL)))
1770 				mp->pr_mflags |= MA_ANON;
1771 			if (seg == brkseg)
1772 				mp->pr_mflags |= MA_BREAK;
1773 			else if (seg == stkseg) {
1774 				mp->pr_mflags |= MA_STACK;
1775 				if (reserved) {
1776 					size_t maxstack =
1777 					    ((size_t)p->p_stk_ctl +
1778 					    PAGEOFFSET) & PAGEMASK;
1779 					mp->pr_vaddr =
1780 					    (uintptr_t)prgetstackbase(p) +
1781 					    p->p_stksize - maxstack;
1782 					mp->pr_size = (uintptr_t)naddr -
1783 					    mp->pr_vaddr;
1784 				}
1785 			}
1786 			if (seg->s_ops == &segspt_shmops)
1787 				mp->pr_mflags |= MA_ISM | MA_SHM;
1788 			mp->pr_pagesize = PAGESIZE;
1789 
1790 			/*
1791 			 * Manufacture a filename for the "object" directory.
1792 			 */
1793 			vattr.va_mask = AT_FSID|AT_NODEID;
1794 			if (seg->s_ops == &segvn_ops &&
1795 			    SEGOP_GETVP(seg, saddr, &vp) == 0 &&
1796 			    vp != NULL && vp->v_type == VREG &&
1797 			    VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
1798 				if (vp == p->p_exec)
1799 					(void) strcpy(mp->pr_mapname, "a.out");
1800 				else
1801 					pr_object_name(mp->pr_mapname,
1802 					    vp, &vattr);
1803 			}
1804 
1805 			/*
1806 			 * Get the SysV shared memory id, if any.
1807 			 */
1808 			if ((mp->pr_mflags & MA_SHARED) && p->p_segacct &&
1809 			    (mp->pr_shmid = shmgetid(p, seg->s_base)) !=
1810 			    SHMID_NONE) {
1811 				if (mp->pr_shmid == SHMID_FREE)
1812 					mp->pr_shmid = -1;
1813 
1814 				mp->pr_mflags |= MA_SHM;
1815 			} else {
1816 				mp->pr_shmid = -1;
1817 			}
1818 		}
1819 		ASSERT(tmp == NULL);
1820 	} while ((seg = AS_SEGNEXT(as, seg)) != NULL);
1821 
1822 	return (0);
1823 }
1824 
1825 #ifdef _SYSCALL32_IMPL
1826 int
1827 prgetmap32(proc_t *p, int reserved, list_t *iolhead)
1828 {
1829 	struct as *as = p->p_as;
1830 	prmap32_t *mp;
1831 	struct seg *seg;
1832 	struct seg *brkseg, *stkseg;
1833 	struct vnode *vp;
1834 	struct vattr vattr;
1835 	uint_t prot;
1836 
1837 	ASSERT(as != &kas && AS_WRITE_HELD(as));
1838 
1839 	/*
1840 	 * Request an initial buffer size that doesn't waste memory
1841 	 * if the address space has only a small number of segments.
1842 	 */
1843 	pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree));
1844 
1845 	if ((seg = AS_SEGFIRST(as)) == NULL)
1846 		return (0);
1847 
1848 	brkseg = break_seg(p);
1849 	stkseg = as_segat(as, prgetstackbase(p));
1850 
1851 	do {
1852 		caddr_t eaddr = seg->s_base + pr_getsegsize(seg, reserved);
1853 		caddr_t saddr, naddr;
1854 		void *tmp = NULL;
1855 
1856 		if ((seg->s_flags & S_HOLE) != 0) {
1857 			continue;
1858 		}
1859 
1860 		for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
1861 			prot = pr_getprot(seg, reserved, &tmp,
1862 			    &saddr, &naddr, eaddr);
1863 			if (saddr == naddr)
1864 				continue;
1865 
1866 			mp = pr_iol_newbuf(iolhead, sizeof (*mp));
1867 
1868 			mp->pr_vaddr = (caddr32_t)(uintptr_t)saddr;
1869 			mp->pr_size = (size32_t)(naddr - saddr);
1870 			mp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
1871 			mp->pr_mflags = 0;
1872 			if (prot & PROT_READ)
1873 				mp->pr_mflags |= MA_READ;
1874 			if (prot & PROT_WRITE)
1875 				mp->pr_mflags |= MA_WRITE;
1876 			if (prot & PROT_EXEC)
1877 				mp->pr_mflags |= MA_EXEC;
1878 			if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
1879 				mp->pr_mflags |= MA_SHARED;
1880 			if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
1881 				mp->pr_mflags |= MA_NORESERVE;
1882 			if (seg->s_ops == &segspt_shmops ||
1883 			    (seg->s_ops == &segvn_ops &&
1884 			    (SEGOP_GETVP(seg, saddr, &vp) != 0 || vp == NULL)))
1885 				mp->pr_mflags |= MA_ANON;
1886 			if (seg == brkseg)
1887 				mp->pr_mflags |= MA_BREAK;
1888 			else if (seg == stkseg) {
1889 				mp->pr_mflags |= MA_STACK;
1890 				if (reserved) {
1891 					size_t maxstack =
1892 					    ((size_t)p->p_stk_ctl +
1893 					    PAGEOFFSET) & PAGEMASK;
1894 					uintptr_t vaddr =
1895 					    (uintptr_t)prgetstackbase(p) +
1896 					    p->p_stksize - maxstack;
1897 					mp->pr_vaddr = (caddr32_t)vaddr;
1898 					mp->pr_size = (size32_t)
1899 					    ((uintptr_t)naddr - vaddr);
1900 				}
1901 			}
1902 			if (seg->s_ops == &segspt_shmops)
1903 				mp->pr_mflags |= MA_ISM | MA_SHM;
1904 			mp->pr_pagesize = PAGESIZE;
1905 
1906 			/*
1907 			 * Manufacture a filename for the "object" directory.
1908 			 */
1909 			vattr.va_mask = AT_FSID|AT_NODEID;
1910 			if (seg->s_ops == &segvn_ops &&
1911 			    SEGOP_GETVP(seg, saddr, &vp) == 0 &&
1912 			    vp != NULL && vp->v_type == VREG &&
1913 			    VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
1914 				if (vp == p->p_exec)
1915 					(void) strcpy(mp->pr_mapname, "a.out");
1916 				else
1917 					pr_object_name(mp->pr_mapname,
1918 					    vp, &vattr);
1919 			}
1920 
1921 			/*
1922 			 * Get the SysV shared memory id, if any.
1923 			 */
1924 			if ((mp->pr_mflags & MA_SHARED) && p->p_segacct &&
1925 			    (mp->pr_shmid = shmgetid(p, seg->s_base)) !=
1926 			    SHMID_NONE) {
1927 				if (mp->pr_shmid == SHMID_FREE)
1928 					mp->pr_shmid = -1;
1929 
1930 				mp->pr_mflags |= MA_SHM;
1931 			} else {
1932 				mp->pr_shmid = -1;
1933 			}
1934 		}
1935 		ASSERT(tmp == NULL);
1936 	} while ((seg = AS_SEGNEXT(as, seg)) != NULL);
1937 
1938 	return (0);
1939 }
1940 #endif	/* _SYSCALL32_IMPL */
1941 
1942 /*
1943  * Return the size of the /proc page data file.
1944  */
1945 size_t
1946 prpdsize(struct as *as)
1947 {
1948 	struct seg *seg;
1949 	size_t size;
1950 
1951 	ASSERT(as != &kas && AS_WRITE_HELD(as));
1952 
1953 	if ((seg = AS_SEGFIRST(as)) == NULL)
1954 		return (0);
1955 
1956 	size = sizeof (prpageheader_t);
1957 	do {
1958 		caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
1959 		caddr_t saddr, naddr;
1960 		void *tmp = NULL;
1961 		size_t npage;
1962 
1963 		if ((seg->s_flags & S_HOLE) != 0) {
1964 			continue;
1965 		}
1966 
1967 		for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
1968 			(void) pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
1969 			if ((npage = (naddr - saddr) / PAGESIZE) != 0)
1970 				size += sizeof (prasmap_t) + round8(npage);
1971 		}
1972 		ASSERT(tmp == NULL);
1973 	} while ((seg = AS_SEGNEXT(as, seg)) != NULL);
1974 
1975 	return (size);
1976 }
1977 
1978 #ifdef _SYSCALL32_IMPL
1979 size_t
1980 prpdsize32(struct as *as)
1981 {
1982 	struct seg *seg;
1983 	size_t size;
1984 
1985 	ASSERT(as != &kas && AS_WRITE_HELD(as));
1986 
1987 	if ((seg = AS_SEGFIRST(as)) == NULL)
1988 		return (0);
1989 
1990 	size = sizeof (prpageheader32_t);
1991 	do {
1992 		caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
1993 		caddr_t saddr, naddr;
1994 		void *tmp = NULL;
1995 		size_t npage;
1996 
1997 		if ((seg->s_flags & S_HOLE) != 0) {
1998 			continue;
1999 		}
2000 
2001 		for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
2002 			(void) pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
2003 			if ((npage = (naddr - saddr) / PAGESIZE) != 0)
2004 				size += sizeof (prasmap32_t) + round8(npage);
2005 		}
2006 		ASSERT(tmp == NULL);
2007 	} while ((seg = AS_SEGNEXT(as, seg)) != NULL);
2008 
2009 	return (size);
2010 }
2011 #endif	/* _SYSCALL32_IMPL */
2012 
2013 /*
2014  * Read page data information.
2015  */
2016 int
2017 prpdread(proc_t *p, uint_t hatid, struct uio *uiop)
2018 {
2019 	struct as *as = p->p_as;
2020 	caddr_t buf;
2021 	size_t size;
2022 	prpageheader_t *php;
2023 	prasmap_t *pmp;
2024 	struct seg *seg;
2025 	int error;
2026 
2027 again:
2028 	AS_LOCK_ENTER(as, RW_WRITER);
2029 
2030 	if ((seg = AS_SEGFIRST(as)) == NULL) {
2031 		AS_LOCK_EXIT(as);
2032 		return (0);
2033 	}
2034 	size = prpdsize(as);
2035 	if (uiop->uio_resid < size) {
2036 		AS_LOCK_EXIT(as);
2037 		return (E2BIG);
2038 	}
2039 
2040 	buf = kmem_zalloc(size, KM_SLEEP);
2041 	php = (prpageheader_t *)buf;
2042 	pmp = (prasmap_t *)(buf + sizeof (prpageheader_t));
2043 
2044 	hrt2ts(gethrtime(), &php->pr_tstamp);
2045 	php->pr_nmap = 0;
2046 	php->pr_npage = 0;
2047 	do {
2048 		caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
2049 		caddr_t saddr, naddr;
2050 		void *tmp = NULL;
2051 
2052 		if ((seg->s_flags & S_HOLE) != 0) {
2053 			continue;
2054 		}
2055 
2056 		for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
2057 			struct vnode *vp;
2058 			struct vattr vattr;
2059 			size_t len;
2060 			size_t npage;
2061 			uint_t prot;
2062 			uintptr_t next;
2063 
2064 			prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
2065 			if ((len = (size_t)(naddr - saddr)) == 0)
2066 				continue;
2067 			npage = len / PAGESIZE;
2068 			next = (uintptr_t)(pmp + 1) + round8(npage);
2069 			/*
2070 			 * It's possible that the address space can change
2071 			 * subtlely even though we're holding as->a_lock
2072 			 * due to the nondeterminism of page_exists() in
2073 			 * the presence of asychronously flushed pages or
2074 			 * mapped files whose sizes are changing.
2075 			 * page_exists() may be called indirectly from
2076 			 * pr_getprot() by a SEGOP_INCORE() routine.
2077 			 * If this happens we need to make sure we don't
2078 			 * overrun the buffer whose size we computed based
2079 			 * on the initial iteration through the segments.
2080 			 * Once we've detected an overflow, we need to clean
2081 			 * up the temporary memory allocated in pr_getprot()
2082 			 * and retry. If there's a pending signal, we return
2083 			 * EINTR so that this thread can be dislodged if
2084 			 * a latent bug causes us to spin indefinitely.
2085 			 */
2086 			if (next > (uintptr_t)buf + size) {
2087 				pr_getprot_done(&tmp);
2088 				AS_LOCK_EXIT(as);
2089 
2090 				kmem_free(buf, size);
2091 
2092 				if (ISSIG(curthread, JUSTLOOKING))
2093 					return (EINTR);
2094 
2095 				goto again;
2096 			}
2097 
2098 			php->pr_nmap++;
2099 			php->pr_npage += npage;
2100 			pmp->pr_vaddr = (uintptr_t)saddr;
2101 			pmp->pr_npage = npage;
2102 			pmp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
2103 			pmp->pr_mflags = 0;
2104 			if (prot & PROT_READ)
2105 				pmp->pr_mflags |= MA_READ;
2106 			if (prot & PROT_WRITE)
2107 				pmp->pr_mflags |= MA_WRITE;
2108 			if (prot & PROT_EXEC)
2109 				pmp->pr_mflags |= MA_EXEC;
2110 			if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
2111 				pmp->pr_mflags |= MA_SHARED;
2112 			if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
2113 				pmp->pr_mflags |= MA_NORESERVE;
2114 			if (seg->s_ops == &segspt_shmops ||
2115 			    (seg->s_ops == &segvn_ops &&
2116 			    (SEGOP_GETVP(seg, saddr, &vp) != 0 || vp == NULL)))
2117 				pmp->pr_mflags |= MA_ANON;
2118 			if (seg->s_ops == &segspt_shmops)
2119 				pmp->pr_mflags |= MA_ISM | MA_SHM;
2120 			pmp->pr_pagesize = PAGESIZE;
2121 			/*
2122 			 * Manufacture a filename for the "object" directory.
2123 			 */
2124 			vattr.va_mask = AT_FSID|AT_NODEID;
2125 			if (seg->s_ops == &segvn_ops &&
2126 			    SEGOP_GETVP(seg, saddr, &vp) == 0 &&
2127 			    vp != NULL && vp->v_type == VREG &&
2128 			    VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
2129 				if (vp == p->p_exec)
2130 					(void) strcpy(pmp->pr_mapname, "a.out");
2131 				else
2132 					pr_object_name(pmp->pr_mapname,
2133 					    vp, &vattr);
2134 			}
2135 
2136 			/*
2137 			 * Get the SysV shared memory id, if any.
2138 			 */
2139 			if ((pmp->pr_mflags & MA_SHARED) && p->p_segacct &&
2140 			    (pmp->pr_shmid = shmgetid(p, seg->s_base)) !=
2141 			    SHMID_NONE) {
2142 				if (pmp->pr_shmid == SHMID_FREE)
2143 					pmp->pr_shmid = -1;
2144 
2145 				pmp->pr_mflags |= MA_SHM;
2146 			} else {
2147 				pmp->pr_shmid = -1;
2148 			}
2149 
2150 			hat_getstat(as, saddr, len, hatid,
2151 			    (char *)(pmp + 1), HAT_SYNC_ZERORM);
2152 			pmp = (prasmap_t *)next;
2153 		}
2154 		ASSERT(tmp == NULL);
2155 	} while ((seg = AS_SEGNEXT(as, seg)) != NULL);
2156 
2157 	AS_LOCK_EXIT(as);
2158 
2159 	ASSERT((uintptr_t)pmp <= (uintptr_t)buf + size);
2160 	error = uiomove(buf, (caddr_t)pmp - buf, UIO_READ, uiop);
2161 	kmem_free(buf, size);
2162 
2163 	return (error);
2164 }
2165 
2166 #ifdef _SYSCALL32_IMPL
2167 int
2168 prpdread32(proc_t *p, uint_t hatid, struct uio *uiop)
2169 {
2170 	struct as *as = p->p_as;
2171 	caddr_t buf;
2172 	size_t size;
2173 	prpageheader32_t *php;
2174 	prasmap32_t *pmp;
2175 	struct seg *seg;
2176 	int error;
2177 
2178 again:
2179 	AS_LOCK_ENTER(as, RW_WRITER);
2180 
2181 	if ((seg = AS_SEGFIRST(as)) == NULL) {
2182 		AS_LOCK_EXIT(as);
2183 		return (0);
2184 	}
2185 	size = prpdsize32(as);
2186 	if (uiop->uio_resid < size) {
2187 		AS_LOCK_EXIT(as);
2188 		return (E2BIG);
2189 	}
2190 
2191 	buf = kmem_zalloc(size, KM_SLEEP);
2192 	php = (prpageheader32_t *)buf;
2193 	pmp = (prasmap32_t *)(buf + sizeof (prpageheader32_t));
2194 
2195 	hrt2ts32(gethrtime(), &php->pr_tstamp);
2196 	php->pr_nmap = 0;
2197 	php->pr_npage = 0;
2198 	do {
2199 		caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
2200 		caddr_t saddr, naddr;
2201 		void *tmp = NULL;
2202 
2203 		if ((seg->s_flags & S_HOLE) != 0) {
2204 			continue;
2205 		}
2206 
2207 		for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
2208 			struct vnode *vp;
2209 			struct vattr vattr;
2210 			size_t len;
2211 			size_t npage;
2212 			uint_t prot;
2213 			uintptr_t next;
2214 
2215 			prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
2216 			if ((len = (size_t)(naddr - saddr)) == 0)
2217 				continue;
2218 			npage = len / PAGESIZE;
2219 			next = (uintptr_t)(pmp + 1) + round8(npage);
2220 			/*
2221 			 * It's possible that the address space can change
2222 			 * subtlely even though we're holding as->a_lock
2223 			 * due to the nondeterminism of page_exists() in
2224 			 * the presence of asychronously flushed pages or
2225 			 * mapped files whose sizes are changing.
2226 			 * page_exists() may be called indirectly from
2227 			 * pr_getprot() by a SEGOP_INCORE() routine.
2228 			 * If this happens we need to make sure we don't
2229 			 * overrun the buffer whose size we computed based
2230 			 * on the initial iteration through the segments.
2231 			 * Once we've detected an overflow, we need to clean
2232 			 * up the temporary memory allocated in pr_getprot()
2233 			 * and retry. If there's a pending signal, we return
2234 			 * EINTR so that this thread can be dislodged if
2235 			 * a latent bug causes us to spin indefinitely.
2236 			 */
2237 			if (next > (uintptr_t)buf + size) {
2238 				pr_getprot_done(&tmp);
2239 				AS_LOCK_EXIT(as);
2240 
2241 				kmem_free(buf, size);
2242 
2243 				if (ISSIG(curthread, JUSTLOOKING))
2244 					return (EINTR);
2245 
2246 				goto again;
2247 			}
2248 
2249 			php->pr_nmap++;
2250 			php->pr_npage += npage;
2251 			pmp->pr_vaddr = (caddr32_t)(uintptr_t)saddr;
2252 			pmp->pr_npage = (size32_t)npage;
2253 			pmp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
2254 			pmp->pr_mflags = 0;
2255 			if (prot & PROT_READ)
2256 				pmp->pr_mflags |= MA_READ;
2257 			if (prot & PROT_WRITE)
2258 				pmp->pr_mflags |= MA_WRITE;
2259 			if (prot & PROT_EXEC)
2260 				pmp->pr_mflags |= MA_EXEC;
2261 			if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
2262 				pmp->pr_mflags |= MA_SHARED;
2263 			if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
2264 				pmp->pr_mflags |= MA_NORESERVE;
2265 			if (seg->s_ops == &segspt_shmops ||
2266 			    (seg->s_ops == &segvn_ops &&
2267 			    (SEGOP_GETVP(seg, saddr, &vp) != 0 || vp == NULL)))
2268 				pmp->pr_mflags |= MA_ANON;
2269 			if (seg->s_ops == &segspt_shmops)
2270 				pmp->pr_mflags |= MA_ISM | MA_SHM;
2271 			pmp->pr_pagesize = PAGESIZE;
2272 			/*
2273 			 * Manufacture a filename for the "object" directory.
2274 			 */
2275 			vattr.va_mask = AT_FSID|AT_NODEID;
2276 			if (seg->s_ops == &segvn_ops &&
2277 			    SEGOP_GETVP(seg, saddr, &vp) == 0 &&
2278 			    vp != NULL && vp->v_type == VREG &&
2279 			    VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
2280 				if (vp == p->p_exec)
2281 					(void) strcpy(pmp->pr_mapname, "a.out");
2282 				else
2283 					pr_object_name(pmp->pr_mapname,
2284 					    vp, &vattr);
2285 			}
2286 
2287 			/*
2288 			 * Get the SysV shared memory id, if any.
2289 			 */
2290 			if ((pmp->pr_mflags & MA_SHARED) && p->p_segacct &&
2291 			    (pmp->pr_shmid = shmgetid(p, seg->s_base)) !=
2292 			    SHMID_NONE) {
2293 				if (pmp->pr_shmid == SHMID_FREE)
2294 					pmp->pr_shmid = -1;
2295 
2296 				pmp->pr_mflags |= MA_SHM;
2297 			} else {
2298 				pmp->pr_shmid = -1;
2299 			}
2300 
2301 			hat_getstat(as, saddr, len, hatid,
2302 			    (char *)(pmp + 1), HAT_SYNC_ZERORM);
2303 			pmp = (prasmap32_t *)next;
2304 		}
2305 		ASSERT(tmp == NULL);
2306 	} while ((seg = AS_SEGNEXT(as, seg)) != NULL);
2307 
2308 	AS_LOCK_EXIT(as);
2309 
2310 	ASSERT((uintptr_t)pmp <= (uintptr_t)buf + size);
2311 	error = uiomove(buf, (caddr_t)pmp - buf, UIO_READ, uiop);
2312 	kmem_free(buf, size);
2313 
2314 	return (error);
2315 }
2316 #endif	/* _SYSCALL32_IMPL */
2317 
2318 ushort_t
2319 prgetpctcpu(uint64_t pct)
2320 {
2321 	/*
2322 	 * The value returned will be relevant in the zone of the examiner,
2323 	 * which may not be the same as the zone which performed the procfs
2324 	 * mount.
2325 	 */
2326 	int nonline = zone_ncpus_online_get(curproc->p_zone);
2327 
2328 	/*
2329 	 * Prorate over online cpus so we don't exceed 100%
2330 	 */
2331 	if (nonline > 1)
2332 		pct /= nonline;
2333 	pct >>= 16;		/* convert to 16-bit scaled integer */
2334 	if (pct > 0x8000)	/* might happen, due to rounding */
2335 		pct = 0x8000;
2336 	return ((ushort_t)pct);
2337 }
2338 
2339 /*
2340  * Return information used by ps(1).
2341  */
2342 void
2343 prgetpsinfo(proc_t *p, psinfo_t *psp)
2344 {
2345 	kthread_t *t;
2346 	struct cred *cred;
2347 	hrtime_t hrutime, hrstime;
2348 
2349 	ASSERT(MUTEX_HELD(&p->p_lock));
2350 
2351 	if ((t = prchoose(p)) == NULL)	/* returns locked thread */
2352 		bzero(psp, sizeof (*psp));
2353 	else {
2354 		thread_unlock(t);
2355 		bzero(psp, sizeof (*psp) - sizeof (psp->pr_lwp));
2356 	}
2357 
2358 	/*
2359 	 * only export SSYS and SMSACCT; everything else is off-limits to
2360 	 * userland apps.
2361 	 */
2362 	psp->pr_flag = p->p_flag & (SSYS | SMSACCT);
2363 	psp->pr_nlwp = p->p_lwpcnt;
2364 	psp->pr_nzomb = p->p_zombcnt;
2365 	mutex_enter(&p->p_crlock);
2366 	cred = p->p_cred;
2367 	psp->pr_uid = crgetruid(cred);
2368 	psp->pr_euid = crgetuid(cred);
2369 	psp->pr_gid = crgetrgid(cred);
2370 	psp->pr_egid = crgetgid(cred);
2371 	mutex_exit(&p->p_crlock);
2372 	psp->pr_pid = p->p_pid;
2373 	if (curproc->p_zone->zone_id != GLOBAL_ZONEID &&
2374 	    (p->p_flag & SZONETOP)) {
2375 		ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID);
2376 		/*
2377 		 * Inside local zones, fake zsched's pid as parent pids for
2378 		 * processes which reference processes outside of the zone.
2379 		 */
2380 		psp->pr_ppid = curproc->p_zone->zone_zsched->p_pid;
2381 	} else {
2382 		psp->pr_ppid = p->p_ppid;
2383 	}
2384 	psp->pr_pgid = p->p_pgrp;
2385 	psp->pr_sid = p->p_sessp->s_sid;
2386 	psp->pr_taskid = p->p_task->tk_tkid;
2387 	psp->pr_projid = p->p_task->tk_proj->kpj_id;
2388 	psp->pr_poolid = p->p_pool->pool_id;
2389 	psp->pr_zoneid = p->p_zone->zone_id;
2390 	if ((psp->pr_contract = PRCTID(p)) == 0)
2391 		psp->pr_contract = -1;
2392 	psp->pr_addr = (uintptr_t)prgetpsaddr(p);
2393 	switch (p->p_model) {
2394 	case DATAMODEL_ILP32:
2395 		psp->pr_dmodel = PR_MODEL_ILP32;
2396 		break;
2397 	case DATAMODEL_LP64:
2398 		psp->pr_dmodel = PR_MODEL_LP64;
2399 		break;
2400 	}
2401 	hrutime = mstate_aggr_state(p, LMS_USER);
2402 	hrstime = mstate_aggr_state(p, LMS_SYSTEM);
2403 	hrt2ts((hrutime + hrstime), &psp->pr_time);
2404 	TICK_TO_TIMESTRUC(p->p_cutime + p->p_cstime, &psp->pr_ctime);
2405 
2406 	if (t == NULL) {
2407 		int wcode = p->p_wcode;		/* must be atomic read */
2408 
2409 		if (wcode)
2410 			psp->pr_wstat = wstat(wcode, p->p_wdata);
2411 		psp->pr_ttydev = PRNODEV;
2412 		psp->pr_lwp.pr_state = SZOMB;
2413 		psp->pr_lwp.pr_sname = 'Z';
2414 		psp->pr_lwp.pr_bindpro = PBIND_NONE;
2415 		psp->pr_lwp.pr_bindpset = PS_NONE;
2416 	} else {
2417 		user_t *up = PTOU(p);
2418 		struct as *as;
2419 		dev_t d;
2420 		extern dev_t rwsconsdev, rconsdev, uconsdev;
2421 
2422 		d = cttydev(p);
2423 		/*
2424 		 * If the controlling terminal is the real
2425 		 * or workstation console device, map to what the
2426 		 * user thinks is the console device. Handle case when
2427 		 * rwsconsdev or rconsdev is set to NODEV for Starfire.
2428 		 */
2429 		if ((d == rwsconsdev || d == rconsdev) && d != NODEV)
2430 			d = uconsdev;
2431 		psp->pr_ttydev = (d == NODEV) ? PRNODEV : d;
2432 		psp->pr_start = up->u_start;
2433 		bcopy(up->u_comm, psp->pr_fname,
2434 		    MIN(sizeof (up->u_comm), sizeof (psp->pr_fname)-1));
2435 		bcopy(up->u_psargs, psp->pr_psargs,
2436 		    MIN(PRARGSZ-1, PSARGSZ));
2437 		psp->pr_argc = up->u_argc;
2438 		psp->pr_argv = up->u_argv;
2439 		psp->pr_envp = up->u_envp;
2440 
2441 		/* get the chosen lwp's lwpsinfo */
2442 		prgetlwpsinfo(t, &psp->pr_lwp);
2443 
2444 		/* compute %cpu for the process */
2445 		if (p->p_lwpcnt == 1)
2446 			psp->pr_pctcpu = psp->pr_lwp.pr_pctcpu;
2447 		else {
2448 			uint64_t pct = 0;
2449 			hrtime_t cur_time = gethrtime_unscaled();
2450 
2451 			t = p->p_tlist;
2452 			do {
2453 				pct += cpu_update_pct(t, cur_time);
2454 			} while ((t = t->t_forw) != p->p_tlist);
2455 
2456 			psp->pr_pctcpu = prgetpctcpu(pct);
2457 		}
2458 		if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
2459 			psp->pr_size = 0;
2460 			psp->pr_rssize = 0;
2461 		} else {
2462 			mutex_exit(&p->p_lock);
2463 			AS_LOCK_ENTER(as, RW_READER);
2464 			psp->pr_size = btopr(as->a_resvsize) *
2465 			    (PAGESIZE / 1024);
2466 			psp->pr_rssize = rm_asrss(as) * (PAGESIZE / 1024);
2467 			psp->pr_pctmem = rm_pctmemory(as);
2468 			AS_LOCK_EXIT(as);
2469 			mutex_enter(&p->p_lock);
2470 		}
2471 	}
2472 }
2473 
2474 static size_t
2475 prfdinfomisc(list_t *data, uint_t type, const void *val, size_t vlen)
2476 {
2477 	pr_misc_header_t *misc;
2478 	size_t len;
2479 
2480 	len = PRFDINFO_ROUNDUP(sizeof (*misc) + vlen);
2481 
2482 	if (data != NULL) {
2483 		misc = pr_iol_newbuf(data, len);
2484 		misc->pr_misc_type = type;
2485 		misc->pr_misc_size = len;
2486 		misc++;
2487 		bcopy((char *)val, (char *)misc, vlen);
2488 	}
2489 
2490 	return (len);
2491 }
2492 
2493 /*
2494  * There's no elegant way to determine if a character device
2495  * supports TLI, so just check a hardcoded list of known TLI
2496  * devices.
2497  */
2498 
2499 static boolean_t
2500 pristli(vnode_t *vp)
2501 {
2502 	static const char *tlidevs[] = {
2503 	    "udp", "udp6", "tcp", "tcp6"
2504 	};
2505 	char *devname;
2506 	uint_t i;
2507 
2508 	ASSERT(vp != NULL);
2509 
2510 	if (vp->v_type != VCHR || vp->v_stream == NULL || vp->v_rdev == 0)
2511 		return (B_FALSE);
2512 
2513 	if ((devname = mod_major_to_name(getmajor(vp->v_rdev))) == NULL)
2514 		return (B_FALSE);
2515 
2516 	for (i = 0; i < ARRAY_SIZE(tlidevs); i++) {
2517 		if (strcmp(devname, tlidevs[i]) == 0)
2518 			return (B_TRUE);
2519 	}
2520 
2521 	return (B_FALSE);
2522 }
2523 
2524 static size_t
2525 prfdinfopath(proc_t *p, vnode_t *vp, list_t *data, cred_t *cred)
2526 {
2527 	char *pathname;
2528 	size_t pathlen;
2529 	size_t sz = 0;
2530 
2531 	/*
2532 	 * The global zone's path to a file in a non-global zone can exceed
2533 	 * MAXPATHLEN.
2534 	 */
2535 	pathlen = MAXPATHLEN * 2 + 1;
2536 	pathname = kmem_alloc(pathlen, KM_SLEEP);
2537 
2538 	if (vnodetopath(NULL, vp, pathname, pathlen, cred) == 0) {
2539 		sz += prfdinfomisc(data, PR_PATHNAME,
2540 		    pathname, strlen(pathname) + 1);
2541 	}
2542 
2543 	kmem_free(pathname, pathlen);
2544 
2545 	return (sz);
2546 }
2547 
2548 static size_t
2549 prfdinfotlisockopt(vnode_t *vp, list_t *data, cred_t *cred)
2550 {
2551 	strcmd_t strcmd;
2552 	int32_t rval;
2553 	size_t sz = 0;
2554 
2555 	strcmd.sc_cmd = TI_GETMYNAME;
2556 	strcmd.sc_timeout = 1;
2557 	strcmd.sc_len = STRCMDBUFSIZE;
2558 
2559 	if (VOP_IOCTL(vp, _I_CMD, (intptr_t)&strcmd, FKIOCTL, cred,
2560 	    &rval, NULL) == 0 && strcmd.sc_len > 0) {
2561 		sz += prfdinfomisc(data, PR_SOCKETNAME, strcmd.sc_buf,
2562 		    strcmd.sc_len);
2563 	}
2564 
2565 	strcmd.sc_cmd = TI_GETPEERNAME;
2566 	strcmd.sc_timeout = 1;
2567 	strcmd.sc_len = STRCMDBUFSIZE;
2568 
2569 	if (VOP_IOCTL(vp, _I_CMD, (intptr_t)&strcmd, FKIOCTL, cred,
2570 	    &rval, NULL) == 0 && strcmd.sc_len > 0) {
2571 		sz += prfdinfomisc(data, PR_PEERSOCKNAME, strcmd.sc_buf,
2572 		    strcmd.sc_len);
2573 	}
2574 
2575 	return (sz);
2576 }
2577 
2578 static size_t
2579 prfdinfosockopt(vnode_t *vp, list_t *data, cred_t *cred)
2580 {
2581 	sonode_t *so;
2582 	socklen_t vlen;
2583 	size_t sz = 0;
2584 	uint_t i;
2585 
2586 	if (vp->v_stream != NULL) {
2587 		so = VTOSO(vp->v_stream->sd_vnode);
2588 
2589 		if (so->so_version == SOV_STREAM)
2590 			so = NULL;
2591 	} else {
2592 		so = VTOSO(vp);
2593 	}
2594 
2595 	if (so == NULL)
2596 		return (0);
2597 
2598 	DTRACE_PROBE1(sonode, sonode_t *, so);
2599 
2600 	/* prmisc - PR_SOCKETNAME */
2601 
2602 	struct sockaddr_storage buf;
2603 	struct sockaddr *name = (struct sockaddr *)&buf;
2604 
2605 	vlen = sizeof (buf);
2606 	if (SOP_GETSOCKNAME(so, name, &vlen, cred) == 0 && vlen > 0)
2607 		sz += prfdinfomisc(data, PR_SOCKETNAME, name, vlen);
2608 
2609 	/* prmisc - PR_PEERSOCKNAME */
2610 
2611 	vlen = sizeof (buf);
2612 	if (SOP_GETPEERNAME(so, name, &vlen, B_FALSE, cred) == 0 && vlen > 0)
2613 		sz += prfdinfomisc(data, PR_PEERSOCKNAME, name, vlen);
2614 
2615 	/* prmisc - PR_SOCKOPTS_BOOL_OPTS */
2616 
2617 	static struct boolopt {
2618 		int		level;
2619 		int		opt;
2620 		int		bopt;
2621 	} boolopts[] = {
2622 		{ SOL_SOCKET, SO_DEBUG,		PR_SO_DEBUG },
2623 		{ SOL_SOCKET, SO_REUSEADDR,	PR_SO_REUSEADDR },
2624 #ifdef SO_REUSEPORT
2625 		/* SmartOS and OmniOS have SO_REUSEPORT */
2626 		{ SOL_SOCKET, SO_REUSEPORT,	PR_SO_REUSEPORT },
2627 #endif
2628 		{ SOL_SOCKET, SO_KEEPALIVE,	PR_SO_KEEPALIVE },
2629 		{ SOL_SOCKET, SO_DONTROUTE,	PR_SO_DONTROUTE },
2630 		{ SOL_SOCKET, SO_BROADCAST,	PR_SO_BROADCAST },
2631 		{ SOL_SOCKET, SO_OOBINLINE,	PR_SO_OOBINLINE },
2632 		{ SOL_SOCKET, SO_DGRAM_ERRIND,	PR_SO_DGRAM_ERRIND },
2633 		{ SOL_SOCKET, SO_ALLZONES,	PR_SO_ALLZONES },
2634 		{ SOL_SOCKET, SO_MAC_EXEMPT,	PR_SO_MAC_EXEMPT },
2635 		{ SOL_SOCKET, SO_MAC_IMPLICIT,	PR_SO_MAC_IMPLICIT },
2636 		{ SOL_SOCKET, SO_EXCLBIND,	PR_SO_EXCLBIND },
2637 		{ SOL_SOCKET, SO_VRRP,		PR_SO_VRRP },
2638 		{ IPPROTO_UDP, UDP_NAT_T_ENDPOINT,
2639 		    PR_UDP_NAT_T_ENDPOINT }
2640 	};
2641 	prsockopts_bool_opts_t opts;
2642 	int val;
2643 
2644 	if (data != NULL) {
2645 		opts.prsock_bool_opts = 0;
2646 
2647 		for (i = 0; i < ARRAY_SIZE(boolopts); i++) {
2648 			vlen = sizeof (val);
2649 			if (SOP_GETSOCKOPT(so, boolopts[i].level,
2650 			    boolopts[i].opt, &val, &vlen, 0, cred) == 0 &&
2651 			    val != 0) {
2652 				opts.prsock_bool_opts |= boolopts[i].bopt;
2653 			}
2654 		}
2655 	}
2656 
2657 	sz += prfdinfomisc(data, PR_SOCKOPTS_BOOL_OPTS, &opts, sizeof (opts));
2658 
2659 	/* prmisc - PR_SOCKOPT_LINGER */
2660 
2661 	struct linger l;
2662 
2663 	vlen = sizeof (l);
2664 	if (SOP_GETSOCKOPT(so, SOL_SOCKET, SO_LINGER, &l, &vlen,
2665 	    0, cred) == 0 && vlen > 0) {
2666 		sz += prfdinfomisc(data, PR_SOCKOPT_LINGER, &l, vlen);
2667 	}
2668 
2669 	/* prmisc - PR_SOCKOPT_* int types */
2670 
2671 	static struct sopt {
2672 		int		level;
2673 		int		opt;
2674 		int		bopt;
2675 	} sopts[] = {
2676 		{ SOL_SOCKET, SO_TYPE,		PR_SOCKOPT_TYPE },
2677 		{ SOL_SOCKET, SO_SNDBUF,	PR_SOCKOPT_SNDBUF },
2678 		{ SOL_SOCKET, SO_RCVBUF,	PR_SOCKOPT_RCVBUF }
2679 	};
2680 
2681 	for (i = 0; i < ARRAY_SIZE(sopts); i++) {
2682 		vlen = sizeof (val);
2683 		if (SOP_GETSOCKOPT(so, sopts[i].level, sopts[i].opt,
2684 		    &val, &vlen, 0, cred) == 0 && vlen > 0) {
2685 			sz += prfdinfomisc(data, sopts[i].bopt, &val, vlen);
2686 		}
2687 	}
2688 
2689 	/* prmisc - PR_SOCKOPT_IP_NEXTHOP */
2690 
2691 	in_addr_t nexthop_val;
2692 
2693 	vlen = sizeof (nexthop_val);
2694 	if (SOP_GETSOCKOPT(so, IPPROTO_IP, IP_NEXTHOP,
2695 	    &nexthop_val, &vlen, 0, cred) == 0 && vlen > 0) {
2696 		sz += prfdinfomisc(data, PR_SOCKOPT_IP_NEXTHOP,
2697 		    &nexthop_val, vlen);
2698 	}
2699 
2700 	/* prmisc - PR_SOCKOPT_IPV6_NEXTHOP */
2701 
2702 	struct sockaddr_in6 nexthop6_val;
2703 
2704 	vlen = sizeof (nexthop6_val);
2705 	if (SOP_GETSOCKOPT(so, IPPROTO_IPV6, IPV6_NEXTHOP,
2706 	    &nexthop6_val, &vlen, 0, cred) == 0 && vlen > 0) {
2707 		sz += prfdinfomisc(data, PR_SOCKOPT_IPV6_NEXTHOP,
2708 		    &nexthop6_val, vlen);
2709 	}
2710 
2711 	/* prmisc - PR_SOCKOPT_TCP_CONGESTION */
2712 
2713 	char cong[CC_ALGO_NAME_MAX];
2714 
2715 	vlen = sizeof (cong);
2716 	if (SOP_GETSOCKOPT(so, IPPROTO_TCP, TCP_CONGESTION,
2717 	    &cong, &vlen, 0, cred) == 0 && vlen > 0) {
2718 		sz += prfdinfomisc(data, PR_SOCKOPT_TCP_CONGESTION, cong, vlen);
2719 	}
2720 
2721 	/* prmisc - PR_SOCKFILTERS_PRIV */
2722 
2723 	struct fil_info fi;
2724 
2725 	vlen = sizeof (fi);
2726 	if (SOP_GETSOCKOPT(so, SOL_FILTER, FIL_LIST,
2727 	    &fi, &vlen, 0, cred) == 0 && vlen != 0) {
2728 		pr_misc_header_t *misc;
2729 		size_t len;
2730 
2731 		/*
2732 		 * We limit the number of returned filters to 32.
2733 		 * This is the maximum number that pfiles will print
2734 		 * anyway.
2735 		 */
2736 		vlen = MIN(32, fi.fi_pos + 1);
2737 		vlen *= sizeof (fi);
2738 
2739 		len = PRFDINFO_ROUNDUP(sizeof (*misc) + vlen);
2740 		sz += len;
2741 
2742 		if (data != NULL) {
2743 			/*
2744 			 * So that the filter list can be built incrementally,
2745 			 * prfdinfomisc() is not used here. Instead we
2746 			 * allocate a buffer directly on the copyout list using
2747 			 * pr_iol_newbuf()
2748 			 */
2749 			misc = pr_iol_newbuf(data, len);
2750 			misc->pr_misc_type = PR_SOCKFILTERS_PRIV;
2751 			misc->pr_misc_size = len;
2752 			misc++;
2753 			len = vlen;
2754 			if (SOP_GETSOCKOPT(so, SOL_FILTER, FIL_LIST,
2755 			    misc, &vlen, 0, cred) == 0) {
2756 				/*
2757 				 * In case the number of filters has reduced
2758 				 * since the first call, explicitly zero out
2759 				 * any unpopulated space.
2760 				 */
2761 				if (vlen < len)
2762 					bzero(misc + vlen, len - vlen);
2763 			} else {
2764 				/* Something went wrong, zero out the result */
2765 				bzero(misc, vlen);
2766 			}
2767 		}
2768 	}
2769 
2770 	return (sz);
2771 }
2772 
2773 typedef struct prfdinfo_nm_path_cbdata {
2774 	proc_t		*nmp_p;
2775 	u_offset_t	nmp_sz;
2776 	list_t		*nmp_data;
2777 } prfdinfo_nm_path_cbdata_t;
2778 
2779 static int
2780 prfdinfo_nm_path(const struct namenode *np, cred_t *cred, void *arg)
2781 {
2782 	prfdinfo_nm_path_cbdata_t *cb = arg;
2783 
2784 	cb->nmp_sz += prfdinfopath(cb->nmp_p, np->nm_vnode, cb->nmp_data, cred);
2785 
2786 	return (0);
2787 }
2788 
2789 u_offset_t
2790 prgetfdinfosize(proc_t *p, vnode_t *vp, cred_t *cred)
2791 {
2792 	u_offset_t sz;
2793 
2794 	/*
2795 	 * All fdinfo files will be at least this big -
2796 	 * sizeof fdinfo struct + zero length trailer
2797 	 */
2798 	sz = offsetof(prfdinfo_t, pr_misc) + sizeof (pr_misc_header_t);
2799 
2800 	/* Pathname */
2801 	switch (vp->v_type) {
2802 	case VDOOR: {
2803 		prfdinfo_nm_path_cbdata_t cb = {
2804 			.nmp_p		= p,
2805 			.nmp_data	= NULL,
2806 			.nmp_sz		= 0
2807 		};
2808 
2809 		(void) nm_walk_mounts(vp, prfdinfo_nm_path, cred, &cb);
2810 		sz += cb.nmp_sz;
2811 		break;
2812 	}
2813 	case VSOCK:
2814 		break;
2815 	default:
2816 		sz += prfdinfopath(p, vp, NULL, cred);
2817 	}
2818 
2819 	/* Socket options */
2820 	if (vp->v_type == VSOCK)
2821 		sz += prfdinfosockopt(vp, NULL, cred);
2822 
2823 	/* TLI/XTI sockets */
2824 	if (pristli(vp))
2825 		sz += prfdinfotlisockopt(vp, NULL, cred);
2826 
2827 	return (sz);
2828 }
2829 
2830 int
2831 prgetfdinfo(proc_t *p, vnode_t *vp, prfdinfo_t *fdinfo, cred_t *cred,
2832     cred_t *file_cred, list_t *data)
2833 {
2834 	vattr_t vattr;
2835 	int error;
2836 
2837 	/*
2838 	 * The buffer has been initialised to zero by pr_iol_newbuf().
2839 	 * Initialise defaults for any values that should not default to zero.
2840 	 */
2841 	fdinfo->pr_uid = (uid_t)-1;
2842 	fdinfo->pr_gid = (gid_t)-1;
2843 	fdinfo->pr_size = -1;
2844 	fdinfo->pr_locktype = F_UNLCK;
2845 	fdinfo->pr_lockpid = -1;
2846 	fdinfo->pr_locksysid = -1;
2847 	fdinfo->pr_peerpid = -1;
2848 
2849 	/* Offset */
2850 
2851 	/*
2852 	 * pr_offset has already been set from the underlying file_t.
2853 	 * Check if it is plausible and reset to -1 if not.
2854 	 */
2855 	if (fdinfo->pr_offset != -1 &&
2856 	    VOP_SEEK(vp, 0, (offset_t *)&fdinfo->pr_offset, NULL) != 0)
2857 		fdinfo->pr_offset = -1;
2858 
2859 	/*
2860 	 * Attributes
2861 	 *
2862 	 * We have two cred_t structures available here.
2863 	 * 'cred' is the caller's credential, and 'file_cred' is the credential
2864 	 * for the file being inspected.
2865 	 *
2866 	 * When looking up the file attributes, file_cred is used in order
2867 	 * that the correct ownership is set for doors and FIFOs. Since the
2868 	 * caller has permission to read the fdinfo file in proc, this does
2869 	 * not expose any additional information.
2870 	 */
2871 	vattr.va_mask = AT_STAT;
2872 	if (VOP_GETATTR(vp, &vattr, 0, file_cred, NULL) == 0) {
2873 		fdinfo->pr_major = getmajor(vattr.va_fsid);
2874 		fdinfo->pr_minor = getminor(vattr.va_fsid);
2875 		fdinfo->pr_rmajor = getmajor(vattr.va_rdev);
2876 		fdinfo->pr_rminor = getminor(vattr.va_rdev);
2877 		fdinfo->pr_ino = (ino64_t)vattr.va_nodeid;
2878 		fdinfo->pr_size = (off64_t)vattr.va_size;
2879 		fdinfo->pr_mode = VTTOIF(vattr.va_type) | vattr.va_mode;
2880 		fdinfo->pr_uid = vattr.va_uid;
2881 		fdinfo->pr_gid = vattr.va_gid;
2882 		if (vp->v_type == VSOCK)
2883 			fdinfo->pr_fileflags |= sock_getfasync(vp);
2884 	}
2885 
2886 	/* locks */
2887 
2888 	flock64_t bf;
2889 
2890 	bzero(&bf, sizeof (bf));
2891 	bf.l_type = F_WRLCK;
2892 
2893 	if (VOP_FRLOCK(vp, F_GETLK, &bf,
2894 	    (uint16_t)(fdinfo->pr_fileflags & 0xffff), 0, NULL,
2895 	    cred, NULL) == 0 && bf.l_type != F_UNLCK) {
2896 		fdinfo->pr_locktype = bf.l_type;
2897 		fdinfo->pr_lockpid = bf.l_pid;
2898 		fdinfo->pr_locksysid = bf.l_sysid;
2899 	}
2900 
2901 	/* peer cred */
2902 
2903 	k_peercred_t kpc;
2904 
2905 	switch (vp->v_type) {
2906 	case VFIFO:
2907 	case VSOCK: {
2908 		int32_t rval;
2909 
2910 		error = VOP_IOCTL(vp, _I_GETPEERCRED, (intptr_t)&kpc,
2911 		    FKIOCTL, cred, &rval, NULL);
2912 		break;
2913 	}
2914 	case VCHR: {
2915 		struct strioctl strioc;
2916 		int32_t rval;
2917 
2918 		if (vp->v_stream == NULL) {
2919 			error = ENOTSUP;
2920 			break;
2921 		}
2922 		strioc.ic_cmd = _I_GETPEERCRED;
2923 		strioc.ic_timout = INFTIM;
2924 		strioc.ic_len = (int)sizeof (k_peercred_t);
2925 		strioc.ic_dp = (char *)&kpc;
2926 
2927 		error = strdoioctl(vp->v_stream, &strioc, FNATIVE | FKIOCTL,
2928 		    STR_NOSIG | K_TO_K, cred, &rval);
2929 		break;
2930 	}
2931 	default:
2932 		error = ENOTSUP;
2933 		break;
2934 	}
2935 
2936 	if (error == 0 && kpc.pc_cr != NULL) {
2937 		proc_t *peerp;
2938 
2939 		fdinfo->pr_peerpid = kpc.pc_cpid;
2940 
2941 		crfree(kpc.pc_cr);
2942 
2943 		mutex_enter(&pidlock);
2944 		if ((peerp = prfind(fdinfo->pr_peerpid)) != NULL) {
2945 			user_t *up;
2946 
2947 			mutex_enter(&peerp->p_lock);
2948 			mutex_exit(&pidlock);
2949 
2950 			up = PTOU(peerp);
2951 			bcopy(up->u_comm, fdinfo->pr_peername,
2952 			    MIN(sizeof (up->u_comm),
2953 			    sizeof (fdinfo->pr_peername) - 1));
2954 
2955 			mutex_exit(&peerp->p_lock);
2956 		} else {
2957 			mutex_exit(&pidlock);
2958 		}
2959 	}
2960 
2961 	/* pathname */
2962 
2963 	switch (vp->v_type) {
2964 	case VDOOR: {
2965 		prfdinfo_nm_path_cbdata_t cb = {
2966 			.nmp_p		= p,
2967 			.nmp_data	= data,
2968 			.nmp_sz		= 0
2969 		};
2970 
2971 		(void) nm_walk_mounts(vp, prfdinfo_nm_path, cred, &cb);
2972 		break;
2973 	}
2974 	case VSOCK:
2975 		/*
2976 		 * Don't attempt to determine the path for a socket as the
2977 		 * vnode has no associated v_path. It will cause a linear scan
2978 		 * of the dnlc table and result in no path being found.
2979 		 */
2980 		break;
2981 	default:
2982 		(void) prfdinfopath(p, vp, data, cred);
2983 	}
2984 
2985 	/* socket options */
2986 	if (vp->v_type == VSOCK)
2987 		(void) prfdinfosockopt(vp, data, cred);
2988 
2989 	/* TLI/XTI stream sockets */
2990 	if (pristli(vp))
2991 		(void) prfdinfotlisockopt(vp, data, cred);
2992 
2993 	/*
2994 	 * Add a terminating header with a zero size.
2995 	 */
2996 	pr_misc_header_t *misc;
2997 
2998 	misc = pr_iol_newbuf(data, sizeof (*misc));
2999 	misc->pr_misc_size = 0;
3000 	misc->pr_misc_type = (uint_t)-1;
3001 
3002 	return (0);
3003 }
3004 
3005 #ifdef _SYSCALL32_IMPL
3006 void
3007 prgetpsinfo32(proc_t *p, psinfo32_t *psp)
3008 {
3009 	kthread_t *t;
3010 	struct cred *cred;
3011 	hrtime_t hrutime, hrstime;
3012 
3013 	ASSERT(MUTEX_HELD(&p->p_lock));
3014 
3015 	if ((t = prchoose(p)) == NULL)	/* returns locked thread */
3016 		bzero(psp, sizeof (*psp));
3017 	else {
3018 		thread_unlock(t);
3019 		bzero(psp, sizeof (*psp) - sizeof (psp->pr_lwp));
3020 	}
3021 
3022 	/*
3023 	 * only export SSYS and SMSACCT; everything else is off-limits to
3024 	 * userland apps.
3025 	 */
3026 	psp->pr_flag = p->p_flag & (SSYS | SMSACCT);
3027 	psp->pr_nlwp = p->p_lwpcnt;
3028 	psp->pr_nzomb = p->p_zombcnt;
3029 	mutex_enter(&p->p_crlock);
3030 	cred = p->p_cred;
3031 	psp->pr_uid = crgetruid(cred);
3032 	psp->pr_euid = crgetuid(cred);
3033 	psp->pr_gid = crgetrgid(cred);
3034 	psp->pr_egid = crgetgid(cred);
3035 	mutex_exit(&p->p_crlock);
3036 	psp->pr_pid = p->p_pid;
3037 	if (curproc->p_zone->zone_id != GLOBAL_ZONEID &&
3038 	    (p->p_flag & SZONETOP)) {
3039 		ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID);
3040 		/*
3041 		 * Inside local zones, fake zsched's pid as parent pids for
3042 		 * processes which reference processes outside of the zone.
3043 		 */
3044 		psp->pr_ppid = curproc->p_zone->zone_zsched->p_pid;
3045 	} else {
3046 		psp->pr_ppid = p->p_ppid;
3047 	}
3048 	psp->pr_pgid = p->p_pgrp;
3049 	psp->pr_sid = p->p_sessp->s_sid;
3050 	psp->pr_taskid = p->p_task->tk_tkid;
3051 	psp->pr_projid = p->p_task->tk_proj->kpj_id;
3052 	psp->pr_poolid = p->p_pool->pool_id;
3053 	psp->pr_zoneid = p->p_zone->zone_id;
3054 	if ((psp->pr_contract = PRCTID(p)) == 0)
3055 		psp->pr_contract = -1;
3056 	psp->pr_addr = 0;	/* cannot represent 64-bit addr in 32 bits */
3057 	switch (p->p_model) {
3058 	case DATAMODEL_ILP32:
3059 		psp->pr_dmodel = PR_MODEL_ILP32;
3060 		break;
3061 	case DATAMODEL_LP64:
3062 		psp->pr_dmodel = PR_MODEL_LP64;
3063 		break;
3064 	}
3065 	hrutime = mstate_aggr_state(p, LMS_USER);
3066 	hrstime = mstate_aggr_state(p, LMS_SYSTEM);
3067 	hrt2ts32(hrutime + hrstime, &psp->pr_time);
3068 	TICK_TO_TIMESTRUC32(p->p_cutime + p->p_cstime, &psp->pr_ctime);
3069 
3070 	if (t == NULL) {
3071 		extern int wstat(int, int);	/* needs a header file */
3072 		int wcode = p->p_wcode;		/* must be atomic read */
3073 
3074 		if (wcode)
3075 			psp->pr_wstat = wstat(wcode, p->p_wdata);
3076 		psp->pr_ttydev = PRNODEV32;
3077 		psp->pr_lwp.pr_state = SZOMB;
3078 		psp->pr_lwp.pr_sname = 'Z';
3079 	} else {
3080 		user_t *up = PTOU(p);
3081 		struct as *as;
3082 		dev_t d;
3083 		extern dev_t rwsconsdev, rconsdev, uconsdev;
3084 
3085 		d = cttydev(p);
3086 		/*
3087 		 * If the controlling terminal is the real
3088 		 * or workstation console device, map to what the
3089 		 * user thinks is the console device. Handle case when
3090 		 * rwsconsdev or rconsdev is set to NODEV for Starfire.
3091 		 */
3092 		if ((d == rwsconsdev || d == rconsdev) && d != NODEV)
3093 			d = uconsdev;
3094 		(void) cmpldev(&psp->pr_ttydev, d);
3095 		TIMESPEC_TO_TIMESPEC32(&psp->pr_start, &up->u_start);
3096 		bcopy(up->u_comm, psp->pr_fname,
3097 		    MIN(sizeof (up->u_comm), sizeof (psp->pr_fname)-1));
3098 		bcopy(up->u_psargs, psp->pr_psargs,
3099 		    MIN(PRARGSZ-1, PSARGSZ));
3100 		psp->pr_argc = up->u_argc;
3101 		psp->pr_argv = (caddr32_t)up->u_argv;
3102 		psp->pr_envp = (caddr32_t)up->u_envp;
3103 
3104 		/* get the chosen lwp's lwpsinfo */
3105 		prgetlwpsinfo32(t, &psp->pr_lwp);
3106 
3107 		/* compute %cpu for the process */
3108 		if (p->p_lwpcnt == 1)
3109 			psp->pr_pctcpu = psp->pr_lwp.pr_pctcpu;
3110 		else {
3111 			uint64_t pct = 0;
3112 			hrtime_t cur_time;
3113 
3114 			t = p->p_tlist;
3115 			cur_time = gethrtime_unscaled();
3116 			do {
3117 				pct += cpu_update_pct(t, cur_time);
3118 			} while ((t = t->t_forw) != p->p_tlist);
3119 
3120 			psp->pr_pctcpu = prgetpctcpu(pct);
3121 		}
3122 		if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
3123 			psp->pr_size = 0;
3124 			psp->pr_rssize = 0;
3125 		} else {
3126 			mutex_exit(&p->p_lock);
3127 			AS_LOCK_ENTER(as, RW_READER);
3128 			psp->pr_size = (size32_t)
3129 			    (btopr(as->a_resvsize) * (PAGESIZE / 1024));
3130 			psp->pr_rssize = (size32_t)
3131 			    (rm_asrss(as) * (PAGESIZE / 1024));
3132 			psp->pr_pctmem = rm_pctmemory(as);
3133 			AS_LOCK_EXIT(as);
3134 			mutex_enter(&p->p_lock);
3135 		}
3136 	}
3137 
3138 	/*
3139 	 * If we are looking at an LP64 process, zero out
3140 	 * the fields that cannot be represented in ILP32.
3141 	 */
3142 	if (p->p_model != DATAMODEL_ILP32) {
3143 		psp->pr_size = 0;
3144 		psp->pr_rssize = 0;
3145 		psp->pr_argv = 0;
3146 		psp->pr_envp = 0;
3147 	}
3148 }
3149 
3150 #endif	/* _SYSCALL32_IMPL */
3151 
3152 void
3153 prgetlwpsinfo(kthread_t *t, lwpsinfo_t *psp)
3154 {
3155 	klwp_t *lwp = ttolwp(t);
3156 	sobj_ops_t *sobj;
3157 	char c, state;
3158 	uint64_t pct;
3159 	int retval, niceval;
3160 	hrtime_t hrutime, hrstime;
3161 
3162 	ASSERT(MUTEX_HELD(&ttoproc(t)->p_lock));
3163 
3164 	bzero(psp, sizeof (*psp));
3165 
3166 	psp->pr_flag = 0;	/* lwpsinfo_t.pr_flag is deprecated */
3167 	psp->pr_lwpid = t->t_tid;
3168 	psp->pr_addr = (uintptr_t)t;
3169 	psp->pr_wchan = (uintptr_t)t->t_wchan;
3170 
3171 	/* map the thread state enum into a process state enum */
3172 	state = VSTOPPED(t) ? TS_STOPPED : t->t_state;
3173 	switch (state) {
3174 	case TS_SLEEP:		state = SSLEEP;		c = 'S';	break;
3175 	case TS_RUN:		state = SRUN;		c = 'R';	break;
3176 	case TS_ONPROC:		state = SONPROC;	c = 'O';	break;
3177 	case TS_ZOMB:		state = SZOMB;		c = 'Z';	break;
3178 	case TS_STOPPED:	state = SSTOP;		c = 'T';	break;
3179 	case TS_WAIT:		state = SWAIT;		c = 'W';	break;
3180 	default:		state = 0;		c = '?';	break;
3181 	}
3182 	psp->pr_state = state;
3183 	psp->pr_sname = c;
3184 	if ((sobj = t->t_sobj_ops) != NULL)
3185 		psp->pr_stype = SOBJ_TYPE(sobj);
3186 	retval = CL_DONICE(t, NULL, 0, &niceval);
3187 	if (retval == 0) {
3188 		psp->pr_oldpri = v.v_maxsyspri - t->t_pri;
3189 		psp->pr_nice = niceval + NZERO;
3190 	}
3191 	psp->pr_syscall = t->t_sysnum;
3192 	psp->pr_pri = t->t_pri;
3193 	psp->pr_start.tv_sec = t->t_start;
3194 	psp->pr_start.tv_nsec = 0L;
3195 	hrutime = lwp->lwp_mstate.ms_acct[LMS_USER];
3196 	scalehrtime(&hrutime);
3197 	hrstime = lwp->lwp_mstate.ms_acct[LMS_SYSTEM] +
3198 	    lwp->lwp_mstate.ms_acct[LMS_TRAP];
3199 	scalehrtime(&hrstime);
3200 	hrt2ts(hrutime + hrstime, &psp->pr_time);
3201 	/* compute %cpu for the lwp */
3202 	pct = cpu_update_pct(t, gethrtime_unscaled());
3203 	psp->pr_pctcpu = prgetpctcpu(pct);
3204 	psp->pr_cpu = (psp->pr_pctcpu*100 + 0x6000) >> 15;	/* [0..99] */
3205 	if (psp->pr_cpu > 99)
3206 		psp->pr_cpu = 99;
3207 
3208 	(void) strncpy(psp->pr_clname, sclass[t->t_cid].cl_name,
3209 	    sizeof (psp->pr_clname) - 1);
3210 	bzero(psp->pr_name, sizeof (psp->pr_name));	/* XXX ??? */
3211 	psp->pr_onpro = t->t_cpu->cpu_id;
3212 	psp->pr_bindpro = t->t_bind_cpu;
3213 	psp->pr_bindpset = t->t_bind_pset;
3214 	psp->pr_lgrp = t->t_lpl->lpl_lgrpid;
3215 }
3216 
3217 #ifdef _SYSCALL32_IMPL
3218 void
3219 prgetlwpsinfo32(kthread_t *t, lwpsinfo32_t *psp)
3220 {
3221 	klwp_t *lwp = ttolwp(t);
3222 	sobj_ops_t *sobj;
3223 	char c, state;
3224 	uint64_t pct;
3225 	int retval, niceval;
3226 	hrtime_t hrutime, hrstime;
3227 
3228 	ASSERT(MUTEX_HELD(&ttoproc(t)->p_lock));
3229 
3230 	bzero(psp, sizeof (*psp));
3231 
3232 	psp->pr_flag = 0;	/* lwpsinfo_t.pr_flag is deprecated */
3233 	psp->pr_lwpid = t->t_tid;
3234 	psp->pr_addr = 0;	/* cannot represent 64-bit addr in 32 bits */
3235 	psp->pr_wchan = 0;	/* cannot represent 64-bit addr in 32 bits */
3236 
3237 	/* map the thread state enum into a process state enum */
3238 	state = VSTOPPED(t) ? TS_STOPPED : t->t_state;
3239 	switch (state) {
3240 	case TS_SLEEP:		state = SSLEEP;		c = 'S';	break;
3241 	case TS_RUN:		state = SRUN;		c = 'R';	break;
3242 	case TS_ONPROC:		state = SONPROC;	c = 'O';	break;
3243 	case TS_ZOMB:		state = SZOMB;		c = 'Z';	break;
3244 	case TS_STOPPED:	state = SSTOP;		c = 'T';	break;
3245 	case TS_WAIT:		state = SWAIT;		c = 'W';	break;
3246 	default:		state = 0;		c = '?';	break;
3247 	}
3248 	psp->pr_state = state;
3249 	psp->pr_sname = c;
3250 	if ((sobj = t->t_sobj_ops) != NULL)
3251 		psp->pr_stype = SOBJ_TYPE(sobj);
3252 	retval = CL_DONICE(t, NULL, 0, &niceval);
3253 	if (retval == 0) {
3254 		psp->pr_oldpri = v.v_maxsyspri - t->t_pri;
3255 		psp->pr_nice = niceval + NZERO;
3256 	} else {
3257 		psp->pr_oldpri = 0;
3258 		psp->pr_nice = 0;
3259 	}
3260 	psp->pr_syscall = t->t_sysnum;
3261 	psp->pr_pri = t->t_pri;
3262 	psp->pr_start.tv_sec = (time32_t)t->t_start;
3263 	psp->pr_start.tv_nsec = 0L;
3264 	hrutime = lwp->lwp_mstate.ms_acct[LMS_USER];
3265 	scalehrtime(&hrutime);
3266 	hrstime = lwp->lwp_mstate.ms_acct[LMS_SYSTEM] +
3267 	    lwp->lwp_mstate.ms_acct[LMS_TRAP];
3268 	scalehrtime(&hrstime);
3269 	hrt2ts32(hrutime + hrstime, &psp->pr_time);
3270 	/* compute %cpu for the lwp */
3271 	pct = cpu_update_pct(t, gethrtime_unscaled());
3272 	psp->pr_pctcpu = prgetpctcpu(pct);
3273 	psp->pr_cpu = (psp->pr_pctcpu*100 + 0x6000) >> 15;	/* [0..99] */
3274 	if (psp->pr_cpu > 99)
3275 		psp->pr_cpu = 99;
3276 
3277 	(void) strncpy(psp->pr_clname, sclass[t->t_cid].cl_name,
3278 	    sizeof (psp->pr_clname) - 1);
3279 	bzero(psp->pr_name, sizeof (psp->pr_name));	/* XXX ??? */
3280 	psp->pr_onpro = t->t_cpu->cpu_id;
3281 	psp->pr_bindpro = t->t_bind_cpu;
3282 	psp->pr_bindpset = t->t_bind_pset;
3283 	psp->pr_lgrp = t->t_lpl->lpl_lgrpid;
3284 }
3285 #endif	/* _SYSCALL32_IMPL */
3286 
3287 #ifdef _SYSCALL32_IMPL
3288 
3289 #define	PR_COPY_FIELD(s, d, field)	 d->field = s->field
3290 
3291 #define	PR_COPY_FIELD_ILP32(s, d, field)				\
3292 	if (s->pr_dmodel == PR_MODEL_ILP32) {			\
3293 		d->field = s->field;				\
3294 	}
3295 
3296 #define	PR_COPY_TIMESPEC(s, d, field)				\
3297 	TIMESPEC_TO_TIMESPEC32(&d->field, &s->field);
3298 
3299 #define	PR_COPY_BUF(s, d, field)				\
3300 	bcopy(s->field, d->field, sizeof (d->field));
3301 
3302 #define	PR_IGNORE_FIELD(s, d, field)
3303 
3304 void
3305 lwpsinfo_kto32(const struct lwpsinfo *src, struct lwpsinfo32 *dest)
3306 {
3307 	bzero(dest, sizeof (*dest));
3308 
3309 	PR_COPY_FIELD(src, dest, pr_flag);
3310 	PR_COPY_FIELD(src, dest, pr_lwpid);
3311 	PR_IGNORE_FIELD(src, dest, pr_addr);
3312 	PR_IGNORE_FIELD(src, dest, pr_wchan);
3313 	PR_COPY_FIELD(src, dest, pr_stype);
3314 	PR_COPY_FIELD(src, dest, pr_state);
3315 	PR_COPY_FIELD(src, dest, pr_sname);
3316 	PR_COPY_FIELD(src, dest, pr_nice);
3317 	PR_COPY_FIELD(src, dest, pr_syscall);
3318 	PR_COPY_FIELD(src, dest, pr_oldpri);
3319 	PR_COPY_FIELD(src, dest, pr_cpu);
3320 	PR_COPY_FIELD(src, dest, pr_pri);
3321 	PR_COPY_FIELD(src, dest, pr_pctcpu);
3322 	PR_COPY_TIMESPEC(src, dest, pr_start);
3323 	PR_COPY_BUF(src, dest, pr_clname);
3324 	PR_COPY_BUF(src, dest, pr_name);
3325 	PR_COPY_FIELD(src, dest, pr_onpro);
3326 	PR_COPY_FIELD(src, dest, pr_bindpro);
3327 	PR_COPY_FIELD(src, dest, pr_bindpset);
3328 	PR_COPY_FIELD(src, dest, pr_lgrp);
3329 }
3330 
3331 void
3332 psinfo_kto32(const struct psinfo *src, struct psinfo32 *dest)
3333 {
3334 	bzero(dest, sizeof (*dest));
3335 
3336 	PR_COPY_FIELD(src, dest, pr_flag);
3337 	PR_COPY_FIELD(src, dest, pr_nlwp);
3338 	PR_COPY_FIELD(src, dest, pr_pid);
3339 	PR_COPY_FIELD(src, dest, pr_ppid);
3340 	PR_COPY_FIELD(src, dest, pr_pgid);
3341 	PR_COPY_FIELD(src, dest, pr_sid);
3342 	PR_COPY_FIELD(src, dest, pr_uid);
3343 	PR_COPY_FIELD(src, dest, pr_euid);
3344 	PR_COPY_FIELD(src, dest, pr_gid);
3345 	PR_COPY_FIELD(src, dest, pr_egid);
3346 	PR_IGNORE_FIELD(src, dest, pr_addr);
3347 	PR_COPY_FIELD_ILP32(src, dest, pr_size);
3348 	PR_COPY_FIELD_ILP32(src, dest, pr_rssize);
3349 	PR_COPY_FIELD(src, dest, pr_ttydev);
3350 	PR_COPY_FIELD(src, dest, pr_pctcpu);
3351 	PR_COPY_FIELD(src, dest, pr_pctmem);
3352 	PR_COPY_TIMESPEC(src, dest, pr_start);
3353 	PR_COPY_TIMESPEC(src, dest, pr_time);
3354 	PR_COPY_TIMESPEC(src, dest, pr_ctime);
3355 	PR_COPY_BUF(src, dest, pr_fname);
3356 	PR_COPY_BUF(src, dest, pr_psargs);
3357 	PR_COPY_FIELD(src, dest, pr_wstat);
3358 	PR_COPY_FIELD(src, dest, pr_argc);
3359 	PR_COPY_FIELD_ILP32(src, dest, pr_argv);
3360 	PR_COPY_FIELD_ILP32(src, dest, pr_envp);
3361 	PR_COPY_FIELD(src, dest, pr_dmodel);
3362 	PR_COPY_FIELD(src, dest, pr_taskid);
3363 	PR_COPY_FIELD(src, dest, pr_projid);
3364 	PR_COPY_FIELD(src, dest, pr_nzomb);
3365 	PR_COPY_FIELD(src, dest, pr_poolid);
3366 	PR_COPY_FIELD(src, dest, pr_contract);
3367 	PR_COPY_FIELD(src, dest, pr_poolid);
3368 	PR_COPY_FIELD(src, dest, pr_poolid);
3369 
3370 	lwpsinfo_kto32(&src->pr_lwp, &dest->pr_lwp);
3371 }
3372 
3373 #undef	PR_COPY_FIELD
3374 #undef	PR_COPY_FIELD_ILP32
3375 #undef	PR_COPY_TIMESPEC
3376 #undef	PR_COPY_BUF
3377 #undef	PR_IGNORE_FIELD
3378 
3379 #endif	/* _SYSCALL32_IMPL */
3380 
3381 /*
3382  * This used to get called when microstate accounting was disabled but
3383  * microstate information was requested.  Since Microstate accounting is on
3384  * regardless of the proc flags, this simply makes it appear to procfs that
3385  * microstate accounting is on.  This is relatively meaningless since you
3386  * can't turn it off, but this is here for the sake of appearances.
3387  */
3388 
3389 /*ARGSUSED*/
3390 void
3391 estimate_msacct(kthread_t *t, hrtime_t curtime)
3392 {
3393 	proc_t *p;
3394 
3395 	if (t == NULL)
3396 		return;
3397 
3398 	p = ttoproc(t);
3399 	ASSERT(MUTEX_HELD(&p->p_lock));
3400 
3401 	/*
3402 	 * A system process (p0) could be referenced if the thread is
3403 	 * in the process of exiting.  Don't turn on microstate accounting
3404 	 * in that case.
3405 	 */
3406 	if (p->p_flag & SSYS)
3407 		return;
3408 
3409 	/*
3410 	 * Loop through all the LWPs (kernel threads) in the process.
3411 	 */
3412 	t = p->p_tlist;
3413 	do {
3414 		t->t_proc_flag |= TP_MSACCT;
3415 	} while ((t = t->t_forw) != p->p_tlist);
3416 
3417 	p->p_flag |= SMSACCT;			/* set process-wide MSACCT */
3418 }
3419 
3420 /*
3421  * It's not really possible to disable microstate accounting anymore.
3422  * However, this routine simply turns off the ms accounting flags in a process
3423  * This way procfs can still pretend to turn microstate accounting on and
3424  * off for a process, but it actually doesn't do anything.  This is
3425  * a neutered form of preemptive idiot-proofing.
3426  */
3427 void
3428 disable_msacct(proc_t *p)
3429 {
3430 	kthread_t *t;
3431 
3432 	ASSERT(MUTEX_HELD(&p->p_lock));
3433 
3434 	p->p_flag &= ~SMSACCT;		/* clear process-wide MSACCT */
3435 	/*
3436 	 * Loop through all the LWPs (kernel threads) in the process.
3437 	 */
3438 	if ((t = p->p_tlist) != NULL) {
3439 		do {
3440 			/* clear per-thread flag */
3441 			t->t_proc_flag &= ~TP_MSACCT;
3442 		} while ((t = t->t_forw) != p->p_tlist);
3443 	}
3444 }
3445 
3446 /*
3447  * Return resource usage information.
3448  */
3449 void
3450 prgetusage(kthread_t *t, prhusage_t *pup)
3451 {
3452 	klwp_t *lwp = ttolwp(t);
3453 	hrtime_t *mstimep;
3454 	struct mstate *ms = &lwp->lwp_mstate;
3455 	int state;
3456 	int i;
3457 	hrtime_t curtime;
3458 	hrtime_t waitrq;
3459 	hrtime_t tmp1;
3460 
3461 	curtime = gethrtime_unscaled();
3462 
3463 	pup->pr_lwpid	= t->t_tid;
3464 	pup->pr_count	= 1;
3465 	pup->pr_create	= ms->ms_start;
3466 	pup->pr_term    = ms->ms_term;
3467 	scalehrtime(&pup->pr_create);
3468 	scalehrtime(&pup->pr_term);
3469 	if (ms->ms_term == 0) {
3470 		pup->pr_rtime = curtime - ms->ms_start;
3471 		scalehrtime(&pup->pr_rtime);
3472 	} else {
3473 		pup->pr_rtime = ms->ms_term - ms->ms_start;
3474 		scalehrtime(&pup->pr_rtime);
3475 	}
3476 
3477 
3478 	pup->pr_utime    = ms->ms_acct[LMS_USER];
3479 	pup->pr_stime    = ms->ms_acct[LMS_SYSTEM];
3480 	pup->pr_ttime    = ms->ms_acct[LMS_TRAP];
3481 	pup->pr_tftime   = ms->ms_acct[LMS_TFAULT];
3482 	pup->pr_dftime   = ms->ms_acct[LMS_DFAULT];
3483 	pup->pr_kftime   = ms->ms_acct[LMS_KFAULT];
3484 	pup->pr_ltime    = ms->ms_acct[LMS_USER_LOCK];
3485 	pup->pr_slptime  = ms->ms_acct[LMS_SLEEP];
3486 	pup->pr_wtime    = ms->ms_acct[LMS_WAIT_CPU];
3487 	pup->pr_stoptime = ms->ms_acct[LMS_STOPPED];
3488 
3489 	prscaleusage(pup);
3490 
3491 	/*
3492 	 * Adjust for time waiting in the dispatcher queue.
3493 	 */
3494 	waitrq = t->t_waitrq;	/* hopefully atomic */
3495 	if (waitrq != 0) {
3496 		if (waitrq > curtime) {
3497 			curtime = gethrtime_unscaled();
3498 		}
3499 		tmp1 = curtime - waitrq;
3500 		scalehrtime(&tmp1);
3501 		pup->pr_wtime += tmp1;
3502 		curtime = waitrq;
3503 	}
3504 
3505 	/*
3506 	 * Adjust for time spent in current microstate.
3507 	 */
3508 	if (ms->ms_state_start > curtime) {
3509 		curtime = gethrtime_unscaled();
3510 	}
3511 
3512 	i = 0;
3513 	do {
3514 		switch (state = t->t_mstate) {
3515 		case LMS_SLEEP:
3516 			/*
3517 			 * Update the timer for the current sleep state.
3518 			 */
3519 			switch (state = ms->ms_prev) {
3520 			case LMS_TFAULT:
3521 			case LMS_DFAULT:
3522 			case LMS_KFAULT:
3523 			case LMS_USER_LOCK:
3524 				break;
3525 			default:
3526 				state = LMS_SLEEP;
3527 				break;
3528 			}
3529 			break;
3530 		case LMS_TFAULT:
3531 		case LMS_DFAULT:
3532 		case LMS_KFAULT:
3533 		case LMS_USER_LOCK:
3534 			state = LMS_SYSTEM;
3535 			break;
3536 		}
3537 		switch (state) {
3538 		case LMS_USER:		mstimep = &pup->pr_utime;	break;
3539 		case LMS_SYSTEM:	mstimep = &pup->pr_stime;	break;
3540 		case LMS_TRAP:		mstimep = &pup->pr_ttime;	break;
3541 		case LMS_TFAULT:	mstimep = &pup->pr_tftime;	break;
3542 		case LMS_DFAULT:	mstimep = &pup->pr_dftime;	break;
3543 		case LMS_KFAULT:	mstimep = &pup->pr_kftime;	break;
3544 		case LMS_USER_LOCK:	mstimep = &pup->pr_ltime;	break;
3545 		case LMS_SLEEP:		mstimep = &pup->pr_slptime;	break;
3546 		case LMS_WAIT_CPU:	mstimep = &pup->pr_wtime;	break;
3547 		case LMS_STOPPED:	mstimep = &pup->pr_stoptime;	break;
3548 		default:		panic("prgetusage: unknown microstate");
3549 		}
3550 		tmp1 = curtime - ms->ms_state_start;
3551 		if (tmp1 < 0) {
3552 			curtime = gethrtime_unscaled();
3553 			i++;
3554 			continue;
3555 		}
3556 		scalehrtime(&tmp1);
3557 	} while (tmp1 < 0 && i < MAX_ITERS_SPIN);
3558 
3559 	*mstimep += tmp1;
3560 
3561 	/* update pup timestamp */
3562 	pup->pr_tstamp = curtime;
3563 	scalehrtime(&pup->pr_tstamp);
3564 
3565 	/*
3566 	 * Resource usage counters.
3567 	 */
3568 	pup->pr_minf  = lwp->lwp_ru.minflt;
3569 	pup->pr_majf  = lwp->lwp_ru.majflt;
3570 	pup->pr_nswap = lwp->lwp_ru.nswap;
3571 	pup->pr_inblk = lwp->lwp_ru.inblock;
3572 	pup->pr_oublk = lwp->lwp_ru.oublock;
3573 	pup->pr_msnd  = lwp->lwp_ru.msgsnd;
3574 	pup->pr_mrcv  = lwp->lwp_ru.msgrcv;
3575 	pup->pr_sigs  = lwp->lwp_ru.nsignals;
3576 	pup->pr_vctx  = lwp->lwp_ru.nvcsw;
3577 	pup->pr_ictx  = lwp->lwp_ru.nivcsw;
3578 	pup->pr_sysc  = lwp->lwp_ru.sysc;
3579 	pup->pr_ioch  = lwp->lwp_ru.ioch;
3580 }
3581 
3582 /*
3583  * Convert ms_acct stats from unscaled high-res time to nanoseconds
3584  */
3585 void
3586 prscaleusage(prhusage_t *usg)
3587 {
3588 	scalehrtime(&usg->pr_utime);
3589 	scalehrtime(&usg->pr_stime);
3590 	scalehrtime(&usg->pr_ttime);
3591 	scalehrtime(&usg->pr_tftime);
3592 	scalehrtime(&usg->pr_dftime);
3593 	scalehrtime(&usg->pr_kftime);
3594 	scalehrtime(&usg->pr_ltime);
3595 	scalehrtime(&usg->pr_slptime);
3596 	scalehrtime(&usg->pr_wtime);
3597 	scalehrtime(&usg->pr_stoptime);
3598 }
3599 
3600 
3601 /*
3602  * Sum resource usage information.
3603  */
3604 void
3605 praddusage(kthread_t *t, prhusage_t *pup)
3606 {
3607 	klwp_t *lwp = ttolwp(t);
3608 	hrtime_t *mstimep;
3609 	struct mstate *ms = &lwp->lwp_mstate;
3610 	int state;
3611 	int i;
3612 	hrtime_t curtime;
3613 	hrtime_t waitrq;
3614 	hrtime_t tmp;
3615 	prhusage_t conv;
3616 
3617 	curtime = gethrtime_unscaled();
3618 
3619 	if (ms->ms_term == 0) {
3620 		tmp = curtime - ms->ms_start;
3621 		scalehrtime(&tmp);
3622 		pup->pr_rtime += tmp;
3623 	} else {
3624 		tmp = ms->ms_term - ms->ms_start;
3625 		scalehrtime(&tmp);
3626 		pup->pr_rtime += tmp;
3627 	}
3628 
3629 	conv.pr_utime = ms->ms_acct[LMS_USER];
3630 	conv.pr_stime = ms->ms_acct[LMS_SYSTEM];
3631 	conv.pr_ttime = ms->ms_acct[LMS_TRAP];
3632 	conv.pr_tftime = ms->ms_acct[LMS_TFAULT];
3633 	conv.pr_dftime = ms->ms_acct[LMS_DFAULT];
3634 	conv.pr_kftime = ms->ms_acct[LMS_KFAULT];
3635 	conv.pr_ltime = ms->ms_acct[LMS_USER_LOCK];
3636 	conv.pr_slptime = ms->ms_acct[LMS_SLEEP];
3637 	conv.pr_wtime = ms->ms_acct[LMS_WAIT_CPU];
3638 	conv.pr_stoptime = ms->ms_acct[LMS_STOPPED];
3639 
3640 	prscaleusage(&conv);
3641 
3642 	pup->pr_utime	+= conv.pr_utime;
3643 	pup->pr_stime	+= conv.pr_stime;
3644 	pup->pr_ttime	+= conv.pr_ttime;
3645 	pup->pr_tftime	+= conv.pr_tftime;
3646 	pup->pr_dftime	+= conv.pr_dftime;
3647 	pup->pr_kftime	+= conv.pr_kftime;
3648 	pup->pr_ltime	+= conv.pr_ltime;
3649 	pup->pr_slptime	+= conv.pr_slptime;
3650 	pup->pr_wtime	+= conv.pr_wtime;
3651 	pup->pr_stoptime += conv.pr_stoptime;
3652 
3653 	/*
3654 	 * Adjust for time waiting in the dispatcher queue.
3655 	 */
3656 	waitrq = t->t_waitrq;	/* hopefully atomic */
3657 	if (waitrq != 0) {
3658 		if (waitrq > curtime) {
3659 			curtime = gethrtime_unscaled();
3660 		}
3661 		tmp = curtime - waitrq;
3662 		scalehrtime(&tmp);
3663 		pup->pr_wtime += tmp;
3664 		curtime = waitrq;
3665 	}
3666 
3667 	/*
3668 	 * Adjust for time spent in current microstate.
3669 	 */
3670 	if (ms->ms_state_start > curtime) {
3671 		curtime = gethrtime_unscaled();
3672 	}
3673 
3674 	i = 0;
3675 	do {
3676 		switch (state = t->t_mstate) {
3677 		case LMS_SLEEP:
3678 			/*
3679 			 * Update the timer for the current sleep state.
3680 			 */
3681 			switch (state = ms->ms_prev) {
3682 			case LMS_TFAULT:
3683 			case LMS_DFAULT:
3684 			case LMS_KFAULT:
3685 			case LMS_USER_LOCK:
3686 				break;
3687 			default:
3688 				state = LMS_SLEEP;
3689 				break;
3690 			}
3691 			break;
3692 		case LMS_TFAULT:
3693 		case LMS_DFAULT:
3694 		case LMS_KFAULT:
3695 		case LMS_USER_LOCK:
3696 			state = LMS_SYSTEM;
3697 			break;
3698 		}
3699 		switch (state) {
3700 		case LMS_USER:		mstimep = &pup->pr_utime;	break;
3701 		case LMS_SYSTEM:	mstimep = &pup->pr_stime;	break;
3702 		case LMS_TRAP:		mstimep = &pup->pr_ttime;	break;
3703 		case LMS_TFAULT:	mstimep = &pup->pr_tftime;	break;
3704 		case LMS_DFAULT:	mstimep = &pup->pr_dftime;	break;
3705 		case LMS_KFAULT:	mstimep = &pup->pr_kftime;	break;
3706 		case LMS_USER_LOCK:	mstimep = &pup->pr_ltime;	break;
3707 		case LMS_SLEEP:		mstimep = &pup->pr_slptime;	break;
3708 		case LMS_WAIT_CPU:	mstimep = &pup->pr_wtime;	break;
3709 		case LMS_STOPPED:	mstimep = &pup->pr_stoptime;	break;
3710 		default:		panic("praddusage: unknown microstate");
3711 		}
3712 		tmp = curtime - ms->ms_state_start;
3713 		if (tmp < 0) {
3714 			curtime = gethrtime_unscaled();
3715 			i++;
3716 			continue;
3717 		}
3718 		scalehrtime(&tmp);
3719 	} while (tmp < 0 && i < MAX_ITERS_SPIN);
3720 
3721 	*mstimep += tmp;
3722 
3723 	/* update pup timestamp */
3724 	pup->pr_tstamp = curtime;
3725 	scalehrtime(&pup->pr_tstamp);
3726 
3727 	/*
3728 	 * Resource usage counters.
3729 	 */
3730 	pup->pr_minf  += lwp->lwp_ru.minflt;
3731 	pup->pr_majf  += lwp->lwp_ru.majflt;
3732 	pup->pr_nswap += lwp->lwp_ru.nswap;
3733 	pup->pr_inblk += lwp->lwp_ru.inblock;
3734 	pup->pr_oublk += lwp->lwp_ru.oublock;
3735 	pup->pr_msnd  += lwp->lwp_ru.msgsnd;
3736 	pup->pr_mrcv  += lwp->lwp_ru.msgrcv;
3737 	pup->pr_sigs  += lwp->lwp_ru.nsignals;
3738 	pup->pr_vctx  += lwp->lwp_ru.nvcsw;
3739 	pup->pr_ictx  += lwp->lwp_ru.nivcsw;
3740 	pup->pr_sysc  += lwp->lwp_ru.sysc;
3741 	pup->pr_ioch  += lwp->lwp_ru.ioch;
3742 }
3743 
3744 /*
3745  * Convert a prhusage_t to a prusage_t.
3746  * This means convert each hrtime_t to a timestruc_t
3747  * and copy the count fields uint64_t => ulong_t.
3748  */
3749 void
3750 prcvtusage(prhusage_t *pup, prusage_t *upup)
3751 {
3752 	uint64_t *ullp;
3753 	ulong_t *ulp;
3754 	int i;
3755 
3756 	upup->pr_lwpid = pup->pr_lwpid;
3757 	upup->pr_count = pup->pr_count;
3758 
3759 	hrt2ts(pup->pr_tstamp,	&upup->pr_tstamp);
3760 	hrt2ts(pup->pr_create,	&upup->pr_create);
3761 	hrt2ts(pup->pr_term,	&upup->pr_term);
3762 	hrt2ts(pup->pr_rtime,	&upup->pr_rtime);
3763 	hrt2ts(pup->pr_utime,	&upup->pr_utime);
3764 	hrt2ts(pup->pr_stime,	&upup->pr_stime);
3765 	hrt2ts(pup->pr_ttime,	&upup->pr_ttime);
3766 	hrt2ts(pup->pr_tftime,	&upup->pr_tftime);
3767 	hrt2ts(pup->pr_dftime,	&upup->pr_dftime);
3768 	hrt2ts(pup->pr_kftime,	&upup->pr_kftime);
3769 	hrt2ts(pup->pr_ltime,	&upup->pr_ltime);
3770 	hrt2ts(pup->pr_slptime,	&upup->pr_slptime);
3771 	hrt2ts(pup->pr_wtime,	&upup->pr_wtime);
3772 	hrt2ts(pup->pr_stoptime, &upup->pr_stoptime);
3773 	bzero(upup->filltime, sizeof (upup->filltime));
3774 
3775 	ullp = &pup->pr_minf;
3776 	ulp = &upup->pr_minf;
3777 	for (i = 0; i < 22; i++)
3778 		*ulp++ = (ulong_t)*ullp++;
3779 }
3780 
3781 #ifdef _SYSCALL32_IMPL
3782 void
3783 prcvtusage32(prhusage_t *pup, prusage32_t *upup)
3784 {
3785 	uint64_t *ullp;
3786 	uint32_t *ulp;
3787 	int i;
3788 
3789 	upup->pr_lwpid = pup->pr_lwpid;
3790 	upup->pr_count = pup->pr_count;
3791 
3792 	hrt2ts32(pup->pr_tstamp,	&upup->pr_tstamp);
3793 	hrt2ts32(pup->pr_create,	&upup->pr_create);
3794 	hrt2ts32(pup->pr_term,		&upup->pr_term);
3795 	hrt2ts32(pup->pr_rtime,		&upup->pr_rtime);
3796 	hrt2ts32(pup->pr_utime,		&upup->pr_utime);
3797 	hrt2ts32(pup->pr_stime,		&upup->pr_stime);
3798 	hrt2ts32(pup->pr_ttime,		&upup->pr_ttime);
3799 	hrt2ts32(pup->pr_tftime,	&upup->pr_tftime);
3800 	hrt2ts32(pup->pr_dftime,	&upup->pr_dftime);
3801 	hrt2ts32(pup->pr_kftime,	&upup->pr_kftime);
3802 	hrt2ts32(pup->pr_ltime,		&upup->pr_ltime);
3803 	hrt2ts32(pup->pr_slptime,	&upup->pr_slptime);
3804 	hrt2ts32(pup->pr_wtime,		&upup->pr_wtime);
3805 	hrt2ts32(pup->pr_stoptime,	&upup->pr_stoptime);
3806 	bzero(upup->filltime, sizeof (upup->filltime));
3807 
3808 	ullp = &pup->pr_minf;
3809 	ulp = &upup->pr_minf;
3810 	for (i = 0; i < 22; i++)
3811 		*ulp++ = (uint32_t)*ullp++;
3812 }
3813 #endif	/* _SYSCALL32_IMPL */
3814 
3815 /*
3816  * Determine whether a set is empty.
3817  */
3818 int
3819 setisempty(uint32_t *sp, uint_t n)
3820 {
3821 	while (n--)
3822 		if (*sp++)
3823 			return (0);
3824 	return (1);
3825 }
3826 
3827 /*
3828  * Utility routine for establishing a watched area in the process.
3829  * Keep the list of watched areas sorted by virtual address.
3830  */
3831 int
3832 set_watched_area(proc_t *p, struct watched_area *pwa)
3833 {
3834 	caddr_t vaddr = pwa->wa_vaddr;
3835 	caddr_t eaddr = pwa->wa_eaddr;
3836 	ulong_t flags = pwa->wa_flags;
3837 	struct watched_area *target;
3838 	avl_index_t where;
3839 	int error = 0;
3840 
3841 	/* we must not be holding p->p_lock, but the process must be locked */
3842 	ASSERT(MUTEX_NOT_HELD(&p->p_lock));
3843 	ASSERT(p->p_proc_flag & P_PR_LOCK);
3844 
3845 	/*
3846 	 * If this is our first watchpoint, enable watchpoints for the process.
3847 	 */
3848 	if (!pr_watch_active(p)) {
3849 		kthread_t *t;
3850 
3851 		mutex_enter(&p->p_lock);
3852 		if ((t = p->p_tlist) != NULL) {
3853 			do {
3854 				watch_enable(t);
3855 			} while ((t = t->t_forw) != p->p_tlist);
3856 		}
3857 		mutex_exit(&p->p_lock);
3858 	}
3859 
3860 	target = pr_find_watched_area(p, pwa, &where);
3861 	if (target != NULL) {
3862 		/*
3863 		 * We discovered an existing, overlapping watched area.
3864 		 * Allow it only if it is an exact match.
3865 		 */
3866 		if (target->wa_vaddr != vaddr ||
3867 		    target->wa_eaddr != eaddr)
3868 			error = EINVAL;
3869 		else if (target->wa_flags != flags) {
3870 			error = set_watched_page(p, vaddr, eaddr,
3871 			    flags, target->wa_flags);
3872 			target->wa_flags = flags;
3873 		}
3874 		kmem_free(pwa, sizeof (struct watched_area));
3875 	} else {
3876 		avl_insert(&p->p_warea, pwa, where);
3877 		error = set_watched_page(p, vaddr, eaddr, flags, 0);
3878 	}
3879 
3880 	return (error);
3881 }
3882 
3883 /*
3884  * Utility routine for clearing a watched area in the process.
3885  * Must be an exact match of the virtual address.
3886  * size and flags don't matter.
3887  */
3888 int
3889 clear_watched_area(proc_t *p, struct watched_area *pwa)
3890 {
3891 	struct watched_area *found;
3892 
3893 	/* we must not be holding p->p_lock, but the process must be locked */
3894 	ASSERT(MUTEX_NOT_HELD(&p->p_lock));
3895 	ASSERT(p->p_proc_flag & P_PR_LOCK);
3896 
3897 
3898 	if (!pr_watch_active(p)) {
3899 		kmem_free(pwa, sizeof (struct watched_area));
3900 		return (0);
3901 	}
3902 
3903 	/*
3904 	 * Look for a matching address in the watched areas.  If a match is
3905 	 * found, clear the old watched area and adjust the watched page(s).  It
3906 	 * is not an error if there is no match.
3907 	 */
3908 	if ((found = pr_find_watched_area(p, pwa, NULL)) != NULL &&
3909 	    found->wa_vaddr == pwa->wa_vaddr) {
3910 		clear_watched_page(p, found->wa_vaddr, found->wa_eaddr,
3911 		    found->wa_flags);
3912 		avl_remove(&p->p_warea, found);
3913 		kmem_free(found, sizeof (struct watched_area));
3914 	}
3915 
3916 	kmem_free(pwa, sizeof (struct watched_area));
3917 
3918 	/*
3919 	 * If we removed the last watched area from the process, disable
3920 	 * watchpoints.
3921 	 */
3922 	if (!pr_watch_active(p)) {
3923 		kthread_t *t;
3924 
3925 		mutex_enter(&p->p_lock);
3926 		if ((t = p->p_tlist) != NULL) {
3927 			do {
3928 				watch_disable(t);
3929 			} while ((t = t->t_forw) != p->p_tlist);
3930 		}
3931 		mutex_exit(&p->p_lock);
3932 	}
3933 
3934 	return (0);
3935 }
3936 
3937 /*
3938  * Frees all the watched_area structures
3939  */
3940 void
3941 pr_free_watchpoints(proc_t *p)
3942 {
3943 	struct watched_area *delp;
3944 	void *cookie;
3945 
3946 	cookie = NULL;
3947 	while ((delp = avl_destroy_nodes(&p->p_warea, &cookie)) != NULL)
3948 		kmem_free(delp, sizeof (struct watched_area));
3949 
3950 	avl_destroy(&p->p_warea);
3951 }
3952 
3953 /*
3954  * This one is called by the traced process to unwatch all the
3955  * pages while deallocating the list of watched_page structs.
3956  */
3957 void
3958 pr_free_watched_pages(proc_t *p)
3959 {
3960 	struct as *as = p->p_as;
3961 	struct watched_page *pwp;
3962 	uint_t prot;
3963 	int    retrycnt, err;
3964 	void *cookie;
3965 
3966 	if (as == NULL || avl_numnodes(&as->a_wpage) == 0)
3967 		return;
3968 
3969 	ASSERT(MUTEX_NOT_HELD(&curproc->p_lock));
3970 	AS_LOCK_ENTER(as, RW_WRITER);
3971 
3972 	pwp = avl_first(&as->a_wpage);
3973 
3974 	cookie = NULL;
3975 	while ((pwp = avl_destroy_nodes(&as->a_wpage, &cookie)) != NULL) {
3976 		retrycnt = 0;
3977 		if ((prot = pwp->wp_oprot) != 0) {
3978 			caddr_t addr = pwp->wp_vaddr;
3979 			struct seg *seg;
3980 		retry:
3981 
3982 			if ((pwp->wp_prot != prot ||
3983 			    (pwp->wp_flags & WP_NOWATCH)) &&
3984 			    (seg = as_segat(as, addr)) != NULL) {
3985 				err = SEGOP_SETPROT(seg, addr, PAGESIZE, prot);
3986 				if (err == IE_RETRY) {
3987 					ASSERT(retrycnt == 0);
3988 					retrycnt++;
3989 					goto retry;
3990 				}
3991 			}
3992 		}
3993 		kmem_free(pwp, sizeof (struct watched_page));
3994 	}
3995 
3996 	avl_destroy(&as->a_wpage);
3997 	p->p_wprot = NULL;
3998 
3999 	AS_LOCK_EXIT(as);
4000 }
4001 
4002 /*
4003  * Insert a watched area into the list of watched pages.
4004  * If oflags is zero then we are adding a new watched area.
4005  * Otherwise we are changing the flags of an existing watched area.
4006  */
4007 static int
4008 set_watched_page(proc_t *p, caddr_t vaddr, caddr_t eaddr,
4009     ulong_t flags, ulong_t oflags)
4010 {
4011 	struct as *as = p->p_as;
4012 	avl_tree_t *pwp_tree;
4013 	struct watched_page *pwp, *newpwp;
4014 	struct watched_page tpw;
4015 	avl_index_t where;
4016 	struct seg *seg;
4017 	uint_t prot;
4018 	caddr_t addr;
4019 
4020 	/*
4021 	 * We need to pre-allocate a list of structures before we grab the
4022 	 * address space lock to avoid calling kmem_alloc(KM_SLEEP) with locks
4023 	 * held.
4024 	 */
4025 	newpwp = NULL;
4026 	for (addr = (caddr_t)((uintptr_t)vaddr & (uintptr_t)PAGEMASK);
4027 	    addr < eaddr; addr += PAGESIZE) {
4028 		pwp = kmem_zalloc(sizeof (struct watched_page), KM_SLEEP);
4029 		pwp->wp_list = newpwp;
4030 		newpwp = pwp;
4031 	}
4032 
4033 	AS_LOCK_ENTER(as, RW_WRITER);
4034 
4035 	/*
4036 	 * Search for an existing watched page to contain the watched area.
4037 	 * If none is found, grab a new one from the available list
4038 	 * and insert it in the active list, keeping the list sorted
4039 	 * by user-level virtual address.
4040 	 */
4041 	if (p->p_flag & SVFWAIT)
4042 		pwp_tree = &p->p_wpage;
4043 	else
4044 		pwp_tree = &as->a_wpage;
4045 
4046 again:
4047 	if (avl_numnodes(pwp_tree) > prnwatch) {
4048 		AS_LOCK_EXIT(as);
4049 		while (newpwp != NULL) {
4050 			pwp = newpwp->wp_list;
4051 			kmem_free(newpwp, sizeof (struct watched_page));
4052 			newpwp = pwp;
4053 		}
4054 		return (E2BIG);
4055 	}
4056 
4057 	tpw.wp_vaddr = (caddr_t)((uintptr_t)vaddr & (uintptr_t)PAGEMASK);
4058 	if ((pwp = avl_find(pwp_tree, &tpw, &where)) == NULL) {
4059 		pwp = newpwp;
4060 		newpwp = newpwp->wp_list;
4061 		pwp->wp_list = NULL;
4062 		pwp->wp_vaddr = (caddr_t)((uintptr_t)vaddr &
4063 		    (uintptr_t)PAGEMASK);
4064 		avl_insert(pwp_tree, pwp, where);
4065 	}
4066 
4067 	ASSERT(vaddr >= pwp->wp_vaddr && vaddr < pwp->wp_vaddr + PAGESIZE);
4068 
4069 	if (oflags & WA_READ)
4070 		pwp->wp_read--;
4071 	if (oflags & WA_WRITE)
4072 		pwp->wp_write--;
4073 	if (oflags & WA_EXEC)
4074 		pwp->wp_exec--;
4075 
4076 	ASSERT(pwp->wp_read >= 0);
4077 	ASSERT(pwp->wp_write >= 0);
4078 	ASSERT(pwp->wp_exec >= 0);
4079 
4080 	if (flags & WA_READ)
4081 		pwp->wp_read++;
4082 	if (flags & WA_WRITE)
4083 		pwp->wp_write++;
4084 	if (flags & WA_EXEC)
4085 		pwp->wp_exec++;
4086 
4087 	if (!(p->p_flag & SVFWAIT)) {
4088 		vaddr = pwp->wp_vaddr;
4089 		if (pwp->wp_oprot == 0 &&
4090 		    (seg = as_segat(as, vaddr)) != NULL) {
4091 			SEGOP_GETPROT(seg, vaddr, 0, &prot);
4092 			pwp->wp_oprot = (uchar_t)prot;
4093 			pwp->wp_prot = (uchar_t)prot;
4094 		}
4095 		if (pwp->wp_oprot != 0) {
4096 			prot = pwp->wp_oprot;
4097 			if (pwp->wp_read)
4098 				prot &= ~(PROT_READ|PROT_WRITE|PROT_EXEC);
4099 			if (pwp->wp_write)
4100 				prot &= ~PROT_WRITE;
4101 			if (pwp->wp_exec)
4102 				prot &= ~(PROT_READ|PROT_WRITE|PROT_EXEC);
4103 			if (!(pwp->wp_flags & WP_NOWATCH) &&
4104 			    pwp->wp_prot != prot &&
4105 			    (pwp->wp_flags & WP_SETPROT) == 0) {
4106 				pwp->wp_flags |= WP_SETPROT;
4107 				pwp->wp_list = p->p_wprot;
4108 				p->p_wprot = pwp;
4109 			}
4110 			pwp->wp_prot = (uchar_t)prot;
4111 		}
4112 	}
4113 
4114 	/*
4115 	 * If the watched area extends into the next page then do
4116 	 * it over again with the virtual address of the next page.
4117 	 */
4118 	if ((vaddr = pwp->wp_vaddr + PAGESIZE) < eaddr)
4119 		goto again;
4120 
4121 	AS_LOCK_EXIT(as);
4122 
4123 	/*
4124 	 * Free any pages we may have over-allocated
4125 	 */
4126 	while (newpwp != NULL) {
4127 		pwp = newpwp->wp_list;
4128 		kmem_free(newpwp, sizeof (struct watched_page));
4129 		newpwp = pwp;
4130 	}
4131 
4132 	return (0);
4133 }
4134 
4135 /*
4136  * Remove a watched area from the list of watched pages.
4137  * A watched area may extend over more than one page.
4138  */
4139 static void
4140 clear_watched_page(proc_t *p, caddr_t vaddr, caddr_t eaddr, ulong_t flags)
4141 {
4142 	struct as *as = p->p_as;
4143 	struct watched_page *pwp;
4144 	struct watched_page tpw;
4145 	avl_tree_t *tree;
4146 	avl_index_t where;
4147 
4148 	AS_LOCK_ENTER(as, RW_WRITER);
4149 
4150 	if (p->p_flag & SVFWAIT)
4151 		tree = &p->p_wpage;
4152 	else
4153 		tree = &as->a_wpage;
4154 
4155 	tpw.wp_vaddr = vaddr =
4156 	    (caddr_t)((uintptr_t)vaddr & (uintptr_t)PAGEMASK);
4157 	pwp = avl_find(tree, &tpw, &where);
4158 	if (pwp == NULL)
4159 		pwp = avl_nearest(tree, where, AVL_AFTER);
4160 
4161 	while (pwp != NULL && pwp->wp_vaddr < eaddr) {
4162 		ASSERT(vaddr <=  pwp->wp_vaddr);
4163 
4164 		if (flags & WA_READ)
4165 			pwp->wp_read--;
4166 		if (flags & WA_WRITE)
4167 			pwp->wp_write--;
4168 		if (flags & WA_EXEC)
4169 			pwp->wp_exec--;
4170 
4171 		if (pwp->wp_read + pwp->wp_write + pwp->wp_exec != 0) {
4172 			/*
4173 			 * Reset the hat layer's protections on this page.
4174 			 */
4175 			if (pwp->wp_oprot != 0) {
4176 				uint_t prot = pwp->wp_oprot;
4177 
4178 				if (pwp->wp_read)
4179 					prot &=
4180 					    ~(PROT_READ|PROT_WRITE|PROT_EXEC);
4181 				if (pwp->wp_write)
4182 					prot &= ~PROT_WRITE;
4183 				if (pwp->wp_exec)
4184 					prot &=
4185 					    ~(PROT_READ|PROT_WRITE|PROT_EXEC);
4186 				if (!(pwp->wp_flags & WP_NOWATCH) &&
4187 				    pwp->wp_prot != prot &&
4188 				    (pwp->wp_flags & WP_SETPROT) == 0) {
4189 					pwp->wp_flags |= WP_SETPROT;
4190 					pwp->wp_list = p->p_wprot;
4191 					p->p_wprot = pwp;
4192 				}
4193 				pwp->wp_prot = (uchar_t)prot;
4194 			}
4195 		} else {
4196 			/*
4197 			 * No watched areas remain in this page.
4198 			 * Reset everything to normal.
4199 			 */
4200 			if (pwp->wp_oprot != 0) {
4201 				pwp->wp_prot = pwp->wp_oprot;
4202 				if ((pwp->wp_flags & WP_SETPROT) == 0) {
4203 					pwp->wp_flags |= WP_SETPROT;
4204 					pwp->wp_list = p->p_wprot;
4205 					p->p_wprot = pwp;
4206 				}
4207 			}
4208 		}
4209 
4210 		pwp = AVL_NEXT(tree, pwp);
4211 	}
4212 
4213 	AS_LOCK_EXIT(as);
4214 }
4215 
4216 /*
4217  * Return the original protections for the specified page.
4218  */
4219 static void
4220 getwatchprot(struct as *as, caddr_t addr, uint_t *prot)
4221 {
4222 	struct watched_page *pwp;
4223 	struct watched_page tpw;
4224 
4225 	ASSERT(AS_LOCK_HELD(as));
4226 
4227 	tpw.wp_vaddr = (caddr_t)((uintptr_t)addr & (uintptr_t)PAGEMASK);
4228 	if ((pwp = avl_find(&as->a_wpage, &tpw, NULL)) != NULL)
4229 		*prot = pwp->wp_oprot;
4230 }
4231 
4232 static prpagev_t *
4233 pr_pagev_create(struct seg *seg, int check_noreserve)
4234 {
4235 	prpagev_t *pagev = kmem_alloc(sizeof (prpagev_t), KM_SLEEP);
4236 	size_t total_pages = seg_pages(seg);
4237 
4238 	/*
4239 	 * Limit the size of our vectors to pagev_lim pages at a time.  We need
4240 	 * 4 or 5 bytes of storage per page, so this means we limit ourself
4241 	 * to about a megabyte of kernel heap by default.
4242 	 */
4243 	pagev->pg_npages = MIN(total_pages, pagev_lim);
4244 	pagev->pg_pnbase = 0;
4245 
4246 	pagev->pg_protv =
4247 	    kmem_alloc(pagev->pg_npages * sizeof (uint_t), KM_SLEEP);
4248 
4249 	if (check_noreserve)
4250 		pagev->pg_incore =
4251 		    kmem_alloc(pagev->pg_npages * sizeof (char), KM_SLEEP);
4252 	else
4253 		pagev->pg_incore = NULL;
4254 
4255 	return (pagev);
4256 }
4257 
4258 static void
4259 pr_pagev_destroy(prpagev_t *pagev)
4260 {
4261 	if (pagev->pg_incore != NULL)
4262 		kmem_free(pagev->pg_incore, pagev->pg_npages * sizeof (char));
4263 
4264 	kmem_free(pagev->pg_protv, pagev->pg_npages * sizeof (uint_t));
4265 	kmem_free(pagev, sizeof (prpagev_t));
4266 }
4267 
4268 static caddr_t
4269 pr_pagev_fill(prpagev_t *pagev, struct seg *seg, caddr_t addr, caddr_t eaddr)
4270 {
4271 	ulong_t lastpg = seg_page(seg, eaddr - 1);
4272 	ulong_t pn, pnlim;
4273 	caddr_t saddr;
4274 	size_t len;
4275 
4276 	ASSERT(addr >= seg->s_base && addr <= eaddr);
4277 
4278 	if (addr == eaddr)
4279 		return (eaddr);
4280 
4281 refill:
4282 	ASSERT(addr < eaddr);
4283 	pagev->pg_pnbase = seg_page(seg, addr);
4284 	pnlim = pagev->pg_pnbase + pagev->pg_npages;
4285 	saddr = addr;
4286 
4287 	if (lastpg < pnlim)
4288 		len = (size_t)(eaddr - addr);
4289 	else
4290 		len = pagev->pg_npages * PAGESIZE;
4291 
4292 	if (pagev->pg_incore != NULL) {
4293 		/*
4294 		 * INCORE cleverly has different semantics than GETPROT:
4295 		 * it returns info on pages up to but NOT including addr + len.
4296 		 */
4297 		SEGOP_INCORE(seg, addr, len, pagev->pg_incore);
4298 		pn = pagev->pg_pnbase;
4299 
4300 		do {
4301 			/*
4302 			 * Guilty knowledge here:  We know that segvn_incore
4303 			 * returns more than just the low-order bit that
4304 			 * indicates the page is actually in memory.  If any
4305 			 * bits are set, then the page has backing store.
4306 			 */
4307 			if (pagev->pg_incore[pn++ - pagev->pg_pnbase])
4308 				goto out;
4309 
4310 		} while ((addr += PAGESIZE) < eaddr && pn < pnlim);
4311 
4312 		/*
4313 		 * If we examined all the pages in the vector but we're not
4314 		 * at the end of the segment, take another lap.
4315 		 */
4316 		if (addr < eaddr)
4317 			goto refill;
4318 	}
4319 
4320 	/*
4321 	 * Need to take len - 1 because addr + len is the address of the
4322 	 * first byte of the page just past the end of what we want.
4323 	 */
4324 out:
4325 	SEGOP_GETPROT(seg, saddr, len - 1, pagev->pg_protv);
4326 	return (addr);
4327 }
4328 
4329 static caddr_t
4330 pr_pagev_nextprot(prpagev_t *pagev, struct seg *seg,
4331     caddr_t *saddrp, caddr_t eaddr, uint_t *protp)
4332 {
4333 	/*
4334 	 * Our starting address is either the specified address, or the base
4335 	 * address from the start of the pagev.  If the latter is greater,
4336 	 * this means a previous call to pr_pagev_fill has already scanned
4337 	 * further than the end of the previous mapping.
4338 	 */
4339 	caddr_t base = seg->s_base + pagev->pg_pnbase * PAGESIZE;
4340 	caddr_t addr = MAX(*saddrp, base);
4341 	ulong_t pn = seg_page(seg, addr);
4342 	uint_t prot, nprot;
4343 
4344 	/*
4345 	 * If we're dealing with noreserve pages, then advance addr to
4346 	 * the address of the next page which has backing store.
4347 	 */
4348 	if (pagev->pg_incore != NULL) {
4349 		while (pagev->pg_incore[pn - pagev->pg_pnbase] == 0) {
4350 			if ((addr += PAGESIZE) == eaddr) {
4351 				*saddrp = addr;
4352 				prot = 0;
4353 				goto out;
4354 			}
4355 			if (++pn == pagev->pg_pnbase + pagev->pg_npages) {
4356 				addr = pr_pagev_fill(pagev, seg, addr, eaddr);
4357 				if (addr == eaddr) {
4358 					*saddrp = addr;
4359 					prot = 0;
4360 					goto out;
4361 				}
4362 				pn = seg_page(seg, addr);
4363 			}
4364 		}
4365 	}
4366 
4367 	/*
4368 	 * Get the protections on the page corresponding to addr.
4369 	 */
4370 	pn = seg_page(seg, addr);
4371 	ASSERT(pn >= pagev->pg_pnbase);
4372 	ASSERT(pn < (pagev->pg_pnbase + pagev->pg_npages));
4373 
4374 	prot = pagev->pg_protv[pn - pagev->pg_pnbase];
4375 	getwatchprot(seg->s_as, addr, &prot);
4376 	*saddrp = addr;
4377 
4378 	/*
4379 	 * Now loop until we find a backed page with different protections
4380 	 * or we reach the end of this segment.
4381 	 */
4382 	while ((addr += PAGESIZE) < eaddr) {
4383 		/*
4384 		 * If pn has advanced to the page number following what we
4385 		 * have information on, refill the page vector and reset
4386 		 * addr and pn.  If pr_pagev_fill does not return the
4387 		 * address of the next page, we have a discontiguity and
4388 		 * thus have reached the end of the current mapping.
4389 		 */
4390 		if (++pn == pagev->pg_pnbase + pagev->pg_npages) {
4391 			caddr_t naddr = pr_pagev_fill(pagev, seg, addr, eaddr);
4392 			if (naddr != addr)
4393 				goto out;
4394 			pn = seg_page(seg, addr);
4395 		}
4396 
4397 		/*
4398 		 * The previous page's protections are in prot, and it has
4399 		 * backing.  If this page is MAP_NORESERVE and has no backing,
4400 		 * then end this mapping and return the previous protections.
4401 		 */
4402 		if (pagev->pg_incore != NULL &&
4403 		    pagev->pg_incore[pn - pagev->pg_pnbase] == 0)
4404 			break;
4405 
4406 		/*
4407 		 * Otherwise end the mapping if this page's protections (nprot)
4408 		 * are different than those in the previous page (prot).
4409 		 */
4410 		nprot = pagev->pg_protv[pn - pagev->pg_pnbase];
4411 		getwatchprot(seg->s_as, addr, &nprot);
4412 
4413 		if (nprot != prot)
4414 			break;
4415 	}
4416 
4417 out:
4418 	*protp = prot;
4419 	return (addr);
4420 }
4421 
4422 size_t
4423 pr_getsegsize(struct seg *seg, int reserved)
4424 {
4425 	size_t size = seg->s_size;
4426 
4427 	/*
4428 	 * If we're interested in the reserved space, return the size of the
4429 	 * segment itself.  Everything else in this function is a special case
4430 	 * to determine the actual underlying size of various segment types.
4431 	 */
4432 	if (reserved)
4433 		return (size);
4434 
4435 	/*
4436 	 * If this is a segvn mapping of a regular file, return the smaller
4437 	 * of the segment size and the remaining size of the file beyond
4438 	 * the file offset corresponding to seg->s_base.
4439 	 */
4440 	if (seg->s_ops == &segvn_ops) {
4441 		vattr_t vattr;
4442 		vnode_t *vp;
4443 
4444 		vattr.va_mask = AT_SIZE;
4445 
4446 		if (SEGOP_GETVP(seg, seg->s_base, &vp) == 0 &&
4447 		    vp != NULL && vp->v_type == VREG &&
4448 		    VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
4449 
4450 			u_offset_t fsize = vattr.va_size;
4451 			u_offset_t offset = SEGOP_GETOFFSET(seg, seg->s_base);
4452 
4453 			if (fsize < offset)
4454 				fsize = 0;
4455 			else
4456 				fsize -= offset;
4457 
4458 			fsize = roundup(fsize, (u_offset_t)PAGESIZE);
4459 
4460 			if (fsize < (u_offset_t)size)
4461 				size = (size_t)fsize;
4462 		}
4463 
4464 		return (size);
4465 	}
4466 
4467 	/*
4468 	 * If this is an ISM shared segment, don't include pages that are
4469 	 * beyond the real size of the spt segment that backs it.
4470 	 */
4471 	if (seg->s_ops == &segspt_shmops)
4472 		return (MIN(spt_realsize(seg), size));
4473 
4474 	/*
4475 	 * If this is segment is a mapping from /dev/null, then this is a
4476 	 * reservation of virtual address space and has no actual size.
4477 	 * Such segments are backed by segdev and have type set to neither
4478 	 * MAP_SHARED nor MAP_PRIVATE.
4479 	 */
4480 	if (seg->s_ops == &segdev_ops &&
4481 	    ((SEGOP_GETTYPE(seg, seg->s_base) &
4482 	    (MAP_SHARED | MAP_PRIVATE)) == 0))
4483 		return (0);
4484 
4485 	/*
4486 	 * If this segment doesn't match one of the special types we handle,
4487 	 * just return the size of the segment itself.
4488 	 */
4489 	return (size);
4490 }
4491 
4492 uint_t
4493 pr_getprot(struct seg *seg, int reserved, void **tmp,
4494     caddr_t *saddrp, caddr_t *naddrp, caddr_t eaddr)
4495 {
4496 	struct as *as = seg->s_as;
4497 
4498 	caddr_t saddr = *saddrp;
4499 	caddr_t naddr;
4500 
4501 	int check_noreserve;
4502 	uint_t prot;
4503 
4504 	union {
4505 		struct segvn_data *svd;
4506 		struct segdev_data *sdp;
4507 		void *data;
4508 	} s;
4509 
4510 	s.data = seg->s_data;
4511 
4512 	ASSERT(AS_WRITE_HELD(as));
4513 	ASSERT(saddr >= seg->s_base && saddr < eaddr);
4514 	ASSERT(eaddr <= seg->s_base + seg->s_size);
4515 
4516 	/*
4517 	 * Don't include MAP_NORESERVE pages in the address range
4518 	 * unless their mappings have actually materialized.
4519 	 * We cheat by knowing that segvn is the only segment
4520 	 * driver that supports MAP_NORESERVE.
4521 	 */
4522 	check_noreserve =
4523 	    (!reserved && seg->s_ops == &segvn_ops && s.svd != NULL &&
4524 	    (s.svd->vp == NULL || s.svd->vp->v_type != VREG) &&
4525 	    (s.svd->flags & MAP_NORESERVE));
4526 
4527 	/*
4528 	 * Examine every page only as a last resort.  We use guilty knowledge
4529 	 * of segvn and segdev to avoid this: if there are no per-page
4530 	 * protections present in the segment and we don't care about
4531 	 * MAP_NORESERVE, then s_data->prot is the prot for the whole segment.
4532 	 */
4533 	if (!check_noreserve && saddr == seg->s_base &&
4534 	    seg->s_ops == &segvn_ops && s.svd != NULL && s.svd->pageprot == 0) {
4535 		prot = s.svd->prot;
4536 		getwatchprot(as, saddr, &prot);
4537 		naddr = eaddr;
4538 
4539 	} else if (saddr == seg->s_base && seg->s_ops == &segdev_ops &&
4540 	    s.sdp != NULL && s.sdp->pageprot == 0) {
4541 		prot = s.sdp->prot;
4542 		getwatchprot(as, saddr, &prot);
4543 		naddr = eaddr;
4544 
4545 	} else {
4546 		prpagev_t *pagev;
4547 
4548 		/*
4549 		 * If addr is sitting at the start of the segment, then
4550 		 * create a page vector to store protection and incore
4551 		 * information for pages in the segment, and fill it.
4552 		 * Otherwise, we expect *tmp to address the prpagev_t
4553 		 * allocated by a previous call to this function.
4554 		 */
4555 		if (saddr == seg->s_base) {
4556 			pagev = pr_pagev_create(seg, check_noreserve);
4557 			saddr = pr_pagev_fill(pagev, seg, saddr, eaddr);
4558 
4559 			ASSERT(*tmp == NULL);
4560 			*tmp = pagev;
4561 
4562 			ASSERT(saddr <= eaddr);
4563 			*saddrp = saddr;
4564 
4565 			if (saddr == eaddr) {
4566 				naddr = saddr;
4567 				prot = 0;
4568 				goto out;
4569 			}
4570 
4571 		} else {
4572 			ASSERT(*tmp != NULL);
4573 			pagev = (prpagev_t *)*tmp;
4574 		}
4575 
4576 		naddr = pr_pagev_nextprot(pagev, seg, saddrp, eaddr, &prot);
4577 		ASSERT(naddr <= eaddr);
4578 	}
4579 
4580 out:
4581 	if (naddr == eaddr)
4582 		pr_getprot_done(tmp);
4583 	*naddrp = naddr;
4584 	return (prot);
4585 }
4586 
4587 void
4588 pr_getprot_done(void **tmp)
4589 {
4590 	if (*tmp != NULL) {
4591 		pr_pagev_destroy((prpagev_t *)*tmp);
4592 		*tmp = NULL;
4593 	}
4594 }
4595 
4596 /*
4597  * Return true iff the vnode is a /proc file from the object directory.
4598  */
4599 int
4600 pr_isobject(vnode_t *vp)
4601 {
4602 	return (vn_matchops(vp, prvnodeops) && VTOP(vp)->pr_type == PR_OBJECT);
4603 }
4604 
4605 /*
4606  * Return true iff the vnode is a /proc file opened by the process itself.
4607  */
4608 int
4609 pr_isself(vnode_t *vp)
4610 {
4611 	/*
4612 	 * XXX: To retain binary compatibility with the old
4613 	 * ioctl()-based version of /proc, we exempt self-opens
4614 	 * of /proc/<pid> from being marked close-on-exec.
4615 	 */
4616 	return (vn_matchops(vp, prvnodeops) &&
4617 	    (VTOP(vp)->pr_flags & PR_ISSELF) &&
4618 	    VTOP(vp)->pr_type != PR_PIDDIR);
4619 }
4620 
4621 static ssize_t
4622 pr_getpagesize(struct seg *seg, caddr_t saddr, caddr_t *naddrp, caddr_t eaddr)
4623 {
4624 	ssize_t pagesize, hatsize;
4625 
4626 	ASSERT(AS_WRITE_HELD(seg->s_as));
4627 	ASSERT(IS_P2ALIGNED(saddr, PAGESIZE));
4628 	ASSERT(IS_P2ALIGNED(eaddr, PAGESIZE));
4629 	ASSERT(saddr < eaddr);
4630 
4631 	pagesize = hatsize = hat_getpagesize(seg->s_as->a_hat, saddr);
4632 	ASSERT(pagesize == -1 || IS_P2ALIGNED(pagesize, pagesize));
4633 	ASSERT(pagesize != 0);
4634 
4635 	if (pagesize == -1)
4636 		pagesize = PAGESIZE;
4637 
4638 	saddr += P2NPHASE((uintptr_t)saddr, pagesize);
4639 
4640 	while (saddr < eaddr) {
4641 		if (hatsize != hat_getpagesize(seg->s_as->a_hat, saddr))
4642 			break;
4643 		ASSERT(IS_P2ALIGNED(saddr, pagesize));
4644 		saddr += pagesize;
4645 	}
4646 
4647 	*naddrp = ((saddr < eaddr) ? saddr : eaddr);
4648 	return (hatsize);
4649 }
4650 
4651 /*
4652  * Return an array of structures with extended memory map information.
4653  * We allocate here; the caller must deallocate.
4654  */
4655 int
4656 prgetxmap(proc_t *p, list_t *iolhead)
4657 {
4658 	struct as *as = p->p_as;
4659 	prxmap_t *mp;
4660 	struct seg *seg;
4661 	struct seg *brkseg, *stkseg;
4662 	struct vnode *vp;
4663 	struct vattr vattr;
4664 	uint_t prot;
4665 
4666 	ASSERT(as != &kas && AS_WRITE_HELD(as));
4667 
4668 	/*
4669 	 * Request an initial buffer size that doesn't waste memory
4670 	 * if the address space has only a small number of segments.
4671 	 */
4672 	pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree));
4673 
4674 	if ((seg = AS_SEGFIRST(as)) == NULL)
4675 		return (0);
4676 
4677 	brkseg = break_seg(p);
4678 	stkseg = as_segat(as, prgetstackbase(p));
4679 
4680 	do {
4681 		caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
4682 		caddr_t saddr, naddr, baddr;
4683 		void *tmp = NULL;
4684 		ssize_t psz;
4685 		char *parr;
4686 		uint64_t npages;
4687 		uint64_t pagenum;
4688 
4689 		if ((seg->s_flags & S_HOLE) != 0) {
4690 			continue;
4691 		}
4692 		/*
4693 		 * Segment loop part one: iterate from the base of the segment
4694 		 * to its end, pausing at each address boundary (baddr) between
4695 		 * ranges that have different virtual memory protections.
4696 		 */
4697 		for (saddr = seg->s_base; saddr < eaddr; saddr = baddr) {
4698 			prot = pr_getprot(seg, 0, &tmp, &saddr, &baddr, eaddr);
4699 			ASSERT(baddr >= saddr && baddr <= eaddr);
4700 
4701 			/*
4702 			 * Segment loop part two: iterate from the current
4703 			 * position to the end of the protection boundary,
4704 			 * pausing at each address boundary (naddr) between
4705 			 * ranges that have different underlying page sizes.
4706 			 */
4707 			for (; saddr < baddr; saddr = naddr) {
4708 				psz = pr_getpagesize(seg, saddr, &naddr, baddr);
4709 				ASSERT(naddr >= saddr && naddr <= baddr);
4710 
4711 				mp = pr_iol_newbuf(iolhead, sizeof (*mp));
4712 
4713 				mp->pr_vaddr = (uintptr_t)saddr;
4714 				mp->pr_size = naddr - saddr;
4715 				mp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
4716 				mp->pr_mflags = 0;
4717 				if (prot & PROT_READ)
4718 					mp->pr_mflags |= MA_READ;
4719 				if (prot & PROT_WRITE)
4720 					mp->pr_mflags |= MA_WRITE;
4721 				if (prot & PROT_EXEC)
4722 					mp->pr_mflags |= MA_EXEC;
4723 				if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
4724 					mp->pr_mflags |= MA_SHARED;
4725 				if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
4726 					mp->pr_mflags |= MA_NORESERVE;
4727 				if (seg->s_ops == &segspt_shmops ||
4728 				    (seg->s_ops == &segvn_ops &&
4729 				    (SEGOP_GETVP(seg, saddr, &vp) != 0 ||
4730 				    vp == NULL)))
4731 					mp->pr_mflags |= MA_ANON;
4732 				if (seg == brkseg)
4733 					mp->pr_mflags |= MA_BREAK;
4734 				else if (seg == stkseg)
4735 					mp->pr_mflags |= MA_STACK;
4736 				if (seg->s_ops == &segspt_shmops)
4737 					mp->pr_mflags |= MA_ISM | MA_SHM;
4738 
4739 				mp->pr_pagesize = PAGESIZE;
4740 				if (psz == -1) {
4741 					mp->pr_hatpagesize = 0;
4742 				} else {
4743 					mp->pr_hatpagesize = psz;
4744 				}
4745 
4746 				/*
4747 				 * Manufacture a filename for the "object" dir.
4748 				 */
4749 				mp->pr_dev = PRNODEV;
4750 				vattr.va_mask = AT_FSID|AT_NODEID;
4751 				if (seg->s_ops == &segvn_ops &&
4752 				    SEGOP_GETVP(seg, saddr, &vp) == 0 &&
4753 				    vp != NULL && vp->v_type == VREG &&
4754 				    VOP_GETATTR(vp, &vattr, 0, CRED(),
4755 				    NULL) == 0) {
4756 					mp->pr_dev = vattr.va_fsid;
4757 					mp->pr_ino = vattr.va_nodeid;
4758 					if (vp == p->p_exec)
4759 						(void) strcpy(mp->pr_mapname,
4760 						    "a.out");
4761 					else
4762 						pr_object_name(mp->pr_mapname,
4763 						    vp, &vattr);
4764 				}
4765 
4766 				/*
4767 				 * Get the SysV shared memory id, if any.
4768 				 */
4769 				if ((mp->pr_mflags & MA_SHARED) &&
4770 				    p->p_segacct && (mp->pr_shmid = shmgetid(p,
4771 				    seg->s_base)) != SHMID_NONE) {
4772 					if (mp->pr_shmid == SHMID_FREE)
4773 						mp->pr_shmid = -1;
4774 
4775 					mp->pr_mflags |= MA_SHM;
4776 				} else {
4777 					mp->pr_shmid = -1;
4778 				}
4779 
4780 				npages = ((uintptr_t)(naddr - saddr)) >>
4781 				    PAGESHIFT;
4782 				parr = kmem_zalloc(npages, KM_SLEEP);
4783 
4784 				SEGOP_INCORE(seg, saddr, naddr - saddr, parr);
4785 
4786 				for (pagenum = 0; pagenum < npages; pagenum++) {
4787 					if (parr[pagenum] & SEG_PAGE_INCORE)
4788 						mp->pr_rss++;
4789 					if (parr[pagenum] & SEG_PAGE_ANON)
4790 						mp->pr_anon++;
4791 					if (parr[pagenum] & SEG_PAGE_LOCKED)
4792 						mp->pr_locked++;
4793 				}
4794 				kmem_free(parr, npages);
4795 			}
4796 		}
4797 		ASSERT(tmp == NULL);
4798 	} while ((seg = AS_SEGNEXT(as, seg)) != NULL);
4799 
4800 	return (0);
4801 }
4802 
4803 /*
4804  * Return the process's credentials.  We don't need a 32-bit equivalent of
4805  * this function because prcred_t and prcred32_t are actually the same.
4806  */
4807 void
4808 prgetcred(proc_t *p, prcred_t *pcrp)
4809 {
4810 	mutex_enter(&p->p_crlock);
4811 	cred2prcred(p->p_cred, pcrp);
4812 	mutex_exit(&p->p_crlock);
4813 }
4814 
4815 void
4816 prgetsecflags(proc_t *p, prsecflags_t *psfp)
4817 {
4818 	ASSERT(psfp != NULL);
4819 
4820 	psfp->pr_version = PRSECFLAGS_VERSION_CURRENT;
4821 	psfp->pr_lower = p->p_secflags.psf_lower;
4822 	psfp->pr_upper = p->p_secflags.psf_upper;
4823 	psfp->pr_effective = p->p_secflags.psf_effective;
4824 	psfp->pr_inherit = p->p_secflags.psf_inherit;
4825 }
4826 
4827 /*
4828  * Compute actual size of the prpriv_t structure.
4829  */
4830 
4831 size_t
4832 prgetprivsize(void)
4833 {
4834 	return (priv_prgetprivsize(NULL));
4835 }
4836 
4837 /*
4838  * Return the process's privileges.  We don't need a 32-bit equivalent of
4839  * this function because prpriv_t and prpriv32_t are actually the same.
4840  */
4841 void
4842 prgetpriv(proc_t *p, prpriv_t *pprp)
4843 {
4844 	mutex_enter(&p->p_crlock);
4845 	cred2prpriv(p->p_cred, pprp);
4846 	mutex_exit(&p->p_crlock);
4847 }
4848 
4849 #ifdef _SYSCALL32_IMPL
4850 /*
4851  * Return an array of structures with HAT memory map information.
4852  * We allocate here; the caller must deallocate.
4853  */
4854 int
4855 prgetxmap32(proc_t *p, list_t *iolhead)
4856 {
4857 	struct as *as = p->p_as;
4858 	prxmap32_t *mp;
4859 	struct seg *seg;
4860 	struct seg *brkseg, *stkseg;
4861 	struct vnode *vp;
4862 	struct vattr vattr;
4863 	uint_t prot;
4864 
4865 	ASSERT(as != &kas && AS_WRITE_HELD(as));
4866 
4867 	/*
4868 	 * Request an initial buffer size that doesn't waste memory
4869 	 * if the address space has only a small number of segments.
4870 	 */
4871 	pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree));
4872 
4873 	if ((seg = AS_SEGFIRST(as)) == NULL)
4874 		return (0);
4875 
4876 	brkseg = break_seg(p);
4877 	stkseg = as_segat(as, prgetstackbase(p));
4878 
4879 	do {
4880 		caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
4881 		caddr_t saddr, naddr, baddr;
4882 		void *tmp = NULL;
4883 		ssize_t psz;
4884 		char *parr;
4885 		uint64_t npages;
4886 		uint64_t pagenum;
4887 
4888 		if ((seg->s_flags & S_HOLE) != 0) {
4889 			continue;
4890 		}
4891 
4892 		/*
4893 		 * Segment loop part one: iterate from the base of the segment
4894 		 * to its end, pausing at each address boundary (baddr) between
4895 		 * ranges that have different virtual memory protections.
4896 		 */
4897 		for (saddr = seg->s_base; saddr < eaddr; saddr = baddr) {
4898 			prot = pr_getprot(seg, 0, &tmp, &saddr, &baddr, eaddr);
4899 			ASSERT(baddr >= saddr && baddr <= eaddr);
4900 
4901 			/*
4902 			 * Segment loop part two: iterate from the current
4903 			 * position to the end of the protection boundary,
4904 			 * pausing at each address boundary (naddr) between
4905 			 * ranges that have different underlying page sizes.
4906 			 */
4907 			for (; saddr < baddr; saddr = naddr) {
4908 				psz = pr_getpagesize(seg, saddr, &naddr, baddr);
4909 				ASSERT(naddr >= saddr && naddr <= baddr);
4910 
4911 				mp = pr_iol_newbuf(iolhead, sizeof (*mp));
4912 
4913 				mp->pr_vaddr = (caddr32_t)(uintptr_t)saddr;
4914 				mp->pr_size = (size32_t)(naddr - saddr);
4915 				mp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
4916 				mp->pr_mflags = 0;
4917 				if (prot & PROT_READ)
4918 					mp->pr_mflags |= MA_READ;
4919 				if (prot & PROT_WRITE)
4920 					mp->pr_mflags |= MA_WRITE;
4921 				if (prot & PROT_EXEC)
4922 					mp->pr_mflags |= MA_EXEC;
4923 				if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
4924 					mp->pr_mflags |= MA_SHARED;
4925 				if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
4926 					mp->pr_mflags |= MA_NORESERVE;
4927 				if (seg->s_ops == &segspt_shmops ||
4928 				    (seg->s_ops == &segvn_ops &&
4929 				    (SEGOP_GETVP(seg, saddr, &vp) != 0 ||
4930 				    vp == NULL)))
4931 					mp->pr_mflags |= MA_ANON;
4932 				if (seg == brkseg)
4933 					mp->pr_mflags |= MA_BREAK;
4934 				else if (seg == stkseg)
4935 					mp->pr_mflags |= MA_STACK;
4936 				if (seg->s_ops == &segspt_shmops)
4937 					mp->pr_mflags |= MA_ISM | MA_SHM;
4938 
4939 				mp->pr_pagesize = PAGESIZE;
4940 				if (psz == -1) {
4941 					mp->pr_hatpagesize = 0;
4942 				} else {
4943 					mp->pr_hatpagesize = psz;
4944 				}
4945 
4946 				/*
4947 				 * Manufacture a filename for the "object" dir.
4948 				 */
4949 				mp->pr_dev = PRNODEV32;
4950 				vattr.va_mask = AT_FSID|AT_NODEID;
4951 				if (seg->s_ops == &segvn_ops &&
4952 				    SEGOP_GETVP(seg, saddr, &vp) == 0 &&
4953 				    vp != NULL && vp->v_type == VREG &&
4954 				    VOP_GETATTR(vp, &vattr, 0, CRED(),
4955 				    NULL) == 0) {
4956 					(void) cmpldev(&mp->pr_dev,
4957 					    vattr.va_fsid);
4958 					mp->pr_ino = vattr.va_nodeid;
4959 					if (vp == p->p_exec)
4960 						(void) strcpy(mp->pr_mapname,
4961 						    "a.out");
4962 					else
4963 						pr_object_name(mp->pr_mapname,
4964 						    vp, &vattr);
4965 				}
4966 
4967 				/*
4968 				 * Get the SysV shared memory id, if any.
4969 				 */
4970 				if ((mp->pr_mflags & MA_SHARED) &&
4971 				    p->p_segacct && (mp->pr_shmid = shmgetid(p,
4972 				    seg->s_base)) != SHMID_NONE) {
4973 					if (mp->pr_shmid == SHMID_FREE)
4974 						mp->pr_shmid = -1;
4975 
4976 					mp->pr_mflags |= MA_SHM;
4977 				} else {
4978 					mp->pr_shmid = -1;
4979 				}
4980 
4981 				npages = ((uintptr_t)(naddr - saddr)) >>
4982 				    PAGESHIFT;
4983 				parr = kmem_zalloc(npages, KM_SLEEP);
4984 
4985 				SEGOP_INCORE(seg, saddr, naddr - saddr, parr);
4986 
4987 				for (pagenum = 0; pagenum < npages; pagenum++) {
4988 					if (parr[pagenum] & SEG_PAGE_INCORE)
4989 						mp->pr_rss++;
4990 					if (parr[pagenum] & SEG_PAGE_ANON)
4991 						mp->pr_anon++;
4992 					if (parr[pagenum] & SEG_PAGE_LOCKED)
4993 						mp->pr_locked++;
4994 				}
4995 				kmem_free(parr, npages);
4996 			}
4997 		}
4998 		ASSERT(tmp == NULL);
4999 	} while ((seg = AS_SEGNEXT(as, seg)) != NULL);
5000 
5001 	return (0);
5002 }
5003 #endif	/* _SYSCALL32_IMPL */
5004