Print this page
    
OS-3820 lxbrand ptrace(2): the next generation
OS-3685 lxbrand PTRACE_O_TRACEFORK race condition
OS-3834 lxbrand 64-bit strace(1) reports 64-bit process as using x32 ABI
OS-3794 lxbrand panic on init signal death
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Bryan Cantrill <bryan@joyent.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/ptools/pflags/pflags.c
          +++ new/usr/src/cmd/ptools/pflags/pflags.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  
    | 
      ↓ open down ↓ | 
    17 lines elided | 
    
      ↑ open up ↑ | 
  
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   */
  26   26  
  27   27  /*
  28      - * Copyright (c) 2013, Joyent, Inc. All rights reserved.
       28 + * Copyright 2015, Joyent, Inc.
  29   29   */
  30   30  
  31   31  #include <stdio.h>
  32   32  #include <stdio_ext.h>
  33   33  #include <stdlib.h>
  34   34  #include <unistd.h>
  35   35  #include <ctype.h>
  36   36  #include <fcntl.h>
  37   37  #include <strings.h>
  38   38  #include <dirent.h>
  39   39  #include <errno.h>
  40   40  #include <sys/types.h>
  41   41  #include <sys/int_fmtio.h>
  42   42  #include <libproc.h>
  43   43  
  44   44  typedef struct look_arg {
  45   45          int pflags;
  46   46          const char *lwps;
  47   47          int count;
  48   48  } look_arg_t;
  49   49  
  50   50  static  int     look(char *);
  51   51  static  int     lwplook(look_arg_t *, const lwpstatus_t *, const lwpsinfo_t *);
  52   52  static  char    *prflags(int);
  53   53  static  char    *prwhy(int);
  54   54  static  char    *prwhat(int, int);
  55   55  static  void    dumpregs(const prgregset_t, int);
  56   56  #if defined(__sparc) && defined(_ILP32)
  57   57  static  void    dumpregs_v8p(const prgregset_t, const prxregset_t *, int);
  58   58  #endif
  59   59  
  60   60  static  char    *command;
  61   61  static  struct  ps_prochandle *Pr;
  62   62  
  63   63  static  int     is64;   /* Is current process 64-bit? */
  64   64  static  int     rflag;  /* Show registers? */
  65   65  
  66   66  #define LWPFLAGS        \
  67   67          (PR_STOPPED|PR_ISTOP|PR_DSTOP|PR_ASLEEP|PR_PCINVAL|PR_STEP \
  68   68          |PR_AGENT|PR_DETACH|PR_DAEMON)
  69   69  
  70   70  #define PROCFLAGS       \
  71   71          (PR_ISSYS|PR_VFORKP|PR_ORPHAN|PR_NOSIGCHLD|PR_WAITPID \
  72   72          |PR_FORK|PR_RLC|PR_KLC|PR_ASYNC|PR_BPTADJ|PR_MSACCT|PR_MSFORK|PR_PTRACE)
  73   73  
  74   74  #define ALLFLAGS        (LWPFLAGS|PROCFLAGS)
  75   75  
  76   76  int
  77   77  main(int argc, char **argv)
  78   78  {
  79   79          int rc = 0;
  80   80          int errflg = 0;
  81   81          int opt;
  82   82          struct rlimit rlim;
  83   83  
  84   84          if ((command = strrchr(argv[0], '/')) != NULL)
  85   85                  command++;
  86   86          else
  87   87                  command = argv[0];
  88   88  
  89   89          /* options */
  90   90          while ((opt = getopt(argc, argv, "r")) != EOF) {
  91   91                  switch (opt) {
  92   92                  case 'r':               /* show registers */
  93   93                          rflag = 1;
  94   94                          break;
  95   95                  default:
  96   96                          errflg = 1;
  97   97                          break;
  98   98                  }
  99   99          }
 100  100  
 101  101          argc -= optind;
 102  102          argv += optind;
 103  103  
 104  104          if (errflg || argc <= 0) {
 105  105                  (void) fprintf(stderr,
 106  106                      "usage:\t%s [-r] { pid | core }[/lwps] ...\n", command);
 107  107                  (void) fprintf(stderr, "  (report process status flags)\n");
 108  108                  (void) fprintf(stderr, "  -r : report registers\n");
 109  109                  return (2);
 110  110          }
 111  111  
 112  112          /*
 113  113           * Make sure we'll have enough file descriptors to handle a target
 114  114           * that has many many mappings.
 115  115           */
 116  116          if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
 117  117                  rlim.rlim_cur = rlim.rlim_max;
 118  118                  (void) setrlimit(RLIMIT_NOFILE, &rlim);
 119  119                  (void) enable_extended_FILE_stdio(-1, -1);
 120  120          }
 121  121  
 122  122          while (argc-- > 0)
 123  123                  rc += look(*argv++);
 124  124  
 125  125          return (rc);
 126  126  }
 127  127  
 128  128  static int
 129  129  look(char *arg)
 130  130  {
 131  131          int gcode;
 132  132          int gcode2;
 133  133          pstatus_t pstatus;
 134  134          psinfo_t psinfo;
 135  135          int flags;
 136  136          sigset_t sigmask;
 137  137          fltset_t fltmask;
 138  138          sysset_t entryset;
 139  139          sysset_t exitset;
 140  140          uint32_t sigtrace, sigtrace1, sigtrace2, fltbits;
 141  141          uint32_t sigpend, sigpend1, sigpend2;
 142  142          uint32_t *bits;
 143  143          char buf[PRSIGBUFSZ];
 144  144          look_arg_t lookarg;
 145  145  
 146  146          if ((Pr = proc_arg_xgrab(arg, NULL, PR_ARG_ANY,
 147  147              PGRAB_RETAIN | PGRAB_FORCE | PGRAB_RDONLY | PGRAB_NOSTOP, &gcode,
 148  148              &lookarg.lwps)) == NULL) {
 149  149                  if (gcode == G_NOPROC &&
 150  150                      proc_arg_psinfo(arg, PR_ARG_PIDS, &psinfo, &gcode2) > 0 &&
 151  151                      psinfo.pr_nlwp == 0) {
 152  152                          (void) printf("%d:\t<defunct>\n\n", (int)psinfo.pr_pid);
 153  153                          return (0);
 154  154                  }
 155  155                  (void) fprintf(stderr, "%s: cannot examine %s: %s\n",
 156  156                      command, arg, Pgrab_error(gcode));
 157  157                  return (1);
 158  158          }
 159  159  
 160  160          (void) memcpy(&pstatus, Pstatus(Pr), sizeof (pstatus_t));
 161  161          (void) memcpy(&psinfo, Ppsinfo(Pr), sizeof (psinfo_t));
 162  162          proc_unctrl_psinfo(&psinfo);
 163  163  
 164  164          if (psinfo.pr_nlwp == 0) {
 165  165                  (void) printf("%d:\t<defunct>\n\n", (int)psinfo.pr_pid);
 166  166                  Prelease(Pr, PRELEASE_RETAIN);
 167  167                  return (0);
 168  168          }
 169  169  
 170  170          is64 = (pstatus.pr_dmodel == PR_MODEL_LP64);
 171  171  
 172  172          sigmask = pstatus.pr_sigtrace;
 173  173          fltmask = pstatus.pr_flttrace;
 174  174          entryset = pstatus.pr_sysentry;
 175  175          exitset = pstatus.pr_sysexit;
 176  176  
 177  177          if (Pstate(Pr) == PS_DEAD) {
 178  178                  (void) printf("core '%s' of %d:\t%.70s\n",
 179  179                      arg, (int)psinfo.pr_pid, psinfo.pr_psargs);
 180  180          } else {
 181  181                  (void) printf("%d:\t%.70s\n",
 182  182                      (int)psinfo.pr_pid, psinfo.pr_psargs);
 183  183          }
 184  184  
 185  185          (void) printf("\tdata model = %s", is64? "_LP64" : "_ILP32");
 186  186          if ((flags = (pstatus.pr_flags & PROCFLAGS)) != 0)
 187  187                  (void) printf("  flags = %s", prflags(flags));
 188  188          (void) printf("\n");
 189  189  
 190  190          fltbits = *((uint32_t *)&fltmask);
 191  191          if (fltbits)
 192  192                  (void) printf("\tflttrace = 0x%.8x\n", fltbits);
 193  193  
 194  194  #if (MAXSIG > 2 * 32) && (MAXSIG <= 3 * 32)     /* assumption */
 195  195          sigtrace = *((uint32_t *)&sigmask);
 196  196          sigtrace1 = *((uint32_t *)&sigmask + 1);
 197  197          sigtrace2 = *((uint32_t *)&sigmask + 2);
 198  198  #else
 199  199  #error "fix me: MAXSIG out of bounds"
 200  200  #endif
 201  201          if (sigtrace | sigtrace1 | sigtrace2)
 202  202                  (void) printf("\tsigtrace = 0x%.8x 0x%.8x 0x%.8x\n\t    %s\n",
 203  203                      sigtrace, sigtrace1, sigtrace2,
 204  204                      proc_sigset2str(&sigmask, "|", 1, buf, sizeof (buf)));
 205  205  
 206  206          bits = ((uint32_t *)&entryset);
 207  207          if (bits[0] | bits[1] | bits[2] | bits[3] |
 208  208              bits[4] | bits[5] | bits[6] | bits[7])
 209  209                  (void) printf(
 210  210                      "\tentryset = "
 211  211                      "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
 212  212                      "\t           "
 213  213                      "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
 214  214                      bits[0], bits[1], bits[2], bits[3],
 215  215                      bits[4], bits[5], bits[6], bits[7]);
 216  216  
 217  217          bits = ((uint32_t *)&exitset);
 218  218          if (bits[0] | bits[1] | bits[2] | bits[3] |
 219  219              bits[4] | bits[5] | bits[6] | bits[7])
 220  220                  (void) printf(
 221  221                      "\texitset  = "
 222  222                      "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
 223  223                      "\t           "
 224  224                      "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
 225  225                      bits[0], bits[1], bits[2], bits[3],
 226  226                      bits[4], bits[5], bits[6], bits[7]);
 227  227  
 228  228  #if (MAXSIG > 2 * 32) && (MAXSIG <= 3 * 32)     /* assumption */
 229  229          sigpend  = *((uint32_t *)&pstatus.pr_sigpend);
 230  230          sigpend1 = *((uint32_t *)&pstatus.pr_sigpend + 1);
 231  231          sigpend2 = *((uint32_t *)&pstatus.pr_sigpend + 2);
 232  232  #else
 233  233  #error "fix me: MAXSIG out of bounds"
 234  234  #endif
 235  235          if (sigpend | sigpend1 | sigpend2)
 236  236                  (void) printf("\tsigpend = 0x%.8x,0x%.8x,0x%.8x\n",
 237  237                      sigpend, sigpend1, sigpend2);
 238  238  
 239  239          lookarg.pflags = pstatus.pr_flags;
 240  240          lookarg.count = 0;
 241  241          (void) Plwp_iter_all(Pr, (proc_lwp_all_f *)lwplook, &lookarg);
 242  242  
 243  243          if (lookarg.count == 0)
 244  244                  (void) printf("No matching lwps found");
 245  245  
 246  246          (void) printf("\n");
 247  247          Prelease(Pr, PRELEASE_RETAIN);
 248  248  
 249  249          return (0);
 250  250  }
 251  251  
 252  252  static int
 253  253  lwplook_zombie(const lwpsinfo_t *pip)
 254  254  {
 255  255          (void) printf(" /%d:\t<defunct>\n", (int)pip->pr_lwpid);
 256  256          return (0);
 257  257  }
 258  258  
 259  259  static int
 260  260  lwplook(look_arg_t *arg, const lwpstatus_t *psp, const lwpsinfo_t *pip)
 261  261  {
 262  262          int flags;
 263  263          uint32_t sighold, sighold1, sighold2;
 264  264          uint32_t sigpend, sigpend1, sigpend2;
 265  265          psinfo_t ps;
 266  266          int cursig;
 267  267          char buf[32];
 268  268  
 269  269          if (!proc_lwp_in_set(arg->lwps, pip->pr_lwpid))
 270  270                  return (0);
 271  271  
 272  272          arg->count++;
 273  273  
 274  274          if (psp == NULL)
 275  275                  return (lwplook_zombie(pip));
 276  276  
 277  277          /*
 278  278           * PR_PCINVAL is just noise if the lwp is not stopped.
 279  279           * Don't bother reporting it unless the lwp is stopped.
 280  280           */
 281  281          flags = psp->pr_flags & LWPFLAGS;
 282  282          if (!(flags & PR_STOPPED))
 283  283                  flags &= ~PR_PCINVAL;
 284  284  
 285  285          (void) printf(" /%d:\tflags = %s", (int)psp->pr_lwpid, prflags(flags));
 286  286          if ((flags & PR_ASLEEP) || (psp->pr_syscall &&
 287  287              !(arg->pflags & PR_ISSYS))) {
 288  288                  if (flags & PR_ASLEEP) {
 289  289                          if ((flags & ~PR_ASLEEP) != 0)
 290  290                                  (void) printf("|");
 291  291                          (void) printf("ASLEEP");
 292  292                  }
 293  293                  if (psp->pr_syscall && !(arg->pflags & PR_ISSYS)) {
 294  294                          uint_t i;
 295  295  
 296  296                          (void) printf("  %s(",
 297  297                              proc_sysname(psp->pr_syscall, buf, sizeof (buf)));
 298  298                          for (i = 0; i < psp->pr_nsysarg; i++) {
 299  299                                  if (i != 0)
 300  300                                          (void) printf(",");
 301  301                                  (void) printf("0x%lx", psp->pr_sysarg[i]);
 302  302                          }
 303  303                          (void) printf(")");
 304  304                  }
 305  305          }
 306  306          (void) printf("\n");
 307  307  
 308  308          if (flags & PR_STOPPED) {
 309  309                  (void) printf("\twhy = %s", prwhy(psp->pr_why));
 310  310                  if (psp->pr_why != PR_REQUESTED &&
 311  311                      psp->pr_why != PR_SUSPENDED)
 312  312                          (void) printf("  what = %s",
 313  313                              prwhat(psp->pr_why, psp->pr_what));
 314  314                  (void) printf("\n");
 315  315          }
 316  316  
 317  317  #if (MAXSIG > 2 * 32) && (MAXSIG <= 3 * 32)     /* assumption */
 318  318          sighold  = *((uint32_t *)&psp->pr_lwphold);
 319  319          sighold1 = *((uint32_t *)&psp->pr_lwphold + 1);
 320  320          sighold2 = *((uint32_t *)&psp->pr_lwphold + 2);
 321  321          sigpend  = *((uint32_t *)&psp->pr_lwppend);
 322  322          sigpend1 = *((uint32_t *)&psp->pr_lwppend + 1);
 323  323          sigpend2 = *((uint32_t *)&psp->pr_lwppend + 2);
 324  324  #else
 325  325  #error "fix me: MAXSIG out of bounds"
 326  326  #endif
 327  327          cursig   = psp->pr_cursig;
 328  328  
 329  329          if (sighold | sighold1 | sighold2)
 330  330                  (void) printf("\tsigmask = 0x%.8x,0x%.8x,0x%.8x\n",
 331  331                      sighold, sighold1, sighold2);
 332  332          if (sigpend | sigpend1 | sigpend2)
 333  333                  (void) printf("\tlwppend = 0x%.8x,0x%.8x,0x%.8x\n",
 334  334                      sigpend, sigpend1, sigpend2);
 335  335          if (cursig)
 336  336                  (void) printf("\tcursig = %s\n",
 337  337                      proc_signame(cursig, buf, sizeof (buf)));
 338  338  
 339  339          if ((flags & PR_AGENT) &&
 340  340              Plwp_getspymaster(Pr, pip->pr_lwpid, &ps) == 0) {
 341  341                  time_t time = ps.pr_time.tv_sec;
 342  342                  char t[64];
 343  343  
 344  344                  (void) strftime(t, sizeof (t), "%F:%H.%M.%S", localtime(&time));
 345  345  
 346  346                  (void) printf("\tspymaster = pid %d, \"%s\" at %s\n",
 347  347                      (int)ps.pr_pid, ps.pr_psargs, t);
 348  348          }
 349  349  
 350  350          if (rflag) {
 351  351                  if (Pstate(Pr) == PS_DEAD || (arg->pflags & PR_STOPPED)) {
 352  352  #if defined(__sparc) && defined(_ILP32)
 353  353                          /*
 354  354                           * If we're SPARC/32-bit, see if we can get extra
 355  355                           * register state for this lwp.  If it's a v8plus
 356  356                           * program, print the 64-bit register values.
 357  357                           */
 358  358                          prxregset_t prx;
 359  359  
 360  360                          if (Plwp_getxregs(Pr, psp->pr_lwpid, &prx) == 0 &&
 361  361                              prx.pr_type == XR_TYPE_V8P)
 362  362                                  dumpregs_v8p(psp->pr_reg, &prx, is64);
 363  363                          else
 364  364  #endif  /* __sparc && _ILP32 */
 365  365                                  dumpregs(psp->pr_reg, is64);
 366  366                  } else
 367  367                          (void) printf("\tNot stopped, can't show registers\n");
 368  368          }
 369  369  
 370  370          return (0);
 371  371  }
 372  372  
 373  373  static char *
 374  374  prflags(int arg)
 375  375  {
 376  376          static char code_buf[200];
 377  377          char *str = code_buf;
 378  378  
 379  379          if (arg == 0)
 380  380                  return ("0");
 381  381  
 382  382          if (arg & ~ALLFLAGS)
 383  383                  (void) sprintf(str, "0x%x", arg & ~ALLFLAGS);
 384  384          else
 385  385                  *str = '\0';
 386  386  
 387  387          /*
 388  388           * Display the semi-permanent lwp flags first.
 389  389           */
 390  390          if (arg & PR_DAEMON)            /* daemons are always detached so */
 391  391                  (void) strcat(str, "|DAEMON");
 392  392          else if (arg & PR_DETACH)       /* report detach only if non-daemon */
 393  393                  (void) strcat(str, "|DETACH");
 394  394  
 395  395          if (arg & PR_STOPPED)
 396  396                  (void) strcat(str, "|STOPPED");
 397  397          if (arg & PR_ISTOP)
 398  398                  (void) strcat(str, "|ISTOP");
 399  399          if (arg & PR_DSTOP)
 400  400                  (void) strcat(str, "|DSTOP");
 401  401  #if 0           /* displayed elsewhere */
 402  402          if (arg & PR_ASLEEP)
 403  403                  (void) strcat(str, "|ASLEEP");
 404  404  #endif
 405  405          if (arg & PR_PCINVAL)
 406  406                  (void) strcat(str, "|PCINVAL");
 407  407          if (arg & PR_STEP)
 408  408                  (void) strcat(str, "|STEP");
 409  409          if (arg & PR_AGENT)
 410  410                  (void) strcat(str, "|AGENT");
 411  411          if (arg & PR_ISSYS)
 412  412                  (void) strcat(str, "|ISSYS");
 413  413          if (arg & PR_VFORKP)
 414  414                  (void) strcat(str, "|VFORKP");
 415  415          if (arg & PR_ORPHAN)
 416  416                  (void) strcat(str, "|ORPHAN");
 417  417          if (arg & PR_NOSIGCHLD)
 418  418                  (void) strcat(str, "|NOSIGCHLD");
 419  419          if (arg & PR_WAITPID)
 420  420                  (void) strcat(str, "|WAITPID");
 421  421          if (arg & PR_FORK)
 422  422                  (void) strcat(str, "|FORK");
 423  423          if (arg & PR_RLC)
 424  424                  (void) strcat(str, "|RLC");
 425  425          if (arg & PR_KLC)
 426  426                  (void) strcat(str, "|KLC");
 427  427          if (arg & PR_ASYNC)
 428  428                  (void) strcat(str, "|ASYNC");
 429  429          if (arg & PR_BPTADJ)
 430  430                  (void) strcat(str, "|BPTADJ");
 431  431          if (arg & PR_MSACCT)
 432  432                  (void) strcat(str, "|MSACCT");
 433  433          if (arg & PR_MSFORK)
 434  434                  (void) strcat(str, "|MSFORK");
 435  435          if (arg & PR_PTRACE)
 436  436                  (void) strcat(str, "|PTRACE");
 437  437  
 438  438          if (*str == '|')
 439  439                  str++;
 440  440  
 441  441          return (str);
 442  442  }
 443  443  
 444  444  static char *
 445  445  prwhy(int why)
 446  446  {
 447  447          static char buf[20];
 448  448          char *str;
 449  449  
 450  450          switch (why) {
 451  451          case PR_REQUESTED:
 452  452                  str = "PR_REQUESTED";
 453  453                  break;
 454  454          case PR_SIGNALLED:
 455  455                  str = "PR_SIGNALLED";
 456  456                  break;
 457  457          case PR_SYSENTRY:
 458  458                  str = "PR_SYSENTRY";
 459  459                  break;
 460  460          case PR_SYSEXIT:
 461  461                  str = "PR_SYSEXIT";
  
    | 
      ↓ open down ↓ | 
    423 lines elided | 
    
      ↑ open up ↑ | 
  
 462  462                  break;
 463  463          case PR_JOBCONTROL:
 464  464                  str = "PR_JOBCONTROL";
 465  465                  break;
 466  466          case PR_FAULTED:
 467  467                  str = "PR_FAULTED";
 468  468                  break;
 469  469          case PR_SUSPENDED:
 470  470                  str = "PR_SUSPENDED";
 471  471                  break;
      472 +        case PR_BRAND:
      473 +                str = "PR_BRAND";
      474 +                break;
 472  475          default:
 473  476                  str = buf;
 474  477                  (void) sprintf(str, "%d", why);
 475  478                  break;
 476  479          }
 477  480  
 478  481          return (str);
 479  482  }
 480  483  
 481  484  static char *
 482  485  prwhat(int why, int what)
 483  486  {
 484  487          static char buf[32];
 485  488          char *str;
 486  489  
 487  490          switch (why) {
 488  491          case PR_SIGNALLED:
 489  492          case PR_JOBCONTROL:
 490  493                  str = proc_signame(what, buf, sizeof (buf));
 491  494                  break;
 492  495          case PR_SYSENTRY:
 493  496          case PR_SYSEXIT:
 494  497                  str = proc_sysname(what, buf, sizeof (buf));
 495  498                  break;
 496  499          case PR_FAULTED:
 497  500                  str = proc_fltname(what, buf, sizeof (buf));
 498  501                  break;
 499  502          default:
 500  503                  (void) sprintf(str = buf, "%d", what);
 501  504                  break;
 502  505          }
 503  506  
 504  507          return (str);
 505  508  }
 506  509  
 507  510  #if defined(__sparc)
 508  511  static const char * const regname[NPRGREG] = {
 509  512          " %g0", " %g1", " %g2", " %g3", " %g4", " %g5", " %g6", " %g7",
 510  513          " %o0", " %o1", " %o2", " %o3", " %o4", " %o5", " %sp", " %o7",
 511  514          " %l0", " %l1", " %l2", " %l3", " %l4", " %l5", " %l6", " %l7",
 512  515          " %i0", " %i1", " %i2", " %i3", " %i4", " %i5", " %fp", " %i7",
 513  516  #ifdef __sparcv9
 514  517          "%ccr", " %pc", "%npc", "  %y", "%asi", "%fprs"
 515  518  #else
 516  519          "%psr", " %pc", "%npc", "  %y", "%wim", "%tbr"
 517  520  #endif
 518  521  };
 519  522  #endif  /* __sparc */
 520  523  
 521  524  #if defined(__amd64)
 522  525  static const char * const regname[NPRGREG] = {
 523  526          "%r15", "%r14", "%r13", "%r12", "%r11", "%r10", " %r9", " %r8",
 524  527          "%rdi", "%rsi", "%rbp", "%rbx", "%rdx", "%rcx", "%rax", "%trapno",
 525  528          "%err", "%rip", " %cs", "%rfl", "%rsp", " %ss", " %fs", " %gs",
 526  529          " %es", " %ds", "%fsbase", "%gsbase"
 527  530  };
 528  531  
 529  532  static const char * const regname32[NPRGREG32] = {
 530  533          " %gs", " %fs", " %es", " %ds", "%edi", "%esi", "%ebp", "%esp",
 531  534          "%ebx", "%edx", "%ecx", "%eax", "%trapno", "%err", "%eip", " %cs",
 532  535          "%efl", "%uesp", " %ss"
 533  536  };
 534  537  
 535  538  /* XX64 Do we want to expose this through libproc */
 536  539  void
 537  540  prgregset_n_to_32(const prgreg_t *src, prgreg32_t *dst)
 538  541  {
 539  542          bzero(dst, NPRGREG32 * sizeof (prgreg32_t));
 540  543          dst[GS] = src[REG_GS];
 541  544          dst[FS] = src[REG_FS];
 542  545          dst[DS] = src[REG_DS];
 543  546          dst[ES] = src[REG_ES];
 544  547          dst[EDI] = src[REG_RDI];
 545  548          dst[ESI] = src[REG_RSI];
 546  549          dst[EBP] = src[REG_RBP];
 547  550          dst[EBX] = src[REG_RBX];
 548  551          dst[EDX] = src[REG_RDX];
 549  552          dst[ECX] = src[REG_RCX];
 550  553          dst[EAX] = src[REG_RAX];
 551  554          dst[TRAPNO] = src[REG_TRAPNO];
 552  555          dst[ERR] = src[REG_ERR];
 553  556          dst[EIP] = src[REG_RIP];
 554  557          dst[CS] = src[REG_CS];
 555  558          dst[EFL] = src[REG_RFL];
 556  559          dst[UESP] = src[REG_RSP];
 557  560          dst[SS] = src[REG_SS];
 558  561  }
 559  562  
 560  563  #elif defined(__i386)
 561  564  static const char * const regname[NPRGREG] = {
 562  565          " %gs", " %fs", " %es", " %ds", "%edi", "%esi", "%ebp", "%esp",
 563  566          "%ebx", "%edx", "%ecx", "%eax", "%trapno", "%err", "%eip", " %cs",
 564  567          "%efl", "%uesp", " %ss"
 565  568  };
 566  569  #endif /* __i386 */
 567  570  
 568  571  #if defined(__amd64) && defined(_LP64)
 569  572  static void
 570  573  dumpregs32(const prgregset_t reg)
 571  574  {
 572  575          prgregset32_t reg32;
 573  576          int i;
 574  577  
 575  578          prgregset_n_to_32(reg, reg32);
 576  579  
 577  580          for (i = 0; i < NPRGREG32; i++) {
 578  581                  (void) printf("  %s = 0x%.8X",
 579  582                      regname32[i], reg32[i]);
 580  583                  if ((i+1) % 4 == 0)
 581  584                          (void) putchar('\n');
 582  585          }
 583  586          if (i % 4 != 0)
 584  587                  (void) putchar('\n');
 585  588  }
 586  589  #endif
 587  590  
 588  591  static void
 589  592  dumpregs(const prgregset_t reg, int is64)
 590  593  {
 591  594          int width = is64? 16 : 8;
 592  595          int cols = is64? 2 : 4;
 593  596          int i;
 594  597  
 595  598  #if defined(__amd64) && defined(_LP64)
 596  599          if (!is64) {
 597  600                  dumpregs32(reg);
 598  601                  return;
 599  602          }
 600  603  #endif
 601  604  
 602  605          for (i = 0; i < NPRGREG; i++) {
 603  606                  (void) printf("  %s = 0x%.*lX",
 604  607                      regname[i], width, (long)reg[i]);
 605  608                  if ((i+1) % cols == 0)
 606  609                          (void) putchar('\n');
 607  610          }
 608  611          if (i % cols != 0)
 609  612                  (void) putchar('\n');
 610  613  }
 611  614  
 612  615  #if defined(__sparc) && defined(_ILP32)
 613  616  static void
 614  617  dumpregs_v8p(const prgregset_t reg, const prxregset_t *xreg, int is64)
 615  618  {
 616  619          static const uint32_t zero[8] = { 0 };
 617  620          int gr, xr, cols = 2;
 618  621          uint64_t xval;
 619  622  
 620  623          if (memcmp(xreg->pr_un.pr_v8p.pr_xg, zero, sizeof (zero)) == 0 &&
 621  624              memcmp(xreg->pr_un.pr_v8p.pr_xo, zero, sizeof (zero)) == 0) {
 622  625                  dumpregs(reg, is64);
 623  626                  return;
 624  627          }
 625  628  
 626  629          for (gr = R_G0, xr = XR_G0; gr <= R_G7; gr++, xr++) {
 627  630                  xval = (uint64_t)xreg->pr_un.pr_v8p.pr_xg[xr] << 32 |
 628  631                      (uint64_t)(uint32_t)reg[gr];
 629  632                  (void) printf("  %s = 0x%.16" PRIX64, regname[gr], xval);
 630  633                  if ((gr + 1) % cols == 0)
 631  634                          (void) putchar('\n');
 632  635          }
 633  636  
 634  637          for (gr = R_O0, xr = XR_O0; gr <= R_O7; gr++, xr++) {
 635  638                  xval = (uint64_t)xreg->pr_un.pr_v8p.pr_xo[xr] << 32 |
 636  639                      (uint64_t)(uint32_t)reg[gr];
 637  640                  (void) printf("  %s = 0x%.16" PRIX64, regname[gr], xval);
 638  641                  if ((gr + 1) % cols == 0)
 639  642                          (void) putchar('\n');
 640  643          }
 641  644  
 642  645          for (gr = R_L0; gr < NPRGREG; gr++) {
 643  646                  (void) printf("  %s =         0x%.8lX",
 644  647                      regname[gr], (long)reg[gr]);
 645  648                  if ((gr + 1) % cols == 0)
 646  649                          (void) putchar('\n');
 647  650          }
 648  651  
 649  652          if (gr % cols != 0)
 650  653                  (void) putchar('\n');
 651  654  }
 652  655  #endif  /* __sparc && _ILP32 */
  
    | 
      ↓ open down ↓ | 
    171 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX