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


   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*
  26  * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
  27  * Copyright (c) 2013, Joyent, Inc. All rights reserved.

  28  */
  29 
  30 #include <sys/types.h>
  31 #include <sys/utsname.h>
  32 #include <sys/sysmacros.h>
  33 #include <sys/proc.h>
  34 
  35 #include <alloca.h>
  36 #include <rtld_db.h>
  37 #include <libgen.h>
  38 #include <limits.h>
  39 #include <string.h>
  40 #include <stdlib.h>
  41 #include <unistd.h>
  42 #include <errno.h>
  43 #include <gelf.h>
  44 #include <stddef.h>
  45 #include <signal.h>
  46 
  47 #include "libproc.h"


  94                         break;
  95 
  96                 resid -= len;
  97                 addr += len;
  98                 buf = (char *)buf + len;
  99         }
 100 
 101         /*
 102          * Important: Be consistent with the behavior of i/o on the as file:
 103          * writing to an invalid address yields EIO; reading from an invalid
 104          * address falls through to returning success and zero bytes.
 105          */
 106         if (resid == n && n != 0 && prw != pread64) {
 107                 errno = EIO;
 108                 return (-1);
 109         }
 110 
 111         return (n - resid);
 112 }
 113 

 114 static ssize_t
 115 Pread_core(struct ps_prochandle *P, void *buf, size_t n, uintptr_t addr)

 116 {
 117         return (core_rw(P, buf, n, addr, pread64));
 118 }
 119 

 120 static ssize_t
 121 Pwrite_core(struct ps_prochandle *P, const void *buf, size_t n, uintptr_t addr)

 122 {
 123         return (core_rw(P, (void *)buf, n, addr,
 124             (ssize_t (*)(int, void *, size_t, off64_t)) pwrite64));
 125 }
 126 
 127 static const ps_rwops_t P_core_ops = { Pread_core, Pwrite_core };




 128 














































































































































































 129 /*
 130  * Return the lwp_info_t for the given lwpid.  If no such lwpid has been
 131  * encountered yet, allocate a new structure and return a pointer to it.
 132  * Create a list of lwp_info_t structures sorted in decreasing lwp_id order.
 133  */
 134 static lwp_info_t *
 135 lwpid2info(struct ps_prochandle *P, lwpid_t id)
 136 {
 137         lwp_info_t *lwp = list_next(&P->core->core_lwp_head);

 138         lwp_info_t *next;
 139         uint_t i;
 140 
 141         for (i = 0; i < P->core->core_nlwp; i++, lwp = list_next(lwp)) {
 142                 if (lwp->lwp_id == id) {
 143                         P->core->core_lwp = lwp;
 144                         return (lwp);
 145                 }
 146                 if (lwp->lwp_id < id) {
 147                         break;
 148                 }
 149         }
 150 
 151         next = lwp;
 152         if ((lwp = calloc(1, sizeof (lwp_info_t))) == NULL)
 153                 return (NULL);
 154 
 155         list_link(lwp, next);
 156         lwp->lwp_id = id;
 157 
 158         P->core->core_lwp = lwp;
 159         P->core->core_nlwp++;
 160 
 161         return (lwp);
 162 }
 163 
 164 /*
 165  * The core file itself contains a series of NOTE segments containing saved
 166  * structures from /proc at the time the process died.  For each note we
 167  * comprehend, we define a function to read it in from the core file,
 168  * convert it to our native data model if necessary, and store it inside
 169  * the ps_prochandle.  Each function is invoked by Pfgrab_core() with the
 170  * seek pointer on P->asfd positioned appropriately.  We populate a table
 171  * of pointers to these note functions below.
 172  */
 173 
 174 static int
 175 note_pstatus(struct ps_prochandle *P, size_t nbytes)
 176 {
 177 #ifdef _LP64
 178         if (P->core->core_dmodel == PR_MODEL_ILP32) {


 179                 pstatus32_t ps32;
 180 
 181                 if (nbytes < sizeof (pstatus32_t) ||
 182                     read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32))
 183                         goto err;
 184 
 185                 pstatus_32_to_n(&ps32, &P->status);
 186 
 187         } else
 188 #endif
 189         if (nbytes < sizeof (pstatus_t) ||
 190             read(P->asfd, &P->status, sizeof (pstatus_t)) != sizeof (pstatus_t))
 191                 goto err;
 192 
 193         P->orig_status = P->status;
 194         P->pid = P->status.pr_pid;
 195 
 196         return (0);
 197 
 198 err:
 199         dprintf("Pgrab_core: failed to read NT_PSTATUS\n");
 200         return (-1);
 201 }
 202 
 203 static int
 204 note_lwpstatus(struct ps_prochandle *P, size_t nbytes)
 205 {
 206         lwp_info_t *lwp;
 207         lwpstatus_t lps;
 208 
 209 #ifdef _LP64
 210         if (P->core->core_dmodel == PR_MODEL_ILP32) {


 211                 lwpstatus32_t l32;
 212 
 213                 if (nbytes < sizeof (lwpstatus32_t) ||
 214                     read(P->asfd, &l32, sizeof (l32)) != sizeof (l32))
 215                         goto err;
 216 
 217                 lwpstatus_32_to_n(&l32, &lps);
 218         } else
 219 #endif
 220         if (nbytes < sizeof (lwpstatus_t) ||
 221             read(P->asfd, &lps, sizeof (lps)) != sizeof (lps))
 222                 goto err;
 223 
 224         if ((lwp = lwpid2info(P, lps.pr_lwpid)) == NULL) {
 225                 dprintf("Pgrab_core: failed to add NT_LWPSTATUS\n");
 226                 return (-1);
 227         }
 228 
 229         /*
 230          * Erase a useless and confusing artifact of the kernel implementation:
 231          * the lwps which did *not* create the core will show SIGKILL.  We can
 232          * be assured this is bogus because SIGKILL can't produce core files.
 233          */
 234         if (lps.pr_cursig == SIGKILL)
 235                 lps.pr_cursig = 0;
 236 
 237         (void) memcpy(&lwp->lwp_status, &lps, sizeof (lps));
 238         return (0);
 239 
 240 err:
 241         dprintf("Pgrab_core: failed to read NT_LWPSTATUS\n");
 242         return (-1);
 243 }
 244 
 245 static int
 246 note_psinfo(struct ps_prochandle *P, size_t nbytes)
 247 {
 248 #ifdef _LP64
 249         if (P->core->core_dmodel == PR_MODEL_ILP32) {


 250                 psinfo32_t ps32;
 251 
 252                 if (nbytes < sizeof (psinfo32_t) ||
 253                     read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32))
 254                         goto err;
 255 
 256                 psinfo_32_to_n(&ps32, &P->psinfo);
 257         } else
 258 #endif
 259         if (nbytes < sizeof (psinfo_t) ||
 260             read(P->asfd, &P->psinfo, sizeof (psinfo_t)) != sizeof (psinfo_t))
 261                 goto err;
 262 
 263         dprintf("pr_fname = <%s>\n", P->psinfo.pr_fname);
 264         dprintf("pr_psargs = <%s>\n", P->psinfo.pr_psargs);
 265         dprintf("pr_wstat = 0x%x\n", P->psinfo.pr_wstat);
 266 
 267         return (0);
 268 
 269 err:
 270         dprintf("Pgrab_core: failed to read NT_PSINFO\n");
 271         return (-1);
 272 }
 273 
 274 static int
 275 note_lwpsinfo(struct ps_prochandle *P, size_t nbytes)
 276 {
 277         lwp_info_t *lwp;
 278         lwpsinfo_t lps;
 279 
 280 #ifdef _LP64
 281         if (P->core->core_dmodel == PR_MODEL_ILP32) {


 282                 lwpsinfo32_t l32;
 283 
 284                 if (nbytes < sizeof (lwpsinfo32_t) ||
 285                     read(P->asfd, &l32, sizeof (l32)) != sizeof (l32))
 286                         goto err;
 287 
 288                 lwpsinfo_32_to_n(&l32, &lps);
 289         } else
 290 #endif
 291         if (nbytes < sizeof (lwpsinfo_t) ||
 292             read(P->asfd, &lps, sizeof (lps)) != sizeof (lps))
 293                 goto err;
 294 
 295         if ((lwp = lwpid2info(P, lps.pr_lwpid)) == NULL) {
 296                 dprintf("Pgrab_core: failed to add NT_LWPSINFO\n");
 297                 return (-1);
 298         }
 299 
 300         (void) memcpy(&lwp->lwp_psinfo, &lps, sizeof (lps));
 301         return (0);


 311         prfdinfo_t prfd;
 312         fd_info_t *fip;
 313 
 314         if ((nbytes < sizeof (prfd)) ||
 315             (read(P->asfd, &prfd, sizeof (prfd)) != sizeof (prfd))) {
 316                 dprintf("Pgrab_core: failed to read NT_FDINFO\n");
 317                 return (-1);
 318         }
 319 
 320         if ((fip = Pfd2info(P, prfd.pr_fd)) == NULL) {
 321                 dprintf("Pgrab_core: failed to add NT_FDINFO\n");
 322                 return (-1);
 323         }
 324         (void) memcpy(&fip->fd_info, &prfd, sizeof (prfd));
 325         return (0);
 326 }
 327 
 328 static int
 329 note_platform(struct ps_prochandle *P, size_t nbytes)
 330 {

 331         char *plat;
 332 
 333         if (P->core->core_platform != NULL)
 334                 return (0);     /* Already seen */
 335 
 336         if (nbytes != 0 && ((plat = malloc(nbytes + 1)) != NULL)) {
 337                 if (read(P->asfd, plat, nbytes) != nbytes) {
 338                         dprintf("Pgrab_core: failed to read NT_PLATFORM\n");
 339                         free(plat);
 340                         return (-1);
 341                 }
 342                 plat[nbytes - 1] = '\0';
 343                 P->core->core_platform = plat;
 344         }
 345 
 346         return (0);
 347 }
 348 
 349 static int
 350 note_utsname(struct ps_prochandle *P, size_t nbytes)
 351 {

 352         size_t ubytes = sizeof (struct utsname);
 353         struct utsname *utsp;
 354 
 355         if (P->core->core_uts != NULL || nbytes < ubytes)
 356                 return (0);     /* Already seen or bad size */
 357 
 358         if ((utsp = malloc(ubytes)) == NULL)
 359                 return (-1);
 360 
 361         if (read(P->asfd, utsp, ubytes) != ubytes) {
 362                 dprintf("Pgrab_core: failed to read NT_UTSNAME\n");
 363                 free(utsp);
 364                 return (-1);
 365         }
 366 
 367         if (_libproc_debug) {
 368                 dprintf("uts.sysname = \"%s\"\n", utsp->sysname);
 369                 dprintf("uts.nodename = \"%s\"\n", utsp->nodename);
 370                 dprintf("uts.release = \"%s\"\n", utsp->release);
 371                 dprintf("uts.version = \"%s\"\n", utsp->version);
 372                 dprintf("uts.machine = \"%s\"\n", utsp->machine);
 373         }
 374 
 375         P->core->core_uts = utsp;
 376         return (0);
 377 }
 378 
 379 static int
 380 note_content(struct ps_prochandle *P, size_t nbytes)
 381 {

 382         core_content_t content;
 383 
 384         if (sizeof (P->core->core_content) != nbytes)
 385                 return (-1);
 386 
 387         if (read(P->asfd, &content, sizeof (content)) != sizeof (content))
 388                 return (-1);
 389 
 390         P->core->core_content = content;
 391 
 392         dprintf("core content = %llx\n", content);
 393 
 394         return (0);
 395 }
 396 
 397 static int
 398 note_cred(struct ps_prochandle *P, size_t nbytes)
 399 {

 400         prcred_t *pcrp;
 401         int ngroups;
 402         const size_t min_size = sizeof (prcred_t) - sizeof (gid_t);
 403 
 404         /*
 405          * We allow for prcred_t notes that are actually smaller than a
 406          * prcred_t since the last member isn't essential if there are
 407          * no group memberships. This allows for more flexibility when it
 408          * comes to slightly malformed -- but still valid -- notes.
 409          */
 410         if (P->core->core_cred != NULL || nbytes < min_size)
 411                 return (0);     /* Already seen or bad size */
 412 
 413         ngroups = (nbytes - min_size) / sizeof (gid_t);
 414         nbytes = sizeof (prcred_t) + (ngroups - 1) * sizeof (gid_t);
 415 
 416         if ((pcrp = malloc(nbytes)) == NULL)
 417                 return (-1);
 418 
 419         if (read(P->asfd, pcrp, nbytes) != nbytes) {
 420                 dprintf("Pgrab_core: failed to read NT_PRCRED\n");
 421                 free(pcrp);
 422                 return (-1);
 423         }
 424 
 425         if (pcrp->pr_ngroups > ngroups) {
 426                 dprintf("pr_ngroups = %d; resetting to %d based on note size\n",
 427                     pcrp->pr_ngroups, ngroups);
 428                 pcrp->pr_ngroups = ngroups;
 429         }
 430 
 431         P->core->core_cred = pcrp;
 432         return (0);
 433 }
 434 
 435 #if defined(__i386) || defined(__amd64)
 436 static int
 437 note_ldt(struct ps_prochandle *P, size_t nbytes)
 438 {

 439         struct ssd *pldt;
 440         uint_t nldt;
 441 
 442         if (P->core->core_ldt != NULL || nbytes < sizeof (struct ssd))
 443                 return (0);     /* Already seen or bad size */
 444 
 445         nldt = nbytes / sizeof (struct ssd);
 446         nbytes = nldt * sizeof (struct ssd);
 447 
 448         if ((pldt = malloc(nbytes)) == NULL)
 449                 return (-1);
 450 
 451         if (read(P->asfd, pldt, nbytes) != nbytes) {
 452                 dprintf("Pgrab_core: failed to read NT_LDT\n");
 453                 free(pldt);
 454                 return (-1);
 455         }
 456 
 457         P->core->core_ldt = pldt;
 458         P->core->core_nldt = nldt;
 459         return (0);
 460 }
 461 #endif  /* __i386 */
 462 
 463 static int
 464 note_priv(struct ps_prochandle *P, size_t nbytes)
 465 {

 466         prpriv_t *pprvp;
 467 
 468         if (P->core->core_priv != NULL || nbytes < sizeof (prpriv_t))
 469                 return (0);     /* Already seen or bad size */
 470 
 471         if ((pprvp = malloc(nbytes)) == NULL)
 472                 return (-1);
 473 
 474         if (read(P->asfd, pprvp, nbytes) != nbytes) {
 475                 dprintf("Pgrab_core: failed to read NT_PRPRIV\n");
 476                 free(pprvp);
 477                 return (-1);
 478         }
 479 
 480         P->core->core_priv = pprvp;
 481         P->core->core_priv_size = nbytes;
 482         return (0);
 483 }
 484 
 485 static int
 486 note_priv_info(struct ps_prochandle *P, size_t nbytes)
 487 {

 488         extern void *__priv_parse_info();
 489         priv_impl_info_t *ppii;
 490 
 491         if (P->core->core_privinfo != NULL ||
 492             nbytes < sizeof (priv_impl_info_t))
 493                 return (0);     /* Already seen or bad size */
 494 
 495         if ((ppii = malloc(nbytes)) == NULL)
 496                 return (-1);
 497 
 498         if (read(P->asfd, ppii, nbytes) != nbytes ||
 499             PRIV_IMPL_INFO_SIZE(ppii) != nbytes) {
 500                 dprintf("Pgrab_core: failed to read NT_PRPRIVINFO\n");
 501                 free(ppii);
 502                 return (-1);
 503         }
 504 
 505         P->core->core_privinfo = __priv_parse_info(ppii);
 506         P->core->core_ppii = ppii;
 507         return (0);
 508 }
 509 
 510 static int
 511 note_zonename(struct ps_prochandle *P, size_t nbytes)
 512 {

 513         char *zonename;
 514 
 515         if (P->core->core_zonename != NULL)
 516                 return (0);     /* Already seen */
 517 
 518         if (nbytes != 0) {
 519                 if ((zonename = malloc(nbytes)) == NULL)
 520                         return (-1);
 521                 if (read(P->asfd, zonename, nbytes) != nbytes) {
 522                         dprintf("Pgrab_core: failed to read NT_ZONENAME\n");
 523                         free(zonename);
 524                         return (-1);
 525                 }
 526                 zonename[nbytes - 1] = '\0';
 527                 P->core->core_zonename = zonename;
 528         }
 529 
 530         return (0);
 531 }
 532 
 533 static int
 534 note_auxv(struct ps_prochandle *P, size_t nbytes)
 535 {
 536         size_t n, i;
 537 
 538 #ifdef _LP64
 539         if (P->core->core_dmodel == PR_MODEL_ILP32) {


 540                 auxv32_t *a32;
 541 
 542                 n = nbytes / sizeof (auxv32_t);
 543                 nbytes = n * sizeof (auxv32_t);
 544                 a32 = alloca(nbytes);
 545 
 546                 if (read(P->asfd, a32, nbytes) != nbytes) {
 547                         dprintf("Pgrab_core: failed to read NT_AUXV\n");
 548                         return (-1);
 549                 }
 550 
 551                 if ((P->auxv = malloc(sizeof (auxv_t) * (n + 1))) == NULL)
 552                         return (-1);
 553 
 554                 for (i = 0; i < n; i++)
 555                         auxv_32_to_n(&a32[i], &P->auxv[i]);
 556 
 557         } else {
 558 #endif
 559                 n = nbytes / sizeof (auxv_t);


 577                             P->auxv[i].a_type, P->auxv[i].a_un.a_val);
 578                 }
 579         }
 580 
 581         /*
 582          * Defensive coding for loops which depend upon the auxv array being
 583          * terminated by an AT_NULL element; in each case, we've allocated
 584          * P->auxv to have an additional element which we force to be AT_NULL.
 585          */
 586         P->auxv[n].a_type = AT_NULL;
 587         P->auxv[n].a_un.a_val = 0L;
 588         P->nauxv = (int)n;
 589 
 590         return (0);
 591 }
 592 
 593 #ifdef __sparc
 594 static int
 595 note_xreg(struct ps_prochandle *P, size_t nbytes)
 596 {
 597         lwp_info_t *lwp = P->core->core_lwp;

 598         size_t xbytes = sizeof (prxregset_t);
 599         prxregset_t *xregs;
 600 
 601         if (lwp == NULL || lwp->lwp_xregs != NULL || nbytes < xbytes)
 602                 return (0);     /* No lwp yet, already seen, or bad size */
 603 
 604         if ((xregs = malloc(xbytes)) == NULL)
 605                 return (-1);
 606 
 607         if (read(P->asfd, xregs, xbytes) != xbytes) {
 608                 dprintf("Pgrab_core: failed to read NT_PRXREG\n");
 609                 free(xregs);
 610                 return (-1);
 611         }
 612 
 613         lwp->lwp_xregs = xregs;
 614         return (0);
 615 }
 616 
 617 static int
 618 note_gwindows(struct ps_prochandle *P, size_t nbytes)
 619 {
 620         lwp_info_t *lwp = P->core->core_lwp;

 621 
 622         if (lwp == NULL || lwp->lwp_gwins != NULL || nbytes == 0)
 623                 return (0);     /* No lwp yet or already seen or no data */
 624 
 625         if ((lwp->lwp_gwins = malloc(sizeof (gwindows_t))) == NULL)
 626                 return (-1);
 627 
 628         /*
 629          * Since the amount of gwindows data varies with how many windows were
 630          * actually saved, we just read up to the minimum of the note size
 631          * and the size of the gwindows_t type.  It doesn't matter if the read
 632          * fails since we have to zero out gwindows first anyway.
 633          */
 634 #ifdef _LP64
 635         if (P->core->core_dmodel == PR_MODEL_ILP32) {
 636                 gwindows32_t g32;
 637 
 638                 (void) memset(&g32, 0, sizeof (g32));
 639                 (void) read(P->asfd, &g32, MIN(nbytes, sizeof (g32)));
 640                 gwindows_32_to_n(&g32, lwp->lwp_gwins);
 641 
 642         } else {
 643 #endif
 644                 (void) memset(lwp->lwp_gwins, 0, sizeof (gwindows_t));
 645                 (void) read(P->asfd, lwp->lwp_gwins,
 646                     MIN(nbytes, sizeof (gwindows_t)));
 647 #ifdef _LP64
 648         }
 649 #endif
 650         return (0);
 651 }
 652 
 653 #ifdef __sparcv9
 654 static int
 655 note_asrs(struct ps_prochandle *P, size_t nbytes)
 656 {
 657         lwp_info_t *lwp = P->core->core_lwp;

 658         int64_t *asrs;
 659 
 660         if (lwp == NULL || lwp->lwp_asrs != NULL || nbytes < sizeof (asrset_t))
 661                 return (0);     /* No lwp yet, already seen, or bad size */
 662 
 663         if ((asrs = malloc(sizeof (asrset_t))) == NULL)
 664                 return (-1);
 665 
 666         if (read(P->asfd, asrs, sizeof (asrset_t)) != sizeof (asrset_t)) {
 667                 dprintf("Pgrab_core: failed to read NT_ASRS\n");
 668                 free(asrs);
 669                 return (-1);
 670         }
 671 
 672         lwp->lwp_asrs = asrs;
 673         return (0);
 674 }
 675 #endif  /* __sparcv9 */
 676 #endif  /* __sparc */
 677 
 678 static int
 679 note_spymaster(struct ps_prochandle *P, size_t nbytes)
 680 {
 681 #ifdef _LP64
 682         if (P->core->core_dmodel == PR_MODEL_ILP32) {


 683                 psinfo32_t ps32;
 684 
 685                 if (nbytes < sizeof (psinfo32_t) ||
 686                     read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32))
 687                         goto err;
 688 
 689                 psinfo_32_to_n(&ps32, &P->spymaster);
 690         } else
 691 #endif
 692         if (nbytes < sizeof (psinfo_t) || read(P->asfd,
 693             &P->spymaster, sizeof (psinfo_t)) != sizeof (psinfo_t))
 694                 goto err;
 695 
 696         dprintf("spymaster pr_fname = <%s>\n", P->psinfo.pr_fname);
 697         dprintf("spymaster pr_psargs = <%s>\n", P->psinfo.pr_psargs);
 698         dprintf("spymaster pr_wstat = 0x%x\n", P->psinfo.pr_wstat);
 699 
 700         return (0);
 701 
 702 err:


 813                     si->si_pid, si->si_uid, si->si_zoneid, si->si_ctid);
 814         } else {
 815                 (void) snprintf(info, sizeof (info),
 816                     "code=%d", si->si_code);
 817         }
 818 
 819         Perror_printf(P, incfmt, sig, info);
 820         Perror_printf(P, msgfmt, addr);
 821 
 822         dprintf(incfmt, sig, info);
 823         dprintf(msgfmt, addr);
 824 }
 825 
 826 /*
 827  * Add information on the address space mapping described by the given
 828  * PT_LOAD program header.  We fill in more information on the mapping later.
 829  */
 830 static int
 831 core_add_mapping(struct ps_prochandle *P, GElf_Phdr *php)
 832 {

 833         prmap_t pmap;
 834 
 835         dprintf("mapping base %llx filesz %llu memsz %llu offset %llu\n",
 836             (u_longlong_t)php->p_vaddr, (u_longlong_t)php->p_filesz,
 837             (u_longlong_t)php->p_memsz, (u_longlong_t)php->p_offset);
 838 
 839         pmap.pr_vaddr = (uintptr_t)php->p_vaddr;
 840         pmap.pr_size = php->p_memsz;
 841 
 842         /*
 843          * If Pgcore() or elfcore() fail to write a mapping, they will set
 844          * PF_SUNW_FAILURE in the Phdr and try to stash away the errno for us.
 845          */
 846         if (php->p_flags & PF_SUNW_FAILURE) {
 847                 core_report_mapping(P, php);
 848         } else if (php->p_filesz != 0 && php->p_offset >= P->core->core_size) {
 849                 Perror_printf(P, "core file may be corrupt -- data for mapping "
 850                     "at %p is missing\n", (void *)(uintptr_t)php->p_vaddr);
 851                 dprintf("core file may be corrupt -- data for mapping "
 852                     "at %p is missing\n", (void *)(uintptr_t)php->p_vaddr);
 853         }
 854 
 855         /*
 856          * The mapping name and offset will hopefully be filled in
 857          * by the librtld_db agent.  Unfortunately, if it isn't a
 858          * shared library mapping, this information is gone forever.
 859          */
 860         pmap.pr_mapname[0] = '\0';
 861         pmap.pr_offset = 0;
 862 
 863         pmap.pr_mflags = 0;
 864         if (php->p_flags & PF_R)
 865                 pmap.pr_mflags |= MA_READ;
 866         if (php->p_flags & PF_W)
 867                 pmap.pr_mflags |= MA_WRITE;
 868         if (php->p_flags & PF_X)


1464         /*
1465          * It wouldn't be procfs-related code if we didn't make use of
1466          * unclean knowledge of segvn, even in userland ... the prmap_t's
1467          * pr_offset field will be the segvn offset from mmap(2)ing the
1468          * data section, which will be the file offset & PAGEMASK.
1469          */
1470         pagemask = ~(mp->map_pmap.pr_pagesize - 1);
1471         mp->map_pmap.pr_offset = phdr.p_offset & pagemask;
1472 
1473         return (mp);
1474 }
1475 
1476 /*
1477  * Librtld_db agent callback for iterating over load object mappings.
1478  * For each load object, we allocate a new file_info_t, perform naming,
1479  * and attempt to construct a symbol table for the load object.
1480  */
1481 static int
1482 core_iter_mapping(const rd_loadobj_t *rlp, struct ps_prochandle *P)
1483 {

1484         char lname[PATH_MAX], buf[PATH_MAX];
1485         file_info_t *fp;
1486         map_info_t *mp;
1487 
1488         if (Pread_string(P, lname, PATH_MAX, (off_t)rlp->rl_nameaddr) <= 0) {
1489                 dprintf("failed to read name %p\n", (void *)rlp->rl_nameaddr);
1490                 return (1); /* Keep going; forget this if we can't get a name */
1491         }
1492 
1493         dprintf("rd_loadobj name = \"%s\" rl_base = %p\n",
1494             lname, (void *)rlp->rl_base);
1495 
1496         if ((mp = Paddr2mptr(P, rlp->rl_base)) == NULL) {
1497                 dprintf("no mapping for %p\n", (void *)rlp->rl_base);
1498                 return (1); /* No mapping; advance to next mapping */
1499         }
1500 
1501         /*
1502          * Create a new file_info_t for this mapping, and therefore for
1503          * this load object.
1504          *
1505          * If there's an ELF header at the beginning of this mapping,
1506          * file_info_new() will try to use its section headers to
1507          * identify any other mappings that belong to this load object.
1508          */
1509         if ((fp = mp->map_file) == NULL &&
1510             (fp = file_info_new(P, mp)) == NULL) {
1511                 P->core->core_errno = errno;
1512                 dprintf("failed to malloc mapping data\n");
1513                 return (0); /* Abort */
1514         }
1515         fp->file_map = mp;
1516 
1517         /* Create a local copy of the load object representation */
1518         if ((fp->file_lo = calloc(1, sizeof (rd_loadobj_t))) == NULL) {
1519                 P->core->core_errno = errno;
1520                 dprintf("failed to malloc mapping data\n");
1521                 return (0); /* Abort */
1522         }
1523         *fp->file_lo = *rlp;
1524 
1525         if (lname[0] != '\0') {
1526                 /*
1527                  * Naming dance part 1: if we got a name from librtld_db, then
1528                  * copy this name to the prmap_t if it is unnamed.  If the
1529                  * file_info_t is unnamed, name it after the lname.
1530                  */
1531                 if (mp->map_pmap.pr_mapname[0] == '\0') {
1532                         (void) strncpy(mp->map_pmap.pr_mapname, lname, PRMAPSZ);
1533                         mp->map_pmap.pr_mapname[PRMAPSZ - 1] = '\0';
1534                 }
1535 
1536                 if (fp->file_lname == NULL)
1537                         fp->file_lname = strdup(lname);
1538 
1539         } else if (fp->file_lname == NULL &&


1766                 } else if (strcmp(name, ".symtab") == 0) {
1767                         fake_up_symtab(P, &efp->e_hdr,
1768                             shp, &shdrs[shp->sh_link]);
1769                 }
1770         }
1771 out:
1772         free(shstrtab);
1773         free(shdrs);
1774 }
1775 
1776 /*
1777  * Main engine for core file initialization: given an fd for the core file
1778  * and an optional pathname, construct the ps_prochandle.  The aout_path can
1779  * either be a suggested executable pathname, or a suggested directory to
1780  * use as a possible current working directory.
1781  */
1782 struct ps_prochandle *
1783 Pfgrab_core(int core_fd, const char *aout_path, int *perr)
1784 {
1785         struct ps_prochandle *P;

1786         map_info_t *stk_mp, *brk_mp;
1787         const char *execname;
1788         char *interp;
1789         int i, notes, pagesize;
1790         uintptr_t addr, base_addr;
1791         struct stat64 stbuf;
1792         void *phbuf, *php;
1793         size_t nbytes;
1794 
1795         elf_file_t aout;
1796         elf_file_t core;
1797 
1798         Elf_Scn *scn, *intp_scn = NULL;
1799         Elf_Data *dp;
1800 
1801         GElf_Phdr phdr, note_phdr;
1802         GElf_Shdr shdr;
1803         GElf_Xword nleft;
1804 
1805         if (elf_version(EV_CURRENT) == EV_NONE) {


1831          *
1832          * 4. The read/write ops vector uses our core_rw() function defined
1833          *    above to handle i/o requests.
1834          */
1835         if ((P = malloc(sizeof (struct ps_prochandle))) == NULL) {
1836                 *perr = G_STRANGE;
1837                 return (NULL);
1838         }
1839 
1840         (void) memset(P, 0, sizeof (struct ps_prochandle));
1841         (void) mutex_init(&P->proc_lock, USYNC_THREAD, NULL);
1842         P->state = PS_DEAD;
1843         P->pid = (pid_t)-1;
1844         P->asfd = core.e_fd;
1845         P->ctlfd = -1;
1846         P->statfd = -1;
1847         P->agentctlfd = -1;
1848         P->agentstatfd = -1;
1849         P->zoneroot = NULL;
1850         P->info_valid = 1;
1851         P->ops = &P_core_ops;
1852 
1853         Pinitsym(P);
1854 
1855         /*
1856          * Fstat and open the core file and make sure it is a valid ELF core.
1857          */
1858         if (fstat64(P->asfd, &stbuf) == -1) {
1859                 *perr = G_STRANGE;
1860                 goto err;
1861         }
1862 
1863         if (core_elf_fdopen(&core, ET_CORE, perr) == -1)
1864                 goto err;
1865 
1866         /*
1867          * Allocate and initialize a core_info_t to hang off the ps_prochandle
1868          * structure.  We keep all core-specific information in this structure.
1869          */
1870         if ((P->core = calloc(1, sizeof (core_info_t))) == NULL) {
1871                 *perr = G_STRANGE;
1872                 goto err;
1873         }
1874 
1875         list_link(&P->core->core_lwp_head, NULL);
1876         P->core->core_size = stbuf.st_size;

1877         /*
1878          * In the days before adjustable core file content, this was the
1879          * default core file content. For new core files, this value will
1880          * be overwritten by the NT_CONTENT note section.
1881          */
1882         P->core->core_content = CC_CONTENT_STACK | CC_CONTENT_HEAP |
1883             CC_CONTENT_DATA | CC_CONTENT_RODATA | CC_CONTENT_ANON |
1884             CC_CONTENT_SHANON;
1885 
1886         switch (core.e_hdr.e_ident[EI_CLASS]) {
1887         case ELFCLASS32:
1888                 P->core->core_dmodel = PR_MODEL_ILP32;
1889                 break;
1890         case ELFCLASS64:
1891                 P->core->core_dmodel = PR_MODEL_LP64;
1892                 break;
1893         default:
1894                 *perr = G_FORMAT;
1895                 goto err;
1896         }
1897 
1898         /*
1899          * Because the core file may be a large file, we can't use libelf to
1900          * read the Phdrs.  We use e_phnum and e_phentsize to simplify things.
1901          */
1902         nbytes = core.e_hdr.e_phnum * core.e_hdr.e_phentsize;
1903 
1904         if ((phbuf = malloc(nbytes)) == NULL) {
1905                 *perr = G_STRANGE;
1906                 goto err;
1907         }
1908 
1909         if (pread64(core_fd, phbuf, nbytes, core.e_hdr.e_phoff) != nbytes) {
1910                 *perr = G_STRANGE;
1911                 free(phbuf);


2097 
2098         /*
2099          * Get the AT_BASE auxv element.  If this is missing (-1), then
2100          * we assume this is a statically-linked executable.
2101          */
2102         base_addr = Pgetauxval(P, AT_BASE);
2103 
2104         /*
2105          * In order to get librtld_db initialized, we'll need to identify
2106          * and name the mapping corresponding to the run-time linker.  The
2107          * AT_BASE auxv element tells us the address where it was mapped,
2108          * and the .interp section of the executable tells us its path.
2109          * If for some reason that doesn't pan out, just use ld.so.1.
2110          */
2111         if (intp_scn != NULL && (dp = elf_getdata(intp_scn, NULL)) != NULL &&
2112             dp->d_size != 0) {
2113                 dprintf(".interp = <%s>\n", (char *)dp->d_buf);
2114                 interp = dp->d_buf;
2115 
2116         } else if (base_addr != (uintptr_t)-1L) {
2117                 if (P->core->core_dmodel == PR_MODEL_LP64)
2118                         interp = "/usr/lib/64/ld.so.1";
2119                 else
2120                         interp = "/usr/lib/ld.so.1";
2121 
2122                 dprintf(".interp section is missing or could not be read; "
2123                     "defaulting to %s\n", interp);
2124         } else
2125                 dprintf("detected statically linked executable\n");
2126 
2127         /*
2128          * If we have an AT_BASE element, name the mapping at that address
2129          * using the interpreter pathname.  Name the corresponding data
2130          * mapping after the interpreter as well.
2131          */
2132         if (base_addr != (uintptr_t)-1L) {
2133                 elf_file_t intf;
2134 
2135                 P->map_ldso = core_name_mapping(P, base_addr, interp);
2136 
2137                 if (core_elf_open(&intf, interp, ET_DYN, NULL) == 0) {


2212                                 fp->file_ref++;
2213                         }
2214                 }
2215         }
2216 
2217         core_elf_close(&aout);
2218 
2219         /*
2220          * We now have enough information to initialize librtld_db.
2221          * After it warms up, we can iterate through the load object chain
2222          * in the core, which will allow us to construct the file info
2223          * we need to provide symbol information for the other shared
2224          * libraries, and also to fill in the missing mapping names.
2225          */
2226         rd_log(_libproc_debug);
2227 
2228         if ((P->rap = rd_new(P)) != NULL) {
2229                 (void) rd_loadobj_iter(P->rap, (rl_iter_f *)
2230                     core_iter_mapping, P);
2231 
2232                 if (P->core->core_errno != 0) {
2233                         errno = P->core->core_errno;
2234                         *perr = G_STRANGE;
2235                         goto err;
2236                 }
2237         } else
2238                 dprintf("failed to initialize rtld_db agent\n");
2239 
2240         /*
2241          * If there are sections, load them and process the data from any
2242          * sections that we can use to annotate the file_info_t's.
2243          */
2244         core_load_shdrs(P, &core);
2245 
2246         /*
2247          * If we previously located a stack or break mapping, and they are
2248          * still anonymous, we now assume that they were MAP_ANON mappings.
2249          * If brk_mp turns out to now have a name, then the heap is still
2250          * sitting at the end of the executable's data+bss mapping: remove
2251          * the previous MA_BREAK setting to be consistent with /proc.
2252          */
2253         if (stk_mp != NULL && stk_mp->map_pmap.pr_mapname[0] == '\0')




   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*
  26  * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
  27  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  28  * Copyright (c) 2013 by Delphix. All rights reserved.
  29  */
  30 
  31 #include <sys/types.h>
  32 #include <sys/utsname.h>
  33 #include <sys/sysmacros.h>
  34 #include <sys/proc.h>
  35 
  36 #include <alloca.h>
  37 #include <rtld_db.h>
  38 #include <libgen.h>
  39 #include <limits.h>
  40 #include <string.h>
  41 #include <stdlib.h>
  42 #include <unistd.h>
  43 #include <errno.h>
  44 #include <gelf.h>
  45 #include <stddef.h>
  46 #include <signal.h>
  47 
  48 #include "libproc.h"


  95                         break;
  96 
  97                 resid -= len;
  98                 addr += len;
  99                 buf = (char *)buf + len;
 100         }
 101 
 102         /*
 103          * Important: Be consistent with the behavior of i/o on the as file:
 104          * writing to an invalid address yields EIO; reading from an invalid
 105          * address falls through to returning success and zero bytes.
 106          */
 107         if (resid == n && n != 0 && prw != pread64) {
 108                 errno = EIO;
 109                 return (-1);
 110         }
 111 
 112         return (n - resid);
 113 }
 114 
 115 /*ARGSUSED*/
 116 static ssize_t
 117 Pread_core(struct ps_prochandle *P, void *buf, size_t n, uintptr_t addr,
 118     void *data)
 119 {
 120         return (core_rw(P, buf, n, addr, pread64));
 121 }
 122 
 123 /*ARGSUSED*/
 124 static ssize_t
 125 Pwrite_core(struct ps_prochandle *P, const void *buf, size_t n, uintptr_t addr,
 126     void *data)
 127 {
 128         return (core_rw(P, (void *)buf, n, addr,
 129             (ssize_t (*)(int, void *, size_t, off64_t)) pwrite64));
 130 }
 131 
 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;
 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 
 312 /*
 313  * Return the lwp_info_t for the given lwpid.  If no such lwpid has been
 314  * encountered yet, allocate a new structure and return a pointer to it.
 315  * Create a list of lwp_info_t structures sorted in decreasing lwp_id order.
 316  */
 317 static lwp_info_t *
 318 lwpid2info(struct ps_prochandle *P, lwpid_t id)
 319 {
 320         core_info_t *core = P->data;
 321         lwp_info_t *lwp = list_next(&core->core_lwp_head);
 322         lwp_info_t *next;
 323         uint_t i;
 324 
 325         for (i = 0; i < core->core_nlwp; i++, lwp = list_next(lwp)) {
 326                 if (lwp->lwp_id == id) {
 327                         core->core_lwp = lwp;
 328                         return (lwp);
 329                 }
 330                 if (lwp->lwp_id < id) {
 331                         break;
 332                 }
 333         }
 334 
 335         next = lwp;
 336         if ((lwp = calloc(1, sizeof (lwp_info_t))) == NULL)
 337                 return (NULL);
 338 
 339         list_link(lwp, next);
 340         lwp->lwp_id = id;
 341 
 342         core->core_lwp = lwp;
 343         core->core_nlwp++;
 344 
 345         return (lwp);
 346 }
 347 
 348 /*
 349  * The core file itself contains a series of NOTE segments containing saved
 350  * structures from /proc at the time the process died.  For each note we
 351  * comprehend, we define a function to read it in from the core file,
 352  * convert it to our native data model if necessary, and store it inside
 353  * the ps_prochandle.  Each function is invoked by Pfgrab_core() with the
 354  * seek pointer on P->asfd positioned appropriately.  We populate a table
 355  * of pointers to these note functions below.
 356  */
 357 
 358 static int
 359 note_pstatus(struct ps_prochandle *P, size_t nbytes)
 360 {
 361 #ifdef _LP64
 362         core_info_t *core = P->data;
 363 
 364         if (core->core_dmodel == PR_MODEL_ILP32) {
 365                 pstatus32_t ps32;
 366 
 367                 if (nbytes < sizeof (pstatus32_t) ||
 368                     read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32))
 369                         goto err;
 370 
 371                 pstatus_32_to_n(&ps32, &P->status);
 372 
 373         } else
 374 #endif
 375         if (nbytes < sizeof (pstatus_t) ||
 376             read(P->asfd, &P->status, sizeof (pstatus_t)) != sizeof (pstatus_t))
 377                 goto err;
 378 
 379         P->orig_status = P->status;
 380         P->pid = P->status.pr_pid;
 381 
 382         return (0);
 383 
 384 err:
 385         dprintf("Pgrab_core: failed to read NT_PSTATUS\n");
 386         return (-1);
 387 }
 388 
 389 static int
 390 note_lwpstatus(struct ps_prochandle *P, size_t nbytes)
 391 {
 392         lwp_info_t *lwp;
 393         lwpstatus_t lps;
 394 
 395 #ifdef _LP64
 396         core_info_t *core = P->data;
 397 
 398         if (core->core_dmodel == PR_MODEL_ILP32) {
 399                 lwpstatus32_t l32;
 400 
 401                 if (nbytes < sizeof (lwpstatus32_t) ||
 402                     read(P->asfd, &l32, sizeof (l32)) != sizeof (l32))
 403                         goto err;
 404 
 405                 lwpstatus_32_to_n(&l32, &lps);
 406         } else
 407 #endif
 408         if (nbytes < sizeof (lwpstatus_t) ||
 409             read(P->asfd, &lps, sizeof (lps)) != sizeof (lps))
 410                 goto err;
 411 
 412         if ((lwp = lwpid2info(P, lps.pr_lwpid)) == NULL) {
 413                 dprintf("Pgrab_core: failed to add NT_LWPSTATUS\n");
 414                 return (-1);
 415         }
 416 
 417         /*
 418          * Erase a useless and confusing artifact of the kernel implementation:
 419          * the lwps which did *not* create the core will show SIGKILL.  We can
 420          * be assured this is bogus because SIGKILL can't produce core files.
 421          */
 422         if (lps.pr_cursig == SIGKILL)
 423                 lps.pr_cursig = 0;
 424 
 425         (void) memcpy(&lwp->lwp_status, &lps, sizeof (lps));
 426         return (0);
 427 
 428 err:
 429         dprintf("Pgrab_core: failed to read NT_LWPSTATUS\n");
 430         return (-1);
 431 }
 432 
 433 static int
 434 note_psinfo(struct ps_prochandle *P, size_t nbytes)
 435 {
 436 #ifdef _LP64
 437         core_info_t *core = P->data;
 438 
 439         if (core->core_dmodel == PR_MODEL_ILP32) {
 440                 psinfo32_t ps32;
 441 
 442                 if (nbytes < sizeof (psinfo32_t) ||
 443                     read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32))
 444                         goto err;
 445 
 446                 psinfo_32_to_n(&ps32, &P->psinfo);
 447         } else
 448 #endif
 449         if (nbytes < sizeof (psinfo_t) ||
 450             read(P->asfd, &P->psinfo, sizeof (psinfo_t)) != sizeof (psinfo_t))
 451                 goto err;
 452 
 453         dprintf("pr_fname = <%s>\n", P->psinfo.pr_fname);
 454         dprintf("pr_psargs = <%s>\n", P->psinfo.pr_psargs);
 455         dprintf("pr_wstat = 0x%x\n", P->psinfo.pr_wstat);
 456 
 457         return (0);
 458 
 459 err:
 460         dprintf("Pgrab_core: failed to read NT_PSINFO\n");
 461         return (-1);
 462 }
 463 
 464 static int
 465 note_lwpsinfo(struct ps_prochandle *P, size_t nbytes)
 466 {
 467         lwp_info_t *lwp;
 468         lwpsinfo_t lps;
 469 
 470 #ifdef _LP64
 471         core_info_t *core = P->data;
 472 
 473         if (core->core_dmodel == PR_MODEL_ILP32) {
 474                 lwpsinfo32_t l32;
 475 
 476                 if (nbytes < sizeof (lwpsinfo32_t) ||
 477                     read(P->asfd, &l32, sizeof (l32)) != sizeof (l32))
 478                         goto err;
 479 
 480                 lwpsinfo_32_to_n(&l32, &lps);
 481         } else
 482 #endif
 483         if (nbytes < sizeof (lwpsinfo_t) ||
 484             read(P->asfd, &lps, sizeof (lps)) != sizeof (lps))
 485                 goto err;
 486 
 487         if ((lwp = lwpid2info(P, lps.pr_lwpid)) == NULL) {
 488                 dprintf("Pgrab_core: failed to add NT_LWPSINFO\n");
 489                 return (-1);
 490         }
 491 
 492         (void) memcpy(&lwp->lwp_psinfo, &lps, sizeof (lps));
 493         return (0);


 503         prfdinfo_t prfd;
 504         fd_info_t *fip;
 505 
 506         if ((nbytes < sizeof (prfd)) ||
 507             (read(P->asfd, &prfd, sizeof (prfd)) != sizeof (prfd))) {
 508                 dprintf("Pgrab_core: failed to read NT_FDINFO\n");
 509                 return (-1);
 510         }
 511 
 512         if ((fip = Pfd2info(P, prfd.pr_fd)) == NULL) {
 513                 dprintf("Pgrab_core: failed to add NT_FDINFO\n");
 514                 return (-1);
 515         }
 516         (void) memcpy(&fip->fd_info, &prfd, sizeof (prfd));
 517         return (0);
 518 }
 519 
 520 static int
 521 note_platform(struct ps_prochandle *P, size_t nbytes)
 522 {
 523         core_info_t *core = P->data;
 524         char *plat;
 525 
 526         if (core->core_platform != NULL)
 527                 return (0);     /* Already seen */
 528 
 529         if (nbytes != 0 && ((plat = malloc(nbytes + 1)) != NULL)) {
 530                 if (read(P->asfd, plat, nbytes) != nbytes) {
 531                         dprintf("Pgrab_core: failed to read NT_PLATFORM\n");
 532                         free(plat);
 533                         return (-1);
 534                 }
 535                 plat[nbytes - 1] = '\0';
 536                 core->core_platform = plat;
 537         }
 538 
 539         return (0);
 540 }
 541 
 542 static int
 543 note_utsname(struct ps_prochandle *P, size_t nbytes)
 544 {
 545         core_info_t *core = P->data;
 546         size_t ubytes = sizeof (struct utsname);
 547         struct utsname *utsp;
 548 
 549         if (core->core_uts != NULL || nbytes < ubytes)
 550                 return (0);     /* Already seen or bad size */
 551 
 552         if ((utsp = malloc(ubytes)) == NULL)
 553                 return (-1);
 554 
 555         if (read(P->asfd, utsp, ubytes) != ubytes) {
 556                 dprintf("Pgrab_core: failed to read NT_UTSNAME\n");
 557                 free(utsp);
 558                 return (-1);
 559         }
 560 
 561         if (_libproc_debug) {
 562                 dprintf("uts.sysname = \"%s\"\n", utsp->sysname);
 563                 dprintf("uts.nodename = \"%s\"\n", utsp->nodename);
 564                 dprintf("uts.release = \"%s\"\n", utsp->release);
 565                 dprintf("uts.version = \"%s\"\n", utsp->version);
 566                 dprintf("uts.machine = \"%s\"\n", utsp->machine);
 567         }
 568 
 569         core->core_uts = utsp;
 570         return (0);
 571 }
 572 
 573 static int
 574 note_content(struct ps_prochandle *P, size_t nbytes)
 575 {
 576         core_info_t *core = P->data;
 577         core_content_t content;
 578 
 579         if (sizeof (core->core_content) != nbytes)
 580                 return (-1);
 581 
 582         if (read(P->asfd, &content, sizeof (content)) != sizeof (content))
 583                 return (-1);
 584 
 585         core->core_content = content;
 586 
 587         dprintf("core content = %llx\n", content);
 588 
 589         return (0);
 590 }
 591 
 592 static int
 593 note_cred(struct ps_prochandle *P, size_t nbytes)
 594 {
 595         core_info_t *core = P->data;
 596         prcred_t *pcrp;
 597         int ngroups;
 598         const size_t min_size = sizeof (prcred_t) - sizeof (gid_t);
 599 
 600         /*
 601          * We allow for prcred_t notes that are actually smaller than a
 602          * prcred_t since the last member isn't essential if there are
 603          * no group memberships. This allows for more flexibility when it
 604          * comes to slightly malformed -- but still valid -- notes.
 605          */
 606         if (core->core_cred != NULL || nbytes < min_size)
 607                 return (0);     /* Already seen or bad size */
 608 
 609         ngroups = (nbytes - min_size) / sizeof (gid_t);
 610         nbytes = sizeof (prcred_t) + (ngroups - 1) * sizeof (gid_t);
 611 
 612         if ((pcrp = malloc(nbytes)) == NULL)
 613                 return (-1);
 614 
 615         if (read(P->asfd, pcrp, nbytes) != nbytes) {
 616                 dprintf("Pgrab_core: failed to read NT_PRCRED\n");
 617                 free(pcrp);
 618                 return (-1);
 619         }
 620 
 621         if (pcrp->pr_ngroups > ngroups) {
 622                 dprintf("pr_ngroups = %d; resetting to %d based on note size\n",
 623                     pcrp->pr_ngroups, ngroups);
 624                 pcrp->pr_ngroups = ngroups;
 625         }
 626 
 627         core->core_cred = pcrp;
 628         return (0);
 629 }
 630 
 631 #if defined(__i386) || defined(__amd64)
 632 static int
 633 note_ldt(struct ps_prochandle *P, size_t nbytes)
 634 {
 635         core_info_t *core = P->data;
 636         struct ssd *pldt;
 637         uint_t nldt;
 638 
 639         if (core->core_ldt != NULL || nbytes < sizeof (struct ssd))
 640                 return (0);     /* Already seen or bad size */
 641 
 642         nldt = nbytes / sizeof (struct ssd);
 643         nbytes = nldt * sizeof (struct ssd);
 644 
 645         if ((pldt = malloc(nbytes)) == NULL)
 646                 return (-1);
 647 
 648         if (read(P->asfd, pldt, nbytes) != nbytes) {
 649                 dprintf("Pgrab_core: failed to read NT_LDT\n");
 650                 free(pldt);
 651                 return (-1);
 652         }
 653 
 654         core->core_ldt = pldt;
 655         core->core_nldt = nldt;
 656         return (0);
 657 }
 658 #endif  /* __i386 */
 659 
 660 static int
 661 note_priv(struct ps_prochandle *P, size_t nbytes)
 662 {
 663         core_info_t *core = P->data;
 664         prpriv_t *pprvp;
 665 
 666         if (core->core_priv != NULL || nbytes < sizeof (prpriv_t))
 667                 return (0);     /* Already seen or bad size */
 668 
 669         if ((pprvp = malloc(nbytes)) == NULL)
 670                 return (-1);
 671 
 672         if (read(P->asfd, pprvp, nbytes) != nbytes) {
 673                 dprintf("Pgrab_core: failed to read NT_PRPRIV\n");
 674                 free(pprvp);
 675                 return (-1);
 676         }
 677 
 678         core->core_priv = pprvp;
 679         core->core_priv_size = nbytes;
 680         return (0);
 681 }
 682 
 683 static int
 684 note_priv_info(struct ps_prochandle *P, size_t nbytes)
 685 {
 686         core_info_t *core = P->data;
 687         extern void *__priv_parse_info();
 688         priv_impl_info_t *ppii;
 689 
 690         if (core->core_privinfo != NULL ||
 691             nbytes < sizeof (priv_impl_info_t))
 692                 return (0);     /* Already seen or bad size */
 693 
 694         if ((ppii = malloc(nbytes)) == NULL)
 695                 return (-1);
 696 
 697         if (read(P->asfd, ppii, nbytes) != nbytes ||
 698             PRIV_IMPL_INFO_SIZE(ppii) != nbytes) {
 699                 dprintf("Pgrab_core: failed to read NT_PRPRIVINFO\n");
 700                 free(ppii);
 701                 return (-1);
 702         }
 703 
 704         core->core_privinfo = __priv_parse_info(ppii);
 705         core->core_ppii = ppii;
 706         return (0);
 707 }
 708 
 709 static int
 710 note_zonename(struct ps_prochandle *P, size_t nbytes)
 711 {
 712         core_info_t *core = P->data;
 713         char *zonename;
 714 
 715         if (core->core_zonename != NULL)
 716                 return (0);     /* Already seen */
 717 
 718         if (nbytes != 0) {
 719                 if ((zonename = malloc(nbytes)) == NULL)
 720                         return (-1);
 721                 if (read(P->asfd, zonename, nbytes) != nbytes) {
 722                         dprintf("Pgrab_core: failed to read NT_ZONENAME\n");
 723                         free(zonename);
 724                         return (-1);
 725                 }
 726                 zonename[nbytes - 1] = '\0';
 727                 core->core_zonename = zonename;
 728         }
 729 
 730         return (0);
 731 }
 732 
 733 static int
 734 note_auxv(struct ps_prochandle *P, size_t nbytes)
 735 {
 736         size_t n, i;
 737 
 738 #ifdef _LP64
 739         core_info_t *core = P->data;
 740 
 741         if (core->core_dmodel == PR_MODEL_ILP32) {
 742                 auxv32_t *a32;
 743 
 744                 n = nbytes / sizeof (auxv32_t);
 745                 nbytes = n * sizeof (auxv32_t);
 746                 a32 = alloca(nbytes);
 747 
 748                 if (read(P->asfd, a32, nbytes) != nbytes) {
 749                         dprintf("Pgrab_core: failed to read NT_AUXV\n");
 750                         return (-1);
 751                 }
 752 
 753                 if ((P->auxv = malloc(sizeof (auxv_t) * (n + 1))) == NULL)
 754                         return (-1);
 755 
 756                 for (i = 0; i < n; i++)
 757                         auxv_32_to_n(&a32[i], &P->auxv[i]);
 758 
 759         } else {
 760 #endif
 761                 n = nbytes / sizeof (auxv_t);


 779                             P->auxv[i].a_type, P->auxv[i].a_un.a_val);
 780                 }
 781         }
 782 
 783         /*
 784          * Defensive coding for loops which depend upon the auxv array being
 785          * terminated by an AT_NULL element; in each case, we've allocated
 786          * P->auxv to have an additional element which we force to be AT_NULL.
 787          */
 788         P->auxv[n].a_type = AT_NULL;
 789         P->auxv[n].a_un.a_val = 0L;
 790         P->nauxv = (int)n;
 791 
 792         return (0);
 793 }
 794 
 795 #ifdef __sparc
 796 static int
 797 note_xreg(struct ps_prochandle *P, size_t nbytes)
 798 {
 799         core_info_t *core = P->data;
 800         lwp_info_t *lwp = core->core_lwp;
 801         size_t xbytes = sizeof (prxregset_t);
 802         prxregset_t *xregs;
 803 
 804         if (lwp == NULL || lwp->lwp_xregs != NULL || nbytes < xbytes)
 805                 return (0);     /* No lwp yet, already seen, or bad size */
 806 
 807         if ((xregs = malloc(xbytes)) == NULL)
 808                 return (-1);
 809 
 810         if (read(P->asfd, xregs, xbytes) != xbytes) {
 811                 dprintf("Pgrab_core: failed to read NT_PRXREG\n");
 812                 free(xregs);
 813                 return (-1);
 814         }
 815 
 816         lwp->lwp_xregs = xregs;
 817         return (0);
 818 }
 819 
 820 static int
 821 note_gwindows(struct ps_prochandle *P, size_t nbytes)
 822 {
 823         core_info_t *core = P->data;
 824         lwp_info_t *lwp = core->core_lwp;
 825 
 826         if (lwp == NULL || lwp->lwp_gwins != NULL || nbytes == 0)
 827                 return (0);     /* No lwp yet or already seen or no data */
 828 
 829         if ((lwp->lwp_gwins = malloc(sizeof (gwindows_t))) == NULL)
 830                 return (-1);
 831 
 832         /*
 833          * Since the amount of gwindows data varies with how many windows were
 834          * actually saved, we just read up to the minimum of the note size
 835          * and the size of the gwindows_t type.  It doesn't matter if the read
 836          * fails since we have to zero out gwindows first anyway.
 837          */
 838 #ifdef _LP64
 839         if (core->core_dmodel == PR_MODEL_ILP32) {
 840                 gwindows32_t g32;
 841 
 842                 (void) memset(&g32, 0, sizeof (g32));
 843                 (void) read(P->asfd, &g32, MIN(nbytes, sizeof (g32)));
 844                 gwindows_32_to_n(&g32, lwp->lwp_gwins);
 845 
 846         } else {
 847 #endif
 848                 (void) memset(lwp->lwp_gwins, 0, sizeof (gwindows_t));
 849                 (void) read(P->asfd, lwp->lwp_gwins,
 850                     MIN(nbytes, sizeof (gwindows_t)));
 851 #ifdef _LP64
 852         }
 853 #endif
 854         return (0);
 855 }
 856 
 857 #ifdef __sparcv9
 858 static int
 859 note_asrs(struct ps_prochandle *P, size_t nbytes)
 860 {
 861         core_info_t *core = P->data;
 862         lwp_info_t *lwp = core->core_lwp;
 863         int64_t *asrs;
 864 
 865         if (lwp == NULL || lwp->lwp_asrs != NULL || nbytes < sizeof (asrset_t))
 866                 return (0);     /* No lwp yet, already seen, or bad size */
 867 
 868         if ((asrs = malloc(sizeof (asrset_t))) == NULL)
 869                 return (-1);
 870 
 871         if (read(P->asfd, asrs, sizeof (asrset_t)) != sizeof (asrset_t)) {
 872                 dprintf("Pgrab_core: failed to read NT_ASRS\n");
 873                 free(asrs);
 874                 return (-1);
 875         }
 876 
 877         lwp->lwp_asrs = asrs;
 878         return (0);
 879 }
 880 #endif  /* __sparcv9 */
 881 #endif  /* __sparc */
 882 
 883 static int
 884 note_spymaster(struct ps_prochandle *P, size_t nbytes)
 885 {
 886 #ifdef _LP64
 887         core_info_t *core = P->data;
 888 
 889         if (core->core_dmodel == PR_MODEL_ILP32) {
 890                 psinfo32_t ps32;
 891 
 892                 if (nbytes < sizeof (psinfo32_t) ||
 893                     read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32))
 894                         goto err;
 895 
 896                 psinfo_32_to_n(&ps32, &P->spymaster);
 897         } else
 898 #endif
 899         if (nbytes < sizeof (psinfo_t) || read(P->asfd,
 900             &P->spymaster, sizeof (psinfo_t)) != sizeof (psinfo_t))
 901                 goto err;
 902 
 903         dprintf("spymaster pr_fname = <%s>\n", P->psinfo.pr_fname);
 904         dprintf("spymaster pr_psargs = <%s>\n", P->psinfo.pr_psargs);
 905         dprintf("spymaster pr_wstat = 0x%x\n", P->psinfo.pr_wstat);
 906 
 907         return (0);
 908 
 909 err:


