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