/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ #pragma ident "%Z%%M% %I% %E% SMI" #define _SYSCALL32 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ramdata.h" #include "systable.h" #include "proto.h" void show_sigset(private_t *, long, const char *); void show_ioctl(private_t *, int, long); void prtime(private_t *pri, const char *name, time_t value) { char str[80]; (void) strftime(str, sizeof (str), "%b %e %H:%M:%S %Z %Y", localtime(&value)); (void) printf("%s\t%s%s [ %llu ]\n", pri->pname, name, str, (longlong_t)value); } void prtimestruc(private_t *pri, const char *name, timestruc_t *value) { prtime(pri, name, value->tv_sec); } void show_utime(private_t *pri) { long offset; struct utimbuf utimbuf; if (pri->sys_nargs < 2 || (offset = pri->sys_args[1]) == NULL) return; if (data_model == PR_MODEL_NATIVE) { if (Pread(Proc, &utimbuf, sizeof (utimbuf), offset) != sizeof (utimbuf)) return; } else { struct utimbuf32 utimbuf32; if (Pread(Proc, &utimbuf32, sizeof (utimbuf32), offset) != sizeof (utimbuf32)) return; utimbuf.actime = (time_t)utimbuf32.actime; utimbuf.modtime = (time_t)utimbuf32.modtime; } /* print access and modification times */ prtime(pri, "atime: ", utimbuf.actime); prtime(pri, "mtime: ", utimbuf.modtime); } void show_utimes(private_t *pri) { long offset; struct { struct timeval atime; struct timeval mtime; } utimbuf; if (pri->sys_nargs < 2 || (offset = pri->sys_args[1]) == NULL) return; if (data_model == PR_MODEL_NATIVE) { if (Pread(Proc, &utimbuf, sizeof (utimbuf), offset) != sizeof (utimbuf)) return; } else { struct { struct timeval32 atime; struct timeval32 mtime; } utimbuf32; if (Pread(Proc, &utimbuf32, sizeof (utimbuf32), offset) != sizeof (utimbuf32)) return; TIMEVAL32_TO_TIMEVAL(&utimbuf.atime, &utimbuf32.atime); TIMEVAL32_TO_TIMEVAL(&utimbuf.mtime, &utimbuf32.mtime); } /* print access and modification times */ prtime(pri, "atime: ", utimbuf.atime.tv_sec); prtime(pri, "mtime: ", utimbuf.mtime.tv_sec); } void show_timeofday(private_t *pri) { struct timeval tod; long offset; if (pri->sys_nargs < 1 || (offset = pri->sys_args[0]) == NULL) return; if (data_model == PR_MODEL_NATIVE) { if (Pread(Proc, &tod, sizeof (tod), offset) != sizeof (tod)) return; } else { struct timeval32 tod32; if (Pread(Proc, &tod32, sizeof (tod32), offset) != sizeof (tod32)) return; TIMEVAL32_TO_TIMEVAL(&tod, &tod32); } prtime(pri, "time: ", tod.tv_sec); } void show_itimerval(private_t *pri, long offset, const char *name) { struct itimerval itimerval; if (offset == NULL) return; if (data_model == PR_MODEL_NATIVE) { if (Pread(Proc, &itimerval, sizeof (itimerval), offset) != sizeof (itimerval)) return; } else { struct itimerval32 itimerval32; if (Pread(Proc, &itimerval32, sizeof (itimerval32), offset) != sizeof (itimerval32)) return; ITIMERVAL32_TO_ITIMERVAL(&itimerval, &itimerval32); } (void) printf( "%s\t%s: interval: %4ld.%6.6ld sec value: %4ld.%6.6ld sec\n", pri->pname, name, itimerval.it_interval.tv_sec, itimerval.it_interval.tv_usec, itimerval.it_value.tv_sec, itimerval.it_value.tv_usec); } void show_timeval(private_t *pri, long offset, const char *name) { struct timeval timeval; if (offset == NULL) return; if (data_model == PR_MODEL_NATIVE) { if (Pread(Proc, &timeval, sizeof (timeval), offset) != sizeof (timeval)) return; } else { struct timeval32 timeval32; if (Pread(Proc, &timeval32, sizeof (timeval32), offset) != sizeof (timeval32)) return; TIMEVAL32_TO_TIMEVAL(&timeval, &timeval32); } (void) printf( "%s\t%s: %ld.%6.6ld sec\n", pri->pname, name, timeval.tv_sec, timeval.tv_usec); } void show_timestruc(private_t *pri, long offset, const char *name) { timestruc_t timestruc; if (offset == NULL) return; if (data_model == PR_MODEL_NATIVE) { if (Pread(Proc, ×truc, sizeof (timestruc), offset) != sizeof (timestruc)) return; } else { timestruc32_t timestruc32; if (Pread(Proc, ×truc32, sizeof (timestruc32), offset) != sizeof (timestruc32)) return; TIMESPEC32_TO_TIMESPEC(×truc, ×truc32); } (void) printf( "%s\t%s: %ld.%9.9ld sec\n", pri->pname, name, timestruc.tv_sec, timestruc.tv_nsec); } void show_stime(private_t *pri) { if (pri->sys_nargs >= 1) { /* print new system time */ prtime(pri, "systime = ", (time_t)pri->sys_args[0]); } } void show_times(private_t *pri) { long hz = sysconf(_SC_CLK_TCK); long offset; struct tms tms; if (pri->sys_nargs < 1 || (offset = pri->sys_args[0]) == NULL) return; if (data_model == PR_MODEL_NATIVE) { if (Pread(Proc, &tms, sizeof (tms), offset) != sizeof (tms)) return; } else { struct tms32 tms32; if (Pread(Proc, &tms32, sizeof (tms32), offset) != sizeof (tms32)) return; /* * This looks a bit odd (since the values are actually * signed), but we need to suppress sign extension to * preserve compatibility (we've always printed these * numbers as unsigned quantities). */ tms.tms_utime = (unsigned)tms32.tms_utime; tms.tms_stime = (unsigned)tms32.tms_stime; tms.tms_cutime = (unsigned)tms32.tms_cutime; tms.tms_cstime = (unsigned)tms32.tms_cstime; } (void) printf( "%s\tutim=%-6lu stim=%-6lu cutim=%-6lu cstim=%-6lu (HZ=%ld)\n", pri->pname, tms.tms_utime, tms.tms_stime, tms.tms_cutime, tms.tms_cstime, hz); } void show_uname(private_t *pri, long offset) { /* * Old utsname buffer (no longer accessible in ). */ struct { char sysname[9]; char nodename[9]; char release[9]; char version[9]; char machine[9]; } ubuf; if (offset != NULL && Pread(Proc, &ubuf, sizeof (ubuf), offset) == sizeof (ubuf)) { (void) printf( "%s\tsys=%-9.9snod=%-9.9srel=%-9.9sver=%-9.9smch=%.9s\n", pri->pname, ubuf.sysname, ubuf.nodename, ubuf.release, ubuf.version, ubuf.machine); } } /* XX64 -- definition of 'struct ustat' is strange -- check out the defn */ void show_ustat(private_t *pri, long offset) { struct ustat ubuf; if (offset != NULL && Pread(Proc, &ubuf, sizeof (ubuf), offset) == sizeof (ubuf)) { (void) printf( "%s\ttfree=%-6ld tinode=%-5lu fname=%-6.6s fpack=%-.6s\n", pri->pname, ubuf.f_tfree, ubuf.f_tinode, ubuf.f_fname, ubuf.f_fpack); } } #ifdef _LP64 void show_ustat32(private_t *pri, long offset) { struct ustat32 ubuf; if (offset != NULL && Pread(Proc, &ubuf, sizeof (ubuf), offset) == sizeof (ubuf)) { (void) printf( "%s\ttfree=%-6d tinode=%-5u fname=%-6.6s fpack=%-.6s\n", pri->pname, ubuf.f_tfree, ubuf.f_tinode, ubuf.f_fname, ubuf.f_fpack); } } #endif /* _LP64 */ void show_fusers(private_t *pri, long offset, long nproc) { f_user_t fubuf; int serial = (nproc > 4); if (offset == NULL) return; /* enter region of lengthy output */ if (serial) Eserialize(); while (nproc > 0 && Pread(Proc, &fubuf, sizeof (fubuf), offset) == sizeof (fubuf)) { (void) printf("%s\tpid=%-5d uid=%-5u flags=%s\n", pri->pname, (int)fubuf.fu_pid, fubuf.fu_uid, fuflags(pri, fubuf.fu_flags)); nproc--; offset += sizeof (fubuf); } /* exit region of lengthy output */ if (serial) Xserialize(); } void show_utssys(private_t *pri, long r0) { if (pri->sys_nargs >= 3) { switch (pri->sys_args[2]) { case UTS_UNAME: show_uname(pri, (long)pri->sys_args[0]); break; case UTS_USTAT: show_ustat(pri, (long)pri->sys_args[0]); break; case UTS_FUSERS: show_fusers(pri, (long)pri->sys_args[3], r0); break; } } } #ifdef _LP64 void show_utssys32(private_t *pri, long r0) { if (pri->sys_nargs >= 3) { switch (pri->sys_args[2]) { case UTS_UNAME: show_uname(pri, (long)pri->sys_args[0]); break; case UTS_USTAT: show_ustat32(pri, (long)pri->sys_args[0]); break; case UTS_FUSERS: show_fusers(pri, (long)pri->sys_args[3], r0); break; } } } #endif /* _LP64 */ void show_cladm(private_t *pri, int code, int function, long offset) { int arg; switch (code) { case CL_INITIALIZE: switch (function) { case CL_GET_BOOTFLAG: if (Pread(Proc, &arg, sizeof (arg), offset) == sizeof (arg)) { if (arg & CLUSTER_CONFIGURED) (void) printf("%s\tbootflags=" "CLUSTER_CONFIGURED", pri->pname); if (arg & CLUSTER_BOOTED) (void) printf("|CLUSTER_BOOTED\n"); } break; } break; case CL_CONFIG: switch (function) { case CL_NODEID: case CL_HIGHEST_NODEID: if (Pread(Proc, &arg, sizeof (arg), offset) == sizeof (arg)) (void) printf("%s\tnodeid=%d\n", pri->pname, arg); } break; } } #define ALL_LOCK_TYPES \ (USYNC_PROCESS|LOCK_ERRORCHECK|LOCK_RECURSIVE|USYNC_PROCESS_ROBUST|\ LOCK_PRIO_INHERIT|LOCK_PRIO_PROTECT|LOCK_ROBUST_NP) /* return cv and mutex types */ const char * synch_type(private_t *pri, uint_t type) { char *str = pri->code_buf; if (type & USYNC_PROCESS) (void) strcpy(str, "USYNC_PROCESS"); else (void) strcpy(str, "USYNC_THREAD"); if (type & LOCK_ERRORCHECK) (void) strcat(str, "|LOCK_ERRORCHECK"); if (type & LOCK_RECURSIVE) (void) strcat(str, "|LOCK_RECURSIVE"); if (type & USYNC_PROCESS_ROBUST) (void) strcat(str, "|USYNC_PROCESS_ROBUST"); if (type & LOCK_PRIO_INHERIT) (void) strcat(str, "|LOCK_PRIO_INHERIT"); if (type & LOCK_PRIO_PROTECT) (void) strcat(str, "|LOCK_PRIO_PROTECT"); if (type & LOCK_ROBUST_NP) (void) strcat(str, "|LOCK_ROBUST_NP"); if ((type &= ~ALL_LOCK_TYPES) != 0) (void) sprintf(str + strlen(str), "|0x%.4X", type); return ((const char *)str); } void show_mutex(private_t *pri, long offset) { lwp_mutex_t mutex; if (Pread(Proc, &mutex, sizeof (mutex), offset) == sizeof (mutex)) { (void) printf("%s\tmutex type: %s\n", pri->pname, synch_type(pri, mutex.mutex_type)); } } void show_condvar(private_t *pri, long offset) { lwp_cond_t condvar; if (Pread(Proc, &condvar, sizeof (condvar), offset) == sizeof (condvar)) { (void) printf("%s\tcondvar type: %s\n", pri->pname, synch_type(pri, condvar.cond_type)); } } void show_sema(private_t *pri, long offset) { lwp_sema_t sema; if (Pread(Proc, &sema, sizeof (sema), offset) == sizeof (sema)) { (void) printf("%s\tsema type: %s count = %u\n", pri->pname, synch_type(pri, sema.sema_type), sema.sema_count); } } void show_rwlock(private_t *pri, long offset) { lwp_rwlock_t rwlock; if (Pread(Proc, &rwlock, sizeof (rwlock), offset) == sizeof (rwlock)) { (void) printf("%s\trwlock type: %s readers = %d\n", pri->pname, synch_type(pri, rwlock.rwlock_type), rwlock.rwlock_readers); } } /* represent character as itself ('c') or octal (012) */ char * show_char(char *buf, int c) { const char *fmt; if (c >= ' ' && c < 0177) fmt = "'%c'"; else fmt = "%.3o"; (void) sprintf(buf, fmt, c&0xff); return (buf); } void show_termio(private_t *pri, long offset) { struct termio termio; char cbuf[8]; int i; if (Pread(Proc, &termio, sizeof (termio), offset) == sizeof (termio)) { (void) printf( "%s\tiflag=0%.6o oflag=0%.6o cflag=0%.6o lflag=0%.6o line=%d\n", pri->pname, termio.c_iflag, termio.c_oflag, termio.c_cflag, termio.c_lflag, termio.c_line); (void) printf("%s\t cc: ", pri->pname); for (i = 0; i < NCC; i++) (void) printf(" %s", show_char(cbuf, (int)termio.c_cc[i])); (void) fputc('\n', stdout); } } void show_termios(private_t *pri, long offset) { struct termios termios; char cbuf[8]; int i; if (Pread(Proc, &termios, sizeof (termios), offset) == sizeof (termios)) { (void) printf( "%s\tiflag=0%.6o oflag=0%.6o cflag=0%.6o lflag=0%.6o\n", pri->pname, termios.c_iflag, termios.c_oflag, termios.c_cflag, termios.c_lflag); (void) printf("%s\t cc: ", pri->pname); for (i = 0; i < NCCS; i++) { if (i == NCC) /* show new chars on new line */ (void) printf("\n%s\t\t", pri->pname); (void) printf(" %s", show_char(cbuf, (int)termios.c_cc[i])); } (void) fputc('\n', stdout); } } void show_termiox(private_t *pri, long offset) { struct termiox termiox; int i; if (Pread(Proc, &termiox, sizeof (termiox), offset) == sizeof (termiox)) { (void) printf("%s\thflag=0%.3o cflag=0%.3o rflag=0%.3o", pri->pname, termiox.x_hflag, termiox.x_cflag, termiox.x_rflag[0]); for (i = 1; i < NFF; i++) (void) printf(",0%.3o", termiox.x_rflag[i]); (void) printf(" sflag=0%.3o\n", termiox.x_sflag); } } void show_sgttyb(private_t *pri, long offset) { struct sgttyb sgttyb; if (Pread(Proc, &sgttyb, sizeof (sgttyb), offset) == sizeof (sgttyb)) { char erase[8]; char kill[8]; (void) printf( "%s\tispeed=%-2d ospeed=%-2d erase=%s kill=%s flags=0x%.8x\n", pri->pname, sgttyb.sg_ispeed&0xff, sgttyb.sg_ospeed&0xff, show_char(erase, sgttyb.sg_erase), show_char(kill, sgttyb.sg_kill), sgttyb.sg_flags); } } void show_ltchars(private_t *pri, long offset) { struct ltchars ltchars; char *p; char cbuf[8]; int i; if (Pread(Proc, <chars, sizeof (ltchars), offset) == sizeof (ltchars)) { (void) printf("%s\t cc: ", pri->pname); for (p = (char *)<chars, i = 0; i < sizeof (ltchars); i++) (void) printf(" %s", show_char(cbuf, (int)*p++)); (void) fputc('\n', stdout); } } void show_tchars(private_t *pri, long offset) { struct tchars tchars; char *p; char cbuf[8]; int i; if (Pread(Proc, &tchars, sizeof (tchars), offset) == sizeof (tchars)) { (void) printf("%s\t cc: ", pri->pname); for (p = (char *)&tchars, i = 0; i < sizeof (tchars); i++) (void) printf(" %s", show_char(cbuf, (int)*p++)); (void) fputc('\n', stdout); } } void show_termcb(private_t *pri, long offset) { struct termcb termcb; if (Pread(Proc, &termcb, sizeof (termcb), offset) == sizeof (termcb)) { (void) printf( "%s\tflgs=0%.2o termt=%d crow=%d ccol=%d vrow=%d lrow=%d\n", pri->pname, termcb.st_flgs&0xff, termcb.st_termt&0xff, termcb.st_crow&0xff, termcb.st_ccol&0xff, termcb.st_vrow&0xff, termcb.st_lrow&0xff); } } /* integer value pointed to by ioctl() arg */ void show_strint(private_t *pri, int code, long offset) { int val; if (Pread(Proc, &val, sizeof (val), offset) == sizeof (val)) { const char *s = NULL; switch (code) { /* interpret these symbolically */ case I_GRDOPT: s = strrdopt(val); break; case I_GETSIG: s = strevents(pri, val); break; case TIOCFLUSH: s = tiocflush(pri, val); break; } if (s == NULL) (void) printf("%s\t0x%.8lX: %d\n", pri->pname, offset, val); else (void) printf("%s\t0x%.8lX: %s\n", pri->pname, offset, s); } } void show_strioctl(private_t *pri, long offset) { struct strioctl strioctl; if (Pread(Proc, &strioctl, sizeof (strioctl), offset) == sizeof (strioctl)) { (void) printf( "%s\tcmd=%s timout=%d len=%d dp=0x%.8lX\n", pri->pname, ioctlname(pri, strioctl.ic_cmd), strioctl.ic_timout, strioctl.ic_len, (long)strioctl.ic_dp); if (pri->recur++ == 0) /* avoid indefinite recursion */ show_ioctl(pri, strioctl.ic_cmd, (long)strioctl.ic_dp); --pri->recur; } } #ifdef _LP64 void show_strioctl32(private_t *pri, long offset) { struct strioctl32 strioctl; if (Pread(Proc, &strioctl, sizeof (strioctl), offset) == sizeof (strioctl)) { (void) printf( "%s\tcmd=%s timout=%d len=%d dp=0x%.8lX\n", pri->pname, ioctlname(pri, strioctl.ic_cmd), strioctl.ic_timout, strioctl.ic_len, (long)strioctl.ic_dp); if (pri->recur++ == 0) /* avoid indefinite recursion */ show_ioctl(pri, strioctl.ic_cmd, (long)strioctl.ic_dp); --pri->recur; } } #endif /* _LP64 */ void print_strbuf(private_t *pri, struct strbuf *sp, const char *name, int dump) { (void) printf( "%s\t%s: maxlen=%-4d len=%-4d buf=0x%.8lX", pri->pname, name, sp->maxlen, sp->len, (long)sp->buf); /* * Should we show the buffer contents? * Keyed to the '-r fds' and '-w fds' options? */ if (sp->buf == NULL || sp->len <= 0) (void) fputc('\n', stdout); else { int nb = (sp->len > 8)? 8 : sp->len; char buffer[8]; char obuf[40]; if (Pread(Proc, buffer, (size_t)nb, (long)sp->buf) == nb) { (void) strcpy(obuf, ": \""); showbytes(buffer, nb, obuf+3); (void) strcat(obuf, (nb == sp->len)? (const char *)"\"" : (const char *)"\".."); (void) fputs(obuf, stdout); } (void) fputc('\n', stdout); if (dump && sp->len > 8) showbuffer(pri, (long)sp->buf, (long)sp->len); } } #ifdef _LP64 void print_strbuf32(private_t *pri, struct strbuf32 *sp, const char *name, int dump) { (void) printf( "%s\t%s: maxlen=%-4d len=%-4d buf=0x%.8lX", pri->pname, name, sp->maxlen, sp->len, (long)sp->buf); /* * Should we show the buffer contents? * Keyed to the '-r fds' and '-w fds' options? */ if (sp->buf == NULL || sp->len <= 0) (void) fputc('\n', stdout); else { int nb = (sp->len > 8)? 8 : sp->len; char buffer[8]; char obuf[40]; if (Pread(Proc, buffer, (size_t)nb, (long)sp->buf) == nb) { (void) strcpy(obuf, ": \""); showbytes(buffer, nb, obuf+3); (void) strcat(obuf, (nb == sp->len)? (const char *)"\"" : (const char *)"\".."); (void) fputs(obuf, stdout); } (void) fputc('\n', stdout); if (dump && sp->len > 8) showbuffer(pri, (long)sp->buf, (long)sp->len); } } #endif /* _LP64 */ /* strpeek and strfdinsert flags word */ const char * strflags(private_t *pri, int flags) { const char *s; switch (flags) { case 0: s = "0"; break; case RS_HIPRI: s = "RS_HIPRI"; break; default: (void) sprintf(pri->code_buf, "0x%.4X", flags); s = pri->code_buf; } return (s); } void show_strpeek(private_t *pri, long offset) { struct strpeek strpeek; if (Pread(Proc, &strpeek, sizeof (strpeek), offset) == sizeof (strpeek)) { print_strbuf(pri, &strpeek.ctlbuf, "ctl", FALSE); print_strbuf(pri, &strpeek.databuf, "dat", FALSE); (void) printf("%s\tflags=%s\n", pri->pname, strflags(pri, strpeek.flags)); } } #ifdef _LP64 void show_strpeek32(private_t *pri, long offset) { struct strpeek32 strpeek; if (Pread(Proc, &strpeek, sizeof (strpeek), offset) == sizeof (strpeek)) { print_strbuf32(pri, &strpeek.ctlbuf, "ctl", FALSE); print_strbuf32(pri, &strpeek.databuf, "dat", FALSE); (void) printf("%s\tflags=%s\n", pri->pname, strflags(pri, strpeek.flags)); } } #endif /* _LP64 */ void show_strfdinsert(private_t *pri, long offset) { struct strfdinsert strfdinsert; if (Pread(Proc, &strfdinsert, sizeof (strfdinsert), offset) == sizeof (strfdinsert)) { print_strbuf(pri, &strfdinsert.ctlbuf, "ctl", FALSE); print_strbuf(pri, &strfdinsert.databuf, "dat", FALSE); (void) printf("%s\tflags=%s fildes=%d offset=%d\n", pri->pname, strflags(pri, strfdinsert.flags), strfdinsert.fildes, strfdinsert.offset); } } #ifdef _LP64 void show_strfdinsert32(private_t *pri, long offset) { struct strfdinsert32 strfdinsert; if (Pread(Proc, &strfdinsert, sizeof (strfdinsert), offset) == sizeof (strfdinsert)) { print_strbuf32(pri, &strfdinsert.ctlbuf, "ctl", FALSE); print_strbuf32(pri, &strfdinsert.databuf, "dat", FALSE); (void) printf("%s\tflags=%s fildes=%d offset=%d\n", pri->pname, strflags(pri, strfdinsert.flags), strfdinsert.fildes, strfdinsert.offset); } } #endif /* _LP64 */ void show_strrecvfd(private_t *pri, long offset) { struct strrecvfd strrecvfd; if (Pread(Proc, &strrecvfd, sizeof (strrecvfd), offset) == sizeof (strrecvfd)) { (void) printf( "%s\tfd=%-5d uid=%-5u gid=%u\n", pri->pname, strrecvfd.fd, strrecvfd.uid, strrecvfd.gid); } } void show_strlist(private_t *pri, long offset) { struct str_list strlist; struct str_mlist list; int count; if (Pread(Proc, &strlist, sizeof (strlist), offset) == sizeof (strlist)) { (void) printf("%s\tnmods=%d modlist=0x%.8lX\n", pri->pname, strlist.sl_nmods, (long)strlist.sl_modlist); count = strlist.sl_nmods; offset = (long)strlist.sl_modlist; while (!interrupt && --count >= 0) { if (Pread(Proc, &list, sizeof (list), offset) != sizeof (list)) break; (void) printf("%s\t\t\"%.*s\"\n", pri->pname, (int)sizeof (list.l_name), list.l_name); offset += sizeof (struct str_mlist); } } } #ifdef _LP64 void show_strlist32(private_t *pri, long offset) { struct str_list32 strlist; struct str_mlist list; int count; if (Pread(Proc, &strlist, sizeof (strlist), offset) == sizeof (strlist)) { (void) printf("%s\tnmods=%d modlist=0x%.8lX\n", pri->pname, strlist.sl_nmods, (long)strlist.sl_modlist); count = strlist.sl_nmods; offset = (long)strlist.sl_modlist; while (!interrupt && --count >= 0) { if (Pread(Proc, &list, sizeof (list), offset) != sizeof (list)) break; (void) printf("%s\t\t\"%.*s\"\n", pri->pname, (int)sizeof (list.l_name), list.l_name); offset += sizeof (struct str_mlist); } } } #endif /* _LP64 */ void show_jwinsize(private_t *pri, long offset) { struct jwinsize jwinsize; if (Pread(Proc, &jwinsize, sizeof (jwinsize), offset) == sizeof (jwinsize)) { (void) printf( "%s\tbytesx=%-3u bytesy=%-3u bitsx=%-3u bitsy=%-3u\n", pri->pname, (unsigned)jwinsize.bytesx, (unsigned)jwinsize.bytesy, (unsigned)jwinsize.bitsx, (unsigned)jwinsize.bitsy); } } void show_winsize(private_t *pri, long offset) { struct winsize winsize; if (Pread(Proc, &winsize, sizeof (winsize), offset) == sizeof (winsize)) { (void) printf( "%s\trow=%-3d col=%-3d xpixel=%-3d ypixel=%-3d\n", pri->pname, winsize.ws_row, winsize.ws_col, winsize.ws_xpixel, winsize.ws_ypixel); } } struct audio_stuff { uint_t bit; const char *str; }; const struct audio_stuff audio_output_ports[] = { { AUDIO_SPEAKER, "SPEAKER" }, { AUDIO_HEADPHONE, "HEADPHONE" }, { AUDIO_LINE_OUT, "LINE_OUT" }, { AUDIO_SPDIF_OUT, "SPDIF_OUT" }, { AUDIO_AUX1_OUT, "AUX1_OUT" }, { AUDIO_AUX2_OUT, "AUX2_OUT" }, { 0, NULL } }; const struct audio_stuff audio_input_ports[] = { { AUDIO_MICROPHONE, "MICROPHONE" }, { AUDIO_LINE_IN, "LINE_IN" }, { AUDIO_CD, "CD" }, { AUDIO_SPDIF_IN, "SPDIF_IN" }, { AUDIO_AUX1_IN, "AUX1_IN" }, { AUDIO_AUX2_IN, "AUX2_IN" }, { AUDIO_CODEC_LOOPB_IN, "CODEC_LOOPB_IN" }, { AUDIO_SUNVTS, "SUNVTS" }, { 0, NULL } }; static const struct audio_stuff audio_hw_features[] = { { AUDIO_HWFEATURE_DUPLEX, "DUPLEX" }, { AUDIO_HWFEATURE_MSCODEC, "MSCODEC" }, { AUDIO_HWFEATURE_IN2OUT, "IN2OUT" }, { AUDIO_HWFEATURE_PLAY, "PLAY" }, { AUDIO_HWFEATURE_RECORD, "RECORD" }, { 0, NULL } }; static const struct audio_stuff audio_sw_features[] = { { AUDIO_SWFEATURE_MIXER, "MIXER" }, { 0, NULL } }; void show_audio_features(const private_t *pri, const struct audio_stuff *audio_porttab, uint_t features, const char *name) { (void) printf("%s\t%s=", pri->pname, name); if (features == 0) { (void) printf("0\n"); return; } for (; audio_porttab->bit != 0; ++audio_porttab) { if (features & audio_porttab->bit) { (void) printf(audio_porttab->str); features &= ~audio_porttab->bit; if (features) (void) putchar('|'); } } if (features) (void) printf("0x%x", features); (void) putchar('\n'); } void show_audio_ports(private_t *pri, const char *mode, const char *field, uint_t ports) { const struct audio_stuff *audio_porttab; (void) printf("%s\t%s\t%s=", pri->pname, mode, field); if (ports == 0) { (void) printf("0\n"); return; } if (*mode == 'p') audio_porttab = audio_output_ports; else audio_porttab = audio_input_ports; for (; audio_porttab->bit != 0; ++audio_porttab) { if (ports & audio_porttab->bit) { (void) printf(audio_porttab->str); ports &= ~audio_porttab->bit; if (ports) (void) putchar('|'); } } if (ports) (void) printf("0x%x", ports); (void) putchar('\n'); } void show_audio_prinfo(private_t *pri, const char *mode, struct audio_prinfo *au_pr) { const char *s; /* * The following values describe the audio data encoding. */ (void) printf("%s\t%s\tsample_rate=%u channels=%u precision=%u\n", pri->pname, mode, au_pr->sample_rate, au_pr->channels, au_pr->precision); s = NULL; switch (au_pr->encoding) { case AUDIO_ENCODING_NONE: s = "NONE"; break; case AUDIO_ENCODING_ULAW: s = "ULAW"; break; case AUDIO_ENCODING_ALAW: s = "ALAW"; break; case AUDIO_ENCODING_LINEAR: s = "LINEAR"; break; case AUDIO_ENCODING_DVI: s = "DVI"; break; case AUDIO_ENCODING_LINEAR8: s = "LINEAR8"; break; } if (s) (void) printf("%s\t%s\tencoding=%s\n", pri->pname, mode, s); else { (void) printf("%s\t%s\tencoding=%u\n", pri->pname, mode, au_pr->encoding); } /* * The following values control audio device configuration */ (void) printf( "%s\t%s\tgain=%u buffer_size=%u\n", pri->pname, mode, au_pr->gain, au_pr->buffer_size); show_audio_ports(pri, mode, "port", au_pr->port); show_audio_ports(pri, mode, "avail_ports", au_pr->avail_ports); show_audio_ports(pri, mode, "mod_ports", au_pr->mod_ports); /* * The following values describe driver state */ (void) printf("%s\t%s\tsamples=%u eof=%u pause=%u error=%u\n", pri->pname, mode, au_pr->samples, au_pr->eof, au_pr->pause, au_pr->error); (void) printf("%s\t%s\twaiting=%u balance=%u minordev=%u\n", pri->pname, mode, au_pr->waiting, au_pr->balance, au_pr->minordev); /* * The following values are read-only state flags */ (void) printf("%s\t%s\topen=%u active=%u\n", pri->pname, mode, au_pr->open, au_pr->active); } void show_audio_info(private_t *pri, long offset) { struct audio_info au; if (Pread(Proc, &au, sizeof (au), offset) == sizeof (au)) { show_audio_prinfo(pri, "play", &au.play); show_audio_prinfo(pri, "record", &au.record); (void) printf("%s\tmonitor_gain=%u output_muted=%u\n", pri->pname, au.monitor_gain, au.output_muted); show_audio_features(pri, audio_hw_features, au.hw_features, "hw_features"); show_audio_features(pri, audio_sw_features, au.sw_features, "sw_features"); show_audio_features(pri, audio_sw_features, au.sw_features_enabled, "sw_features_enabled"); } } void show_ioctl(private_t *pri, int code, long offset) { int lp64 = (data_model == PR_MODEL_LP64); int err = pri->Errno; /* don't display output parameters */ /* for a failed system call */ #ifndef _LP64 if (lp64) return; #endif if (offset == NULL) return; switch (code) { case TCGETA: if (err) break; /*FALLTHROUGH*/ case TCSETA: case TCSETAW: case TCSETAF: show_termio(pri, offset); break; case TCGETS: if (err) break; /*FALLTHROUGH*/ case TCSETS: case TCSETSW: case TCSETSF: show_termios(pri, offset); break; case TCGETX: if (err) break; /*FALLTHROUGH*/ case TCSETX: case TCSETXW: case TCSETXF: show_termiox(pri, offset); break; case TIOCGETP: if (err) break; /*FALLTHROUGH*/ case TIOCSETN: case TIOCSETP: show_sgttyb(pri, offset); break; case TIOCGLTC: if (err) break; /*FALLTHROUGH*/ case TIOCSLTC: show_ltchars(pri, offset); break; case TIOCGETC: if (err) break; /*FALLTHROUGH*/ case TIOCSETC: show_tchars(pri, offset); break; case LDGETT: if (err) break; /*FALLTHROUGH*/ case LDSETT: show_termcb(pri, offset); break; /* streams ioctl()s */ #if 0 /* these are displayed as strings in the arg list */ /* by prt_ioa(). don't display them again here */ case I_PUSH: case I_LOOK: case I_FIND: /* these are displayed as decimal in the arg list */ /* by prt_ioa(). don't display them again here */ case I_LINK: case I_UNLINK: case I_SENDFD: /* these are displayed symbolically in the arg list */ /* by prt_ioa(). don't display them again here */ case I_SRDOPT: case I_SETSIG: case I_FLUSH: break; /* this one just ignores the argument */ case I_POP: break; #endif /* these return something in an int pointed to by arg */ case I_NREAD: case I_GRDOPT: case I_GETSIG: case TIOCGSID: case TIOCGPGRP: case TIOCLGET: case FIONREAD: case FIORDCHK: if (err) break; /*FALLTHROUGH*/ /* these pass something in an int pointed to by arg */ case TIOCSPGRP: case TIOCFLUSH: case TIOCLBIS: case TIOCLBIC: case TIOCLSET: show_strint(pri, code, offset); break; /* these all point to structures */ case I_STR: #ifdef _LP64 if (lp64) show_strioctl(pri, offset); else show_strioctl32(pri, offset); #else show_strioctl(pri, offset); #endif break; case I_PEEK: #ifdef _LP64 if (lp64) show_strpeek(pri, offset); else show_strpeek32(pri, offset); #else show_strpeek(pri, offset); #endif break; case I_FDINSERT: #ifdef _LP64 if (lp64) show_strfdinsert(pri, offset); else show_strfdinsert32(pri, offset); #else show_strfdinsert(pri, offset); #endif break; case I_RECVFD: if (err) break; show_strrecvfd(pri, offset); break; case I_LIST: if (err) break; #ifdef _LP64 if (lp64) show_strlist(pri, offset); else show_strlist32(pri, offset); #else show_strlist(pri, offset); #endif break; case JWINSIZE: if (err) break; show_jwinsize(pri, offset); break; case TIOCGWINSZ: if (err) break; /*FALLTHROUGH*/ case TIOCSWINSZ: show_winsize(pri, offset); break; case AUDIO_GETINFO: case (int)AUDIO_SETINFO: show_audio_info(pri, offset); break; default: if (code & IOC_INOUT) { const char *str = ioctldatastruct(code); (void) printf("\t\t%s", (code & IOC_INOUT) == IOC_INOUT ? "write/read" : code & IOC_IN ? "write" : "read"); if (str != NULL) { (void) printf(" (struct %s)\n", str); } else { (void) printf(" %d bytes\n", (code >> 16) & IOCPARM_MASK); } } } } void show_statvfs(private_t *pri) { long offset; struct statvfs statvfs; char *cp; if (pri->sys_nargs > 1 && (offset = pri->sys_args[1]) != NULL && Pread(Proc, &statvfs, sizeof (statvfs), offset) == sizeof (statvfs)) { (void) printf( "%s\tbsize=%-10lu frsize=%-9lu blocks=%-8llu bfree=%-9llu\n", pri->pname, statvfs.f_bsize, statvfs.f_frsize, (u_longlong_t)statvfs.f_blocks, (u_longlong_t)statvfs.f_bfree); (void) printf( "%s\tbavail=%-9llu files=%-10llu ffree=%-9llu favail=%-9llu\n", pri->pname, (u_longlong_t)statvfs.f_bavail, (u_longlong_t)statvfs.f_files, (u_longlong_t)statvfs.f_ffree, (u_longlong_t)statvfs.f_favail); (void) printf( "%s\tfsid=0x%-9.4lX basetype=%-7.16s namemax=%ld\n", pri->pname, statvfs.f_fsid, statvfs.f_basetype, (long)statvfs.f_namemax); (void) printf( "%s\tflag=%s\n", pri->pname, svfsflags(pri, (ulong_t)statvfs.f_flag)); cp = statvfs.f_fstr + strlen(statvfs.f_fstr); if (cp < statvfs.f_fstr + sizeof (statvfs.f_fstr) - 1 && *(cp+1) != '\0') *cp = ' '; (void) printf("%s\tfstr=\"%.*s\"\n", pri->pname, (int)sizeof (statvfs.f_fstr), statvfs.f_fstr); } } #ifdef _LP64 void show_statvfs32(private_t *pri) { long offset; struct statvfs32 statvfs; char *cp; if (pri->sys_nargs > 1 && (offset = pri->sys_args[1]) != NULL && Pread(Proc, &statvfs, sizeof (statvfs), offset) == sizeof (statvfs)) { (void) printf( "%s\tbsize=%-10u frsize=%-9u blocks=%-8u bfree=%-9u\n", pri->pname, statvfs.f_bsize, statvfs.f_frsize, statvfs.f_blocks, statvfs.f_bfree); (void) printf( "%s\tbavail=%-9u files=%-10u ffree=%-9u favail=%-9u\n", pri->pname, statvfs.f_bavail, statvfs.f_files, statvfs.f_ffree, statvfs.f_favail); (void) printf( "%s\tfsid=0x%-9.4X basetype=%-7.16s namemax=%d\n", pri->pname, statvfs.f_fsid, statvfs.f_basetype, (int)statvfs.f_namemax); (void) printf( "%s\tflag=%s\n", pri->pname, svfsflags(pri, (ulong_t)statvfs.f_flag)); cp = statvfs.f_fstr + strlen(statvfs.f_fstr); if (cp < statvfs.f_fstr + sizeof (statvfs.f_fstr) - 1 && *(cp+1) != '\0') *cp = ' '; (void) printf("%s\tfstr=\"%.*s\"\n", pri->pname, (int)sizeof (statvfs.f_fstr), statvfs.f_fstr); } } #endif /* _LP64 */ void show_statvfs64(private_t *pri) { long offset; struct statvfs64_32 statvfs; char *cp; if (pri->sys_nargs > 1 && (offset = pri->sys_args[1]) != NULL && Pread(Proc, &statvfs, sizeof (statvfs), offset) == sizeof (statvfs)) { (void) printf( "%s\tbsize=%-10u frsize=%-9u blocks=%-8llu bfree=%-9llu\n", pri->pname, statvfs.f_bsize, statvfs.f_frsize, (u_longlong_t)statvfs.f_blocks, (u_longlong_t)statvfs.f_bfree); (void) printf( "%s\tbavail=%-9llu files=%-10llu ffree=%-9llu favail=%-9llu\n", pri->pname, (u_longlong_t)statvfs.f_bavail, (u_longlong_t)statvfs.f_files, (u_longlong_t)statvfs.f_ffree, (u_longlong_t)statvfs.f_favail); (void) printf( "%s\tfsid=0x%-9.4X basetype=%-7.16s namemax=%d\n", pri->pname, statvfs.f_fsid, statvfs.f_basetype, (int)statvfs.f_namemax); (void) printf( "%s\tflag=%s\n", pri->pname, svfsflags(pri, (ulong_t)statvfs.f_flag)); cp = statvfs.f_fstr + strlen(statvfs.f_fstr); if (cp < statvfs.f_fstr + sizeof (statvfs.f_fstr) - 1 && *(cp+1) != '\0') *cp = ' '; (void) printf("%s\tfstr=\"%.*s\"\n", pri->pname, (int)sizeof (statvfs.f_fstr), statvfs.f_fstr); } } void show_statfs(private_t *pri) { long offset; struct statfs statfs; if (pri->sys_nargs >= 2 && (offset = pri->sys_args[1]) != NULL && Pread(Proc, &statfs, sizeof (statfs), offset) == sizeof (statfs)) { (void) printf( "%s\tfty=%d bsz=%ld fsz=%ld blk=%ld bfr=%ld fil=%lu ffr=%lu\n", pri->pname, statfs.f_fstyp, statfs.f_bsize, statfs.f_frsize, statfs.f_blocks, statfs.f_bfree, statfs.f_files, statfs.f_ffree); (void) printf("%s\t fname=%.6s fpack=%.6s\n", pri->pname, statfs.f_fname, statfs.f_fpack); } } #ifdef _LP64 void show_statfs32(private_t *pri) { long offset; struct statfs32 statfs; if (pri->sys_nargs >= 2 && (offset = pri->sys_args[1]) != NULL && Pread(Proc, &statfs, sizeof (statfs), offset) == sizeof (statfs)) { (void) printf( "%s\tfty=%d bsz=%d fsz=%d blk=%d bfr=%d fil=%u ffr=%u\n", pri->pname, statfs.f_fstyp, statfs.f_bsize, statfs.f_frsize, statfs.f_blocks, statfs.f_bfree, statfs.f_files, statfs.f_ffree); (void) printf("%s\t fname=%.6s fpack=%.6s\n", pri->pname, statfs.f_fname, statfs.f_fpack); } } #endif /* _LP64 */ void show_flock32(private_t *pri, long offset) { struct flock32 flock; if (Pread(Proc, &flock, sizeof (flock), offset) == sizeof (flock)) { const char *str = NULL; (void) printf("%s\ttyp=", pri->pname); switch (flock.l_type) { case F_RDLCK: str = "F_RDLCK"; break; case F_WRLCK: str = "F_WRLCK"; break; case F_UNLCK: str = "F_UNLCK"; break; } if (str != NULL) (void) printf("%s", str); else (void) printf("%-7d", flock.l_type); str = whencearg(flock.l_whence); if (str != NULL) (void) printf(" whence=%s", str); else (void) printf(" whence=%-8u", flock.l_whence); (void) printf( " start=%-5d len=%-5d sys=%-2u pid=%d\n", flock.l_start, flock.l_len, flock.l_sysid, flock.l_pid); } } void show_flock64(private_t *pri, long offset) { struct flock64 flock; if (Pread(Proc, &flock, sizeof (flock), offset) == sizeof (flock)) { const char *str = NULL; (void) printf("%s\ttyp=", pri->pname); switch (flock.l_type) { case F_RDLCK: str = "F_RDLCK"; break; case F_WRLCK: str = "F_WRLCK"; break; case F_UNLCK: str = "F_UNLCK"; break; } if (str != NULL) (void) printf("%s", str); else (void) printf("%-7d", flock.l_type); str = whencearg(flock.l_whence); if (str != NULL) (void) printf(" whence=%s", str); else (void) printf(" whence=%-8u", flock.l_whence); (void) printf( " start=%-5lld len=%-5lld sys=%-2u pid=%d\n", (long long)flock.l_start, (long long)flock.l_len, flock.l_sysid, (int)flock.l_pid); } } void show_share(private_t *pri, long offset) { struct fshare fshare; if (Pread(Proc, &fshare, sizeof (fshare), offset) == sizeof (fshare)) { const char *str = NULL; int manddny = 0; (void) printf("%s\taccess=", pri->pname); switch (fshare.f_access) { case F_RDACC: str = "F_RDACC"; break; case F_WRACC: str = "F_WRACC"; break; case F_RWACC: str = "F_RWACC"; break; } if (str != NULL) (void) printf("%s", str); else (void) printf("%-7d", fshare.f_access); str = NULL; if (fshare.f_deny & F_MANDDNY) { fshare.f_deny &= ~F_MANDDNY; manddny = 1; } switch (fshare.f_deny) { case F_NODNY: str = "F_NODNY"; break; case F_RDDNY: str = "F_RDDNY"; break; case F_WRDNY: str = "F_WRDNY"; break; case F_RWDNY: str = "F_RWDNY"; break; case F_COMPAT: str = "F_COMPAT"; break; } if (str != NULL) { if (manddny) (void) printf(" deny=F_MANDDNY|%s", str); else (void) printf(" deny=%s", str); } else { (void) printf(" deny=0x%x", manddny? fshare.f_deny | F_MANDDNY : fshare.f_deny); } (void) printf(" id=%x\n", fshare.f_id); } } void show_ffg(private_t *pri) { (void) putchar('\t'); (void) putchar('\t'); prt_ffg(pri, 0, pri->Rval1); (void) puts(pri->sys_string); } /* print values in fcntl() pointed-to structure */ void show_fcntl(private_t *pri) { long offset; if (pri->sys_nargs >= 2 && pri->sys_args[1] == F_GETFL) { show_ffg(pri); return; } if (pri->sys_nargs < 3 || (offset = pri->sys_args[2]) == NULL) return; switch (pri->sys_args[1]) { #ifdef _LP64 case F_GETLK: case F_SETLK: case F_SETLKW: case F_FREESP: case F_ALLOCSP: case F_SETLK_NBMAND: if (data_model == PR_MODEL_LP64) show_flock64(pri, offset); else show_flock32(pri, offset); break; case 33: /* F_GETLK64 */ case 34: /* F_SETLK64 */ case 35: /* F_SETLKW64 */ case 27: /* F_FREESP64 */ case 44: /* F_SETLK64_NBMAND */ show_flock64(pri, offset); break; #else /* _LP64 */ case F_GETLK: case F_SETLK: case F_SETLKW: case F_FREESP: case F_ALLOCSP: case F_SETLK_NBMAND: show_flock32(pri, offset); break; case F_GETLK64: case F_SETLK64: case F_SETLKW64: case F_FREESP64: case F_SETLK64_NBMAND: show_flock64(pri, offset); break; #endif /* _LP64 */ case F_SHARE: case F_UNSHARE: show_share(pri, offset); break; } } void show_strbuf(private_t *pri, long offset, const char *name, int dump) { struct strbuf strbuf; if (Pread(Proc, &strbuf, sizeof (strbuf), offset) == sizeof (strbuf)) print_strbuf(pri, &strbuf, name, dump); } #ifdef _LP64 void show_strbuf32(private_t *pri, long offset, const char *name, int dump) { struct strbuf32 strbuf; if (Pread(Proc, &strbuf, sizeof (strbuf), offset) == sizeof (strbuf)) print_strbuf32(pri, &strbuf, name, dump); } #endif /* _LP64 */ void show_gp_msg(private_t *pri, int what) { long offset; int dump = FALSE; int fdp1 = pri->sys_args[0] + 1; switch (what) { case SYS_getmsg: case SYS_getpmsg: if (pri->Errno == 0 && prismember(&readfd, fdp1)) dump = TRUE; break; case SYS_putmsg: case SYS_putpmsg: if (prismember(&writefd, fdp1)) dump = TRUE; break; } /* enter region of lengthy output */ if (dump) Eserialize(); #ifdef _LP64 if (pri->sys_nargs >= 2 && (offset = pri->sys_args[1]) != NULL) { if (data_model == PR_MODEL_LP64) show_strbuf(pri, offset, "ctl", dump); else show_strbuf32(pri, offset, "ctl", dump); } if (pri->sys_nargs >= 3 && (offset = pri->sys_args[2]) != NULL) { if (data_model == PR_MODEL_LP64) show_strbuf(pri, offset, "dat", dump); else show_strbuf32(pri, offset, "dat", dump); } #else /* _LP64 */ if (pri->sys_nargs >= 2 && (offset = pri->sys_args[1]) != NULL) show_strbuf(pri, offset, "ctl", dump); if (pri->sys_nargs >= 3 && (offset = pri->sys_args[2]) != NULL) show_strbuf(pri, offset, "dat", dump); #endif /* _LP64 */ /* exit region of lengthy output */ if (dump) Xserialize(); } void show_int(private_t *pri, long offset, const char *name) { int value; if (offset != 0 && Pread(Proc, &value, sizeof (value), offset) == sizeof (value)) (void) printf("%s\t%s:\t%d\n", pri->pname, name, value); } void show_hhex_int(private_t *pri, long offset, const char *name) { int value; if (Pread(Proc, &value, sizeof (value), offset) == sizeof (value)) (void) printf("%s\t%s:\t0x%.4X\n", pri->pname, name, value); } #define ALL_POLL_FLAGS (POLLIN|POLLPRI|POLLOUT| \ POLLRDNORM|POLLRDBAND|POLLWRBAND|POLLERR|POLLHUP|POLLNVAL) const char * pollevent(private_t *pri, int arg) { char *str = pri->code_buf; if (arg == 0) return ("0"); if (arg & ~ALL_POLL_FLAGS) { (void) sprintf(str, "0x%-5X", arg); return ((const char *)str); } *str = '\0'; if (arg & POLLIN) (void) strcat(str, "|POLLIN"); if (arg & POLLPRI) (void) strcat(str, "|POLLPRI"); if (arg & POLLOUT) (void) strcat(str, "|POLLOUT"); if (arg & POLLRDNORM) (void) strcat(str, "|POLLRDNORM"); if (arg & POLLRDBAND) (void) strcat(str, "|POLLRDBAND"); if (arg & POLLWRBAND) (void) strcat(str, "|POLLWRBAND"); if (arg & POLLERR) (void) strcat(str, "|POLLERR"); if (arg & POLLHUP) (void) strcat(str, "|POLLHUP"); if (arg & POLLNVAL) (void) strcat(str, "|POLLNVAL"); return ((const char *)(str+1)); } static void show_one_pollfd(private_t *pri, struct pollfd *ppollfd) { /* * can't print both events and revents in same printf. * pollevent() returns a pointer to a TSD location. */ (void) printf("%s\tfd=%-2d ev=%s", pri->pname, ppollfd->fd, pollevent(pri, ppollfd->events)); (void) printf(" rev=%s\n", pollevent(pri, ppollfd->revents)); } static void show_all_pollfds(private_t *pri, long offset, int nfds) { struct pollfd pollfd[2]; int skip = -1; for (; nfds && !interrupt; nfds--, offset += sizeof (struct pollfd)) { if (Pread(Proc, &pollfd[0], sizeof (struct pollfd), offset) != sizeof (struct pollfd)) continue; if (skip >= 0 && pollfd[0].fd == pollfd[1].fd && pollfd[0].events == pollfd[1].events && pollfd[0].revents == pollfd[1].revents) { skip++; continue; } if (skip > 0) (void) printf("%s\t...last pollfd structure" " repeated %d time%s...\n", pri->pname, skip, (skip == 1 ? "" : "s")); skip = 0; show_one_pollfd(pri, &pollfd[0]); pollfd[1] = pollfd[0]; } if (skip > 0) (void) printf( "%s\t...last pollfd structure repeated %d time%s...\n", pri->pname, skip, (skip == 1 ? "" : "s")); } void show_poll(private_t *pri) { long offset; int nfds; int serial = 0; if (pri->sys_nargs < 2 || (offset = pri->sys_args[0]) == NULL || (nfds = pri->sys_args[1]) <= 0) return; /* enter region of lengthy output */ if (nfds > 32) { Eserialize(); serial = 1; } show_all_pollfds(pri, offset, nfds); /* exit region of lengthy output */ if (serial) Xserialize(); } void show_pollsys(private_t *pri) { long offset; int nfds; int serial = 0; if (pri->sys_nargs < 2) return; offset = pri->sys_args[0]; nfds = pri->sys_args[1]; /* enter region of lengthy output */ if (offset != NULL && nfds > 32) { Eserialize(); serial = 1; } if (offset != NULL && nfds > 0) show_all_pollfds(pri, offset, nfds); if (pri->sys_nargs > 2) show_timestruc(pri, (long)pri->sys_args[2], "timeout"); if (pri->sys_nargs > 3) show_sigset(pri, (long)pri->sys_args[3], "sigmask"); /* exit region of lengthy output */ if (serial) Xserialize(); } static void show_perm64(private_t *pri, struct ipc_perm64 *ip) { (void) printf("%s\tu=%-5u g=%-5u cu=%-5u cg=%-5u z=%-5d " "m=0%.6o key=%d projid=%-5d\n", pri->pname, ip->ipcx_uid, ip->ipcx_gid, ip->ipcx_cuid, ip->ipcx_cgid, (int)ip->ipcx_zoneid, (unsigned int)ip->ipcx_mode, ip->ipcx_key, (int)ip->ipcx_projid); } void show_perm(private_t *pri, struct ipc_perm *ip) { (void) printf( "%s\tu=%-5u g=%-5u cu=%-5u cg=%-5u m=0%.6o seq=%u key=%d\n", pri->pname, ip->uid, ip->gid, ip->cuid, ip->cgid, (int)ip->mode, ip->seq, ip->key); } #ifdef _LP64 void show_perm32(private_t *pri, struct ipc_perm32 *ip) { (void) printf( "%s\tu=%-5u g=%-5u cu=%-5u cg=%-5u m=0%.6o seq=%u key=%d\n", pri->pname, ip->uid, ip->gid, ip->cuid, ip->cgid, ip->mode, ip->seq, ip->key); } #endif /* _LP64 */ static void show_msgctl64(private_t *pri, long offset) { struct msqid_ds64 msgq; if (offset != NULL && Pread(Proc, &msgq, sizeof (msgq), offset) == sizeof (msgq)) { show_perm64(pri, &msgq.msgx_perm); (void) printf("%s\tbytes=%-5llu msgs=%-5llu maxby=%-5llu " "lspid=%-5d lrpid=%-5d\n", pri->pname, (unsigned long long)msgq.msgx_cbytes, (unsigned long long)msgq.msgx_qnum, (unsigned long long)msgq.msgx_qbytes, (int)msgq.msgx_lspid, (int)msgq.msgx_lrpid); prtime(pri, " st = ", (time_t)msgq.msgx_stime); prtime(pri, " rt = ", (time_t)msgq.msgx_rtime); prtime(pri, " ct = ", (time_t)msgq.msgx_ctime); } } void show_msgctl(private_t *pri, long offset) { struct msqid_ds msgq; if (offset != NULL && Pread(Proc, &msgq, sizeof (msgq), offset) == sizeof (msgq)) { show_perm(pri, &msgq.msg_perm); (void) printf( "%s\tbytes=%-5lu msgs=%-5lu maxby=%-5lu lspid=%-5u lrpid=%-5u\n", pri->pname, msgq.msg_cbytes, msgq.msg_qnum, msgq.msg_qbytes, (int)msgq.msg_lspid, (int)msgq.msg_lrpid); prtime(pri, " st = ", msgq.msg_stime); prtime(pri, " rt = ", msgq.msg_rtime); prtime(pri, " ct = ", msgq.msg_ctime); } } #ifdef _LP64 void show_msgctl32(private_t *pri, long offset) { struct msqid_ds32 msgq; if (offset != NULL && Pread(Proc, &msgq, sizeof (msgq), offset) == sizeof (msgq)) { show_perm32(pri, &msgq.msg_perm); (void) printf( "%s\tbytes=%-5u msgs=%-5u maxby=%-5u lspid=%-5u lrpid=%-5u\n", pri->pname, msgq.msg_cbytes, msgq.msg_qnum, msgq.msg_qbytes, msgq.msg_lspid, msgq.msg_lrpid); prtime(pri, " st = ", msgq.msg_stime); prtime(pri, " rt = ", msgq.msg_rtime); prtime(pri, " ct = ", msgq.msg_ctime); } } #endif /* _LP64 */ void show_msgbuf(private_t *pri, long offset, long msgsz) { struct msgbuf msgb; if (offset != NULL && Pread(Proc, &msgb, sizeof (msgb.mtype), offset) == sizeof (msgb.mtype)) { /* enter region of lengthy output */ if (msgsz > MYBUFSIZ / 4) Eserialize(); (void) printf("%s\tmtype=%lu mtext[]=\n", pri->pname, msgb.mtype); showbuffer(pri, (long)(offset + sizeof (msgb.mtype)), msgsz); /* exit region of lengthy output */ if (msgsz > MYBUFSIZ / 4) Xserialize(); } } #ifdef _LP64 void show_msgbuf32(private_t *pri, long offset, long msgsz) { struct ipcmsgbuf32 msgb; if (offset != NULL && Pread(Proc, &msgb, sizeof (msgb.mtype), offset) == sizeof (msgb.mtype)) { /* enter region of lengthy output */ if (msgsz > MYBUFSIZ / 4) Eserialize(); (void) printf("%s\tmtype=%u mtext[]=\n", pri->pname, msgb.mtype); showbuffer(pri, (long)(offset + sizeof (msgb.mtype)), msgsz); /* exit region of lengthy output */ if (msgsz > MYBUFSIZ / 4) Xserialize(); } } #endif /* _LP64 */ #ifdef _LP64 void show_msgsys(private_t *pri, long msgsz) { switch (pri->sys_args[0]) { case 0: /* msgget() */ break; case 1: /* msgctl() */ if (pri->sys_nargs > 3) { switch (pri->sys_args[2]) { case IPC_STAT: if (pri->Errno) break; /*FALLTHROUGH*/ case IPC_SET: if (data_model == PR_MODEL_LP64) show_msgctl(pri, (long)pri->sys_args[3]); else show_msgctl32(pri, (long)pri->sys_args[3]); break; case IPC_STAT64: if (pri->Errno) break; /*FALLTHROUGH*/ case IPC_SET64: show_msgctl64(pri, (long)pri->sys_args[3]); break; } } break; case 2: /* msgrcv() */ if (!pri->Errno && pri->sys_nargs > 2) { if (data_model == PR_MODEL_LP64) show_msgbuf(pri, pri->sys_args[2], msgsz); else show_msgbuf32(pri, pri->sys_args[2], msgsz); } break; case 3: /* msgsnd() */ if (pri->sys_nargs > 3) { if (data_model == PR_MODEL_LP64) show_msgbuf(pri, pri->sys_args[2], pri->sys_args[3]); else show_msgbuf32(pri, pri->sys_args[2], pri->sys_args[3]); } break; case 4: /* msgids() */ case 5: /* msgsnap() */ default: /* unexpected subcode */ break; } } #else /* _LP64 */ void show_msgsys(private_t *pri, long msgsz) { switch (pri->sys_args[0]) { case 0: /* msgget() */ break; case 1: /* msgctl() */ if (pri->sys_nargs > 3) { switch (pri->sys_args[2]) { case IPC_STAT: if (pri->Errno) break; /*FALLTHROUGH*/ case IPC_SET: show_msgctl(pri, (long)pri->sys_args[3]); break; case IPC_STAT64: if (pri->Errno) break; /*FALLTHROUGH*/ case IPC_SET64: show_msgctl64(pri, (long)pri->sys_args[3]); break; } } break; case 2: /* msgrcv() */ if (!pri->Errno && pri->sys_nargs > 2) show_msgbuf(pri, pri->sys_args[2], msgsz); break; case 3: /* msgsnd() */ if (pri->sys_nargs > 3) show_msgbuf(pri, pri->sys_args[2], pri->sys_args[3]); break; case 4: /* msgids() */ case 5: /* msgsnap() */ default: /* unexpected subcode */ break; } } #endif /* _LP64 */ static void show_semctl64(private_t *pri, long offset) { struct semid_ds64 semds; if (offset != NULL && Pread(Proc, &semds, sizeof (semds), offset) == sizeof (semds)) { show_perm64(pri, &semds.semx_perm); (void) printf("%s\tnsems=%u\n", pri->pname, semds.semx_nsems); prtime(pri, " ot = ", (time_t)semds.semx_otime); prtime(pri, " ct = ", (time_t)semds.semx_ctime); } } void show_semctl(private_t *pri, long offset) { struct semid_ds semds; if (offset != NULL && Pread(Proc, &semds, sizeof (semds), offset) == sizeof (semds)) { show_perm(pri, &semds.sem_perm); (void) printf("%s\tnsems=%u\n", pri->pname, semds.sem_nsems); prtime(pri, " ot = ", semds.sem_otime); prtime(pri, " ct = ", semds.sem_ctime); } } #ifdef _LP64 void show_semctl32(private_t *pri, long offset) { struct semid_ds32 semds; if (offset != NULL && Pread(Proc, &semds, sizeof (semds), offset) == sizeof (semds)) { show_perm32(pri, &semds.sem_perm); (void) printf("%s\tnsems=%u\n", pri->pname, semds.sem_nsems); prtime(pri, " ot = ", semds.sem_otime); prtime(pri, " ct = ", semds.sem_ctime); } } #endif /* _LP64 */ void show_semop(private_t *pri, long offset, long nsops, long timeout) { struct sembuf sembuf; const char *str; if (offset == NULL) return; if (nsops > 40) /* let's not be ridiculous */ nsops = 40; for (; nsops > 0 && !interrupt; --nsops, offset += sizeof (sembuf)) { if (Pread(Proc, &sembuf, sizeof (sembuf), offset) != sizeof (sembuf)) break; (void) printf("%s\tsemnum=%-5u semop=%-5d semflg=", pri->pname, sembuf.sem_num, sembuf.sem_op); if (sembuf.sem_flg == 0) (void) printf("0\n"); else if ((str = semflags(pri, sembuf.sem_flg)) != NULL) (void) printf("%s\n", str); else (void) printf("0%.6o\n", sembuf.sem_flg); } if (timeout) show_timestruc(pri, timeout, "timeout"); } void show_semsys(private_t *pri) { switch (pri->sys_args[0]) { case 0: /* semctl() */ if (pri->sys_nargs > 4) { switch (pri->sys_args[3]) { case IPC_STAT: if (pri->Errno) break; /*FALLTHROUGH*/ case IPC_SET: #ifdef _LP64 if (data_model == PR_MODEL_LP64) show_semctl(pri, (long)pri->sys_args[4]); else show_semctl32(pri, (long)pri->sys_args[4]); #else show_semctl(pri, (long)pri->sys_args[4]); #endif break; case IPC_STAT64: if (pri->Errno) break; /*FALLTHROUGH*/ case IPC_SET64: show_semctl64(pri, (long)pri->sys_args[4]); break; } } break; case 1: /* semget() */ break; case 2: /* semop() */ if (pri->sys_nargs > 3) show_semop(pri, (long)pri->sys_args[2], pri->sys_args[3], 0); break; case 3: /* semids() */ break; case 4: /* semtimedop() */ if (pri->sys_nargs > 4) show_semop(pri, (long)pri->sys_args[2], pri->sys_args[3], pri->sys_args[4]); break; default: /* unexpected subcode */ break; } } static void show_shmctl64(private_t *pri, long offset) { struct shmid_ds64 shmds; if (offset != NULL && Pread(Proc, &shmds, sizeof (shmds), offset) == sizeof (shmds)) { show_perm64(pri, &shmds.shmx_perm); (void) printf( "%s\tsize=%-6llu lpid=%-5d cpid=%-5d na=%-5llu cna=%llu\n", pri->pname, (unsigned long long)shmds.shmx_segsz, (int)shmds.shmx_lpid, (int)shmds.shmx_cpid, (unsigned long long)shmds.shmx_nattch, (unsigned long long)shmds.shmx_cnattch); prtime(pri, " at = ", (time_t)shmds.shmx_atime); prtime(pri, " dt = ", (time_t)shmds.shmx_dtime); prtime(pri, " ct = ", (time_t)shmds.shmx_ctime); } } void show_shmctl(private_t *pri, long offset) { struct shmid_ds shmds; if (offset != NULL && Pread(Proc, &shmds, sizeof (shmds), offset) == sizeof (shmds)) { show_perm(pri, &shmds.shm_perm); (void) printf( "%s\tsize=%-6lu lpid=%-5u cpid=%-5u na=%-5lu cna=%lu\n", pri->pname, (ulong_t)shmds.shm_segsz, (int)shmds.shm_lpid, (int)shmds.shm_cpid, shmds.shm_nattch, shmds.shm_cnattch); prtime(pri, " at = ", shmds.shm_atime); prtime(pri, " dt = ", shmds.shm_dtime); prtime(pri, " ct = ", shmds.shm_ctime); } } #ifdef _LP64 void show_shmctl32(private_t *pri, long offset) { struct shmid_ds32 shmds; if (offset != NULL && Pread(Proc, &shmds, sizeof (shmds), offset) == sizeof (shmds)) { show_perm32(pri, &shmds.shm_perm); (void) printf( "%s\tsize=%-6u lpid=%-5u cpid=%-5u na=%-5u cna=%u\n", pri->pname, shmds.shm_segsz, shmds.shm_lpid, shmds.shm_cpid, shmds.shm_nattch, shmds.shm_cnattch); prtime(pri, " at = ", shmds.shm_atime); prtime(pri, " dt = ", shmds.shm_dtime); prtime(pri, " ct = ", shmds.shm_ctime); } } #endif /* _LP64 */ void show_shmsys(private_t *pri) { switch (pri->sys_args[0]) { case 0: /* shmat() */ break; case 1: /* shmctl() */ if (pri->sys_nargs > 3) { switch (pri->sys_args[2]) { case IPC_STAT: if (pri->Errno) break; /*FALLTHROUGH*/ case IPC_SET: #ifdef _LP64 if (data_model == PR_MODEL_LP64) show_shmctl(pri, (long)pri->sys_args[3]); else show_shmctl32(pri, (long)pri->sys_args[3]); #else show_shmctl(pri, (long)pri->sys_args[3]); #endif break; case IPC_STAT64: if (pri->Errno) break; /*FALLTHROUGH*/ case IPC_SET64: show_shmctl64(pri, (long)pri->sys_args[3]); break; } } break; case 2: /* shmdt() */ case 3: /* shmget() */ case 4: /* shmids() */ default: /* unexpected subcode */ break; } } void show_groups(private_t *pri, long offset, long count) { int groups[100]; if (count > 100) count = 100; if (count > 0 && offset != NULL && Pread(Proc, &groups[0], count*sizeof (int), offset) == count*sizeof (int)) { int n; (void) printf("%s\t", pri->pname); for (n = 0; !interrupt && n < count; n++) { if (n != 0 && n%10 == 0) (void) printf("\n%s\t", pri->pname); (void) printf(" %5d", groups[n]); } (void) fputc('\n', stdout); } } /* * This assumes that a sigset_t is simply an array of ints. */ char * sigset_string(private_t *pri, sigset_t *sp) { char *s = pri->code_buf; int n = sizeof (*sp) / sizeof (int32_t); int32_t *lp = (int32_t *)sp; while (--n >= 0) { int32_t val = *lp++; if (val == 0) s += sprintf(s, " 0"); else s += sprintf(s, " 0x%.8X", val); } return (pri->code_buf); } void show_sigset(private_t *pri, long offset, const char *name) { sigset_t sigset; if (offset != NULL && Pread(Proc, &sigset, sizeof (sigset), offset) == sizeof (sigset)) { (void) printf("%s\t%s =%s\n", pri->pname, name, sigset_string(pri, &sigset)); } } #ifdef _LP64 void show_sigaltstack32(private_t *pri, long offset, const char *name) { struct sigaltstack32 altstack; if (offset != NULL && Pread(Proc, &altstack, sizeof (altstack), offset) == sizeof (altstack)) { (void) printf("%s\t%s: sp=0x%.8X size=%u flags=0x%.4X\n", pri->pname, name, altstack.ss_sp, altstack.ss_size, altstack.ss_flags); } } #endif /* _LP64 */ void show_sigaltstack(private_t *pri, long offset, const char *name) { struct sigaltstack altstack; #ifdef _LP64 if (data_model != PR_MODEL_LP64) { show_sigaltstack32(pri, offset, name); return; } #endif if (offset != NULL && Pread(Proc, &altstack, sizeof (altstack), offset) == sizeof (altstack)) { (void) printf("%s\t%s: sp=0x%.8lX size=%lu flags=0x%.4X\n", pri->pname, name, (ulong_t)altstack.ss_sp, (ulong_t)altstack.ss_size, altstack.ss_flags); } } #ifdef _LP64 void show_sigaction32(private_t *pri, long offset, const char *name, long odisp) { struct sigaction32 sigaction; if (offset != NULL && Pread(Proc, &sigaction, sizeof (sigaction), offset) == sizeof (sigaction)) { /* This is stupid, we shouldn't have to do this */ if (odisp != NULL) sigaction.sa_handler = (caddr32_t)odisp; (void) printf( "%s %s: hand = 0x%.8X mask =%s flags = 0x%.4X\n", pri->pname, name, sigaction.sa_handler, sigset_string(pri, (sigset_t *)&sigaction.sa_mask), sigaction.sa_flags); } } #endif /* _LP64 */ void show_sigaction(private_t *pri, long offset, const char *name, long odisp) { struct sigaction sigaction; #ifdef _LP64 if (data_model != PR_MODEL_LP64) { show_sigaction32(pri, offset, name, odisp); return; } #endif if (offset != NULL && Pread(Proc, &sigaction, sizeof (sigaction), offset) == sizeof (sigaction)) { /* This is stupid, we shouldn't have to do this */ if (odisp != NULL) sigaction.sa_handler = (void (*)())odisp; (void) printf( "%s %s: hand = 0x%.8lX mask =%s flags = 0x%.4X\n", pri->pname, name, (long)sigaction.sa_handler, sigset_string(pri, &sigaction.sa_mask), sigaction.sa_flags); } } #ifdef _LP64 void print_siginfo32(private_t *pri, const siginfo32_t *sip) { const char *code = NULL; (void) printf("%s siginfo: %s", pri->pname, signame(pri, sip->si_signo)); if (sip->si_signo != 0 && SI_FROMUSER(sip) && sip->si_pid != 0) { (void) printf(" pid=%d uid=%d", sip->si_pid, sip->si_uid); if (sip->si_code != 0) (void) printf(" code=%d", sip->si_code); (void) fputc('\n', stdout); return; } switch (sip->si_signo) { default: (void) fputc('\n', stdout); return; case SIGILL: case SIGTRAP: case SIGFPE: case SIGSEGV: case SIGBUS: case SIGEMT: case SIGCLD: case SIGPOLL: case SIGXFSZ: break; } switch (sip->si_signo) { case SIGILL: switch (sip->si_code) { case ILL_ILLOPC: code = "ILL_ILLOPC"; break; case ILL_ILLOPN: code = "ILL_ILLOPN"; break; case ILL_ILLADR: code = "ILL_ILLADR"; break; case ILL_ILLTRP: code = "ILL_ILLTRP"; break; case ILL_PRVOPC: code = "ILL_PRVOPC"; break; case ILL_PRVREG: code = "ILL_PRVREG"; break; case ILL_COPROC: code = "ILL_COPROC"; break; case ILL_BADSTK: code = "ILL_BADSTK"; break; } break; case SIGTRAP: switch (sip->si_code) { case TRAP_BRKPT: code = "TRAP_BRKPT"; break; case TRAP_TRACE: code = "TRAP_TRACE"; break; case TRAP_RWATCH: code = "TRAP_RWATCH"; break; case TRAP_WWATCH: code = "TRAP_WWATCH"; break; case TRAP_XWATCH: code = "TRAP_XWATCH"; break; case TRAP_DTRACE: code = "TRAP_DTRACE"; break; } break; case SIGFPE: switch (sip->si_code) { case FPE_INTDIV: code = "FPE_INTDIV"; break; case FPE_INTOVF: code = "FPE_INTOVF"; break; case FPE_FLTDIV: code = "FPE_FLTDIV"; break; case FPE_FLTOVF: code = "FPE_FLTOVF"; break; case FPE_FLTUND: code = "FPE_FLTUND"; break; case FPE_FLTRES: code = "FPE_FLTRES"; break; case FPE_FLTINV: code = "FPE_FLTINV"; break; case FPE_FLTSUB: code = "FPE_FLTSUB"; break; #if defined(FPE_FLTDEN) case FPE_FLTDEN: code = "FPE_FLTDEN"; break; #endif } break; case SIGSEGV: switch (sip->si_code) { case SEGV_MAPERR: code = "SEGV_MAPERR"; break; case SEGV_ACCERR: code = "SEGV_ACCERR"; break; } break; case SIGEMT: switch (sip->si_code) { #ifdef EMT_TAGOVF case EMT_TAGOVF: code = "EMT_TAGOVF"; break; #endif case EMT_CPCOVF: code = "EMT_CPCOVF"; break; } break; case SIGBUS: switch (sip->si_code) { case BUS_ADRALN: code = "BUS_ADRALN"; break; case BUS_ADRERR: code = "BUS_ADRERR"; break; case BUS_OBJERR: code = "BUS_OBJERR"; break; } break; case SIGCLD: switch (sip->si_code) { case CLD_EXITED: code = "CLD_EXITED"; break; case CLD_KILLED: code = "CLD_KILLED"; break; case CLD_DUMPED: code = "CLD_DUMPED"; break; case CLD_TRAPPED: code = "CLD_TRAPPED"; break; case CLD_STOPPED: code = "CLD_STOPPED"; break; case CLD_CONTINUED: code = "CLD_CONTINUED"; break; } break; case SIGPOLL: switch (sip->si_code) { case POLL_IN: code = "POLL_IN"; break; case POLL_OUT: code = "POLL_OUT"; break; case POLL_MSG: code = "POLL_MSG"; break; case POLL_ERR: code = "POLL_ERR"; break; case POLL_PRI: code = "POLL_PRI"; break; case POLL_HUP: code = "POLL_HUP"; break; } break; } if (code == NULL) { (void) sprintf(pri->code_buf, "code=%d", sip->si_code); code = (const char *)pri->code_buf; } switch (sip->si_signo) { case SIGILL: case SIGTRAP: case SIGFPE: case SIGSEGV: case SIGBUS: case SIGEMT: (void) printf(" %s addr=0x%.8X", code, sip->si_addr); break; case SIGCLD: (void) printf(" %s pid=%d status=0x%.4X", code, sip->si_pid, sip->si_status); break; case SIGPOLL: case SIGXFSZ: (void) printf(" %s fd=%d band=%d", code, sip->si_fd, sip->si_band); break; } if (sip->si_errno != 0) { const char *ename = errname(sip->si_errno); (void) printf(" errno=%d", sip->si_errno); if (ename != NULL) (void) printf("(%s)", ename); } (void) fputc('\n', stdout); } #endif /* _LP64 */ void print_siginfo(private_t *pri, const siginfo_t *sip) { const char *code = NULL; (void) printf("%s siginfo: %s", pri->pname, signame(pri, sip->si_signo)); if (sip->si_signo != 0 && SI_FROMUSER(sip) && sip->si_pid != 0) { (void) printf(" pid=%d uid=%u", (int)sip->si_pid, sip->si_uid); if (sip->si_code != 0) (void) printf(" code=%d", sip->si_code); (void) fputc('\n', stdout); return; } switch (sip->si_signo) { default: (void) fputc('\n', stdout); return; case SIGILL: case SIGTRAP: case SIGFPE: case SIGSEGV: case SIGBUS: case SIGEMT: case SIGCLD: case SIGPOLL: case SIGXFSZ: break; } switch (sip->si_signo) { case SIGILL: switch (sip->si_code) { case ILL_ILLOPC: code = "ILL_ILLOPC"; break; case ILL_ILLOPN: code = "ILL_ILLOPN"; break; case ILL_ILLADR: code = "ILL_ILLADR"; break; case ILL_ILLTRP: code = "ILL_ILLTRP"; break; case ILL_PRVOPC: code = "ILL_PRVOPC"; break; case ILL_PRVREG: code = "ILL_PRVREG"; break; case ILL_COPROC: code = "ILL_COPROC"; break; case ILL_BADSTK: code = "ILL_BADSTK"; break; } break; case SIGTRAP: switch (sip->si_code) { case TRAP_BRKPT: code = "TRAP_BRKPT"; break; case TRAP_TRACE: code = "TRAP_TRACE"; break; case TRAP_RWATCH: code = "TRAP_RWATCH"; break; case TRAP_WWATCH: code = "TRAP_WWATCH"; break; case TRAP_XWATCH: code = "TRAP_XWATCH"; break; case TRAP_DTRACE: code = "TRAP_DTRACE"; break; } break; case SIGFPE: switch (sip->si_code) { case FPE_INTDIV: code = "FPE_INTDIV"; break; case FPE_INTOVF: code = "FPE_INTOVF"; break; case FPE_FLTDIV: code = "FPE_FLTDIV"; break; case FPE_FLTOVF: code = "FPE_FLTOVF"; break; case FPE_FLTUND: code = "FPE_FLTUND"; break; case FPE_FLTRES: code = "FPE_FLTRES"; break; case FPE_FLTINV: code = "FPE_FLTINV"; break; case FPE_FLTSUB: code = "FPE_FLTSUB"; break; #if defined(FPE_FLTDEN) case FPE_FLTDEN: code = "FPE_FLTDEN"; break; #endif } break; case SIGSEGV: switch (sip->si_code) { case SEGV_MAPERR: code = "SEGV_MAPERR"; break; case SEGV_ACCERR: code = "SEGV_ACCERR"; break; } break; case SIGEMT: switch (sip->si_code) { #ifdef EMT_TAGOVF case EMT_TAGOVF: code = "EMT_TAGOVF"; break; #endif case EMT_CPCOVF: code = "EMT_CPCOVF"; break; } break; case SIGBUS: switch (sip->si_code) { case BUS_ADRALN: code = "BUS_ADRALN"; break; case BUS_ADRERR: code = "BUS_ADRERR"; break; case BUS_OBJERR: code = "BUS_OBJERR"; break; } break; case SIGCLD: switch (sip->si_code) { case CLD_EXITED: code = "CLD_EXITED"; break; case CLD_KILLED: code = "CLD_KILLED"; break; case CLD_DUMPED: code = "CLD_DUMPED"; break; case CLD_TRAPPED: code = "CLD_TRAPPED"; break; case CLD_STOPPED: code = "CLD_STOPPED"; break; case CLD_CONTINUED: code = "CLD_CONTINUED"; break; } break; case SIGPOLL: switch (sip->si_code) { case POLL_IN: code = "POLL_IN"; break; case POLL_OUT: code = "POLL_OUT"; break; case POLL_MSG: code = "POLL_MSG"; break; case POLL_ERR: code = "POLL_ERR"; break; case POLL_PRI: code = "POLL_PRI"; break; case POLL_HUP: code = "POLL_HUP"; break; } break; } if (code == NULL) { (void) sprintf(pri->code_buf, "code=%d", sip->si_code); code = (const char *)pri->code_buf; } switch (sip->si_signo) { case SIGILL: case SIGTRAP: case SIGFPE: case SIGSEGV: case SIGBUS: case SIGEMT: (void) printf(" %s addr=0x%.8lX", code, (long)sip->si_addr); break; case SIGCLD: (void) printf(" %s pid=%d status=0x%.4X", code, (int)sip->si_pid, sip->si_status); break; case SIGPOLL: case SIGXFSZ: (void) printf(" %s fd=%d band=%ld", code, sip->si_fd, sip->si_band); break; } if (sip->si_errno != 0) { const char *ename = errname(sip->si_errno); (void) printf(" errno=%d", sip->si_errno); if (ename != NULL) (void) printf("(%s)", ename); } (void) fputc('\n', stdout); } #ifdef _LP64 void show_siginfo32(private_t *pri, long offset) { struct siginfo32 siginfo; if (offset != NULL && Pread(Proc, &siginfo, sizeof (siginfo), offset) == sizeof (siginfo)) print_siginfo32(pri, &siginfo); } #endif /* _LP64 */ void show_siginfo(private_t *pri, long offset) { struct siginfo siginfo; #ifdef _LP64 if (data_model != PR_MODEL_LP64) { show_siginfo32(pri, offset); return; } #endif if (offset != NULL && Pread(Proc, &siginfo, sizeof (siginfo), offset) == sizeof (siginfo)) print_siginfo(pri, &siginfo); } void show_bool(private_t *pri, long offset, int count) { int serial = (count > MYBUFSIZ / 4); /* enter region of lengthy output */ if (serial) Eserialize(); while (count > 0) { char buf[32]; int nb = (count < 32)? count : 32; int i; if (Pread(Proc, buf, (size_t)nb, offset) != nb) break; (void) printf("%s ", pri->pname); for (i = 0; i < nb; i++) (void) printf(" %d", buf[i]); (void) fputc('\n', stdout); count -= nb; offset += nb; } /* exit region of lengthy output */ if (serial) Xserialize(); } #ifdef _LP64 void show_iovec32(private_t *pri, long offset, int niov, int showbuf, long count) { iovec32_t iovec[16]; iovec32_t *ip; long nb; int serial = (count > MYBUFSIZ / 4 && showbuf); if (niov > 16) /* is this the real limit? */ niov = 16; if (offset != NULL && niov > 0 && Pread(Proc, &iovec[0], niov*sizeof (iovec32_t), offset) == niov*sizeof (iovec32_t)) { /* enter region of lengthy output */ if (serial) Eserialize(); for (ip = &iovec[0]; niov-- && !interrupt; ip++) { (void) printf("%s\tiov_base = 0x%.8X iov_len = %d\n", pri->pname, ip->iov_base, ip->iov_len); if ((nb = count) > 0) { if (nb > ip->iov_len) nb = ip->iov_len; if (nb > 0) count -= nb; } if (showbuf && nb > 0) showbuffer(pri, (long)ip->iov_base, nb); } /* exit region of lengthy output */ if (serial) Xserialize(); } } #endif /* _LP64 */ void show_iovec(private_t *pri, long offset, long niov, int showbuf, long count) { iovec_t iovec[16]; iovec_t *ip; long nb; int serial = (count > MYBUFSIZ / 4 && showbuf); #ifdef _LP64 if (data_model != PR_MODEL_LP64) { show_iovec32(pri, offset, niov, showbuf, count); return; } #endif if (niov > 16) /* is this the real limit? */ niov = 16; if (offset != NULL && niov > 0 && Pread(Proc, &iovec[0], niov*sizeof (iovec_t), offset) == niov*sizeof (iovec_t)) { /* enter region of lengthy output */ if (serial) Eserialize(); for (ip = &iovec[0]; niov-- && !interrupt; ip++) { (void) printf("%s\tiov_base = 0x%.8lX iov_len = %lu\n", pri->pname, (long)ip->iov_base, ip->iov_len); if ((nb = count) > 0) { if (nb > ip->iov_len) nb = ip->iov_len; if (nb > 0) count -= nb; } if (showbuf && nb > 0) showbuffer(pri, (long)ip->iov_base, nb); } /* exit region of lengthy output */ if (serial) Xserialize(); } } void show_dents32(private_t *pri, long offset, long count) { long buf[MYBUFSIZ / sizeof (long)]; struct dirent32 *dp; int serial = (count > 100); if (offset == NULL) return; /* enter region of lengthy output */ if (serial) Eserialize(); while (count > 0 && !interrupt) { int nb = count < MYBUFSIZ? (int)count : MYBUFSIZ; if ((nb = Pread(Proc, &buf[0], (size_t)nb, offset)) <= 0) break; dp = (struct dirent32 *)&buf[0]; if (nb < (int)(dp->d_name - (char *)dp)) break; if ((unsigned)nb < dp->d_reclen) { /* getdents() error? */ (void) printf( "%s ino=%-5u off=%-4d rlen=%-3d\n", pri->pname, dp->d_ino, dp->d_off, dp->d_reclen); break; } while (!interrupt && nb >= (int)(dp->d_name - (char *)dp) && (unsigned)nb >= dp->d_reclen) { (void) printf( "%s ino=%-5u off=%-4d rlen=%-3d \"%.*s\"\n", pri->pname, dp->d_ino, dp->d_off, dp->d_reclen, dp->d_reclen - (int)(dp->d_name - (char *)dp), dp->d_name); nb -= dp->d_reclen; count -= dp->d_reclen; offset += dp->d_reclen; /* LINTED improper alignment */ dp = (struct dirent32 *)((char *)dp + dp->d_reclen); } } /* exit region of lengthy output */ if (serial) Xserialize(); } void show_dents64(private_t *pri, long offset, long count) { long long buf[MYBUFSIZ / sizeof (long long)]; struct dirent64 *dp; int serial = (count > 100); if (offset == NULL) return; /* enter region of lengthy output */ if (serial) Eserialize(); while (count > 0 && !interrupt) { int nb = count < MYBUFSIZ? (int)count : MYBUFSIZ; if ((nb = Pread(Proc, &buf[0], (size_t)nb, offset)) <= 0) break; dp = (struct dirent64 *)&buf[0]; if (nb < (int)(dp->d_name - (char *)dp)) break; if ((unsigned)nb < dp->d_reclen) { /* getdents() error? */ (void) printf( "%s ino=%-5llu off=%-4lld rlen=%-3d\n", pri->pname, (long long)dp->d_ino, (long long)dp->d_off, dp->d_reclen); break; } while (!interrupt && nb >= (int)(dp->d_name - (char *)dp) && (unsigned)nb >= dp->d_reclen) { (void) printf( "%s ino=%-5llu off=%-4lld rlen=%-3d \"%.*s\"\n", pri->pname, (long long)dp->d_ino, (long long)dp->d_off, dp->d_reclen, dp->d_reclen - (int)(dp->d_name - (char *)dp), dp->d_name); nb -= dp->d_reclen; count -= dp->d_reclen; offset += dp->d_reclen; /* LINTED improper alignment */ dp = (struct dirent64 *)((char *)dp + dp->d_reclen); } } /* exit region of lengthy output */ if (serial) Xserialize(); } void show_rlimit32(private_t *pri, long offset) { struct rlimit32 rlimit; if (offset != NULL && Pread(Proc, &rlimit, sizeof (rlimit), offset) == sizeof (rlimit)) { (void) printf("%s\t", pri->pname); switch (rlimit.rlim_cur) { case RLIM32_INFINITY: (void) fputs("cur = RLIM_INFINITY", stdout); break; case RLIM32_SAVED_MAX: (void) fputs("cur = RLIM_SAVED_MAX", stdout); break; case RLIM32_SAVED_CUR: (void) fputs("cur = RLIM_SAVED_CUR", stdout); break; default: (void) printf("cur = %lu", (long)rlimit.rlim_cur); break; } switch (rlimit.rlim_max) { case RLIM32_INFINITY: (void) fputs(" max = RLIM_INFINITY\n", stdout); break; case RLIM32_SAVED_MAX: (void) fputs(" max = RLIM_SAVED_MAX\n", stdout); break; case RLIM32_SAVED_CUR: (void) fputs(" max = RLIM_SAVED_CUR\n", stdout); break; default: (void) printf(" max = %lu\n", (long)rlimit.rlim_max); break; } } } void show_rlimit64(private_t *pri, long offset) { struct rlimit64 rlimit; if (offset != NULL && Pread(Proc, &rlimit, sizeof (rlimit), offset) == sizeof (rlimit)) { (void) printf("%s\t", pri->pname); switch (rlimit.rlim_cur) { case RLIM64_INFINITY: (void) fputs("cur = RLIM64_INFINITY", stdout); break; case RLIM64_SAVED_MAX: (void) fputs("cur = RLIM64_SAVED_MAX", stdout); break; case RLIM64_SAVED_CUR: (void) fputs("cur = RLIM64_SAVED_CUR", stdout); break; default: (void) printf("cur = %llu", (unsigned long long)rlimit.rlim_cur); break; } switch (rlimit.rlim_max) { case RLIM64_INFINITY: (void) fputs(" max = RLIM64_INFINITY\n", stdout); break; case RLIM64_SAVED_MAX: (void) fputs(" max = RLIM64_SAVED_MAX\n", stdout); break; case RLIM64_SAVED_CUR: (void) fputs(" max = RLIM64_SAVED_CUR\n", stdout); break; default: (void) printf(" max = %llu\n", (unsigned long long)rlimit.rlim_max); break; } } } void show_nuname(private_t *pri, long offset) { struct utsname ubuf; if (offset != NULL && Pread(Proc, &ubuf, sizeof (ubuf), offset) == sizeof (ubuf)) { (void) printf( "%s\tsys=%s nod=%s rel=%s ver=%s mch=%s\n", pri->pname, ubuf.sysname, ubuf.nodename, ubuf.release, ubuf.version, ubuf.machine); } } void show_adjtime(private_t *pri, long off1, long off2) { show_timeval(pri, off1, " delta"); show_timeval(pri, off2, "olddelta"); } void show_sockaddr(private_t *pri, const char *str, long addroff, long lenoff, long len) { /* * A buffer large enough for PATH_MAX size AF_UNIX address, which is * also large enough to store a sockaddr_in or a sockaddr_in6. */ long buf[(sizeof (short) + PATH_MAX + sizeof (long) - 1) / sizeof (long)]; struct sockaddr *sa = (struct sockaddr *)buf; struct sockaddr_in *sin = (struct sockaddr_in *)buf; struct sockaddr_un *soun = (struct sockaddr_un *)buf; struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)buf; char addrbuf[INET6_ADDRSTRLEN]; if (lenoff != 0) { uint_t ilen; if (Pread(Proc, &ilen, sizeof (ilen), lenoff) != sizeof (ilen)) return; len = ilen; } if (len >= sizeof (buf)) /* protect against ridiculous length */ len = sizeof (buf) - 1; if (Pread(Proc, buf, len, addroff) != len) return; switch (sa->sa_family) { case AF_INET6: (void) printf("%s\tAF_INET6 %s = %s port = %u\n", pri->pname, str, inet_ntop(AF_INET6, &sin6->sin6_addr, addrbuf, sizeof (addrbuf)), ntohs(sin6->sin6_port)); (void) printf("%s\tscope id = %u source id = 0x%x\n" "%s\tflow class = 0x%02x flow label = 0x%05x\n", pri->pname, ntohl(sin6->sin6_scope_id), ntohl(sin6->__sin6_src_id), pri->pname, ntohl((sin6->sin6_flowinfo & IPV6_FLOWINFO_TCLASS) >> 20), ntohl(sin6->sin6_flowinfo & IPV6_FLOWINFO_FLOWLABEL)); break; case AF_INET: (void) printf("%s\tAF_%s %s = %s port = %u\n", pri->pname, "INET", str, inet_ntop(AF_INET, &sin->sin_addr, addrbuf, sizeof (addrbuf)), ntohs(sin->sin_port)); break; case AF_UNIX: len -= sizeof (soun->sun_family); if (len >= 0) { /* Null terminate */ soun->sun_path[len] = NULL; (void) printf("%s\tAF_UNIX %s = %s\n", pri->pname, str, soun->sun_path); } break; } } void show_msghdr(private_t *pri, long offset) { const lwpstatus_t *Lsp = pri->lwpstat; int what = Lsp->pr_what; int err = pri->Errno; struct msghdr msg; int showbuf = FALSE; int i = pri->sys_args[0]+1; long nb = (what == SYS_recvmsg)? pri->Rval1 : 32*1024; if (Pread(Proc, &msg, sizeof (msg), offset) != sizeof (msg)) return; if (msg.msg_name != NULL && msg.msg_namelen != 0) show_sockaddr(pri, "msg_name", (long)msg.msg_name, 0, (long)msg.msg_namelen); /* * Print the iovec if the syscall was successful and the fd is * part of the set being traced. */ if ((what == SYS_recvmsg && !err && prismember(&readfd, i)) || (what == SYS_sendmsg && prismember(&writefd, i))) showbuf = TRUE; show_iovec(pri, (long)msg.msg_iov, msg.msg_iovlen, showbuf, nb); } #ifdef _LP64 void show_msghdr32(private_t *pri, long offset) { struct msghdr32 { caddr32_t msg_name; uint32_t msg_namelen; caddr32_t msg_iov; int32_t msg_iovlen; } msg; const lwpstatus_t *Lsp = pri->lwpstat; int what = Lsp->pr_what; int err = pri->Errno; int showbuf = FALSE; int i = pri->sys_args[0]+1; long nb = (what == SYS_recvmsg)? pri->Rval1 : 32*1024; if (Pread(Proc, &msg, sizeof (msg), offset) != sizeof (msg)) return; if (msg.msg_name != NULL && msg.msg_namelen != 0) show_sockaddr(pri, "msg_name", (long)msg.msg_name, 0, (long)msg.msg_namelen); /* * Print the iovec if the syscall was successful and the fd is * part of the set being traced. */ if ((what == SYS_recvmsg && !err && prismember(&readfd, i)) || (what == SYS_sendmsg && prismember(&writefd, i))) showbuf = TRUE; show_iovec32(pri, (long)msg.msg_iov, msg.msg_iovlen, showbuf, nb); } #endif /* _LP64 */ static void show_doorargs(private_t *pri, long offset) { door_arg_t args; if (Pread(Proc, &args, sizeof (args), offset) == sizeof (args)) { (void) printf("%s\tdata_ptr=0x%lX data_size=%lu\n", pri->pname, (ulong_t)args.data_ptr, (ulong_t)args.data_size); (void) printf("%s\tdesc_ptr=0x%lX desc_num=%u\n", pri->pname, (ulong_t)args.desc_ptr, args.desc_num); (void) printf("%s\trbuf=0x%lX rsize=%lu\n", pri->pname, (ulong_t)args.rbuf, (ulong_t)args.rsize); } } static void show_ucred_privsets(private_t *pri, ucred_t *uc) { int i = 0; const priv_set_t *s; priv_ptype_t sn; char *str; while ((sn = priv_getsetbynum(i++)) != NULL) { s = ucred_getprivset(uc, sn); if (s == NULL) continue; (void) printf("%s\t%c: %s\n", pri->pname, *sn, str = priv_set_to_str(s, ',', PRIV_STR_SHORT)); free(str); } } static void show_ucred(private_t *pri, long offset) { ucred_t *uc = _ucred_alloc(); size_t sz; if (uc == NULL) return; sz = Pread(Proc, uc, uc->uc_size, offset); /* * A new uc_size is read, it could be smaller than the previously * value. We accept short reads that fill the whole header. */ if (sz >= sizeof (ucred_t) && sz >= uc->uc_size) { (void) printf("%s\teuid=%u egid=%u\n", pri->pname, ucred_geteuid(uc), ucred_getegid(uc)); (void) printf("%s\truid=%u rgid=%u\n", pri->pname, ucred_getruid(uc), ucred_getrgid(uc)); (void) printf("%s\tpid=%d zoneid=%d\n", pri->pname, (int)ucred_getpid(uc), (int)ucred_getzoneid(uc)); show_ucred_privsets(pri, uc); } ucred_free(uc); } static void show_privset(private_t *pri, long offset, size_t size, char *label) { priv_set_t *tmp = priv_allocset(); size_t sz; if (tmp == NULL) return; sz = Pread(Proc, tmp, size, offset); if (sz == size) { char *str = priv_set_to_str(tmp, ',', PRIV_STR_SHORT); if (str != NULL) { (void) printf("%s\t%s%s\n", pri->pname, label, str); free(str); } } priv_freeset(tmp); } static void show_doorinfo(private_t *pri, long offset) { door_info_t info; door_attr_t attr; if (Pread(Proc, &info, sizeof (info), offset) != sizeof (info)) return; (void) printf("%s\ttarget=%d proc=0x%llX data=0x%llX\n", pri->pname, (int)info.di_target, info.di_proc, info.di_data); attr = info.di_attributes; (void) printf("%s\tattributes=%s\n", pri->pname, door_flags(pri, attr)); (void) printf("%s\tuniquifier=%llu\n", pri->pname, info.di_uniquifier); } static void show_doorparam(private_t *pri, long offset) { ulong_t val; if (Pread(Proc, &val, sizeof (val), offset) == sizeof (val)) { (void) printf("%s\tvalue=%lu\n", pri->pname, val); } } #ifdef _LP64 static void show_doorargs32(private_t *pri, long offset) { struct door_arg32 args; if (Pread(Proc, &args, sizeof (args), offset) == sizeof (args)) { (void) printf("%s\tdata_ptr=%X data_size=%u\n", pri->pname, args.data_ptr, args.data_size); (void) printf("%s\tdesc_ptr=0x%X desc_num=%u\n", pri->pname, args.desc_ptr, args.desc_num); (void) printf("%s\trbuf=0x%X rsize=%u\n", pri->pname, args.rbuf, args.rsize); } } static void show_doorparam32(private_t *pri, long offset) { uint_t val; if (Pread(Proc, &val, sizeof (val), offset) == sizeof (val)) { (void) printf("%s\tvalue=%u\n", pri->pname, val); } } #endif /* _LP64 */ static void show_doors(private_t *pri) { switch (pri->sys_args[5]) { case DOOR_CALL: #ifdef _LP64 if (data_model == PR_MODEL_LP64) show_doorargs(pri, (long)pri->sys_args[1]); else show_doorargs32(pri, (long)pri->sys_args[1]); #else show_doorargs(pri, (long)pri->sys_args[1]); #endif break; case DOOR_UCRED: if (!pri->Errno) show_ucred(pri, (long)pri->sys_args[0]); break; case DOOR_INFO: if (!pri->Errno) show_doorinfo(pri, (long)pri->sys_args[1]); break; case DOOR_GETPARAM: if (!pri->Errno) { #ifdef _LP64 if (data_model == PR_MODEL_LP64) show_doorparam(pri, (long)pri->sys_args[2]); else show_doorparam32(pri, (long)pri->sys_args[2]); #else show_doorparam(pri, (long)pri->sys_args[2]); #endif } break; } } static void show_portargs(private_t *pri, long offset) { port_event_t args; if (Pread(Proc, &args, sizeof (args), offset) == sizeof (args)) { (void) printf("%s\tevents=0x%x source=%u\n", pri->pname, args.portev_events, args.portev_source); (void) printf("%s\tobject=0x%p user=0x%p\n", pri->pname, (void *)args.portev_object, (void *)args.portev_user); } } #ifdef _LP64 static void show_portargs32(private_t *pri, long offset) { port_event32_t args; if (Pread(Proc, &args, sizeof (args), offset) == sizeof (args)) { (void) printf("%s\tevents=0x%x source=%u\n", pri->pname, args.portev_events, args.portev_source); (void) printf("%s\tobject=0x%x user=0x%x\n", pri->pname, args.portev_object, args.portev_user); } } #endif /* _LP64 */ static void show_ports(private_t *pri) { switch (pri->sys_args[0]) { case PORT_GET: #ifdef _LP64 if (data_model == PR_MODEL_LP64) show_portargs(pri, (long)pri->sys_args[2]); else show_portargs32(pri, (long)pri->sys_args[2]); #else show_portargs(pri, (long)pri->sys_args[2]); #endif break; } } #define MAX_SNDFL_PRD 16 #ifdef _LP64 static void show_ksendfilevec32(private_t *pri, int fd, ksendfilevec32_t *sndvec, int sfvcnt) { ksendfilevec32_t *snd_ptr, snd[MAX_SNDFL_PRD]; size_t cpy_rqst; Eserialize(); while (sfvcnt > 0) { cpy_rqst = MIN(sfvcnt, MAX_SNDFL_PRD); sfvcnt -= cpy_rqst; cpy_rqst *= sizeof (snd[0]); if (Pread(Proc, snd, cpy_rqst, (uintptr_t)sndvec) != cpy_rqst) break; snd_ptr = &snd[0]; while (cpy_rqst) { (void) printf( "sfv_fd=%d\tsfv_flag=0x%x\t" "sfv_off=%d\tsfv_len=%u\n", snd_ptr->sfv_fd, snd_ptr->sfv_flag, snd_ptr->sfv_off, snd_ptr->sfv_len); if (snd_ptr->sfv_fd == SFV_FD_SELF && prismember(&writefd, fd)) { showbuffer(pri, (long)snd_ptr->sfv_off & 0xffffffff, (long)snd_ptr->sfv_len); } cpy_rqst -= sizeof (snd[0]); snd_ptr++; } sndvec += MAX_SNDFL_PRD; } Xserialize(); } static void show_ksendfilevec64(private_t *pri, int fd, ksendfilevec64_t *sndvec, int sfvcnt) { ksendfilevec64_t *snd_ptr, snd[MAX_SNDFL_PRD]; size_t cpy_rqst; Eserialize(); while (sfvcnt > 0) { cpy_rqst = MIN(sfvcnt, MAX_SNDFL_PRD); sfvcnt -= cpy_rqst; cpy_rqst *= sizeof (snd[0]); if (Pread(Proc, snd, cpy_rqst, (uintptr_t)sndvec) != cpy_rqst) break; snd_ptr = &snd[0]; while (cpy_rqst) { (void) printf( "sfv_fd=%d\tsfv_flag=0x%x\t" "sfv_off=%ld\tsfv_len=%u\n", snd_ptr->sfv_fd, snd_ptr->sfv_flag, snd_ptr->sfv_off, snd_ptr->sfv_len); if (snd_ptr->sfv_fd == SFV_FD_SELF && prismember(&writefd, fd)) { showbuffer(pri, (long)snd_ptr->sfv_off & 0xffffffff, (long)snd_ptr->sfv_len); } cpy_rqst -= sizeof (snd[0]); snd_ptr++; } sndvec += MAX_SNDFL_PRD; } Xserialize(); } #endif /* _LP64 */ /*ARGSUSED*/ static void show_sendfilevec(private_t *pri, int fd, sendfilevec_t *sndvec, int sfvcnt) { sendfilevec_t *snd_ptr, snd[MAX_SNDFL_PRD]; size_t cpy_rqst; #ifdef _LP64 if (data_model != PR_MODEL_LP64) { show_ksendfilevec32(pri, fd, (ksendfilevec32_t *)sndvec, sfvcnt); return; } #endif Eserialize(); while (sfvcnt > 0) { cpy_rqst = MIN(sfvcnt, MAX_SNDFL_PRD); sfvcnt -= cpy_rqst; cpy_rqst *= sizeof (snd[0]); if (Pread(Proc, snd, cpy_rqst, (uintptr_t)sndvec) != cpy_rqst) break; snd_ptr = &snd[0]; while (cpy_rqst) { (void) printf( "sfv_fd=%d\tsfv_flag=0x%x\t" "sfv_off=%ld\tsfv_len=%lu\n", snd_ptr->sfv_fd, snd_ptr->sfv_flag, snd_ptr->sfv_off, (ulong_t)snd_ptr->sfv_len); if (snd_ptr->sfv_fd == SFV_FD_SELF && prismember(&writefd, fd)) { showbuffer(pri, (long)snd_ptr->sfv_off, (long)snd_ptr->sfv_len); } cpy_rqst -= sizeof (snd[0]); snd_ptr++; } sndvec += MAX_SNDFL_PRD; } Xserialize(); } /*ARGSUSED*/ static void show_sendfilevec64(private_t *pri, int fd, sendfilevec64_t *sndvec, int sfvcnt) { sendfilevec64_t *snd_ptr, snd[MAX_SNDFL_PRD]; size_t cpy_rqst; #ifdef _LP64 if (data_model != PR_MODEL_LP64) { show_ksendfilevec64(pri, fd, (ksendfilevec64_t *)sndvec, sfvcnt); return; } #endif Eserialize(); while (sfvcnt > 0) { cpy_rqst = MIN(sfvcnt, MAX_SNDFL_PRD); sfvcnt -= cpy_rqst; cpy_rqst *= sizeof (snd[0]); if (Pread(Proc, snd, cpy_rqst, (uintptr_t)sndvec) != cpy_rqst) break; snd_ptr = &snd[0]; while (cpy_rqst) { (void) printf( #ifdef _LP64 "sfv_fd=%d\tsfv_flag=0x%x\t" "sfv_off=%ld\tsfv_len=%lu\n", #else "sfv_fd=%d\tsfv_flag=0x%x\t" "sfv_off=%lld\tsfv_len=%lu\n", #endif snd_ptr->sfv_fd, snd_ptr->sfv_flag, snd_ptr->sfv_off, (ulong_t)snd_ptr->sfv_len); if (snd_ptr->sfv_fd == SFV_FD_SELF && prismember(&writefd, fd)) { showbuffer(pri, (long)snd_ptr->sfv_off, (long)snd_ptr->sfv_len); } cpy_rqst -= sizeof (snd[0]); snd_ptr++; } sndvec += MAX_SNDFL_PRD; } Xserialize(); } static void show_memcntl_mha(private_t *pri, long offset) { struct memcntl_mha mha; const char *s = NULL; if (Pread(Proc, &mha, sizeof (mha), offset) == sizeof (mha)) { switch (mha.mha_cmd) { case MHA_MAPSIZE_VA: s = "MHA_MAPSIZE_VA"; break; case MHA_MAPSIZE_BSSBRK: s = "MHA_MAPSIZE_BSSBRK"; break; case MHA_MAPSIZE_STACK: s = "MHA_MAPSIZE_STACK"; break; } if (s) (void) printf("%s\tmha_cmd=%s mha_flags=0x%x" " mha_pagesize=%lu\n", pri->pname, s, mha.mha_flags, (ulong_t)mha.mha_pagesize); else (void) printf("%s\tmha_cmd=0x%.8x mha_flags=0x%x" " mha_pagesize=%lu\n", pri->pname, mha.mha_cmd, mha.mha_flags, (ulong_t)mha.mha_pagesize); } } #ifdef _LP64 static void show_memcntl_mha32(private_t *pri, long offset) { struct memcntl_mha32 mha32; const char *s = NULL; if (Pread(Proc, &mha32, sizeof (mha32), offset) == sizeof (mha32)) { switch (mha32.mha_cmd) { case MHA_MAPSIZE_VA: s = "MHA_MAPSIZE_VA"; break; case MHA_MAPSIZE_BSSBRK: s = "MHA_MAPSIZE_BSSBRK"; break; case MHA_MAPSIZE_STACK: s = "MHA_MAPSIZE_STACK"; break; } if (s) (void) printf("%s\tmha_cmd=%s mha_flags=0x%x" " mha_pagesize=%u\n", pri->pname, s, mha32.mha_flags, mha32.mha_pagesize); else (void) printf("%s\tmha_cmd=0x%.8x mha_flags=0x%x" " mha_pagesize=%u\n", pri->pname, mha32.mha_cmd, mha32.mha_flags, mha32.mha_pagesize); } } #endif /* _LP64 */ static void show_memcntl(private_t *pri) { if ((int)pri->sys_args[2] != MC_HAT_ADVISE) return; #ifdef _LP64 if (data_model == PR_MODEL_LP64) show_memcntl_mha(pri, (long)pri->sys_args[3]); else show_memcntl_mha32(pri, (long)pri->sys_args[3]); #else show_memcntl_mha(pri, (long)pri->sys_args[3]); #endif } void show_ids(private_t *pri, long offset, int count) { id_t buf[MYBUFSIZ / sizeof (id_t)]; id_t *idp; int serial = (count > MYBUFSIZ / 48); if (offset == NULL) return; /* enter region of lengthy output */ if (serial) Eserialize(); while (count > 0 && !interrupt) { ssize_t nb = (count * sizeof (id_t) < MYBUFSIZ)? count * sizeof (id_t) : MYBUFSIZ; if ((nb = Pread(Proc, &buf[0], (size_t)nb, offset)) < 0 || nb < sizeof (id_t)) break; idp = buf; while (!interrupt && nb >= sizeof (id_t)) { (void) printf("%s\t%8d\n", pri->pname, (int)*idp); offset += sizeof (id_t); nb -= sizeof (id_t); idp++; count--; } } /* exit region of lengthy output */ if (serial) Xserialize(); } void show_ntp_gettime(private_t *pri) { struct ntptimeval ntv; long offset; if (pri->sys_nargs < 1 || (offset = pri->sys_args[0]) == NULL) return; if (data_model == PR_MODEL_NATIVE) { if (Pread(Proc, &ntv, sizeof (ntv), offset) != sizeof (ntv)) return; } else { struct ntptimeval32 ntv32; if (Pread(Proc, &ntv32, sizeof (ntv32), offset) != sizeof (ntv32)) return; TIMEVAL32_TO_TIMEVAL(&ntv.time, &ntv32.time); ntv.maxerror = ntv32.maxerror; ntv.esterror = ntv32.esterror; } (void) printf("\ttime: %ld.%6.6ld sec\n", ntv.time.tv_sec, ntv.time.tv_usec); (void) printf("\tmaxerror: %11d usec\n", ntv.maxerror); (void) printf("\testerror: %11d usec\n", ntv.esterror); } static char * get_timex_modes(private_t *pri, uint32_t val) { char *str = pri->code_buf; size_t used = 0; *str = '\0'; if (val & MOD_OFFSET) used = strlcat(str, "|MOD_OFFSET", sizeof (pri->code_buf)); if (val & MOD_FREQUENCY) used = strlcat(str, "|MOD_FREQUENCY", sizeof (pri->code_buf)); if (val & MOD_MAXERROR) used = strlcat(str, "|MOD_MAXERROR", sizeof (pri->code_buf)); if (val & MOD_ESTERROR) used = strlcat(str, "|MOD_ESTERROR", sizeof (pri->code_buf)); if (val & MOD_STATUS) used = strlcat(str, "|MOD_STATUS", sizeof (pri->code_buf)); if (val & MOD_TIMECONST) used = strlcat(str, "|MOD_TIMECONST", sizeof (pri->code_buf)); if (val & MOD_CLKB) used = strlcat(str, "|MOD_CLKB", sizeof (pri->code_buf)); if (val & MOD_CLKA) used = strlcat(str, "|MOD_CLKA", sizeof (pri->code_buf)); if (used == 0 || used >= sizeof (pri->code_buf)) (void) snprintf(str, sizeof (pri->code_buf), " 0x%.4x", val); return (str + 1); } static char * get_timex_status(private_t *pri, int32_t val) { char *str = pri->code_buf; size_t used = 0; *str = '\0'; if (val & STA_PLL) used = strlcat(str, "|STA_PLL", sizeof (pri->code_buf)); if (val & STA_PPSFREQ) used = strlcat(str, "|STA_PPSFREQ", sizeof (pri->code_buf)); if (val & STA_PPSTIME) used = strlcat(str, "|STA_PPSTIME", sizeof (pri->code_buf)); if (val & STA_FLL) used = strlcat(str, "|STA_FLL", sizeof (pri->code_buf)); if (val & STA_INS) used = strlcat(str, "|STA_INS", sizeof (pri->code_buf)); if (val & STA_DEL) used = strlcat(str, "|STA_DEL", sizeof (pri->code_buf)); if (val & STA_UNSYNC) used = strlcat(str, "|STA_UNSYNC", sizeof (pri->code_buf)); if (val & STA_FREQHOLD) used = strlcat(str, "|STA_FREQHOLD", sizeof (pri->code_buf)); if (val & STA_PPSSIGNAL) used = strlcat(str, "|STA_PPSSIGNAL", sizeof (pri->code_buf)); if (val & STA_PPSJITTER) used = strlcat(str, "|STA_PPSJITTER", sizeof (pri->code_buf)); if (val & STA_PPSWANDER) used = strlcat(str, "|STA_PPSWANDER", sizeof (pri->code_buf)); if (val & STA_PPSERROR) used = strlcat(str, "|STA_PPSERROR", sizeof (pri->code_buf)); if (val & STA_CLOCKERR) used = strlcat(str, "|STA_CLOCKERR", sizeof (pri->code_buf)); if (used == 0 || used >= sizeof (pri->code_buf)) (void) snprintf(str, sizeof (pri->code_buf), " 0x%.4x", val); return (str + 1); } void show_ntp_adjtime(private_t *pri) { struct timex timex; long offset; if (pri->sys_nargs < 1 || (offset = pri->sys_args[0]) == NULL) return; if (Pread(Proc, &timex, sizeof (timex), offset) != sizeof (timex)) return; (void) printf("\tmodes: %s\n", get_timex_modes(pri, timex.modes)); (void) printf("\toffset: %11d usec\n", timex.offset); (void) printf("\tfreq: %11d scaled ppm\n", timex.freq); (void) printf("\tmaxerror: %11d usec\n", timex.maxerror); (void) printf("\testerror: %11d usec\n", timex.esterror); (void) printf("\tstatus: %s\n", get_timex_status(pri, timex.status)); (void) printf("\tconstant: %11d\n", timex.constant); (void) printf("\tprecision: %11d usec\n", timex.precision); (void) printf("\ttolerance: %11d scaled ppm\n", timex.tolerance); (void) printf("\tppsfreq: %11d scaled ppm\n", timex.ppsfreq); (void) printf("\tjitter: %11d usec\n", timex.jitter); (void) printf("\tshift: %11d sec\n", timex.shift); (void) printf("\tstabil: %11d scaled ppm\n", timex.stabil); (void) printf("\tjitcnt: %11d\n", timex.jitcnt); (void) printf("\tcalcnt: %11d\n", timex.calcnt); (void) printf("\terrcnt: %11d\n", timex.errcnt); (void) printf("\tstbcnt: %11d\n", timex.stbcnt); } void show_getrusage(long offset) { struct rusage r; if (Pread(Proc, &r, sizeof (r), offset) != sizeof (r)) return; (void) printf("\t user time: %ld.%6.6ld sec\n", r.ru_utime.tv_sec, r.ru_utime.tv_usec); (void) printf("\t system time: %ld.%6.6ld sec\n", r.ru_stime.tv_sec, r.ru_stime.tv_usec); (void) printf("\t max rss: %ld\n", r.ru_maxrss); (void) printf("\t shared data: %ld\n", r.ru_ixrss); (void) printf("\t unshared data: %ld\n", r.ru_idrss); (void) printf("\t unshared stack: %ld\n", r.ru_isrss); (void) printf("\t minor faults: %ld\n", r.ru_minflt); (void) printf("\t major faults: %ld\n", r.ru_majflt); (void) printf("\t # of swaps: %ld\n", r.ru_nswap); (void) printf("\t blocked inputs: %ld\n", r.ru_inblock); (void) printf("\t blocked outputs: %ld\n", r.ru_oublock); (void) printf("\t msgs sent: %ld\n", r.ru_msgsnd); (void) printf("\t msgs rcv'd: %ld\n", r.ru_msgrcv); (void) printf("\t signals rcv'd: %ld\n", r.ru_nsignals); (void) printf("\tvol cntxt swtchs: %ld\n", r.ru_nvcsw); (void) printf("\tinv cntxt swtchs: %ld\n", r.ru_nivcsw); } #ifdef _LP64 void show_getrusage32(long offset) { struct rusage32 r; if (Pread(Proc, &r, sizeof (r), offset) != sizeof (r)) return; (void) printf("\t user time: %d.%6.6d sec\n", r.ru_utime.tv_sec, r.ru_utime.tv_usec); (void) printf("\t system time: %d.%6.6d sec\n", r.ru_stime.tv_sec, r.ru_stime.tv_usec); (void) printf("\t max rss: %d\n", r.ru_maxrss); (void) printf("\t shared data: %d\n", r.ru_ixrss); (void) printf("\t unshared data: %d\n", r.ru_idrss); (void) printf("\t unshared stack: %d\n", r.ru_isrss); (void) printf("\t minor faults: %d\n", r.ru_minflt); (void) printf("\t major faults: %d\n", r.ru_majflt); (void) printf("\t # of swaps: %d\n", r.ru_nswap); (void) printf("\t blocked inputs: %d\n", r.ru_inblock); (void) printf("\t blocked outputs: %d\n", r.ru_oublock); (void) printf("\t msgs sent: %d\n", r.ru_msgsnd); (void) printf("\t msgs rcv'd: %d\n", r.ru_msgrcv); (void) printf("\t signals rcv'd: %d\n", r.ru_nsignals); (void) printf("\tvol cntxt swtchs: %d\n", r.ru_nvcsw); (void) printf("\tinv cntxt swtchs: %d\n", r.ru_nivcsw); } #endif /* * Utility function to print a packed nvlist by unpacking * and calling the libnvpair pretty printer. Frees all * allocated memory internally. */ static void show_packed_nvlist(private_t *pri, uintptr_t offset, size_t size) { nvlist_t *nvl = NULL; size_t readsize; char *buf; if ((offset == 0) || (size == 0)) { return; } buf = my_malloc(size, "nvlist decode buffer"); readsize = Pread(Proc, buf, size, offset); if (readsize != size) { (void) printf("%s\t", pri->pname); } else { int result; result = nvlist_unpack(buf, size, &nvl, 0); if (result == 0) { nvlist_print(stdout, nvl); nvlist_free(nvl); } else { (void) printf("%s\tunpack of nvlist" " failed: %d\n", pri->pname, result); } } free(buf); } static void show_zone_create_args(private_t *pri, long offset) { zone_def args; char zone_name[ZONENAME_MAX]; char zone_root[MAXPATHLEN]; char *zone_zfs = NULL; if (Pread(Proc, &args, sizeof (args), offset) == sizeof (args)) { if (Pread_string(Proc, zone_name, sizeof (zone_name), (uintptr_t)args.zone_name) == -1) (void) strcpy(zone_name, ""); if (Pread_string(Proc, zone_root, sizeof (zone_root), (uintptr_t)args.zone_root) == -1) (void) strcpy(zone_root, ""); if (args.zfsbufsz > 0) { zone_zfs = malloc(MIN(4, args.zfsbufsz)); if (zone_zfs != NULL) { if (Pread(Proc, zone_zfs, args.zfsbufsz, (uintptr_t)args.zfsbuf) == -1) (void) strcpy(zone_zfs, ""); } } else { zone_zfs = ""; } (void) printf("%s\t zone_name: %s\n", pri->pname, zone_name); (void) printf("%s\t zone_root: %s\n", pri->pname, zone_root); show_privset(pri, (uintptr_t)args.zone_privs, args.zone_privssz, " zone_privs: "); (void) printf("%s\t rctlbuf: 0x%p\n", pri->pname, (void *)args.rctlbuf); (void) printf("%s\t rctlbufsz: %lu\n", pri->pname, (ulong_t)args.rctlbufsz); show_packed_nvlist(pri, (uintptr_t)args.rctlbuf, args.rctlbufsz); (void) printf("%s\t zfs: %s\n", pri->pname, zone_zfs); (void) printf("%s\textended_error: 0x%p\n", pri->pname, (void *)args.extended_error); if (is_system_labeled()) { char *label_str = NULL; bslabel_t zone_label; (void) printf("%s\t match: %d\n", pri->pname, args.match); (void) printf("%s\t doi: %d\n", pri->pname, args.doi); if (Pread_string(Proc, (char *)&zone_label, sizeof (zone_label), (uintptr_t)args.label) != -1) { /* show the label as string */ if (label_to_str(&zone_label, &label_str, M_LABEL, SHORT_NAMES) != 0) { /* have to dump label as raw string */ (void) label_to_str(&zone_label, &label_str, M_INTERNAL, SHORT_NAMES); } } (void) printf("%s\t label: %s\n", pri->pname, label_str != NULL ? label_str : ""); if (label_str) free(label_str); } if (args.zfsbufsz > 0) free(zone_zfs); } } #ifdef _LP64 static void show_zone_create_args32(private_t *pri, long offset) { zone_def32 args; char zone_name[ZONENAME_MAX]; char zone_root[MAXPATHLEN]; char *zone_zfs = NULL; if (Pread(Proc, &args, sizeof (args), offset) == sizeof (args)) { if (Pread_string(Proc, zone_name, sizeof (zone_name), (uintptr_t)args.zone_name) == -1) (void) strcpy(zone_name, ""); if (Pread_string(Proc, zone_root, sizeof (zone_root), (uintptr_t)args.zone_root) == -1) (void) strcpy(zone_root, ""); if (args.zfsbufsz > 0) { zone_zfs = malloc(MIN(4, args.zfsbufsz)); if (zone_zfs != NULL) { if (Pread(Proc, zone_zfs, args.zfsbufsz, (uintptr_t)args.zfsbuf) == -1) (void) strcpy(zone_zfs, ""); } } else { zone_zfs = ""; } (void) printf("%s\t zone_name: %s\n", pri->pname, zone_name); (void) printf("%s\t zone_root: %s\n", pri->pname, zone_root); show_privset(pri, (uintptr_t)args.zone_privs, args.zone_privssz, " zone_privs: "); (void) printf("%s\t rctlbuf: 0x%x\n", pri->pname, (caddr32_t)args.rctlbuf); (void) printf("%s\t rctlbufsz: %lu\n", pri->pname, (ulong_t)args.rctlbufsz); show_packed_nvlist(pri, (uintptr_t)args.rctlbuf, args.rctlbufsz); (void) printf("%s\t zfs: %s\n", pri->pname, zone_zfs); (void) printf("%s\textended_error: 0x%x\n", pri->pname, (caddr32_t)args.extended_error); if (is_system_labeled()) { char *label_str = NULL; bslabel_t zone_label; (void) printf("%s\t match: %d\n", pri->pname, args.match); (void) printf("%s\t doi: %d\n", pri->pname, args.doi); if (Pread_string(Proc, (char *)&zone_label, sizeof (zone_label), (caddr32_t)args.label) != -1) { /* show the label as string */ if (label_to_str(&zone_label, &label_str, M_LABEL, SHORT_NAMES) != 0) { /* have to dump label as raw string */ (void) label_to_str(&zone_label, &label_str, M_INTERNAL, SHORT_NAMES); } } (void) printf("%s\t label: %s\n", pri->pname, label_str != NULL ? label_str : ""); if (label_str) free(label_str); } if (args.zfsbufsz > 0) free(zone_zfs); } } #endif static void show_zones(private_t *pri) { switch (pri->sys_args[0]) { case ZONE_CREATE: #ifdef _LP64 if (data_model == PR_MODEL_LP64) show_zone_create_args(pri, (long)pri->sys_args[1]); else show_zone_create_args32(pri, (long)pri->sys_args[1]); #else show_zone_create_args(pri, (long)pri->sys_args[1]); #endif break; } } static void show_rctlblk(private_t *pri, long _rctlblk) { rctlblk_t *blk; int size = rctlblk_size(); size_t readsize; const char *s; blk = my_malloc(size, "rctlblk decode buffer"); readsize = Pread(Proc, blk, size, _rctlblk); if (readsize != size) { (void) printf("%s\t\t", pri->pname); } else { (void) printf("%s\t\t Privilege: 0x%x\n", pri->pname, rctlblk_get_privilege(blk)); (void) printf("%s\t\t Value: %lld\n", pri->pname, rctlblk_get_value(blk)); (void) printf("%s\t\tEnforced Value: %lld\n", pri->pname, rctlblk_get_enforced_value(blk)); { int sig, act; act = rctlblk_get_local_action(blk, &sig); s = rctl_local_action(pri, act); if (s == NULL) { (void) printf("%s\t\t Local action: 0x%x\n", pri->pname, act); } else { (void) printf("%s\t\t Local action: %s\n", pri->pname, s); } if (act & RCTL_LOCAL_SIGNAL) { (void) printf("%s\t\t " "For signal %s\n", pri->pname, signame(pri, sig)); } } s = rctl_local_flags(pri, rctlblk_get_local_flags(blk)); if (s == NULL) { (void) printf("%s\t\t Local flags: 0x%x\n", pri->pname, rctlblk_get_local_flags(blk)); } else { (void) printf("%s\t\t Local flags: %s\n", pri->pname, s); } #ifdef _LP64 (void) printf("%s\t\t Recipient PID: %d\n", pri->pname, rctlblk_get_recipient_pid(blk)); #else (void) printf("%s\t\t Recipient PID: %ld\n", pri->pname, rctlblk_get_recipient_pid(blk)); #endif (void) printf("%s\t\t Firing Time: %lld\n", pri->pname, rctlblk_get_firing_time(blk)); } free(blk); } static void show_rctls(private_t *pri) { int entry; switch (pri->sys_args[0]) { case 0: /* getrctl */ case 1: /* setrctl */ /* * If these offsets look a little odd, remember that they're * into the _raw_ system call */ (void) printf("%s\tOld rctlblk: 0x%lx\n", pri->pname, pri->sys_args[2]); if (pri->sys_args[2] != NULL) { show_rctlblk(pri, pri->sys_args[2]); } (void) printf("%s\tNew rctlblk: 0x%lx\n", pri->pname, pri->sys_args[3]); if (pri->sys_args[3] != NULL) { show_rctlblk(pri, pri->sys_args[3]); } break; case 4: /* setprojrctl */ for (entry = 0; entry < pri->sys_args[4]; entry++) { (void) printf("%s\tNew rctlblk[%d]: 0x%lx\n", pri->pname, entry, (long)RCTLBLK_INC(pri->sys_args[3], entry)); if (RCTLBLK_INC(pri->sys_args[3], entry) != NULL) { show_rctlblk(pri, (long)RCTLBLK_INC(pri->sys_args[3], entry)); } } } } /* expound verbosely upon syscall arguments */ /*ARGSUSED*/ void expound(private_t *pri, long r0, int raw) { const lwpstatus_t *Lsp = pri->lwpstat; int lp64 = (data_model == PR_MODEL_LP64); int what = Lsp->pr_what; int err = pri->Errno; /* don't display output parameters */ /* for a failed system call */ #ifndef _LP64 /* We are a 32-bit truss; we can't grok a 64-bit process */ if (lp64) return; #endif /* for reporting sleeping system calls */ if (what == 0 && (Lsp->pr_flags & (PR_ASLEEP|PR_VFORKP))) what = Lsp->pr_syscall; switch (what) { case SYS_utime: show_utime(pri); break; case SYS_utimes: show_utimes(pri); break; case SYS_gettimeofday: if (!err) show_timeofday(pri); break; case SYS_getitimer: if (!err && pri->sys_nargs > 1) show_itimerval(pri, (long)pri->sys_args[1], " value"); break; case SYS_setitimer: if (pri->sys_nargs > 1) show_itimerval(pri, (long)pri->sys_args[1], " value"); if (!err && pri->sys_nargs > 2) show_itimerval(pri, (long)pri->sys_args[2], "ovalue"); break; case SYS_stime: show_stime(pri); break; case SYS_times: if (!err) show_times(pri); break; case SYS_utssys: if (err) break; #ifdef _LP64 if (lp64) show_utssys(pri, r0); else show_utssys32(pri, r0); #else show_utssys(pri, r0); #endif break; case SYS_ioctl: if (pri->sys_nargs >= 3) /* each case must decide for itself */ show_ioctl(pri, pri->sys_args[1], (long)pri->sys_args[2]); break; case SYS_stat: case SYS_fstat: case SYS_lstat: if (!err && pri->sys_nargs >= 2) show_stat(pri, (long)pri->sys_args[1]); break; case SYS_stat64: case SYS_fstat64: case SYS_lstat64: if (!err && pri->sys_nargs >= 2) show_stat64_32(pri, (long)pri->sys_args[1]); break; case SYS_fsat: /* * subcodes for fstatat() and fstatat64(). */ if (!err && pri->sys_nargs >= 4) { if (pri->sys_args[0] == 3) show_statat(pri, (long)pri->sys_args[3]); else if (pri->sys_args[0] == 2) show_stat64_32(pri, (long)pri->sys_args[3]); } break; case SYS_xstat: case SYS_fxstat: case SYS_lxstat: if (!err && pri->sys_nargs >= 3) show_xstat(pri, (int)pri->sys_args[0], (long)pri->sys_args[2]); break; case SYS_statvfs: case SYS_fstatvfs: if (err) break; #ifdef _LP64 if (!lp64) { show_statvfs32(pri); break; } #endif show_statvfs(pri); break; case SYS_statvfs64: case SYS_fstatvfs64: if (err) break; show_statvfs64(pri); break; case SYS_statfs: case SYS_fstatfs: if (err) break; #ifdef _LP64 if (lp64) show_statfs(pri); else show_statfs32(pri); #else show_statfs(pri); #endif break; case SYS_fcntl: show_fcntl(pri); break; case SYS_msgsys: show_msgsys(pri, r0); /* each case must decide for itself */ break; case SYS_semsys: show_semsys(pri); /* each case must decide for itself */ break; case SYS_shmsys: show_shmsys(pri); /* each case must decide for itself */ break; case SYS_getdents: if (err || pri->sys_nargs <= 1 || r0 <= 0) break; #ifdef _LP64 if (!lp64) { show_dents32(pri, (long)pri->sys_args[1], r0); break; } /* FALLTHROUGH */ #else show_dents32(pri, (long)pri->sys_args[1], r0); break; #endif case SYS_getdents64: if (err || pri->sys_nargs <= 1 || r0 <= 0) break; show_dents64(pri, (long)pri->sys_args[1], r0); break; case SYS_getmsg: show_gp_msg(pri, what); if (pri->sys_nargs > 3) show_hhex_int(pri, (long)pri->sys_args[3], "flags"); break; case SYS_getpmsg: show_gp_msg(pri, what); if (pri->sys_nargs > 3) show_hhex_int(pri, (long)pri->sys_args[3], "band"); if (pri->sys_nargs > 4) show_hhex_int(pri, (long)pri->sys_args[4], "flags"); break; case SYS_putmsg: case SYS_putpmsg: show_gp_msg(pri, what); break; case SYS_poll: show_poll(pri); break; case SYS_pollsys: show_pollsys(pri); break; case SYS_setgroups: if (pri->sys_nargs > 1 && (r0 = pri->sys_args[0]) > 0) show_groups(pri, (long)pri->sys_args[1], r0); break; case SYS_getgroups: if (!err && pri->sys_nargs > 1 && pri->sys_args[0] > 0) show_groups(pri, (long)pri->sys_args[1], r0); break; case SYS_sigprocmask: if (pri->sys_nargs > 1) show_sigset(pri, (long)pri->sys_args[1], " set"); if (!err && pri->sys_nargs > 2) show_sigset(pri, (long)pri->sys_args[2], "oset"); break; case SYS_sigsuspend: case SYS_sigtimedwait: if (pri->sys_nargs > 0) show_sigset(pri, (long)pri->sys_args[0], "sigmask"); if (!err && pri->sys_nargs > 1) show_siginfo(pri, (long)pri->sys_args[1]); if (pri->sys_nargs > 2) show_timestruc(pri, (long)pri->sys_args[2], "timeout"); break; case SYS_sigaltstack: if (pri->sys_nargs > 0) show_sigaltstack(pri, (long)pri->sys_args[0], "new"); if (!err && pri->sys_nargs > 1) show_sigaltstack(pri, (long)pri->sys_args[1], "old"); break; case SYS_sigaction: if (pri->sys_nargs > 1) show_sigaction(pri, (long)pri->sys_args[1], "new", NULL); if (!err && pri->sys_nargs > 2) show_sigaction(pri, (long)pri->sys_args[2], "old", r0); break; case SYS_sigpending: if (!err && pri->sys_nargs > 1) show_sigset(pri, (long)pri->sys_args[1], "sigmask"); break; case SYS_waitsys: if (!err && pri->sys_nargs > 2) show_siginfo(pri, (long)pri->sys_args[2]); break; case SYS_sigsendsys: if (pri->sys_nargs > 0) show_procset(pri, (long)pri->sys_args[0]); break; case SYS_priocntlsys: if (pri->sys_nargs > 1) show_procset(pri, (long)pri->sys_args[1]); break; case SYS_mincore: if (!err && pri->sys_nargs > 2) show_bool(pri, (long)pri->sys_args[2], (pri->sys_args[1] + pagesize - 1) / pagesize); break; case SYS_readv: case SYS_writev: if (pri->sys_nargs > 2) { int i = pri->sys_args[0]+1; int showbuf = FALSE; long nb = (what == SYS_readv)? r0 : 32*1024; if ((what == SYS_readv && !err && prismember(&readfd, i)) || (what == SYS_writev && prismember(&writefd, i))) showbuf = TRUE; show_iovec(pri, (long)pri->sys_args[1], pri->sys_args[2], showbuf, nb); } break; case SYS_getrlimit: if (err) break; /*FALLTHROUGH*/ case SYS_setrlimit: if (pri->sys_nargs <= 1) break; #ifdef _LP64 if (lp64) show_rlimit64(pri, (long)pri->sys_args[1]); else show_rlimit32(pri, (long)pri->sys_args[1]); #else show_rlimit32(pri, (long)pri->sys_args[1]); #endif break; case SYS_getrlimit64: if (err) break; /*FALLTHROUGH*/ case SYS_setrlimit64: if (pri->sys_nargs <= 1) break; show_rlimit64(pri, (long)pri->sys_args[1]); break; case SYS_uname: if (!err && pri->sys_nargs > 0) show_nuname(pri, (long)pri->sys_args[0]); break; case SYS_adjtime: if (!err && pri->sys_nargs > 1) show_adjtime(pri, (long)pri->sys_args[0], (long)pri->sys_args[1]); break; case SYS_lwp_info: if (!err && pri->sys_nargs > 0) show_timestruc(pri, (long)pri->sys_args[0], "cpu time"); break; case SYS_lwp_wait: if (!err && pri->sys_nargs > 1) show_int(pri, (long)pri->sys_args[1], "lwpid"); break; case SYS_lwp_mutex_wakeup: case SYS_lwp_mutex_lock: case SYS_lwp_mutex_unlock: case SYS_lwp_mutex_trylock: case SYS_lwp_mutex_init: if (pri->sys_nargs > 0) show_mutex(pri, (long)pri->sys_args[0]); break; case SYS_lwp_mutex_timedlock: if (pri->sys_nargs > 0) show_mutex(pri, (long)pri->sys_args[0]); if (pri->sys_nargs > 1) show_timestruc(pri, (long)pri->sys_args[1], "timeout"); break; case SYS_lwp_cond_wait: if (pri->sys_nargs > 0) show_condvar(pri, (long)pri->sys_args[0]); if (pri->sys_nargs > 1) show_mutex(pri, (long)pri->sys_args[1]); if (pri->sys_nargs > 2) show_timestruc(pri, (long)pri->sys_args[2], "timeout"); break; case SYS_lwp_cond_signal: case SYS_lwp_cond_broadcast: if (pri->sys_nargs > 0) show_condvar(pri, (long)pri->sys_args[0]); break; case SYS_lwp_sema_wait: case SYS_lwp_sema_trywait: case SYS_lwp_sema_post: if (pri->sys_nargs > 0) show_sema(pri, (long)pri->sys_args[0]); break; case SYS_lwp_sema_timedwait: if (pri->sys_nargs > 0) show_sema(pri, (long)pri->sys_args[0]); if (pri->sys_nargs > 1) show_timestruc(pri, (long)pri->sys_args[1], "timeout"); break; case SYS_lwp_rwlock_sys: if (pri->sys_nargs > 1) show_rwlock(pri, (long)pri->sys_args[1]); if (pri->sys_nargs > 2 && (pri->sys_args[0] == 0 || pri->sys_args[0] == 1)) show_timestruc(pri, (long)pri->sys_args[2], "timeout"); break; case SYS_lwp_create: /* XXX print some values in ucontext ??? */ if (!err && pri->sys_nargs > 2) show_int(pri, (long)pri->sys_args[2], "lwpid"); break; case SYS_kaio: if (pri->sys_args[0] == AIOWAIT && !err && pri->sys_nargs > 1) show_timeval(pri, (long)pri->sys_args[1], "timeout"); break; case SYS_nanosleep: if (pri->sys_nargs > 0) show_timestruc(pri, (long)pri->sys_args[0], "tmout"); if (pri->sys_nargs > 1 && (err == 0 || err == EINTR)) show_timestruc(pri, (long)pri->sys_args[1], "resid"); break; case SYS_privsys: switch (pri->sys_args[0]) { case PRIVSYS_SETPPRIV: case PRIVSYS_GETPPRIV: if (!err) show_privset(pri, (long)pri->sys_args[3], (size_t)pri->sys_args[4], ""); } break; case SYS_ucredsys: switch (pri->sys_args[0]) { case UCREDSYS_UCREDGET: case UCREDSYS_GETPEERUCRED: if (err == 0) show_ucred(pri, (long)pri->sys_args[2]); break; } break; case SYS_bind: case SYS_connect: if (pri->sys_nargs > 2) show_sockaddr(pri, "name", (long)pri->sys_args[1], 0, (long)pri->sys_args[2]); break; case SYS_sendto: if (pri->sys_nargs > 5) show_sockaddr(pri, "to", (long)pri->sys_args[4], 0, pri->sys_args[5]); break; case SYS_accept: if (!err && pri->sys_nargs > 2) show_sockaddr(pri, "name", (long)pri->sys_args[1], (long)pri->sys_args[2], 0); break; case SYS_getsockname: case SYS_getpeername: if (!err && pri->sys_nargs > 2) show_sockaddr(pri, "name", (long)pri->sys_args[1], (long)pri->sys_args[2], 0); break; case SYS_cladm: if (!err && pri->sys_nargs > 2) show_cladm(pri, pri->sys_args[0], pri->sys_args[1], (long)pri->sys_args[2]); break; case SYS_recvfrom: if (!err && pri->sys_nargs > 5) show_sockaddr(pri, "from", (long)pri->sys_args[4], (long)pri->sys_args[5], 0); break; case SYS_recvmsg: if (err) break; /* FALLTHROUGH */ case SYS_sendmsg: if (pri->sys_nargs <= 2) break; #ifdef _LP64 if (lp64) show_msghdr(pri, pri->sys_args[1]); else show_msghdr32(pri, pri->sys_args[1]); #else show_msghdr(pri, pri->sys_args[1]); #endif break; case SYS_door: show_doors(pri); break; case SYS_sendfilev: if (pri->sys_nargs != 5) break; if (pri->sys_args[0] == SENDFILEV) { show_sendfilevec(pri, (int)pri->sys_args[1], (sendfilevec_t *)pri->sys_args[2], (int)pri->sys_args[3]); } else if (pri->sys_args[0] == SENDFILEV64) { show_sendfilevec64(pri, (int)pri->sys_args[1], (sendfilevec64_t *)pri->sys_args[2], (int)pri->sys_args[3]); } break; case SYS_memcntl: show_memcntl(pri); break; case SYS_lwp_park: /* * subcode 0: lwp_park(timespec_t *, id_t) * subcode 4: lwp_set_park(timespec_t *, id_t) */ if (pri->sys_nargs > 1 && (pri->sys_args[0] == 0 || pri->sys_args[0] == 4)) show_timestruc(pri, (long)pri->sys_args[1], "timeout"); /* subcode 2: lwp_unpark_all(id_t *, int) */ if (pri->sys_nargs > 2 && pri->sys_args[0] == 2) show_ids(pri, (long)pri->sys_args[1], (int)pri->sys_args[2]); break; case SYS_ntp_gettime: if (!err) show_ntp_gettime(pri); break; case SYS_ntp_adjtime: if (!err) show_ntp_adjtime(pri); break; case SYS_rusagesys: if (!err) if (pri->sys_args[0] == _RUSAGESYS_GETRUSAGE) { #ifdef _LP64 if (!lp64) show_getrusage32(pri->sys_args[1]); else #endif show_getrusage(pri->sys_args[1]); } break; case SYS_port: show_ports(pri); break; case SYS_zone: show_zones(pri); break; case SYS_rctlsys: show_rctls(pri); break; } }