Print this page
3946 ::gcore
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libproc/common/Pcore.c
          +++ new/usr/src/lib/libproc/common/Pcore.c
↓ open down ↓ 17 lines elided ↑ open up ↑
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   */
  25   25  /*
  26   26   * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
  27   27   * Copyright (c) 2013, Joyent, Inc. All rights reserved.
       28 + * Copyright (c) 2013 by Delphix. All rights reserved.
  28   29   */
  29   30  
  30   31  #include <sys/types.h>
  31   32  #include <sys/utsname.h>
  32   33  #include <sys/sysmacros.h>
  33   34  #include <sys/proc.h>
  34   35  
  35   36  #include <alloca.h>
  36   37  #include <rtld_db.h>
  37   38  #include <libgen.h>
↓ open down ↓ 66 lines elided ↑ open up ↑
 104  105           * address falls through to returning success and zero bytes.
 105  106           */
 106  107          if (resid == n && n != 0 && prw != pread64) {
 107  108                  errno = EIO;
 108  109                  return (-1);
 109  110          }
 110  111  
 111  112          return (n - resid);
 112  113  }
 113  114  
      115 +/*ARGSUSED*/
 114  116  static ssize_t
 115      -Pread_core(struct ps_prochandle *P, void *buf, size_t n, uintptr_t addr)
      117 +Pread_core(struct ps_prochandle *P, void *buf, size_t n, uintptr_t addr,
      118 +    void *data)
 116  119  {
 117  120          return (core_rw(P, buf, n, addr, pread64));
 118  121  }
 119  122  
      123 +/*ARGSUSED*/
 120  124  static ssize_t
 121      -Pwrite_core(struct ps_prochandle *P, const void *buf, size_t n, uintptr_t addr)
      125 +Pwrite_core(struct ps_prochandle *P, const void *buf, size_t n, uintptr_t addr,
      126 +    void *data)
 122  127  {
 123  128          return (core_rw(P, (void *)buf, n, addr,
 124  129              (ssize_t (*)(int, void *, size_t, off64_t)) pwrite64));
 125  130  }
 126  131  
 127      -static const ps_rwops_t P_core_ops = { Pread_core, Pwrite_core };
      132 +/*ARGSUSED*/
      133 +static int
      134 +Pcred_core(struct ps_prochandle *P, prcred_t *pcrp, int ngroups, void *data)
      135 +{
      136 +        core_info_t *core = data;
 128  137  
      138 +        if (core->core_cred != NULL) {
      139 +                /*
      140 +                 * Avoid returning more supplementary group data than the
      141 +                 * caller has allocated in their buffer.  We expect them to
      142 +                 * check pr_ngroups afterward and potentially call us again.
      143 +                 */
      144 +                ngroups = MIN(ngroups, core->core_cred->pr_ngroups);
      145 +
      146 +                (void) memcpy(pcrp, core->core_cred,
      147 +                    sizeof (prcred_t) + (ngroups - 1) * sizeof (gid_t));
      148 +
      149 +                return (0);
      150 +        }
      151 +
      152 +        errno = ENODATA;
      153 +        return (-1);
      154 +}
      155 +
      156 +/*ARGSUSED*/
      157 +static int
      158 +Ppriv_core(struct ps_prochandle *P, prpriv_t **pprv, void *data)
      159 +{
      160 +        core_info_t *core = data;
      161 +
      162 +        if (core->core_priv == NULL) {
      163 +                errno = ENODATA;
      164 +                return (-1);
      165 +        }
      166 +
      167 +        *pprv = malloc(core->core_priv_size);
      168 +        if (*pprv == NULL) {
      169 +                return (-1);
      170 +        }
      171 +
      172 +        (void) memcpy(*pprv, core->core_priv, core->core_priv_size);
      173 +        return (0);
      174 +}
      175 +
      176 +/*ARGSUSED*/
      177 +static const psinfo_t *
      178 +Ppsinfo_core(struct ps_prochandle *P, psinfo_t *psinfo, void *data)
      179 +{
      180 +        return (&P->psinfo);
      181 +}
      182 +
      183 +/*ARGSUSED*/
      184 +static void
      185 +Pfini_core(struct ps_prochandle *P, void *data)
      186 +{
      187 +        core_info_t *core = data;
      188 +
      189 +        if (core != NULL) {
      190 +                extern void __priv_free_info(void *);
      191 +                lwp_info_t *nlwp, *lwp = list_next(&core->core_lwp_head);
      192 +                int i;
      193 +
      194 +                for (i = 0; i < core->core_nlwp; i++, lwp = nlwp) {
      195 +                        nlwp = list_next(lwp);
      196 +#ifdef __sparc
      197 +                        if (lwp->lwp_gwins != NULL)
      198 +                                free(lwp->lwp_gwins);
      199 +                        if (lwp->lwp_xregs != NULL)
      200 +                                free(lwp->lwp_xregs);
      201 +                        if (lwp->lwp_asrs != NULL)
      202 +                                free(lwp->lwp_asrs);
      203 +#endif
      204 +                        free(lwp);
      205 +                }
      206 +
      207 +                if (core->core_platform != NULL)
      208 +                        free(core->core_platform);
      209 +                if (core->core_uts != NULL)
      210 +                        free(core->core_uts);
      211 +                if (core->core_cred != NULL)
      212 +                        free(core->core_cred);
      213 +                if (core->core_priv != NULL)
      214 +                        free(core->core_priv);
      215 +                if (core->core_privinfo != NULL)
      216 +                        __priv_free_info(core->core_privinfo);
      217 +                if (core->core_ppii != NULL)
      218 +                        free(core->core_ppii);
      219 +                if (core->core_zonename != NULL)
      220 +                        free(core->core_zonename);
      221 +#if defined(__i386) || defined(__amd64)
      222 +                if (core->core_ldt != NULL)
      223 +                        free(core->core_ldt);
      224 +#endif
      225 +
      226 +                free(core);
      227 +        }
      228 +}
      229 +
      230 +/*ARGSUSED*/
      231 +static char *
      232 +Pplatform_core(struct ps_prochandle *P, char *s, size_t n, void *data)
      233 +{
      234 +        core_info_t *core = data;
      235 +
      236 +        if (core->core_platform == NULL) {
      237 +                errno = ENODATA;
      238 +                return (NULL);
      239 +        }
      240 +        (void) strncpy(s, core->core_platform, n - 1);
      241 +        s[n - 1] = '\0';
      242 +        return (s);
      243 +}
      244 +
      245 +/*ARGSUSED*/
      246 +static int
      247 +Puname_core(struct ps_prochandle *P, struct utsname *u, void *data)
      248 +{
      249 +        core_info_t *core = data;
      250 +
      251 +        if (core->core_uts == NULL) {
      252 +                errno = ENODATA;
      253 +                return (-1);
      254 +        }
      255 +        (void) memcpy(u, core->core_uts, sizeof (struct utsname));
      256 +        return (0);
      257 +}
      258 +
      259 +/*ARGSUSED*/
      260 +static char *
      261 +Pzonename_core(struct ps_prochandle *P, char *s, size_t n, void *data)
      262 +{
      263 +        core_info_t *core = data;
      264 +
      265 +        if (core->core_zonename == NULL) {
      266 +                errno = ENODATA;
      267 +                return (NULL);
      268 +        }
      269 +        (void) strlcpy(s, core->core_zonename, n);
      270 +        return (s);
      271 +}
      272 +
      273 +#if defined(__i386) || defined(__amd64)
      274 +/*ARGSUSED*/
      275 +static int
      276 +Pldt_core(struct ps_prochandle *P, struct ssd *pldt, int nldt, void *data)
      277 +{
      278 +        core_info_t *core = data;
      279 +
      280 +        if (pldt == NULL || nldt == 0)
      281 +                return (core->core_nldt);
      282 +
      283 +        if (core->core_ldt != NULL) {
      284 +                nldt = MIN(nldt, core->core_nldt);
      285 +
      286 +                (void) memcpy(pldt, core->core_ldt,
      287 +                    nldt * sizeof (struct ssd));
      288 +
      289 +                return (nldt);
      290 +        }
      291 +
      292 +        errno = ENODATA;
      293 +        return (-1);
      294 +}
      295 +#endif
      296 +
      297 +static const ps_ops_t P_core_ops = {
      298 +        .pop_pread      = Pread_core,
      299 +        .pop_pwrite     = Pwrite_core,
      300 +        .pop_cred       = Pcred_core,
      301 +        .pop_priv       = Ppriv_core,
      302 +        .pop_psinfo     = Ppsinfo_core,
      303 +        .pop_fini       = Pfini_core,
      304 +        .pop_platform   = Pplatform_core,
      305 +        .pop_uname      = Puname_core,
      306 +        .pop_zonename   = Pzonename_core,
      307 +#if defined(__i386) || defined(__amd64)
      308 +        .pop_ldt        = Pldt_core
      309 +#endif
      310 +};
      311 +
 129  312  /*
 130  313   * Return the lwp_info_t for the given lwpid.  If no such lwpid has been
 131  314   * encountered yet, allocate a new structure and return a pointer to it.
 132  315   * Create a list of lwp_info_t structures sorted in decreasing lwp_id order.
 133  316   */
 134  317  static lwp_info_t *
 135  318  lwpid2info(struct ps_prochandle *P, lwpid_t id)
 136  319  {
 137      -        lwp_info_t *lwp = list_next(&P->core->core_lwp_head);
      320 +        core_info_t *core = P->data;
      321 +        lwp_info_t *lwp = list_next(&core->core_lwp_head);
 138  322          lwp_info_t *next;
 139  323          uint_t i;
 140  324  
 141      -        for (i = 0; i < P->core->core_nlwp; i++, lwp = list_next(lwp)) {
      325 +        for (i = 0; i < core->core_nlwp; i++, lwp = list_next(lwp)) {
 142  326                  if (lwp->lwp_id == id) {
 143      -                        P->core->core_lwp = lwp;
      327 +                        core->core_lwp = lwp;
 144  328                          return (lwp);
 145  329                  }
 146  330                  if (lwp->lwp_id < id) {
 147  331                          break;
 148  332                  }
 149  333          }
 150  334  
 151  335          next = lwp;
 152  336          if ((lwp = calloc(1, sizeof (lwp_info_t))) == NULL)
 153  337                  return (NULL);
 154  338  
 155  339          list_link(lwp, next);
 156  340          lwp->lwp_id = id;
 157  341  
 158      -        P->core->core_lwp = lwp;
 159      -        P->core->core_nlwp++;
      342 +        core->core_lwp = lwp;
      343 +        core->core_nlwp++;
 160  344  
 161  345          return (lwp);
 162  346  }
 163  347  
 164  348  /*
 165  349   * The core file itself contains a series of NOTE segments containing saved
 166  350   * structures from /proc at the time the process died.  For each note we
 167  351   * comprehend, we define a function to read it in from the core file,
 168  352   * convert it to our native data model if necessary, and store it inside
 169  353   * the ps_prochandle.  Each function is invoked by Pfgrab_core() with the
 170  354   * seek pointer on P->asfd positioned appropriately.  We populate a table
 171  355   * of pointers to these note functions below.
 172  356   */
 173  357  
 174  358  static int
 175  359  note_pstatus(struct ps_prochandle *P, size_t nbytes)
 176  360  {
 177  361  #ifdef _LP64
 178      -        if (P->core->core_dmodel == PR_MODEL_ILP32) {
      362 +        core_info_t *core = P->data;
      363 +
      364 +        if (core->core_dmodel == PR_MODEL_ILP32) {
 179  365                  pstatus32_t ps32;
 180  366  
 181  367                  if (nbytes < sizeof (pstatus32_t) ||
 182  368                      read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32))
 183  369                          goto err;
 184  370  
 185  371                  pstatus_32_to_n(&ps32, &P->status);
 186  372  
 187  373          } else
 188  374  #endif
↓ open down ↓ 11 lines elided ↑ open up ↑
 200  386          return (-1);
 201  387  }
 202  388  
 203  389  static int
 204  390  note_lwpstatus(struct ps_prochandle *P, size_t nbytes)
 205  391  {
 206  392          lwp_info_t *lwp;
 207  393          lwpstatus_t lps;
 208  394  
 209  395  #ifdef _LP64
 210      -        if (P->core->core_dmodel == PR_MODEL_ILP32) {
      396 +        core_info_t *core = P->data;
      397 +
      398 +        if (core->core_dmodel == PR_MODEL_ILP32) {
 211  399                  lwpstatus32_t l32;
 212  400  
 213  401                  if (nbytes < sizeof (lwpstatus32_t) ||
 214  402                      read(P->asfd, &l32, sizeof (l32)) != sizeof (l32))
 215  403                          goto err;
 216  404  
 217  405                  lwpstatus_32_to_n(&l32, &lps);
 218  406          } else
 219  407  #endif
 220  408          if (nbytes < sizeof (lwpstatus_t) ||
↓ open down ↓ 18 lines elided ↑ open up ↑
 239  427  
 240  428  err:
 241  429          dprintf("Pgrab_core: failed to read NT_LWPSTATUS\n");
 242  430          return (-1);
 243  431  }
 244  432  
 245  433  static int
 246  434  note_psinfo(struct ps_prochandle *P, size_t nbytes)
 247  435  {
 248  436  #ifdef _LP64
 249      -        if (P->core->core_dmodel == PR_MODEL_ILP32) {
      437 +        core_info_t *core = P->data;
      438 +
      439 +        if (core->core_dmodel == PR_MODEL_ILP32) {
 250  440                  psinfo32_t ps32;
 251  441  
 252  442                  if (nbytes < sizeof (psinfo32_t) ||
 253  443                      read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32))
 254  444                          goto err;
 255  445  
 256  446                  psinfo_32_to_n(&ps32, &P->psinfo);
 257  447          } else
 258  448  #endif
 259  449          if (nbytes < sizeof (psinfo_t) ||
↓ open down ↓ 11 lines elided ↑ open up ↑
 271  461          return (-1);
 272  462  }
 273  463  
 274  464  static int
 275  465  note_lwpsinfo(struct ps_prochandle *P, size_t nbytes)
 276  466  {
 277  467          lwp_info_t *lwp;
 278  468          lwpsinfo_t lps;
 279  469  
 280  470  #ifdef _LP64
 281      -        if (P->core->core_dmodel == PR_MODEL_ILP32) {
      471 +        core_info_t *core = P->data;
      472 +
      473 +        if (core->core_dmodel == PR_MODEL_ILP32) {
 282  474                  lwpsinfo32_t l32;
 283  475  
 284  476                  if (nbytes < sizeof (lwpsinfo32_t) ||
 285  477                      read(P->asfd, &l32, sizeof (l32)) != sizeof (l32))
 286  478                          goto err;
 287  479  
 288  480                  lwpsinfo_32_to_n(&l32, &lps);
 289  481          } else
 290  482  #endif
 291  483          if (nbytes < sizeof (lwpsinfo_t) ||
↓ open down ↓ 29 lines elided ↑ open up ↑
 321  513                  dprintf("Pgrab_core: failed to add NT_FDINFO\n");
 322  514                  return (-1);
 323  515          }
 324  516          (void) memcpy(&fip->fd_info, &prfd, sizeof (prfd));
 325  517          return (0);
 326  518  }
 327  519  
 328  520  static int
 329  521  note_platform(struct ps_prochandle *P, size_t nbytes)
 330  522  {
      523 +        core_info_t *core = P->data;
 331  524          char *plat;
 332  525  
 333      -        if (P->core->core_platform != NULL)
      526 +        if (core->core_platform != NULL)
 334  527                  return (0);     /* Already seen */
 335  528  
 336  529          if (nbytes != 0 && ((plat = malloc(nbytes + 1)) != NULL)) {
 337  530                  if (read(P->asfd, plat, nbytes) != nbytes) {
 338  531                          dprintf("Pgrab_core: failed to read NT_PLATFORM\n");
 339  532                          free(plat);
 340  533                          return (-1);
 341  534                  }
 342  535                  plat[nbytes - 1] = '\0';
 343      -                P->core->core_platform = plat;
      536 +                core->core_platform = plat;
 344  537          }
 345  538  
 346  539          return (0);
 347  540  }
 348  541  
 349  542  static int
 350  543  note_utsname(struct ps_prochandle *P, size_t nbytes)
 351  544  {
      545 +        core_info_t *core = P->data;
 352  546          size_t ubytes = sizeof (struct utsname);
 353  547          struct utsname *utsp;
 354  548  
 355      -        if (P->core->core_uts != NULL || nbytes < ubytes)
      549 +        if (core->core_uts != NULL || nbytes < ubytes)
 356  550                  return (0);     /* Already seen or bad size */
 357  551  
 358  552          if ((utsp = malloc(ubytes)) == NULL)
 359  553                  return (-1);
 360  554  
 361  555          if (read(P->asfd, utsp, ubytes) != ubytes) {
 362  556                  dprintf("Pgrab_core: failed to read NT_UTSNAME\n");
 363  557                  free(utsp);
 364  558                  return (-1);
 365  559          }
 366  560  
 367  561          if (_libproc_debug) {
 368  562                  dprintf("uts.sysname = \"%s\"\n", utsp->sysname);
 369  563                  dprintf("uts.nodename = \"%s\"\n", utsp->nodename);
 370  564                  dprintf("uts.release = \"%s\"\n", utsp->release);
 371  565                  dprintf("uts.version = \"%s\"\n", utsp->version);
 372  566                  dprintf("uts.machine = \"%s\"\n", utsp->machine);
 373  567          }
 374  568  
 375      -        P->core->core_uts = utsp;
      569 +        core->core_uts = utsp;
 376  570          return (0);
 377  571  }
 378  572  
 379  573  static int
 380  574  note_content(struct ps_prochandle *P, size_t nbytes)
 381  575  {
      576 +        core_info_t *core = P->data;
 382  577          core_content_t content;
 383  578  
 384      -        if (sizeof (P->core->core_content) != nbytes)
      579 +        if (sizeof (core->core_content) != nbytes)
 385  580                  return (-1);
 386  581  
 387  582          if (read(P->asfd, &content, sizeof (content)) != sizeof (content))
 388  583                  return (-1);
 389  584  
 390      -        P->core->core_content = content;
      585 +        core->core_content = content;
 391  586  
 392  587          dprintf("core content = %llx\n", content);
 393  588  
 394  589          return (0);
 395  590  }
 396  591  
 397  592  static int
 398  593  note_cred(struct ps_prochandle *P, size_t nbytes)
 399  594  {
      595 +        core_info_t *core = P->data;
 400  596          prcred_t *pcrp;
 401  597          int ngroups;
 402  598          const size_t min_size = sizeof (prcred_t) - sizeof (gid_t);
 403  599  
 404  600          /*
 405  601           * We allow for prcred_t notes that are actually smaller than a
 406  602           * prcred_t since the last member isn't essential if there are
 407  603           * no group memberships. This allows for more flexibility when it
 408  604           * comes to slightly malformed -- but still valid -- notes.
 409  605           */
 410      -        if (P->core->core_cred != NULL || nbytes < min_size)
      606 +        if (core->core_cred != NULL || nbytes < min_size)
 411  607                  return (0);     /* Already seen or bad size */
 412  608  
 413  609          ngroups = (nbytes - min_size) / sizeof (gid_t);
 414  610          nbytes = sizeof (prcred_t) + (ngroups - 1) * sizeof (gid_t);
 415  611  
 416  612          if ((pcrp = malloc(nbytes)) == NULL)
 417  613                  return (-1);
 418  614  
 419  615          if (read(P->asfd, pcrp, nbytes) != nbytes) {
 420  616                  dprintf("Pgrab_core: failed to read NT_PRCRED\n");
 421  617                  free(pcrp);
 422  618                  return (-1);
 423  619          }
 424  620  
 425  621          if (pcrp->pr_ngroups > ngroups) {
 426  622                  dprintf("pr_ngroups = %d; resetting to %d based on note size\n",
 427  623                      pcrp->pr_ngroups, ngroups);
 428  624                  pcrp->pr_ngroups = ngroups;
 429  625          }
 430  626  
 431      -        P->core->core_cred = pcrp;
      627 +        core->core_cred = pcrp;
 432  628          return (0);
 433  629  }
 434  630  
 435  631  #if defined(__i386) || defined(__amd64)
 436  632  static int
 437  633  note_ldt(struct ps_prochandle *P, size_t nbytes)
 438  634  {
      635 +        core_info_t *core = P->data;
 439  636          struct ssd *pldt;
 440  637          uint_t nldt;
 441  638  
 442      -        if (P->core->core_ldt != NULL || nbytes < sizeof (struct ssd))
      639 +        if (core->core_ldt != NULL || nbytes < sizeof (struct ssd))
 443  640                  return (0);     /* Already seen or bad size */
 444  641  
 445  642          nldt = nbytes / sizeof (struct ssd);
 446  643          nbytes = nldt * sizeof (struct ssd);
 447  644  
 448  645          if ((pldt = malloc(nbytes)) == NULL)
 449  646                  return (-1);
 450  647  
 451  648          if (read(P->asfd, pldt, nbytes) != nbytes) {
 452  649                  dprintf("Pgrab_core: failed to read NT_LDT\n");
 453  650                  free(pldt);
 454  651                  return (-1);
 455  652          }
 456  653  
 457      -        P->core->core_ldt = pldt;
 458      -        P->core->core_nldt = nldt;
      654 +        core->core_ldt = pldt;
      655 +        core->core_nldt = nldt;
 459  656          return (0);
 460  657  }
 461  658  #endif  /* __i386 */
 462  659  
 463  660  static int
 464  661  note_priv(struct ps_prochandle *P, size_t nbytes)
 465  662  {
      663 +        core_info_t *core = P->data;
 466  664          prpriv_t *pprvp;
 467  665  
 468      -        if (P->core->core_priv != NULL || nbytes < sizeof (prpriv_t))
      666 +        if (core->core_priv != NULL || nbytes < sizeof (prpriv_t))
 469  667                  return (0);     /* Already seen or bad size */
 470  668  
 471  669          if ((pprvp = malloc(nbytes)) == NULL)
 472  670                  return (-1);
 473  671  
 474  672          if (read(P->asfd, pprvp, nbytes) != nbytes) {
 475  673                  dprintf("Pgrab_core: failed to read NT_PRPRIV\n");
 476  674                  free(pprvp);
 477  675                  return (-1);
 478  676          }
 479  677  
 480      -        P->core->core_priv = pprvp;
 481      -        P->core->core_priv_size = nbytes;
      678 +        core->core_priv = pprvp;
      679 +        core->core_priv_size = nbytes;
 482  680          return (0);
 483  681  }
 484  682  
 485  683  static int
 486  684  note_priv_info(struct ps_prochandle *P, size_t nbytes)
 487  685  {
      686 +        core_info_t *core = P->data;
 488  687          extern void *__priv_parse_info();
 489  688          priv_impl_info_t *ppii;
 490  689  
 491      -        if (P->core->core_privinfo != NULL ||
      690 +        if (core->core_privinfo != NULL ||
 492  691              nbytes < sizeof (priv_impl_info_t))
 493  692                  return (0);     /* Already seen or bad size */
 494  693  
 495  694          if ((ppii = malloc(nbytes)) == NULL)
 496  695                  return (-1);
 497  696  
 498  697          if (read(P->asfd, ppii, nbytes) != nbytes ||
 499  698              PRIV_IMPL_INFO_SIZE(ppii) != nbytes) {
 500  699                  dprintf("Pgrab_core: failed to read NT_PRPRIVINFO\n");
 501  700                  free(ppii);
 502  701                  return (-1);
 503  702          }
 504  703  
 505      -        P->core->core_privinfo = __priv_parse_info(ppii);
 506      -        P->core->core_ppii = ppii;
      704 +        core->core_privinfo = __priv_parse_info(ppii);
      705 +        core->core_ppii = ppii;
 507  706          return (0);
 508  707  }
 509  708  
 510  709  static int
 511  710  note_zonename(struct ps_prochandle *P, size_t nbytes)
 512  711  {
      712 +        core_info_t *core = P->data;
 513  713          char *zonename;
 514  714  
 515      -        if (P->core->core_zonename != NULL)
      715 +        if (core->core_zonename != NULL)
 516  716                  return (0);     /* Already seen */
 517  717  
 518  718          if (nbytes != 0) {
 519  719                  if ((zonename = malloc(nbytes)) == NULL)
 520  720                          return (-1);
 521  721                  if (read(P->asfd, zonename, nbytes) != nbytes) {
 522  722                          dprintf("Pgrab_core: failed to read NT_ZONENAME\n");
 523  723                          free(zonename);
 524  724                          return (-1);
 525  725                  }
 526  726                  zonename[nbytes - 1] = '\0';
 527      -                P->core->core_zonename = zonename;
      727 +                core->core_zonename = zonename;
 528  728          }
 529  729  
 530  730          return (0);
 531  731  }
 532  732  
 533  733  static int
 534  734  note_auxv(struct ps_prochandle *P, size_t nbytes)
 535  735  {
 536  736          size_t n, i;
 537  737  
 538  738  #ifdef _LP64
 539      -        if (P->core->core_dmodel == PR_MODEL_ILP32) {
      739 +        core_info_t *core = P->data;
      740 +
      741 +        if (core->core_dmodel == PR_MODEL_ILP32) {
 540  742                  auxv32_t *a32;
 541  743  
 542  744                  n = nbytes / sizeof (auxv32_t);
 543  745                  nbytes = n * sizeof (auxv32_t);
 544  746                  a32 = alloca(nbytes);
 545  747  
 546  748                  if (read(P->asfd, a32, nbytes) != nbytes) {
 547  749                          dprintf("Pgrab_core: failed to read NT_AUXV\n");
 548  750                          return (-1);
 549  751                  }
↓ open down ↓ 37 lines elided ↑ open up ↑
 587  789          P->auxv[n].a_un.a_val = 0L;
 588  790          P->nauxv = (int)n;
 589  791  
 590  792          return (0);
 591  793  }
 592  794  
 593  795  #ifdef __sparc
 594  796  static int
 595  797  note_xreg(struct ps_prochandle *P, size_t nbytes)
 596  798  {
 597      -        lwp_info_t *lwp = P->core->core_lwp;
      799 +        core_info_t *core = P->data;
      800 +        lwp_info_t *lwp = core->core_lwp;
 598  801          size_t xbytes = sizeof (prxregset_t);
 599  802          prxregset_t *xregs;
 600  803  
 601  804          if (lwp == NULL || lwp->lwp_xregs != NULL || nbytes < xbytes)
 602  805                  return (0);     /* No lwp yet, already seen, or bad size */
 603  806  
 604  807          if ((xregs = malloc(xbytes)) == NULL)
 605  808                  return (-1);
 606  809  
 607  810          if (read(P->asfd, xregs, xbytes) != xbytes) {
↓ open down ↓ 2 lines elided ↑ open up ↑
 610  813                  return (-1);
 611  814          }
 612  815  
 613  816          lwp->lwp_xregs = xregs;
 614  817          return (0);
 615  818  }
 616  819  
 617  820  static int
 618  821  note_gwindows(struct ps_prochandle *P, size_t nbytes)
 619  822  {
 620      -        lwp_info_t *lwp = P->core->core_lwp;
      823 +        core_info_t *core = P->data;
      824 +        lwp_info_t *lwp = core->core_lwp;
 621  825  
 622  826          if (lwp == NULL || lwp->lwp_gwins != NULL || nbytes == 0)
 623  827                  return (0);     /* No lwp yet or already seen or no data */
 624  828  
 625  829          if ((lwp->lwp_gwins = malloc(sizeof (gwindows_t))) == NULL)
 626  830                  return (-1);
 627  831  
 628  832          /*
 629  833           * Since the amount of gwindows data varies with how many windows were
 630  834           * actually saved, we just read up to the minimum of the note size
 631  835           * and the size of the gwindows_t type.  It doesn't matter if the read
 632  836           * fails since we have to zero out gwindows first anyway.
 633  837           */
 634  838  #ifdef _LP64
 635      -        if (P->core->core_dmodel == PR_MODEL_ILP32) {
      839 +        if (core->core_dmodel == PR_MODEL_ILP32) {
 636  840                  gwindows32_t g32;
 637  841  
 638  842                  (void) memset(&g32, 0, sizeof (g32));
 639  843                  (void) read(P->asfd, &g32, MIN(nbytes, sizeof (g32)));
 640  844                  gwindows_32_to_n(&g32, lwp->lwp_gwins);
 641  845  
 642  846          } else {
 643  847  #endif
 644  848                  (void) memset(lwp->lwp_gwins, 0, sizeof (gwindows_t));
 645  849                  (void) read(P->asfd, lwp->lwp_gwins,
↓ open down ↓ 1 lines elided ↑ open up ↑
 647  851  #ifdef _LP64
 648  852          }
 649  853  #endif
 650  854          return (0);
 651  855  }
 652  856  
 653  857  #ifdef __sparcv9
 654  858  static int
 655  859  note_asrs(struct ps_prochandle *P, size_t nbytes)
 656  860  {
 657      -        lwp_info_t *lwp = P->core->core_lwp;
      861 +        core_info_t *core = P->data;
      862 +        lwp_info_t *lwp = core->core_lwp;
 658  863          int64_t *asrs;
 659  864  
 660  865          if (lwp == NULL || lwp->lwp_asrs != NULL || nbytes < sizeof (asrset_t))
 661  866                  return (0);     /* No lwp yet, already seen, or bad size */
 662  867  
 663  868          if ((asrs = malloc(sizeof (asrset_t))) == NULL)
 664  869                  return (-1);
 665  870  
 666  871          if (read(P->asfd, asrs, sizeof (asrset_t)) != sizeof (asrset_t)) {
 667  872                  dprintf("Pgrab_core: failed to read NT_ASRS\n");
↓ open down ↓ 4 lines elided ↑ open up ↑
 672  877          lwp->lwp_asrs = asrs;
 673  878          return (0);
 674  879  }
 675  880  #endif  /* __sparcv9 */
 676  881  #endif  /* __sparc */
 677  882  
 678  883  static int
 679  884  note_spymaster(struct ps_prochandle *P, size_t nbytes)
 680  885  {
 681  886  #ifdef _LP64
 682      -        if (P->core->core_dmodel == PR_MODEL_ILP32) {
      887 +        core_info_t *core = P->data;
      888 +
      889 +        if (core->core_dmodel == PR_MODEL_ILP32) {
 683  890                  psinfo32_t ps32;
 684  891  
 685  892                  if (nbytes < sizeof (psinfo32_t) ||
 686  893                      read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32))
 687  894                          goto err;
 688  895  
 689  896                  psinfo_32_to_n(&ps32, &P->spymaster);
 690  897          } else
 691  898  #endif
 692  899          if (nbytes < sizeof (psinfo_t) || read(P->asfd,
↓ open down ↓ 130 lines elided ↑ open up ↑
 823 1030          dprintf(msgfmt, addr);
 824 1031  }
 825 1032  
 826 1033  /*
 827 1034   * Add information on the address space mapping described by the given
 828 1035   * PT_LOAD program header.  We fill in more information on the mapping later.
 829 1036   */
 830 1037  static int
 831 1038  core_add_mapping(struct ps_prochandle *P, GElf_Phdr *php)
 832 1039  {
     1040 +        core_info_t *core = P->data;
 833 1041          prmap_t pmap;
 834 1042  
 835 1043          dprintf("mapping base %llx filesz %llu memsz %llu offset %llu\n",
 836 1044              (u_longlong_t)php->p_vaddr, (u_longlong_t)php->p_filesz,
 837 1045              (u_longlong_t)php->p_memsz, (u_longlong_t)php->p_offset);
 838 1046  
 839 1047          pmap.pr_vaddr = (uintptr_t)php->p_vaddr;
 840 1048          pmap.pr_size = php->p_memsz;
 841 1049  
 842 1050          /*
 843 1051           * If Pgcore() or elfcore() fail to write a mapping, they will set
 844 1052           * PF_SUNW_FAILURE in the Phdr and try to stash away the errno for us.
 845 1053           */
 846 1054          if (php->p_flags & PF_SUNW_FAILURE) {
 847 1055                  core_report_mapping(P, php);
 848      -        } else if (php->p_filesz != 0 && php->p_offset >= P->core->core_size) {
     1056 +        } else if (php->p_filesz != 0 && php->p_offset >= core->core_size) {
 849 1057                  Perror_printf(P, "core file may be corrupt -- data for mapping "
 850 1058                      "at %p is missing\n", (void *)(uintptr_t)php->p_vaddr);
 851 1059                  dprintf("core file may be corrupt -- data for mapping "
 852 1060                      "at %p is missing\n", (void *)(uintptr_t)php->p_vaddr);
 853 1061          }
 854 1062  
 855 1063          /*
 856 1064           * The mapping name and offset will hopefully be filled in
 857 1065           * by the librtld_db agent.  Unfortunately, if it isn't a
 858 1066           * shared library mapping, this information is gone forever.
↓ open down ↓ 615 lines elided ↑ open up ↑
1474 1682  }
1475 1683  
1476 1684  /*
1477 1685   * Librtld_db agent callback for iterating over load object mappings.
1478 1686   * For each load object, we allocate a new file_info_t, perform naming,
1479 1687   * and attempt to construct a symbol table for the load object.
1480 1688   */
1481 1689  static int
1482 1690  core_iter_mapping(const rd_loadobj_t *rlp, struct ps_prochandle *P)
1483 1691  {
     1692 +        core_info_t *core = P->data;
1484 1693          char lname[PATH_MAX], buf[PATH_MAX];
1485 1694          file_info_t *fp;
1486 1695          map_info_t *mp;
1487 1696  
1488 1697          if (Pread_string(P, lname, PATH_MAX, (off_t)rlp->rl_nameaddr) <= 0) {
1489 1698                  dprintf("failed to read name %p\n", (void *)rlp->rl_nameaddr);
1490 1699                  return (1); /* Keep going; forget this if we can't get a name */
1491 1700          }
1492 1701  
1493 1702          dprintf("rd_loadobj name = \"%s\" rl_base = %p\n",
↓ open down ↓ 7 lines elided ↑ open up ↑
1501 1710          /*
1502 1711           * Create a new file_info_t for this mapping, and therefore for
1503 1712           * this load object.
1504 1713           *
1505 1714           * If there's an ELF header at the beginning of this mapping,
1506 1715           * file_info_new() will try to use its section headers to
1507 1716           * identify any other mappings that belong to this load object.
1508 1717           */
1509 1718          if ((fp = mp->map_file) == NULL &&
1510 1719              (fp = file_info_new(P, mp)) == NULL) {
1511      -                P->core->core_errno = errno;
     1720 +                core->core_errno = errno;
1512 1721                  dprintf("failed to malloc mapping data\n");
1513 1722                  return (0); /* Abort */
1514 1723          }
1515 1724          fp->file_map = mp;
1516 1725  
1517 1726          /* Create a local copy of the load object representation */
1518 1727          if ((fp->file_lo = calloc(1, sizeof (rd_loadobj_t))) == NULL) {
1519      -                P->core->core_errno = errno;
     1728 +                core->core_errno = errno;
1520 1729                  dprintf("failed to malloc mapping data\n");
1521 1730                  return (0); /* Abort */
1522 1731          }
1523 1732          *fp->file_lo = *rlp;
1524 1733  
1525 1734          if (lname[0] != '\0') {
1526 1735                  /*
1527 1736                   * Naming dance part 1: if we got a name from librtld_db, then
1528 1737                   * copy this name to the prmap_t if it is unnamed.  If the
1529 1738                   * file_info_t is unnamed, name it after the lname.
↓ open down ↓ 246 lines elided ↑ open up ↑
1776 1985  /*
1777 1986   * Main engine for core file initialization: given an fd for the core file
1778 1987   * and an optional pathname, construct the ps_prochandle.  The aout_path can
1779 1988   * either be a suggested executable pathname, or a suggested directory to
1780 1989   * use as a possible current working directory.
1781 1990   */
1782 1991  struct ps_prochandle *
1783 1992  Pfgrab_core(int core_fd, const char *aout_path, int *perr)
1784 1993  {
1785 1994          struct ps_prochandle *P;
     1995 +        core_info_t *core_info;
1786 1996          map_info_t *stk_mp, *brk_mp;
1787 1997          const char *execname;
1788 1998          char *interp;
1789 1999          int i, notes, pagesize;
1790 2000          uintptr_t addr, base_addr;
1791 2001          struct stat64 stbuf;
1792 2002          void *phbuf, *php;
1793 2003          size_t nbytes;
1794 2004  
1795 2005          elf_file_t aout;
↓ open down ↓ 45 lines elided ↑ open up ↑
1841 2051          (void) mutex_init(&P->proc_lock, USYNC_THREAD, NULL);
1842 2052          P->state = PS_DEAD;
1843 2053          P->pid = (pid_t)-1;
1844 2054          P->asfd = core.e_fd;
1845 2055          P->ctlfd = -1;
1846 2056          P->statfd = -1;
1847 2057          P->agentctlfd = -1;
1848 2058          P->agentstatfd = -1;
1849 2059          P->zoneroot = NULL;
1850 2060          P->info_valid = 1;
1851      -        P->ops = &P_core_ops;
     2061 +        Pinit_ops(&P->ops, &P_core_ops);
1852 2062  
1853 2063          Pinitsym(P);
1854 2064  
1855 2065          /*
1856 2066           * Fstat and open the core file and make sure it is a valid ELF core.
1857 2067           */
1858 2068          if (fstat64(P->asfd, &stbuf) == -1) {
1859 2069                  *perr = G_STRANGE;
1860 2070                  goto err;
1861 2071          }
1862 2072  
1863 2073          if (core_elf_fdopen(&core, ET_CORE, perr) == -1)
1864 2074                  goto err;
1865 2075  
1866 2076          /*
1867 2077           * Allocate and initialize a core_info_t to hang off the ps_prochandle
1868 2078           * structure.  We keep all core-specific information in this structure.
1869 2079           */
1870      -        if ((P->core = calloc(1, sizeof (core_info_t))) == NULL) {
     2080 +        if ((core_info = calloc(1, sizeof (core_info_t))) == NULL) {
1871 2081                  *perr = G_STRANGE;
1872 2082                  goto err;
1873 2083          }
1874 2084  
1875      -        list_link(&P->core->core_lwp_head, NULL);
1876      -        P->core->core_size = stbuf.st_size;
     2085 +        P->data = core_info;
     2086 +        list_link(&core_info->core_lwp_head, NULL);
     2087 +        core_info->core_size = stbuf.st_size;
1877 2088          /*
1878 2089           * In the days before adjustable core file content, this was the
1879 2090           * default core file content. For new core files, this value will
1880 2091           * be overwritten by the NT_CONTENT note section.
1881 2092           */
1882      -        P->core->core_content = CC_CONTENT_STACK | CC_CONTENT_HEAP |
     2093 +        core_info->core_content = CC_CONTENT_STACK | CC_CONTENT_HEAP |
1883 2094              CC_CONTENT_DATA | CC_CONTENT_RODATA | CC_CONTENT_ANON |
1884 2095              CC_CONTENT_SHANON;
1885 2096  
1886 2097          switch (core.e_hdr.e_ident[EI_CLASS]) {
1887 2098          case ELFCLASS32:
1888      -                P->core->core_dmodel = PR_MODEL_ILP32;
     2099 +                core_info->core_dmodel = PR_MODEL_ILP32;
1889 2100                  break;
1890 2101          case ELFCLASS64:
1891      -                P->core->core_dmodel = PR_MODEL_LP64;
     2102 +                core_info->core_dmodel = PR_MODEL_LP64;
1892 2103                  break;
1893 2104          default:
1894 2105                  *perr = G_FORMAT;
1895 2106                  goto err;
1896 2107          }
1897 2108  
1898 2109          /*
1899 2110           * Because the core file may be a large file, we can't use libelf to
1900 2111           * read the Phdrs.  We use e_phnum and e_phentsize to simplify things.
1901 2112           */
↓ open down ↓ 205 lines elided ↑ open up ↑
2107 2318           * AT_BASE auxv element tells us the address where it was mapped,
2108 2319           * and the .interp section of the executable tells us its path.
2109 2320           * If for some reason that doesn't pan out, just use ld.so.1.
2110 2321           */
2111 2322          if (intp_scn != NULL && (dp = elf_getdata(intp_scn, NULL)) != NULL &&
2112 2323              dp->d_size != 0) {
2113 2324                  dprintf(".interp = <%s>\n", (char *)dp->d_buf);
2114 2325                  interp = dp->d_buf;
2115 2326  
2116 2327          } else if (base_addr != (uintptr_t)-1L) {
2117      -                if (P->core->core_dmodel == PR_MODEL_LP64)
     2328 +                if (core_info->core_dmodel == PR_MODEL_LP64)
2118 2329                          interp = "/usr/lib/64/ld.so.1";
2119 2330                  else
2120 2331                          interp = "/usr/lib/ld.so.1";
2121 2332  
2122 2333                  dprintf(".interp section is missing or could not be read; "
2123 2334                      "defaulting to %s\n", interp);
2124 2335          } else
2125 2336                  dprintf("detected statically linked executable\n");
2126 2337  
2127 2338          /*
↓ open down ↓ 94 lines elided ↑ open up ↑
2222 2433           * in the core, which will allow us to construct the file info
2223 2434           * we need to provide symbol information for the other shared
2224 2435           * libraries, and also to fill in the missing mapping names.
2225 2436           */
2226 2437          rd_log(_libproc_debug);
2227 2438  
2228 2439          if ((P->rap = rd_new(P)) != NULL) {
2229 2440                  (void) rd_loadobj_iter(P->rap, (rl_iter_f *)
2230 2441                      core_iter_mapping, P);
2231 2442  
2232      -                if (P->core->core_errno != 0) {
2233      -                        errno = P->core->core_errno;
     2443 +                if (core_info->core_errno != 0) {
     2444 +                        errno = core_info->core_errno;
2234 2445                          *perr = G_STRANGE;
2235 2446                          goto err;
2236 2447                  }
2237 2448          } else
2238 2449                  dprintf("failed to initialize rtld_db agent\n");
2239 2450  
2240 2451          /*
2241 2452           * If there are sections, load them and process the data from any
2242 2453           * sections that we can use to annotate the file_info_t's.
2243 2454           */
↓ open down ↓ 43 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX