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