1020                     si->si_pid, si->si_uid, si->si_zoneid, si->si_ctid);
1021         } else {
1022                 (void) snprintf(info, sizeof (info),
1023                     "code=%d", si->si_code);
1024         }
1025 
1026         Perror_printf(P, incfmt, sig, info);
1027         Perror_printf(P, msgfmt, addr);
1028 
1029         dprintf(incfmt, sig, info);
1030         dprintf(msgfmt, addr);
1031 }
1032 
1033 /*
1034  * Add information on the address space mapping described by the given
1035  * PT_LOAD program header.  We fill in more information on the mapping later.
1036  */
1037 static int
1038 core_add_mapping(struct ps_prochandle *P, GElf_Phdr *php)
1039 {
1040         core_info_t *core = P->data;
1041         prmap_t pmap;
1042 
1043         dprintf("mapping base %llx filesz %llu memsz %llu offset %llu\n",
1044             (u_longlong_t)php->p_vaddr, (u_longlong_t)php->p_filesz,
1045             (u_longlong_t)php->p_memsz, (u_longlong_t)php->p_offset);
1046 
1047         pmap.pr_vaddr = (uintptr_t)php->p_vaddr;
1048         pmap.pr_size = php->p_memsz;
1049 
1050         /*
1051          * If Pgcore() or elfcore() fail to write a mapping, they will set
1052          * PF_SUNW_FAILURE in the Phdr and try to stash away the errno for us.
1053          */
1054         if (php->p_flags & PF_SUNW_FAILURE) {
1055                 core_report_mapping(P, php);
1056         } else if (php->p_filesz != 0 && php->p_offset >= core->core_size) {
1057                 Perror_printf(P, "core file may be corrupt -- data for mapping "
1058                     "at %p is missing\n", (void *)(uintptr_t)php->p_vaddr);
1059                 dprintf("core file may be corrupt -- data for mapping "
1060                     "at %p is missing\n", (void *)(uintptr_t)php->p_vaddr);
1061         }
1062 
1063         /*
1064          * The mapping name and offset will hopefully be filled in
1065          * by the librtld_db agent.  Unfortunately, if it isn't a
1066          * shared library mapping, this information is gone forever.
1067          */
1068         pmap.pr_mapname[0] = '\0';
1069         pmap.pr_offset = 0;
1070 
1071         pmap.pr_mflags = 0;
1072         if (php->p_flags & PF_R)
1073                 pmap.pr_mflags |= MA_READ;
1074         if (php->p_flags & PF_W)
1075                 pmap.pr_mflags |= MA_WRITE;
1076         if (php->p_flags & PF_X)


1672         /*
1673          * It wouldn't be procfs-related code if we didn't make use of
1674          * unclean knowledge of segvn, even in userland ... the prmap_t's
1675          * pr_offset field will be the segvn offset from mmap(2)ing the
1676          * data section, which will be the file offset & PAGEMASK.
1677          */
1678         pagemask = ~(mp->map_pmap.pr_pagesize - 1);
1679         mp->map_pmap.pr_offset = phdr.p_offset & pagemask;
1680 
1681         return (mp);
1682 }
1683 
1684 /*
1685  * Librtld_db agent callback for iterating over load object mappings.
1686  * For each load object, we allocate a new file_info_t, perform naming,
1687  * and attempt to construct a symbol table for the load object.
1688  */
1689 static int
1690 core_iter_mapping(const rd_loadobj_t *rlp, struct ps_prochandle *P)
1691 {
1692         core_info_t *core = P->data;
1693         char lname[PATH_MAX], buf[PATH_MAX];
1694         file_info_t *fp;
1695         map_info_t *mp;
1696 
1697         if (Pread_string(P, lname, PATH_MAX, (off_t)rlp->rl_nameaddr) <= 0) {
1698                 dprintf("failed to read name %p\n", (void *)rlp->rl_nameaddr);
1699                 return (1); /* Keep going; forget this if we can't get a name */
1700         }
1701 
1702         dprintf("rd_loadobj name = \"%s\" rl_base = %p\n",
1703             lname, (void *)rlp->rl_base);
1704 
1705         if ((mp = Paddr2mptr(P, rlp->rl_base)) == NULL) {
1706                 dprintf("no mapping for %p\n", (void *)rlp->rl_base);
1707                 return (1); /* No mapping; advance to next mapping */
1708         }
1709 
1710         /*
1711          * Create a new file_info_t for this mapping, and therefore for
1712          * this load object.
1713          *
1714          * If there's an ELF header at the beginning of this mapping,
1715          * file_info_new() will try to use its section headers to
1716          * identify any other mappings that belong to this load object.
1717          */
1718         if ((fp = mp->map_file) == NULL &&
1719             (fp = file_info_new(P, mp)) == NULL) {
1720                 core->core_errno = errno;
1721                 dprintf("failed to malloc mapping data\n");
1722                 return (0); /* Abort */
1723         }
1724         fp->file_map = mp;
1725 
1726         /* Create a local copy of the load object representation */
1727         if ((fp->file_lo = calloc(1, sizeof (rd_loadobj_t))) == NULL) {
1728                 core->core_errno = errno;
1729                 dprintf("failed to malloc mapping data\n");
1730                 return (0); /* Abort */
1731         }
1732         *fp->file_lo = *rlp;
1733 
1734         if (lname[0] != '\0') {
1735                 /*
1736                  * Naming dance part 1: if we got a name from librtld_db, then
1737                  * copy this name to the prmap_t if it is unnamed.  If the
1738                  * file_info_t is unnamed, name it after the lname.
1739                  */
1740                 if (mp->map_pmap.pr_mapname[0] == '\0') {
1741                         (void) strncpy(mp->map_pmap.pr_mapname, lname, PRMAPSZ);
1742                         mp->map_pmap.pr_mapname[PRMAPSZ - 1] = '\0';
1743                 }
1744 
1745                 if (fp->file_lname == NULL)
1746                         fp->file_lname = strdup(lname);
1747 
1748         } else if (fp->file_lname == NULL &&


1975                 } else if (strcmp(name, ".symtab") == 0) {
1976                         fake_up_symtab(P, &efp->e_hdr,
1977                             shp, &shdrs[shp->sh_link]);
1978                 }
1979         }
1980 out:
1981         free(shstrtab);
1982         free(shdrs);
1983 }
1984 
1985 /*
1986  * Main engine for core file initialization: given an fd for the core file
1987  * and an optional pathname, construct the ps_prochandle.  The aout_path can
1988  * either be a suggested executable pathname, or a suggested directory to
1989  * use as a possible current working directory.
1990  */
1991 struct ps_prochandle *
1992 Pfgrab_core(int core_fd, const char *aout_path, int *perr)
1993 {
1994         struct ps_prochandle *P;
1995         core_info_t *core_info;
1996         map_info_t *stk_mp, *brk_mp;
1997         const char *execname;
1998         char *interp;
1999         int i, notes, pagesize;
2000         uintptr_t addr, base_addr;
2001         struct stat64 stbuf;
2002         void *phbuf, *php;
2003         size_t nbytes;
2004 
2005         elf_file_t aout;
2006         elf_file_t core;
2007 
2008         Elf_Scn *scn, *intp_scn = NULL;
2009         Elf_Data *dp;
2010 
2011         GElf_Phdr phdr, note_phdr;
2012         GElf_Shdr shdr;
2013         GElf_Xword nleft;
2014 
2015         if (elf_version(EV_CURRENT) == EV_NONE) {


2041          *
2042          * 4. The read/write ops vector uses our core_rw() function defined
2043          *    above to handle i/o requests.
2044          */
2045         if ((P = malloc(sizeof (struct ps_prochandle))) == NULL) {
2046                 *perr = G_STRANGE;
2047                 return (NULL);
2048         }
2049 
2050         (void) memset(P, 0, sizeof (struct ps_prochandle));
2051         (void) mutex_init(&P->proc_lock, USYNC_THREAD, NULL);
2052         P->state = PS_DEAD;
2053         P->pid = (pid_t)-1;
2054         P->asfd = core.e_fd;
2055         P->ctlfd = -1;
2056         P->statfd = -1;
2057         P->agentctlfd = -1;
2058         P->agentstatfd = -1;
2059         P->zoneroot = NULL;
2060         P->info_valid = 1;
2061         Pinit_ops(&P->ops, &P_core_ops);
2062 
2063         Pinitsym(P);
2064 
2065         /*
2066          * Fstat and open the core file and make sure it is a valid ELF core.
2067          */
2068         if (fstat64(P->asfd, &stbuf) == -1) {
2069                 *perr = G_STRANGE;
2070                 goto err;
2071         }
2072 
2073         if (core_elf_fdopen(&core, ET_CORE, perr) == -1)
2074                 goto err;
2075 
2076         /*
2077          * Allocate and initialize a core_info_t to hang off the ps_prochandle
2078          * structure.  We keep all core-specific information in this structure.
2079          */
2080         if ((core_info = calloc(1, sizeof (core_info_t))) == NULL) {
2081                 *perr = G_STRANGE;
2082                 goto err;
2083         }
2084 
2085         P->data = core_info;
2086         list_link(&core_info->core_lwp_head, NULL);
2087         core_info->core_size = stbuf.st_size;
2088         /*
2089          * In the days before adjustable core file content, this was the
2090          * default core file content. For new core files, this value will
2091          * be overwritten by the NT_CONTENT note section.
2092          */
2093         core_info->core_content = CC_CONTENT_STACK | CC_CONTENT_HEAP |
2094             CC_CONTENT_DATA | CC_CONTENT_RODATA | CC_CONTENT_ANON |
2095             CC_CONTENT_SHANON;
2096 
2097         switch (core.e_hdr.e_ident[EI_CLASS]) {
2098         case ELFCLASS32:
2099                 core_info->core_dmodel = PR_MODEL_ILP32;
2100                 break;
2101         case ELFCLASS64:
2102                 core_info->core_dmodel = PR_MODEL_LP64;
2103                 break;
2104         default:
2105                 *perr = G_FORMAT;
2106                 goto err;
2107         }
2108 
2109         /*
2110          * Because the core file may be a large file, we can't use libelf to
2111          * read the Phdrs.  We use e_phnum and e_phentsize to simplify things.
2112          */
2113         nbytes = core.e_hdr.e_phnum * core.e_hdr.e_phentsize;
2114 
2115         if ((phbuf = malloc(nbytes)) == NULL) {
2116                 *perr = G_STRANGE;
2117                 goto err;
2118         }
2119 
2120         if (pread64(core_fd, phbuf, nbytes, core.e_hdr.e_phoff) != nbytes) {
2121                 *perr = G_STRANGE;
2122                 free(phbuf);


2308 
2309         /*
2310          * Get the AT_BASE auxv element.  If this is missing (-1), then
2311          * we assume this is a statically-linked executable.
2312          */
2313         base_addr = Pgetauxval(P, AT_BASE);
2314 
2315         /*
2316          * In order to get librtld_db initialized, we'll need to identify
2317          * and name the mapping corresponding to the run-time linker.  The
2318          * AT_BASE auxv element tells us the address where it was mapped,
2319          * and the .interp section of the executable tells us its path.
2320          * If for some reason that doesn't pan out, just use ld.so.1.
2321          */
2322         if (intp_scn != NULL && (dp = elf_getdata(intp_scn, NULL)) != NULL &&
2323             dp->d_size != 0) {
2324                 dprintf(".interp = <%s>\n", (char *)dp->d_buf);
2325                 interp = dp->d_buf;
2326 
2327         } else if (base_addr != (uintptr_t)-1L) {
2328                 if (core_info->core_dmodel == PR_MODEL_LP64)
2329                         interp = "/usr/lib/64/ld.so.1";
2330                 else
2331                         interp = "/usr/lib/ld.so.1";
2332 
2333                 dprintf(".interp section is missing or could not be read; "
2334                     "defaulting to %s\n", interp);
2335         } else
2336                 dprintf("detected statically linked executable\n");
2337 
2338         /*
2339          * If we have an AT_BASE element, name the mapping at that address
2340          * using the interpreter pathname.  Name the corresponding data
2341          * mapping after the interpreter as well.
2342          */
2343         if (base_addr != (uintptr_t)-1L) {
2344                 elf_file_t intf;
2345 
2346                 P->map_ldso = core_name_mapping(P, base_addr, interp);
2347 
2348                 if (core_elf_open(&intf, interp, ET_DYN, NULL) == 0) {


2423                                 fp->file_ref++;
2424                         }
2425                 }
2426         }
2427 
2428         core_elf_close(&aout);
2429 
2430         /*
2431          * We now have enough information to initialize librtld_db.
2432          * After it warms up, we can iterate through the load object chain
2433          * in the core, which will allow us to construct the file info
2434          * we need to provide symbol information for the other shared
2435          * libraries, and also to fill in the missing mapping names.
2436          */
2437         rd_log(_libproc_debug);
2438 
2439         if ((P->rap = rd_new(P)) != NULL) {
2440                 (void) rd_loadobj_iter(P->rap, (rl_iter_f *)
2441                     core_iter_mapping, P);
2442 
2443                 if (core_info->core_errno != 0) {
2444                         errno = core_info->core_errno;
2445                         *perr = G_STRANGE;
2446                         goto err;
2447                 }
2448         } else
2449                 dprintf("failed to initialize rtld_db agent\n");
2450 
2451         /*
2452          * If there are sections, load them and process the data from any
2453          * sections that we can use to annotate the file_info_t's.
2454          */
2455         core_load_shdrs(P, &core);
2456 
2457         /*
2458          * If we previously located a stack or break mapping, and they are
2459          * still anonymous, we now assume that they were MAP_ANON mappings.
2460          * If brk_mp turns out to now have a name, then the heap is still
2461          * sitting at the end of the executable's data+bss mapping: remove
2462          * the previous MA_BREAK setting to be consistent with /proc.
2463          */
2464         if (stk_mp != NULL && stk_mp->map_pmap.pr_mapname[0] == '\0')