Print this page
    
OS-3822 OS-3780 creates a life of fd crime in libproc
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/lib/libproc/common/Pcore.c
          +++ new/usr/src/lib/libproc/common/Pcore.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]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   */
  25   25  /*
  26   26   * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
  27   27   * Copyright (c) 2014, Joyent, Inc. All rights reserved.
  28   28   * Copyright (c) 2013 by Delphix. All rights reserved.
  29   29   * Copyright 2015 Gary Mills
  30   30   */
  31   31  
  32   32  #include <sys/types.h>
  33   33  #include <sys/utsname.h>
  34   34  #include <sys/sysmacros.h>
  35   35  #include <sys/proc.h>
  36   36  
  37   37  #include <alloca.h>
  38   38  #include <rtld_db.h>
  39   39  #include <libgen.h>
  40   40  #include <limits.h>
  41   41  #include <string.h>
  42   42  #include <stdlib.h>
  43   43  #include <unistd.h>
  44   44  #include <errno.h>
  45   45  #include <gelf.h>
  46   46  #include <stddef.h>
  47   47  #include <signal.h>
  48   48  
  49   49  #include "libproc.h"
  50   50  #include "Pcontrol.h"
  51   51  #include "P32ton.h"
  52   52  #include "Putil.h"
  53   53  #ifdef __x86
  54   54  #include "Pcore_linux.h"
  55   55  #endif
  56   56  
  57   57  /*
  58   58   * Pcore.c - Code to initialize a ps_prochandle from a core dump.  We
  59   59   * allocate an additional structure to hold information from the core
  60   60   * file, and attach this to the standard ps_prochandle in place of the
  61   61   * ability to examine /proc/<pid>/ files.
  62   62   */
  63   63  
  64   64  /*
  65   65   * Basic i/o function for reading and writing from the process address space
  66   66   * stored in the core file and associated shared libraries.  We compute the
  67   67   * appropriate fd and offsets, and let the provided prw function do the rest.
  68   68   */
  69   69  static ssize_t
  70   70  core_rw(struct ps_prochandle *P, void *buf, size_t n, uintptr_t addr,
  71   71      ssize_t (*prw)(int, void *, size_t, off64_t))
  72   72  {
  73   73          ssize_t resid = n;
  74   74  
  75   75          while (resid != 0) {
  76   76                  map_info_t *mp = Paddr2mptr(P, addr);
  77   77  
  78   78                  uintptr_t mapoff;
  79   79                  ssize_t len;
  80   80                  off64_t off;
  81   81                  int fd;
  82   82  
  83   83                  if (mp == NULL)
  84   84                          break;  /* No mapping for this address */
  85   85  
  86   86                  if (mp->map_pmap.pr_mflags & MA_RESERVED1) {
  87   87                          if (mp->map_file == NULL || mp->map_file->file_fd < 0)
  88   88                                  break;  /* No file or file not open */
  89   89  
  90   90                          fd = mp->map_file->file_fd;
  91   91                  } else
  92   92                          fd = P->asfd;
  93   93  
  94   94                  mapoff = addr - mp->map_pmap.pr_vaddr;
  95   95                  len = MIN(resid, mp->map_pmap.pr_size - mapoff);
  96   96                  off = mp->map_offset + mapoff;
  97   97  
  98   98                  if ((len = prw(fd, buf, len, off)) <= 0)
  99   99                          break;
 100  100  
 101  101                  resid -= len;
 102  102                  addr += len;
 103  103                  buf = (char *)buf + len;
 104  104          }
 105  105  
 106  106          /*
 107  107           * Important: Be consistent with the behavior of i/o on the as file:
 108  108           * writing to an invalid address yields EIO; reading from an invalid
 109  109           * address falls through to returning success and zero bytes.
 110  110           */
 111  111          if (resid == n && n != 0 && prw != pread64) {
 112  112                  errno = EIO;
 113  113                  return (-1);
 114  114          }
 115  115  
 116  116          return (n - resid);
 117  117  }
 118  118  
 119  119  /*ARGSUSED*/
 120  120  static ssize_t
 121  121  Pread_core(struct ps_prochandle *P, void *buf, size_t n, uintptr_t addr,
 122  122      void *data)
 123  123  {
 124  124          return (core_rw(P, buf, n, addr, pread64));
 125  125  }
 126  126  
 127  127  /*ARGSUSED*/
 128  128  static ssize_t
 129  129  Pwrite_core(struct ps_prochandle *P, const void *buf, size_t n, uintptr_t addr,
 130  130      void *data)
 131  131  {
 132  132          return (core_rw(P, (void *)buf, n, addr,
 133  133              (ssize_t (*)(int, void *, size_t, off64_t)) pwrite64));
 134  134  }
 135  135  
 136  136  /*ARGSUSED*/
 137  137  static int
 138  138  Pcred_core(struct ps_prochandle *P, prcred_t *pcrp, int ngroups, void *data)
 139  139  {
 140  140          core_info_t *core = data;
 141  141  
 142  142          if (core->core_cred != NULL) {
 143  143                  /*
 144  144                   * Avoid returning more supplementary group data than the
 145  145                   * caller has allocated in their buffer.  We expect them to
 146  146                   * check pr_ngroups afterward and potentially call us again.
 147  147                   */
 148  148                  ngroups = MIN(ngroups, core->core_cred->pr_ngroups);
 149  149  
 150  150                  (void) memcpy(pcrp, core->core_cred,
 151  151                      sizeof (prcred_t) + (ngroups - 1) * sizeof (gid_t));
 152  152  
 153  153                  return (0);
 154  154          }
 155  155  
 156  156          errno = ENODATA;
 157  157          return (-1);
 158  158  }
 159  159  
 160  160  /*ARGSUSED*/
 161  161  static int
 162  162  Ppriv_core(struct ps_prochandle *P, prpriv_t **pprv, void *data)
 163  163  {
 164  164          core_info_t *core = data;
 165  165  
 166  166          if (core->core_priv == NULL) {
 167  167                  errno = ENODATA;
 168  168                  return (-1);
 169  169          }
 170  170  
 171  171          *pprv = malloc(core->core_priv_size);
 172  172          if (*pprv == NULL) {
 173  173                  return (-1);
 174  174          }
 175  175  
 176  176          (void) memcpy(*pprv, core->core_priv, core->core_priv_size);
 177  177          return (0);
 178  178  }
 179  179  
 180  180  /*ARGSUSED*/
 181  181  static const psinfo_t *
 182  182  Ppsinfo_core(struct ps_prochandle *P, psinfo_t *psinfo, void *data)
 183  183  {
 184  184          return (&P->psinfo);
 185  185  }
 186  186  
 187  187  /*ARGSUSED*/
 188  188  static void
 189  189  Pfini_core(struct ps_prochandle *P, void *data)
 190  190  {
 191  191          core_info_t *core = data;
 192  192  
 193  193          if (core != NULL) {
 194  194                  extern void __priv_free_info(void *);
 195  195                  lwp_info_t *nlwp, *lwp = list_next(&core->core_lwp_head);
 196  196                  int i;
 197  197  
 198  198                  for (i = 0; i < core->core_nlwp; i++, lwp = nlwp) {
 199  199                          nlwp = list_next(lwp);
 200  200  #ifdef __sparc
 201  201                          if (lwp->lwp_gwins != NULL)
 202  202                                  free(lwp->lwp_gwins);
 203  203                          if (lwp->lwp_xregs != NULL)
 204  204                                  free(lwp->lwp_xregs);
 205  205                          if (lwp->lwp_asrs != NULL)
 206  206                                  free(lwp->lwp_asrs);
 207  207  #endif
 208  208                          free(lwp);
 209  209                  }
 210  210  
 211  211                  if (core->core_platform != NULL)
 212  212                          free(core->core_platform);
 213  213                  if (core->core_uts != NULL)
 214  214                          free(core->core_uts);
 215  215                  if (core->core_cred != NULL)
 216  216                          free(core->core_cred);
 217  217                  if (core->core_priv != NULL)
 218  218                          free(core->core_priv);
 219  219                  if (core->core_privinfo != NULL)
 220  220                          __priv_free_info(core->core_privinfo);
 221  221                  if (core->core_ppii != NULL)
 222  222                          free(core->core_ppii);
 223  223                  if (core->core_zonename != NULL)
 224  224                          free(core->core_zonename);
 225  225  #ifdef __x86
 226  226                  if (core->core_ldt != NULL)
 227  227                          free(core->core_ldt);
 228  228  #endif
 229  229  
 230  230                  free(core);
 231  231          }
 232  232  }
 233  233  
 234  234  /*ARGSUSED*/
 235  235  static char *
 236  236  Pplatform_core(struct ps_prochandle *P, char *s, size_t n, void *data)
 237  237  {
 238  238          core_info_t *core = data;
 239  239  
 240  240          if (core->core_platform == NULL) {
 241  241                  errno = ENODATA;
 242  242                  return (NULL);
 243  243          }
 244  244          (void) strncpy(s, core->core_platform, n - 1);
 245  245          s[n - 1] = '\0';
 246  246          return (s);
 247  247  }
 248  248  
 249  249  /*ARGSUSED*/
 250  250  static int
 251  251  Puname_core(struct ps_prochandle *P, struct utsname *u, void *data)
 252  252  {
 253  253          core_info_t *core = data;
 254  254  
 255  255          if (core->core_uts == NULL) {
 256  256                  errno = ENODATA;
 257  257                  return (-1);
 258  258          }
 259  259          (void) memcpy(u, core->core_uts, sizeof (struct utsname));
 260  260          return (0);
 261  261  }
 262  262  
 263  263  /*ARGSUSED*/
 264  264  static char *
 265  265  Pzonename_core(struct ps_prochandle *P, char *s, size_t n, void *data)
 266  266  {
 267  267          core_info_t *core = data;
 268  268  
 269  269          if (core->core_zonename == NULL) {
 270  270                  errno = ENODATA;
 271  271                  return (NULL);
 272  272          }
 273  273          (void) strlcpy(s, core->core_zonename, n);
 274  274          return (s);
 275  275  }
 276  276  
 277  277  #ifdef __x86
 278  278  /*ARGSUSED*/
 279  279  static int
 280  280  Pldt_core(struct ps_prochandle *P, struct ssd *pldt, int nldt, void *data)
 281  281  {
 282  282          core_info_t *core = data;
 283  283  
 284  284          if (pldt == NULL || nldt == 0)
 285  285                  return (core->core_nldt);
 286  286  
 287  287          if (core->core_ldt != NULL) {
 288  288                  nldt = MIN(nldt, core->core_nldt);
 289  289  
 290  290                  (void) memcpy(pldt, core->core_ldt,
 291  291                      nldt * sizeof (struct ssd));
 292  292  
 293  293                  return (nldt);
 294  294          }
 295  295  
 296  296          errno = ENODATA;
 297  297          return (-1);
 298  298  }
 299  299  #endif
 300  300  
 301  301  static const ps_ops_t P_core_ops = {
 302  302          .pop_pread      = Pread_core,
 303  303          .pop_pwrite     = Pwrite_core,
 304  304          .pop_cred       = Pcred_core,
 305  305          .pop_priv       = Ppriv_core,
 306  306          .pop_psinfo     = Ppsinfo_core,
 307  307          .pop_fini       = Pfini_core,
 308  308          .pop_platform   = Pplatform_core,
 309  309          .pop_uname      = Puname_core,
 310  310          .pop_zonename   = Pzonename_core,
 311  311  #ifdef __x86
 312  312          .pop_ldt        = Pldt_core
 313  313  #endif
 314  314  };
 315  315  
 316  316  /*
 317  317   * Return the lwp_info_t for the given lwpid.  If no such lwpid has been
 318  318   * encountered yet, allocate a new structure and return a pointer to it.
 319  319   * Create a list of lwp_info_t structures sorted in decreasing lwp_id order.
 320  320   */
 321  321  static lwp_info_t *
 322  322  lwpid2info(struct ps_prochandle *P, lwpid_t id)
 323  323  {
 324  324          core_info_t *core = P->data;
 325  325          lwp_info_t *lwp = list_next(&core->core_lwp_head);
 326  326          lwp_info_t *next;
 327  327          uint_t i;
 328  328  
 329  329          for (i = 0; i < core->core_nlwp; i++, lwp = list_next(lwp)) {
 330  330                  if (lwp->lwp_id == id) {
 331  331                          core->core_lwp = lwp;
 332  332                          return (lwp);
 333  333                  }
 334  334                  if (lwp->lwp_id < id) {
 335  335                          break;
 336  336                  }
 337  337          }
 338  338  
 339  339          next = lwp;
 340  340          if ((lwp = calloc(1, sizeof (lwp_info_t))) == NULL)
 341  341                  return (NULL);
 342  342  
 343  343          list_link(lwp, next);
 344  344          lwp->lwp_id = id;
 345  345  
 346  346          core->core_lwp = lwp;
 347  347          core->core_nlwp++;
 348  348  
 349  349          return (lwp);
 350  350  }
 351  351  
 352  352  /*
 353  353   * The core file itself contains a series of NOTE segments containing saved
 354  354   * structures from /proc at the time the process died.  For each note we
 355  355   * comprehend, we define a function to read it in from the core file,
 356  356   * convert it to our native data model if necessary, and store it inside
 357  357   * the ps_prochandle.  Each function is invoked by Pfgrab_core() with the
 358  358   * seek pointer on P->asfd positioned appropriately.  We populate a table
 359  359   * of pointers to these note functions below.
 360  360   */
 361  361  
 362  362  static int
 363  363  note_pstatus(struct ps_prochandle *P, size_t nbytes)
 364  364  {
 365  365  #ifdef _LP64
 366  366          core_info_t *core = P->data;
 367  367  
 368  368          if (core->core_dmodel == PR_MODEL_ILP32) {
 369  369                  pstatus32_t ps32;
 370  370  
 371  371                  if (nbytes < sizeof (pstatus32_t) ||
 372  372                      read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32))
 373  373                          goto err;
 374  374  
 375  375                  pstatus_32_to_n(&ps32, &P->status);
 376  376  
 377  377          } else
 378  378  #endif
 379  379          if (nbytes < sizeof (pstatus_t) ||
 380  380              read(P->asfd, &P->status, sizeof (pstatus_t)) != sizeof (pstatus_t))
 381  381                  goto err;
 382  382  
 383  383          P->orig_status = P->status;
 384  384          P->pid = P->status.pr_pid;
 385  385  
 386  386          return (0);
 387  387  
 388  388  err:
 389  389          dprintf("Pgrab_core: failed to read NT_PSTATUS\n");
 390  390          return (-1);
 391  391  }
 392  392  
 393  393  static int
 394  394  note_lwpstatus(struct ps_prochandle *P, size_t nbytes)
 395  395  {
 396  396          lwp_info_t *lwp;
 397  397          lwpstatus_t lps;
 398  398  
 399  399  #ifdef _LP64
 400  400          core_info_t *core = P->data;
 401  401  
 402  402          if (core->core_dmodel == PR_MODEL_ILP32) {
 403  403                  lwpstatus32_t l32;
 404  404  
 405  405                  if (nbytes < sizeof (lwpstatus32_t) ||
 406  406                      read(P->asfd, &l32, sizeof (l32)) != sizeof (l32))
 407  407                          goto err;
 408  408  
 409  409                  lwpstatus_32_to_n(&l32, &lps);
 410  410          } else
 411  411  #endif
 412  412          if (nbytes < sizeof (lwpstatus_t) ||
 413  413              read(P->asfd, &lps, sizeof (lps)) != sizeof (lps))
 414  414                  goto err;
 415  415  
 416  416          if ((lwp = lwpid2info(P, lps.pr_lwpid)) == NULL) {
 417  417                  dprintf("Pgrab_core: failed to add NT_LWPSTATUS\n");
 418  418                  return (-1);
 419  419          }
 420  420  
 421  421          /*
 422  422           * Erase a useless and confusing artifact of the kernel implementation:
 423  423           * the lwps which did *not* create the core will show SIGKILL.  We can
 424  424           * be assured this is bogus because SIGKILL can't produce core files.
 425  425           */
 426  426          if (lps.pr_cursig == SIGKILL)
 427  427                  lps.pr_cursig = 0;
 428  428  
 429  429          (void) memcpy(&lwp->lwp_status, &lps, sizeof (lps));
 430  430          return (0);
 431  431  
 432  432  err:
 433  433          dprintf("Pgrab_core: failed to read NT_LWPSTATUS\n");
 434  434          return (-1);
 435  435  }
 436  436  
 437  437  #ifdef __x86
 438  438  
 439  439  static void
 440  440  lx_prpsinfo32_to_psinfo(lx_prpsinfo32_t *p32, psinfo_t *psinfo)
 441  441  {
 442  442          psinfo->pr_flag = p32->pr_flag;
 443  443          psinfo->pr_pid = p32->pr_pid;
 444  444          psinfo->pr_ppid = p32->pr_ppid;
 445  445          psinfo->pr_uid = p32->pr_uid;
 446  446          psinfo->pr_gid = p32->pr_gid;
 447  447          psinfo->pr_sid = p32->pr_sid;
 448  448          psinfo->pr_pgid = p32->pr_pgrp;
 449  449  
 450  450          (void) memcpy(psinfo->pr_fname, p32->pr_fname,
 451  451              sizeof (psinfo->pr_fname));
 452  452          (void) memcpy(psinfo->pr_psargs, p32->pr_psargs,
 453  453              sizeof (psinfo->pr_psargs));
 454  454  }
 455  455  
 456  456  static void
 457  457  lx_prpsinfo64_to_psinfo(lx_prpsinfo64_t *p64, psinfo_t *psinfo)
 458  458  {
 459  459          psinfo->pr_flag = p64->pr_flag;
 460  460          psinfo->pr_pid = p64->pr_pid;
 461  461          psinfo->pr_ppid = p64->pr_ppid;
 462  462          psinfo->pr_uid = p64->pr_uid;
 463  463          psinfo->pr_gid = p64->pr_gid;
 464  464          psinfo->pr_sid = p64->pr_sid;
 465  465          psinfo->pr_pgid = p64->pr_pgrp;
 466  466          psinfo->pr_pgid = p64->pr_pgrp;
 467  467  
 468  468          (void) memcpy(psinfo->pr_fname, p64->pr_fname,
 469  469              sizeof (psinfo->pr_fname));
 470  470          (void) memcpy(psinfo->pr_psargs, p64->pr_psargs,
 471  471              sizeof (psinfo->pr_psargs));
 472  472  }
 473  473  
 474  474  static int
 475  475  note_linux_psinfo(struct ps_prochandle *P, size_t nbytes)
 476  476  {
 477  477          core_info_t *core = P->data;
 478  478          lx_prpsinfo32_t p32;
 479  479          lx_prpsinfo64_t p64;
 480  480  
 481  481          if (core->core_dmodel == PR_MODEL_ILP32) {
 482  482                  if (nbytes < sizeof (p32) ||
 483  483                      read(P->asfd, &p32, sizeof (p32)) != sizeof (p32))
 484  484                          goto err;
 485  485  
 486  486                  lx_prpsinfo32_to_psinfo(&p32, &P->psinfo);
 487  487          } else {
 488  488                  if (nbytes < sizeof (p64) ||
 489  489                      read(P->asfd, &p64, sizeof (p64)) != sizeof (p64))
 490  490                          goto err;
 491  491  
 492  492                  lx_prpsinfo64_to_psinfo(&p64, &P->psinfo);
 493  493          }
 494  494  
 495  495  
 496  496          P->status.pr_pid = P->psinfo.pr_pid;
 497  497          P->status.pr_ppid = P->psinfo.pr_ppid;
 498  498          P->status.pr_pgid = P->psinfo.pr_pgid;
 499  499          P->status.pr_sid = P->psinfo.pr_sid;
 500  500  
 501  501          P->psinfo.pr_nlwp = 0;
 502  502          P->status.pr_nlwp = 0;
 503  503  
 504  504          return (0);
 505  505  err:
 506  506          dprintf("Pgrab_core: failed to read NT_PSINFO\n");
 507  507          return (-1);
 508  508  }
 509  509  
 510  510  static void
 511  511  lx_prstatus64_to_lwp(lx_prstatus64_t *prs64, lwp_info_t *lwp)
 512  512  {
 513  513          LTIME_TO_TIMESPEC(lwp->lwp_status.pr_utime, prs64->pr_utime);
 514  514          LTIME_TO_TIMESPEC(lwp->lwp_status.pr_stime, prs64->pr_stime);
 515  515  
 516  516          lwp->lwp_status.pr_reg[REG_R15] = prs64->pr_reg.lxr_r15;
 517  517          lwp->lwp_status.pr_reg[REG_R14] = prs64->pr_reg.lxr_r14;
 518  518          lwp->lwp_status.pr_reg[REG_R13] = prs64->pr_reg.lxr_r13;
 519  519          lwp->lwp_status.pr_reg[REG_R12] = prs64->pr_reg.lxr_r12;
 520  520          lwp->lwp_status.pr_reg[REG_R11] = prs64->pr_reg.lxr_r11;
 521  521          lwp->lwp_status.pr_reg[REG_R10] = prs64->pr_reg.lxr_r10;
 522  522          lwp->lwp_status.pr_reg[REG_R9] = prs64->pr_reg.lxr_r9;
 523  523          lwp->lwp_status.pr_reg[REG_R8] = prs64->pr_reg.lxr_r8;
 524  524  
 525  525          lwp->lwp_status.pr_reg[REG_RDI] = prs64->pr_reg.lxr_rdi;
 526  526          lwp->lwp_status.pr_reg[REG_RSI] = prs64->pr_reg.lxr_rsi;
 527  527          lwp->lwp_status.pr_reg[REG_RBP] = prs64->pr_reg.lxr_rbp;
 528  528          lwp->lwp_status.pr_reg[REG_RBX] = prs64->pr_reg.lxr_rbx;
 529  529          lwp->lwp_status.pr_reg[REG_RDX] = prs64->pr_reg.lxr_rdx;
 530  530          lwp->lwp_status.pr_reg[REG_RCX] = prs64->pr_reg.lxr_rcx;
 531  531          lwp->lwp_status.pr_reg[REG_RAX] = prs64->pr_reg.lxr_rax;
 532  532  
 533  533          lwp->lwp_status.pr_reg[REG_RIP] = prs64->pr_reg.lxr_rip;
 534  534          lwp->lwp_status.pr_reg[REG_CS] = prs64->pr_reg.lxr_cs;
 535  535          lwp->lwp_status.pr_reg[REG_RSP] = prs64->pr_reg.lxr_rsp;
 536  536          lwp->lwp_status.pr_reg[REG_FS] = prs64->pr_reg.lxr_fs;
 537  537          lwp->lwp_status.pr_reg[REG_SS] = prs64->pr_reg.lxr_ss;
 538  538          lwp->lwp_status.pr_reg[REG_GS] = prs64->pr_reg.lxr_gs;
 539  539          lwp->lwp_status.pr_reg[REG_ES] = prs64->pr_reg.lxr_es;
 540  540          lwp->lwp_status.pr_reg[REG_DS] = prs64->pr_reg.lxr_ds;
 541  541  
 542  542          lwp->lwp_status.pr_reg[REG_GSBASE] = prs64->pr_reg.lxr_gs_base;
 543  543          lwp->lwp_status.pr_reg[REG_FSBASE] = prs64->pr_reg.lxr_fs_base;
 544  544  }
 545  545  
 546  546  static void
 547  547  lx_prstatus32_to_lwp(lx_prstatus32_t *prs32, lwp_info_t *lwp)
 548  548  {
 549  549          LTIME_TO_TIMESPEC(lwp->lwp_status.pr_utime, prs32->pr_utime);
 550  550          LTIME_TO_TIMESPEC(lwp->lwp_status.pr_stime, prs32->pr_stime);
 551  551  
 552  552  #ifdef __amd64
 553  553          lwp->lwp_status.pr_reg[REG_GS] = prs32->pr_reg.lxr_gs;
 554  554          lwp->lwp_status.pr_reg[REG_FS] = prs32->pr_reg.lxr_fs;
 555  555          lwp->lwp_status.pr_reg[REG_DS] = prs32->pr_reg.lxr_ds;
 556  556          lwp->lwp_status.pr_reg[REG_ES] = prs32->pr_reg.lxr_es;
 557  557          lwp->lwp_status.pr_reg[REG_RDI] = prs32->pr_reg.lxr_di;
 558  558          lwp->lwp_status.pr_reg[REG_RSI] = prs32->pr_reg.lxr_si;
 559  559          lwp->lwp_status.pr_reg[REG_RBP] = prs32->pr_reg.lxr_bp;
 560  560          lwp->lwp_status.pr_reg[REG_RBX] = prs32->pr_reg.lxr_bx;
 561  561          lwp->lwp_status.pr_reg[REG_RDX] = prs32->pr_reg.lxr_dx;
 562  562          lwp->lwp_status.pr_reg[REG_RCX] = prs32->pr_reg.lxr_cx;
 563  563          lwp->lwp_status.pr_reg[REG_RAX] = prs32->pr_reg.lxr_ax;
 564  564          lwp->lwp_status.pr_reg[REG_RIP] = prs32->pr_reg.lxr_ip;
 565  565          lwp->lwp_status.pr_reg[REG_CS] = prs32->pr_reg.lxr_cs;
 566  566          lwp->lwp_status.pr_reg[REG_RFL] = prs32->pr_reg.lxr_flags;
 567  567          lwp->lwp_status.pr_reg[REG_RSP] = prs32->pr_reg.lxr_sp;
 568  568          lwp->lwp_status.pr_reg[REG_SS] = prs32->pr_reg.lxr_ss;
 569  569  #else /* __amd64 */
 570  570          lwp->lwp_status.pr_reg[EBX] = prs32->pr_reg.lxr_bx;
 571  571          lwp->lwp_status.pr_reg[ECX] = prs32->pr_reg.lxr_cx;
 572  572          lwp->lwp_status.pr_reg[EDX] = prs32->pr_reg.lxr_dx;
 573  573          lwp->lwp_status.pr_reg[ESI] = prs32->pr_reg.lxr_si;
 574  574          lwp->lwp_status.pr_reg[EDI] = prs32->pr_reg.lxr_di;
 575  575          lwp->lwp_status.pr_reg[EBP] = prs32->pr_reg.lxr_bp;
 576  576          lwp->lwp_status.pr_reg[EAX] = prs32->pr_reg.lxr_ax;
 577  577          lwp->lwp_status.pr_reg[EIP] = prs32->pr_reg.lxr_ip;
 578  578          lwp->lwp_status.pr_reg[UESP] = prs32->pr_reg.lxr_sp;
 579  579  
 580  580          lwp->lwp_status.pr_reg[DS] = prs32->pr_reg.lxr_ds;
 581  581          lwp->lwp_status.pr_reg[ES] = prs32->pr_reg.lxr_es;
 582  582          lwp->lwp_status.pr_reg[FS] = prs32->pr_reg.lxr_fs;
 583  583          lwp->lwp_status.pr_reg[GS] = prs32->pr_reg.lxr_gs;
 584  584          lwp->lwp_status.pr_reg[CS] = prs32->pr_reg.lxr_cs;
 585  585          lwp->lwp_status.pr_reg[SS] = prs32->pr_reg.lxr_ss;
 586  586  
 587  587          lwp->lwp_status.pr_reg[EFL] = prs32->pr_reg.lxr_flags;
 588  588  #endif  /* !__amd64 */
 589  589  }
 590  590  
 591  591  static int
 592  592  note_linux_prstatus(struct ps_prochandle *P, size_t nbytes)
 593  593  {
 594  594          core_info_t *core = P->data;
 595  595  
 596  596          lx_prstatus64_t prs64;
 597  597          lx_prstatus32_t prs32;
 598  598          lwp_info_t *lwp;
 599  599          lwpid_t tid;
 600  600  
 601  601          dprintf("looking for model %d, %ld/%ld\n", core->core_dmodel,
 602  602              (ulong_t)nbytes, (ulong_t)sizeof (prs32));
 603  603          if (core->core_dmodel == PR_MODEL_ILP32) {
 604  604                  if (nbytes < sizeof (prs32) ||
 605  605                      read(P->asfd, &prs32, sizeof (prs32)) != nbytes)
 606  606                          goto err;
 607  607                  tid = prs32.pr_pid;
 608  608          } else {
 609  609                  if (nbytes < sizeof (prs64) ||
 610  610                      read(P->asfd, &prs64, sizeof (prs64)) != nbytes)
 611  611                          goto err;
 612  612                  tid = prs64.pr_pid;
 613  613          }
 614  614  
 615  615          if ((lwp = lwpid2info(P, tid)) == NULL) {
 616  616                  dprintf("Pgrab_core: failed to add lwpid2info "
 617  617                      "linux_prstatus\n");
 618  618                  return (-1);
 619  619          }
 620  620  
 621  621          P->psinfo.pr_nlwp++;
 622  622          P->status.pr_nlwp++;
 623  623  
 624  624          lwp->lwp_status.pr_lwpid = tid;
 625  625  
 626  626          if (core->core_dmodel == PR_MODEL_ILP32)
 627  627                  lx_prstatus32_to_lwp(&prs32, lwp);
 628  628          else
 629  629                  lx_prstatus64_to_lwp(&prs64, lwp);
 630  630  
 631  631          return (0);
 632  632  err:
 633  633          dprintf("Pgrab_core: failed to read NT_PRSTATUS\n");
 634  634          return (-1);
 635  635  }
 636  636  
 637  637  #endif /* __x86 */
 638  638  
 639  639  static int
 640  640  note_psinfo(struct ps_prochandle *P, size_t nbytes)
 641  641  {
 642  642  #ifdef _LP64
 643  643          core_info_t *core = P->data;
 644  644  
 645  645          if (core->core_dmodel == PR_MODEL_ILP32) {
 646  646                  psinfo32_t ps32;
 647  647  
 648  648                  if (nbytes < sizeof (psinfo32_t) ||
 649  649                      read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32))
 650  650                          goto err;
 651  651  
 652  652                  psinfo_32_to_n(&ps32, &P->psinfo);
 653  653          } else
 654  654  #endif
 655  655          if (nbytes < sizeof (psinfo_t) ||
 656  656              read(P->asfd, &P->psinfo, sizeof (psinfo_t)) != sizeof (psinfo_t))
 657  657                  goto err;
 658  658  
 659  659          dprintf("pr_fname = <%s>\n", P->psinfo.pr_fname);
 660  660          dprintf("pr_psargs = <%s>\n", P->psinfo.pr_psargs);
 661  661          dprintf("pr_wstat = 0x%x\n", P->psinfo.pr_wstat);
 662  662  
 663  663          return (0);
 664  664  
 665  665  err:
 666  666          dprintf("Pgrab_core: failed to read NT_PSINFO\n");
 667  667          return (-1);
 668  668  }
 669  669  
 670  670  static int
 671  671  note_lwpsinfo(struct ps_prochandle *P, size_t nbytes)
 672  672  {
 673  673          lwp_info_t *lwp;
 674  674          lwpsinfo_t lps;
 675  675  
 676  676  #ifdef _LP64
 677  677          core_info_t *core = P->data;
 678  678  
 679  679          if (core->core_dmodel == PR_MODEL_ILP32) {
 680  680                  lwpsinfo32_t l32;
 681  681  
 682  682                  if (nbytes < sizeof (lwpsinfo32_t) ||
 683  683                      read(P->asfd, &l32, sizeof (l32)) != sizeof (l32))
 684  684                          goto err;
 685  685  
 686  686                  lwpsinfo_32_to_n(&l32, &lps);
 687  687          } else
 688  688  #endif
 689  689          if (nbytes < sizeof (lwpsinfo_t) ||
 690  690              read(P->asfd, &lps, sizeof (lps)) != sizeof (lps))
 691  691                  goto err;
 692  692  
 693  693          if ((lwp = lwpid2info(P, lps.pr_lwpid)) == NULL) {
 694  694                  dprintf("Pgrab_core: failed to add NT_LWPSINFO\n");
 695  695                  return (-1);
 696  696          }
 697  697  
 698  698          (void) memcpy(&lwp->lwp_psinfo, &lps, sizeof (lps));
 699  699          return (0);
 700  700  
 701  701  err:
 702  702          dprintf("Pgrab_core: failed to read NT_LWPSINFO\n");
 703  703          return (-1);
 704  704  }
 705  705  
 706  706  static int
 707  707  note_fdinfo(struct ps_prochandle *P, size_t nbytes)
 708  708  {
 709  709          prfdinfo_t prfd;
 710  710          fd_info_t *fip;
 711  711  
 712  712          if ((nbytes < sizeof (prfd)) ||
 713  713              (read(P->asfd, &prfd, sizeof (prfd)) != sizeof (prfd))) {
 714  714                  dprintf("Pgrab_core: failed to read NT_FDINFO\n");
 715  715                  return (-1);
 716  716          }
 717  717  
 718  718          if ((fip = Pfd2info(P, prfd.pr_fd)) == NULL) {
 719  719                  dprintf("Pgrab_core: failed to add NT_FDINFO\n");
 720  720                  return (-1);
 721  721          }
 722  722          (void) memcpy(&fip->fd_info, &prfd, sizeof (prfd));
 723  723          return (0);
 724  724  }
 725  725  
 726  726  static int
 727  727  note_platform(struct ps_prochandle *P, size_t nbytes)
 728  728  {
 729  729          core_info_t *core = P->data;
 730  730          char *plat;
 731  731  
 732  732          if (core->core_platform != NULL)
 733  733                  return (0);     /* Already seen */
 734  734  
 735  735          if (nbytes != 0 && ((plat = malloc(nbytes + 1)) != NULL)) {
 736  736                  if (read(P->asfd, plat, nbytes) != nbytes) {
 737  737                          dprintf("Pgrab_core: failed to read NT_PLATFORM\n");
 738  738                          free(plat);
 739  739                          return (-1);
 740  740                  }
 741  741                  plat[nbytes - 1] = '\0';
 742  742                  core->core_platform = plat;
 743  743          }
 744  744  
 745  745          return (0);
 746  746  }
 747  747  
 748  748  static int
 749  749  note_utsname(struct ps_prochandle *P, size_t nbytes)
 750  750  {
 751  751          core_info_t *core = P->data;
 752  752          size_t ubytes = sizeof (struct utsname);
 753  753          struct utsname *utsp;
 754  754  
 755  755          if (core->core_uts != NULL || nbytes < ubytes)
 756  756                  return (0);     /* Already seen or bad size */
 757  757  
 758  758          if ((utsp = malloc(ubytes)) == NULL)
 759  759                  return (-1);
 760  760  
 761  761          if (read(P->asfd, utsp, ubytes) != ubytes) {
 762  762                  dprintf("Pgrab_core: failed to read NT_UTSNAME\n");
 763  763                  free(utsp);
 764  764                  return (-1);
 765  765          }
 766  766  
 767  767          if (_libproc_debug) {
 768  768                  dprintf("uts.sysname = \"%s\"\n", utsp->sysname);
 769  769                  dprintf("uts.nodename = \"%s\"\n", utsp->nodename);
 770  770                  dprintf("uts.release = \"%s\"\n", utsp->release);
 771  771                  dprintf("uts.version = \"%s\"\n", utsp->version);
 772  772                  dprintf("uts.machine = \"%s\"\n", utsp->machine);
 773  773          }
 774  774  
 775  775          core->core_uts = utsp;
 776  776          return (0);
 777  777  }
 778  778  
 779  779  static int
 780  780  note_content(struct ps_prochandle *P, size_t nbytes)
 781  781  {
 782  782          core_info_t *core = P->data;
 783  783          core_content_t content;
 784  784  
 785  785          if (sizeof (core->core_content) != nbytes)
 786  786                  return (-1);
 787  787  
 788  788          if (read(P->asfd, &content, sizeof (content)) != sizeof (content))
 789  789                  return (-1);
 790  790  
 791  791          core->core_content = content;
 792  792  
 793  793          dprintf("core content = %llx\n", content);
 794  794  
 795  795          return (0);
 796  796  }
 797  797  
 798  798  static int
 799  799  note_cred(struct ps_prochandle *P, size_t nbytes)
 800  800  {
 801  801          core_info_t *core = P->data;
 802  802          prcred_t *pcrp;
 803  803          int ngroups;
 804  804          const size_t min_size = sizeof (prcred_t) - sizeof (gid_t);
 805  805  
 806  806          /*
 807  807           * We allow for prcred_t notes that are actually smaller than a
 808  808           * prcred_t since the last member isn't essential if there are
 809  809           * no group memberships. This allows for more flexibility when it
 810  810           * comes to slightly malformed -- but still valid -- notes.
 811  811           */
 812  812          if (core->core_cred != NULL || nbytes < min_size)
 813  813                  return (0);     /* Already seen or bad size */
 814  814  
 815  815          ngroups = (nbytes - min_size) / sizeof (gid_t);
 816  816          nbytes = sizeof (prcred_t) + (ngroups - 1) * sizeof (gid_t);
 817  817  
 818  818          if ((pcrp = malloc(nbytes)) == NULL)
 819  819                  return (-1);
 820  820  
 821  821          if (read(P->asfd, pcrp, nbytes) != nbytes) {
 822  822                  dprintf("Pgrab_core: failed to read NT_PRCRED\n");
 823  823                  free(pcrp);
 824  824                  return (-1);
 825  825          }
 826  826  
 827  827          if (pcrp->pr_ngroups > ngroups) {
 828  828                  dprintf("pr_ngroups = %d; resetting to %d based on note size\n",
 829  829                      pcrp->pr_ngroups, ngroups);
 830  830                  pcrp->pr_ngroups = ngroups;
 831  831          }
 832  832  
 833  833          core->core_cred = pcrp;
 834  834          return (0);
 835  835  }
 836  836  
 837  837  #ifdef __x86
 838  838  static int
 839  839  note_ldt(struct ps_prochandle *P, size_t nbytes)
 840  840  {
 841  841          core_info_t *core = P->data;
 842  842          struct ssd *pldt;
 843  843          uint_t nldt;
 844  844  
 845  845          if (core->core_ldt != NULL || nbytes < sizeof (struct ssd))
 846  846                  return (0);     /* Already seen or bad size */
 847  847  
 848  848          nldt = nbytes / sizeof (struct ssd);
 849  849          nbytes = nldt * sizeof (struct ssd);
 850  850  
 851  851          if ((pldt = malloc(nbytes)) == NULL)
 852  852                  return (-1);
 853  853  
 854  854          if (read(P->asfd, pldt, nbytes) != nbytes) {
 855  855                  dprintf("Pgrab_core: failed to read NT_LDT\n");
 856  856                  free(pldt);
 857  857                  return (-1);
 858  858          }
 859  859  
 860  860          core->core_ldt = pldt;
 861  861          core->core_nldt = nldt;
 862  862          return (0);
 863  863  }
 864  864  #endif  /* __i386 */
 865  865  
 866  866  static int
 867  867  note_priv(struct ps_prochandle *P, size_t nbytes)
 868  868  {
 869  869          core_info_t *core = P->data;
 870  870          prpriv_t *pprvp;
 871  871  
 872  872          if (core->core_priv != NULL || nbytes < sizeof (prpriv_t))
 873  873                  return (0);     /* Already seen or bad size */
 874  874  
 875  875          if ((pprvp = malloc(nbytes)) == NULL)
 876  876                  return (-1);
 877  877  
 878  878          if (read(P->asfd, pprvp, nbytes) != nbytes) {
 879  879                  dprintf("Pgrab_core: failed to read NT_PRPRIV\n");
 880  880                  free(pprvp);
 881  881                  return (-1);
 882  882          }
 883  883  
 884  884          core->core_priv = pprvp;
 885  885          core->core_priv_size = nbytes;
 886  886          return (0);
 887  887  }
 888  888  
 889  889  static int
 890  890  note_priv_info(struct ps_prochandle *P, size_t nbytes)
 891  891  {
 892  892          core_info_t *core = P->data;
 893  893          extern void *__priv_parse_info();
 894  894          priv_impl_info_t *ppii;
 895  895  
 896  896          if (core->core_privinfo != NULL ||
 897  897              nbytes < sizeof (priv_impl_info_t))
 898  898                  return (0);     /* Already seen or bad size */
 899  899  
 900  900          if ((ppii = malloc(nbytes)) == NULL)
 901  901                  return (-1);
 902  902  
 903  903          if (read(P->asfd, ppii, nbytes) != nbytes ||
 904  904              PRIV_IMPL_INFO_SIZE(ppii) != nbytes) {
 905  905                  dprintf("Pgrab_core: failed to read NT_PRPRIVINFO\n");
 906  906                  free(ppii);
 907  907                  return (-1);
 908  908          }
 909  909  
 910  910          core->core_privinfo = __priv_parse_info(ppii);
 911  911          core->core_ppii = ppii;
 912  912          return (0);
 913  913  }
 914  914  
 915  915  static int
 916  916  note_zonename(struct ps_prochandle *P, size_t nbytes)
 917  917  {
 918  918          core_info_t *core = P->data;
 919  919          char *zonename;
 920  920  
 921  921          if (core->core_zonename != NULL)
 922  922                  return (0);     /* Already seen */
 923  923  
 924  924          if (nbytes != 0) {
 925  925                  if ((zonename = malloc(nbytes)) == NULL)
 926  926                          return (-1);
 927  927                  if (read(P->asfd, zonename, nbytes) != nbytes) {
 928  928                          dprintf("Pgrab_core: failed to read NT_ZONENAME\n");
 929  929                          free(zonename);
 930  930                          return (-1);
 931  931                  }
 932  932                  zonename[nbytes - 1] = '\0';
 933  933                  core->core_zonename = zonename;
 934  934          }
 935  935  
 936  936          return (0);
 937  937  }
 938  938  
 939  939  static int
 940  940  note_auxv(struct ps_prochandle *P, size_t nbytes)
 941  941  {
 942  942          size_t n, i;
 943  943  
 944  944  #ifdef _LP64
 945  945          core_info_t *core = P->data;
 946  946  
 947  947          if (core->core_dmodel == PR_MODEL_ILP32) {
 948  948                  auxv32_t *a32;
 949  949  
 950  950                  n = nbytes / sizeof (auxv32_t);
 951  951                  nbytes = n * sizeof (auxv32_t);
 952  952                  a32 = alloca(nbytes);
 953  953  
 954  954                  if (read(P->asfd, a32, nbytes) != nbytes) {
 955  955                          dprintf("Pgrab_core: failed to read NT_AUXV\n");
 956  956                          return (-1);
 957  957                  }
 958  958  
 959  959                  if ((P->auxv = malloc(sizeof (auxv_t) * (n + 1))) == NULL)
 960  960                          return (-1);
 961  961  
 962  962                  for (i = 0; i < n; i++)
 963  963                          auxv_32_to_n(&a32[i], &P->auxv[i]);
 964  964  
 965  965          } else {
 966  966  #endif
 967  967                  n = nbytes / sizeof (auxv_t);
 968  968                  nbytes = n * sizeof (auxv_t);
 969  969  
 970  970                  if ((P->auxv = malloc(nbytes + sizeof (auxv_t))) == NULL)
 971  971                          return (-1);
 972  972  
 973  973                  if (read(P->asfd, P->auxv, nbytes) != nbytes) {
 974  974                          free(P->auxv);
 975  975                          P->auxv = NULL;
 976  976                          return (-1);
 977  977                  }
 978  978  #ifdef _LP64
 979  979          }
 980  980  #endif
 981  981  
 982  982          if (_libproc_debug) {
 983  983                  for (i = 0; i < n; i++) {
 984  984                          dprintf("P->auxv[%lu] = ( %d, 0x%lx )\n", (ulong_t)i,
 985  985                              P->auxv[i].a_type, P->auxv[i].a_un.a_val);
 986  986                  }
 987  987          }
 988  988  
 989  989          /*
 990  990           * Defensive coding for loops which depend upon the auxv array being
 991  991           * terminated by an AT_NULL element; in each case, we've allocated
 992  992           * P->auxv to have an additional element which we force to be AT_NULL.
 993  993           */
 994  994          P->auxv[n].a_type = AT_NULL;
 995  995          P->auxv[n].a_un.a_val = 0L;
 996  996          P->nauxv = (int)n;
 997  997  
 998  998          return (0);
 999  999  }
