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