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 (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*      Copyright (c) 1988 AT&T     */
  27 /*        All Rights Reserved   */
  28 
  29 #include <stdio.h>
  30 #include <stdlib.h>
  31 #include <unistd.h>
  32 #include <ctype.h>
  33 #include <string.h>
  34 #include <memory.h>
  35 #include <errno.h>
  36 #include <limits.h>
  37 #include <sys/types.h>
  38 #include <sys/stack.h>
  39 #include <signal.h>
  40 #include <sys/isa_defs.h>
  41 #include <libproc.h>
  42 #include <priv.h>
  43 #include "ramdata.h"
  44 #include "systable.h"
  45 #include "print.h"
  46 #include "proto.h"
  47 
  48 /*
  49  * Actions to take when process stops.
  50  */
  51 
  52 /*
  53  * Function prototypes for static routines in this module.
  54  */
  55 int     stopsig(private_t *);
  56 void    showpaths(private_t *, const struct systable *);
  57 void    showargs(private_t *, int);
  58 void    dumpargs(private_t *, long, const char *);
  59 
  60 /*
  61  * Report an lwp to be sleeping (if true).
  62  */
  63 void
  64 report_sleeping(private_t *pri, int dotrace)
  65 {
  66         const lwpstatus_t *Lsp = pri->lwpstat;
  67         int sys = Lsp->pr_syscall;
  68 
  69         if (!prismember(&trace, sys) || !dotrace ||
  70             !(Lsp->pr_flags & (PR_ASLEEP|PR_VFORKP))) {
  71                 /* Make sure we catch sysexit even if we're not tracing it. */
  72                 (void) Psysexit(Proc, sys, TRUE);
  73                 return;
  74         }
  75 
  76         pri->length = 0;
  77         pri->Errno = 0;
  78         pri->ErrPriv = PRIV_NONE;
  79         pri->Rval1 = pri->Rval2 = 0;
  80         (void) sysentry(pri, dotrace);
  81         make_pname(pri, 0);
  82         putpname(pri);
  83         timestamp(pri);
  84         pri->length += printf("%s", pri->sys_string);
  85         pri->sys_leng = 0;
  86         *pri->sys_string = '\0';
  87         pri->length >>= 3;
  88         if (Lsp->pr_flags & PR_VFORKP)
  89                 pri->length += 2;
  90         if (pri->length >= 4)
  91                 (void) fputc(' ', stdout);
  92         for (; pri->length < 4; pri->length++)
  93                 (void) fputc('\t', stdout);
  94         if (Lsp->pr_flags & PR_VFORKP)
  95                 (void) fputs("(waiting for child to exit()/exec()...)\n",
  96                     stdout);
  97         else
  98                 (void) fputs("(sleeping...)\n", stdout);
  99         pri->length = 0;
 100         if (prismember(&verbose, sys)) {
 101                 int raw = prismember(&rawout, sys);
 102                 pri->Errno = 1;
 103                 expound(pri, 0, raw);
 104                 pri->Errno = 0;
 105         }
 106         Flush();
 107 }
 108 
 109 /*
 110  * requested() gets called for these reasons:
 111  *      flag == JOBSIG:         report nothing; change state to JOBSTOP
 112  *      flag == JOBSTOP:        report "Continued ..."
 113  *      default:                report sleeping system call
 114  *
 115  * It returns a new flag:  JOBSTOP or SLEEPING or 0.
 116  */
 117 int
 118 requested(private_t *pri, int flag, int dotrace)
 119 {
 120         const lwpstatus_t *Lsp = pri->lwpstat;
 121         int sig = Lsp->pr_cursig;
 122         int newflag = 0;
 123 
 124         switch (flag) {
 125         case JOBSIG:
 126                 return (JOBSTOP);
 127 
 128         case JOBSTOP:
 129                 if (dotrace && !cflag && prismember(&signals, sig)) {
 130                         pri->length = 0;
 131                         putpname(pri);
 132                         timestamp(pri);
 133                         (void) printf("    Continued with signal #%d, %s",
 134                             sig, signame(pri, sig));
 135                         if (Lsp->pr_action.sa_handler == SIG_DFL)
 136                                 (void) printf(" [default]");
 137                         else if (Lsp->pr_action.sa_handler == SIG_IGN)
 138                                 (void) printf(" [ignored]");
 139                         else
 140                                 (void) printf(" [caught]");
 141                         (void) fputc('\n', stdout);
 142                         Flush();
 143                 }
 144                 newflag = 0;
 145                 break;
 146 
 147         default:
 148                 newflag = SLEEPING;
 149                 if (!cflag)
 150                         report_sleeping(pri, dotrace);
 151                 break;
 152         }
 153 
 154         return (newflag);
 155 }
 156 
 157 int
 158 jobcontrol(private_t *pri, int dotrace)
 159 {
 160         const lwpstatus_t *Lsp = pri->lwpstat;
 161         int sig = stopsig(pri);
 162 
 163         if (sig == 0)
 164                 return (0);
 165 
 166         if (dotrace && !cflag &&                /* not just counting */
 167             prismember(&signals, sig)) {    /* tracing this signal */
 168                 int sys;
 169 
 170                 pri->length = 0;
 171                 putpname(pri);
 172                 timestamp(pri);
 173                 (void) printf("    Stopped by signal #%d, %s",
 174                     sig, signame(pri, sig));
 175                 if ((Lsp->pr_flags & PR_ASLEEP) &&
 176                     (sys = Lsp->pr_syscall) > 0 && sys <= PRMAXSYS)
 177                         (void) printf(", in %s()",
 178                             sysname(pri, sys, getsubcode(pri)));
 179                 (void) fputc('\n', stdout);
 180                 Flush();
 181         }
 182 
 183         return (JOBSTOP);
 184 }
 185 
 186 /*
 187  * Return the signal the process stopped on iff process is already stopped on
 188  * PR_JOBCONTROL or is stopped on PR_SIGNALLED or PR_REQUESTED with a current
 189  * signal that will cause a JOBCONTROL stop when the process is set running.
 190  */
 191 int
 192 stopsig(private_t *pri)
 193 {
 194         const lwpstatus_t *Lsp = pri->lwpstat;
 195         int sig = 0;
 196 
 197         if (Lsp->pr_flags & PR_STOPPED) {
 198                 switch (Lsp->pr_why) {
 199                 case PR_JOBCONTROL:
 200                         sig = Lsp->pr_what;
 201                         if (sig < 0 || sig > PRMAXSIG)
 202                                 sig = 0;
 203                         break;
 204                 case PR_SIGNALLED:
 205                 case PR_REQUESTED:
 206                         if (Lsp->pr_action.sa_handler == SIG_DFL) {
 207                                 switch (Lsp->pr_cursig) {
 208                                 case SIGSTOP:
 209                                         sig = SIGSTOP;
 210                                         break;
 211                                 case SIGTSTP:
 212                                 case SIGTTIN:
 213                                 case SIGTTOU:
 214                                         if (!(Lsp->pr_flags & PR_ORPHAN))
 215                                                 sig = Lsp->pr_cursig;
 216                                         break;
 217                                 }
 218                         }
 219                         break;
 220                 }
 221         }
 222 
 223         return (sig);
 224 }
 225 
 226 int
 227 signalled(private_t *pri, int flag, int dotrace)
 228 {
 229         const lwpstatus_t *Lsp = pri->lwpstat;
 230         int sig = Lsp->pr_what;
 231 
 232         if (sig <= 0 || sig > PRMAXSIG)   /* check bounds */
 233                 return (0);
 234 
 235         if (dotrace && cflag) {                 /* just counting */
 236                 (void) mutex_lock(&count_lock);
 237                 Cp->sigcount[sig]++;
 238                 (void) mutex_unlock(&count_lock);
 239         }
 240 
 241         if (sig == SIGCONT && (flag == JOBSIG || flag == JOBSTOP))
 242                 flag = requested(pri, JOBSTOP, dotrace);
 243         else if ((flag = jobcontrol(pri, dotrace)) == 0 &&
 244             !cflag && dotrace &&
 245             prismember(&signals, sig)) {
 246                 int sys;
 247 
 248                 pri->length = 0;
 249                 putpname(pri);
 250                 timestamp(pri);
 251                 (void) printf("    Received signal #%d, %s",
 252                     sig, signame(pri, sig));
 253                 if ((Lsp->pr_flags & PR_ASLEEP) &&
 254                     (sys = Lsp->pr_syscall) > 0 && sys <= PRMAXSYS)
 255                         (void) printf(", in %s()",
 256                             sysname(pri, sys, getsubcode(pri)));
 257                 if (Lsp->pr_action.sa_handler == SIG_DFL)
 258                         (void) printf(" [default]");
 259                 else if (Lsp->pr_action.sa_handler == SIG_IGN)
 260                         (void) printf(" [ignored]");
 261                 else
 262                         (void) printf(" [caught]");
 263                 (void) fputc('\n', stdout);
 264                 if (Lsp->pr_info.si_code != 0 ||
 265                     Lsp->pr_info.si_pid != 0)
 266                         print_siginfo(pri, &Lsp->pr_info);
 267                 Flush();
 268         }
 269 
 270         if (flag == JOBSTOP)
 271                 flag = JOBSIG;
 272         return (flag);
 273 }
 274 
 275 int
 276 faulted(private_t *pri, int dotrace)
 277 {
 278         const lwpstatus_t *Lsp = pri->lwpstat;
 279         int flt = Lsp->pr_what;
 280 
 281         if ((uint_t)flt > PRMAXFAULT || !prismember(&faults, flt) || !dotrace)
 282                 return (0);
 283 
 284         (void) mutex_lock(&count_lock);
 285         Cp->fltcount[flt]++;
 286         (void) mutex_unlock(&count_lock);
 287 
 288         if (cflag)              /* just counting */
 289                 return (1);
 290 
 291         pri->length = 0;
 292         putpname(pri);
 293         timestamp(pri);
 294 
 295         (void) printf("    Incurred fault #%d, %s  %%pc = 0x%.8lX",
 296             flt, proc_fltname(flt, pri->flt_name, sizeof (pri->flt_name)),
 297             (long)Lsp->pr_reg[R_PC]);
 298 
 299         if (flt == FLTPAGE)
 300                 (void) printf("  addr = 0x%.8lX",
 301                     (long)Lsp->pr_info.si_addr);
 302         (void) fputc('\n', stdout);
 303         if (Lsp->pr_info.si_signo != 0)
 304                 print_siginfo(pri, &Lsp->pr_info);
 305         Flush();
 306         return (1);
 307 }
 308 
 309 /*
 310  * Set up pri->sys_nargs and pri->sys_args[] (syscall args).
 311  */
 312 void
 313 setupsysargs(private_t *pri, int what)
 314 {
 315         const lwpstatus_t *Lsp = pri->lwpstat;
 316         int nargs;
 317         int i;
 318 
 319 #if sparc
 320         /* determine whether syscall is indirect */
 321         pri->sys_indirect = (Lsp->pr_reg[R_G1] == SYS_syscall)? 1 : 0;
 322 #else
 323         pri->sys_indirect = 0;
 324 #endif
 325 
 326         (void) memset(pri->sys_args, 0, sizeof (pri->sys_args));
 327         if (what != Lsp->pr_syscall) {       /* assertion */
 328                 (void) printf("%s\t*** Inconsistent syscall: %d vs %d ***\n",
 329                     pri->pname, what, Lsp->pr_syscall);
 330         }
 331         nargs = Lsp->pr_nsysarg;
 332         for (i = 0;
 333             i < nargs && i < sizeof (pri->sys_args) / sizeof (pri->sys_args[0]);
 334             i++)
 335                 pri->sys_args[i] = Lsp->pr_sysarg[i];
 336         pri->sys_nargs = nargs;
 337 }
 338 
 339 #define ISREAD(code) \
 340         ((code) == SYS_read || (code) == SYS_pread || \
 341         (code) == SYS_pread64 || (code) == SYS_readv || \
 342         (code) == SYS_recv || (code) == SYS_recvfrom)
 343 #define ISWRITE(code) \
 344         ((code) == SYS_write || (code) == SYS_pwrite || \
 345         (code) == SYS_pwrite64 || (code) == SYS_writev || \
 346         (code) == SYS_send || (code) == SYS_sendto)
 347 
 348 /*
 349  * Return TRUE iff syscall is being traced.
 350  */
 351 int
 352 sysentry(private_t *pri, int dotrace)
 353 {
 354         pid_t pid = Pstatus(Proc)->pr_pid;
 355         const lwpstatus_t *Lsp = pri->lwpstat;
 356         long arg;
 357         int nargs;
 358         int i;
 359         int x;
 360         int len;
 361         char *s;
 362         const struct systable *stp;
 363         int what = Lsp->pr_what;
 364         int subcode;
 365         int istraced;
 366         int raw;
 367 
 368         /* for reporting sleeping system calls */
 369         if (what == 0 && (Lsp->pr_flags & (PR_ASLEEP|PR_VFORKP)))
 370                 what = Lsp->pr_syscall;
 371 
 372         /* protect ourself from operating system error */
 373         if (what <= 0 || what > PRMAXSYS)
 374                 what = 0;
 375 
 376         /*
 377          * Set up the system call arguments (pri->sys_nargs & pri->sys_args[]).
 378          */
 379         setupsysargs(pri, what);
 380         nargs = pri->sys_nargs;
 381 
 382         /* get systable entry for this syscall */
 383         subcode = getsubcode(pri);
 384         stp = subsys(what, subcode);
 385 
 386         if (nargs > stp->nargs)
 387                 nargs = stp->nargs;
 388         pri->sys_nargs = nargs;
 389 
 390         /*
 391          * Fetch and remember first argument if it's a string,
 392          * or second argument if SYS_openat or SYS_openat64.
 393          */
 394         pri->sys_valid = FALSE;
 395         if ((nargs > 0 && stp->arg[0] == STG) ||
 396             (nargs > 1 && (what == SYS_openat || what == SYS_openat64))) {
 397                 long offset;
 398                 uint32_t offset32;
 399 
 400                 /*
 401                  * Special case for exit from exec().
 402                  * The address in pri->sys_args[0] refers to the old process
 403                  * image.  We must fetch the string from the new image.
 404                  */
 405                 if (Lsp->pr_why == PR_SYSEXIT && what == SYS_execve) {
 406                         psinfo_t psinfo;
 407                         long argv;
 408                         auxv_t auxv[32];
 409                         int naux;
 410 
 411                         offset = 0;
 412                         naux = proc_get_auxv(pid, auxv, 32);
 413                         for (i = 0; i < naux; i++) {
 414                                 if (auxv[i].a_type == AT_SUN_EXECNAME) {
 415                                         offset = (long)auxv[i].a_un.a_ptr;
 416                                         break;
 417                                 }
 418                         }
 419                         if (offset == 0 &&
 420                             proc_get_psinfo(pid, &psinfo) == 0) {
 421                                 argv = (long)psinfo.pr_argv;
 422                                 if (data_model == PR_MODEL_LP64)
 423                                         (void) Pread(Proc, &offset,
 424                                             sizeof (offset), argv);
 425                                 else {
 426                                         offset32 = 0;
 427                                         (void) Pread(Proc, &offset32,
 428                                             sizeof (offset32), argv);
 429                                         offset = offset32;
 430                                 }
 431                         }
 432                 } else if (stp->arg[0] == STG) {
 433                         offset = pri->sys_args[0];
 434                 } else {
 435                         offset = pri->sys_args[1];
 436                 }
 437                 if ((s = fetchstring(pri, offset, PATH_MAX)) != NULL) {
 438                         pri->sys_valid = TRUE;
 439                         len = strlen(s);
 440                         /* reallocate if necessary */
 441                         while (len >= pri->sys_psize) {
 442                                 free(pri->sys_path);
 443                                 pri->sys_path = my_malloc(pri->sys_psize *= 2,
 444                                     "pathname buffer");
 445                         }
 446                         (void) strcpy(pri->sys_path, s); /* remember pathname */
 447                 }
 448         }
 449 
 450         istraced = dotrace && prismember(&trace, what);
 451         raw = prismember(&rawout, what);
 452 
 453         /* force tracing of read/write buffer dump syscalls */
 454         if (!istraced && nargs > 2) {
 455                 int fdp1 = (int)pri->sys_args[0] + 1;
 456 
 457                 if (ISREAD(what)) {
 458                         if (prismember(&readfd, fdp1))
 459                                 istraced = TRUE;
 460                 } else if (ISWRITE(what)) {
 461                         if (prismember(&writefd, fdp1))
 462                                 istraced = TRUE;
 463                 }
 464         }
 465 
 466         pri->sys_leng = 0;
 467         if (cflag || !istraced)         /* just counting */
 468                 *pri->sys_string = 0;
 469         else {
 470                 int argprinted = FALSE;
 471                 const char *name;
 472 
 473                 name = sysname(pri, what, raw? -1 : subcode);
 474                 grow(pri, strlen(name) + 1);
 475                 pri->sys_leng = snprintf(pri->sys_string, pri->sys_ssize,
 476                     "%s(", name);
 477                 for (i = 0; i < nargs; i++) {
 478                         arg = pri->sys_args[i];
 479                         x = stp->arg[i];
 480 
 481                         if (!raw && pri->sys_valid &&
 482                             ((i == 0 && x == STG) ||
 483                             (i == 1 && (what == SYS_openat ||
 484                             what == SYS_openat64)))) {  /* already fetched */
 485                                 if (argprinted)
 486                                         outstring(pri, ", ");
 487                                 escape_string(pri, pri->sys_path);
 488                                 argprinted = TRUE;
 489                         } else if (x != NOV && (x != HID || raw)) {
 490                                 if (argprinted)
 491                                         outstring(pri, ", ");
 492                                 if (x == LLO || x == SAD)
 493                                         (*Print[x])(pri, raw, arg,
 494                                             pri->sys_args[++i]);
 495                                 else
 496                                         (*Print[x])(pri, raw, arg);
 497                                 argprinted = TRUE;
 498                         }
 499                 }
 500                 outstring(pri, ")");
 501         }
 502 
 503         return (istraced);
 504 }
 505 #undef  ISREAD
 506 #undef  ISWRITE
 507 
 508 /*
 509  * sysexit() returns non-zero if anything was printed.
 510  */
 511 int
 512 sysexit(private_t *pri, int dotrace)
 513 {
 514         const lwpstatus_t *Lsp = pri->lwpstat;
 515         int what = Lsp->pr_what;
 516         struct syscount *scp;
 517         const struct systable *stp;
 518         int subcode;
 519         int istraced;
 520         int raw;
 521 
 522         /* protect ourself from operating system error */
 523         if (what <= 0 || what > PRMAXSYS)
 524                 return (0);
 525 
 526         /*
 527          * If we aren't supposed to be tracing this one, then
 528          * delete it from the traced signal set.  We got here
 529          * because the process was sleeping in an untraced syscall.
 530          */
 531         if (!prismember(&traceeven, what)) {
 532                 (void) Psysexit(Proc, what, FALSE);
 533                 return (0);
 534         }
 535 
 536         /* pick up registers & set pri->Errno before anything else */
 537         pri->Errno = Lsp->pr_errno;
 538         pri->ErrPriv = Lsp->pr_errpriv;
 539         pri->Rval1 = Lsp->pr_rval1;
 540         pri->Rval2 = Lsp->pr_rval2;
 541 
 542         switch (what) {
 543         case SYS_exit:          /* these are traced on entry */
 544         case SYS_lwp_exit:
 545         case SYS_context:
 546                 istraced = dotrace && prismember(&trace, what);
 547                 break;
 548         case SYS_execve:        /* this is normally traced on entry */
 549                 istraced = dotrace && prismember(&trace, what);
 550                 if (pri->exec_string && *pri->exec_string) {
 551                         if (!cflag && istraced) { /* print exec() string now */
 552                                 if (pri->exec_pname[0] != '\0')
 553                                         (void) fputs(pri->exec_pname, stdout);
 554                                 timestamp(pri);
 555                                 (void) fputs(pri->exec_string, stdout);
 556                         }
 557                         pri->exec_pname[0] = '\0';
 558                         pri->exec_string[0] = '\0';
 559                         break;
 560                 }
 561                 /* FALLTHROUGH */
 562         default:
 563                 /* we called sysentry() in main() for these */
 564                 if (what == SYS_openat || what == SYS_openat64 ||
 565                     what == SYS_open || what == SYS_open64)
 566                         istraced = dotrace && prismember(&trace, what);
 567                 else
 568                         istraced = sysentry(pri, dotrace) && dotrace;
 569                 pri->length = 0;
 570                 if (!cflag && istraced) {
 571                         putpname(pri);
 572                         timestamp(pri);
 573                         pri->length += printf("%s", pri->sys_string);
 574                 }
 575                 pri->sys_leng = 0;
 576                 *pri->sys_string = '\0';
 577                 break;
 578         }
 579 
 580         /* get systable entry for this syscall */
 581         subcode = getsubcode(pri);
 582         stp = subsys(what, subcode);
 583 
 584         if (cflag && istraced) {
 585                 (void) mutex_lock(&count_lock);
 586                 scp = Cp->syscount[what];
 587                 if (what == SYS_forksys && subcode >= 3)
 588                         scp += subcode - 3;
 589                 else if (subcode != -1 &&
 590                     (what != SYS_openat && what != SYS_openat64 &&
 591                     what != SYS_open && what != SYS_open64 &&
 592                     what != SYS_lwp_create))
 593                         scp += subcode;
 594                 scp->count++;
 595                 accumulate(&scp->stime, &Lsp->pr_stime, &pri->syslast);
 596                 accumulate(&Cp->usrtotal, &Lsp->pr_utime, &pri->usrlast);
 597                 pri->syslast = Lsp->pr_stime;
 598                 pri->usrlast = Lsp->pr_utime;
 599                 (void) mutex_unlock(&count_lock);
 600         }
 601 
 602         raw = prismember(&rawout, what);
 603 
 604         if (!cflag && istraced) {
 605                 if ((what == SYS_vfork || what == SYS_forksys) &&
 606                     pri->Errno == 0 && pri->Rval2 != 0) {
 607                         pri->length &= ~07;
 608                         if (strlen(sysname(pri, what, raw? -1 : subcode)) < 6) {
 609                                 (void) fputc('\t', stdout);
 610                                 pri->length += 8;
 611                         }
 612                         pri->length +=
 613                             7 + printf("\t(returning as child ...)");
 614                 }
 615                 if (what == SYS_lwp_create &&
 616                     pri->Errno == 0 && pri->Rval1 == 0) {
 617                         pri->length &= ~07;
 618                         pri->length +=
 619                             7 + printf("\t(returning as new lwp ...)");
 620                 }
 621                 if (pri->Errno != 0 || what != SYS_execve) {
 622                         /* prepare to print the return code */
 623                         pri->length >>= 3;
 624                         if (pri->length >= 6)
 625                                 (void) fputc(' ', stdout);
 626                         for (; pri->length < 6; pri->length++)
 627                                 (void) fputc('\t', stdout);
 628                 }
 629         }
 630         pri->length = 0;
 631 
 632         if (pri->Errno != 0) {               /* error in syscall */
 633                 if (istraced) {
 634                         if (cflag)
 635                                 scp->error++;
 636                         else {
 637                                 const char *ename = errname(pri->Errno);
 638                                 const char *privname;
 639 
 640                                 (void) printf("Err#%d", pri->Errno);
 641                                 if (ename != NULL) {
 642                                         (void) fputc(' ', stdout);
 643                                         (void) fputs(ename, stdout);
 644                                 }
 645                                 switch (pri->ErrPriv) {
 646                                 case PRIV_NONE:
 647                                         privname = NULL;
 648                                         break;
 649                                 case PRIV_ALL:
 650                                         privname = "ALL";
 651                                         break;
 652                                 case PRIV_MULTIPLE:
 653                                         privname = "MULTIPLE";
 654                                         break;
 655                                 case PRIV_ALLZONE:
 656                                         privname = "ZONE";
 657                                         break;
 658                                 default:
 659                                         privname = priv_getbynum(pri->ErrPriv);
 660                                         break;
 661                                 }
 662                                 if (privname != NULL)
 663                                         (void) printf(" [%s]", privname);
 664 
 665                                 (void) fputc('\n', stdout);
 666                         }
 667                 }
 668         } else {
 669                 /* show arguments on successful exec */
 670                 if (what == SYS_execve) {
 671                         if (!cflag && istraced)
 672                                 showargs(pri, raw);
 673                 } else if (!cflag && istraced) {
 674                         const char *fmt = NULL;
 675                         long rv1 = pri->Rval1;
 676                         long rv2 = pri->Rval2;
 677 
 678 #ifdef _LP64
 679                         /*
 680                          * 32-bit system calls return 32-bit values. We
 681                          * later mask out the upper bits if we want to
 682                          * print these as unsigned values.
 683                          */
 684                         if (data_model == PR_MODEL_ILP32) {
 685                                 rv1 = (int)rv1;
 686                                 rv2 = (int)rv2;
 687                         }
 688 #endif
 689 
 690                         switch (what) {
 691                         case SYS_llseek:
 692                                 rv1 &= 0xffffffff;
 693                                 rv2 &= 0xffffffff;
 694 #ifdef _LONG_LONG_LTOH  /* first long of a longlong is the low order */
 695                                 if (rv2 != 0) {
 696                                         long temp = rv1;
 697                                         fmt = "= 0x%lX%.8lX";
 698                                         rv1 = rv2;
 699                                         rv2 = temp;
 700                                         break;
 701                                 }
 702 #else   /* the other way around */
 703                                 if (rv1 != 0) {
 704                                         fmt = "= 0x%lX%.8lX";
 705                                         break;
 706                                 }
 707                                 rv1 = rv2;      /* ugly */
 708 #endif
 709                                 /* FALLTHROUGH */
 710                         case SYS_lseek:
 711                         case SYS_ulimit:
 712                                 if (rv1 & 0xff000000) {
 713 #ifdef _LP64
 714                                         if (data_model == PR_MODEL_ILP32)
 715                                                 rv1 &= 0xffffffff;
 716 #endif
 717                                         fmt = "= 0x%.8lX";
 718                                 }
 719                                 break;
 720                         case SYS_sigtimedwait:
 721                                 if (raw)
 722                                         /* EMPTY */;
 723                                 else if ((fmt = rawsigname(pri, rv1)) != NULL) {
 724                                         rv1 = (long)fmt;        /* filthy */
 725                                         fmt = "= %s";
 726                                 }
 727                                 break;
 728                         case SYS_port:
 729 #ifdef _LP64
 730                                 if (data_model == PR_MODEL_LP64) {
 731                                         rv2 = rv1 & 0xffffffff;
 732                                         rv1 = rv1 >> 32;
 733                                 }
 734 #endif
 735                                 break;
 736                         }
 737 
 738                         if (fmt == NULL) {
 739                                 switch (stp->rval[0]) {
 740                                 case HEX:
 741 #ifdef _LP64
 742                                         if (data_model == PR_MODEL_ILP32)
 743                                                 rv1 &= 0xffffffff;
 744 #endif
 745                                         fmt = "= 0x%.8lX";
 746                                         break;
 747                                 case HHX:
 748 #ifdef _LP64
 749                                         if (data_model == PR_MODEL_ILP32)
 750                                                 rv1 &= 0xffffffff;
 751 #endif
 752                                         fmt = "= 0x%.4lX";
 753                                         break;
 754                                 case OCT:
 755 #ifdef _LP64
 756                                         if (data_model == PR_MODEL_ILP32)
 757                                                 rv1 &= 0xffffffff;
 758 #endif
 759                                         fmt = "= %#lo";
 760                                         break;
 761                                 case UNS:
 762 #ifdef _LP64
 763                                         if (data_model == PR_MODEL_ILP32)
 764                                                 rv1 &= 0xffffffff;
 765 #endif
 766                                         fmt = "= %lu";
 767                                         break;
 768                                 default:
 769                                         fmt = "= %ld";
 770                                         break;
 771                                 }
 772                         }
 773 
 774                         (void) printf(fmt, rv1, rv2);
 775 
 776                         switch (stp->rval[1]) {
 777                         case NOV:
 778                                 fmt = NULL;
 779                                 break;
 780                         case HEX:
 781 #ifdef _LP64
 782                                 if (data_model == PR_MODEL_ILP32)
 783                                         rv2 &= 0xffffffff;
 784 #endif
 785                                 fmt = " [0x%.8lX]";
 786                                 break;
 787                         case HHX:
 788 #ifdef _LP64
 789                                 if (data_model == PR_MODEL_ILP32)
 790                                         rv2 &= 0xffffffff;
 791 #endif
 792                                 fmt = " [0x%.4lX]";
 793                                 break;
 794                         case OCT:
 795 #ifdef _LP64
 796                                 if (data_model == PR_MODEL_ILP32)
 797                                         rv2 &= 0xffffffff;
 798 #endif
 799                                 fmt = " [%#lo]";
 800                                 break;
 801                         case UNS:
 802 #ifdef _LP64
 803                                 if (data_model == PR_MODEL_ILP32)
 804                                         rv2 &= 0xffffffff;
 805 #endif
 806                                 fmt = " [%lu]";
 807                                 break;
 808                         default:
 809                                 fmt = " [%ld]";
 810                                 break;
 811                         }
 812 
 813                         if (fmt != NULL)
 814                                 (void) printf(fmt, rv2);
 815                         (void) fputc('\n', stdout);
 816                 }
 817 
 818                 if (what == SYS_vfork || what == SYS_forksys) {
 819                         if (pri->Rval2 == 0)         /* child was created */
 820                                 pri->child = pri->Rval1;
 821                         else if (cflag && istraced)     /* this is the child */
 822                                 scp->count--;
 823                 }
 824                 if (what == SYS_lwp_create && pri->Rval1 == 0 &&
 825                     cflag && istraced)          /* this is the created lwp */
 826                         scp->count--;
 827         }
 828 
 829 #define ISREAD(code) \
 830         ((code) == SYS_read || (code) == SYS_pread || (code) == SYS_pread64 || \
 831         (code) == SYS_recv || (code) == SYS_recvfrom)
 832 #define ISWRITE(code) \
 833         ((code) == SYS_write || (code) == SYS_pwrite || \
 834         (code) == SYS_pwrite64 || (code) == SYS_send || (code) == SYS_sendto)
 835 
 836         if (!cflag && istraced) {
 837                 int fdp1 = (int)pri->sys_args[0] + 1; /* filedescriptor + 1 */
 838 
 839                 if (raw) {
 840                         if (what != SYS_execve)
 841                                 showpaths(pri, stp);
 842                         if (ISREAD(what) || ISWRITE(what)) {
 843                                 if (pri->iob_buf[0] != '\0')
 844                                         (void) printf("%s     0x%.8lX: %s\n",
 845                                             pri->pname, pri->sys_args[1],
 846                                             pri->iob_buf);
 847                         }
 848                 }
 849 
 850                 /*
 851                  * Show buffer contents for read()/pread() or write()/pwrite().
 852                  * IOBSIZE bytes have already been shown;
 853                  * don't show them again unless there's more.
 854                  */
 855                 if ((ISREAD(what) && pri->Errno == 0 &&
 856                     prismember(&readfd, fdp1)) ||
 857                     (ISWRITE(what) && prismember(&writefd, fdp1))) {
 858                         long nb = ISWRITE(what) ? pri->sys_args[2] : pri->Rval1;
 859 
 860                         if (nb > IOBSIZE) {
 861                                 /* enter region of lengthy output */
 862                                 if (nb > MYBUFSIZ / 4)
 863                                         Eserialize();
 864 
 865                                 showbuffer(pri, pri->sys_args[1], nb);
 866 
 867                                 /* exit region of lengthy output */
 868                                 if (nb > MYBUFSIZ / 4)
 869                                         Xserialize();
 870                         }
 871                 }
 872 #undef  ISREAD
 873 #undef  ISWRITE
 874                 /*
 875                  * Do verbose interpretation if requested.
 876                  * If buffer contents for read or write have been requested and
 877                  * this is a readv() or writev(), force verbose interpretation.
 878                  */
 879                 if (prismember(&verbose, what) ||
 880                     ((what == SYS_readv || what == SYS_recvmsg) &&
 881                     pri->Errno == 0 && prismember(&readfd, fdp1)) ||
 882                     ((what == SYS_writev || what == SYS_sendfilev ||
 883                     what == SYS_sendmsg) &&
 884                     prismember(&writefd, fdp1)))
 885                         expound(pri, pri->Rval1, raw);
 886         }
 887 
 888         return (!cflag && istraced);
 889 }
 890 
 891 void
 892 showpaths(private_t *pri, const struct systable *stp)
 893 {
 894         int what = pri->lwpstat->pr_what;
 895         int i;
 896 
 897         for (i = 0; i < pri->sys_nargs; i++) {
 898                 if (stp->arg[i] == ATC && (int)pri->sys_args[i] == AT_FDCWD) {
 899                         (void) printf("%s     0x%.8X: AT_FDCWD\n",
 900                             pri->pname, AT_FDCWD);
 901                 } else if ((stp->arg[i] == STG) ||
 902                     (stp->arg[i] == RST && !pri->Errno) ||
 903                     (stp->arg[i] == RLK && !pri->Errno && pri->Rval1 > 0)) {
 904                         long addr = pri->sys_args[i];
 905                         int maxleng =
 906                             (stp->arg[i] == RLK)? (int)pri->Rval1 : PATH_MAX;
 907                         char *s;
 908 
 909                         if (pri->sys_valid &&
 910                             ((i == 0 && stp->arg[0] == STG) ||
 911                             (i == 1 && (what == SYS_openat ||
 912                             what == SYS_openat64))))    /* already fetched */
 913                                 s = pri->sys_path;
 914                         else
 915                                 s = fetchstring(pri, addr,
 916                                     maxleng > PATH_MAX ? PATH_MAX : maxleng);
 917 
 918                         if (s != (char *)NULL)
 919                                 (void) printf("%s     0x%.8lX: \"%s\"\n",
 920                                     pri->pname, addr, s);
 921                 }
 922         }
 923 }
 924 
 925 /*
 926  * Display arguments to successful exec().
 927  */
 928 void
 929 showargs(private_t *pri, int raw)
 930 {
 931         const lwpstatus_t *Lsp = pri->lwpstat;
 932         int nargs;
 933         long ap;
 934         int ptrsize;
 935         int fail;
 936 
 937         pri->length = 0;
 938         ptrsize = (data_model == PR_MODEL_LP64)? 8 : 4;
 939 
 940 #if defined(__i386) || defined(__amd64) /* XX64 */
 941         ap = (long)Lsp->pr_reg[R_SP];
 942         fail = (Pread(Proc, &nargs, sizeof (nargs), ap) != sizeof (nargs));
 943         ap += ptrsize;
 944 #endif /* i386 */
 945 
 946 #if sparc
 947         if (data_model == PR_MODEL_LP64) {
 948                 int64_t xnargs;
 949                 ap = (long)(Lsp->pr_reg[R_SP]) + 16 * sizeof (int64_t)
 950                     + STACK_BIAS;
 951                 fail = (Pread(Proc, &xnargs, sizeof (xnargs), ap) !=
 952                     sizeof (xnargs));
 953                 nargs = (int)xnargs;
 954         } else {
 955                 ap = (long)(Lsp->pr_reg[R_SP]) + 16 * sizeof (int32_t);
 956                 fail = (Pread(Proc, &nargs, sizeof (nargs), ap) !=
 957                     sizeof (nargs));
 958         }
 959         ap += ptrsize;
 960 #endif /* sparc */
 961 
 962         if (fail) {
 963                 (void) printf("\n%s\t*** Bad argument list? ***\n", pri->pname);
 964                 return;
 965         }
 966 
 967         (void) printf("  argc = %d\n", nargs);
 968         if (raw)
 969                 showpaths(pri, &systable[SYS_execve]);
 970 
 971         show_cred(pri, FALSE, FALSE);
 972 
 973         if (aflag || eflag) {           /* dump args or environment */
 974 
 975                 /* enter region of (potentially) lengthy output */
 976                 Eserialize();
 977 
 978                 if (aflag)              /* dump the argument list */
 979                         dumpargs(pri, ap, "argv:");
 980                 ap += (nargs+1) * ptrsize;
 981                 if (eflag)              /* dump the environment */
 982                         dumpargs(pri, ap, "envp:");
 983 
 984                 /* exit region of lengthy output */
 985                 Xserialize();
 986         }
 987 }
 988 
 989 void
 990 dumpargs(private_t *pri, long ap, const char *str)
 991 {
 992         char *string;
 993         unsigned int leng = 0;
 994         int ptrsize;
 995         long arg = 0;
 996         char *argaddr;
 997         char badaddr[32];
 998 
 999         if (interrupt)
1000                 return;
1001 
1002 #ifdef _LP64
1003         if (data_model == PR_MODEL_LP64) {
1004                 argaddr = (char *)&arg;
1005                 ptrsize = 8;
1006         } else {
1007 #if defined(_LITTLE_ENDIAN)
1008                 argaddr = (char *)&arg;
1009 #else
1010                 argaddr = (char *)&arg + 4;
1011 #endif
1012                 ptrsize = 4;
1013         }
1014 #else
1015         argaddr = (char *)&arg;
1016         ptrsize = 4;
1017 #endif
1018         putpname(pri);
1019         (void) fputc(' ', stdout);
1020         (void) fputs(str, stdout);
1021         leng += 1 + strlen(str);
1022 
1023         while (!interrupt) {
1024                 if (Pread(Proc, argaddr, ptrsize, ap) != ptrsize) {
1025                         (void) printf("\n%s\t*** Bad argument list? ***\n",
1026                             pri->pname);
1027                         return;
1028                 }
1029                 ap += ptrsize;
1030 
1031                 if (arg == 0)
1032                         break;
1033                 string = fetchstring(pri, arg, PATH_MAX);
1034                 if (string == NULL) {
1035                         (void) sprintf(badaddr, "BadAddress:0x%.8lX", arg);
1036                         string = badaddr;
1037                 }
1038                 if ((leng += strlen(string)) < 63) {
1039                         (void) fputc(' ', stdout);
1040                         leng++;
1041                 } else {
1042                         (void) fputc('\n', stdout);
1043                         leng = 0;
1044                         putpname(pri);
1045                         (void) fputs("  ", stdout);
1046                         leng += 2 + strlen(string);
1047                 }
1048                 (void) fputs(string, stdout);
1049         }
1050         (void) fputc('\n', stdout);
1051 }
1052 
1053 /*
1054  * Display contents of read() or write() buffer.
1055  */
1056 void
1057 showbuffer(private_t *pri, long offset, long count)
1058 {
1059         char buffer[320];
1060         int nbytes;
1061         char *buf;
1062         int n;
1063 
1064         while (count > 0 && !interrupt) {
1065                 nbytes = (count < sizeof (buffer))? count : sizeof (buffer);
1066                 if ((nbytes = Pread(Proc, buffer, nbytes, offset)) <= 0)
1067                         break;
1068                 count -= nbytes;
1069                 offset += nbytes;
1070                 buf = buffer;
1071                 while (nbytes > 0 && !interrupt) {
1072                         char obuf[65];
1073 
1074                         n = (nbytes < 32)? nbytes : 32;
1075                         showbytes(buf, n, obuf);
1076 
1077                         putpname(pri);
1078                         (void) fputs("  ", stdout);
1079                         (void) fputs(obuf, stdout);
1080                         (void) fputc('\n', stdout);
1081                         nbytes -= n;
1082                         buf += n;
1083                 }
1084         }
1085 }
1086 
1087 void
1088 showbytes(const char *buf, int n, char *obuf)
1089 {
1090         int c;
1091 
1092         while (--n >= 0) {
1093                 int c1 = '\\';
1094                 int c2;
1095 
1096                 switch (c = (*buf++ & 0xff)) {
1097                 case '\0':
1098                         c2 = '0';
1099                         break;
1100                 case '\b':
1101                         c2 = 'b';
1102                         break;
1103                 case '\t':
1104                         c2 = 't';
1105                         break;
1106                 case '\n':
1107                         c2 = 'n';
1108                         break;
1109                 case '\v':
1110                         c2 = 'v';
1111                         break;
1112                 case '\f':
1113                         c2 = 'f';
1114                         break;
1115                 case '\r':
1116                         c2 = 'r';
1117                         break;
1118                 default:
1119                         if (isprint(c)) {
1120                                 c1 = ' ';
1121                                 c2 = c;
1122                         } else {
1123                                 c1 = c>>4;
1124                                 c1 += (c1 < 10)? '0' : 'A'-10;
1125                                 c2 = c&0xf;
1126                                 c2 += (c2 < 10)? '0' : 'A'-10;
1127                         }
1128                         break;
1129                 }
1130                 *obuf++ = (char)c1;
1131                 *obuf++ = (char)c2;
1132         }
1133 
1134         *obuf = '\0';
1135 }