1000 1000  
1001 1001  #ifdef __sparc
1002 1002  static int
1003 1003  note_xreg(struct ps_prochandle *P, size_t nbytes)
1004 1004  {
1005 1005          core_info_t *core = P->data;
1006 1006          lwp_info_t *lwp = core->core_lwp;
1007 1007          size_t xbytes = sizeof (prxregset_t);
1008 1008          prxregset_t *xregs;
1009 1009  
1010 1010          if (lwp == NULL || lwp->lwp_xregs != NULL || nbytes < xbytes)
1011 1011                  return (0);     /* No lwp yet, already seen, or bad size */
1012 1012  
1013 1013          if ((xregs = malloc(xbytes)) == NULL)
1014 1014                  return (-1);
1015 1015  
1016 1016          if (read(P->asfd, xregs, xbytes) != xbytes) {
1017 1017                  dprintf("Pgrab_core: failed to read NT_PRXREG\n");
1018 1018                  free(xregs);
1019 1019                  return (-1);
1020 1020          }
1021 1021  
1022 1022          lwp->lwp_xregs = xregs;
1023 1023          return (0);
1024 1024  }
1025 1025  
1026 1026  static int
1027 1027  note_gwindows(struct ps_prochandle *P, size_t nbytes)
1028 1028  {
1029 1029          core_info_t *core = P->data;
1030 1030          lwp_info_t *lwp = core->core_lwp;
1031 1031  
1032 1032          if (lwp == NULL || lwp->lwp_gwins != NULL || nbytes == 0)
1033 1033                  return (0);     /* No lwp yet or already seen or no data */
1034 1034  
1035 1035          if ((lwp->lwp_gwins = malloc(sizeof (gwindows_t))) == NULL)
1036 1036                  return (-1);
1037 1037  
1038 1038          /*
1039 1039           * Since the amount of gwindows data varies with how many windows were
1040 1040           * actually saved, we just read up to the minimum of the note size
1041 1041           * and the size of the gwindows_t type.  It doesn't matter if the read
1042 1042           * fails since we have to zero out gwindows first anyway.
1043 1043           */
1044 1044  #ifdef _LP64
1045 1045          if (core->core_dmodel == PR_MODEL_ILP32) {
1046 1046                  gwindows32_t g32;
1047 1047  
1048 1048                  (void) memset(&g32, 0, sizeof (g32));
1049 1049                  (void) read(P->asfd, &g32, MIN(nbytes, sizeof (g32)));
1050 1050                  gwindows_32_to_n(&g32, lwp->lwp_gwins);
1051 1051  
1052 1052          } else {
1053 1053  #endif
1054 1054                  (void) memset(lwp->lwp_gwins, 0, sizeof (gwindows_t));
1055 1055                  (void) read(P->asfd, lwp->lwp_gwins,
1056 1056                      MIN(nbytes, sizeof (gwindows_t)));
1057 1057  #ifdef _LP64
1058 1058          }
1059 1059  #endif
1060 1060          return (0);
1061 1061  }
1062 1062  
1063 1063  #ifdef __sparcv9
1064 1064  static int
1065 1065  note_asrs(struct ps_prochandle *P, size_t nbytes)
1066 1066  {
1067 1067          core_info_t *core = P->data;
1068 1068          lwp_info_t *lwp = core->core_lwp;
1069 1069          int64_t *asrs;
1070 1070  
1071 1071          if (lwp == NULL || lwp->lwp_asrs != NULL || nbytes < sizeof (asrset_t))
1072 1072                  return (0);     /* No lwp yet, already seen, or bad size */
1073 1073  
1074 1074          if ((asrs = malloc(sizeof (asrset_t))) == NULL)
1075 1075                  return (-1);
1076 1076  
1077 1077          if (read(P->asfd, asrs, sizeof (asrset_t)) != sizeof (asrset_t)) {
1078 1078                  dprintf("Pgrab_core: failed to read NT_ASRS\n");
1079 1079                  free(asrs);
1080 1080                  return (-1);
1081 1081          }
1082 1082  
1083 1083          lwp->lwp_asrs = asrs;
1084 1084          return (0);
1085 1085  }
1086 1086  #endif  /* __sparcv9 */
1087 1087  #endif  /* __sparc */
1088 1088  
1089 1089  static int
1090 1090  note_spymaster(struct ps_prochandle *P, size_t nbytes)
1091 1091  {
1092 1092  #ifdef _LP64
1093 1093          core_info_t *core = P->data;
1094 1094  
1095 1095          if (core->core_dmodel == PR_MODEL_ILP32) {
1096 1096                  psinfo32_t ps32;
1097 1097  
1098 1098                  if (nbytes < sizeof (psinfo32_t) ||
1099 1099                      read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32))
1100 1100                          goto err;
1101 1101  
1102 1102                  psinfo_32_to_n(&ps32, &P->spymaster);
1103 1103          } else
1104 1104  #endif
1105 1105          if (nbytes < sizeof (psinfo_t) || read(P->asfd,
1106 1106              &P->spymaster, sizeof (psinfo_t)) != sizeof (psinfo_t))
1107 1107                  goto err;
1108 1108  
1109 1109          dprintf("spymaster pr_fname = <%s>\n", P->psinfo.pr_fname);
1110 1110          dprintf("spymaster pr_psargs = <%s>\n", P->psinfo.pr_psargs);
1111 1111          dprintf("spymaster pr_wstat = 0x%x\n", P->psinfo.pr_wstat);
1112 1112  
1113 1113          return (0);
1114 1114  
1115 1115  err:
1116 1116          dprintf("Pgrab_core: failed to read NT_SPYMASTER\n");
1117 1117          return (-1);
1118 1118  }
1119 1119  
1120 1120  /*ARGSUSED*/
1121 1121  static int
1122 1122  note_notsup(struct ps_prochandle *P, size_t nbytes)
1123 1123  {
1124 1124          dprintf("skipping unsupported note type of size %ld bytes\n",
1125 1125              (ulong_t)nbytes);
1126 1126          return (0);
1127 1127  }
1128 1128  
1129 1129  /*
1130 1130   * Populate a table of function pointers indexed by Note type with our
1131 1131   * functions to process each type of core file note:
1132 1132   */
1133 1133  static int (*nhdlrs[])(struct ps_prochandle *, size_t) = {
1134 1134          note_notsup,            /*  0   unassigned              */
1135 1135  #ifdef __x86
1136 1136          note_linux_prstatus,            /*  1   NT_PRSTATUS (old)       */
1137 1137  #else
1138 1138          note_notsup,            /*  1   NT_PRSTATUS (old)       */
1139 1139  #endif
1140 1140          note_notsup,            /*  2   NT_PRFPREG (old)        */
1141 1141  #ifdef __x86
1142 1142          note_linux_psinfo,              /*  3   NT_PRPSINFO (old)       */
1143 1143  #else
1144 1144          note_notsup,            /*  3   NT_PRPSINFO (old)       */
1145 1145  #endif
1146 1146  #ifdef __sparc
1147 1147          note_xreg,              /*  4   NT_PRXREG               */
1148 1148  #else
1149 1149          note_notsup,            /*  4   NT_PRXREG               */
1150 1150  #endif
1151 1151          note_platform,          /*  5   NT_PLATFORM             */
1152 1152          note_auxv,              /*  6   NT_AUXV                 */
1153 1153  #ifdef __sparc
1154 1154          note_gwindows,          /*  7   NT_GWINDOWS             */
1155 1155  #ifdef __sparcv9
1156 1156          note_asrs,              /*  8   NT_ASRS                 */
1157 1157  #else
1158 1158          note_notsup,            /*  8   NT_ASRS                 */
1159 1159  #endif
1160 1160  #else
1161 1161          note_notsup,            /*  7   NT_GWINDOWS             */
1162 1162          note_notsup,            /*  8   NT_ASRS                 */
1163 1163  #endif
1164 1164  #ifdef __x86
1165 1165          note_ldt,               /*  9   NT_LDT                  */
1166 1166  #else
1167 1167          note_notsup,            /*  9   NT_LDT                  */
1168 1168  #endif
1169 1169          note_pstatus,           /* 10   NT_PSTATUS              */
1170 1170          note_notsup,            /* 11   unassigned              */
1171 1171          note_notsup,            /* 12   unassigned              */
1172 1172          note_psinfo,            /* 13   NT_PSINFO               */
1173 1173          note_cred,              /* 14   NT_PRCRED               */
1174 1174          note_utsname,           /* 15   NT_UTSNAME              */
1175 1175          note_lwpstatus,         /* 16   NT_LWPSTATUS            */
1176 1176          note_lwpsinfo,          /* 17   NT_LWPSINFO             */
1177 1177          note_priv,              /* 18   NT_PRPRIV               */
1178 1178          note_priv_info,         /* 19   NT_PRPRIVINFO           */
1179 1179          note_content,           /* 20   NT_CONTENT              */
1180 1180          note_zonename,          /* 21   NT_ZONENAME             */
1181 1181          note_fdinfo,            /* 22   NT_FDINFO               */
1182 1182          note_spymaster,         /* 23   NT_SPYMASTER            */
1183 1183  };
1184 1184  
1185 1185  static void
1186 1186  core_report_mapping(struct ps_prochandle *P, GElf_Phdr *php)
1187 1187  {
1188 1188          prkillinfo_t killinfo;
1189 1189          siginfo_t *si = &killinfo.prk_info;
1190 1190          char signame[SIG2STR_MAX], sig[64], info[64];
1191 1191          void *addr = (void *)(uintptr_t)php->p_vaddr;
1192 1192  
1193 1193          const char *errfmt = "core file data for mapping at %p not saved: %s\n";
1194 1194          const char *incfmt = "core file incomplete due to %s%s\n";
1195 1195          const char *msgfmt = "mappings at and above %p are missing\n";
1196 1196  
1197 1197          if (!(php->p_flags & PF_SUNW_KILLED)) {
1198 1198                  int err = 0;
1199 1199  
1200 1200                  (void) pread64(P->asfd, &err,
1201 1201                      sizeof (err), (off64_t)php->p_offset);
1202 1202  
1203 1203                  Perror_printf(P, errfmt, addr, strerror(err));
1204 1204                  dprintf(errfmt, addr, strerror(err));
1205 1205                  return;
1206 1206          }
1207 1207  
1208 1208          if (!(php->p_flags & PF_SUNW_SIGINFO))
1209 1209                  return;
1210 1210  
1211 1211          (void) memset(&killinfo, 0, sizeof (killinfo));
1212 1212  
1213 1213          (void) pread64(P->asfd, &killinfo,
1214 1214              sizeof (killinfo), (off64_t)php->p_offset);
1215 1215  
1216 1216          /*
1217 1217           * While there is (or at least should be) only one segment that has
1218 1218           * PF_SUNW_SIGINFO set, the signal information there is globally
1219 1219           * useful (even if only to those debugging libproc consumers); we hang
1220 1220           * the signal information gleaned here off of the ps_prochandle.
1221 1221           */
1222 1222          P->map_missing = php->p_vaddr;
1223 1223          P->killinfo = killinfo.prk_info;
1224 1224  
1225 1225          if (sig2str(si->si_signo, signame) == -1) {
1226 1226                  (void) snprintf(sig, sizeof (sig),
1227 1227                      "<Unknown signal: 0x%x>, ", si->si_signo);
1228 1228          } else {
1229 1229                  (void) snprintf(sig, sizeof (sig), "SIG%s, ", signame);
1230 1230          }
1231 1231  
1232 1232          if (si->si_code == SI_USER || si->si_code == SI_QUEUE) {
1233 1233                  (void) snprintf(info, sizeof (info),
1234 1234                      "pid=%d uid=%d zone=%d ctid=%d",
1235 1235                      si->si_pid, si->si_uid, si->si_zoneid, si->si_ctid);
1236 1236          } else {
1237 1237                  (void) snprintf(info, sizeof (info),
1238 1238                      "code=%d", si->si_code);
1239 1239          }
1240 1240  
1241 1241          Perror_printf(P, incfmt, sig, info);
1242 1242          Perror_printf(P, msgfmt, addr);
1243 1243  
1244 1244          dprintf(incfmt, sig, info);
1245 1245          dprintf(msgfmt, addr);
1246 1246  }
1247 1247  
1248 1248  /*
1249 1249   * Add information on the address space mapping described by the given
1250 1250   * PT_LOAD program header.  We fill in more information on the mapping later.
1251 1251   */
1252 1252  static int
1253 1253  core_add_mapping(struct ps_prochandle *P, GElf_Phdr *php)
1254 1254  {
1255 1255          core_info_t *core = P->data;
1256 1256          prmap_t pmap;
1257 1257  
1258 1258          dprintf("mapping base %llx filesz %llx memsz %llx offset %llx\n",
1259 1259              (u_longlong_t)php->p_vaddr, (u_longlong_t)php->p_filesz,
1260 1260              (u_longlong_t)php->p_memsz, (u_longlong_t)php->p_offset);
1261 1261  
1262 1262          pmap.pr_vaddr = (uintptr_t)php->p_vaddr;
1263 1263          pmap.pr_size = php->p_memsz;
1264 1264  
1265 1265          /*
1266 1266           * If Pgcore() or elfcore() fail to write a mapping, they will set
1267 1267           * PF_SUNW_FAILURE in the Phdr and try to stash away the errno for us.
1268 1268           */
1269 1269          if (php->p_flags & PF_SUNW_FAILURE) {
1270 1270                  core_report_mapping(P, php);
1271 1271          } else if (php->p_filesz != 0 && php->p_offset >= core->core_size) {
1272 1272                  Perror_printf(P, "core file may be corrupt -- data for mapping "
1273 1273                      "at %p is missing\n", (void *)(uintptr_t)php->p_vaddr);
1274 1274                  dprintf("core file may be corrupt -- data for mapping "
1275 1275                      "at %p is missing\n", (void *)(uintptr_t)php->p_vaddr);
1276 1276          }
1277 1277  
1278 1278          /*
1279 1279           * The mapping name and offset will hopefully be filled in
1280 1280           * by the librtld_db agent.  Unfortunately, if it isn't a
1281 1281           * shared library mapping, this information is gone forever.
1282 1282           */
1283 1283          pmap.pr_mapname[0] = '\0';
1284 1284          pmap.pr_offset = 0;
1285 1285  
1286 1286          pmap.pr_mflags = 0;
1287 1287          if (php->p_flags & PF_R)
1288 1288                  pmap.pr_mflags |= MA_READ;
1289 1289          if (php->p_flags & PF_W)
1290 1290                  pmap.pr_mflags |= MA_WRITE;
1291 1291          if (php->p_flags & PF_X)
1292 1292                  pmap.pr_mflags |= MA_EXEC;
1293 1293  
1294 1294          if (php->p_filesz == 0)
1295 1295                  pmap.pr_mflags |= MA_RESERVED1;
1296 1296  
1297 1297          /*
1298 1298           * At the time of adding this mapping, we just zero the pagesize.
1299 1299           * Once we've processed more of the core file, we'll have the
1300 1300           * pagesize from the auxv's AT_PAGESZ element and we can fill this in.
1301 1301           */
1302 1302          pmap.pr_pagesize = 0;
1303 1303  
1304 1304          /*
1305 1305           * Unfortunately whether or not the mapping was a System V
1306 1306           * shared memory segment is lost.  We use -1 to mark it as not shm.
1307 1307           */
1308 1308          pmap.pr_shmid = -1;
1309 1309  
1310 1310          return (Padd_mapping(P, php->p_offset, NULL, &pmap));
1311 1311  }
1312 1312  
1313 1313  /*
1314 1314   * Given a virtual address, name the mapping at that address using the
1315 1315   * specified name, and return the map_info_t pointer.
1316 1316   */
1317 1317  static map_info_t *
1318 1318  core_name_mapping(struct ps_prochandle *P, uintptr_t addr, const char *name)
1319 1319  {
1320 1320          map_info_t *mp = Paddr2mptr(P, addr);
1321 1321  
1322 1322          if (mp != NULL) {
1323 1323                  (void) strncpy(mp->map_pmap.pr_mapname, name, PRMAPSZ);
1324 1324                  mp->map_pmap.pr_mapname[PRMAPSZ - 1] = '\0';
1325 1325          }
1326 1326  
1327 1327          return (mp);
1328 1328  }
1329 1329  
1330 1330  /*
1331 1331   * libproc uses libelf for all of its symbol table manipulation. This function
1332 1332   * takes a symbol table and string table from a core file and places them
1333 1333   * in a memory backed elf file.
1334 1334   */
1335 1335  static void
1336 1336  fake_up_symtab(struct ps_prochandle *P, const elf_file_header_t *ehdr,
1337 1337      GElf_Shdr *symtab, GElf_Shdr *strtab)
1338 1338  {
1339 1339          size_t size;
1340 1340          off64_t off, base;
1341 1341          map_info_t *mp;
1342 1342          file_info_t *fp;
1343 1343          Elf_Scn *scn;
1344 1344          Elf_Data *data;
1345 1345  
1346 1346          if (symtab->sh_addr == 0 ||
1347 1347              (mp = Paddr2mptr(P, symtab->sh_addr)) == NULL ||
1348 1348              (fp = mp->map_file) == NULL) {
1349 1349                  dprintf("fake_up_symtab: invalid section\n");
1350 1350                  return;
1351 1351          }
1352 1352  
1353 1353          if (fp->file_symtab.sym_data_pri != NULL) {
1354 1354                  dprintf("Symbol table already loaded (sh_addr 0x%lx)\n",
1355 1355                      (long)symtab->sh_addr);
1356 1356                  return;
1357 1357          }
1358 1358  
1359 1359          if (P->status.pr_dmodel == PR_MODEL_ILP32) {
1360 1360                  struct {
1361 1361                          Elf32_Ehdr ehdr;
1362 1362                          Elf32_Shdr shdr[3];
1363 1363                          char data[1];
1364 1364                  } *b;
1365 1365  
1366 1366                  base = sizeof (b->ehdr) + sizeof (b->shdr);
1367 1367                  size = base + symtab->sh_size + strtab->sh_size;
1368 1368  
1369 1369                  if ((b = calloc(1, size)) == NULL)
1370 1370                          return;
1371 1371  
1372 1372                  (void) memcpy(b->ehdr.e_ident, ehdr->e_ident,
1373 1373                      sizeof (ehdr->e_ident));
1374 1374                  b->ehdr.e_type = ehdr->e_type;
1375 1375                  b->ehdr.e_machine = ehdr->e_machine;
1376 1376                  b->ehdr.e_version = ehdr->e_version;
1377 1377                  b->ehdr.e_flags = ehdr->e_flags;
1378 1378                  b->ehdr.e_ehsize = sizeof (b->ehdr);
1379 1379                  b->ehdr.e_shoff = sizeof (b->ehdr);
1380 1380                  b->ehdr.e_shentsize = sizeof (b->shdr[0]);
1381 1381                  b->ehdr.e_shnum = 3;
1382 1382                  off = 0;
1383 1383  
1384 1384                  b->shdr[1].sh_size = symtab->sh_size;
1385 1385                  b->shdr[1].sh_type = SHT_SYMTAB;
1386 1386                  b->shdr[1].sh_offset = off + base;
1387 1387                  b->shdr[1].sh_entsize = sizeof (Elf32_Sym);
1388 1388                  b->shdr[1].sh_link = 2;
1389 1389                  b->shdr[1].sh_info =  symtab->sh_info;
1390 1390                  b->shdr[1].sh_addralign = symtab->sh_addralign;
1391 1391  
1392 1392                  if (pread64(P->asfd, &b->data[off], b->shdr[1].sh_size,
1393 1393                      symtab->sh_offset) != b->shdr[1].sh_size) {
1394 1394                          dprintf("fake_up_symtab: pread of symtab[1] failed\n");
1395 1395                          free(b);
1396 1396                          return;
1397 1397                  }
1398 1398  
1399 1399                  off += b->shdr[1].sh_size;
1400 1400  
1401 1401                  b->shdr[2].sh_flags = SHF_STRINGS;
1402 1402                  b->shdr[2].sh_size = strtab->sh_size;
1403 1403                  b->shdr[2].sh_type = SHT_STRTAB;
1404 1404                  b->shdr[2].sh_offset = off + base;
1405 1405                  b->shdr[2].sh_info =  strtab->sh_info;
1406 1406                  b->shdr[2].sh_addralign = 1;
1407 1407  
1408 1408                  if (pread64(P->asfd, &b->data[off], b->shdr[2].sh_size,
1409 1409                      strtab->sh_offset) != b->shdr[2].sh_size) {
1410 1410                          dprintf("fake_up_symtab: pread of symtab[2] failed\n");
1411 1411                          free(b);
1412 1412                          return;
1413 1413                  }
1414 1414  
1415 1415                  off += b->shdr[2].sh_size;
1416 1416  
1417 1417                  fp->file_symtab.sym_elf = elf_memory((char *)b, size);
1418 1418                  if (fp->file_symtab.sym_elf == NULL) {
1419 1419                          free(b);
1420 1420                          return;
1421 1421                  }
1422 1422  
1423 1423                  fp->file_symtab.sym_elfmem = b;
1424 1424  #ifdef _LP64
1425 1425          } else {
1426 1426                  struct {
1427 1427                          Elf64_Ehdr ehdr;
1428 1428                          Elf64_Shdr shdr[3];
1429 1429                          char data[1];
1430 1430                  } *b;
1431 1431  
1432 1432                  base = sizeof (b->ehdr) + sizeof (b->shdr);
1433 1433                  size = base + symtab->sh_size + strtab->sh_size;
1434 1434  
1435 1435                  if ((b = calloc(1, size)) == NULL)
1436 1436                          return;
1437 1437  
1438 1438                  (void) memcpy(b->ehdr.e_ident, ehdr->e_ident,
1439 1439                      sizeof (ehdr->e_ident));
1440 1440                  b->ehdr.e_type = ehdr->e_type;
1441 1441                  b->ehdr.e_machine = ehdr->e_machine;
1442 1442                  b->ehdr.e_version = ehdr->e_version;
1443 1443                  b->ehdr.e_flags = ehdr->e_flags;
1444 1444                  b->ehdr.e_ehsize = sizeof (b->ehdr);
1445 1445                  b->ehdr.e_shoff = sizeof (b->ehdr);
1446 1446                  b->ehdr.e_shentsize = sizeof (b->shdr[0]);
1447 1447                  b->ehdr.e_shnum = 3;
1448 1448                  off = 0;
1449 1449  
1450 1450                  b->shdr[1].sh_size = symtab->sh_size;
1451 1451                  b->shdr[1].sh_type = SHT_SYMTAB;
1452 1452                  b->shdr[1].sh_offset = off + base;
1453 1453                  b->shdr[1].sh_entsize = sizeof (Elf64_Sym);
1454 1454                  b->shdr[1].sh_link = 2;
1455 1455                  b->shdr[1].sh_info =  symtab->sh_info;
1456 1456                  b->shdr[1].sh_addralign = symtab->sh_addralign;
1457 1457  
1458 1458                  if (pread64(P->asfd, &b->data[off], b->shdr[1].sh_size,
1459 1459                      symtab->sh_offset) != b->shdr[1].sh_size) {
1460 1460                          free(b);
1461 1461                          return;
1462 1462                  }
1463 1463  
1464 1464                  off += b->shdr[1].sh_size;
1465 1465  
1466 1466                  b->shdr[2].sh_flags = SHF_STRINGS;
1467 1467                  b->shdr[2].sh_size = strtab->sh_size;
1468 1468                  b->shdr[2].sh_type = SHT_STRTAB;
1469 1469                  b->shdr[2].sh_offset = off + base;
1470 1470                  b->shdr[2].sh_info =  strtab->sh_info;
1471 1471                  b->shdr[2].sh_addralign = 1;
1472 1472  
1473 1473                  if (pread64(P->asfd, &b->data[off], b->shdr[2].sh_size,
1474 1474                      strtab->sh_offset) != b->shdr[2].sh_size) {
1475 1475                          free(b);
1476 1476                          return;
1477 1477                  }
1478 1478  
1479 1479                  off += b->shdr[2].sh_size;
1480 1480  
1481 1481                  fp->file_symtab.sym_elf = elf_memory((char *)b, size);
1482 1482                  if (fp->file_symtab.sym_elf == NULL) {
1483 1483                          free(b);
1484 1484                          return;
1485 1485                  }
1486 1486  
1487 1487                  fp->file_symtab.sym_elfmem = b;
1488 1488  #endif
1489 1489          }
1490 1490  
1491 1491          if ((scn = elf_getscn(fp->file_symtab.sym_elf, 1)) == NULL ||
1492 1492              (fp->file_symtab.sym_data_pri = elf_getdata(scn, NULL)) == NULL ||
1493 1493              (scn = elf_getscn(fp->file_symtab.sym_elf, 2)) == NULL ||
1494 1494              (data = elf_getdata(scn, NULL)) == NULL) {
1495 1495                  dprintf("fake_up_symtab: failed to get section data at %p\n",
1496 1496                      (void *)scn);
1497 1497                  goto err;
1498 1498          }
1499 1499  
1500 1500          fp->file_symtab.sym_strs = data->d_buf;
1501 1501          fp->file_symtab.sym_strsz = data->d_size;
1502 1502          fp->file_symtab.sym_symn = symtab->sh_size / symtab->sh_entsize;
1503 1503          fp->file_symtab.sym_hdr_pri = *symtab;
1504 1504          fp->file_symtab.sym_strhdr = *strtab;
1505 1505  
1506 1506          optimize_symtab(&fp->file_symtab);
1507 1507  
1508 1508          return;
1509 1509  err:
1510 1510          (void) elf_end(fp->file_symtab.sym_elf);
1511 1511          free(fp->file_symtab.sym_elfmem);
1512 1512          fp->file_symtab.sym_elf = NULL;
1513 1513          fp->file_symtab.sym_elfmem = NULL;
1514 1514  }
1515 1515  
1516 1516  static void
1517 1517  core_phdr_to_gelf(const Elf32_Phdr *src, GElf_Phdr *dst)
1518 1518  {
1519 1519          dst->p_type = src->p_type;
1520 1520          dst->p_flags = src->p_flags;
1521 1521          dst->p_offset = (Elf64_Off)src->p_offset;
1522 1522          dst->p_vaddr = (Elf64_Addr)src->p_vaddr;
1523 1523          dst->p_paddr = (Elf64_Addr)src->p_paddr;
1524 1524          dst->p_filesz = (Elf64_Xword)src->p_filesz;
1525 1525          dst->p_memsz = (Elf64_Xword)src->p_memsz;
1526 1526          dst->p_align = (Elf64_Xword)src->p_align;
1527 1527  }
1528 1528  
1529 1529  static void
1530 1530  core_shdr_to_gelf(const Elf32_Shdr *src, GElf_Shdr *dst)
1531 1531  {
1532 1532          dst->sh_name = src->sh_name;
1533 1533          dst->sh_type = src->sh_type;
1534 1534          dst->sh_flags = (Elf64_Xword)src->sh_flags;
1535 1535          dst->sh_addr = (Elf64_Addr)src->sh_addr;
1536 1536          dst->sh_offset = (Elf64_Off)src->sh_offset;
1537 1537          dst->sh_size = (Elf64_Xword)src->sh_size;
1538 1538          dst->sh_link = src->sh_link;
1539 1539          dst->sh_info = src->sh_info;
1540 1540          dst->sh_addralign = (Elf64_Xword)src->sh_addralign;
1541 1541          dst->sh_entsize = (Elf64_Xword)src->sh_entsize;
1542 1542  }
1543 1543  
1544 1544  /*
1545 1545   * Perform elf_begin on efp->e_fd and verify the ELF file's type and class.
1546 1546   */
1547 1547  static int
1548 1548  core_elf_fdopen(elf_file_t *efp, GElf_Half type, int *perr)
1549 1549  {
1550 1550  #ifdef _BIG_ENDIAN
1551 1551          uchar_t order = ELFDATA2MSB;
1552 1552  #else
1553 1553          uchar_t order = ELFDATA2LSB;
1554 1554  #endif
1555 1555          Elf32_Ehdr e32;
1556 1556          int is_noelf = -1;
1557 1557          int isa_err = 0;
1558 1558  
1559 1559          /*
1560 1560           * Because 32-bit libelf cannot deal with large files, we need to read,
1561 1561           * check, and convert the file header manually in case type == ET_CORE.
1562 1562           */
1563 1563          if (pread64(efp->e_fd, &e32, sizeof (e32), 0) != sizeof (e32)) {
1564 1564                  if (perr != NULL)
1565 1565                          *perr = G_FORMAT;
1566 1566                  goto err;
1567 1567          }
1568 1568          if ((is_noelf = memcmp(&e32.e_ident[EI_MAG0], ELFMAG, SELFMAG)) != 0 ||
1569 1569              e32.e_type != type || (isa_err = (e32.e_ident[EI_DATA] != order)) ||
1570 1570              e32.e_version != EV_CURRENT) {
1571 1571                  if (perr != NULL) {
1572 1572                          if (is_noelf == 0 && isa_err) {
1573 1573                                  *perr = G_ISAINVAL;
1574 1574                          } else {
1575 1575                                  *perr = G_FORMAT;
1576 1576                          }
1577 1577                  }
1578 1578                  goto err;
1579 1579          }
1580 1580  
1581 1581          /*
1582 1582           * If the file is 64-bit and we are 32-bit, fail with G_LP64.  If the
1583 1583           * file is 64-bit and we are 64-bit, re-read the header as a Elf64_Ehdr,
1584 1584           * and convert it to a elf_file_header_t.  Otherwise, the file is
1585 1585           * 32-bit, so convert e32 to a elf_file_header_t.
1586 1586           */
1587 1587          if (e32.e_ident[EI_CLASS] == ELFCLASS64) {
1588 1588  #ifdef _LP64
1589 1589                  Elf64_Ehdr e64;
1590 1590  
1591 1591                  if (pread64(efp->e_fd, &e64, sizeof (e64), 0) != sizeof (e64)) {
1592 1592                          if (perr != NULL)
1593 1593                                  *perr = G_FORMAT;
1594 1594                          goto err;
1595 1595                  }
1596 1596  
1597 1597                  (void) memcpy(efp->e_hdr.e_ident, e64.e_ident, EI_NIDENT);
1598 1598                  efp->e_hdr.e_type = e64.e_type;
1599 1599                  efp->e_hdr.e_machine = e64.e_machine;
1600 1600                  efp->e_hdr.e_version = e64.e_version;
1601 1601                  efp->e_hdr.e_entry = e64.e_entry;
1602 1602                  efp->e_hdr.e_phoff = e64.e_phoff;
1603 1603                  efp->e_hdr.e_shoff = e64.e_shoff;
1604 1604                  efp->e_hdr.e_flags = e64.e_flags;
1605 1605                  efp->e_hdr.e_ehsize = e64.e_ehsize;
1606 1606                  efp->e_hdr.e_phentsize = e64.e_phentsize;
1607 1607                  efp->e_hdr.e_phnum = (Elf64_Word)e64.e_phnum;
1608 1608                  efp->e_hdr.e_shentsize = e64.e_shentsize;
1609 1609                  efp->e_hdr.e_shnum = (Elf64_Word)e64.e_shnum;
1610 1610                  efp->e_hdr.e_shstrndx = (Elf64_Word)e64.e_shstrndx;
1611 1611  #else   /* _LP64 */
1612 1612                  if (perr != NULL)
1613 1613                          *perr = G_LP64;
1614 1614                  goto err;
1615 1615  #endif  /* _LP64 */
1616 1616          } else {
1617 1617                  (void) memcpy(efp->e_hdr.e_ident, e32.e_ident, EI_NIDENT);
1618 1618                  efp->e_hdr.e_type = e32.e_type;
1619 1619                  efp->e_hdr.e_machine = e32.e_machine;
1620 1620                  efp->e_hdr.e_version = e32.e_version;
1621 1621                  efp->e_hdr.e_entry = (Elf64_Addr)e32.e_entry;
1622 1622                  efp->e_hdr.e_phoff = (Elf64_Off)e32.e_phoff;
1623 1623                  efp->e_hdr.e_shoff = (Elf64_Off)e32.e_shoff;
1624 1624                  efp->e_hdr.e_flags = e32.e_flags;
1625 1625                  efp->e_hdr.e_ehsize = e32.e_ehsize;
1626 1626                  efp->e_hdr.e_phentsize = e32.e_phentsize;
1627 1627                  efp->e_hdr.e_phnum = (Elf64_Word)e32.e_phnum;
1628 1628                  efp->e_hdr.e_shentsize = e32.e_shentsize;
1629 1629                  efp->e_hdr.e_shnum = (Elf64_Word)e32.e_shnum;
1630 1630                  efp->e_hdr.e_shstrndx = (Elf64_Word)e32.e_shstrndx;
1631 1631          }
1632 1632  
1633 1633          /*
1634 1634           * If the number of section headers or program headers or the section
1635 1635           * header string table index would overflow their respective fields
1636 1636           * in the ELF header, they're stored in the section header at index
1637 1637           * zero. To simplify use elsewhere, we look for those sentinel values
1638 1638           * here.
1639 1639           */
1640 1640          if ((efp->e_hdr.e_shnum == 0 && efp->e_hdr.e_shoff != 0) ||
1641 1641              efp->e_hdr.e_shstrndx == SHN_XINDEX ||
1642 1642              efp->e_hdr.e_phnum == PN_XNUM) {
1643 1643                  GElf_Shdr shdr;
1644 1644  
1645 1645                  dprintf("extended ELF header\n");
1646 1646  
1647 1647                  if (efp->e_hdr.e_shoff == 0) {
1648 1648                          if (perr != NULL)
1649 1649                                  *perr = G_FORMAT;
1650 1650                          goto err;
1651 1651                  }
1652 1652  
1653 1653                  if (efp->e_hdr.e_ident[EI_CLASS] == ELFCLASS32) {
1654 1654                          Elf32_Shdr shdr32;
1655 1655  
1656 1656                          if (pread64(efp->e_fd, &shdr32, sizeof (shdr32),
1657 1657                              efp->e_hdr.e_shoff) != sizeof (shdr32)) {
1658 1658                                  if (perr != NULL)
1659 1659                                          *perr = G_FORMAT;
1660 1660                                  goto err;
1661 1661                          }
1662 1662  
1663 1663                          core_shdr_to_gelf(&shdr32, &shdr);
1664 1664                  } else {
1665 1665                          if (pread64(efp->e_fd, &shdr, sizeof (shdr),
1666 1666                              efp->e_hdr.e_shoff) != sizeof (shdr)) {
1667 1667                                  if (perr != NULL)
1668 1668                                          *perr = G_FORMAT;
1669 1669                                  goto err;
1670 1670                          }
1671 1671                  }
1672 1672  
1673 1673                  if (efp->e_hdr.e_shnum == 0) {
1674 1674                          efp->e_hdr.e_shnum = shdr.sh_size;
1675 1675                          dprintf("section header count %lu\n",
1676 1676                              (ulong_t)shdr.sh_size);
1677 1677                  }
1678 1678  
1679 1679                  if (efp->e_hdr.e_shstrndx == SHN_XINDEX) {
1680 1680                          efp->e_hdr.e_shstrndx = shdr.sh_link;
1681 1681                          dprintf("section string index %u\n", shdr.sh_link);
1682 1682                  }
1683 1683  
1684 1684                  if (efp->e_hdr.e_phnum == PN_XNUM && shdr.sh_info != 0) {
1685 1685                          efp->e_hdr.e_phnum = shdr.sh_info;
1686 1686                          dprintf("program header count %u\n", shdr.sh_info);
1687 1687                  }
1688 1688  
1689 1689          } else if (efp->e_hdr.e_phoff != 0) {
1690 1690                  GElf_Phdr phdr;
1691 1691                  uint64_t phnum;
1692 1692  
1693 1693                  /*
1694 1694                   * It's possible this core file came from a system that
1695 1695                   * accidentally truncated the e_phnum field without correctly
1696 1696                   * using the extended format in the section header at index
1697 1697                   * zero. We try to detect and correct that specific type of
1698 1698                   * corruption by using the knowledge that the core dump
1699 1699                   * routines usually place the data referenced by the first
1700 1700                   * program header immediately after the last header element.
1701 1701                   */
1702 1702                  if (efp->e_hdr.e_ident[EI_CLASS] == ELFCLASS32) {
1703 1703                          Elf32_Phdr phdr32;
1704 1704  
1705 1705                          if (pread64(efp->e_fd, &phdr32, sizeof (phdr32),
1706 1706                              efp->e_hdr.e_phoff) != sizeof (phdr32)) {
1707 1707                                  if (perr != NULL)
1708 1708                                          *perr = G_FORMAT;
1709 1709                                  goto err;
1710 1710                          }
1711 1711  
1712 1712                          core_phdr_to_gelf(&phdr32, &phdr);
1713 1713                  } else {
1714 1714                          if (pread64(efp->e_fd, &phdr, sizeof (phdr),
1715 1715                              efp->e_hdr.e_phoff) != sizeof (phdr)) {
1716 1716                                  if (perr != NULL)
1717 1717                                          *perr = G_FORMAT;
1718 1718                                  goto err;
1719 1719                          }
1720 1720                  }
1721 1721  
1722 1722                  phnum = phdr.p_offset - efp->e_hdr.e_ehsize -
1723 1723                      (uint64_t)efp->e_hdr.e_shnum * efp->e_hdr.e_shentsize;
1724 1724                  phnum /= efp->e_hdr.e_phentsize;
1725 1725  
1726 1726                  if (phdr.p_offset != 0 && phnum != efp->e_hdr.e_phnum) {
1727 1727                          dprintf("suspicious program header count %u %u\n",
1728 1728                              (uint_t)phnum, efp->e_hdr.e_phnum);
1729 1729  
1730 1730                          /*
1731 1731                           * If the new program header count we computed doesn't
1732 1732                           * jive with count in the ELF header, we'll use the
1733 1733                           * data that's there and hope for the best.
1734 1734                           *
1735 1735                           * If it does, it's also possible that the section
1736 1736                           * header offset is incorrect; we'll check that and
1737 1737                           * possibly try to fix it.
1738 1738                           */
1739 1739                          if (phnum <= INT_MAX &&
1740 1740                              (uint16_t)phnum == efp->e_hdr.e_phnum) {
1741 1741  
1742 1742                                  if (efp->e_hdr.e_shoff == efp->e_hdr.e_phoff +
1743 1743                                      efp->e_hdr.e_phentsize *
1744 1744                                      (uint_t)efp->e_hdr.e_phnum) {
1745 1745                                          efp->e_hdr.e_shoff =
1746 1746                                              efp->e_hdr.e_phoff +
1747 1747                                              efp->e_hdr.e_phentsize * phnum;
1748 1748                                  }
1749 1749  
1750 1750                                  efp->e_hdr.e_phnum = (Elf64_Word)phnum;
1751 1751                                  dprintf("using new program header count\n");
1752 1752                          } else {
1753 1753                                  dprintf("inconsistent program header count\n");
1754 1754                          }
1755 1755                  }
1756 1756          }
1757 1757  
1758 1758          /*
1759 1759           * The libelf implementation was never ported to be large-file aware.
1760 1760           * This is typically not a problem for your average executable or
1761 1761           * shared library, but a large 32-bit core file can exceed 2GB in size.
1762 1762           * So if type is ET_CORE, we don't bother doing elf_begin; the code
1763 1763           * in Pfgrab_core() below will do its own i/o and struct conversion.
1764 1764           */
1765 1765  
1766 1766          if (type == ET_CORE) {
1767 1767                  efp->e_elf = NULL;
1768 1768                  return (0);
1769 1769          }
1770 1770  
1771 1771          if ((efp->e_elf = elf_begin(efp->e_fd, ELF_C_READ, NULL)) == NULL) {
1772 1772                  if (perr != NULL)
1773 1773                          *perr = G_ELF;
1774 1774                  goto err;
1775 1775          }
1776 1776  
1777 1777          return (0);
1778 1778  
1779 1779  err:
1780 1780          efp->e_elf = NULL;
1781 1781          return (-1);
1782 1782  }
1783 1783  
1784 1784  /*
1785 1785   * Open the specified file and then do a core_elf_fdopen on it.
1786 1786   */
1787 1787  static int
1788 1788  core_elf_open(elf_file_t *efp, const char *path, GElf_Half type, int *perr)
1789 1789  {
1790 1790          (void) memset(efp, 0, sizeof (elf_file_t));
1791 1791  
1792 1792          if ((efp->e_fd = open64(path, O_RDONLY)) >= 0) {
1793 1793                  if (core_elf_fdopen(efp, type, perr) == 0)
1794 1794                          return (0);
1795 1795  
1796 1796                  (void) close(efp->e_fd);
1797 1797                  efp->e_fd = -1;
1798 1798          }
1799 1799  
1800 1800          return (-1);
1801 1801  }
1802 1802  
1803 1803  /*
1804 1804   * Close the ELF handle and file descriptor.
1805 1805   */
1806 1806  static void
1807 1807  core_elf_close(elf_file_t *efp)
1808 1808  {
1809 1809          if (efp->e_elf != NULL) {
1810 1810                  (void) elf_end(efp->e_elf);
1811 1811                  efp->e_elf = NULL;
1812 1812          }
1813 1813  
1814 1814          if (efp->e_fd != -1) {
1815 1815                  (void) close(efp->e_fd);
1816 1816                  efp->e_fd = -1;
1817 1817          }
1818 1818  }
1819 1819  
1820 1820  /*
1821 1821   * Given an ELF file for a statically linked executable, locate the likely
1822 1822   * primary text section and fill in rl_base with its virtual address.
1823 1823   */
1824 1824  static map_info_t *
1825 1825  core_find_text(struct ps_prochandle *P, Elf *elf, rd_loadobj_t *rlp)
1826 1826  {
1827 1827          GElf_Phdr phdr;
1828 1828          uint_t i;
1829 1829          size_t nphdrs;
1830 1830  
1831 1831          if (elf_getphdrnum(elf, &nphdrs) == -1)
1832 1832                  return (NULL);
1833 1833  
1834 1834          for (i = 0; i < nphdrs; i++) {
1835 1835                  if (gelf_getphdr(elf, i, &phdr) != NULL &&
1836 1836                      phdr.p_type == PT_LOAD && (phdr.p_flags & PF_X)) {
1837 1837                          rlp->rl_base = phdr.p_vaddr;
1838 1838                          return (Paddr2mptr(P, rlp->rl_base));
1839 1839                  }
1840 1840          }
1841 1841  
1842 1842          return (NULL);
1843 1843  }
1844 1844  
1845 1845  /*
1846 1846   * Given an ELF file and the librtld_db structure corresponding to its primary
1847 1847   * text mapping, deduce where its data segment was loaded and fill in
1848 1848   * rl_data_base and prmap_t.pr_offset accordingly.
1849 1849   */
1850 1850  static map_info_t *
1851 1851  core_find_data(struct ps_prochandle *P, Elf *elf, rd_loadobj_t *rlp)
1852 1852  {
1853 1853          GElf_Ehdr ehdr;
1854 1854          GElf_Phdr phdr;
1855 1855          map_info_t *mp;
1856 1856          uint_t i, pagemask;
1857 1857          size_t nphdrs;
1858 1858  
1859 1859          rlp->rl_data_base = NULL;
1860 1860  
1861 1861          /*
1862 1862           * Find the first loadable, writeable Phdr and compute rl_data_base
1863 1863           * as the virtual address at which is was loaded.
1864 1864           */
1865 1865          if (gelf_getehdr(elf, &ehdr) == NULL ||
1866 1866              elf_getphdrnum(elf, &nphdrs) == -1)
1867 1867                  return (NULL);
1868 1868  
1869 1869          for (i = 0; i < nphdrs; i++) {
1870 1870                  if (gelf_getphdr(elf, i, &phdr) != NULL &&
1871 1871                      phdr.p_type == PT_LOAD && (phdr.p_flags & PF_W)) {
1872 1872                          rlp->rl_data_base = phdr.p_vaddr;
1873 1873                          if (ehdr.e_type == ET_DYN)
1874 1874                                  rlp->rl_data_base += rlp->rl_base;
1875 1875                          break;
1876 1876                  }
1877 1877          }
1878 1878  
1879 1879          /*
1880 1880           * If we didn't find an appropriate phdr or if the address we
1881 1881           * computed has no mapping, return NULL.
1882 1882           */
1883 1883          if (rlp->rl_data_base == NULL ||
1884 1884              (mp = Paddr2mptr(P, rlp->rl_data_base)) == NULL)
1885 1885                  return (NULL);
1886 1886  
1887 1887          /*
1888 1888           * It wouldn't be procfs-related code if we didn't make use of
1889 1889           * unclean knowledge of segvn, even in userland ... the prmap_t's
1890 1890           * pr_offset field will be the segvn offset from mmap(2)ing the
1891 1891           * data section, which will be the file offset & PAGEMASK.
1892 1892           */
1893 1893          pagemask = ~(mp->map_pmap.pr_pagesize - 1);
1894 1894          mp->map_pmap.pr_offset = phdr.p_offset & pagemask;
1895 1895  
1896 1896          return (mp);
1897 1897  }
1898 1898  
1899 1899  /*
1900 1900   * Librtld_db agent callback for iterating over load object mappings.
1901 1901   * For each load object, we allocate a new file_info_t, perform naming,
1902 1902   * and attempt to construct a symbol table for the load object.
1903 1903   */
1904 1904  static int
1905 1905  core_iter_mapping(const rd_loadobj_t *rlp, struct ps_prochandle *P)
1906 1906  {
1907 1907          core_info_t *core = P->data;
1908 1908          char lname[PATH_MAX], buf[PATH_MAX];
1909 1909          file_info_t *fp;
1910 1910          map_info_t *mp;
1911 1911  
1912 1912          if (Pread_string(P, lname, PATH_MAX, (off_t)rlp->rl_nameaddr) <= 0) {
1913 1913                  dprintf("failed to read name %p\n", (void *)rlp->rl_nameaddr);
1914 1914                  return (1); /* Keep going; forget this if we can't get a name */
1915 1915          }
1916 1916  
1917 1917          dprintf("rd_loadobj name = \"%s\" rl_base = %p\n",
1918 1918              lname, (void *)rlp->rl_base);
1919 1919  
1920 1920          if ((mp = Paddr2mptr(P, rlp->rl_base)) == NULL) {
1921 1921                  dprintf("no mapping for %p\n", (void *)rlp->rl_base);
1922 1922                  return (1); /* No mapping; advance to next mapping */
1923 1923          }
1924 1924  
1925 1925          /*
1926 1926           * Create a new file_info_t for this mapping, and therefore for
1927 1927           * this load object.
1928 1928           *
1929 1929           * If there's an ELF header at the beginning of this mapping,
1930 1930           * file_info_new() will try to use its section headers to
1931 1931           * identify any other mappings that belong to this load object.
1932 1932           */
1933 1933          if ((fp = mp->map_file) == NULL &&
1934 1934              (fp = file_info_new(P, mp)) == NULL) {
1935 1935                  core->core_errno = errno;
1936 1936                  dprintf("failed to malloc mapping data\n");
1937 1937                  return (0); /* Abort */
1938 1938          }
1939 1939          fp->file_map = mp;
1940 1940  
1941 1941          /* Create a local copy of the load object representation */
1942 1942          if ((fp->file_lo = calloc(1, sizeof (rd_loadobj_t))) == NULL) {
1943 1943                  core->core_errno = errno;
1944 1944                  dprintf("failed to malloc mapping data\n");
1945 1945                  return (0); /* Abort */
1946 1946          }
1947 1947          *fp->file_lo = *rlp;
1948 1948  
1949 1949          if (lname[0] != '\0') {
1950 1950                  /*
1951 1951                   * Naming dance part 1: if we got a name from librtld_db, then
1952 1952                   * copy this name to the prmap_t if it is unnamed.  If the
1953 1953                   * file_info_t is unnamed, name it after the lname.
1954 1954                   */
1955 1955                  if (mp->map_pmap.pr_mapname[0] == '\0') {
1956 1956                          (void) strncpy(mp->map_pmap.pr_mapname, lname, PRMAPSZ);
1957 1957                          mp->map_pmap.pr_mapname[PRMAPSZ - 1] = '\0';
1958 1958                  }
1959 1959  
1960 1960                  if (fp->file_lname == NULL)
1961 1961                          fp->file_lname = strdup(lname);
1962 1962  
1963 1963          } else if (fp->file_lname == NULL &&
1964 1964              mp->map_pmap.pr_mapname[0] != '\0') {
1965 1965                  /*
1966 1966                   * Naming dance part 2: if the mapping is named and the
1967 1967                   * file_info_t is not, name the file after the mapping.
1968 1968                   */
1969 1969                  fp->file_lname = strdup(mp->map_pmap.pr_mapname);
1970 1970          }
1971 1971  
1972 1972          if ((fp->file_rname == NULL) &&
1973 1973              (Pfindmap(P, mp, buf, sizeof (buf)) != NULL))
1974 1974                  fp->file_rname = strdup(buf);
1975 1975  
1976 1976          if (fp->file_lname != NULL)
1977 1977                  fp->file_lbase = basename(fp->file_lname);
1978 1978          if (fp->file_rname != NULL)
1979 1979                  fp->file_rbase = basename(fp->file_rname);
1980 1980  
1981 1981          /* Associate the file and the mapping. */
1982 1982          (void) strncpy(fp->file_pname, mp->map_pmap.pr_mapname, PRMAPSZ);
1983 1983          fp->file_pname[PRMAPSZ - 1] = '\0';
1984 1984  
1985 1985          /*
1986 1986           * If no section headers were available then we'll have to
1987 1987           * identify this load object's other mappings with what we've
1988 1988           * got: the start and end of the object's corresponding
1989 1989           * address space.
1990 1990           */
1991 1991          if (fp->file_saddrs == NULL) {
1992 1992                  for (mp = fp->file_map + 1; mp < P->mappings + P->map_count &&
1993 1993                      mp->map_pmap.pr_vaddr < rlp->rl_bend; mp++) {
1994 1994  
1995 1995                          if (mp->map_file == NULL) {
1996 1996                                  dprintf("core_iter_mapping %s: associating "
1997 1997                                      "segment at %p\n",
1998 1998                                      fp->file_pname,
1999 1999                                      (void *)mp->map_pmap.pr_vaddr);
2000 2000                                  mp->map_file = fp;
2001 2001                                  fp->file_ref++;
2002 2002                          } else {
2003 2003                                  dprintf("core_iter_mapping %s: segment at "
2004 2004                                      "%p already associated with %s\n",
2005 2005                                      fp->file_pname,
2006 2006                                      (void *)mp->map_pmap.pr_vaddr,
2007 2007                                      (mp == fp->file_map ? "this file" :
2008 2008                                      mp->map_file->file_pname));
2009 2009                          }
2010 2010                  }
2011 2011          }
2012 2012  
2013 2013          /* Ensure that all this file's mappings are named. */
2014 2014          for (mp = fp->file_map; mp < P->mappings + P->map_count &&
2015 2015              mp->map_file == fp; mp++) {
2016 2016                  if (mp->map_pmap.pr_mapname[0] == '\0' &&
2017 2017                      !(mp->map_pmap.pr_mflags & MA_BREAK)) {
2018 2018                          (void) strncpy(mp->map_pmap.pr_mapname, fp->file_pname,
2019 2019                              PRMAPSZ);
2020 2020                          mp->map_pmap.pr_mapname[PRMAPSZ - 1] = '\0';
2021 2021                  }
2022 2022          }
2023 2023  
2024 2024          /* Attempt to build a symbol table for this file. */
2025 2025          Pbuild_file_symtab(P, fp);
2026 2026          if (fp->file_elf == NULL)
2027 2027                  dprintf("core_iter_mapping: no symtab for %s\n",
2028 2028                      fp->file_pname);
2029 2029  
2030 2030          /* Locate the start of a data segment associated with this file. */
2031 2031          if ((mp = core_find_data(P, fp->file_elf, fp->file_lo)) != NULL) {
2032 2032                  dprintf("found data for %s at %p (pr_offset 0x%llx)\n",
2033 2033                      fp->file_pname, (void *)fp->file_lo->rl_data_base,
2034 2034                      mp->map_pmap.pr_offset);
2035 2035          } else {
2036 2036                  dprintf("core_iter_mapping: no data found for %s\n",
2037 2037                      fp->file_pname);
2038 2038          }
2039 2039  
2040 2040          return (1); /* Advance to next mapping */
2041 2041  }
2042 2042  
2043 2043  /*
2044 2044   * Callback function for Pfindexec().  In order to confirm a given pathname,
2045 2045   * we verify that we can open it as an ELF file of type ET_EXEC or ET_DYN.
2046 2046   */
2047 2047  static int
2048 2048  core_exec_open(const char *path, void *efp)
2049 2049  {
2050 2050          if (core_elf_open(efp, path, ET_EXEC, NULL) == 0)
2051 2051                  return (1);
2052 2052          if (core_elf_open(efp, path, ET_DYN, NULL) == 0)
2053 2053                  return (1);
2054 2054          return (0);
2055 2055  }
2056 2056  
2057 2057  /*
2058 2058   * Attempt to load any section headers found in the core file.  If present,
2059 2059   * this will refer to non-loadable data added to the core file by the kernel
2060 2060   * based on coreadm(1M) settings, including CTF data and the symbol table.
2061 2061   */
2062 2062  static void
2063 2063  core_load_shdrs(struct ps_prochandle *P, elf_file_t *efp)
2064 2064  {
2065 2065          GElf_Shdr *shp, *shdrs = NULL;
2066 2066          char *shstrtab = NULL;
2067 2067          ulong_t shstrtabsz;
2068 2068          const char *name;
2069 2069          map_info_t *mp;
2070 2070  
2071 2071          size_t nbytes;
2072 2072          void *buf;
2073 2073          int i;
2074 2074  
2075 2075          if (efp->e_hdr.e_shstrndx >= efp->e_hdr.e_shnum) {
2076 2076                  dprintf("corrupt shstrndx (%u) exceeds shnum (%u)\n",
2077 2077                      efp->e_hdr.e_shstrndx, efp->e_hdr.e_shnum);
2078 2078                  return;
2079 2079          }
2080 2080  
2081 2081          /*
2082 2082           * Read the section header table from the core file and then iterate
2083 2083           * over the section headers, converting each to a GElf_Shdr.
2084 2084           */
2085 2085          if ((shdrs = malloc(efp->e_hdr.e_shnum * sizeof (GElf_Shdr))) == NULL) {
2086 2086                  dprintf("failed to malloc %u section headers: %s\n",
2087 2087                      (uint_t)efp->e_hdr.e_shnum, strerror(errno));
2088 2088                  return;
2089 2089          }
2090 2090  
2091 2091          nbytes = efp->e_hdr.e_shnum * efp->e_hdr.e_shentsize;
2092 2092          if ((buf = malloc(nbytes)) == NULL) {
2093 2093                  dprintf("failed to malloc %d bytes: %s\n", (int)nbytes,
2094 2094                      strerror(errno));
2095 2095                  free(shdrs);
2096 2096                  goto out;
2097 2097          }
2098 2098  
2099 2099          if (pread64(efp->e_fd, buf, nbytes, efp->e_hdr.e_shoff) != nbytes) {
2100 2100                  dprintf("failed to read section headers at off %lld: %s\n",
2101 2101                      (longlong_t)efp->e_hdr.e_shoff, strerror(errno));
2102 2102                  free(buf);
2103 2103                  goto out;
2104 2104          }
2105 2105  
2106 2106          for (i = 0; i < efp->e_hdr.e_shnum; i++) {
2107 2107                  void *p = (uchar_t *)buf + efp->e_hdr.e_shentsize * i;
2108 2108  
2109 2109                  if (efp->e_hdr.e_ident[EI_CLASS] == ELFCLASS32)
2110 2110                          core_shdr_to_gelf(p, &shdrs[i]);
2111 2111                  else
2112 2112                          (void) memcpy(&shdrs[i], p, sizeof (GElf_Shdr));
2113 2113          }
2114 2114  
2115 2115          free(buf);
2116 2116          buf = NULL;
2117 2117  
2118 2118          /*
2119 2119           * Read the .shstrtab section from the core file, terminating it with
2120 2120           * an extra \0 so that a corrupt section will not cause us to die.
2121 2121           */
2122 2122          shp = &shdrs[efp->e_hdr.e_shstrndx];
2123 2123          shstrtabsz = shp->sh_size;
2124 2124  
2125 2125          if ((shstrtab = malloc(shstrtabsz + 1)) == NULL) {
2126 2126                  dprintf("failed to allocate %lu bytes for shstrtab\n",
2127 2127                      (ulong_t)shstrtabsz);
2128 2128                  goto out;
2129 2129          }
2130 2130  
2131 2131          if (pread64(efp->e_fd, shstrtab, shstrtabsz,
2132 2132              shp->sh_offset) != shstrtabsz) {
2133 2133                  dprintf("failed to read %lu bytes of shstrs at off %lld: %s\n",
2134 2134                      shstrtabsz, (longlong_t)shp->sh_offset, strerror(errno));
2135 2135                  goto out;
2136 2136          }
2137 2137  
2138 2138          shstrtab[shstrtabsz] = '\0';
2139 2139  
2140 2140          /*
2141 2141           * Now iterate over each section in the section header table, locating
2142 2142           * sections of interest and initializing more of the ps_prochandle.
2143 2143           */
2144 2144          for (i = 0; i < efp->e_hdr.e_shnum; i++) {
2145 2145                  shp = &shdrs[i];
2146 2146                  name = shstrtab + shp->sh_name;
2147 2147  
2148 2148                  if (shp->sh_name >= shstrtabsz) {
2149 2149                          dprintf("skipping section [%d]: corrupt sh_name\n", i);
2150 2150                          continue;
2151 2151                  }
2152 2152  
2153 2153                  if (shp->sh_link >= efp->e_hdr.e_shnum) {
2154 2154                          dprintf("skipping section [%d]: corrupt sh_link\n", i);
2155 2155                          continue;
2156 2156                  }
2157 2157  
2158 2158                  dprintf("found section header %s (sh_addr 0x%llx)\n",
2159 2159                      name, (u_longlong_t)shp->sh_addr);
2160 2160  
2161 2161                  if (strcmp(name, ".SUNW_ctf") == 0) {
2162 2162                          if ((mp = Paddr2mptr(P, shp->sh_addr)) == NULL) {
2163 2163                                  dprintf("no map at addr 0x%llx for %s [%d]\n",
2164 2164                                      (u_longlong_t)shp->sh_addr, name, i);
2165 2165                                  continue;
2166 2166                          }
2167 2167  
2168 2168                          if (mp->map_file == NULL ||
2169 2169                              mp->map_file->file_ctf_buf != NULL) {
2170 2170                                  dprintf("no mapping file or duplicate buffer "
2171 2171                                      "for %s [%d]\n", name, i);
2172 2172                                  continue;
2173 2173                          }
2174 2174  
2175 2175                          if ((buf = malloc(shp->sh_size)) == NULL ||
2176 2176                              pread64(efp->e_fd, buf, shp->sh_size,
2177 2177                              shp->sh_offset) != shp->sh_size) {
2178 2178                                  dprintf("skipping section %s [%d]: %s\n",
2179 2179                                      name, i, strerror(errno));
2180 2180                                  free(buf);
2181 2181                                  continue;
2182 2182                          }
2183 2183  
2184 2184                          mp->map_file->file_ctf_size = shp->sh_size;
2185 2185                          mp->map_file->file_ctf_buf = buf;
2186 2186  
2187 2187                          if (shdrs[shp->sh_link].sh_type == SHT_DYNSYM)
2188 2188                                  mp->map_file->file_ctf_dyn = 1;
2189 2189  
2190 2190                  } else if (strcmp(name, ".symtab") == 0) {
2191 2191                          fake_up_symtab(P, &efp->e_hdr,
2192 2192                              shp, &shdrs[shp->sh_link]);
2193 2193                  }
2194 2194          }
2195 2195  out:
2196 2196          free(shstrtab);
2197 2197          free(shdrs);
2198 2198  }
2199 2199  
2200 2200  /*
2201 2201   * Main engine for core file initialization: given an fd for the core file
2202 2202   * and an optional pathname, construct the ps_prochandle.  The aout_path can
2203 2203   * either be a suggested executable pathname, or a suggested directory to
2204 2204   * use as a possible current working directory.
2205 2205   */
2206 2206  struct ps_prochandle *
2207 2207  Pfgrab_core(int core_fd, const char *aout_path, int *perr)
2208 2208  {
2209 2209          struct ps_prochandle *P;
2210 2210          core_info_t *core_info;
2211 2211          map_info_t *stk_mp, *brk_mp;
2212 2212          const char *execname;
2213 2213          char *interp;
2214 2214          int i, notes, pagesize;
2215 2215          uintptr_t addr, base_addr;
2216 2216          struct stat64 stbuf;
2217 2217          void *phbuf, *php;
2218 2218          size_t nbytes;
2219 2219  #ifdef __x86
2220 2220          boolean_t from_linux = B_FALSE;
2221 2221  #endif
2222 2222  
2223 2223          elf_file_t aout;
2224 2224          elf_file_t core;
2225 2225  
2226 2226          Elf_Scn *scn, *intp_scn = NULL;
2227 2227          Elf_Data *dp;
2228 2228  
2229 2229          GElf_Phdr phdr, note_phdr;
2230 2230          GElf_Shdr shdr;
2231 2231          GElf_Xword nleft;
2232 2232  
2233 2233          if (elf_version(EV_CURRENT) == EV_NONE) {
2234 2234                  dprintf("libproc ELF version is more recent than libelf\n");
2235 2235                  *perr = G_ELF;
2236 2236                  return (NULL);
2237 2237          }
2238 2238  
2239 2239          aout.e_elf = NULL;
2240 2240          aout.e_fd = -1;
2241 2241  
2242 2242          core.e_elf = NULL;
2243 2243          core.e_fd = core_fd;
2244 2244  
2245 2245          /*
2246 2246           * Allocate and initialize a ps_prochandle structure for the core.
2247 2247           * There are several key pieces of initialization here:
2248 2248           *
2249 2249           * 1. The PS_DEAD state flag marks this prochandle as a core file.
2250 2250           *    PS_DEAD also thus prevents all operations which require state
2251 2251           *    to be PS_STOP from operating on this handle.
2252 2252           *
2253 2253           * 2. We keep the core file fd in P->asfd since the core file contains
2254 2254           *    the remnants of the process address space.
2255 2255           *
2256 2256           * 3. We set the P->info_valid bit because all information about the
2257 2257           *    core is determined by the end of this function; there is no need
2258 2258           *    for proc_update_maps() to reload mappings at any later point.
2259 2259           *
2260 2260           * 4. The read/write ops vector uses our core_rw() function defined
2261 2261           *    above to handle i/o requests.
2262 2262           */
2263 2263          if ((P = malloc(sizeof (struct ps_prochandle))) == NULL) {
2264 2264                  *perr = G_STRANGE;
2265 2265                  return (NULL);
2266 2266          }
2267 2267  
2268 2268          (void) memset(P, 0, sizeof (struct ps_prochandle));
2269 2269          (void) mutex_init(&P->proc_lock, USYNC_THREAD, NULL);
2270 2270          P->state = PS_DEAD;
2271 2271          P->pid = (pid_t)-1;
2272 2272          P->asfd = core.e_fd;
2273 2273          P->ctlfd = -1;
2274 2274          P->statfd = -1;
2275 2275          P->agentctlfd = -1;
2276 2276          P->agentstatfd = -1;
2277 2277          P->zoneroot = NULL;
2278 2278          P->info_valid = 1;
2279 2279          Pinit_ops(&P->ops, &P_core_ops);
2280 2280  
2281 2281          Pinitsym(P);
2282 2282  
2283 2283          /*
2284 2284           * Fstat and open the core file and make sure it is a valid ELF core.
2285 2285           */
2286 2286          if (fstat64(P->asfd, &stbuf) == -1) {
2287 2287                  *perr = G_STRANGE;
2288 2288                  goto err;
2289 2289          }
2290 2290  
2291 2291          if (core_elf_fdopen(&core, ET_CORE, perr) == -1)
2292 2292                  goto err;
2293 2293  
2294 2294          /*
2295 2295           * Allocate and initialize a core_info_t to hang off the ps_prochandle
2296 2296           * structure.  We keep all core-specific information in this structure.
2297 2297           */
2298 2298          if ((core_info = calloc(1, sizeof (core_info_t))) == NULL) {
2299 2299                  *perr = G_STRANGE;
2300 2300                  goto err;
2301 2301          }
2302 2302  
2303 2303          P->data = core_info;
2304 2304          list_link(&core_info->core_lwp_head, NULL);
2305 2305          core_info->core_size = stbuf.st_size;
2306 2306          /*
2307 2307           * In the days before adjustable core file content, this was the
2308 2308           * default core file content. For new core files, this value will
2309 2309           * be overwritten by the NT_CONTENT note section.
2310 2310           */
2311 2311          core_info->core_content = CC_CONTENT_STACK | CC_CONTENT_HEAP |
2312 2312              CC_CONTENT_DATA | CC_CONTENT_RODATA | CC_CONTENT_ANON |
2313 2313              CC_CONTENT_SHANON;
2314 2314  
2315 2315          switch (core.e_hdr.e_ident[EI_CLASS]) {
2316 2316          case ELFCLASS32:
2317 2317                  core_info->core_dmodel = PR_MODEL_ILP32;
2318 2318                  break;
2319 2319          case ELFCLASS64:
2320 2320                  core_info->core_dmodel = PR_MODEL_LP64;
2321 2321                  break;
2322 2322          default:
2323 2323                  *perr = G_FORMAT;
2324 2324                  goto err;
2325 2325          }
2326 2326          core_info->core_osabi = core.e_hdr.e_ident[EI_OSABI];
2327 2327  
2328 2328          /*
2329 2329           * Because the core file may be a large file, we can't use libelf to
2330 2330           * read the Phdrs.  We use e_phnum and e_phentsize to simplify things.
2331 2331           */
2332 2332          nbytes = core.e_hdr.e_phnum * core.e_hdr.e_phentsize;
2333 2333  
2334 2334          if ((phbuf = malloc(nbytes)) == NULL) {
2335 2335                  *perr = G_STRANGE;
2336 2336                  goto err;
2337 2337          }
2338 2338  
2339 2339          if (pread64(core_fd, phbuf, nbytes, core.e_hdr.e_phoff) != nbytes) {
2340 2340                  *perr = G_STRANGE;
2341 2341                  free(phbuf);
2342 2342                  goto err;
2343 2343          }
2344 2344  
2345 2345          /*
2346 2346           * Iterate through the program headers in the core file.
2347 2347           * We're interested in two types of Phdrs: PT_NOTE (which
2348 2348           * contains a set of saved /proc structures), and PT_LOAD (which
2349 2349           * represents a memory mapping from the process's address space).
2350 2350           * In the case of PT_NOTE, we're interested in the last PT_NOTE
2351 2351           * in the core file; currently the first PT_NOTE (if present)
2352 2352           * contains /proc structs in the pre-2.6 unstructured /proc format.
2353 2353           */
2354 2354          for (php = phbuf, notes = 0, i = 0; i < core.e_hdr.e_phnum; i++) {
2355 2355                  if (core.e_hdr.e_ident[EI_CLASS] == ELFCLASS64)
2356 2356                          (void) memcpy(&phdr, php, sizeof (GElf_Phdr));
2357 2357                  else
2358 2358                          core_phdr_to_gelf(php, &phdr);
2359 2359  
2360 2360                  switch (phdr.p_type) {
2361 2361                  case PT_NOTE:
2362 2362                          note_phdr = phdr;
2363 2363                          notes++;
2364 2364                          break;
2365 2365  
2366 2366                  case PT_LOAD:
2367 2367                          if (core_add_mapping(P, &phdr) == -1) {
2368 2368                                  *perr = G_STRANGE;
2369 2369                                  free(phbuf);
2370 2370                                  goto err;
2371 2371                          }
2372 2372                          break;
2373 2373                  default:
2374 2374                          dprintf("Pgrab_core: unknown phdr %d\n", phdr.p_type);
2375 2375                          break;
2376 2376                  }
2377 2377  
2378 2378                  php = (char *)php + core.e_hdr.e_phentsize;
2379 2379          }
2380 2380  
2381 2381          free(phbuf);
2382 2382  
2383 2383          Psort_mappings(P);
2384 2384  
2385 2385          /*
2386 2386           * If we couldn't find anything of type PT_NOTE, or only one PT_NOTE
2387 2387           * was present, abort.  The core file is either corrupt or too old.
2388 2388           */
2389 2389          if (notes == 0 || (notes == 1 && core_info->core_osabi ==
2390 2390              ELFOSABI_SOLARIS)) {
2391 2391                  *perr = G_NOTE;
2392 2392                  goto err;
2393 2393          }
2394 2394  
2395 2395          /*
2396 2396           * Advance the seek pointer to the start of the PT_NOTE data
2397 2397           */
2398 2398          if (lseek64(P->asfd, note_phdr.p_offset, SEEK_SET) == (off64_t)-1) {
2399 2399                  dprintf("Pgrab_core: failed to lseek to PT_NOTE data\n");
2400 2400                  *perr = G_STRANGE;
2401 2401                  goto err;
2402 2402          }
2403 2403  
2404 2404          /*
2405 2405           * Now process the PT_NOTE structures.  Each one is preceded by
2406 2406           * an Elf{32/64}_Nhdr structure describing its type and size.
2407 2407           *
2408 2408           *  +--------+
2409 2409           *  | header |
2410 2410           *  +--------+
2411 2411           *  | name   |
2412 2412           *  | ...    |
2413 2413           *  +--------+
2414 2414           *  | desc   |
2415 2415           *  | ...    |
2416 2416           *  +--------+
2417 2417           */
2418 2418          for (nleft = note_phdr.p_filesz; nleft > 0; ) {
2419 2419                  Elf64_Nhdr nhdr;
2420 2420                  off64_t off, namesz, descsz;
2421 2421  
2422 2422                  /*
2423 2423                   * Although <sys/elf.h> defines both Elf32_Nhdr and Elf64_Nhdr
2424 2424                   * as different types, they are both of the same content and
2425 2425                   * size, so we don't need to worry about 32/64 conversion here.
2426 2426                   */
2427 2427                  if (read(P->asfd, &nhdr, sizeof (nhdr)) != sizeof (nhdr)) {
2428 2428                          dprintf("Pgrab_core: failed to read ELF note header\n");
2429 2429                          *perr = G_NOTE;
2430 2430                          goto err;
2431 2431                  }
2432 2432  
2433 2433                  /*
2434 2434                   * According to the System V ABI, the amount of padding
2435 2435                   * following the name field should align the description
2436 2436                   * field on a 4 byte boundary for 32-bit binaries or on an 8
2437 2437                   * byte boundary for 64-bit binaries. However, this change
2438 2438                   * was not made correctly during the 64-bit port so all
2439 2439                   * descriptions can assume only 4-byte alignment. We ignore
2440 2440                   * the name field and the padding to 4-byte alignment.
2441 2441                   */
2442 2442                  namesz = P2ROUNDUP((off64_t)nhdr.n_namesz, (off64_t)4);
2443 2443  
2444 2444                  if (lseek64(P->asfd, namesz, SEEK_CUR) == (off64_t)-1) {
2445 2445                          dprintf("failed to seek past name and padding\n");
2446 2446                          *perr = G_STRANGE;
2447 2447                          goto err;
2448 2448                  }
2449 2449  
2450 2450                  dprintf("Note hdr n_type=%u n_namesz=%u n_descsz=%u\n",
2451 2451                      nhdr.n_type, nhdr.n_namesz, nhdr.n_descsz);
2452 2452  
2453 2453                  off = lseek64(P->asfd, (off64_t)0L, SEEK_CUR);
2454 2454  
2455 2455                  /*
2456 2456                   * Invoke the note handler function from our table
2457 2457                   */
2458 2458                  if (nhdr.n_type < sizeof (nhdlrs) / sizeof (nhdlrs[0])) {
2459 2459                          if (nhdlrs[nhdr.n_type](P, nhdr.n_descsz) < 0) {
2460 2460                                  dprintf("handler for type %d returned < 0",
2461 2461                                      nhdr.n_type);
2462 2462                                  *perr = G_NOTE;
2463 2463                                  goto err;
2464 2464                          }
2465 2465                          /*
2466 2466                           * The presence of either of these notes indicates that
2467 2467                           * the dump was generated on Linux.
2468 2468                           */
2469 2469  #ifdef __x86
2470 2470                          if (nhdr.n_type == NT_PRSTATUS ||
2471 2471                              nhdr.n_type == NT_PRPSINFO)
2472 2472                                  from_linux = B_TRUE;
2473 2473  #endif
2474 2474                  } else {
2475 2475                          (void) note_notsup(P, nhdr.n_descsz);
2476 2476                  }
2477 2477  
2478 2478                  /*
2479 2479                   * Seek past the current note data to the next Elf_Nhdr
2480 2480                   */
2481 2481                  descsz = P2ROUNDUP((off64_t)nhdr.n_descsz, (off64_t)4);
2482 2482                  if (lseek64(P->asfd, off + descsz, SEEK_SET) == (off64_t)-1) {
2483 2483                          dprintf("Pgrab_core: failed to seek to next nhdr\n");
2484 2484                          *perr = G_STRANGE;
2485 2485                          goto err;
2486 2486                  }
2487 2487  
2488 2488                  /*
2489 2489                   * Subtract the size of the header and its data from what
2490 2490                   * we have left to process.
2491 2491                   */
2492 2492                  nleft -= sizeof (nhdr) + namesz + descsz;
2493 2493          }
2494 2494  
2495 2495  #ifdef __x86
2496 2496          if (from_linux) {
2497 2497                  size_t tcount, pid;
2498 2498                  lwp_info_t *lwp;
2499 2499  
2500 2500                  P->status.pr_dmodel = core_info->core_dmodel;
2501 2501  
2502 2502                  lwp = list_next(&core_info->core_lwp_head);
2503 2503  
2504 2504                  pid = P->status.pr_pid;
2505 2505  
2506 2506                  for (tcount = 0; tcount < core_info->core_nlwp;
2507 2507                      tcount++, lwp = list_next(lwp)) {
2508 2508                          dprintf("Linux thread with id %d\n", lwp->lwp_id);
2509 2509  
2510 2510                          /*
2511 2511                           * In the case we don't have a valid psinfo (i.e. pid is
2512 2512                           * 0, probably because of gdb creating the core) assume
2513 2513                           * lowest pid count is the first thread (what if the
2514 2514                           * next thread wraps the pid around?)
2515 2515                           */
2516 2516                          if (P->status.pr_pid == 0 &&
2517 2517                              ((pid == 0 && lwp->lwp_id > 0) ||
2518 2518                              (lwp->lwp_id < pid))) {
2519 2519                                  pid = lwp->lwp_id;
2520 2520                          }
2521 2521                  }
2522 2522  
2523 2523                  if (P->status.pr_pid != pid) {
2524 2524                          dprintf("No valid pid, setting to %ld\n", (ulong_t)pid);
2525 2525                          P->status.pr_pid = pid;
2526 2526                          P->psinfo.pr_pid = pid;
2527 2527                  }
2528 2528  
2529 2529                  /*
2530 2530                   * Consumers like mdb expect the first thread to actually have
2531 2531                   * an id of 1, on linux that is actually the pid. Find the the
2532 2532                   * thread with our process id, and set the id to 1
2533 2533                   */
2534 2534                  if ((lwp = lwpid2info(P, pid)) == NULL) {
2535 2535                          dprintf("Couldn't find first thread\n");
2536 2536                          *perr = G_STRANGE;
2537 2537                          goto err;
2538 2538                  }
2539 2539  
2540 2540                  dprintf("setting representative thread: %d\n", lwp->lwp_id);
2541 2541  
2542 2542                  lwp->lwp_id = 1;
2543 2543                  lwp->lwp_status.pr_lwpid = 1;
2544 2544  
2545 2545                  /* set representative thread */
2546 2546                  (void) memcpy(&P->status.pr_lwp, &lwp->lwp_status,
2547 2547                      sizeof (P->status.pr_lwp));
2548 2548          }
2549 2549  #endif /* __x86 */
2550 2550  
2551 2551          if (nleft != 0) {
2552 2552                  dprintf("Pgrab_core: note section malformed\n");
2553 2553                  *perr = G_STRANGE;
2554 2554                  goto err;
2555 2555          }
2556 2556  
2557 2557          if ((pagesize = Pgetauxval(P, AT_PAGESZ)) == -1) {
2558 2558                  pagesize = getpagesize();
2559 2559                  dprintf("AT_PAGESZ missing; defaulting to %d\n", pagesize);
2560 2560          }
2561 2561  
2562 2562          /*
2563 2563           * Locate and label the mappings corresponding to the end of the
2564 2564           * heap (MA_BREAK) and the base of the stack (MA_STACK).
2565 2565           */
2566 2566          if ((P->status.pr_brkbase != 0 || P->status.pr_brksize != 0) &&
2567 2567              (brk_mp = Paddr2mptr(P, P->status.pr_brkbase +
2568 2568              P->status.pr_brksize - 1)) != NULL)
2569 2569                  brk_mp->map_pmap.pr_mflags |= MA_BREAK;
2570 2570          else
2571 2571                  brk_mp = NULL;
2572 2572  
2573 2573          if ((stk_mp = Paddr2mptr(P, P->status.pr_stkbase)) != NULL)
2574 2574                  stk_mp->map_pmap.pr_mflags |= MA_STACK;
2575 2575  
2576 2576          /*
2577 2577           * At this point, we have enough information to look for the
2578 2578           * executable and open it: we have access to the auxv, a psinfo_t,
2579 2579           * and the ability to read from mappings provided by the core file.
2580 2580           */
2581 2581          (void) Pfindexec(P, aout_path, core_exec_open, &aout);
2582 2582          dprintf("P->execname = \"%s\"\n", P->execname ? P->execname : "NULL");
2583 2583          execname = P->execname ? P->execname : "a.out";
2584 2584  
2585 2585          /*
2586 2586           * Iterate through the sections, looking for the .dynamic and .interp
2587 2587           * sections.  If we encounter them, remember their section pointers.
2588 2588           */
2589 2589          for (scn = NULL; (scn = elf_nextscn(aout.e_elf, scn)) != NULL; ) {
2590 2590                  char *sname;
2591 2591  
2592 2592                  if ((gelf_getshdr(scn, &shdr) == NULL) ||
2593 2593                      (sname = elf_strptr(aout.e_elf, aout.e_hdr.e_shstrndx,
2594 2594                      (size_t)shdr.sh_name)) == NULL)
2595 2595                          continue;
2596 2596  
2597 2597                  if (strcmp(sname, ".interp") == 0)
2598 2598                          intp_scn = scn;
2599 2599          }
2600 2600  
2601 2601          /*
2602 2602           * Get the AT_BASE auxv element.  If this is missing (-1), then
2603 2603           * we assume this is a statically-linked executable.
2604 2604           */
2605 2605          base_addr = Pgetauxval(P, AT_BASE);
2606 2606  
2607 2607          /*
2608 2608           * In order to get librtld_db initialized, we'll need to identify
2609 2609           * and name the mapping corresponding to the run-time linker.  The
2610 2610           * AT_BASE auxv element tells us the address where it was mapped,
2611 2611           * and the .interp section of the executable tells us its path.
2612 2612           * If for some reason that doesn't pan out, just use ld.so.1.
2613 2613           */
2614 2614          if (intp_scn != NULL && (dp = elf_getdata(intp_scn, NULL)) != NULL &&
2615 2615              dp->d_size != 0) {
2616 2616                  dprintf(".interp = <%s>\n", (char *)dp->d_buf);
2617 2617                  interp = dp->d_buf;
2618 2618  
2619 2619          } else if (base_addr != (uintptr_t)-1L) {
2620 2620                  if (core_info->core_dmodel == PR_MODEL_LP64)
2621 2621                          interp = "/usr/lib/64/ld.so.1";
2622 2622                  else
2623 2623                          interp = "/usr/lib/ld.so.1";
2624 2624  
2625 2625                  dprintf(".interp section is missing or could not be read; "
2626 2626                      "defaulting to %s\n", interp);
2627 2627          } else
2628 2628                  dprintf("detected statically linked executable\n");
2629 2629  
2630 2630          /*
2631 2631           * If we have an AT_BASE element, name the mapping at that address
2632 2632           * using the interpreter pathname.  Name the corresponding data
2633 2633           * mapping after the interpreter as well.
2634 2634           */
2635 2635          if (base_addr != (uintptr_t)-1L) {
2636 2636                  elf_file_t intf;
2637 2637  
2638 2638                  P->map_ldso = core_name_mapping(P, base_addr, interp);
2639 2639  
2640 2640                  if (core_elf_open(&intf, interp, ET_DYN, NULL) == 0) {
2641 2641                          rd_loadobj_t rl;
2642 2642                          map_info_t *dmp;
2643 2643  
2644 2644                          rl.rl_base = base_addr;
2645 2645                          dmp = core_find_data(P, intf.e_elf, &rl);
2646 2646  
2647 2647                          if (dmp != NULL) {
2648 2648                                  dprintf("renamed data at %p to %s\n",
2649 2649                                      (void *)rl.rl_data_base, interp);
2650 2650                                  (void) strncpy(dmp->map_pmap.pr_mapname,
2651 2651                                      interp, PRMAPSZ);
2652 2652                                  dmp->map_pmap.pr_mapname[PRMAPSZ - 1] = '\0';
2653 2653                          }
2654 2654                  }
2655 2655  
2656 2656                  core_elf_close(&intf);
2657 2657          }
2658 2658  
2659 2659          /*
2660 2660           * If we have an AT_ENTRY element, name the mapping at that address
2661 2661           * using the special name "a.out" just like /proc does.
2662 2662           */
2663 2663          if ((addr = Pgetauxval(P, AT_ENTRY)) != (uintptr_t)-1L)
2664 2664                  P->map_exec = core_name_mapping(P, addr, "a.out");
2665 2665  
2666 2666          /*
2667 2667           * If we're a statically linked executable (or we're on x86 and looking
2668 2668           * at a Linux core dump), then just locate the executable's text and
2669 2669           * data and name them after the executable.
2670 2670           */
2671 2671  #ifndef __x86
2672 2672          if (base_addr == (uintptr_t)-1L) {
2673 2673  #else
2674 2674          if (base_addr == (uintptr_t)-1L || from_linux) {
2675 2675  #endif
2676 2676                  dprintf("looking for text and data: %s\n", execname);
2677 2677                  map_info_t *tmp, *dmp;
2678 2678                  file_info_t *fp;
2679 2679                  rd_loadobj_t rl;
2680 2680  
2681 2681                  if ((tmp = core_find_text(P, aout.e_elf, &rl)) != NULL &&
2682 2682                      (dmp = core_find_data(P, aout.e_elf, &rl)) != NULL) {
2683 2683                          (void) strncpy(tmp->map_pmap.pr_mapname,
2684 2684                              execname, PRMAPSZ);
2685 2685                          tmp->map_pmap.pr_mapname[PRMAPSZ - 1] = '\0';
2686 2686                          (void) strncpy(dmp->map_pmap.pr_mapname,
2687 2687                              execname, PRMAPSZ);
2688 2688                          dmp->map_pmap.pr_mapname[PRMAPSZ - 1] = '\0';
2689 2689                  }
2690 2690  
2691 2691                  if ((P->map_exec = tmp) != NULL &&
  
    | 
      ↓ open down ↓ | 
    2691 lines elided | 
    
      ↑ open up ↑ | 
  
2692 2692                      (fp = malloc(sizeof (file_info_t))) != NULL) {
2693 2693  
2694 2694                          (void) memset(fp, 0, sizeof (file_info_t));
2695 2695  
2696 2696                          list_link(fp, &P->file_head);
2697 2697                          tmp->map_file = fp;
2698 2698                          P->num_files++;
2699 2699  
2700 2700                          fp->file_ref = 1;
2701 2701                          fp->file_fd = -1;
     2702 +                        fp->file_dbgfile = -1;
2702 2703  
2703 2704                          fp->file_lo = malloc(sizeof (rd_loadobj_t));
2704 2705                          fp->file_lname = strdup(execname);
2705 2706  
2706 2707                          if (fp->file_lo)
2707 2708                                  *fp->file_lo = rl;
2708 2709                          if (fp->file_lname)
2709 2710                                  fp->file_lbase = basename(fp->file_lname);
2710 2711                          if (fp->file_rname)
2711 2712                                  fp->file_rbase = basename(fp->file_rname);
2712 2713  
2713 2714                          (void) strcpy(fp->file_pname,
2714 2715                              P->mappings[0].map_pmap.pr_mapname);
2715 2716                          fp->file_map = tmp;
2716 2717  
2717 2718                          Pbuild_file_symtab(P, fp);
2718 2719  
2719 2720                          if (dmp != NULL) {
2720 2721                                  dmp->map_file = fp;
2721 2722                                  fp->file_ref++;
2722 2723                          }
2723 2724                  }
2724 2725          }
2725 2726  
2726 2727          core_elf_close(&aout);
2727 2728  
2728 2729          /*
2729 2730           * We now have enough information to initialize librtld_db.
2730 2731           * After it warms up, we can iterate through the load object chain
2731 2732           * in the core, which will allow us to construct the file info
2732 2733           * we need to provide symbol information for the other shared
2733 2734           * libraries, and also to fill in the missing mapping names.
2734 2735           */
2735 2736          rd_log(_libproc_debug);
2736 2737  
2737 2738          if ((P->rap = rd_new(P)) != NULL) {
2738 2739                  (void) rd_loadobj_iter(P->rap, (rl_iter_f *)
2739 2740                      core_iter_mapping, P);
2740 2741  
2741 2742                  if (core_info->core_errno != 0) {
2742 2743                          errno = core_info->core_errno;
2743 2744                          *perr = G_STRANGE;
2744 2745                          goto err;
2745 2746                  }
2746 2747          } else
2747 2748                  dprintf("failed to initialize rtld_db agent\n");
2748 2749  
2749 2750          /*
2750 2751           * If there are sections, load them and process the data from any
2751 2752           * sections that we can use to annotate the file_info_t's.
2752 2753           */
2753 2754          core_load_shdrs(P, &core);
2754 2755  
2755 2756          /*
2756 2757           * If we previously located a stack or break mapping, and they are
2757 2758           * still anonymous, we now assume that they were MAP_ANON mappings.
2758 2759           * If brk_mp turns out to now have a name, then the heap is still
2759 2760           * sitting at the end of the executable's data+bss mapping: remove
2760 2761           * the previous MA_BREAK setting to be consistent with /proc.
2761 2762           */
2762 2763          if (stk_mp != NULL && stk_mp->map_pmap.pr_mapname[0] == '\0')
2763 2764                  stk_mp->map_pmap.pr_mflags |= MA_ANON;
2764 2765          if (brk_mp != NULL && brk_mp->map_pmap.pr_mapname[0] == '\0')
2765 2766                  brk_mp->map_pmap.pr_mflags |= MA_ANON;
2766 2767          else if (brk_mp != NULL)
2767 2768                  brk_mp->map_pmap.pr_mflags &= ~MA_BREAK;
2768 2769  
2769 2770          *perr = 0;
2770 2771          return (P);
2771 2772  
2772 2773  err:
2773 2774          Pfree(P);
2774 2775          core_elf_close(&aout);
2775 2776          return (NULL);
2776 2777  }
2777 2778  
2778 2779  /*
2779 2780   * Grab a core file using a pathname.  We just open it and call Pfgrab_core().
2780 2781   */
2781 2782  struct ps_prochandle *
2782 2783  Pgrab_core(const char *core, const char *aout, int gflag, int *perr)
2783 2784  {
2784 2785          int fd, oflag = (gflag & PGRAB_RDONLY) ? O_RDONLY : O_RDWR;
2785 2786  
2786 2787          if ((fd = open64(core, oflag)) >= 0)
2787 2788                  return (Pfgrab_core(fd, aout, perr));
2788 2789  
2789 2790          if (errno != ENOENT)
2790 2791                  *perr = G_STRANGE;
2791 2792          else
2792 2793                  *perr = G_NOCORE;
2793 2794  
2794 2795          return (NULL);
2795 2796  }
  
    | 
      ↓ open down ↓ | 
    84 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX