xref: /illumos-gate/usr/src/cmd/truss/expound.c (revision aa4a4f3b)
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 2006 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28 /*	  All Rights Reserved  	*/
29 
30 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
32 
33 #define	_SYSCALL32
34 
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <unistd.h>
38 #include <ctype.h>
39 #include <sys/types.h>
40 #include <sys/mman.h>
41 #include <libproc.h>
42 #include <string.h>
43 #include <limits.h>
44 #include <sys/statfs.h>
45 #include <sys/times.h>
46 #include <sys/timex.h>
47 #include <sys/utssys.h>
48 #include <sys/utsname.h>
49 #include <sys/ipc.h>
50 #include <sys/ipc_impl.h>
51 #include <sys/msg.h>
52 #include <sys/msg_impl.h>
53 #include <sys/sem.h>
54 #include <sys/sem_impl.h>
55 #include <sys/shm.h>
56 #include <sys/shm_impl.h>
57 #include <sys/dirent.h>
58 #include <sys/utime.h>
59 #include <ustat.h>
60 #include <fcntl.h>
61 #include <time.h>
62 #include <sys/termios.h>
63 #include <sys/termiox.h>
64 #include <sys/termio.h>
65 #include <sys/ttold.h>
66 #include <sys/jioctl.h>
67 #include <sys/filio.h>
68 #include <stropts.h>
69 #include <poll.h>
70 #include <sys/uio.h>
71 #include <sys/resource.h>
72 #include <sys/statvfs.h>
73 #include <sys/time.h>
74 #include <sys/aio.h>
75 #include <sys/socket.h>
76 #include <netinet/in.h>
77 #include <sys/un.h>
78 #include <sys/byteorder.h>
79 #include <arpa/inet.h>
80 #include <sys/audioio.h>
81 #include <sys/cladm.h>
82 #include <sys/synch.h>
83 #include <sys/synch32.h>
84 #include <sys/sysmacros.h>
85 #include <sys/sendfile.h>
86 #include <priv.h>
87 #include <ucred.h>
88 #include <sys/ucred.h>
89 #include <sys/port_impl.h>
90 #include <sys/zone.h>
91 #include <sys/priv_impl.h>
92 #include <sys/priv.h>
93 #include <tsol/label.h>
94 #include <sys/nvpair.h>
95 #include <libnvpair.h>
96 
97 #include "ramdata.h"
98 #include "systable.h"
99 #include "proto.h"
100 
101 void	show_sigset(private_t *, long, const char *);
102 void	show_ioctl(private_t *, int, long);
103 
104 void
105 prtime(private_t *pri, const char *name, time_t value)
106 {
107 	char str[80];
108 
109 	(void) strftime(str, sizeof (str), "%b %e %H:%M:%S %Z %Y",
110 		localtime(&value));
111 	(void) printf("%s\t%s%s  [ %llu ]\n",
112 	    pri->pname,
113 	    name,
114 	    str,
115 	    (longlong_t)value);
116 }
117 
118 void
119 prtimestruc(private_t *pri, const char *name, timestruc_t *value)
120 {
121 	prtime(pri, name, value->tv_sec);
122 }
123 
124 void
125 show_utime(private_t *pri)
126 {
127 	long offset;
128 	struct utimbuf utimbuf;
129 
130 	if (pri->sys_nargs < 2 || (offset = pri->sys_args[1]) == NULL)
131 		return;
132 
133 	if (data_model == PR_MODEL_NATIVE) {
134 		if (Pread(Proc, &utimbuf, sizeof (utimbuf), offset)
135 		    != sizeof (utimbuf))
136 			return;
137 	} else {
138 		struct utimbuf32 utimbuf32;
139 
140 		if (Pread(Proc, &utimbuf32, sizeof (utimbuf32), offset)
141 		    != sizeof (utimbuf32))
142 			return;
143 
144 		utimbuf.actime = (time_t)utimbuf32.actime;
145 		utimbuf.modtime = (time_t)utimbuf32.modtime;
146 	}
147 
148 	/* print access and modification times */
149 	prtime(pri, "atime: ", utimbuf.actime);
150 	prtime(pri, "mtime: ", utimbuf.modtime);
151 }
152 
153 void
154 show_utimes(private_t *pri)
155 {
156 	long offset;
157 	struct {
158 		struct timeval	atime;
159 		struct timeval	mtime;
160 	} utimbuf;
161 
162 	if (pri->sys_nargs < 2 || (offset = pri->sys_args[1]) == NULL)
163 		return;
164 
165 	if (data_model == PR_MODEL_NATIVE) {
166 		if (Pread(Proc, &utimbuf, sizeof (utimbuf), offset)
167 		    != sizeof (utimbuf))
168 			return;
169 	} else {
170 		struct {
171 			struct timeval32 atime;
172 			struct timeval32 mtime;
173 		} utimbuf32;
174 
175 		if (Pread(Proc, &utimbuf32, sizeof (utimbuf32), offset)
176 		    != sizeof (utimbuf32))
177 			return;
178 
179 		TIMEVAL32_TO_TIMEVAL(&utimbuf.atime, &utimbuf32.atime);
180 		TIMEVAL32_TO_TIMEVAL(&utimbuf.mtime, &utimbuf32.mtime);
181 	}
182 
183 	/* print access and modification times */
184 	prtime(pri, "atime: ", utimbuf.atime.tv_sec);
185 	prtime(pri, "mtime: ", utimbuf.mtime.tv_sec);
186 }
187 
188 void
189 show_timeofday(private_t *pri)
190 {
191 	struct timeval tod;
192 	long offset;
193 
194 	if (pri->sys_nargs < 1 || (offset = pri->sys_args[0]) == NULL)
195 		return;
196 
197 	if (data_model == PR_MODEL_NATIVE) {
198 		if (Pread(Proc, &tod, sizeof (tod), offset)
199 		    != sizeof (tod))
200 			return;
201 	} else {
202 		struct timeval32 tod32;
203 
204 		if (Pread(Proc, &tod32, sizeof (tod32), offset)
205 		    != sizeof (tod32))
206 			return;
207 
208 		TIMEVAL32_TO_TIMEVAL(&tod, &tod32);
209 	}
210 
211 	prtime(pri, "time: ", tod.tv_sec);
212 }
213 
214 void
215 show_itimerval(private_t *pri, long offset, const char *name)
216 {
217 	struct itimerval itimerval;
218 
219 	if (offset == NULL)
220 		return;
221 
222 	if (data_model == PR_MODEL_NATIVE) {
223 		if (Pread(Proc, &itimerval, sizeof (itimerval), offset)
224 		    != sizeof (itimerval))
225 			return;
226 	} else {
227 		struct itimerval32 itimerval32;
228 
229 		if (Pread(Proc, &itimerval32, sizeof (itimerval32), offset)
230 		    != sizeof (itimerval32))
231 			return;
232 
233 		ITIMERVAL32_TO_ITIMERVAL(&itimerval, &itimerval32);
234 	}
235 
236 	(void) printf(
237 	    "%s\t%s:  interval: %4ld.%6.6ld sec  value: %4ld.%6.6ld sec\n",
238 	    pri->pname,
239 	    name,
240 	    itimerval.it_interval.tv_sec,
241 	    itimerval.it_interval.tv_usec,
242 	    itimerval.it_value.tv_sec,
243 	    itimerval.it_value.tv_usec);
244 }
245 
246 void
247 show_timeval(private_t *pri, long offset, const char *name)
248 {
249 	struct timeval timeval;
250 
251 	if (offset == NULL)
252 		return;
253 
254 	if (data_model == PR_MODEL_NATIVE) {
255 		if (Pread(Proc, &timeval, sizeof (timeval), offset)
256 		    != sizeof (timeval))
257 			return;
258 	} else {
259 		struct timeval32 timeval32;
260 
261 		if (Pread(Proc, &timeval32, sizeof (timeval32), offset)
262 		    != sizeof (timeval32))
263 			return;
264 
265 		TIMEVAL32_TO_TIMEVAL(&timeval, &timeval32);
266 	}
267 
268 	(void) printf(
269 	    "%s\t%s: %ld.%6.6ld sec\n",
270 	    pri->pname,
271 	    name,
272 	    timeval.tv_sec,
273 	    timeval.tv_usec);
274 }
275 
276 void
277 show_timestruc(private_t *pri, long offset, const char *name)
278 {
279 	timestruc_t timestruc;
280 
281 	if (offset == NULL)
282 		return;
283 
284 	if (data_model == PR_MODEL_NATIVE) {
285 		if (Pread(Proc, &timestruc, sizeof (timestruc), offset)
286 		    != sizeof (timestruc))
287 			return;
288 	} else {
289 		timestruc32_t timestruc32;
290 
291 		if (Pread(Proc, &timestruc32, sizeof (timestruc32), offset)
292 		    != sizeof (timestruc32))
293 			return;
294 
295 		TIMESPEC32_TO_TIMESPEC(&timestruc, &timestruc32);
296 	}
297 
298 	(void) printf(
299 	    "%s\t%s: %ld.%9.9ld sec\n",
300 	    pri->pname,
301 	    name,
302 	    timestruc.tv_sec,
303 	    timestruc.tv_nsec);
304 }
305 
306 void
307 show_stime(private_t *pri)
308 {
309 	if (pri->sys_nargs >= 1) {
310 		/* print new system time */
311 		prtime(pri, "systime = ", (time_t)pri->sys_args[0]);
312 	}
313 }
314 
315 void
316 show_times(private_t *pri)
317 {
318 	long hz = sysconf(_SC_CLK_TCK);
319 	long offset;
320 	struct tms tms;
321 
322 	if (pri->sys_nargs < 1 || (offset = pri->sys_args[0]) == NULL)
323 		return;
324 
325 	if (data_model == PR_MODEL_NATIVE) {
326 		if (Pread(Proc, &tms, sizeof (tms), offset)
327 		    != sizeof (tms))
328 			return;
329 	} else {
330 		struct tms32 tms32;
331 
332 		if (Pread(Proc, &tms32, sizeof (tms32), offset)
333 		    != sizeof (tms32))
334 			return;
335 
336 		/*
337 		 * This looks a bit odd (since the values are actually
338 		 * signed), but we need to suppress sign extension to
339 		 * preserve compatibility (we've always printed these
340 		 * numbers as unsigned quantities).
341 		 */
342 		tms.tms_utime = (unsigned)tms32.tms_utime;
343 		tms.tms_stime = (unsigned)tms32.tms_stime;
344 		tms.tms_cutime = (unsigned)tms32.tms_cutime;
345 		tms.tms_cstime = (unsigned)tms32.tms_cstime;
346 	}
347 
348 	(void) printf(
349 	    "%s\tutim=%-6lu stim=%-6lu cutim=%-6lu cstim=%-6lu (HZ=%ld)\n",
350 	    pri->pname,
351 	    tms.tms_utime,
352 	    tms.tms_stime,
353 	    tms.tms_cutime,
354 	    tms.tms_cstime,
355 	    hz);
356 }
357 
358 void
359 show_uname(private_t *pri, long offset)
360 {
361 	/*
362 	 * Old utsname buffer (no longer accessible in <sys/utsname.h>).
363 	 */
364 	struct {
365 		char	sysname[9];
366 		char	nodename[9];
367 		char	release[9];
368 		char	version[9];
369 		char	machine[9];
370 	} ubuf;
371 
372 	if (offset != NULL &&
373 	    Pread(Proc, &ubuf, sizeof (ubuf), offset) == sizeof (ubuf)) {
374 		(void) printf(
375 		"%s\tsys=%-9.9snod=%-9.9srel=%-9.9sver=%-9.9smch=%.9s\n",
376 			pri->pname,
377 			ubuf.sysname,
378 			ubuf.nodename,
379 			ubuf.release,
380 			ubuf.version,
381 			ubuf.machine);
382 	}
383 }
384 
385 /* XX64 -- definition of 'struct ustat' is strange -- check out the defn */
386 void
387 show_ustat(private_t *pri, long offset)
388 {
389 	struct ustat ubuf;
390 
391 	if (offset != NULL &&
392 	    Pread(Proc, &ubuf, sizeof (ubuf), offset) == sizeof (ubuf)) {
393 		(void) printf(
394 		"%s\ttfree=%-6ld tinode=%-5lu fname=%-6.6s fpack=%-.6s\n",
395 			pri->pname,
396 			ubuf.f_tfree,
397 			ubuf.f_tinode,
398 			ubuf.f_fname,
399 			ubuf.f_fpack);
400 	}
401 }
402 
403 #ifdef _LP64
404 void
405 show_ustat32(private_t *pri, long offset)
406 {
407 	struct ustat32 ubuf;
408 
409 	if (offset != NULL &&
410 	    Pread(Proc, &ubuf, sizeof (ubuf), offset) == sizeof (ubuf)) {
411 		(void) printf(
412 		"%s\ttfree=%-6d tinode=%-5u fname=%-6.6s fpack=%-.6s\n",
413 			pri->pname,
414 			ubuf.f_tfree,
415 			ubuf.f_tinode,
416 			ubuf.f_fname,
417 			ubuf.f_fpack);
418 	}
419 }
420 #endif	/* _LP64 */
421 
422 void
423 show_fusers(private_t *pri, long offset, long nproc)
424 {
425 	f_user_t fubuf;
426 	int serial = (nproc > 4);
427 
428 	if (offset == NULL)
429 		return;
430 
431 	/* enter region of lengthy output */
432 	if (serial)
433 		Eserialize();
434 
435 	while (nproc > 0 &&
436 	    Pread(Proc, &fubuf, sizeof (fubuf), offset) == sizeof (fubuf)) {
437 		(void) printf("%s\tpid=%-5d uid=%-5d flags=%s\n",
438 		    pri->pname,
439 		    (int)fubuf.fu_pid,
440 		    (int)fubuf.fu_uid,
441 		    fuflags(pri, fubuf.fu_flags));
442 		nproc--;
443 		offset += sizeof (fubuf);
444 	}
445 
446 	/* exit region of lengthy output */
447 	if (serial)
448 		Xserialize();
449 }
450 
451 void
452 show_utssys(private_t *pri, long r0)
453 {
454 	if (pri->sys_nargs >= 3) {
455 		switch (pri->sys_args[2]) {
456 		case UTS_UNAME:
457 			show_uname(pri, (long)pri->sys_args[0]);
458 			break;
459 		case UTS_USTAT:
460 			show_ustat(pri, (long)pri->sys_args[0]);
461 			break;
462 		case UTS_FUSERS:
463 			show_fusers(pri, (long)pri->sys_args[3], r0);
464 			break;
465 		}
466 	}
467 }
468 
469 #ifdef _LP64
470 void
471 show_utssys32(private_t *pri, long r0)
472 {
473 	if (pri->sys_nargs >= 3) {
474 		switch (pri->sys_args[2]) {
475 		case UTS_UNAME:
476 			show_uname(pri, (long)pri->sys_args[0]);
477 			break;
478 		case UTS_USTAT:
479 			show_ustat32(pri, (long)pri->sys_args[0]);
480 			break;
481 		case UTS_FUSERS:
482 			show_fusers(pri, (long)pri->sys_args[3], r0);
483 			break;
484 		}
485 	}
486 }
487 #endif	/* _LP64 */
488 
489 void
490 show_cladm(private_t *pri, int code, int function, long offset)
491 {
492 	int	arg;
493 
494 	switch (code) {
495 	case CL_INITIALIZE:
496 		switch (function) {
497 		case CL_GET_BOOTFLAG:
498 			if (Pread(Proc, &arg, sizeof (arg), offset)
499 			    == sizeof (arg)) {
500 				if (arg & CLUSTER_CONFIGURED)
501 					(void) printf("%s\tbootflags="
502 					    "CLUSTER_CONFIGURED", pri->pname);
503 				if (arg & CLUSTER_BOOTED)
504 					(void) printf("|CLUSTER_BOOTED\n");
505 			}
506 			break;
507 		}
508 		break;
509 	case CL_CONFIG:
510 		switch (function) {
511 		case CL_NODEID:
512 		case CL_HIGHEST_NODEID:
513 			if (Pread(Proc, &arg, sizeof (arg), offset)
514 			    == sizeof (arg))
515 				(void) printf("%s\tnodeid=%d\n",
516 					pri->pname, arg);
517 		}
518 		break;
519 	}
520 }
521 
522 #define	ALL_LOCK_TYPES	\
523 	(USYNC_PROCESS|LOCK_ERRORCHECK|LOCK_RECURSIVE|USYNC_PROCESS_ROBUST|\
524 	    LOCK_PRIO_INHERIT|LOCK_PRIO_PROTECT|LOCK_ROBUST_NP)
525 
526 /* return cv and mutex types */
527 const char *
528 synch_type(private_t *pri, uint_t type)
529 {
530 	char *str = pri->code_buf;
531 
532 	if (type & USYNC_PROCESS)
533 		(void) strcpy(str, "USYNC_PROCESS");
534 	else
535 		(void) strcpy(str, "USYNC_THREAD");
536 
537 	if (type & LOCK_ERRORCHECK)
538 		(void) strcat(str, "|LOCK_ERRORCHECK");
539 	if (type & LOCK_RECURSIVE)
540 		(void) strcat(str, "|LOCK_RECURSIVE");
541 	if (type & USYNC_PROCESS_ROBUST)
542 		(void) strcat(str, "|USYNC_PROCESS_ROBUST");
543 	if (type & LOCK_PRIO_INHERIT)
544 		(void) strcat(str, "|LOCK_PRIO_INHERIT");
545 	if (type & LOCK_PRIO_PROTECT)
546 		(void) strcat(str, "|LOCK_PRIO_PROTECT");
547 	if (type & LOCK_ROBUST_NP)
548 		(void) strcat(str, "|LOCK_ROBUST_NP");
549 
550 	if ((type &= ~ALL_LOCK_TYPES) != 0)
551 		(void) sprintf(str + strlen(str), "|0x%.4X", type);
552 
553 	return ((const char *)str);
554 }
555 
556 void
557 show_mutex(private_t *pri, long offset)
558 {
559 	lwp_mutex_t mutex;
560 
561 	if (Pread(Proc, &mutex, sizeof (mutex), offset) == sizeof (mutex)) {
562 		(void) printf("%s\tmutex type: %s\n",
563 			pri->pname,
564 			synch_type(pri, mutex.mutex_type));
565 	}
566 }
567 
568 void
569 show_condvar(private_t *pri, long offset)
570 {
571 	lwp_cond_t condvar;
572 
573 	if (Pread(Proc, &condvar, sizeof (condvar), offset)
574 	    == sizeof (condvar)) {
575 		(void) printf("%s\tcondvar type: %s\n",
576 			pri->pname,
577 			synch_type(pri, condvar.cond_type));
578 	}
579 }
580 
581 void
582 show_sema(private_t *pri, long offset)
583 {
584 	lwp_sema_t sema;
585 
586 	if (Pread(Proc, &sema, sizeof (sema), offset) == sizeof (sema)) {
587 		(void) printf("%s\tsema type: %s  count = %u\n",
588 			pri->pname,
589 			synch_type(pri, sema.sema_type),
590 			sema.sema_count);
591 	}
592 }
593 
594 void
595 show_rwlock(private_t *pri, long offset)
596 {
597 	lwp_rwlock_t rwlock;
598 
599 	if (Pread(Proc, &rwlock, sizeof (rwlock), offset) == sizeof (rwlock)) {
600 		(void) printf("%s\trwlock type: %s  readers = %d\n",
601 			pri->pname,
602 			synch_type(pri, rwlock.rwlock_type),
603 			rwlock.rwlock_readers);
604 	}
605 }
606 
607 /* represent character as itself ('c') or octal (012) */
608 char *
609 show_char(char *buf, int c)
610 {
611 	const char *fmt;
612 
613 	if (c >= ' ' && c < 0177)
614 		fmt = "'%c'";
615 	else
616 		fmt = "%.3o";
617 
618 	(void) sprintf(buf, fmt, c&0xff);
619 	return (buf);
620 }
621 
622 void
623 show_termio(private_t *pri, long offset)
624 {
625 	struct termio termio;
626 	char cbuf[8];
627 	int i;
628 
629 	if (Pread(Proc, &termio, sizeof (termio), offset) == sizeof (termio)) {
630 		(void) printf(
631 		"%s\tiflag=0%.6o oflag=0%.6o cflag=0%.6o lflag=0%.6o line=%d\n",
632 			pri->pname,
633 			termio.c_iflag,
634 			termio.c_oflag,
635 			termio.c_cflag,
636 			termio.c_lflag,
637 			termio.c_line);
638 		(void) printf("%s\t    cc: ", pri->pname);
639 		for (i = 0; i < NCC; i++)
640 			(void) printf(" %s",
641 				show_char(cbuf, (int)termio.c_cc[i]));
642 		(void) fputc('\n', stdout);
643 	}
644 }
645 
646 void
647 show_termios(private_t *pri, long offset)
648 {
649 	struct termios termios;
650 	char cbuf[8];
651 	int i;
652 
653 	if (Pread(Proc, &termios, sizeof (termios), offset)
654 	    == sizeof (termios)) {
655 		(void) printf(
656 		"%s\tiflag=0%.6o oflag=0%.6o cflag=0%.6o lflag=0%.6o\n",
657 			pri->pname,
658 			termios.c_iflag,
659 			termios.c_oflag,
660 			termios.c_cflag,
661 			termios.c_lflag);
662 		(void) printf("%s\t    cc: ", pri->pname);
663 		for (i = 0; i < NCCS; i++) {
664 			if (i == NCC)	/* show new chars on new line */
665 				(void) printf("\n%s\t\t", pri->pname);
666 			(void) printf(" %s",
667 				show_char(cbuf, (int)termios.c_cc[i]));
668 		}
669 		(void) fputc('\n', stdout);
670 	}
671 }
672 
673 void
674 show_termiox(private_t *pri, long offset)
675 {
676 	struct termiox termiox;
677 	int i;
678 
679 	if (Pread(Proc, &termiox, sizeof (termiox), offset)
680 	    == sizeof (termiox)) {
681 		(void) printf("%s\thflag=0%.3o cflag=0%.3o rflag=0%.3o",
682 			pri->pname,
683 			termiox.x_hflag,
684 			termiox.x_cflag,
685 			termiox.x_rflag[0]);
686 		for (i = 1; i < NFF; i++)
687 			(void) printf(",0%.3o", termiox.x_rflag[i]);
688 		(void) printf(" sflag=0%.3o\n",
689 			termiox.x_sflag);
690 	}
691 }
692 
693 void
694 show_sgttyb(private_t *pri, long offset)
695 {
696 	struct sgttyb sgttyb;
697 
698 	if (Pread(Proc, &sgttyb, sizeof (sgttyb), offset) == sizeof (sgttyb)) {
699 		char erase[8];
700 		char kill[8];
701 
702 		(void) printf(
703 		"%s\tispeed=%-2d ospeed=%-2d erase=%s kill=%s flags=0x%.8x\n",
704 			pri->pname,
705 			sgttyb.sg_ispeed&0xff,
706 			sgttyb.sg_ospeed&0xff,
707 			show_char(erase, sgttyb.sg_erase),
708 			show_char(kill, sgttyb.sg_kill),
709 			sgttyb.sg_flags);
710 	}
711 }
712 
713 void
714 show_ltchars(private_t *pri, long offset)
715 {
716 	struct ltchars ltchars;
717 	char *p;
718 	char cbuf[8];
719 	int i;
720 
721 	if (Pread(Proc, &ltchars, sizeof (ltchars), offset)
722 	    == sizeof (ltchars)) {
723 		(void) printf("%s\t    cc: ", pri->pname);
724 		for (p = (char *)&ltchars, i = 0; i < sizeof (ltchars); i++)
725 			(void) printf(" %s", show_char(cbuf, (int)*p++));
726 		(void) fputc('\n', stdout);
727 	}
728 }
729 
730 void
731 show_tchars(private_t *pri, long offset)
732 {
733 	struct tchars tchars;
734 	char *p;
735 	char cbuf[8];
736 	int i;
737 
738 	if (Pread(Proc, &tchars, sizeof (tchars), offset) == sizeof (tchars)) {
739 		(void) printf("%s\t    cc: ", pri->pname);
740 		for (p = (char *)&tchars, i = 0; i < sizeof (tchars); i++)
741 			(void) printf(" %s", show_char(cbuf, (int)*p++));
742 		(void) fputc('\n', stdout);
743 	}
744 }
745 
746 void
747 show_termcb(private_t *pri, long offset)
748 {
749 	struct termcb termcb;
750 
751 	if (Pread(Proc, &termcb, sizeof (termcb), offset) == sizeof (termcb)) {
752 		(void) printf(
753 		"%s\tflgs=0%.2o termt=%d crow=%d ccol=%d vrow=%d lrow=%d\n",
754 			pri->pname,
755 			termcb.st_flgs&0xff,
756 			termcb.st_termt&0xff,
757 			termcb.st_crow&0xff,
758 			termcb.st_ccol&0xff,
759 			termcb.st_vrow&0xff,
760 			termcb.st_lrow&0xff);
761 	}
762 }
763 
764 /* integer value pointed to by ioctl() arg */
765 void
766 show_strint(private_t *pri, int code, long offset)
767 {
768 	int val;
769 
770 	if (Pread(Proc, &val, sizeof (val), offset) == sizeof (val)) {
771 		const char *s = NULL;
772 
773 		switch (code) {		/* interpret these symbolically */
774 		case I_GRDOPT:
775 			s = strrdopt(val);
776 			break;
777 		case I_GETSIG:
778 			s = strevents(pri, val);
779 			break;
780 		case TIOCFLUSH:
781 			s = tiocflush(pri, val);
782 			break;
783 		}
784 
785 		if (s == NULL)
786 			(void) printf("%s\t0x%.8lX: %d\n",
787 				pri->pname, offset, val);
788 		else
789 			(void) printf("%s\t0x%.8lX: %s\n",
790 				pri->pname, offset, s);
791 	}
792 }
793 
794 void
795 show_strioctl(private_t *pri, long offset)
796 {
797 	struct strioctl strioctl;
798 
799 	if (Pread(Proc, &strioctl, sizeof (strioctl), offset) ==
800 	    sizeof (strioctl)) {
801 		(void) printf(
802 			"%s\tcmd=%s timout=%d len=%d dp=0x%.8lX\n",
803 			pri->pname,
804 			ioctlname(pri, strioctl.ic_cmd),
805 			strioctl.ic_timout,
806 			strioctl.ic_len,
807 			(long)strioctl.ic_dp);
808 
809 		if (pri->recur++ == 0)	/* avoid indefinite recursion */
810 			show_ioctl(pri, strioctl.ic_cmd,
811 				(long)strioctl.ic_dp);
812 		--pri->recur;
813 	}
814 }
815 
816 #ifdef _LP64
817 void
818 show_strioctl32(private_t *pri, long offset)
819 {
820 	struct strioctl32 strioctl;
821 
822 	if (Pread(Proc, &strioctl, sizeof (strioctl), offset) ==
823 	    sizeof (strioctl)) {
824 		(void) printf(
825 			"%s\tcmd=%s timout=%d len=%d dp=0x%.8lX\n",
826 			pri->pname,
827 			ioctlname(pri, strioctl.ic_cmd),
828 			strioctl.ic_timout,
829 			strioctl.ic_len,
830 			(long)strioctl.ic_dp);
831 
832 		if (pri->recur++ == 0)	/* avoid indefinite recursion */
833 			show_ioctl(pri, strioctl.ic_cmd,
834 				(long)strioctl.ic_dp);
835 		--pri->recur;
836 	}
837 }
838 #endif	/* _LP64 */
839 
840 void
841 print_strbuf(private_t *pri, struct strbuf *sp, const char *name, int dump)
842 {
843 	(void) printf(
844 		"%s\t%s:  maxlen=%-4d len=%-4d buf=0x%.8lX",
845 		pri->pname,
846 		name,
847 		sp->maxlen,
848 		sp->len,
849 		(long)sp->buf);
850 	/*
851 	 * Should we show the buffer contents?
852 	 * Keyed to the '-r fds' and '-w fds' options?
853 	 */
854 	if (sp->buf == NULL || sp->len <= 0)
855 		(void) fputc('\n', stdout);
856 	else {
857 		int nb = (sp->len > 8)? 8 : sp->len;
858 		char buffer[8];
859 		char obuf[40];
860 
861 		if (Pread(Proc, buffer, (size_t)nb, (long)sp->buf) == nb) {
862 			(void) strcpy(obuf, ": \"");
863 			showbytes(buffer, nb, obuf+3);
864 			(void) strcat(obuf,
865 				(nb == sp->len)?
866 				    (const char *)"\"" : (const char *)"\"..");
867 			(void) fputs(obuf, stdout);
868 		}
869 		(void) fputc('\n', stdout);
870 		if (dump && sp->len > 8)
871 			showbuffer(pri, (long)sp->buf, (long)sp->len);
872 	}
873 }
874 
875 #ifdef _LP64
876 void
877 print_strbuf32(private_t *pri, struct strbuf32 *sp, const char *name, int dump)
878 {
879 	(void) printf(
880 		"%s\t%s:  maxlen=%-4d len=%-4d buf=0x%.8lX",
881 		pri->pname,
882 		name,
883 		sp->maxlen,
884 		sp->len,
885 		(long)sp->buf);
886 	/*
887 	 * Should we show the buffer contents?
888 	 * Keyed to the '-r fds' and '-w fds' options?
889 	 */
890 	if (sp->buf == NULL || sp->len <= 0)
891 		(void) fputc('\n', stdout);
892 	else {
893 		int nb = (sp->len > 8)? 8 : sp->len;
894 		char buffer[8];
895 		char obuf[40];
896 
897 		if (Pread(Proc, buffer, (size_t)nb, (long)sp->buf) == nb) {
898 			(void) strcpy(obuf, ": \"");
899 			showbytes(buffer, nb, obuf+3);
900 			(void) strcat(obuf,
901 				(nb == sp->len)?
902 				    (const char *)"\"" : (const char *)"\"..");
903 			(void) fputs(obuf, stdout);
904 		}
905 		(void) fputc('\n', stdout);
906 		if (dump && sp->len > 8)
907 			showbuffer(pri, (long)sp->buf, (long)sp->len);
908 	}
909 }
910 #endif	/* _LP64 */
911 
912 /* strpeek and strfdinsert flags word */
913 const char *
914 strflags(private_t *pri, int flags)
915 {
916 	const char *s;
917 
918 	switch (flags) {
919 	case 0:
920 		s = "0";
921 		break;
922 	case RS_HIPRI:
923 		s = "RS_HIPRI";
924 		break;
925 	default:
926 		(void) sprintf(pri->code_buf, "0x%.4X", flags);
927 		s = pri->code_buf;
928 	}
929 
930 	return (s);
931 }
932 
933 void
934 show_strpeek(private_t *pri, long offset)
935 {
936 	struct strpeek strpeek;
937 
938 	if (Pread(Proc, &strpeek, sizeof (strpeek), offset)
939 	    == sizeof (strpeek)) {
940 
941 		print_strbuf(pri, &strpeek.ctlbuf, "ctl", FALSE);
942 		print_strbuf(pri, &strpeek.databuf, "dat", FALSE);
943 
944 		(void) printf("%s\tflags=%s\n",
945 			pri->pname,
946 			strflags(pri, strpeek.flags));
947 	}
948 }
949 
950 #ifdef _LP64
951 void
952 show_strpeek32(private_t *pri, long offset)
953 {
954 	struct strpeek32 strpeek;
955 
956 	if (Pread(Proc, &strpeek, sizeof (strpeek), offset)
957 	    == sizeof (strpeek)) {
958 
959 		print_strbuf32(pri, &strpeek.ctlbuf, "ctl", FALSE);
960 		print_strbuf32(pri, &strpeek.databuf, "dat", FALSE);
961 
962 		(void) printf("%s\tflags=%s\n",
963 			pri->pname,
964 			strflags(pri, strpeek.flags));
965 	}
966 }
967 #endif	/* _LP64 */
968 
969 void
970 show_strfdinsert(private_t *pri, long offset)
971 {
972 	struct strfdinsert strfdinsert;
973 
974 	if (Pread(Proc, &strfdinsert, sizeof (strfdinsert), offset) ==
975 	    sizeof (strfdinsert)) {
976 
977 		print_strbuf(pri, &strfdinsert.ctlbuf, "ctl", FALSE);
978 		print_strbuf(pri, &strfdinsert.databuf, "dat", FALSE);
979 
980 		(void) printf("%s\tflags=%s fildes=%d offset=%d\n",
981 			pri->pname,
982 			strflags(pri, strfdinsert.flags),
983 			strfdinsert.fildes,
984 			strfdinsert.offset);
985 	}
986 }
987 
988 #ifdef _LP64
989 void
990 show_strfdinsert32(private_t *pri, long offset)
991 {
992 	struct strfdinsert32 strfdinsert;
993 
994 	if (Pread(Proc, &strfdinsert, sizeof (strfdinsert), offset) ==
995 	    sizeof (strfdinsert)) {
996 
997 		print_strbuf32(pri, &strfdinsert.ctlbuf, "ctl", FALSE);
998 		print_strbuf32(pri, &strfdinsert.databuf, "dat", FALSE);
999 
1000 		(void) printf("%s\tflags=%s fildes=%d offset=%d\n",
1001 			pri->pname,
1002 			strflags(pri, strfdinsert.flags),
1003 			strfdinsert.fildes,
1004 			strfdinsert.offset);
1005 	}
1006 }
1007 #endif	/* _LP64 */
1008 
1009 void
1010 show_strrecvfd(private_t *pri, long offset)
1011 {
1012 	struct strrecvfd strrecvfd;
1013 
1014 	if (Pread(Proc, &strrecvfd, sizeof (strrecvfd), offset) ==
1015 	    sizeof (strrecvfd)) {
1016 		(void) printf(
1017 			"%s\tfd=%-5d uid=%-5d gid=%d\n",
1018 			pri->pname,
1019 			strrecvfd.fd,
1020 			(int)strrecvfd.uid,
1021 			(int)strrecvfd.gid);
1022 	}
1023 }
1024 
1025 void
1026 show_strlist(private_t *pri, long offset)
1027 {
1028 	struct str_list strlist;
1029 	struct str_mlist list;
1030 	int count;
1031 
1032 	if (Pread(Proc, &strlist, sizeof (strlist), offset) ==
1033 	    sizeof (strlist)) {
1034 		(void) printf("%s\tnmods=%d  modlist=0x%.8lX\n",
1035 			pri->pname,
1036 			strlist.sl_nmods,
1037 			(long)strlist.sl_modlist);
1038 
1039 		count = strlist.sl_nmods;
1040 		offset = (long)strlist.sl_modlist;
1041 		while (!interrupt && --count >= 0) {
1042 			if (Pread(Proc, &list, sizeof (list), offset) !=
1043 			    sizeof (list))
1044 				break;
1045 			(void) printf("%s\t\t\"%.*s\"\n",
1046 				pri->pname,
1047 				(int)sizeof (list.l_name),
1048 				list.l_name);
1049 			offset += sizeof (struct str_mlist);
1050 		}
1051 	}
1052 }
1053 
1054 #ifdef _LP64
1055 void
1056 show_strlist32(private_t *pri, long offset)
1057 {
1058 	struct str_list32 strlist;
1059 	struct str_mlist list;
1060 	int count;
1061 
1062 	if (Pread(Proc, &strlist, sizeof (strlist), offset) ==
1063 	    sizeof (strlist)) {
1064 		(void) printf("%s\tnmods=%d  modlist=0x%.8lX\n",
1065 			pri->pname,
1066 			strlist.sl_nmods,
1067 			(long)strlist.sl_modlist);
1068 
1069 		count = strlist.sl_nmods;
1070 		offset = (long)strlist.sl_modlist;
1071 		while (!interrupt && --count >= 0) {
1072 			if (Pread(Proc, &list, sizeof (list), offset) !=
1073 			    sizeof (list))
1074 				break;
1075 			(void) printf("%s\t\t\"%.*s\"\n",
1076 				pri->pname,
1077 				(int)sizeof (list.l_name),
1078 				list.l_name);
1079 			offset += sizeof (struct str_mlist);
1080 		}
1081 	}
1082 }
1083 #endif	/* _LP64 */
1084 
1085 void
1086 show_jwinsize(private_t *pri, long offset)
1087 {
1088 	struct jwinsize jwinsize;
1089 
1090 	if (Pread(Proc, &jwinsize, sizeof (jwinsize), offset) ==
1091 	    sizeof (jwinsize)) {
1092 		(void) printf(
1093 			"%s\tbytesx=%-3u bytesy=%-3u bitsx=%-3u bitsy=%-3u\n",
1094 			pri->pname,
1095 			(unsigned)jwinsize.bytesx,
1096 			(unsigned)jwinsize.bytesy,
1097 			(unsigned)jwinsize.bitsx,
1098 			(unsigned)jwinsize.bitsy);
1099 	}
1100 }
1101 
1102 void
1103 show_winsize(private_t *pri, long offset)
1104 {
1105 	struct winsize winsize;
1106 
1107 	if (Pread(Proc, &winsize, sizeof (winsize), offset)
1108 	    == sizeof (winsize)) {
1109 		(void) printf(
1110 			"%s\trow=%-3d col=%-3d xpixel=%-3d ypixel=%-3d\n",
1111 			pri->pname,
1112 			winsize.ws_row,
1113 			winsize.ws_col,
1114 			winsize.ws_xpixel,
1115 			winsize.ws_ypixel);
1116 	}
1117 }
1118 
1119 struct audio_stuff {
1120 	uint_t	bit;
1121 	const char *str;
1122 };
1123 
1124 const struct audio_stuff audio_output_ports[] = {
1125 	{ AUDIO_SPEAKER, "SPEAKER" },
1126 	{ AUDIO_HEADPHONE, "HEADPHONE" },
1127 	{ AUDIO_LINE_OUT, "LINE_OUT" },
1128 	{ AUDIO_SPDIF_OUT, "SPDIF_OUT" },
1129 	{ AUDIO_AUX1_OUT, "AUX1_OUT" },
1130 	{ AUDIO_AUX2_OUT, "AUX2_OUT" },
1131 	{ 0, NULL }
1132 };
1133 
1134 const struct audio_stuff audio_input_ports[] = {
1135 	{ AUDIO_MICROPHONE, "MICROPHONE" },
1136 	{ AUDIO_LINE_IN, "LINE_IN" },
1137 	{ AUDIO_CD, "CD" },
1138 	{ AUDIO_SPDIF_IN, "SPDIF_IN" },
1139 	{ AUDIO_AUX1_IN, "AUX1_IN" },
1140 	{ AUDIO_AUX2_IN, "AUX2_IN" },
1141 	{ AUDIO_CODEC_LOOPB_IN, "CODEC_LOOPB_IN" },
1142 	{ AUDIO_SUNVTS, "SUNVTS" },
1143 	{ 0, NULL }
1144 };
1145 
1146 static const struct audio_stuff audio_hw_features[] = {
1147 	{ AUDIO_HWFEATURE_DUPLEX, "DUPLEX" },
1148 	{ AUDIO_HWFEATURE_MSCODEC, "MSCODEC" },
1149 	{ AUDIO_HWFEATURE_IN2OUT, "IN2OUT" },
1150 	{ AUDIO_HWFEATURE_PLAY, "PLAY" },
1151 	{ AUDIO_HWFEATURE_RECORD, "RECORD" },
1152 	{ 0, NULL }
1153 };
1154 
1155 static const struct audio_stuff audio_sw_features[] = {
1156 	{ AUDIO_SWFEATURE_MIXER, "MIXER" },
1157 	{ 0, NULL }
1158 };
1159 
1160 void
1161 show_audio_features(const private_t *pri,
1162 	const struct audio_stuff *audio_porttab, uint_t features,
1163 	const char *name)
1164 {
1165 	(void) printf("%s\t%s=", pri->pname, name);
1166 	if (features == 0) {
1167 		(void) printf("0\n");
1168 		return;
1169 	}
1170 
1171 	for (; audio_porttab->bit != 0; ++audio_porttab) {
1172 		if (features & audio_porttab->bit) {
1173 			(void) printf(audio_porttab->str);
1174 			features &= ~audio_porttab->bit;
1175 			if (features)
1176 				(void) putchar('|');
1177 		}
1178 	}
1179 	if (features)
1180 		(void) printf("0x%x", features);
1181 	(void) putchar('\n');
1182 }
1183 
1184 void
1185 show_audio_ports(private_t *pri, const char *mode,
1186 	const char *field, uint_t ports)
1187 {
1188 	const struct audio_stuff *audio_porttab;
1189 
1190 	(void) printf("%s\t%s\t%s=", pri->pname, mode, field);
1191 	if (ports == 0) {
1192 		(void) printf("0\n");
1193 		return;
1194 	}
1195 	if (*mode == 'p')
1196 		audio_porttab = audio_output_ports;
1197 	else
1198 		audio_porttab = audio_input_ports;
1199 	for (; audio_porttab->bit != 0; ++audio_porttab) {
1200 		if (ports & audio_porttab->bit) {
1201 			(void) printf(audio_porttab->str);
1202 			ports &= ~audio_porttab->bit;
1203 			if (ports)
1204 				(void) putchar('|');
1205 		}
1206 	}
1207 	if (ports)
1208 		(void) printf("0x%x", ports);
1209 	(void) putchar('\n');
1210 }
1211 
1212 void
1213 show_audio_prinfo(private_t *pri, const char *mode, struct audio_prinfo *au_pr)
1214 {
1215 	const char *s;
1216 
1217 	/*
1218 	 * The following values describe the audio data encoding.
1219 	 */
1220 
1221 	(void) printf("%s\t%s\tsample_rate=%u channels=%u precision=%u\n",
1222 		pri->pname, mode,
1223 		au_pr->sample_rate,
1224 		au_pr->channels,
1225 		au_pr->precision);
1226 
1227 	s = NULL;
1228 	switch (au_pr->encoding) {
1229 	case AUDIO_ENCODING_NONE:	s = "NONE";	break;
1230 	case AUDIO_ENCODING_ULAW:	s = "ULAW";	break;
1231 	case AUDIO_ENCODING_ALAW:	s = "ALAW";	break;
1232 	case AUDIO_ENCODING_LINEAR:	s = "LINEAR";	break;
1233 	case AUDIO_ENCODING_DVI:	s = "DVI";	break;
1234 	case AUDIO_ENCODING_LINEAR8:	s = "LINEAR8";	break;
1235 	}
1236 	if (s)
1237 		(void) printf("%s\t%s\tencoding=%s\n", pri->pname, mode, s);
1238 	else {
1239 		(void) printf("%s\t%s\tencoding=%u\n",
1240 			pri->pname, mode, au_pr->encoding);
1241 	}
1242 
1243 	/*
1244 	 * The following values control audio device configuration
1245 	 */
1246 
1247 	(void) printf(
1248 	"%s\t%s\tgain=%u buffer_size=%u\n",
1249 		pri->pname, mode,
1250 		au_pr->gain,
1251 		au_pr->buffer_size);
1252 	show_audio_ports(pri, mode, "port", au_pr->port);
1253 	show_audio_ports(pri, mode, "avail_ports", au_pr->avail_ports);
1254 	show_audio_ports(pri, mode, "mod_ports", au_pr->mod_ports);
1255 
1256 	/*
1257 	 * The following values describe driver state
1258 	 */
1259 
1260 	(void) printf("%s\t%s\tsamples=%u eof=%u pause=%u error=%u\n",
1261 		pri->pname, mode,
1262 		au_pr->samples,
1263 		au_pr->eof,
1264 		au_pr->pause,
1265 		au_pr->error);
1266 	(void) printf("%s\t%s\twaiting=%u balance=%u minordev=%u\n",
1267 		pri->pname, mode,
1268 		au_pr->waiting,
1269 		au_pr->balance,
1270 		au_pr->minordev);
1271 
1272 	/*
1273 	 * The following values are read-only state flags
1274 	 */
1275 	(void) printf("%s\t%s\topen=%u active=%u\n",
1276 		pri->pname, mode,
1277 		au_pr->open,
1278 		au_pr->active);
1279 }
1280 
1281 void
1282 show_audio_info(private_t *pri, long offset)
1283 {
1284 	struct audio_info au;
1285 
1286 	if (Pread(Proc, &au, sizeof (au), offset) == sizeof (au)) {
1287 		show_audio_prinfo(pri, "play", &au.play);
1288 		show_audio_prinfo(pri, "record", &au.record);
1289 		(void) printf("%s\tmonitor_gain=%u output_muted=%u\n",
1290 			pri->pname, au.monitor_gain, au.output_muted);
1291 		show_audio_features(pri, audio_hw_features, au.hw_features,
1292 		    "hw_features");
1293 		show_audio_features(pri, audio_sw_features, au.sw_features,
1294 		    "sw_features");
1295 		show_audio_features(pri, audio_sw_features,
1296 		    au.sw_features_enabled, "sw_features_enabled");
1297 	}
1298 }
1299 
1300 void
1301 show_ioctl(private_t *pri, int code, long offset)
1302 {
1303 	int lp64 = (data_model == PR_MODEL_LP64);
1304 	int err = pri->Errno;	/* don't display output parameters */
1305 				/* for a failed system call */
1306 #ifndef _LP64
1307 	if (lp64)
1308 		return;
1309 #endif
1310 	if (offset == NULL)
1311 		return;
1312 
1313 	switch (code) {
1314 	case TCGETA:
1315 		if (err)
1316 			break;
1317 		/*FALLTHROUGH*/
1318 	case TCSETA:
1319 	case TCSETAW:
1320 	case TCSETAF:
1321 		show_termio(pri, offset);
1322 		break;
1323 	case TCGETS:
1324 		if (err)
1325 			break;
1326 		/*FALLTHROUGH*/
1327 	case TCSETS:
1328 	case TCSETSW:
1329 	case TCSETSF:
1330 		show_termios(pri, offset);
1331 		break;
1332 	case TCGETX:
1333 		if (err)
1334 			break;
1335 		/*FALLTHROUGH*/
1336 	case TCSETX:
1337 	case TCSETXW:
1338 	case TCSETXF:
1339 		show_termiox(pri, offset);
1340 		break;
1341 	case TIOCGETP:
1342 		if (err)
1343 			break;
1344 		/*FALLTHROUGH*/
1345 	case TIOCSETN:
1346 	case TIOCSETP:
1347 		show_sgttyb(pri, offset);
1348 		break;
1349 	case TIOCGLTC:
1350 		if (err)
1351 			break;
1352 		/*FALLTHROUGH*/
1353 	case TIOCSLTC:
1354 		show_ltchars(pri, offset);
1355 		break;
1356 	case TIOCGETC:
1357 		if (err)
1358 			break;
1359 		/*FALLTHROUGH*/
1360 	case TIOCSETC:
1361 		show_tchars(pri, offset);
1362 		break;
1363 	case LDGETT:
1364 		if (err)
1365 			break;
1366 		/*FALLTHROUGH*/
1367 	case LDSETT:
1368 		show_termcb(pri, offset);
1369 		break;
1370 	/* streams ioctl()s */
1371 #if 0
1372 		/* these are displayed as strings in the arg list */
1373 		/* by prt_ioa().  don't display them again here */
1374 	case I_PUSH:
1375 	case I_LOOK:
1376 	case I_FIND:
1377 		/* these are displayed as decimal in the arg list */
1378 		/* by prt_ioa().  don't display them again here */
1379 	case I_LINK:
1380 	case I_UNLINK:
1381 	case I_SENDFD:
1382 		/* these are displayed symbolically in the arg list */
1383 		/* by prt_ioa().  don't display them again here */
1384 	case I_SRDOPT:
1385 	case I_SETSIG:
1386 	case I_FLUSH:
1387 		break;
1388 		/* this one just ignores the argument */
1389 	case I_POP:
1390 		break;
1391 #endif
1392 		/* these return something in an int pointed to by arg */
1393 	case I_NREAD:
1394 	case I_GRDOPT:
1395 	case I_GETSIG:
1396 	case TIOCGSID:
1397 	case TIOCGPGRP:
1398 	case TIOCLGET:
1399 	case FIONREAD:
1400 	case FIORDCHK:
1401 		if (err)
1402 			break;
1403 		/*FALLTHROUGH*/
1404 		/* these pass something in an int pointed to by arg */
1405 	case TIOCSPGRP:
1406 	case TIOCFLUSH:
1407 	case TIOCLBIS:
1408 	case TIOCLBIC:
1409 	case TIOCLSET:
1410 		show_strint(pri, code, offset);
1411 		break;
1412 		/* these all point to structures */
1413 	case I_STR:
1414 #ifdef _LP64
1415 		if (lp64)
1416 			show_strioctl(pri, offset);
1417 		else
1418 			show_strioctl32(pri, offset);
1419 #else
1420 		show_strioctl(pri, offset);
1421 #endif
1422 		break;
1423 	case I_PEEK:
1424 #ifdef _LP64
1425 		if (lp64)
1426 			show_strpeek(pri, offset);
1427 		else
1428 			show_strpeek32(pri, offset);
1429 #else
1430 		show_strpeek(pri, offset);
1431 #endif
1432 		break;
1433 	case I_FDINSERT:
1434 #ifdef _LP64
1435 		if (lp64)
1436 			show_strfdinsert(pri, offset);
1437 		else
1438 			show_strfdinsert32(pri, offset);
1439 #else
1440 		show_strfdinsert(pri, offset);
1441 #endif
1442 		break;
1443 	case I_RECVFD:
1444 		if (err)
1445 			break;
1446 		show_strrecvfd(pri, offset);
1447 		break;
1448 	case I_LIST:
1449 		if (err)
1450 			break;
1451 #ifdef _LP64
1452 		if (lp64)
1453 			show_strlist(pri, offset);
1454 		else
1455 			show_strlist32(pri, offset);
1456 #else
1457 		show_strlist(pri, offset);
1458 #endif
1459 		break;
1460 	case JWINSIZE:
1461 		if (err)
1462 			break;
1463 		show_jwinsize(pri, offset);
1464 		break;
1465 	case TIOCGWINSZ:
1466 		if (err)
1467 			break;
1468 		/*FALLTHROUGH*/
1469 	case TIOCSWINSZ:
1470 		show_winsize(pri, offset);
1471 		break;
1472 	case AUDIO_GETINFO:
1473 	case (int)AUDIO_SETINFO:
1474 		show_audio_info(pri, offset);
1475 		break;
1476 
1477 	default:
1478 		if (code & IOC_INOUT) {
1479 			const char *str = ioctldatastruct(code);
1480 
1481 			(void) printf("\t\t%s",
1482 			    (code & IOC_INOUT) == IOC_INOUT ? "write/read" :
1483 			    code & IOC_IN ? "write" : "read");
1484 			if (str != NULL) {
1485 				(void) printf(" (struct %s)\n", str);
1486 			} else {
1487 				(void) printf(" %d bytes\n",
1488 				    (code >> 16) & IOCPARM_MASK);
1489 			}
1490 		}
1491 	}
1492 }
1493 
1494 void
1495 show_statvfs(private_t *pri)
1496 {
1497 	long offset;
1498 	struct statvfs statvfs;
1499 	char *cp;
1500 
1501 	if (pri->sys_nargs > 1 && (offset = pri->sys_args[1]) != NULL &&
1502 	    Pread(Proc, &statvfs, sizeof (statvfs), offset)
1503 	    == sizeof (statvfs)) {
1504 		(void) printf(
1505 		"%s\tbsize=%-10lu frsize=%-9lu blocks=%-8llu bfree=%-9llu\n",
1506 			pri->pname,
1507 			statvfs.f_bsize,
1508 			statvfs.f_frsize,
1509 			(u_longlong_t)statvfs.f_blocks,
1510 			(u_longlong_t)statvfs.f_bfree);
1511 		(void) printf(
1512 		"%s\tbavail=%-9llu files=%-10llu ffree=%-9llu favail=%-9llu\n",
1513 			pri->pname,
1514 			(u_longlong_t)statvfs.f_bavail,
1515 			(u_longlong_t)statvfs.f_files,
1516 			(u_longlong_t)statvfs.f_ffree,
1517 			(u_longlong_t)statvfs.f_favail);
1518 		(void) printf(
1519 		"%s\tfsid=0x%-9.4lX basetype=%-7.16s namemax=%ld\n",
1520 			pri->pname,
1521 			statvfs.f_fsid,
1522 			statvfs.f_basetype,
1523 			(long)statvfs.f_namemax);
1524 		(void) printf(
1525 		"%s\tflag=%s\n",
1526 			pri->pname,
1527 			svfsflags(pri, (ulong_t)statvfs.f_flag));
1528 		cp = statvfs.f_fstr + strlen(statvfs.f_fstr);
1529 		if (cp < statvfs.f_fstr + sizeof (statvfs.f_fstr) - 1 &&
1530 		    *(cp+1) != '\0')
1531 			*cp = ' ';
1532 		(void) printf("%s\tfstr=\"%.*s\"\n",
1533 			pri->pname,
1534 			(int)sizeof (statvfs.f_fstr),
1535 			statvfs.f_fstr);
1536 	}
1537 }
1538 
1539 #ifdef _LP64
1540 void
1541 show_statvfs32(private_t *pri)
1542 {
1543 	long offset;
1544 	struct statvfs32 statvfs;
1545 	char *cp;
1546 
1547 	if (pri->sys_nargs > 1 && (offset = pri->sys_args[1]) != NULL &&
1548 	    Pread(Proc, &statvfs, sizeof (statvfs), offset)
1549 	    == sizeof (statvfs)) {
1550 		(void) printf(
1551 		"%s\tbsize=%-10u frsize=%-9u blocks=%-8u bfree=%-9u\n",
1552 			pri->pname,
1553 			statvfs.f_bsize,
1554 			statvfs.f_frsize,
1555 			statvfs.f_blocks,
1556 			statvfs.f_bfree);
1557 		(void) printf(
1558 		"%s\tbavail=%-9u files=%-10u ffree=%-9u favail=%-9u\n",
1559 			pri->pname,
1560 			statvfs.f_bavail,
1561 			statvfs.f_files,
1562 			statvfs.f_ffree,
1563 			statvfs.f_favail);
1564 		(void) printf(
1565 		"%s\tfsid=0x%-9.4X basetype=%-7.16s namemax=%d\n",
1566 			pri->pname,
1567 			statvfs.f_fsid,
1568 			statvfs.f_basetype,
1569 			(int)statvfs.f_namemax);
1570 		(void) printf(
1571 		"%s\tflag=%s\n",
1572 			pri->pname,
1573 			svfsflags(pri, (ulong_t)statvfs.f_flag));
1574 		cp = statvfs.f_fstr + strlen(statvfs.f_fstr);
1575 		if (cp < statvfs.f_fstr + sizeof (statvfs.f_fstr) - 1 &&
1576 		    *(cp+1) != '\0')
1577 			*cp = ' ';
1578 		(void) printf("%s\tfstr=\"%.*s\"\n",
1579 			pri->pname,
1580 			(int)sizeof (statvfs.f_fstr),
1581 			statvfs.f_fstr);
1582 	}
1583 }
1584 #endif	/* _LP64 */
1585 
1586 void
1587 show_statvfs64(private_t *pri)
1588 {
1589 	long offset;
1590 	struct statvfs64_32 statvfs;
1591 	char *cp;
1592 
1593 	if (pri->sys_nargs > 1 && (offset = pri->sys_args[1]) != NULL &&
1594 	    Pread(Proc, &statvfs, sizeof (statvfs), offset)
1595 	    == sizeof (statvfs)) {
1596 		(void) printf(
1597 		"%s\tbsize=%-10u frsize=%-9u blocks=%-8llu bfree=%-9llu\n",
1598 			pri->pname,
1599 			statvfs.f_bsize,
1600 			statvfs.f_frsize,
1601 			(u_longlong_t)statvfs.f_blocks,
1602 			(u_longlong_t)statvfs.f_bfree);
1603 		(void) printf(
1604 		"%s\tbavail=%-9llu files=%-10llu ffree=%-9llu favail=%-9llu\n",
1605 			pri->pname,
1606 			(u_longlong_t)statvfs.f_bavail,
1607 			(u_longlong_t)statvfs.f_files,
1608 			(u_longlong_t)statvfs.f_ffree,
1609 			(u_longlong_t)statvfs.f_favail);
1610 		(void) printf(
1611 		"%s\tfsid=0x%-9.4X basetype=%-7.16s namemax=%d\n",
1612 			pri->pname,
1613 			statvfs.f_fsid,
1614 			statvfs.f_basetype,
1615 			(int)statvfs.f_namemax);
1616 		(void) printf(
1617 		"%s\tflag=%s\n",
1618 			pri->pname,
1619 			svfsflags(pri, (ulong_t)statvfs.f_flag));
1620 		cp = statvfs.f_fstr + strlen(statvfs.f_fstr);
1621 		if (cp < statvfs.f_fstr + sizeof (statvfs.f_fstr) - 1 &&
1622 		    *(cp+1) != '\0')
1623 			*cp = ' ';
1624 		(void) printf("%s\tfstr=\"%.*s\"\n",
1625 			pri->pname,
1626 			(int)sizeof (statvfs.f_fstr),
1627 			statvfs.f_fstr);
1628 	}
1629 }
1630 
1631 void
1632 show_statfs(private_t *pri)
1633 {
1634 	long offset;
1635 	struct statfs statfs;
1636 
1637 	if (pri->sys_nargs >= 2 && (offset = pri->sys_args[1]) != NULL &&
1638 	    Pread(Proc, &statfs, sizeof (statfs), offset) == sizeof (statfs)) {
1639 		(void) printf(
1640 		"%s\tfty=%d bsz=%ld fsz=%ld blk=%ld bfr=%ld fil=%lu ffr=%lu\n",
1641 			pri->pname,
1642 			statfs.f_fstyp,
1643 			statfs.f_bsize,
1644 			statfs.f_frsize,
1645 			statfs.f_blocks,
1646 			statfs.f_bfree,
1647 			statfs.f_files,
1648 			statfs.f_ffree);
1649 		(void) printf("%s\t    fname=%.6s fpack=%.6s\n",
1650 			pri->pname,
1651 			statfs.f_fname,
1652 			statfs.f_fpack);
1653 	}
1654 }
1655 
1656 #ifdef _LP64
1657 void
1658 show_statfs32(private_t *pri)
1659 {
1660 	long offset;
1661 	struct statfs32 statfs;
1662 
1663 	if (pri->sys_nargs >= 2 && (offset = pri->sys_args[1]) != NULL &&
1664 	    Pread(Proc, &statfs, sizeof (statfs), offset) == sizeof (statfs)) {
1665 		(void) printf(
1666 		"%s\tfty=%d bsz=%d fsz=%d blk=%d bfr=%d fil=%u ffr=%u\n",
1667 			pri->pname,
1668 			statfs.f_fstyp,
1669 			statfs.f_bsize,
1670 			statfs.f_frsize,
1671 			statfs.f_blocks,
1672 			statfs.f_bfree,
1673 			statfs.f_files,
1674 			statfs.f_ffree);
1675 		(void) printf("%s\t    fname=%.6s fpack=%.6s\n",
1676 			pri->pname,
1677 			statfs.f_fname,
1678 			statfs.f_fpack);
1679 	}
1680 }
1681 #endif	/* _LP64 */
1682 
1683 void
1684 show_flock32(private_t *pri, long offset)
1685 {
1686 	struct flock32 flock;
1687 
1688 	if (Pread(Proc, &flock, sizeof (flock), offset) == sizeof (flock)) {
1689 		const char *str = NULL;
1690 
1691 		(void) printf("%s\ttyp=", pri->pname);
1692 
1693 		switch (flock.l_type) {
1694 		case F_RDLCK:
1695 			str = "F_RDLCK";
1696 			break;
1697 		case F_WRLCK:
1698 			str = "F_WRLCK";
1699 			break;
1700 		case F_UNLCK:
1701 			str = "F_UNLCK";
1702 			break;
1703 		}
1704 		if (str != NULL)
1705 			(void) printf("%s", str);
1706 		else
1707 			(void) printf("%-7d", flock.l_type);
1708 
1709 		str = whencearg(flock.l_whence);
1710 		if (str != NULL)
1711 			(void) printf("  whence=%s", str);
1712 		else
1713 			(void) printf("  whence=%-8u", flock.l_whence);
1714 
1715 		(void) printf(
1716 			" start=%-5d len=%-5d sys=%-2u pid=%d\n",
1717 			flock.l_start,
1718 			flock.l_len,
1719 			flock.l_sysid,
1720 			flock.l_pid);
1721 	}
1722 }
1723 
1724 void
1725 show_flock64(private_t *pri, long offset)
1726 {
1727 	struct flock64 flock;
1728 
1729 	if (Pread(Proc, &flock, sizeof (flock), offset) == sizeof (flock)) {
1730 		const char *str = NULL;
1731 
1732 		(void) printf("%s\ttyp=", pri->pname);
1733 
1734 		switch (flock.l_type) {
1735 		case F_RDLCK:
1736 			str = "F_RDLCK";
1737 			break;
1738 		case F_WRLCK:
1739 			str = "F_WRLCK";
1740 			break;
1741 		case F_UNLCK:
1742 			str = "F_UNLCK";
1743 			break;
1744 		}
1745 		if (str != NULL)
1746 			(void) printf("%s", str);
1747 		else
1748 			(void) printf("%-7d", flock.l_type);
1749 
1750 		str = whencearg(flock.l_whence);
1751 		if (str != NULL)
1752 			(void) printf("  whence=%s", str);
1753 		else
1754 			(void) printf("  whence=%-8u", flock.l_whence);
1755 
1756 		(void) printf(
1757 			" start=%-5lld len=%-5lld sys=%-2u pid=%d\n",
1758 			(long long)flock.l_start,
1759 			(long long)flock.l_len,
1760 			flock.l_sysid,
1761 			(int)flock.l_pid);
1762 	}
1763 }
1764 
1765 void
1766 show_share(private_t *pri, long offset)
1767 {
1768 	struct fshare fshare;
1769 
1770 	if (Pread(Proc, &fshare, sizeof (fshare), offset) == sizeof (fshare)) {
1771 		const char *str = NULL;
1772 		int manddny = 0;
1773 
1774 		(void) printf("%s\taccess=", pri->pname);
1775 
1776 		switch (fshare.f_access) {
1777 		case F_RDACC:
1778 			str = "F_RDACC";
1779 			break;
1780 		case F_WRACC:
1781 			str = "F_WRACC";
1782 			break;
1783 		case F_RWACC:
1784 			str = "F_RWACC";
1785 			break;
1786 		}
1787 		if (str != NULL)
1788 			(void) printf("%s", str);
1789 		else
1790 			(void) printf("%-7d", fshare.f_access);
1791 
1792 		str = NULL;
1793 		if (fshare.f_deny & F_MANDDNY) {
1794 			fshare.f_deny &= ~F_MANDDNY;
1795 			manddny = 1;
1796 		}
1797 		switch (fshare.f_deny) {
1798 		case F_NODNY:
1799 			str = "F_NODNY";
1800 			break;
1801 		case F_RDDNY:
1802 			str = "F_RDDNY";
1803 			break;
1804 		case F_WRDNY:
1805 			str = "F_WRDNY";
1806 			break;
1807 		case F_RWDNY:
1808 			str = "F_RWDNY";
1809 			break;
1810 		case F_COMPAT:
1811 			str = "F_COMPAT";
1812 			break;
1813 		}
1814 		if (str != NULL) {
1815 			if (manddny)
1816 				(void) printf("  deny=F_MANDDNY|%s", str);
1817 			else
1818 				(void) printf("  deny=%s", str);
1819 		} else {
1820 			(void) printf("  deny=0x%x", manddny?
1821 				fshare.f_deny | F_MANDDNY : fshare.f_deny);
1822 		}
1823 
1824 		(void) printf("  id=%x\n", fshare.f_id);
1825 	}
1826 }
1827 
1828 void
1829 show_ffg(private_t *pri)
1830 {
1831 	(void) putchar('\t');
1832 	(void) putchar('\t');
1833 	prt_ffg(pri, 0, pri->Rval1);
1834 	(void) puts(pri->sys_string);
1835 }
1836 
1837 /* print values in fcntl() pointed-to structure */
1838 void
1839 show_fcntl(private_t *pri)
1840 {
1841 	long offset;
1842 
1843 	if (pri->sys_nargs >= 2 && pri->sys_args[1] == F_GETFL) {
1844 		show_ffg(pri);
1845 		return;
1846 	}
1847 
1848 	if (pri->sys_nargs < 3 || (offset = pri->sys_args[2]) == NULL)
1849 		return;
1850 
1851 	switch (pri->sys_args[1]) {
1852 #ifdef _LP64
1853 	case F_GETLK:
1854 	case F_SETLK:
1855 	case F_SETLKW:
1856 	case F_FREESP:
1857 	case F_ALLOCSP:
1858 	case F_SETLK_NBMAND:
1859 		if (data_model == PR_MODEL_LP64)
1860 			show_flock64(pri, offset);
1861 		else
1862 			show_flock32(pri, offset);
1863 		break;
1864 	case 33:	/* F_GETLK64 */
1865 	case 34:	/* F_SETLK64 */
1866 	case 35:	/* F_SETLKW64 */
1867 	case 27:	/* F_FREESP64 */
1868 	case 44:	/* F_SETLK64_NBMAND */
1869 		show_flock64(pri, offset);
1870 		break;
1871 #else	/* _LP64 */
1872 	case F_GETLK:
1873 	case F_SETLK:
1874 	case F_SETLKW:
1875 	case F_FREESP:
1876 	case F_ALLOCSP:
1877 	case F_SETLK_NBMAND:
1878 		show_flock32(pri, offset);
1879 		break;
1880 	case F_GETLK64:
1881 	case F_SETLK64:
1882 	case F_SETLKW64:
1883 	case F_FREESP64:
1884 	case F_SETLK64_NBMAND:
1885 		show_flock64(pri, offset);
1886 		break;
1887 #endif	/* _LP64 */
1888 	case F_SHARE:
1889 	case F_UNSHARE:
1890 		show_share(pri, offset);
1891 		break;
1892 	}
1893 }
1894 
1895 void
1896 show_strbuf(private_t *pri, long offset, const char *name, int dump)
1897 {
1898 	struct strbuf strbuf;
1899 
1900 	if (Pread(Proc, &strbuf, sizeof (strbuf), offset) == sizeof (strbuf))
1901 		print_strbuf(pri, &strbuf, name, dump);
1902 }
1903 
1904 #ifdef _LP64
1905 void
1906 show_strbuf32(private_t *pri, long offset, const char *name, int dump)
1907 {
1908 	struct strbuf32 strbuf;
1909 
1910 	if (Pread(Proc, &strbuf, sizeof (strbuf), offset) == sizeof (strbuf))
1911 		print_strbuf32(pri, &strbuf, name, dump);
1912 }
1913 #endif	/* _LP64 */
1914 
1915 void
1916 show_gp_msg(private_t *pri, int what)
1917 {
1918 	long offset;
1919 	int dump = FALSE;
1920 	int fdp1 = pri->sys_args[0] + 1;
1921 
1922 	switch (what) {
1923 	case SYS_getmsg:
1924 	case SYS_getpmsg:
1925 		if (pri->Errno == 0 && prismember(&readfd, fdp1))
1926 			dump = TRUE;
1927 		break;
1928 	case SYS_putmsg:
1929 	case SYS_putpmsg:
1930 		if (prismember(&writefd, fdp1))
1931 			dump = TRUE;
1932 		break;
1933 	}
1934 
1935 	/* enter region of lengthy output */
1936 	if (dump)
1937 		Eserialize();
1938 
1939 #ifdef _LP64
1940 	if (pri->sys_nargs >= 2 && (offset = pri->sys_args[1]) != NULL) {
1941 		if (data_model == PR_MODEL_LP64)
1942 			show_strbuf(pri, offset, "ctl", dump);
1943 		else
1944 			show_strbuf32(pri, offset, "ctl", dump);
1945 	}
1946 	if (pri->sys_nargs >= 3 && (offset = pri->sys_args[2]) != NULL) {
1947 		if (data_model == PR_MODEL_LP64)
1948 			show_strbuf(pri, offset, "dat", dump);
1949 		else
1950 			show_strbuf32(pri, offset, "dat", dump);
1951 	}
1952 #else	/* _LP64 */
1953 	if (pri->sys_nargs >= 2 && (offset = pri->sys_args[1]) != NULL)
1954 		show_strbuf(pri, offset, "ctl", dump);
1955 	if (pri->sys_nargs >= 3 && (offset = pri->sys_args[2]) != NULL)
1956 		show_strbuf(pri, offset, "dat", dump);
1957 #endif	/* _LP64 */
1958 
1959 	/* exit region of lengthy output */
1960 	if (dump)
1961 		Xserialize();
1962 }
1963 
1964 void
1965 show_int(private_t *pri, long offset, const char *name)
1966 {
1967 	int value;
1968 
1969 	if (offset != 0 &&
1970 	    Pread(Proc, &value, sizeof (value), offset) == sizeof (value))
1971 		(void) printf("%s\t%s:\t%d\n",
1972 			pri->pname,
1973 			name,
1974 			value);
1975 }
1976 
1977 void
1978 show_hhex_int(private_t *pri, long offset, const char *name)
1979 {
1980 	int value;
1981 
1982 	if (Pread(Proc, &value, sizeof (value), offset) == sizeof (value))
1983 		(void) printf("%s\t%s:\t0x%.4X\n",
1984 			pri->pname,
1985 			name,
1986 			value);
1987 }
1988 
1989 #define	ALL_POLL_FLAGS	(POLLIN|POLLPRI|POLLOUT| \
1990 	POLLRDNORM|POLLRDBAND|POLLWRBAND|POLLERR|POLLHUP|POLLNVAL)
1991 
1992 const char *
1993 pollevent(private_t *pri, int arg)
1994 {
1995 	char *str = pri->code_buf;
1996 
1997 	if (arg == 0)
1998 		return ("0");
1999 	if (arg & ~ALL_POLL_FLAGS) {
2000 		(void) sprintf(str, "0x%-5X", arg);
2001 		return ((const char *)str);
2002 	}
2003 
2004 	*str = '\0';
2005 	if (arg & POLLIN)
2006 		(void) strcat(str, "|POLLIN");
2007 	if (arg & POLLPRI)
2008 		(void) strcat(str, "|POLLPRI");
2009 	if (arg & POLLOUT)
2010 		(void) strcat(str, "|POLLOUT");
2011 	if (arg & POLLRDNORM)
2012 		(void) strcat(str, "|POLLRDNORM");
2013 	if (arg & POLLRDBAND)
2014 		(void) strcat(str, "|POLLRDBAND");
2015 	if (arg & POLLWRBAND)
2016 		(void) strcat(str, "|POLLWRBAND");
2017 	if (arg & POLLERR)
2018 		(void) strcat(str, "|POLLERR");
2019 	if (arg & POLLHUP)
2020 		(void) strcat(str, "|POLLHUP");
2021 	if (arg & POLLNVAL)
2022 		(void) strcat(str, "|POLLNVAL");
2023 
2024 	return ((const char *)(str+1));
2025 }
2026 
2027 static void
2028 show_one_pollfd(private_t *pri, struct pollfd *ppollfd)
2029 {
2030 	/*
2031 	 * can't print both events and revents in same printf.
2032 	 * pollevent() returns a pointer to a TSD location.
2033 	 */
2034 	(void) printf("%s\tfd=%-2d ev=%s",
2035 	    pri->pname, ppollfd->fd, pollevent(pri, ppollfd->events));
2036 	(void) printf(" rev=%s\n", pollevent(pri, ppollfd->revents));
2037 }
2038 
2039 static void
2040 show_all_pollfds(private_t *pri, long offset, int nfds)
2041 {
2042 	struct pollfd pollfd[2];
2043 	int skip = -1;
2044 
2045 	for (; nfds && !interrupt; nfds--, offset += sizeof (struct pollfd)) {
2046 		if (Pread(Proc, &pollfd[0], sizeof (struct pollfd), offset) !=
2047 		    sizeof (struct pollfd))
2048 			continue;
2049 
2050 		if (skip >= 0 && pollfd[0].fd == pollfd[1].fd &&
2051 		    pollfd[0].events == pollfd[1].events &&
2052 		    pollfd[0].revents == pollfd[1].revents) {
2053 			skip++;
2054 			continue;
2055 		}
2056 
2057 		if (skip > 0)
2058 			(void) printf("%s\t...last pollfd structure"
2059 			    " repeated %d time%s...\n",
2060 			    pri->pname, skip, (skip == 1 ? "" : "s"));
2061 
2062 		skip = 0;
2063 		show_one_pollfd(pri, &pollfd[0]);
2064 		pollfd[1] = pollfd[0];
2065 	}
2066 
2067 	if (skip > 0)
2068 		(void) printf(
2069 		    "%s\t...last pollfd structure repeated %d time%s...\n",
2070 		    pri->pname, skip, (skip == 1 ? "" : "s"));
2071 }
2072 
2073 void
2074 show_poll(private_t *pri)
2075 {
2076 	long offset;
2077 	int nfds;
2078 	int serial = 0;
2079 
2080 	if (pri->sys_nargs < 2 || (offset = pri->sys_args[0]) == NULL ||
2081 	    (nfds = pri->sys_args[1]) <= 0)
2082 		return;
2083 
2084 	/* enter region of lengthy output */
2085 	if (nfds > 32) {
2086 		Eserialize();
2087 		serial = 1;
2088 	}
2089 
2090 	show_all_pollfds(pri, offset, nfds);
2091 
2092 	/* exit region of lengthy output */
2093 	if (serial)
2094 		Xserialize();
2095 }
2096 
2097 void
2098 show_pollsys(private_t *pri)
2099 {
2100 	long offset;
2101 	int nfds;
2102 	int serial = 0;
2103 
2104 	if (pri->sys_nargs < 2)
2105 		return;
2106 
2107 	offset = pri->sys_args[0];
2108 	nfds = pri->sys_args[1];
2109 
2110 	/* enter region of lengthy output */
2111 	if (offset != NULL && nfds > 32) {
2112 		Eserialize();
2113 		serial = 1;
2114 	}
2115 
2116 	if (offset != NULL && nfds > 0)
2117 		show_all_pollfds(pri, offset, nfds);
2118 
2119 	if (pri->sys_nargs > 2)
2120 		show_timestruc(pri, (long)pri->sys_args[2], "timeout");
2121 
2122 	if (pri->sys_nargs > 3)
2123 		show_sigset(pri, (long)pri->sys_args[3], "sigmask");
2124 
2125 	/* exit region of lengthy output */
2126 	if (serial)
2127 		Xserialize();
2128 }
2129 
2130 static void
2131 show_perm64(private_t *pri, struct ipc_perm64 *ip)
2132 {
2133 	(void) printf("%s\tu=%-5d g=%-5d cu=%-5d cg=%-5d z=%-5d "
2134 	    "m=0%.6o key=%d projid=%-5d\n",
2135 	    pri->pname,
2136 	    (int)ip->ipcx_uid,
2137 	    (int)ip->ipcx_gid,
2138 	    (int)ip->ipcx_cuid,
2139 	    (int)ip->ipcx_cgid,
2140 	    (int)ip->ipcx_zoneid,
2141 	    (unsigned int)ip->ipcx_mode,
2142 	    ip->ipcx_key,
2143 	    (int)ip->ipcx_projid);
2144 }
2145 
2146 void
2147 show_perm(private_t *pri, struct ipc_perm *ip)
2148 {
2149 	(void) printf(
2150 	"%s\tu=%-5u g=%-5u cu=%-5u cg=%-5u m=0%.6o seq=%u key=%d\n",
2151 		pri->pname,
2152 		(int)ip->uid,
2153 		(int)ip->gid,
2154 		(int)ip->cuid,
2155 		(int)ip->cgid,
2156 		(int)ip->mode,
2157 		ip->seq,
2158 		ip->key);
2159 }
2160 
2161 #ifdef _LP64
2162 void
2163 show_perm32(private_t *pri, struct ipc_perm32 *ip)
2164 {
2165 	(void) printf(
2166 	"%s\tu=%-5u g=%-5u cu=%-5u cg=%-5u m=0%.6o seq=%u key=%d\n",
2167 		pri->pname,
2168 		ip->uid,
2169 		ip->gid,
2170 		ip->cuid,
2171 		ip->cgid,
2172 		ip->mode,
2173 		ip->seq,
2174 		ip->key);
2175 }
2176 #endif	/* _LP64 */
2177 
2178 static void
2179 show_msgctl64(private_t *pri, long offset)
2180 {
2181 	struct msqid_ds64 msgq;
2182 
2183 	if (offset != NULL &&
2184 	    Pread(Proc, &msgq, sizeof (msgq), offset) == sizeof (msgq)) {
2185 		show_perm64(pri, &msgq.msgx_perm);
2186 
2187 		(void) printf("%s\tbytes=%-5llu msgs=%-5llu maxby=%-5llu "
2188 		    "lspid=%-5d lrpid=%-5d\n", pri->pname,
2189 		    (unsigned long long)msgq.msgx_cbytes,
2190 		    (unsigned long long)msgq.msgx_qnum,
2191 		    (unsigned long long)msgq.msgx_qbytes,
2192 		    (int)msgq.msgx_lspid,
2193 		    (int)msgq.msgx_lrpid);
2194 
2195 		prtime(pri, "    st = ", (time_t)msgq.msgx_stime);
2196 		prtime(pri, "    rt = ", (time_t)msgq.msgx_rtime);
2197 		prtime(pri, "    ct = ", (time_t)msgq.msgx_ctime);
2198 	}
2199 }
2200 
2201 void
2202 show_msgctl(private_t *pri, long offset)
2203 {
2204 	struct msqid_ds msgq;
2205 
2206 	if (offset != NULL &&
2207 	    Pread(Proc, &msgq, sizeof (msgq), offset) == sizeof (msgq)) {
2208 		show_perm(pri, &msgq.msg_perm);
2209 
2210 		(void) printf(
2211 	"%s\tbytes=%-5lu msgs=%-5lu maxby=%-5lu lspid=%-5u lrpid=%-5u\n",
2212 			pri->pname,
2213 			msgq.msg_cbytes,
2214 			msgq.msg_qnum,
2215 			msgq.msg_qbytes,
2216 			(int)msgq.msg_lspid,
2217 			(int)msgq.msg_lrpid);
2218 
2219 		prtime(pri, "    st = ", msgq.msg_stime);
2220 		prtime(pri, "    rt = ", msgq.msg_rtime);
2221 		prtime(pri, "    ct = ", msgq.msg_ctime);
2222 	}
2223 }
2224 
2225 #ifdef _LP64
2226 void
2227 show_msgctl32(private_t *pri, long offset)
2228 {
2229 	struct msqid_ds32 msgq;
2230 
2231 	if (offset != NULL &&
2232 	    Pread(Proc, &msgq, sizeof (msgq), offset) == sizeof (msgq)) {
2233 		show_perm32(pri, &msgq.msg_perm);
2234 
2235 		(void) printf(
2236 	"%s\tbytes=%-5u msgs=%-5u maxby=%-5u lspid=%-5u lrpid=%-5u\n",
2237 			pri->pname,
2238 			msgq.msg_cbytes,
2239 			msgq.msg_qnum,
2240 			msgq.msg_qbytes,
2241 			msgq.msg_lspid,
2242 			msgq.msg_lrpid);
2243 
2244 		prtime(pri, "    st = ", msgq.msg_stime);
2245 		prtime(pri, "    rt = ", msgq.msg_rtime);
2246 		prtime(pri, "    ct = ", msgq.msg_ctime);
2247 	}
2248 }
2249 #endif	/* _LP64 */
2250 
2251 void
2252 show_msgbuf(private_t *pri, long offset, long msgsz)
2253 {
2254 	struct msgbuf msgb;
2255 
2256 	if (offset != NULL &&
2257 	    Pread(Proc, &msgb, sizeof (msgb.mtype), offset) ==
2258 	    sizeof (msgb.mtype)) {
2259 		/* enter region of lengthy output */
2260 		if (msgsz > MYBUFSIZ / 4)
2261 			Eserialize();
2262 
2263 		(void) printf("%s\tmtype=%lu  mtext[]=\n",
2264 			pri->pname,
2265 			msgb.mtype);
2266 		showbuffer(pri,
2267 			(long)(offset + sizeof (msgb.mtype)), msgsz);
2268 
2269 		/* exit region of lengthy output */
2270 		if (msgsz > MYBUFSIZ / 4)
2271 			Xserialize();
2272 	}
2273 }
2274 
2275 #ifdef _LP64
2276 void
2277 show_msgbuf32(private_t *pri, long offset, long msgsz)
2278 {
2279 	struct ipcmsgbuf32 msgb;
2280 
2281 	if (offset != NULL &&
2282 	    Pread(Proc, &msgb, sizeof (msgb.mtype), offset) ==
2283 	    sizeof (msgb.mtype)) {
2284 		/* enter region of lengthy output */
2285 		if (msgsz > MYBUFSIZ / 4)
2286 			Eserialize();
2287 
2288 		(void) printf("%s\tmtype=%u  mtext[]=\n",
2289 			pri->pname,
2290 			msgb.mtype);
2291 		showbuffer(pri,
2292 			(long)(offset + sizeof (msgb.mtype)), msgsz);
2293 
2294 		/* exit region of lengthy output */
2295 		if (msgsz > MYBUFSIZ / 4)
2296 			Xserialize();
2297 	}
2298 }
2299 #endif	/* _LP64 */
2300 
2301 #ifdef _LP64
2302 void
2303 show_msgsys(private_t *pri, long msgsz)
2304 {
2305 	switch (pri->sys_args[0]) {
2306 	case 0:			/* msgget() */
2307 		break;
2308 	case 1:			/* msgctl() */
2309 		if (pri->sys_nargs > 3) {
2310 			switch (pri->sys_args[2]) {
2311 			case IPC_STAT:
2312 				if (pri->Errno)
2313 					break;
2314 				/*FALLTHROUGH*/
2315 			case IPC_SET:
2316 				if (data_model == PR_MODEL_LP64)
2317 					show_msgctl(pri,
2318 						(long)pri->sys_args[3]);
2319 				else
2320 					show_msgctl32(pri,
2321 						(long)pri->sys_args[3]);
2322 				break;
2323 			case IPC_STAT64:
2324 				if (pri->Errno)
2325 					break;
2326 				/*FALLTHROUGH*/
2327 			case IPC_SET64:
2328 				show_msgctl64(pri, (long)pri->sys_args[3]);
2329 				break;
2330 			}
2331 		}
2332 		break;
2333 	case 2:			/* msgrcv() */
2334 		if (!pri->Errno && pri->sys_nargs > 2) {
2335 			if (data_model == PR_MODEL_LP64)
2336 				show_msgbuf(pri, pri->sys_args[2], msgsz);
2337 			else
2338 				show_msgbuf32(pri, pri->sys_args[2], msgsz);
2339 		}
2340 		break;
2341 	case 3:			/* msgsnd() */
2342 		if (pri->sys_nargs > 3) {
2343 			if (data_model == PR_MODEL_LP64)
2344 				show_msgbuf(pri, pri->sys_args[2],
2345 					pri->sys_args[3]);
2346 			else
2347 				show_msgbuf32(pri, pri->sys_args[2],
2348 					pri->sys_args[3]);
2349 		}
2350 		break;
2351 	case 4:			/* msgids() */
2352 	case 5:			/* msgsnap() */
2353 	default:		/* unexpected subcode */
2354 		break;
2355 	}
2356 }
2357 #else	/* _LP64 */
2358 void
2359 show_msgsys(private_t *pri, long msgsz)
2360 {
2361 	switch (pri->sys_args[0]) {
2362 	case 0:			/* msgget() */
2363 		break;
2364 	case 1:			/* msgctl() */
2365 		if (pri->sys_nargs > 3) {
2366 			switch (pri->sys_args[2]) {
2367 			case IPC_STAT:
2368 				if (pri->Errno)
2369 					break;
2370 				/*FALLTHROUGH*/
2371 			case IPC_SET:
2372 				show_msgctl(pri, (long)pri->sys_args[3]);
2373 				break;
2374 			case IPC_STAT64:
2375 				if (pri->Errno)
2376 					break;
2377 				/*FALLTHROUGH*/
2378 			case IPC_SET64:
2379 				show_msgctl64(pri, (long)pri->sys_args[3]);
2380 				break;
2381 			}
2382 		}
2383 		break;
2384 	case 2:			/* msgrcv() */
2385 		if (!pri->Errno && pri->sys_nargs > 2)
2386 			show_msgbuf(pri, pri->sys_args[2], msgsz);
2387 		break;
2388 	case 3:			/* msgsnd() */
2389 		if (pri->sys_nargs > 3)
2390 			show_msgbuf(pri, pri->sys_args[2],
2391 				pri->sys_args[3]);
2392 		break;
2393 	case 4:			/* msgids() */
2394 	case 5:			/* msgsnap() */
2395 	default:		/* unexpected subcode */
2396 		break;
2397 	}
2398 }
2399 #endif	/* _LP64 */
2400 
2401 static void
2402 show_semctl64(private_t *pri, long offset)
2403 {
2404 	struct semid_ds64 semds;
2405 
2406 	if (offset != NULL &&
2407 	    Pread(Proc, &semds, sizeof (semds), offset) == sizeof (semds)) {
2408 		show_perm64(pri, &semds.semx_perm);
2409 
2410 		(void) printf("%s\tnsems=%u\n", pri->pname, semds.semx_nsems);
2411 
2412 		prtime(pri, "    ot = ", (time_t)semds.semx_otime);
2413 		prtime(pri, "    ct = ", (time_t)semds.semx_ctime);
2414 	}
2415 }
2416 
2417 void
2418 show_semctl(private_t *pri, long offset)
2419 {
2420 	struct semid_ds semds;
2421 
2422 	if (offset != NULL &&
2423 	    Pread(Proc, &semds, sizeof (semds), offset) == sizeof (semds)) {
2424 		show_perm(pri, &semds.sem_perm);
2425 
2426 		(void) printf("%s\tnsems=%u\n",
2427 			pri->pname,
2428 			semds.sem_nsems);
2429 
2430 		prtime(pri, "    ot = ", semds.sem_otime);
2431 		prtime(pri, "    ct = ", semds.sem_ctime);
2432 	}
2433 }
2434 
2435 #ifdef _LP64
2436 void
2437 show_semctl32(private_t *pri, long offset)
2438 {
2439 	struct semid_ds32 semds;
2440 
2441 	if (offset != NULL &&
2442 	    Pread(Proc, &semds, sizeof (semds), offset) == sizeof (semds)) {
2443 		show_perm32(pri, &semds.sem_perm);
2444 
2445 		(void) printf("%s\tnsems=%u\n",
2446 			pri->pname,
2447 			semds.sem_nsems);
2448 
2449 		prtime(pri, "    ot = ", semds.sem_otime);
2450 		prtime(pri, "    ct = ", semds.sem_ctime);
2451 	}
2452 }
2453 #endif	/* _LP64 */
2454 
2455 void
2456 show_semop(private_t *pri, long offset, long nsops, long timeout)
2457 {
2458 	struct sembuf sembuf;
2459 	const char *str;
2460 
2461 	if (offset == NULL)
2462 		return;
2463 
2464 	if (nsops > 40)		/* let's not be ridiculous */
2465 		nsops = 40;
2466 
2467 	for (; nsops > 0 && !interrupt; --nsops, offset += sizeof (sembuf)) {
2468 		if (Pread(Proc, &sembuf, sizeof (sembuf), offset) !=
2469 		    sizeof (sembuf))
2470 			break;
2471 
2472 		(void) printf("%s\tsemnum=%-5u semop=%-5d semflg=",
2473 			pri->pname,
2474 			sembuf.sem_num,
2475 			sembuf.sem_op);
2476 
2477 		if (sembuf.sem_flg == 0)
2478 			(void) printf("0\n");
2479 		else if ((str = semflags(pri, sembuf.sem_flg)) != NULL)
2480 			(void) printf("%s\n", str);
2481 		else
2482 			(void) printf("0%.6o\n", sembuf.sem_flg);
2483 	}
2484 	if (timeout)
2485 		show_timestruc(pri, timeout, "timeout");
2486 }
2487 
2488 void
2489 show_semsys(private_t *pri)
2490 {
2491 	switch (pri->sys_args[0]) {
2492 	case 0:			/* semctl() */
2493 		if (pri->sys_nargs > 4) {
2494 			switch (pri->sys_args[3]) {
2495 			case IPC_STAT:
2496 				if (pri->Errno)
2497 					break;
2498 				/*FALLTHROUGH*/
2499 			case IPC_SET:
2500 #ifdef _LP64
2501 				if (data_model == PR_MODEL_LP64)
2502 					show_semctl(pri,
2503 						(long)pri->sys_args[4]);
2504 				else
2505 					show_semctl32(pri,
2506 						(long)pri->sys_args[4]);
2507 #else
2508 				show_semctl(pri, (long)pri->sys_args[4]);
2509 #endif
2510 				break;
2511 			case IPC_STAT64:
2512 				if (pri->Errno)
2513 					break;
2514 				/*FALLTHROUGH*/
2515 			case IPC_SET64:
2516 				show_semctl64(pri, (long)pri->sys_args[4]);
2517 				break;
2518 			}
2519 		}
2520 		break;
2521 	case 1:			/* semget() */
2522 		break;
2523 	case 2:			/* semop() */
2524 		if (pri->sys_nargs > 3)
2525 			show_semop(pri, (long)pri->sys_args[2],
2526 				pri->sys_args[3], 0);
2527 		break;
2528 	case 3:			/* semids() */
2529 		break;
2530 	case 4:			/* semtimedop() */
2531 		if (pri->sys_nargs > 4)
2532 			show_semop(pri, (long)pri->sys_args[2],
2533 				pri->sys_args[3], pri->sys_args[4]);
2534 		break;
2535 	default:		/* unexpected subcode */
2536 		break;
2537 	}
2538 }
2539 
2540 static void
2541 show_shmctl64(private_t *pri, long offset)
2542 {
2543 	struct shmid_ds64 shmds;
2544 
2545 	if (offset != NULL &&
2546 	    Pread(Proc, &shmds, sizeof (shmds), offset) == sizeof (shmds)) {
2547 		show_perm64(pri, &shmds.shmx_perm);
2548 
2549 		(void) printf(
2550 		    "%s\tsize=%-6llu lpid=%-5d cpid=%-5d na=%-5llu cna=%llu\n",
2551 		    pri->pname,
2552 		    (unsigned long long)shmds.shmx_segsz,
2553 		    (int)shmds.shmx_lpid,
2554 		    (int)shmds.shmx_cpid,
2555 		    (unsigned long long)shmds.shmx_nattch,
2556 		    (unsigned long long)shmds.shmx_cnattch);
2557 
2558 		prtime(pri, "    at = ", (time_t)shmds.shmx_atime);
2559 		prtime(pri, "    dt = ", (time_t)shmds.shmx_dtime);
2560 		prtime(pri, "    ct = ", (time_t)shmds.shmx_ctime);
2561 	}
2562 }
2563 
2564 void
2565 show_shmctl(private_t *pri, long offset)
2566 {
2567 	struct shmid_ds shmds;
2568 
2569 	if (offset != NULL &&
2570 	    Pread(Proc, &shmds, sizeof (shmds), offset) == sizeof (shmds)) {
2571 		show_perm(pri, &shmds.shm_perm);
2572 
2573 		(void) printf(
2574 		"%s\tsize=%-6lu lpid=%-5u cpid=%-5u na=%-5lu cna=%lu\n",
2575 			pri->pname,
2576 			(ulong_t)shmds.shm_segsz,
2577 			(int)shmds.shm_lpid,
2578 			(int)shmds.shm_cpid,
2579 			shmds.shm_nattch,
2580 			shmds.shm_cnattch);
2581 
2582 		prtime(pri, "    at = ", shmds.shm_atime);
2583 		prtime(pri, "    dt = ", shmds.shm_dtime);
2584 		prtime(pri, "    ct = ", shmds.shm_ctime);
2585 	}
2586 }
2587 
2588 #ifdef _LP64
2589 void
2590 show_shmctl32(private_t *pri, long offset)
2591 {
2592 	struct shmid_ds32 shmds;
2593 
2594 	if (offset != NULL &&
2595 	    Pread(Proc, &shmds, sizeof (shmds), offset) == sizeof (shmds)) {
2596 		show_perm32(pri, &shmds.shm_perm);
2597 
2598 		(void) printf(
2599 		"%s\tsize=%-6u lpid=%-5u cpid=%-5u na=%-5u cna=%u\n",
2600 			pri->pname,
2601 			shmds.shm_segsz,
2602 			shmds.shm_lpid,
2603 			shmds.shm_cpid,
2604 			shmds.shm_nattch,
2605 			shmds.shm_cnattch);
2606 
2607 		prtime(pri, "    at = ", shmds.shm_atime);
2608 		prtime(pri, "    dt = ", shmds.shm_dtime);
2609 		prtime(pri, "    ct = ", shmds.shm_ctime);
2610 	}
2611 }
2612 #endif	/* _LP64 */
2613 
2614 void
2615 show_shmsys(private_t *pri)
2616 {
2617 	switch (pri->sys_args[0]) {
2618 	case 0:			/* shmat() */
2619 		break;
2620 	case 1:			/* shmctl() */
2621 		if (pri->sys_nargs > 3) {
2622 			switch (pri->sys_args[2]) {
2623 			case IPC_STAT:
2624 				if (pri->Errno)
2625 					break;
2626 				/*FALLTHROUGH*/
2627 			case IPC_SET:
2628 #ifdef _LP64
2629 				if (data_model == PR_MODEL_LP64)
2630 					show_shmctl(pri,
2631 						(long)pri->sys_args[3]);
2632 				else
2633 					show_shmctl32(pri,
2634 						(long)pri->sys_args[3]);
2635 #else
2636 				show_shmctl(pri, (long)pri->sys_args[3]);
2637 #endif
2638 				break;
2639 			case IPC_STAT64:
2640 				if (pri->Errno)
2641 					break;
2642 				/*FALLTHROUGH*/
2643 			case IPC_SET64:
2644 				show_shmctl64(pri, (long)pri->sys_args[3]);
2645 				break;
2646 			}
2647 		}
2648 		break;
2649 	case 2:			/* shmdt() */
2650 	case 3:			/* shmget() */
2651 	case 4:			/* shmids() */
2652 	default:		/* unexpected subcode */
2653 		break;
2654 	}
2655 }
2656 
2657 void
2658 show_groups(private_t *pri, long offset, long count)
2659 {
2660 	int groups[100];
2661 
2662 	if (count > 100)
2663 		count = 100;
2664 
2665 	if (count > 0 && offset != NULL &&
2666 	    Pread(Proc, &groups[0], count*sizeof (int), offset) ==
2667 	    count*sizeof (int)) {
2668 		int n;
2669 
2670 		(void) printf("%s\t", pri->pname);
2671 		for (n = 0; !interrupt && n < count; n++) {
2672 			if (n != 0 && n%10 == 0)
2673 				(void) printf("\n%s\t", pri->pname);
2674 			(void) printf(" %5d", groups[n]);
2675 		}
2676 		(void) fputc('\n', stdout);
2677 	}
2678 }
2679 
2680 /*
2681  * This assumes that a sigset_t is simply an array of ints.
2682  */
2683 char *
2684 sigset_string(private_t *pri, sigset_t *sp)
2685 {
2686 	char *s = pri->code_buf;
2687 	int n = sizeof (*sp) / sizeof (int32_t);
2688 	int32_t *lp = (int32_t *)sp;
2689 
2690 	while (--n >= 0) {
2691 		int32_t val = *lp++;
2692 
2693 		if (val == 0)
2694 			s += sprintf(s, " 0");
2695 		else
2696 			s += sprintf(s, " 0x%.8X", val);
2697 	}
2698 
2699 	return (pri->code_buf);
2700 }
2701 
2702 void
2703 show_sigset(private_t *pri, long offset, const char *name)
2704 {
2705 	sigset_t sigset;
2706 
2707 	if (offset != NULL &&
2708 	    Pread(Proc, &sigset, sizeof (sigset), offset) == sizeof (sigset)) {
2709 		(void) printf("%s\t%s =%s\n",
2710 			pri->pname, name, sigset_string(pri, &sigset));
2711 	}
2712 }
2713 
2714 #ifdef _LP64
2715 void
2716 show_sigaltstack32(private_t *pri, long offset, const char *name)
2717 {
2718 	struct sigaltstack32 altstack;
2719 
2720 	if (offset != NULL &&
2721 	    Pread(Proc, &altstack, sizeof (altstack), offset) ==
2722 	    sizeof (altstack)) {
2723 		(void) printf("%s\t%s: sp=0x%.8X size=%u flags=0x%.4X\n",
2724 			pri->pname,
2725 			name,
2726 			altstack.ss_sp,
2727 			altstack.ss_size,
2728 			altstack.ss_flags);
2729 	}
2730 }
2731 #endif	/* _LP64 */
2732 
2733 void
2734 show_sigaltstack(private_t *pri, long offset, const char *name)
2735 {
2736 	struct sigaltstack altstack;
2737 
2738 #ifdef _LP64
2739 	if (data_model != PR_MODEL_LP64) {
2740 		show_sigaltstack32(pri, offset, name);
2741 		return;
2742 	}
2743 #endif
2744 	if (offset != NULL &&
2745 	    Pread(Proc, &altstack, sizeof (altstack), offset) ==
2746 	    sizeof (altstack)) {
2747 		(void) printf("%s\t%s: sp=0x%.8lX size=%lu flags=0x%.4X\n",
2748 			pri->pname,
2749 			name,
2750 			(ulong_t)altstack.ss_sp,
2751 			(ulong_t)altstack.ss_size,
2752 			altstack.ss_flags);
2753 	}
2754 }
2755 
2756 #ifdef _LP64
2757 void
2758 show_sigaction32(private_t *pri, long offset, const char *name, long odisp)
2759 {
2760 	struct sigaction32 sigaction;
2761 
2762 	if (offset != NULL &&
2763 	    Pread(Proc, &sigaction, sizeof (sigaction), offset) ==
2764 	    sizeof (sigaction)) {
2765 		/* This is stupid, we shouldn't have to do this */
2766 		if (odisp != NULL)
2767 			sigaction.sa_handler = (caddr32_t)odisp;
2768 		(void) printf(
2769 			"%s    %s: hand = 0x%.8X mask =%s flags = 0x%.4X\n",
2770 			pri->pname,
2771 			name,
2772 			sigaction.sa_handler,
2773 			sigset_string(pri, (sigset_t *)&sigaction.sa_mask),
2774 			sigaction.sa_flags);
2775 	}
2776 }
2777 #endif	/* _LP64 */
2778 
2779 void
2780 show_sigaction(private_t *pri, long offset, const char *name, long odisp)
2781 {
2782 	struct sigaction sigaction;
2783 
2784 #ifdef _LP64
2785 	if (data_model != PR_MODEL_LP64) {
2786 		show_sigaction32(pri, offset, name, odisp);
2787 		return;
2788 	}
2789 #endif
2790 	if (offset != NULL &&
2791 	    Pread(Proc, &sigaction, sizeof (sigaction), offset) ==
2792 	    sizeof (sigaction)) {
2793 		/* This is stupid, we shouldn't have to do this */
2794 		if (odisp != NULL)
2795 			sigaction.sa_handler = (void (*)())odisp;
2796 		(void) printf(
2797 			"%s    %s: hand = 0x%.8lX mask =%s flags = 0x%.4X\n",
2798 			pri->pname,
2799 			name,
2800 			(long)sigaction.sa_handler,
2801 			sigset_string(pri, &sigaction.sa_mask),
2802 			sigaction.sa_flags);
2803 	}
2804 }
2805 
2806 #ifdef _LP64
2807 void
2808 print_siginfo32(private_t *pri, const siginfo32_t *sip)
2809 {
2810 	const char *code = NULL;
2811 
2812 	(void) printf("%s      siginfo: %s", pri->pname,
2813 		signame(pri, sip->si_signo));
2814 
2815 	if (sip->si_signo != 0 && SI_FROMUSER(sip) && sip->si_pid != 0) {
2816 		(void) printf(" pid=%d uid=%d", sip->si_pid, sip->si_uid);
2817 		if (sip->si_code != 0)
2818 			(void) printf(" code=%d", sip->si_code);
2819 		(void) fputc('\n', stdout);
2820 		return;
2821 	}
2822 
2823 	switch (sip->si_signo) {
2824 	default:
2825 		(void) fputc('\n', stdout);
2826 		return;
2827 	case SIGILL:
2828 	case SIGTRAP:
2829 	case SIGFPE:
2830 	case SIGSEGV:
2831 	case SIGBUS:
2832 	case SIGEMT:
2833 	case SIGCLD:
2834 	case SIGPOLL:
2835 	case SIGXFSZ:
2836 		break;
2837 	}
2838 
2839 	switch (sip->si_signo) {
2840 	case SIGILL:
2841 		switch (sip->si_code) {
2842 		case ILL_ILLOPC:	code = "ILL_ILLOPC";	break;
2843 		case ILL_ILLOPN:	code = "ILL_ILLOPN";	break;
2844 		case ILL_ILLADR:	code = "ILL_ILLADR";	break;
2845 		case ILL_ILLTRP:	code = "ILL_ILLTRP";	break;
2846 		case ILL_PRVOPC:	code = "ILL_PRVOPC";	break;
2847 		case ILL_PRVREG:	code = "ILL_PRVREG";	break;
2848 		case ILL_COPROC:	code = "ILL_COPROC";	break;
2849 		case ILL_BADSTK:	code = "ILL_BADSTK";	break;
2850 		}
2851 		break;
2852 	case SIGTRAP:
2853 		switch (sip->si_code) {
2854 		case TRAP_BRKPT:	code = "TRAP_BRKPT";	break;
2855 		case TRAP_TRACE:	code = "TRAP_TRACE";	break;
2856 		case TRAP_RWATCH:	code = "TRAP_RWATCH";	break;
2857 		case TRAP_WWATCH:	code = "TRAP_WWATCH";	break;
2858 		case TRAP_XWATCH:	code = "TRAP_XWATCH";	break;
2859 		case TRAP_DTRACE:	code = "TRAP_DTRACE";	break;
2860 		}
2861 		break;
2862 	case SIGFPE:
2863 		switch (sip->si_code) {
2864 		case FPE_INTDIV:	code = "FPE_INTDIV";	break;
2865 		case FPE_INTOVF:	code = "FPE_INTOVF";	break;
2866 		case FPE_FLTDIV:	code = "FPE_FLTDIV";	break;
2867 		case FPE_FLTOVF:	code = "FPE_FLTOVF";	break;
2868 		case FPE_FLTUND:	code = "FPE_FLTUND";	break;
2869 		case FPE_FLTRES:	code = "FPE_FLTRES";	break;
2870 		case FPE_FLTINV:	code = "FPE_FLTINV";	break;
2871 		case FPE_FLTSUB:	code = "FPE_FLTSUB";	break;
2872 #if defined(FPE_FLTDEN)
2873 		case FPE_FLTDEN:	code = "FPE_FLTDEN";	break;
2874 #endif
2875 		}
2876 		break;
2877 	case SIGSEGV:
2878 		switch (sip->si_code) {
2879 		case SEGV_MAPERR:	code = "SEGV_MAPERR";	break;
2880 		case SEGV_ACCERR:	code = "SEGV_ACCERR";	break;
2881 		}
2882 		break;
2883 	case SIGEMT:
2884 		switch (sip->si_code) {
2885 #ifdef EMT_TAGOVF
2886 		case EMT_TAGOVF:	code = "EMT_TAGOVF";	break;
2887 #endif
2888 		case EMT_CPCOVF:	code = "EMT_CPCOVF";	break;
2889 		}
2890 		break;
2891 	case SIGBUS:
2892 		switch (sip->si_code) {
2893 		case BUS_ADRALN:	code = "BUS_ADRALN";	break;
2894 		case BUS_ADRERR:	code = "BUS_ADRERR";	break;
2895 		case BUS_OBJERR:	code = "BUS_OBJERR";	break;
2896 		}
2897 		break;
2898 	case SIGCLD:
2899 		switch (sip->si_code) {
2900 		case CLD_EXITED:	code = "CLD_EXITED";	break;
2901 		case CLD_KILLED:	code = "CLD_KILLED";	break;
2902 		case CLD_DUMPED:	code = "CLD_DUMPED";	break;
2903 		case CLD_TRAPPED:	code = "CLD_TRAPPED";	break;
2904 		case CLD_STOPPED:	code = "CLD_STOPPED";	break;
2905 		case CLD_CONTINUED:	code = "CLD_CONTINUED";	break;
2906 		}
2907 		break;
2908 	case SIGPOLL:
2909 		switch (sip->si_code) {
2910 		case POLL_IN:		code = "POLL_IN";	break;
2911 		case POLL_OUT:		code = "POLL_OUT";	break;
2912 		case POLL_MSG:		code = "POLL_MSG";	break;
2913 		case POLL_ERR:		code = "POLL_ERR";	break;
2914 		case POLL_PRI:		code = "POLL_PRI";	break;
2915 		case POLL_HUP:		code = "POLL_HUP";	break;
2916 		}
2917 		break;
2918 	}
2919 
2920 	if (code == NULL) {
2921 		(void) sprintf(pri->code_buf, "code=%d", sip->si_code);
2922 		code = (const char *)pri->code_buf;
2923 	}
2924 
2925 	switch (sip->si_signo) {
2926 	case SIGILL:
2927 	case SIGTRAP:
2928 	case SIGFPE:
2929 	case SIGSEGV:
2930 	case SIGBUS:
2931 	case SIGEMT:
2932 		(void) printf(" %s addr=0x%.8X",
2933 			code,
2934 			sip->si_addr);
2935 		break;
2936 	case SIGCLD:
2937 		(void) printf(" %s pid=%d status=0x%.4X",
2938 			code,
2939 			sip->si_pid,
2940 			sip->si_status);
2941 		break;
2942 	case SIGPOLL:
2943 	case SIGXFSZ:
2944 		(void) printf(" %s fd=%d band=%d",
2945 			code,
2946 			sip->si_fd,
2947 			sip->si_band);
2948 		break;
2949 	}
2950 
2951 	if (sip->si_errno != 0) {
2952 		const char *ename = errname(sip->si_errno);
2953 
2954 		(void) printf(" errno=%d", sip->si_errno);
2955 		if (ename != NULL)
2956 			(void) printf("(%s)", ename);
2957 	}
2958 
2959 	(void) fputc('\n', stdout);
2960 }
2961 #endif	/* _LP64 */
2962 
2963 void
2964 print_siginfo(private_t *pri, const siginfo_t *sip)
2965 {
2966 	const char *code = NULL;
2967 
2968 	(void) printf("%s      siginfo: %s", pri->pname,
2969 		signame(pri, sip->si_signo));
2970 
2971 	if (sip->si_signo != 0 && SI_FROMUSER(sip) && sip->si_pid != 0) {
2972 		(void) printf(" pid=%d uid=%d",
2973 		    (int)sip->si_pid,
2974 		    (int)sip->si_uid);
2975 		if (sip->si_code != 0)
2976 			(void) printf(" code=%d", sip->si_code);
2977 		(void) fputc('\n', stdout);
2978 		return;
2979 	}
2980 
2981 	switch (sip->si_signo) {
2982 	default:
2983 		(void) fputc('\n', stdout);
2984 		return;
2985 	case SIGILL:
2986 	case SIGTRAP:
2987 	case SIGFPE:
2988 	case SIGSEGV:
2989 	case SIGBUS:
2990 	case SIGEMT:
2991 	case SIGCLD:
2992 	case SIGPOLL:
2993 	case SIGXFSZ:
2994 		break;
2995 	}
2996 
2997 	switch (sip->si_signo) {
2998 	case SIGILL:
2999 		switch (sip->si_code) {
3000 		case ILL_ILLOPC:	code = "ILL_ILLOPC";	break;
3001 		case ILL_ILLOPN:	code = "ILL_ILLOPN";	break;
3002 		case ILL_ILLADR:	code = "ILL_ILLADR";	break;
3003 		case ILL_ILLTRP:	code = "ILL_ILLTRP";	break;
3004 		case ILL_PRVOPC:	code = "ILL_PRVOPC";	break;
3005 		case ILL_PRVREG:	code = "ILL_PRVREG";	break;
3006 		case ILL_COPROC:	code = "ILL_COPROC";	break;
3007 		case ILL_BADSTK:	code = "ILL_BADSTK";	break;
3008 		}
3009 		break;
3010 	case SIGTRAP:
3011 		switch (sip->si_code) {
3012 		case TRAP_BRKPT:	code = "TRAP_BRKPT";	break;
3013 		case TRAP_TRACE:	code = "TRAP_TRACE";	break;
3014 		case TRAP_RWATCH:	code = "TRAP_RWATCH";	break;
3015 		case TRAP_WWATCH:	code = "TRAP_WWATCH";	break;
3016 		case TRAP_XWATCH:	code = "TRAP_XWATCH";	break;
3017 		case TRAP_DTRACE:	code = "TRAP_DTRACE";	break;
3018 		}
3019 		break;
3020 	case SIGFPE:
3021 		switch (sip->si_code) {
3022 		case FPE_INTDIV:	code = "FPE_INTDIV";	break;
3023 		case FPE_INTOVF:	code = "FPE_INTOVF";	break;
3024 		case FPE_FLTDIV:	code = "FPE_FLTDIV";	break;
3025 		case FPE_FLTOVF:	code = "FPE_FLTOVF";	break;
3026 		case FPE_FLTUND:	code = "FPE_FLTUND";	break;
3027 		case FPE_FLTRES:	code = "FPE_FLTRES";	break;
3028 		case FPE_FLTINV:	code = "FPE_FLTINV";	break;
3029 		case FPE_FLTSUB:	code = "FPE_FLTSUB";	break;
3030 #if defined(FPE_FLTDEN)
3031 		case FPE_FLTDEN:	code = "FPE_FLTDEN";	break;
3032 #endif
3033 		}
3034 		break;
3035 	case SIGSEGV:
3036 		switch (sip->si_code) {
3037 		case SEGV_MAPERR:	code = "SEGV_MAPERR";	break;
3038 		case SEGV_ACCERR:	code = "SEGV_ACCERR";	break;
3039 		}
3040 		break;
3041 	case SIGEMT:
3042 		switch (sip->si_code) {
3043 #ifdef EMT_TAGOVF
3044 		case EMT_TAGOVF:	code = "EMT_TAGOVF";	break;
3045 #endif
3046 		case EMT_CPCOVF:	code = "EMT_CPCOVF";	break;
3047 		}
3048 		break;
3049 	case SIGBUS:
3050 		switch (sip->si_code) {
3051 		case BUS_ADRALN:	code = "BUS_ADRALN";	break;
3052 		case BUS_ADRERR:	code = "BUS_ADRERR";	break;
3053 		case BUS_OBJERR:	code = "BUS_OBJERR";	break;
3054 		}
3055 		break;
3056 	case SIGCLD:
3057 		switch (sip->si_code) {
3058 		case CLD_EXITED:	code = "CLD_EXITED";	break;
3059 		case CLD_KILLED:	code = "CLD_KILLED";	break;
3060 		case CLD_DUMPED:	code = "CLD_DUMPED";	break;
3061 		case CLD_TRAPPED:	code = "CLD_TRAPPED";	break;
3062 		case CLD_STOPPED:	code = "CLD_STOPPED";	break;
3063 		case CLD_CONTINUED:	code = "CLD_CONTINUED";	break;
3064 		}
3065 		break;
3066 	case SIGPOLL:
3067 		switch (sip->si_code) {
3068 		case POLL_IN:		code = "POLL_IN";	break;
3069 		case POLL_OUT:		code = "POLL_OUT";	break;
3070 		case POLL_MSG:		code = "POLL_MSG";	break;
3071 		case POLL_ERR:		code = "POLL_ERR";	break;
3072 		case POLL_PRI:		code = "POLL_PRI";	break;
3073 		case POLL_HUP:		code = "POLL_HUP";	break;
3074 		}
3075 		break;
3076 	}
3077 
3078 	if (code == NULL) {
3079 		(void) sprintf(pri->code_buf, "code=%d", sip->si_code);
3080 		code = (const char *)pri->code_buf;
3081 	}
3082 
3083 	switch (sip->si_signo) {
3084 	case SIGILL:
3085 	case SIGTRAP:
3086 	case SIGFPE:
3087 	case SIGSEGV:
3088 	case SIGBUS:
3089 	case SIGEMT:
3090 		(void) printf(" %s addr=0x%.8lX",
3091 			code,
3092 			(long)sip->si_addr);
3093 		break;
3094 	case SIGCLD:
3095 		(void) printf(" %s pid=%d status=0x%.4X",
3096 			code,
3097 			(int)sip->si_pid,
3098 			sip->si_status);
3099 		break;
3100 	case SIGPOLL:
3101 	case SIGXFSZ:
3102 		(void) printf(" %s fd=%d band=%ld",
3103 			code,
3104 			sip->si_fd,
3105 			sip->si_band);
3106 		break;
3107 	}
3108 
3109 	if (sip->si_errno != 0) {
3110 		const char *ename = errname(sip->si_errno);
3111 
3112 		(void) printf(" errno=%d", sip->si_errno);
3113 		if (ename != NULL)
3114 			(void) printf("(%s)", ename);
3115 	}
3116 
3117 	(void) fputc('\n', stdout);
3118 }
3119 
3120 #ifdef _LP64
3121 void
3122 show_siginfo32(private_t *pri, long offset)
3123 {
3124 	struct siginfo32 siginfo;
3125 
3126 	if (offset != NULL &&
3127 	    Pread(Proc, &siginfo, sizeof (siginfo), offset) == sizeof (siginfo))
3128 		print_siginfo32(pri, &siginfo);
3129 }
3130 #endif	/* _LP64 */
3131 
3132 void
3133 show_siginfo(private_t *pri, long offset)
3134 {
3135 	struct siginfo siginfo;
3136 
3137 #ifdef _LP64
3138 	if (data_model != PR_MODEL_LP64) {
3139 		show_siginfo32(pri, offset);
3140 		return;
3141 	}
3142 #endif
3143 	if (offset != NULL &&
3144 	    Pread(Proc, &siginfo, sizeof (siginfo), offset) == sizeof (siginfo))
3145 		print_siginfo(pri, &siginfo);
3146 }
3147 
3148 void
3149 show_bool(private_t *pri, long offset, int count)
3150 {
3151 	int serial = (count > MYBUFSIZ / 4);
3152 
3153 	/* enter region of lengthy output */
3154 	if (serial)
3155 		Eserialize();
3156 
3157 	while (count > 0) {
3158 		char buf[32];
3159 		int nb = (count < 32)? count : 32;
3160 		int i;
3161 
3162 		if (Pread(Proc, buf, (size_t)nb, offset) != nb)
3163 			break;
3164 
3165 		(void) printf("%s   ", pri->pname);
3166 		for (i = 0; i < nb; i++)
3167 			(void) printf(" %d", buf[i]);
3168 		(void) fputc('\n', stdout);
3169 
3170 		count -= nb;
3171 		offset += nb;
3172 	}
3173 
3174 	/* exit region of lengthy output */
3175 	if (serial)
3176 		Xserialize();
3177 }
3178 
3179 #ifdef _LP64
3180 void
3181 show_iovec32(private_t *pri, long offset, int niov, int showbuf, long count)
3182 {
3183 	iovec32_t iovec[16];
3184 	iovec32_t *ip;
3185 	long nb;
3186 	int serial = (count > MYBUFSIZ / 4 && showbuf);
3187 
3188 	if (niov > 16)		/* is this the real limit? */
3189 		niov = 16;
3190 
3191 	if (offset != NULL && niov > 0 &&
3192 	    Pread(Proc, &iovec[0], niov*sizeof (iovec32_t), offset)
3193 	    == niov*sizeof (iovec32_t)) {
3194 		/* enter region of lengthy output */
3195 		if (serial)
3196 			Eserialize();
3197 
3198 		for (ip = &iovec[0]; niov-- && !interrupt; ip++) {
3199 			(void) printf("%s\tiov_base = 0x%.8X  iov_len = %d\n",
3200 				pri->pname,
3201 				ip->iov_base,
3202 				ip->iov_len);
3203 			if ((nb = count) > 0) {
3204 				if (nb > ip->iov_len)
3205 					nb = ip->iov_len;
3206 				if (nb > 0)
3207 					count -= nb;
3208 			}
3209 			if (showbuf && nb > 0)
3210 				showbuffer(pri, (long)ip->iov_base, nb);
3211 		}
3212 
3213 		/* exit region of lengthy output */
3214 		if (serial)
3215 			Xserialize();
3216 	}
3217 }
3218 #endif	/* _LP64 */
3219 
3220 void
3221 show_iovec(private_t *pri, long offset, long niov, int showbuf, long count)
3222 {
3223 	iovec_t iovec[16];
3224 	iovec_t *ip;
3225 	long nb;
3226 	int serial = (count > MYBUFSIZ / 4 && showbuf);
3227 
3228 #ifdef _LP64
3229 	if (data_model != PR_MODEL_LP64) {
3230 		show_iovec32(pri, offset, niov, showbuf, count);
3231 		return;
3232 	}
3233 #endif
3234 	if (niov > 16)		/* is this the real limit? */
3235 		niov = 16;
3236 
3237 	if (offset != NULL && niov > 0 &&
3238 	    Pread(Proc, &iovec[0], niov*sizeof (iovec_t), offset)
3239 	    == niov*sizeof (iovec_t)) {
3240 		/* enter region of lengthy output */
3241 		if (serial)
3242 			Eserialize();
3243 
3244 		for (ip = &iovec[0]; niov-- && !interrupt; ip++) {
3245 			(void) printf("%s\tiov_base = 0x%.8lX  iov_len = %lu\n",
3246 				pri->pname,
3247 				(long)ip->iov_base,
3248 				ip->iov_len);
3249 			if ((nb = count) > 0) {
3250 				if (nb > ip->iov_len)
3251 					nb = ip->iov_len;
3252 				if (nb > 0)
3253 					count -= nb;
3254 			}
3255 			if (showbuf && nb > 0)
3256 				showbuffer(pri, (long)ip->iov_base, nb);
3257 		}
3258 
3259 		/* exit region of lengthy output */
3260 		if (serial)
3261 			Xserialize();
3262 	}
3263 }
3264 
3265 void
3266 show_dents32(private_t *pri, long offset, long count)
3267 {
3268 	long buf[MYBUFSIZ / sizeof (long)];
3269 	struct dirent32 *dp;
3270 	int serial = (count > 100);
3271 
3272 	if (offset == NULL)
3273 		return;
3274 
3275 	/* enter region of lengthy output */
3276 	if (serial)
3277 		Eserialize();
3278 
3279 	while (count > 0 && !interrupt) {
3280 		int nb = count < MYBUFSIZ? (int)count : MYBUFSIZ;
3281 
3282 		if ((nb = Pread(Proc, &buf[0], (size_t)nb, offset)) <= 0)
3283 			break;
3284 
3285 		dp = (struct dirent32 *)&buf[0];
3286 		if (nb < (int)(dp->d_name - (char *)dp))
3287 			break;
3288 		if ((unsigned)nb < dp->d_reclen) {
3289 			/* getdents() error? */
3290 			(void) printf(
3291 			"%s    ino=%-5u off=%-4d rlen=%-3d\n",
3292 				pri->pname,
3293 				dp->d_ino,
3294 				dp->d_off,
3295 				dp->d_reclen);
3296 			break;
3297 		}
3298 
3299 		while (!interrupt &&
3300 		    nb >= (int)(dp->d_name - (char *)dp) &&
3301 		    (unsigned)nb >= dp->d_reclen) {
3302 			(void) printf(
3303 			"%s    ino=%-5u off=%-4d rlen=%-3d \"%.*s\"\n",
3304 				pri->pname,
3305 				dp->d_ino,
3306 				dp->d_off,
3307 				dp->d_reclen,
3308 				dp->d_reclen - (int)(dp->d_name - (char *)dp),
3309 				dp->d_name);
3310 			nb -= dp->d_reclen;
3311 			count -= dp->d_reclen;
3312 			offset += dp->d_reclen;
3313 			/* LINTED improper alignment */
3314 			dp = (struct dirent32 *)((char *)dp + dp->d_reclen);
3315 		}
3316 	}
3317 
3318 	/* exit region of lengthy output */
3319 	if (serial)
3320 		Xserialize();
3321 }
3322 
3323 void
3324 show_dents64(private_t *pri, long offset, long count)
3325 {
3326 	long long buf[MYBUFSIZ / sizeof (long long)];
3327 	struct dirent64 *dp;
3328 	int serial = (count > 100);
3329 
3330 	if (offset == NULL)
3331 		return;
3332 
3333 	/* enter region of lengthy output */
3334 	if (serial)
3335 		Eserialize();
3336 
3337 	while (count > 0 && !interrupt) {
3338 		int nb = count < MYBUFSIZ? (int)count : MYBUFSIZ;
3339 
3340 		if ((nb = Pread(Proc, &buf[0], (size_t)nb, offset)) <= 0)
3341 			break;
3342 
3343 		dp = (struct dirent64 *)&buf[0];
3344 		if (nb < (int)(dp->d_name - (char *)dp))
3345 			break;
3346 		if ((unsigned)nb < dp->d_reclen) {
3347 			/* getdents() error? */
3348 			(void) printf(
3349 			"%s    ino=%-5llu off=%-4lld rlen=%-3d\n",
3350 				pri->pname,
3351 				(long long)dp->d_ino,
3352 				(long long)dp->d_off,
3353 				dp->d_reclen);
3354 			break;
3355 		}
3356 
3357 		while (!interrupt &&
3358 		    nb >= (int)(dp->d_name - (char *)dp) &&
3359 		    (unsigned)nb >= dp->d_reclen) {
3360 			(void) printf(
3361 			"%s    ino=%-5llu off=%-4lld rlen=%-3d \"%.*s\"\n",
3362 				pri->pname,
3363 				(long long)dp->d_ino,
3364 				(long long)dp->d_off,
3365 				dp->d_reclen,
3366 				dp->d_reclen - (int)(dp->d_name - (char *)dp),
3367 				dp->d_name);
3368 			nb -= dp->d_reclen;
3369 			count -= dp->d_reclen;
3370 			offset += dp->d_reclen;
3371 			/* LINTED improper alignment */
3372 			dp = (struct dirent64 *)((char *)dp + dp->d_reclen);
3373 		}
3374 	}
3375 
3376 	/* exit region of lengthy output */
3377 	if (serial)
3378 		Xserialize();
3379 }
3380 
3381 void
3382 show_rlimit32(private_t *pri, long offset)
3383 {
3384 	struct rlimit32 rlimit;
3385 
3386 	if (offset != NULL &&
3387 	    Pread(Proc, &rlimit, sizeof (rlimit), offset) == sizeof (rlimit)) {
3388 		(void) printf("%s\t", pri->pname);
3389 		switch (rlimit.rlim_cur) {
3390 		case RLIM32_INFINITY:
3391 			(void) fputs("cur = RLIM_INFINITY", stdout);
3392 			break;
3393 		case RLIM32_SAVED_MAX:
3394 			(void) fputs("cur = RLIM_SAVED_MAX", stdout);
3395 			break;
3396 		case RLIM32_SAVED_CUR:
3397 			(void) fputs("cur = RLIM_SAVED_CUR", stdout);
3398 			break;
3399 		default:
3400 			(void) printf("cur = %lu", (long)rlimit.rlim_cur);
3401 			break;
3402 		}
3403 		switch (rlimit.rlim_max) {
3404 		case RLIM32_INFINITY:
3405 			(void) fputs("  max = RLIM_INFINITY\n", stdout);
3406 			break;
3407 		case RLIM32_SAVED_MAX:
3408 			(void) fputs("  max = RLIM_SAVED_MAX\n", stdout);
3409 			break;
3410 		case RLIM32_SAVED_CUR:
3411 			(void) fputs("  max = RLIM_SAVED_CUR\n", stdout);
3412 			break;
3413 		default:
3414 			(void) printf("  max = %lu\n", (long)rlimit.rlim_max);
3415 			break;
3416 		}
3417 	}
3418 }
3419 
3420 void
3421 show_rlimit64(private_t *pri, long offset)
3422 {
3423 	struct rlimit64 rlimit;
3424 
3425 	if (offset != NULL &&
3426 	    Pread(Proc, &rlimit, sizeof (rlimit), offset) == sizeof (rlimit)) {
3427 		(void) printf("%s\t", pri->pname);
3428 		switch (rlimit.rlim_cur) {
3429 		case RLIM64_INFINITY:
3430 			(void) fputs("cur = RLIM64_INFINITY", stdout);
3431 			break;
3432 		case RLIM64_SAVED_MAX:
3433 			(void) fputs("cur = RLIM64_SAVED_MAX", stdout);
3434 			break;
3435 		case RLIM64_SAVED_CUR:
3436 			(void) fputs("cur = RLIM64_SAVED_CUR", stdout);
3437 			break;
3438 		default:
3439 			(void) printf("cur = %llu",
3440 			    (unsigned long long)rlimit.rlim_cur);
3441 			break;
3442 		}
3443 		switch (rlimit.rlim_max) {
3444 		case RLIM64_INFINITY:
3445 			(void) fputs("  max = RLIM64_INFINITY\n", stdout);
3446 			break;
3447 		case RLIM64_SAVED_MAX:
3448 			(void) fputs("  max = RLIM64_SAVED_MAX\n", stdout);
3449 			break;
3450 		case RLIM64_SAVED_CUR:
3451 			(void) fputs("  max = RLIM64_SAVED_CUR\n", stdout);
3452 			break;
3453 		default:
3454 			(void) printf("  max = %llu\n",
3455 			    (unsigned long long)rlimit.rlim_max);
3456 			break;
3457 		}
3458 	}
3459 }
3460 
3461 void
3462 show_nuname(private_t *pri, long offset)
3463 {
3464 	struct utsname ubuf;
3465 
3466 	if (offset != NULL &&
3467 	    Pread(Proc, &ubuf, sizeof (ubuf), offset) == sizeof (ubuf)) {
3468 		(void) printf(
3469 		"%s\tsys=%s nod=%s rel=%s ver=%s mch=%s\n",
3470 			pri->pname,
3471 			ubuf.sysname,
3472 			ubuf.nodename,
3473 			ubuf.release,
3474 			ubuf.version,
3475 			ubuf.machine);
3476 	}
3477 }
3478 
3479 void
3480 show_adjtime(private_t *pri, long off1, long off2)
3481 {
3482 	show_timeval(pri, off1, "   delta");
3483 	show_timeval(pri, off2, "olddelta");
3484 }
3485 
3486 void
3487 show_sockaddr(private_t *pri,
3488 	const char *str, long addroff, long lenoff, long len)
3489 {
3490 	/*
3491 	 * A buffer large enough for PATH_MAX size AF_UNIX address, which is
3492 	 * also large enough to store a sockaddr_in or a sockaddr_in6.
3493 	 */
3494 	long buf[(sizeof (short) + PATH_MAX + sizeof (long) - 1)
3495 		/ sizeof (long)];
3496 	struct sockaddr *sa = (struct sockaddr *)buf;
3497 	struct sockaddr_in *sin = (struct sockaddr_in *)buf;
3498 	struct sockaddr_un *soun = (struct sockaddr_un *)buf;
3499 	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)buf;
3500 	char addrbuf[INET6_ADDRSTRLEN];
3501 
3502 	if (lenoff != 0) {
3503 		uint_t ilen;
3504 		if (Pread(Proc, &ilen, sizeof (ilen), lenoff) != sizeof (ilen))
3505 			return;
3506 		len = ilen;
3507 	}
3508 
3509 	if (len >= sizeof (buf))	/* protect against ridiculous length */
3510 		len = sizeof (buf) - 1;
3511 	if (Pread(Proc, buf, len, addroff) != len)
3512 		return;
3513 
3514 	switch (sa->sa_family) {
3515 	case AF_INET6:
3516 		(void) printf("%s\tAF_INET6  %s = %s  port = %u\n",
3517 		    pri->pname, str,
3518 		    inet_ntop(AF_INET6, &sin6->sin6_addr, addrbuf,
3519 			sizeof (addrbuf)),
3520 		    ntohs(sin6->sin6_port));
3521 		(void) printf("%s\tscope id = %u  source id = 0x%x\n"
3522 		    "%s\tflow class = 0x%02x  flow label = 0x%05x\n",
3523 		    pri->pname, ntohl(sin6->sin6_scope_id),
3524 		    ntohl(sin6->__sin6_src_id),
3525 		    pri->pname,
3526 		    ntohl((sin6->sin6_flowinfo & IPV6_FLOWINFO_TCLASS) >> 20),
3527 		    ntohl(sin6->sin6_flowinfo & IPV6_FLOWINFO_FLOWLABEL));
3528 		break;
3529 	case AF_INET:
3530 		(void) printf("%s\tAF_%s  %s = %s  port = %u\n",
3531 		    pri->pname, "INET",
3532 		    str, inet_ntop(AF_INET, &sin->sin_addr, addrbuf,
3533 		    sizeof (addrbuf)), ntohs(sin->sin_port));
3534 		break;
3535 	case AF_UNIX:
3536 		len -= sizeof (soun->sun_family);
3537 		if (len >= 0) {
3538 			/* Null terminate */
3539 			soun->sun_path[len] = NULL;
3540 			(void) printf("%s\tAF_UNIX  %s = %s\n", pri->pname,
3541 				str, soun->sun_path);
3542 		}
3543 		break;
3544 	}
3545 }
3546 
3547 void
3548 show_msghdr(private_t *pri, long offset)
3549 {
3550 	const lwpstatus_t *Lsp = pri->lwpstat;
3551 	int what = Lsp->pr_what;
3552 	int err = pri->Errno;
3553 	struct msghdr msg;
3554 	int showbuf = FALSE;
3555 	int i = pri->sys_args[0]+1;
3556 	long nb = (what == SYS_recvmsg)? pri->Rval1 : 32*1024;
3557 
3558 	if (Pread(Proc, &msg, sizeof (msg), offset) != sizeof (msg))
3559 		return;
3560 
3561 	if (msg.msg_name != NULL && msg.msg_namelen != 0)
3562 		show_sockaddr(pri, "msg_name",
3563 			(long)msg.msg_name, 0, (long)msg.msg_namelen);
3564 
3565 	/*
3566 	 * Print the iovec if the syscall was successful and the fd is
3567 	 * part of the set being traced.
3568 	 */
3569 	if ((what == SYS_recvmsg && !err &&
3570 	    prismember(&readfd, i)) ||
3571 	    (what == SYS_sendmsg &&
3572 	    prismember(&writefd, i)))
3573 		showbuf = TRUE;
3574 
3575 	show_iovec(pri, (long)msg.msg_iov, msg.msg_iovlen, showbuf, nb);
3576 
3577 }
3578 
3579 #ifdef _LP64
3580 void
3581 show_msghdr32(private_t *pri, long offset)
3582 {
3583 	struct msghdr32 {
3584 		caddr32_t	msg_name;
3585 		uint32_t	msg_namelen;
3586 		caddr32_t 	msg_iov;
3587 		int32_t		msg_iovlen;
3588 	} msg;
3589 	const lwpstatus_t *Lsp = pri->lwpstat;
3590 	int what = Lsp->pr_what;
3591 	int err = pri->Errno;
3592 	int showbuf = FALSE;
3593 	int i = pri->sys_args[0]+1;
3594 	long nb = (what == SYS_recvmsg)? pri->Rval1 : 32*1024;
3595 
3596 	if (Pread(Proc, &msg, sizeof (msg), offset) != sizeof (msg))
3597 		return;
3598 
3599 	if (msg.msg_name != NULL && msg.msg_namelen != 0)
3600 		show_sockaddr(pri, "msg_name",
3601 			(long)msg.msg_name, 0, (long)msg.msg_namelen);
3602 	/*
3603 	 * Print the iovec if the syscall was successful and the fd is
3604 	 * part of the set being traced.
3605 	 */
3606 	if ((what == SYS_recvmsg && !err &&
3607 	    prismember(&readfd, i)) ||
3608 	    (what == SYS_sendmsg &&
3609 	    prismember(&writefd, i)))
3610 		showbuf = TRUE;
3611 
3612 	show_iovec32(pri, (long)msg.msg_iov, msg.msg_iovlen, showbuf, nb);
3613 
3614 }
3615 #endif	/* _LP64 */
3616 
3617 static void
3618 show_doorargs(private_t *pri, long offset)
3619 {
3620 	door_arg_t args;
3621 
3622 	if (Pread(Proc, &args, sizeof (args), offset) == sizeof (args)) {
3623 		(void) printf("%s\tdata_ptr=0x%lX data_size=%lu\n",
3624 		    pri->pname,
3625 		    (ulong_t)args.data_ptr,
3626 		    (ulong_t)args.data_size);
3627 		(void) printf("%s\tdesc_ptr=0x%lX desc_num=%u\n",
3628 		    pri->pname,
3629 		    (ulong_t)args.desc_ptr,
3630 		    args.desc_num);
3631 		(void) printf("%s\trbuf=0x%lX rsize=%lu\n",
3632 		    pri->pname,
3633 		    (ulong_t)args.rbuf,
3634 		    (ulong_t)args.rsize);
3635 	}
3636 }
3637 
3638 static void
3639 show_ucred_privsets(private_t *pri, ucred_t *uc)
3640 {
3641 	int i = 0;
3642 	const priv_set_t *s;
3643 	priv_ptype_t sn;
3644 	char *str;
3645 
3646 	while ((sn = priv_getsetbynum(i++)) != NULL) {
3647 		s = ucred_getprivset(uc, sn);
3648 
3649 		if (s == NULL)
3650 			continue;
3651 
3652 		(void) printf("%s\t%c: %s\n",
3653 		    pri->pname,
3654 		    *sn,
3655 		    str = priv_set_to_str(s, ',', PRIV_STR_SHORT));
3656 
3657 		free(str);
3658 	}
3659 }
3660 
3661 static void
3662 show_ucred(private_t *pri, long offset)
3663 {
3664 	ucred_t *uc = _ucred_alloc();
3665 	size_t sz;
3666 
3667 	if (uc == NULL)
3668 		return;
3669 
3670 	sz = Pread(Proc, uc, uc->uc_size, offset);
3671 
3672 	/*
3673 	 * A new uc_size is read, it could be smaller than the previously
3674 	 * value.  We accept short reads that fill the whole header.
3675 	 */
3676 	if (sz >= sizeof (ucred_t) && sz >= uc->uc_size) {
3677 		(void) printf("%s\teuid=%d egid=%d\n",
3678 		    pri->pname,
3679 		    (int)ucred_geteuid(uc),
3680 		    (int)ucred_getegid(uc));
3681 		(void) printf("%s\truid=%d rgid=%d\n",
3682 		    pri->pname,
3683 		    (int)ucred_getruid(uc),
3684 		    (int)ucred_getrgid(uc));
3685 		(void) printf("%s\tpid=%d zoneid=%d\n",
3686 		    pri->pname,
3687 		    (int)ucred_getpid(uc),
3688 		    (int)ucred_getzoneid(uc));
3689 		show_ucred_privsets(pri, uc);
3690 	}
3691 	ucred_free(uc);
3692 }
3693 
3694 static void
3695 show_privset(private_t *pri, long offset, size_t size, char *label)
3696 {
3697 	priv_set_t *tmp = priv_allocset();
3698 	size_t sz;
3699 
3700 	if (tmp == NULL)
3701 		return;
3702 
3703 	sz = Pread(Proc, tmp, size, offset);
3704 
3705 	if (sz == size) {
3706 		char *str = priv_set_to_str(tmp, ',', PRIV_STR_SHORT);
3707 		if (str != NULL) {
3708 			(void) printf("%s\t%s%s\n", pri->pname, label, str);
3709 			free(str);
3710 		}
3711 	}
3712 	priv_freeset(tmp);
3713 }
3714 
3715 static void
3716 show_doorinfo(private_t *pri, long offset)
3717 {
3718 	door_info_t info;
3719 	door_attr_t attr;
3720 
3721 	if (Pread(Proc, &info, sizeof (info), offset) != sizeof (info))
3722 		return;
3723 	(void) printf("%s\ttarget=%d proc=0x%llX data=0x%llX\n",
3724 	    pri->pname,
3725 	    (int)info.di_target,
3726 	    info.di_proc,
3727 	    info.di_data);
3728 	attr = info.di_attributes;
3729 	(void) printf("%s\tattributes=%s\n", pri->pname, door_flags(pri, attr));
3730 	(void) printf("%s\tuniquifier=%llu\n", pri->pname, info.di_uniquifier);
3731 }
3732 
3733 static void
3734 show_doorparam(private_t *pri, long offset)
3735 {
3736 	ulong_t val;
3737 
3738 	if (Pread(Proc, &val, sizeof (val), offset) == sizeof (val)) {
3739 		(void) printf("%s\tvalue=%lu\n",
3740 		    pri->pname,
3741 		    val);
3742 	}
3743 }
3744 
3745 #ifdef _LP64
3746 
3747 static void
3748 show_doorargs32(private_t *pri, long offset)
3749 {
3750 	struct door_arg32 args;
3751 
3752 	if (Pread(Proc, &args, sizeof (args), offset) == sizeof (args)) {
3753 		(void) printf("%s\tdata_ptr=%X data_size=%u\n",
3754 		    pri->pname,
3755 		    args.data_ptr,
3756 		    args.data_size);
3757 		(void) printf("%s\tdesc_ptr=0x%X desc_num=%u\n",
3758 		    pri->pname,
3759 		    args.desc_ptr,
3760 		    args.desc_num);
3761 		(void) printf("%s\trbuf=0x%X rsize=%u\n",
3762 		    pri->pname,
3763 		    args.rbuf,
3764 		    args.rsize);
3765 	}
3766 }
3767 
3768 static void
3769 show_doorparam32(private_t *pri, long offset)
3770 {
3771 	uint_t val;
3772 
3773 	if (Pread(Proc, &val, sizeof (val), offset) == sizeof (val)) {
3774 		(void) printf("%s\tvalue=%u\n",
3775 		    pri->pname,
3776 		    val);
3777 	}
3778 }
3779 
3780 #endif	/* _LP64 */
3781 
3782 static void
3783 show_doors(private_t *pri)
3784 {
3785 	switch (pri->sys_args[5]) {
3786 	case DOOR_CALL:
3787 #ifdef _LP64
3788 		if (data_model == PR_MODEL_LP64)
3789 			show_doorargs(pri, (long)pri->sys_args[1]);
3790 		else
3791 			show_doorargs32(pri, (long)pri->sys_args[1]);
3792 #else
3793 		show_doorargs(pri, (long)pri->sys_args[1]);
3794 #endif
3795 		break;
3796 	case DOOR_UCRED:
3797 		if (!pri->Errno)
3798 			show_ucred(pri, (long)pri->sys_args[0]);
3799 		break;
3800 	case DOOR_INFO:
3801 		if (!pri->Errno)
3802 			show_doorinfo(pri, (long)pri->sys_args[1]);
3803 		break;
3804 	case DOOR_GETPARAM:
3805 		if (!pri->Errno) {
3806 #ifdef _LP64
3807 			if (data_model == PR_MODEL_LP64)
3808 				show_doorparam(pri, (long)pri->sys_args[2]);
3809 			else
3810 				show_doorparam32(pri, (long)pri->sys_args[2]);
3811 #else
3812 			show_doorparam(pri, (long)pri->sys_args[2]);
3813 #endif
3814 		}
3815 		break;
3816 	}
3817 }
3818 
3819 static void
3820 show_portargs(private_t *pri, long offset)
3821 {
3822 	port_event_t args;
3823 
3824 	if (Pread(Proc, &args, sizeof (args), offset) == sizeof (args)) {
3825 		(void) printf("%s\tevents=0x%x source=%u\n",
3826 		    pri->pname,
3827 		    args.portev_events,
3828 		    args.portev_source);
3829 		(void) printf("%s\tobject=0x%p user=0x%p\n",
3830 		    pri->pname,
3831 		    (void *)args.portev_object,
3832 		    (void *)args.portev_user);
3833 	}
3834 }
3835 
3836 
3837 #ifdef _LP64
3838 
3839 static void
3840 show_portargs32(private_t *pri, long offset)
3841 {
3842 	port_event32_t args;
3843 
3844 	if (Pread(Proc, &args, sizeof (args), offset) == sizeof (args)) {
3845 		(void) printf("%s\tevents=0x%x source=%u\n",
3846 		    pri->pname,
3847 		    args.portev_events,
3848 		    args.portev_source);
3849 		(void) printf("%s\tobject=0x%x user=0x%x\n",
3850 		    pri->pname,
3851 		    args.portev_object,
3852 		    args.portev_user);
3853 	}
3854 }
3855 
3856 #endif	/* _LP64 */
3857 
3858 static void
3859 show_ports(private_t *pri)
3860 {
3861 	switch (pri->sys_args[0]) {
3862 	case PORT_GET:
3863 #ifdef _LP64
3864 		if (data_model == PR_MODEL_LP64)
3865 			show_portargs(pri, (long)pri->sys_args[2]);
3866 		else
3867 			show_portargs32(pri, (long)pri->sys_args[2]);
3868 #else
3869 		show_portargs(pri, (long)pri->sys_args[2]);
3870 #endif
3871 		break;
3872 	}
3873 }
3874 
3875 #define	MAX_SNDFL_PRD 16
3876 
3877 #ifdef _LP64
3878 
3879 static void
3880 show_ksendfilevec32(private_t *pri, int fd,
3881     ksendfilevec32_t *sndvec, int sfvcnt)
3882 {
3883 	ksendfilevec32_t *snd_ptr, snd[MAX_SNDFL_PRD];
3884 	size_t cpy_rqst;
3885 
3886 	Eserialize();
3887 	while (sfvcnt > 0) {
3888 		cpy_rqst = MIN(sfvcnt, MAX_SNDFL_PRD);
3889 		sfvcnt -= cpy_rqst;
3890 		cpy_rqst *= sizeof (snd[0]);
3891 
3892 		if (Pread(Proc, snd, cpy_rqst, (uintptr_t)sndvec) != cpy_rqst)
3893 			break;
3894 
3895 		snd_ptr = &snd[0];
3896 
3897 		while (cpy_rqst) {
3898 			(void) printf(
3899 			    "sfv_fd=%d\tsfv_flag=0x%x\t"
3900 			    "sfv_off=%d\tsfv_len=%u\n",
3901 			    snd_ptr->sfv_fd,
3902 			    snd_ptr->sfv_flag,
3903 			    snd_ptr->sfv_off,
3904 			    snd_ptr->sfv_len);
3905 
3906 			if (snd_ptr->sfv_fd == SFV_FD_SELF &&
3907 			    prismember(&writefd, fd)) {
3908 				showbuffer(pri,
3909 				    (long)snd_ptr->sfv_off & 0xffffffff,
3910 				    (long)snd_ptr->sfv_len);
3911 			}
3912 
3913 			cpy_rqst -= sizeof (snd[0]);
3914 			snd_ptr++;
3915 		}
3916 
3917 		sndvec += MAX_SNDFL_PRD;
3918 	}
3919 	Xserialize();
3920 }
3921 
3922 static void
3923 show_ksendfilevec64(private_t *pri, int fd,
3924     ksendfilevec64_t *sndvec, int sfvcnt)
3925 {
3926 	ksendfilevec64_t *snd_ptr, snd[MAX_SNDFL_PRD];
3927 	size_t cpy_rqst;
3928 
3929 	Eserialize();
3930 	while (sfvcnt > 0) {
3931 		cpy_rqst = MIN(sfvcnt, MAX_SNDFL_PRD);
3932 		sfvcnt -= cpy_rqst;
3933 		cpy_rqst *= sizeof (snd[0]);
3934 
3935 		if (Pread(Proc, snd, cpy_rqst, (uintptr_t)sndvec) != cpy_rqst)
3936 			break;
3937 
3938 		snd_ptr = &snd[0];
3939 
3940 		while (cpy_rqst) {
3941 			(void) printf(
3942 			    "sfv_fd=%d\tsfv_flag=0x%x\t"
3943 			    "sfv_off=%ld\tsfv_len=%u\n",
3944 			    snd_ptr->sfv_fd,
3945 			    snd_ptr->sfv_flag,
3946 			    snd_ptr->sfv_off,
3947 			    snd_ptr->sfv_len);
3948 
3949 			if (snd_ptr->sfv_fd == SFV_FD_SELF &&
3950 			    prismember(&writefd, fd)) {
3951 				showbuffer(pri,
3952 				    (long)snd_ptr->sfv_off & 0xffffffff,
3953 				    (long)snd_ptr->sfv_len);
3954 			}
3955 
3956 			cpy_rqst -= sizeof (snd[0]);
3957 			snd_ptr++;
3958 		}
3959 
3960 		sndvec += MAX_SNDFL_PRD;
3961 	}
3962 	Xserialize();
3963 }
3964 
3965 #endif /* _LP64 */
3966 
3967 /*ARGSUSED*/
3968 static void
3969 show_sendfilevec(private_t *pri, int fd, sendfilevec_t *sndvec, int sfvcnt)
3970 {
3971 	sendfilevec_t *snd_ptr, snd[MAX_SNDFL_PRD];
3972 	size_t cpy_rqst;
3973 
3974 #ifdef _LP64
3975 	if (data_model != PR_MODEL_LP64) {
3976 		show_ksendfilevec32(pri, fd,
3977 		    (ksendfilevec32_t *)sndvec, sfvcnt);
3978 		return;
3979 	}
3980 #endif
3981 	Eserialize();
3982 	while (sfvcnt > 0) {
3983 		cpy_rqst = MIN(sfvcnt, MAX_SNDFL_PRD);
3984 		sfvcnt -= cpy_rqst;
3985 		cpy_rqst *= sizeof (snd[0]);
3986 
3987 		if (Pread(Proc, snd, cpy_rqst, (uintptr_t)sndvec) != cpy_rqst)
3988 			break;
3989 
3990 		snd_ptr = &snd[0];
3991 
3992 		while (cpy_rqst) {
3993 			(void) printf(
3994 			    "sfv_fd=%d\tsfv_flag=0x%x\t"
3995 			    "sfv_off=%ld\tsfv_len=%lu\n",
3996 			    snd_ptr->sfv_fd,
3997 			    snd_ptr->sfv_flag,
3998 			    snd_ptr->sfv_off,
3999 			    (ulong_t)snd_ptr->sfv_len);
4000 
4001 			if (snd_ptr->sfv_fd == SFV_FD_SELF &&
4002 			    prismember(&writefd, fd)) {
4003 				showbuffer(pri, (long)snd_ptr->sfv_off,
4004 					    (long)snd_ptr->sfv_len);
4005 			}
4006 
4007 			cpy_rqst -= sizeof (snd[0]);
4008 			snd_ptr++;
4009 		}
4010 
4011 		sndvec += MAX_SNDFL_PRD;
4012 	}
4013 	Xserialize();
4014 }
4015 
4016 /*ARGSUSED*/
4017 static void
4018 show_sendfilevec64(private_t *pri, int fd, sendfilevec64_t *sndvec, int sfvcnt)
4019 {
4020 	sendfilevec64_t *snd_ptr, snd[MAX_SNDFL_PRD];
4021 	size_t cpy_rqst;
4022 
4023 #ifdef _LP64
4024 	if (data_model != PR_MODEL_LP64) {
4025 		show_ksendfilevec64(pri, fd,
4026 		    (ksendfilevec64_t *)sndvec, sfvcnt);
4027 		return;
4028 	}
4029 #endif
4030 
4031 	Eserialize();
4032 	while (sfvcnt > 0) {
4033 		cpy_rqst = MIN(sfvcnt, MAX_SNDFL_PRD);
4034 		sfvcnt -= cpy_rqst;
4035 		cpy_rqst *= sizeof (snd[0]);
4036 
4037 		if (Pread(Proc, snd, cpy_rqst, (uintptr_t)sndvec) != cpy_rqst)
4038 			break;
4039 
4040 		snd_ptr = &snd[0];
4041 
4042 		while (cpy_rqst) {
4043 			(void) printf(
4044 #ifdef _LP64
4045 			    "sfv_fd=%d\tsfv_flag=0x%x\t"
4046 			    "sfv_off=%ld\tsfv_len=%lu\n",
4047 #else
4048 			    "sfv_fd=%d\tsfv_flag=0x%x\t"
4049 			    "sfv_off=%lld\tsfv_len=%lu\n",
4050 #endif
4051 			    snd_ptr->sfv_fd,
4052 			    snd_ptr->sfv_flag,
4053 			    snd_ptr->sfv_off,
4054 			    (ulong_t)snd_ptr->sfv_len);
4055 
4056 			if (snd_ptr->sfv_fd == SFV_FD_SELF &&
4057 			    prismember(&writefd, fd)) {
4058 				showbuffer(pri, (long)snd_ptr->sfv_off,
4059 					    (long)snd_ptr->sfv_len);
4060 			}
4061 
4062 			cpy_rqst -= sizeof (snd[0]);
4063 			snd_ptr++;
4064 		}
4065 
4066 		sndvec += MAX_SNDFL_PRD;
4067 	}
4068 	Xserialize();
4069 }
4070 
4071 static void
4072 show_memcntl_mha(private_t *pri, long offset)
4073 {
4074 	struct memcntl_mha mha;
4075 	const char *s = NULL;
4076 
4077 	if (Pread(Proc, &mha, sizeof (mha), offset) == sizeof (mha)) {
4078 		switch (mha.mha_cmd) {
4079 		case MHA_MAPSIZE_VA:	    s = "MHA_MAPSIZE_VA";	break;
4080 		case MHA_MAPSIZE_BSSBRK:    s = "MHA_MAPSIZE_BSSBRK";	break;
4081 		case MHA_MAPSIZE_STACK:	    s = "MHA_MAPSIZE_STACK";	break;
4082 		}
4083 		if (s)
4084 			(void) printf("%s\tmha_cmd=%s mha_flags=0x%x"
4085 			    " mha_pagesize=%lu\n",
4086 			    pri->pname, s, mha.mha_flags,
4087 			    (ulong_t)mha.mha_pagesize);
4088 		else
4089 			(void) printf("%s\tmha_cmd=0x%.8x mha_flags=0x%x"
4090 			    " mha_pagesize=%lu\n",
4091 			    pri->pname, mha.mha_cmd, mha.mha_flags,
4092 			    (ulong_t)mha.mha_pagesize);
4093 	}
4094 }
4095 
4096 #ifdef _LP64
4097 
4098 static void
4099 show_memcntl_mha32(private_t *pri, long offset)
4100 {
4101 	struct memcntl_mha32 mha32;
4102 	const char *s = NULL;
4103 
4104 	if (Pread(Proc, &mha32, sizeof (mha32), offset) ==
4105 	    sizeof (mha32)) {
4106 		switch (mha32.mha_cmd) {
4107 		case MHA_MAPSIZE_VA:	    s = "MHA_MAPSIZE_VA";	break;
4108 		case MHA_MAPSIZE_BSSBRK:    s = "MHA_MAPSIZE_BSSBRK";	break;
4109 		case MHA_MAPSIZE_STACK:	    s = "MHA_MAPSIZE_STACK";	break;
4110 		}
4111 		if (s)
4112 			(void) printf("%s\tmha_cmd=%s mha_flags=0x%x"
4113 			    " mha_pagesize=%u\n",
4114 			    pri->pname, s, mha32.mha_flags, mha32.mha_pagesize);
4115 		else
4116 			(void) printf("%s\tmha_cmd=0x%.8x mha_flags=0x%x"
4117 			    " mha_pagesize=%u\n",
4118 			    pri->pname, mha32.mha_cmd, mha32.mha_flags,
4119 			    mha32.mha_pagesize);
4120 	}
4121 }
4122 
4123 #endif	/* _LP64 */
4124 
4125 static void
4126 show_memcntl(private_t *pri)
4127 {
4128 
4129 	if ((int)pri->sys_args[2] != MC_HAT_ADVISE)
4130 		return;
4131 #ifdef _LP64
4132 	if (data_model == PR_MODEL_LP64)
4133 		show_memcntl_mha(pri, (long)pri->sys_args[3]);
4134 	else
4135 		show_memcntl_mha32(pri, (long)pri->sys_args[3]);
4136 #else
4137 	show_memcntl_mha(pri, (long)pri->sys_args[3]);
4138 #endif
4139 }
4140 
4141 void
4142 show_ids(private_t *pri, long offset, int count)
4143 {
4144 	id_t buf[MYBUFSIZ / sizeof (id_t)];
4145 	id_t *idp;
4146 	int serial = (count > MYBUFSIZ / 48);
4147 
4148 	if (offset == NULL)
4149 		return;
4150 
4151 	/* enter region of lengthy output */
4152 	if (serial)
4153 		Eserialize();
4154 
4155 	while (count > 0 && !interrupt) {
4156 		ssize_t nb = (count * sizeof (id_t) < MYBUFSIZ)?
4157 			count * sizeof (id_t) : MYBUFSIZ;
4158 
4159 		if ((nb = Pread(Proc, &buf[0], (size_t)nb, offset)) < 0 ||
4160 		    nb < sizeof (id_t))
4161 			break;
4162 
4163 		idp = buf;
4164 		while (!interrupt && nb >= sizeof (id_t)) {
4165 			(void) printf("%s\t%8d\n", pri->pname, (int)*idp);
4166 			offset += sizeof (id_t);
4167 			nb -= sizeof (id_t);
4168 			idp++;
4169 			count--;
4170 		}
4171 	}
4172 
4173 	/* exit region of lengthy output */
4174 	if (serial)
4175 		Xserialize();
4176 }
4177 
4178 void
4179 show_ntp_gettime(private_t *pri)
4180 {
4181 	struct ntptimeval ntv;
4182 	long offset;
4183 
4184 	if (pri->sys_nargs < 1 || (offset = pri->sys_args[0]) == NULL)
4185 		return;
4186 
4187 	if (data_model == PR_MODEL_NATIVE) {
4188 		if (Pread(Proc, &ntv, sizeof (ntv), offset)
4189 		    != sizeof (ntv))
4190 			return;
4191 	} else {
4192 		struct ntptimeval32 ntv32;
4193 
4194 		if (Pread(Proc, &ntv32, sizeof (ntv32), offset)
4195 		    != sizeof (ntv32))
4196 			return;
4197 
4198 		TIMEVAL32_TO_TIMEVAL(&ntv.time, &ntv32.time);
4199 		ntv.maxerror = ntv32.maxerror;
4200 		ntv.esterror = ntv32.esterror;
4201 	}
4202 
4203 	(void) printf("\ttime:     %ld.%6.6ld sec\n",
4204 	    ntv.time.tv_sec, ntv.time.tv_usec);
4205 	(void) printf("\tmaxerror: %11d usec\n", ntv.maxerror);
4206 	(void) printf("\testerror: %11d usec\n", ntv.esterror);
4207 }
4208 
4209 static char *
4210 get_timex_modes(private_t *pri, uint32_t val)
4211 {
4212 	char *str = pri->code_buf;
4213 	size_t used = 0;
4214 
4215 	*str = '\0';
4216 	if (val & MOD_OFFSET)
4217 		used = strlcat(str, "|MOD_OFFSET", sizeof (pri->code_buf));
4218 	if (val & MOD_FREQUENCY)
4219 		used = strlcat(str, "|MOD_FREQUENCY", sizeof (pri->code_buf));
4220 	if (val & MOD_MAXERROR)
4221 		used = strlcat(str, "|MOD_MAXERROR", sizeof (pri->code_buf));
4222 	if (val & MOD_ESTERROR)
4223 		used = strlcat(str, "|MOD_ESTERROR", sizeof (pri->code_buf));
4224 	if (val & MOD_STATUS)
4225 		used = strlcat(str, "|MOD_STATUS", sizeof (pri->code_buf));
4226 	if (val & MOD_TIMECONST)
4227 		used = strlcat(str, "|MOD_TIMECONST", sizeof (pri->code_buf));
4228 	if (val & MOD_CLKB)
4229 		used = strlcat(str, "|MOD_CLKB", sizeof (pri->code_buf));
4230 	if (val & MOD_CLKA)
4231 		used = strlcat(str, "|MOD_CLKA", sizeof (pri->code_buf));
4232 
4233 	if (used == 0 || used >= sizeof (pri->code_buf))
4234 		(void) snprintf(str, sizeof (pri->code_buf), " 0x%.4x", val);
4235 
4236 	return (str + 1);
4237 }
4238 
4239 static char *
4240 get_timex_status(private_t *pri, int32_t val)
4241 {
4242 	char *str = pri->code_buf;
4243 	size_t used = 0;
4244 
4245 	*str = '\0';
4246 	if (val & STA_PLL)
4247 		used = strlcat(str, "|STA_PLL", sizeof (pri->code_buf));
4248 	if (val & STA_PPSFREQ)
4249 		used = strlcat(str, "|STA_PPSFREQ", sizeof (pri->code_buf));
4250 	if (val & STA_PPSTIME)
4251 		used = strlcat(str, "|STA_PPSTIME", sizeof (pri->code_buf));
4252 	if (val & STA_FLL)
4253 		used = strlcat(str, "|STA_FLL", sizeof (pri->code_buf));
4254 
4255 	if (val & STA_INS)
4256 		used = strlcat(str, "|STA_INS", sizeof (pri->code_buf));
4257 	if (val & STA_DEL)
4258 		used = strlcat(str, "|STA_DEL", sizeof (pri->code_buf));
4259 	if (val & STA_UNSYNC)
4260 		used = strlcat(str, "|STA_UNSYNC", sizeof (pri->code_buf));
4261 	if (val & STA_FREQHOLD)
4262 		used = strlcat(str, "|STA_FREQHOLD", sizeof (pri->code_buf));
4263 
4264 	if (val & STA_PPSSIGNAL)
4265 		used = strlcat(str, "|STA_PPSSIGNAL", sizeof (pri->code_buf));
4266 	if (val & STA_PPSJITTER)
4267 		used = strlcat(str, "|STA_PPSJITTER", sizeof (pri->code_buf));
4268 	if (val & STA_PPSWANDER)
4269 		used = strlcat(str, "|STA_PPSWANDER", sizeof (pri->code_buf));
4270 	if (val & STA_PPSERROR)
4271 		used = strlcat(str, "|STA_PPSERROR", sizeof (pri->code_buf));
4272 
4273 	if (val & STA_CLOCKERR)
4274 		used = strlcat(str, "|STA_CLOCKERR", sizeof (pri->code_buf));
4275 
4276 	if (used == 0 || used >= sizeof (pri->code_buf))
4277 		(void) snprintf(str, sizeof (pri->code_buf), " 0x%.4x", val);
4278 
4279 	return (str + 1);
4280 }
4281 
4282 void
4283 show_ntp_adjtime(private_t *pri)
4284 {
4285 	struct timex timex;
4286 	long offset;
4287 
4288 	if (pri->sys_nargs < 1 || (offset = pri->sys_args[0]) == NULL)
4289 		return;
4290 
4291 	if (Pread(Proc, &timex, sizeof (timex), offset) != sizeof (timex))
4292 		return;
4293 
4294 	(void) printf("\tmodes:     %s\n", get_timex_modes(pri, timex.modes));
4295 	(void) printf("\toffset:    %11d usec\n", timex.offset);
4296 	(void) printf("\tfreq:      %11d scaled ppm\n", timex.freq);
4297 	(void) printf("\tmaxerror:  %11d usec\n", timex.maxerror);
4298 	(void) printf("\testerror:  %11d usec\n", timex.esterror);
4299 	(void) printf("\tstatus:    %s\n", get_timex_status(pri, timex.status));
4300 	(void) printf("\tconstant:  %11d\n", timex.constant);
4301 	(void) printf("\tprecision: %11d usec\n", timex.precision);
4302 	(void) printf("\ttolerance: %11d scaled ppm\n", timex.tolerance);
4303 	(void) printf("\tppsfreq:   %11d scaled ppm\n", timex.ppsfreq);
4304 	(void) printf("\tjitter:    %11d usec\n", timex.jitter);
4305 	(void) printf("\tshift:     %11d sec\n", timex.shift);
4306 	(void) printf("\tstabil:    %11d scaled ppm\n", timex.stabil);
4307 	(void) printf("\tjitcnt:    %11d\n", timex.jitcnt);
4308 	(void) printf("\tcalcnt:    %11d\n", timex.calcnt);
4309 	(void) printf("\terrcnt:    %11d\n", timex.errcnt);
4310 	(void) printf("\tstbcnt:    %11d\n", timex.stbcnt);
4311 }
4312 
4313 void
4314 show_getrusage(long offset)
4315 {
4316 	struct rusage r;
4317 	if (Pread(Proc, &r, sizeof (r), offset) != sizeof (r))
4318 		return;
4319 	(void) printf("\t       user time: %ld.%6.6ld sec\n",
4320 	    r.ru_utime.tv_sec,
4321 	    r.ru_utime.tv_usec);
4322 	(void) printf("\t     system time: %ld.%6.6ld sec\n",
4323 	    r.ru_stime.tv_sec,
4324 	    r.ru_stime.tv_usec);
4325 	(void) printf("\t         max rss: <unimpl> %ld\n",
4326 	    r.ru_maxrss);
4327 	(void) printf("\t     shared data: <unimpl> %ld\n",
4328 	    r.ru_ixrss);
4329 	(void) printf("\t   unshared data: <unimpl> %ld\n",
4330 	    r.ru_idrss);
4331 	(void) printf("\t  unshared stack: <unimpl> %ld\n",
4332 	    r.ru_isrss);
4333 	(void) printf("\t    minor faults: %ld\n",
4334 	    r.ru_minflt);
4335 	(void) printf("\t    major faults: %ld\n",
4336 	    r.ru_majflt);
4337 	(void) printf("\t      # of swaps: %ld\n",
4338 	    r.ru_nswap);
4339 	(void) printf("\t  blocked inputs: %ld\n",
4340 	    r.ru_inblock);
4341 	(void) printf("\t blocked outputs: %ld\n",
4342 	    r.ru_oublock);
4343 	(void) printf("\t       msgs sent: %ld\n",
4344 	    r.ru_msgsnd);
4345 	(void) printf("\t      msgs rcv'd: %ld\n",
4346 	    r.ru_msgrcv);
4347 	(void) printf("\t   signals rcv'd: %ld\n",
4348 	    r.ru_nsignals);
4349 	(void) printf("\tvol cntxt swtchs: %ld\n",
4350 	    r.ru_nvcsw);
4351 	(void) printf("\tinv cntxt swtchs: %ld\n",
4352 	    r.ru_nivcsw);
4353 }
4354 
4355 #ifdef _LP64
4356 void
4357 show_getrusage32(long offset)
4358 {
4359 	struct rusage32 r;
4360 	if (Pread(Proc, &r, sizeof (r), offset) != sizeof (r))
4361 		return;
4362 	(void) printf("\t       user time: %d.%6.6d sec\n",
4363 	    r.ru_utime.tv_sec,
4364 	    r.ru_utime.tv_usec);
4365 	(void) printf("\t     system time: %d.%6.6d sec\n",
4366 	    r.ru_stime.tv_sec,
4367 	    r.ru_stime.tv_usec);
4368 	(void) printf("\t         max rss: <unimpl> %d\n",
4369 	    r.ru_maxrss);
4370 	(void) printf("\t     shared data: <unimpl> %d\n",
4371 	    r.ru_ixrss);
4372 	(void) printf("\t   unshared data: <unimpl> %d\n",
4373 	    r.ru_idrss);
4374 	(void) printf("\t  unshared stack: <unimpl> %d\n",
4375 	    r.ru_isrss);
4376 	(void) printf("\t    minor faults: %d\n",
4377 	    r.ru_minflt);
4378 	(void) printf("\t    major faults: %d\n",
4379 	    r.ru_majflt);
4380 	(void) printf("\t      # of swaps: %d\n",
4381 	    r.ru_nswap);
4382 	(void) printf("\t  blocked inputs: %d\n",
4383 	    r.ru_inblock);
4384 	(void) printf("\t blocked outputs: %d\n",
4385 	    r.ru_oublock);
4386 	(void) printf("\t       msgs sent: %d\n",
4387 	    r.ru_msgsnd);
4388 	(void) printf("\t      msgs rcv'd: %d\n",
4389 	    r.ru_msgrcv);
4390 	(void) printf("\t   signals rcv'd: %d\n",
4391 	    r.ru_nsignals);
4392 	(void) printf("\tvol cntxt swtchs: %d\n",
4393 	    r.ru_nvcsw);
4394 	(void) printf("\tinv cntxt swtchs: %d\n",
4395 	    r.ru_nivcsw);
4396 }
4397 #endif
4398 
4399 /*
4400  * Utility function to print a packed nvlist by unpacking
4401  * and calling the libnvpair pretty printer.  Frees all
4402  * allocated memory internally.
4403  */
4404 static void
4405 show_packed_nvlist(private_t *pri, uintptr_t offset, size_t size)
4406 {
4407 	nvlist_t *nvl = NULL;
4408 	size_t readsize;
4409 	char *buf;
4410 
4411 	if ((offset == 0) || (size == 0)) {
4412 		return;
4413 	}
4414 
4415 	buf = my_malloc(size, "nvlist decode buffer");
4416 	readsize = Pread(Proc, buf, size, offset);
4417 	if (readsize != size) {
4418 		(void) printf("%s\t<?>", pri->pname);
4419 	} else {
4420 		int result;
4421 
4422 		result = nvlist_unpack(buf, size, &nvl, 0);
4423 		if (result == 0) {
4424 			nvlist_print(stdout, nvl);
4425 			nvlist_free(nvl);
4426 		} else {
4427 			(void) printf("%s\tunpack of nvlist"
4428 			    " failed: %d\n", pri->pname, result);
4429 		}
4430 	}
4431 	free(buf);
4432 }
4433 
4434 static void
4435 show_zone_create_args(private_t *pri, long offset)
4436 {
4437 	zone_def args;
4438 	char zone_name[ZONENAME_MAX];
4439 	char zone_root[MAXPATHLEN];
4440 	char *zone_zfs = NULL;
4441 
4442 	if (Pread(Proc, &args, sizeof (args), offset) == sizeof (args)) {
4443 
4444 		if (Pread_string(Proc, zone_name, sizeof (zone_name),
4445 		    (uintptr_t)args.zone_name) == -1)
4446 			(void) strcpy(zone_name, "<?>");
4447 
4448 		if (Pread_string(Proc, zone_root, sizeof (zone_root),
4449 		    (uintptr_t)args.zone_root) == -1)
4450 			(void) strcpy(zone_root, "<?>");
4451 
4452 		if (args.zfsbufsz > 0) {
4453 			zone_zfs = malloc(MIN(4, args.zfsbufsz));
4454 			if (zone_zfs != NULL) {
4455 				if (Pread(Proc, zone_zfs, args.zfsbufsz,
4456 				    (uintptr_t)args.zfsbuf) == -1)
4457 					(void) strcpy(zone_zfs, "<?>");
4458 			}
4459 		} else {
4460 			zone_zfs = "";
4461 		}
4462 
4463 		(void) printf("%s\t     zone_name: %s\n", pri->pname,
4464 		    zone_name);
4465 		(void) printf("%s\t     zone_root: %s\n", pri->pname,
4466 		    zone_root);
4467 
4468 		show_privset(pri, (uintptr_t)args.zone_privs,
4469 		    args.zone_privssz, "    zone_privs: ");
4470 
4471 		(void) printf("%s\t       rctlbuf: 0x%p\n", pri->pname,
4472 		    (void *)args.rctlbuf);
4473 		(void) printf("%s\t     rctlbufsz: %lu\n", pri->pname,
4474 		    (ulong_t)args.rctlbufsz);
4475 
4476 		show_packed_nvlist(pri, (uintptr_t)args.rctlbuf,
4477 		    args.rctlbufsz);
4478 
4479 		(void) printf("%s\t           zfs: %s\n", pri->pname, zone_zfs);
4480 
4481 		(void) printf("%s\textended_error: 0x%p\n", pri->pname,
4482 		    (void *)args.extended_error);
4483 
4484 		if (is_system_labeled()) {
4485 			char		*label_str = NULL;
4486 			bslabel_t	zone_label;
4487 
4488 			(void) printf("%s\t         match: %d\n", pri->pname,
4489 			    args.match);
4490 			(void) printf("%s\t           doi: %d\n", pri->pname,
4491 			    args.doi);
4492 
4493 			if (Pread_string(Proc, (char *)&zone_label,
4494 			    sizeof (zone_label), (uintptr_t)args.label) != -1) {
4495 				/* show the label as string */
4496 				if (label_to_str(&zone_label, &label_str,
4497 				    M_LABEL, SHORT_NAMES) != 0) {
4498 					/* have to dump label as raw string */
4499 					(void) label_to_str(&zone_label,
4500 					    &label_str, M_INTERNAL,
4501 					    SHORT_NAMES);
4502 				}
4503 			}
4504 
4505 			(void) printf("%s\t         label: %s\n",
4506 			    pri->pname, label_str != NULL ? label_str : "<?>");
4507 			if (label_str)
4508 				free(label_str);
4509 		}
4510 
4511 		if (args.zfsbufsz > 0)
4512 			free(zone_zfs);
4513 	}
4514 }
4515 
4516 
4517 #ifdef _LP64
4518 
4519 static void
4520 show_zone_create_args32(private_t *pri, long offset)
4521 {
4522 	zone_def32 args;
4523 	char zone_name[ZONENAME_MAX];
4524 	char zone_root[MAXPATHLEN];
4525 	char *zone_zfs = NULL;
4526 
4527 	if (Pread(Proc, &args, sizeof (args), offset) == sizeof (args)) {
4528 
4529 		if (Pread_string(Proc, zone_name, sizeof (zone_name),
4530 		    (uintptr_t)args.zone_name) == -1)
4531 			(void) strcpy(zone_name, "<?>");
4532 
4533 		if (Pread_string(Proc, zone_root, sizeof (zone_root),
4534 		    (uintptr_t)args.zone_root) == -1)
4535 			(void) strcpy(zone_root, "<?>");
4536 
4537 		if (args.zfsbufsz > 0) {
4538 			zone_zfs = malloc(MIN(4, args.zfsbufsz));
4539 			if (zone_zfs != NULL) {
4540 				if (Pread(Proc, zone_zfs, args.zfsbufsz,
4541 				    (uintptr_t)args.zfsbuf) == -1)
4542 					(void) strcpy(zone_zfs, "<?>");
4543 			}
4544 		} else {
4545 			zone_zfs = "";
4546 		}
4547 
4548 		(void) printf("%s\t     zone_name: %s\n", pri->pname,
4549 		    zone_name);
4550 		(void) printf("%s\t     zone_root: %s\n", pri->pname,
4551 		    zone_root);
4552 
4553 		show_privset(pri, (uintptr_t)args.zone_privs,
4554 		    args.zone_privssz, "    zone_privs: ");
4555 
4556 		(void) printf("%s\t       rctlbuf: 0x%x\n", pri->pname,
4557 		    (caddr32_t)args.rctlbuf);
4558 		(void) printf("%s\t     rctlbufsz: %lu\n", pri->pname,
4559 		    (ulong_t)args.rctlbufsz);
4560 
4561 		show_packed_nvlist(pri, (uintptr_t)args.rctlbuf,
4562 		    args.rctlbufsz);
4563 
4564 		(void) printf("%s\t           zfs: %s\n", pri->pname, zone_zfs);
4565 
4566 		(void) printf("%s\textended_error: 0x%x\n", pri->pname,
4567 		    (caddr32_t)args.extended_error);
4568 
4569 		if (is_system_labeled()) {
4570 			char		*label_str = NULL;
4571 			bslabel_t	zone_label;
4572 
4573 			(void) printf("%s\t         match: %d\n", pri->pname,
4574 			    args.match);
4575 			(void) printf("%s\t           doi: %d\n", pri->pname,
4576 			    args.doi);
4577 
4578 			if (Pread_string(Proc, (char *)&zone_label,
4579 			    sizeof (zone_label), (caddr32_t)args.label) != -1) {
4580 				/* show the label as string */
4581 				if (label_to_str(&zone_label, &label_str,
4582 				    M_LABEL, SHORT_NAMES) != 0) {
4583 					/* have to dump label as raw string */
4584 					(void) label_to_str(&zone_label,
4585 					    &label_str, M_INTERNAL,
4586 					    SHORT_NAMES);
4587 				}
4588 			}
4589 			(void) printf("%s\t         label: %s\n",
4590 			    pri->pname, label_str != NULL ? label_str : "<?>");
4591 			if (label_str)
4592 				free(label_str);
4593 		}
4594 
4595 		if (args.zfsbufsz > 0)
4596 			free(zone_zfs);
4597 	}
4598 }
4599 
4600 #endif
4601 
4602 static void
4603 show_zones(private_t *pri)
4604 {
4605 	switch (pri->sys_args[0]) {
4606 	case ZONE_CREATE:
4607 #ifdef _LP64
4608 		if (data_model == PR_MODEL_LP64)
4609 			show_zone_create_args(pri, (long)pri->sys_args[1]);
4610 		else
4611 			show_zone_create_args32(pri, (long)pri->sys_args[1]);
4612 #else
4613 		show_zone_create_args(pri, (long)pri->sys_args[1]);
4614 #endif
4615 		break;
4616 	}
4617 }
4618 
4619 static void
4620 show_rctlblk(private_t *pri, long _rctlblk)
4621 {
4622 	rctlblk_t *blk;
4623 	int size = rctlblk_size();
4624 	size_t readsize;
4625 	const char *s;
4626 
4627 	blk = my_malloc(size, "rctlblk decode buffer");
4628 	readsize = Pread(Proc, blk, size, _rctlblk);
4629 	if (readsize != size) {
4630 		(void) printf("%s\t\t<?>", pri->pname);
4631 	} else {
4632 		(void) printf("%s\t\t     Privilege: 0x%x\n",
4633 		    pri->pname,
4634 		    rctlblk_get_privilege(blk));
4635 		(void) printf("%s\t\t         Value: %lld\n",
4636 		    pri->pname,
4637 		    rctlblk_get_value(blk));
4638 		(void) printf("%s\t\tEnforced Value: %lld\n",
4639 		    pri->pname,
4640 		    rctlblk_get_enforced_value(blk));
4641 
4642 		{
4643 			int sig, act;
4644 			act = rctlblk_get_local_action(blk, &sig);
4645 
4646 			s = rctl_local_action(pri, act);
4647 			if (s == NULL) {
4648 				(void) printf("%s\t\t  Local action: 0x%x\n",
4649 				    pri->pname, act);
4650 			} else {
4651 				(void) printf("%s\t\t  Local action: %s\n",
4652 				    pri->pname, s);
4653 			}
4654 
4655 			if (act & RCTL_LOCAL_SIGNAL) {
4656 				(void) printf("%s\t\t                "
4657 				    "For signal %s\n",
4658 				    pri->pname, signame(pri, sig));
4659 			}
4660 		}
4661 
4662 		s = rctl_local_flags(pri, rctlblk_get_local_flags(blk));
4663 		if (s == NULL) {
4664 			(void) printf("%s\t\t   Local flags: 0x%x\n",
4665 			    pri->pname, rctlblk_get_local_flags(blk));
4666 		} else {
4667 			(void) printf("%s\t\t   Local flags: %s\n",
4668 			    pri->pname, s);
4669 		}
4670 
4671 #ifdef _LP64
4672 		(void) printf("%s\t\t Recipient PID: %d\n",
4673 		    pri->pname,
4674 		    rctlblk_get_recipient_pid(blk));
4675 #else
4676 		(void) printf("%s\t\t Recipient PID: %ld\n",
4677 		    pri->pname,
4678 		    rctlblk_get_recipient_pid(blk));
4679 #endif
4680 		(void) printf("%s\t\t   Firing Time: %lld\n",
4681 		    pri->pname,
4682 		    rctlblk_get_firing_time(blk));
4683 	}
4684 	free(blk);
4685 }
4686 
4687 static void
4688 show_rctls(private_t *pri)
4689 {
4690 	switch (pri->sys_args[0]) {
4691 	case 0:	/* getrctl */
4692 	case 1: /* setrctl */
4693 		/*
4694 		 * If these offsets look a little odd, remember that they're
4695 		 * into the _raw_ system call
4696 		 */
4697 		(void) printf("%s\tOld rctlblk: 0x%lx\n", pri->pname,
4698 		    pri->sys_args[2]);
4699 		if (pri->sys_args[2] != NULL) {
4700 			show_rctlblk(pri, pri->sys_args[2]);
4701 		}
4702 		(void) printf("%s\tNew rctlblk: 0x%lx\n", pri->pname,
4703 		    pri->sys_args[3]);
4704 		if (pri->sys_args[3] != NULL) {
4705 			show_rctlblk(pri, pri->sys_args[3]);
4706 		}
4707 		break;
4708 	}
4709 }
4710 
4711 /* expound verbosely upon syscall arguments */
4712 /*ARGSUSED*/
4713 void
4714 expound(private_t *pri, long r0, int raw)
4715 {
4716 	const lwpstatus_t *Lsp = pri->lwpstat;
4717 	int lp64 = (data_model == PR_MODEL_LP64);
4718 	int what = Lsp->pr_what;
4719 	int err = pri->Errno;		/* don't display output parameters */
4720 					/* for a failed system call */
4721 #ifndef _LP64
4722 	/* We are a 32-bit truss; we can't grok a 64-bit process */
4723 	if (lp64)
4724 		return;
4725 #endif
4726 	/* for reporting sleeping system calls */
4727 	if (what == 0 && (Lsp->pr_flags & (PR_ASLEEP|PR_VFORKP)))
4728 		what = Lsp->pr_syscall;
4729 
4730 	switch (what) {
4731 	case SYS_utime:
4732 		show_utime(pri);
4733 		break;
4734 	case SYS_utimes:
4735 		show_utimes(pri);
4736 		break;
4737 	case SYS_gettimeofday:
4738 		if (!err)
4739 			show_timeofday(pri);
4740 		break;
4741 	case SYS_getitimer:
4742 		if (!err && pri->sys_nargs > 1)
4743 			show_itimerval(pri, (long)pri->sys_args[1],
4744 				" value");
4745 		break;
4746 	case SYS_setitimer:
4747 		if (pri->sys_nargs > 1)
4748 			show_itimerval(pri, (long)pri->sys_args[1],
4749 				" value");
4750 		if (!err && pri->sys_nargs > 2)
4751 			show_itimerval(pri, (long)pri->sys_args[2],
4752 				"ovalue");
4753 		break;
4754 	case SYS_stime:
4755 		show_stime(pri);
4756 		break;
4757 	case SYS_times:
4758 		if (!err)
4759 			show_times(pri);
4760 		break;
4761 	case SYS_utssys:
4762 		if (err)
4763 			break;
4764 #ifdef _LP64
4765 		if (lp64)
4766 			show_utssys(pri, r0);
4767 		else
4768 			show_utssys32(pri, r0);
4769 #else
4770 		show_utssys(pri, r0);
4771 #endif
4772 		break;
4773 	case SYS_ioctl:
4774 		if (pri->sys_nargs >= 3) /* each case must decide for itself */
4775 			show_ioctl(pri, pri->sys_args[1],
4776 				(long)pri->sys_args[2]);
4777 		break;
4778 	case SYS_stat:
4779 	case SYS_fstat:
4780 	case SYS_lstat:
4781 		if (!err && pri->sys_nargs >= 2)
4782 			show_stat(pri, (long)pri->sys_args[1]);
4783 		break;
4784 	case SYS_stat64:
4785 	case SYS_fstat64:
4786 	case SYS_lstat64:
4787 		if (!err && pri->sys_nargs >= 2)
4788 			show_stat64_32(pri, (long)pri->sys_args[1]);
4789 		break;
4790 	case SYS_fsat:
4791 		/*
4792 		 * subcodes for fstatat() and fstatat64().
4793 		 */
4794 		if (!err && pri->sys_nargs >= 4) {
4795 			if (pri->sys_args[0] == 3)
4796 				show_statat(pri, (long)pri->sys_args[3]);
4797 			else if (pri->sys_args[0] == 2)
4798 				show_stat64_32(pri, (long)pri->sys_args[3]);
4799 		}
4800 		break;
4801 	case SYS_xstat:
4802 	case SYS_fxstat:
4803 	case SYS_lxstat:
4804 		if (!err && pri->sys_nargs >= 3)
4805 			show_xstat(pri, (int)pri->sys_args[0],
4806 				(long)pri->sys_args[2]);
4807 		break;
4808 	case SYS_statvfs:
4809 	case SYS_fstatvfs:
4810 		if (err)
4811 			break;
4812 #ifdef _LP64
4813 		if (!lp64) {
4814 			show_statvfs32(pri);
4815 			break;
4816 		}
4817 #endif
4818 		show_statvfs(pri);
4819 		break;
4820 	case SYS_statvfs64:
4821 	case SYS_fstatvfs64:
4822 		if (err)
4823 			break;
4824 		show_statvfs64(pri);
4825 		break;
4826 	case SYS_statfs:
4827 	case SYS_fstatfs:
4828 		if (err)
4829 			break;
4830 #ifdef _LP64
4831 		if (lp64)
4832 			show_statfs(pri);
4833 		else
4834 			show_statfs32(pri);
4835 #else
4836 		show_statfs(pri);
4837 #endif
4838 		break;
4839 	case SYS_fcntl:
4840 		show_fcntl(pri);
4841 		break;
4842 	case SYS_msgsys:
4843 		show_msgsys(pri, r0); /* each case must decide for itself */
4844 		break;
4845 	case SYS_semsys:
4846 		show_semsys(pri);	/* each case must decide for itself */
4847 		break;
4848 	case SYS_shmsys:
4849 		show_shmsys(pri);	/* each case must decide for itself */
4850 		break;
4851 	case SYS_getdents:
4852 		if (err || pri->sys_nargs <= 1 || r0 <= 0)
4853 			break;
4854 #ifdef _LP64
4855 		if (!lp64) {
4856 			show_dents32(pri, (long)pri->sys_args[1], r0);
4857 			break;
4858 		}
4859 		/* FALLTHROUGH */
4860 #else
4861 		show_dents32(pri, (long)pri->sys_args[1], r0);
4862 		break;
4863 #endif
4864 	case SYS_getdents64:
4865 		if (err || pri->sys_nargs <= 1 || r0 <= 0)
4866 			break;
4867 		show_dents64(pri, (long)pri->sys_args[1], r0);
4868 		break;
4869 	case SYS_getmsg:
4870 		show_gp_msg(pri, what);
4871 		if (pri->sys_nargs > 3)
4872 			show_hhex_int(pri, (long)pri->sys_args[3], "flags");
4873 		break;
4874 	case SYS_getpmsg:
4875 		show_gp_msg(pri, what);
4876 		if (pri->sys_nargs > 3)
4877 			show_hhex_int(pri, (long)pri->sys_args[3], "band");
4878 		if (pri->sys_nargs > 4)
4879 			show_hhex_int(pri, (long)pri->sys_args[4], "flags");
4880 		break;
4881 	case SYS_putmsg:
4882 	case SYS_putpmsg:
4883 		show_gp_msg(pri, what);
4884 		break;
4885 	case SYS_poll:
4886 		show_poll(pri);
4887 		break;
4888 	case SYS_pollsys:
4889 		show_pollsys(pri);
4890 		break;
4891 	case SYS_setgroups:
4892 		if (pri->sys_nargs > 1 && (r0 = pri->sys_args[0]) > 0)
4893 			show_groups(pri, (long)pri->sys_args[1], r0);
4894 		break;
4895 	case SYS_getgroups:
4896 		if (!err && pri->sys_nargs > 1 && pri->sys_args[0] > 0)
4897 			show_groups(pri, (long)pri->sys_args[1], r0);
4898 		break;
4899 	case SYS_sigprocmask:
4900 		if (pri->sys_nargs > 1)
4901 			show_sigset(pri, (long)pri->sys_args[1], " set");
4902 		if (!err && pri->sys_nargs > 2)
4903 			show_sigset(pri, (long)pri->sys_args[2], "oset");
4904 		break;
4905 	case SYS_sigsuspend:
4906 	case SYS_sigtimedwait:
4907 		if (pri->sys_nargs > 0)
4908 			show_sigset(pri, (long)pri->sys_args[0], "sigmask");
4909 		if (!err && pri->sys_nargs > 1)
4910 			show_siginfo(pri, (long)pri->sys_args[1]);
4911 		if (pri->sys_nargs > 2)
4912 			show_timestruc(pri, (long)pri->sys_args[2], "timeout");
4913 		break;
4914 	case SYS_sigaltstack:
4915 		if (pri->sys_nargs > 0)
4916 			show_sigaltstack(pri, (long)pri->sys_args[0],
4917 				"new");
4918 		if (!err && pri->sys_nargs > 1)
4919 			show_sigaltstack(pri, (long)pri->sys_args[1],
4920 				"old");
4921 		break;
4922 	case SYS_sigaction:
4923 		if (pri->sys_nargs > 1)
4924 			show_sigaction(pri, (long)pri->sys_args[1],
4925 				"new", NULL);
4926 		if (!err && pri->sys_nargs > 2)
4927 			show_sigaction(pri, (long)pri->sys_args[2],
4928 				"old", r0);
4929 		break;
4930 	case SYS_sigpending:
4931 		if (!err && pri->sys_nargs > 1)
4932 			show_sigset(pri, (long)pri->sys_args[1], "sigmask");
4933 		break;
4934 	case SYS_waitsys:
4935 		if (!err && pri->sys_nargs > 2)
4936 			show_siginfo(pri, (long)pri->sys_args[2]);
4937 		break;
4938 	case SYS_sigsendsys:
4939 		if (pri->sys_nargs > 0)
4940 			show_procset(pri, (long)pri->sys_args[0]);
4941 		break;
4942 	case SYS_priocntlsys:
4943 		if (pri->sys_nargs > 1)
4944 			show_procset(pri, (long)pri->sys_args[1]);
4945 		break;
4946 	case SYS_mincore:
4947 		if (!err && pri->sys_nargs > 2)
4948 			show_bool(pri, (long)pri->sys_args[2],
4949 				(pri->sys_args[1] + pagesize - 1) / pagesize);
4950 		break;
4951 	case SYS_readv:
4952 	case SYS_writev:
4953 		if (pri->sys_nargs > 2) {
4954 			int i = pri->sys_args[0]+1;
4955 			int showbuf = FALSE;
4956 			long nb = (what == SYS_readv)? r0 : 32*1024;
4957 
4958 			if ((what == SYS_readv && !err &&
4959 			    prismember(&readfd, i)) ||
4960 			    (what == SYS_writev &&
4961 			    prismember(&writefd, i)))
4962 				showbuf = TRUE;
4963 			show_iovec(pri, (long)pri->sys_args[1],
4964 				pri->sys_args[2], showbuf, nb);
4965 		}
4966 		break;
4967 	case SYS_getrlimit:
4968 		if (err)
4969 			break;
4970 		/*FALLTHROUGH*/
4971 	case SYS_setrlimit:
4972 		if (pri->sys_nargs <= 1)
4973 			break;
4974 #ifdef _LP64
4975 		if (lp64)
4976 			show_rlimit64(pri, (long)pri->sys_args[1]);
4977 		else
4978 			show_rlimit32(pri, (long)pri->sys_args[1]);
4979 #else
4980 		show_rlimit32(pri, (long)pri->sys_args[1]);
4981 #endif
4982 		break;
4983 	case SYS_getrlimit64:
4984 		if (err)
4985 			break;
4986 		/*FALLTHROUGH*/
4987 	case SYS_setrlimit64:
4988 		if (pri->sys_nargs <= 1)
4989 			break;
4990 		show_rlimit64(pri, (long)pri->sys_args[1]);
4991 		break;
4992 	case SYS_uname:
4993 		if (!err && pri->sys_nargs > 0)
4994 			show_nuname(pri, (long)pri->sys_args[0]);
4995 		break;
4996 	case SYS_adjtime:
4997 		if (!err && pri->sys_nargs > 1)
4998 			show_adjtime(pri, (long)pri->sys_args[0],
4999 				(long)pri->sys_args[1]);
5000 		break;
5001 	case SYS_lwp_info:
5002 		if (!err && pri->sys_nargs > 0)
5003 			show_timestruc(pri, (long)pri->sys_args[0], "cpu time");
5004 		break;
5005 	case SYS_lwp_wait:
5006 		if (!err && pri->sys_nargs > 1)
5007 			show_int(pri, (long)pri->sys_args[1], "lwpid");
5008 		break;
5009 	case SYS_lwp_mutex_wakeup:
5010 	case SYS_lwp_mutex_lock:
5011 	case SYS_lwp_mutex_unlock:
5012 	case SYS_lwp_mutex_trylock:
5013 	case SYS_lwp_mutex_init:
5014 		if (pri->sys_nargs > 0)
5015 			show_mutex(pri, (long)pri->sys_args[0]);
5016 		break;
5017 	case SYS_lwp_mutex_timedlock:
5018 		if (pri->sys_nargs > 0)
5019 			show_mutex(pri, (long)pri->sys_args[0]);
5020 		if (pri->sys_nargs > 1)
5021 			show_timestruc(pri, (long)pri->sys_args[1], "timeout");
5022 		break;
5023 	case SYS_lwp_cond_wait:
5024 		if (pri->sys_nargs > 0)
5025 			show_condvar(pri, (long)pri->sys_args[0]);
5026 		if (pri->sys_nargs > 1)
5027 			show_mutex(pri, (long)pri->sys_args[1]);
5028 		if (pri->sys_nargs > 2)
5029 			show_timestruc(pri, (long)pri->sys_args[2], "timeout");
5030 		break;
5031 	case SYS_lwp_cond_signal:
5032 	case SYS_lwp_cond_broadcast:
5033 		if (pri->sys_nargs > 0)
5034 			show_condvar(pri, (long)pri->sys_args[0]);
5035 		break;
5036 	case SYS_lwp_sema_wait:
5037 	case SYS_lwp_sema_trywait:
5038 	case SYS_lwp_sema_post:
5039 		if (pri->sys_nargs > 0)
5040 			show_sema(pri, (long)pri->sys_args[0]);
5041 		break;
5042 	case SYS_lwp_sema_timedwait:
5043 		if (pri->sys_nargs > 0)
5044 			show_sema(pri, (long)pri->sys_args[0]);
5045 		if (pri->sys_nargs > 1)
5046 			show_timestruc(pri, (long)pri->sys_args[1], "timeout");
5047 		break;
5048 	case SYS_lwp_rwlock_sys:
5049 		if (pri->sys_nargs > 1)
5050 			show_rwlock(pri, (long)pri->sys_args[1]);
5051 		if (pri->sys_nargs > 2 &&
5052 		    (pri->sys_args[0] == 0 || pri->sys_args[0] == 1))
5053 			show_timestruc(pri, (long)pri->sys_args[2], "timeout");
5054 		break;
5055 	case SYS_lwp_create:
5056 		/* XXX print some values in ucontext ??? */
5057 		if (!err && pri->sys_nargs > 2)
5058 			show_int(pri, (long)pri->sys_args[2], "lwpid");
5059 		break;
5060 	case SYS_kaio:
5061 		if (pri->sys_args[0] == AIOWAIT && !err && pri->sys_nargs > 1)
5062 			show_timeval(pri, (long)pri->sys_args[1], "timeout");
5063 		break;
5064 	case SYS_nanosleep:
5065 		if (pri->sys_nargs > 0)
5066 			show_timestruc(pri, (long)pri->sys_args[0], "tmout");
5067 		if (pri->sys_nargs > 1 && (err == 0 || err == EINTR))
5068 			show_timestruc(pri, (long)pri->sys_args[1], "resid");
5069 		break;
5070 	case SYS_privsys:
5071 		switch (pri->sys_args[0]) {
5072 		case PRIVSYS_SETPPRIV:
5073 		case PRIVSYS_GETPPRIV:
5074 			if (!err)
5075 				show_privset(pri, (long)pri->sys_args[3],
5076 					(size_t)pri->sys_args[4], "");
5077 		}
5078 		break;
5079 	case SYS_ucredsys:
5080 		switch (pri->sys_args[0]) {
5081 		case UCREDSYS_UCREDGET:
5082 		case UCREDSYS_GETPEERUCRED:
5083 			if (err == 0)
5084 				show_ucred(pri, (long)pri->sys_args[2]);
5085 			break;
5086 		}
5087 		break;
5088 	case SYS_bind:
5089 	case SYS_connect:
5090 		if (pri->sys_nargs > 2)
5091 			show_sockaddr(pri, "name", (long)pri->sys_args[1],
5092 				0, (long)pri->sys_args[2]);
5093 		break;
5094 	case SYS_sendto:
5095 		if (pri->sys_nargs > 5)
5096 			show_sockaddr(pri, "to", (long)pri->sys_args[4], 0,
5097 				pri->sys_args[5]);
5098 		break;
5099 	case SYS_accept:
5100 		if (!err && pri->sys_nargs > 2)
5101 			show_sockaddr(pri, "name", (long)pri->sys_args[1],
5102 				(long)pri->sys_args[2], 0);
5103 		break;
5104 	case SYS_getsockname:
5105 	case SYS_getpeername:
5106 		if (!err && pri->sys_nargs > 2)
5107 			show_sockaddr(pri, "name", (long)pri->sys_args[1],
5108 				(long)pri->sys_args[2], 0);
5109 		break;
5110 	case SYS_cladm:
5111 		if (!err && pri->sys_nargs > 2)
5112 			show_cladm(pri, pri->sys_args[0], pri->sys_args[1],
5113 			    (long)pri->sys_args[2]);
5114 		break;
5115 	case SYS_recvfrom:
5116 		if (!err && pri->sys_nargs > 5)
5117 			show_sockaddr(pri, "from", (long)pri->sys_args[4],
5118 				(long)pri->sys_args[5], 0);
5119 		break;
5120 	case SYS_recvmsg:
5121 		if (err)
5122 			break;
5123 		/* FALLTHROUGH */
5124 	case SYS_sendmsg:
5125 		if (pri->sys_nargs <= 2)
5126 			break;
5127 #ifdef _LP64
5128 		if (lp64)
5129 			show_msghdr(pri, pri->sys_args[1]);
5130 		else
5131 			show_msghdr32(pri, pri->sys_args[1]);
5132 #else
5133 		show_msghdr(pri, pri->sys_args[1]);
5134 #endif
5135 		break;
5136 	case SYS_door:
5137 		show_doors(pri);
5138 		break;
5139 	case SYS_sendfilev:
5140 		if (pri->sys_nargs != 5)
5141 			break;
5142 
5143 		if (pri->sys_args[0] == SENDFILEV) {
5144 			show_sendfilevec(pri, (int)pri->sys_args[1],
5145 				(sendfilevec_t *)pri->sys_args[2],
5146 				(int)pri->sys_args[3]);
5147 		} else if (pri->sys_args[0] == SENDFILEV64) {
5148 			show_sendfilevec64(pri, (int)pri->sys_args[1],
5149 				(sendfilevec64_t *)pri->sys_args[2],
5150 				(int)pri->sys_args[3]);
5151 		}
5152 		break;
5153 	case SYS_memcntl:
5154 		show_memcntl(pri);
5155 		break;
5156 	case SYS_lwp_park:
5157 		/* subcode 0: lwp_park(timespec_t *, id_t) */
5158 		if (pri->sys_nargs > 1 && pri->sys_args[0] == 0)
5159 			show_timestruc(pri, (long)pri->sys_args[1], "timeout");
5160 		/* subcode 2: lwp_unpark_all(id_t *, int) */
5161 		if (pri->sys_nargs > 2 && pri->sys_args[0] == 2)
5162 			show_ids(pri, (long)pri->sys_args[1],
5163 				(int)pri->sys_args[2]);
5164 		break;
5165 	case SYS_ntp_gettime:
5166 		if (!err)
5167 			show_ntp_gettime(pri);
5168 		break;
5169 	case SYS_ntp_adjtime:
5170 		if (!err)
5171 			show_ntp_adjtime(pri);
5172 		break;
5173 	case SYS_rusagesys:
5174 		if (!err)
5175 			if (pri->sys_args[0] == _RUSAGESYS_GETRUSAGE) {
5176 #ifdef _LP64
5177 				if (!lp64)
5178 				    show_getrusage32(pri->sys_args[1]);
5179 				else
5180 #endif
5181 				    show_getrusage(pri->sys_args[1]);
5182 			}
5183 		break;
5184 	case SYS_port:
5185 		show_ports(pri);
5186 		break;
5187 
5188 	case SYS_zone:
5189 		show_zones(pri);
5190 		break;
5191 
5192 	case SYS_rctlsys:
5193 		show_rctls(pri);
5194 		break;
5195 	}
5196 }
5197