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