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