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