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