Print this page
5383 5234 breaks build on sparc


   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) 2014, 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"
  49 #include "Pcontrol.h"
  50 #include "P32ton.h"
  51 #include "Putil.h"

  52 #include "Pcore_linux.h"

  53 
  54 /*
  55  * Pcore.c - Code to initialize a ps_prochandle from a core dump.  We
  56  * allocate an additional structure to hold information from the core
  57  * file, and attach this to the standard ps_prochandle in place of the
  58  * ability to examine /proc/<pid>/ files.
  59  */
  60 
  61 /*
  62  * Basic i/o function for reading and writing from the process address space
  63  * stored in the core file and associated shared libraries.  We compute the
  64  * appropriate fd and offsets, and let the provided prw function do the rest.
  65  */
  66 static ssize_t
  67 core_rw(struct ps_prochandle *P, void *buf, size_t n, uintptr_t addr,
  68     ssize_t (*prw)(int, void *, size_t, off64_t))
  69 {
  70         ssize_t resid = n;
  71 
  72         while (resid != 0) {


 414                 dprintf("Pgrab_core: failed to add NT_LWPSTATUS\n");
 415                 return (-1);
 416         }
 417 
 418         /*
 419          * Erase a useless and confusing artifact of the kernel implementation:
 420          * the lwps which did *not* create the core will show SIGKILL.  We can
 421          * be assured this is bogus because SIGKILL can't produce core files.
 422          */
 423         if (lps.pr_cursig == SIGKILL)
 424                 lps.pr_cursig = 0;
 425 
 426         (void) memcpy(&lwp->lwp_status, &lps, sizeof (lps));
 427         return (0);
 428 
 429 err:
 430         dprintf("Pgrab_core: failed to read NT_LWPSTATUS\n");
 431         return (-1);
 432 }
 433 


 434 static void
 435 lx_prpsinfo32_to_psinfo(lx_prpsinfo32_t *p32, psinfo_t *psinfo)
 436 {
 437         psinfo->pr_flag = p32->pr_flag;
 438         psinfo->pr_pid = p32->pr_pid;
 439         psinfo->pr_ppid = p32->pr_ppid;
 440         psinfo->pr_uid = p32->pr_uid;
 441         psinfo->pr_gid = p32->pr_gid;
 442         psinfo->pr_sid = p32->pr_sid;
 443         psinfo->pr_pgid = p32->pr_pgrp;
 444 
 445         (void) memcpy(psinfo->pr_fname, p32->pr_fname,
 446             sizeof (psinfo->pr_fname));
 447         (void) memcpy(psinfo->pr_psargs, p32->pr_psargs,
 448             sizeof (psinfo->pr_psargs));
 449 }
 450 
 451 static void
 452 lx_prpsinfo64_to_psinfo(lx_prpsinfo64_t *p64, psinfo_t *psinfo)
 453 {


 612                     "linux_prstatus\n");
 613                 return (-1);
 614         }
 615 
 616         P->psinfo.pr_nlwp++;
 617         P->status.pr_nlwp++;
 618 
 619         lwp->lwp_status.pr_lwpid = tid;
 620 
 621         if (core->core_dmodel == PR_MODEL_ILP32)
 622                 lx_prstatus32_to_lwp(&prs32, lwp);
 623         else
 624                 lx_prstatus64_to_lwp(&prs64, lwp);
 625 
 626         return (0);
 627 err:
 628         dprintf("Pgrab_core: failed to read NT_PRSTATUS\n");
 629         return (-1);
 630 }
 631 


 632 static int
 633 note_psinfo(struct ps_prochandle *P, size_t nbytes)
 634 {
 635 #ifdef _LP64
 636         core_info_t *core = P->data;
 637 
 638         if (core->core_dmodel == PR_MODEL_ILP32) {
 639                 psinfo32_t ps32;
 640 
 641                 if (nbytes < sizeof (psinfo32_t) ||
 642                     read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32))
 643                         goto err;
 644 
 645                 psinfo_32_to_n(&ps32, &P->psinfo);
 646         } else
 647 #endif
 648         if (nbytes < sizeof (psinfo_t) ||
 649             read(P->asfd, &P->psinfo, sizeof (psinfo_t)) != sizeof (psinfo_t))
 650                 goto err;
 651 


1108 err:
1109         dprintf("Pgrab_core: failed to read NT_SPYMASTER\n");
1110         return (-1);
1111 }
1112 
1113 /*ARGSUSED*/
1114 static int
1115 note_notsup(struct ps_prochandle *P, size_t nbytes)
1116 {
1117         dprintf("skipping unsupported note type of size %ld bytes\n",
1118             (ulong_t)nbytes);
1119         return (0);
1120 }
1121 
1122 /*
1123  * Populate a table of function pointers indexed by Note type with our
1124  * functions to process each type of core file note:
1125  */
1126 static int (*nhdlrs[])(struct ps_prochandle *, size_t) = {
1127         note_notsup,            /*  0   unassigned              */

1128         note_linux_prstatus,            /*  1   NT_PRSTATUS (old)       */



1129         note_notsup,            /*  2   NT_PRFPREG (old)        */

1130         note_linux_psinfo,              /*  3   NT_PRPSINFO (old)       */



1131 #ifdef __sparc
1132         note_xreg,              /*  4   NT_PRXREG               */
1133 #else
1134         note_notsup,            /*  4   NT_PRXREG               */
1135 #endif
1136         note_platform,          /*  5   NT_PLATFORM             */
1137         note_auxv,              /*  6   NT_AUXV                 */
1138 #ifdef __sparc
1139         note_gwindows,          /*  7   NT_GWINDOWS             */
1140 #ifdef __sparcv9
1141         note_asrs,              /*  8   NT_ASRS                 */
1142 #else
1143         note_notsup,            /*  8   NT_ASRS                 */
1144 #endif
1145 #else
1146         note_notsup,            /*  7   NT_GWINDOWS             */
1147         note_notsup,            /*  8   NT_ASRS                 */
1148 #endif
1149 #if defined(__i386) || defined(__amd64)
1150         note_ldt,               /*  9   NT_LDT                  */


2184 
2185 /*
2186  * Main engine for core file initialization: given an fd for the core file
2187  * and an optional pathname, construct the ps_prochandle.  The aout_path can
2188  * either be a suggested executable pathname, or a suggested directory to
2189  * use as a possible current working directory.
2190  */
2191 struct ps_prochandle *
2192 Pfgrab_core(int core_fd, const char *aout_path, int *perr)
2193 {
2194         struct ps_prochandle *P;
2195         core_info_t *core_info;
2196         map_info_t *stk_mp, *brk_mp;
2197         const char *execname;
2198         char *interp;
2199         int i, notes, pagesize;
2200         uintptr_t addr, base_addr;
2201         struct stat64 stbuf;
2202         void *phbuf, *php;
2203         size_t nbytes;

2204         boolean_t from_linux = B_FALSE;

2205 
2206         elf_file_t aout;
2207         elf_file_t core;
2208 
2209         Elf_Scn *scn, *intp_scn = NULL;
2210         Elf_Data *dp;
2211 
2212         GElf_Phdr phdr, note_phdr;
2213         GElf_Shdr shdr;
2214         GElf_Xword nleft;
2215 
2216         if (elf_version(EV_CURRENT) == EV_NONE) {
2217                 dprintf("libproc ELF version is more recent than libelf\n");
2218                 *perr = G_ELF;
2219                 return (NULL);
2220         }
2221 
2222         aout.e_elf = NULL;
2223         aout.e_fd = -1;
2224 


2432 
2433                 dprintf("Note hdr n_type=%u n_namesz=%u n_descsz=%u\n",
2434                     nhdr.n_type, nhdr.n_namesz, nhdr.n_descsz);
2435 
2436                 off = lseek64(P->asfd, (off64_t)0L, SEEK_CUR);
2437 
2438                 /*
2439                  * Invoke the note handler function from our table
2440                  */
2441                 if (nhdr.n_type < sizeof (nhdlrs) / sizeof (nhdlrs[0])) {
2442                         if (nhdlrs[nhdr.n_type](P, nhdr.n_descsz) < 0) {
2443                                 dprintf("handler for type %d returned < 0",
2444                                     nhdr.n_type);
2445                                 *perr = G_NOTE;
2446                                 goto err;
2447                         }
2448                         /*
2449                          * The presence of either of these notes indicates that
2450                          * the dump was generated on Linux.
2451                          */

2452                         if (nhdr.n_type == NT_PRSTATUS ||
2453                             nhdr.n_type == NT_PRPSINFO)
2454                                 from_linux = B_TRUE;

2455                 } else {
2456                         (void) note_notsup(P, nhdr.n_descsz);
2457                 }
2458 
2459                 /*
2460                  * Seek past the current note data to the next Elf_Nhdr
2461                  */
2462                 descsz = P2ROUNDUP((off64_t)nhdr.n_descsz, (off64_t)4);
2463                 if (lseek64(P->asfd, off + descsz, SEEK_SET) == (off64_t)-1) {
2464                         dprintf("Pgrab_core: failed to seek to next nhdr\n");
2465                         *perr = G_STRANGE;
2466                         goto err;
2467                 }
2468 
2469                 /*
2470                  * Subtract the size of the header and its data from what
2471                  * we have left to process.
2472                  */
2473                 nleft -= sizeof (nhdr) + namesz + descsz;
2474         }
2475 

2476         if (from_linux) {
2477                 size_t tcount, pid;
2478                 lwp_info_t *lwp;
2479 
2480                 P->status.pr_dmodel = core_info->core_dmodel;
2481 
2482                 lwp = list_next(&core_info->core_lwp_head);
2483 
2484                 pid = P->status.pr_pid;
2485 
2486                 for (tcount = 0; tcount < core_info->core_nlwp;
2487                     tcount++, lwp = list_next(lwp)) {
2488                         dprintf("Linux thread with id %d\n", lwp->lwp_id);
2489 
2490                         /*
2491                          * In the case we don't have a valid psinfo (i.e. pid is
2492                          * 0, probably because of gdb creating the core) assume
2493                          * lowest pid count is the first thread (what if the
2494                          * next thread wraps the pid around?)
2495                          */


2509                 /*
2510                  * Consumers like mdb expect the first thread to actually have
2511                  * an id of 1, on linux that is actually the pid. Find the the
2512                  * thread with our process id, and set the id to 1
2513                  */
2514                 if ((lwp = lwpid2info(P, pid)) == NULL) {
2515                         dprintf("Couldn't find first thread\n");
2516                         *perr = G_STRANGE;
2517                         goto err;
2518                 }
2519 
2520                 dprintf("setting representative thread: %d\n", lwp->lwp_id);
2521 
2522                 lwp->lwp_id = 1;
2523                 lwp->lwp_status.pr_lwpid = 1;
2524 
2525                 /* set representative thread */
2526                 (void) memcpy(&P->status.pr_lwp, &lwp->lwp_status,
2527                     sizeof (P->status.pr_lwp));
2528         }

2529 
2530         if (nleft != 0) {
2531                 dprintf("Pgrab_core: note section malformed\n");
2532                 *perr = G_STRANGE;
2533                 goto err;
2534         }
2535 
2536         if ((pagesize = Pgetauxval(P, AT_PAGESZ)) == -1) {
2537                 pagesize = getpagesize();
2538                 dprintf("AT_PAGESZ missing; defaulting to %d\n", pagesize);
2539         }
2540 
2541         /*
2542          * Locate and label the mappings corresponding to the end of the
2543          * heap (MA_BREAK) and the base of the stack (MA_STACK).
2544          */
2545         if ((P->status.pr_brkbase != 0 || P->status.pr_brksize != 0) &&
2546             (brk_mp = Paddr2mptr(P, P->status.pr_brkbase +
2547             P->status.pr_brksize - 1)) != NULL)
2548                 brk_mp->map_pmap.pr_mflags |= MA_BREAK;




   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) 2014, Joyent, Inc. All rights reserved.
  28  * Copyright (c) 2013 by Delphix. All rights reserved.
  29  * Copyright 2015 Gary Mills
  30  */
  31 
  32 #include <sys/types.h>
  33 #include <sys/utsname.h>
  34 #include <sys/sysmacros.h>
  35 #include <sys/proc.h>
  36 
  37 #include <alloca.h>
  38 #include <rtld_db.h>
  39 #include <libgen.h>
  40 #include <limits.h>
  41 #include <string.h>
  42 #include <stdlib.h>
  43 #include <unistd.h>
  44 #include <errno.h>
  45 #include <gelf.h>
  46 #include <stddef.h>
  47 #include <signal.h>
  48 
  49 #include "libproc.h"
  50 #include "Pcontrol.h"
  51 #include "P32ton.h"
  52 #include "Putil.h"
  53 #if defined(__i386) || defined(__amd64)
  54 #include "Pcore_linux.h"
  55 #endif
  56 
  57 /*
  58  * Pcore.c - Code to initialize a ps_prochandle from a core dump.  We
  59  * allocate an additional structure to hold information from the core
  60  * file, and attach this to the standard ps_prochandle in place of the
  61  * ability to examine /proc/<pid>/ files.
  62  */
  63 
  64 /*
  65  * Basic i/o function for reading and writing from the process address space
  66  * stored in the core file and associated shared libraries.  We compute the
  67  * appropriate fd and offsets, and let the provided prw function do the rest.
  68  */
  69 static ssize_t
  70 core_rw(struct ps_prochandle *P, void *buf, size_t n, uintptr_t addr,
  71     ssize_t (*prw)(int, void *, size_t, off64_t))
  72 {
  73         ssize_t resid = n;
  74 
  75         while (resid != 0) {


 417                 dprintf("Pgrab_core: failed to add NT_LWPSTATUS\n");
 418                 return (-1);
 419         }
 420 
 421         /*
 422          * Erase a useless and confusing artifact of the kernel implementation:
 423          * the lwps which did *not* create the core will show SIGKILL.  We can
 424          * be assured this is bogus because SIGKILL can't produce core files.
 425          */
 426         if (lps.pr_cursig == SIGKILL)
 427                 lps.pr_cursig = 0;
 428 
 429         (void) memcpy(&lwp->lwp_status, &lps, sizeof (lps));
 430         return (0);
 431 
 432 err:
 433         dprintf("Pgrab_core: failed to read NT_LWPSTATUS\n");
 434         return (-1);
 435 }
 436 
 437 #if defined(__i386) || defined(__amd64)
 438 
 439 static void
 440 lx_prpsinfo32_to_psinfo(lx_prpsinfo32_t *p32, psinfo_t *psinfo)
 441 {
 442         psinfo->pr_flag = p32->pr_flag;
 443         psinfo->pr_pid = p32->pr_pid;
 444         psinfo->pr_ppid = p32->pr_ppid;
 445         psinfo->pr_uid = p32->pr_uid;
 446         psinfo->pr_gid = p32->pr_gid;
 447         psinfo->pr_sid = p32->pr_sid;
 448         psinfo->pr_pgid = p32->pr_pgrp;
 449 
 450         (void) memcpy(psinfo->pr_fname, p32->pr_fname,
 451             sizeof (psinfo->pr_fname));
 452         (void) memcpy(psinfo->pr_psargs, p32->pr_psargs,
 453             sizeof (psinfo->pr_psargs));
 454 }
 455 
 456 static void
 457 lx_prpsinfo64_to_psinfo(lx_prpsinfo64_t *p64, psinfo_t *psinfo)
 458 {


 617                     "linux_prstatus\n");
 618                 return (-1);
 619         }
 620 
 621         P->psinfo.pr_nlwp++;
 622         P->status.pr_nlwp++;
 623 
 624         lwp->lwp_status.pr_lwpid = tid;
 625 
 626         if (core->core_dmodel == PR_MODEL_ILP32)
 627                 lx_prstatus32_to_lwp(&prs32, lwp);
 628         else
 629                 lx_prstatus64_to_lwp(&prs64, lwp);
 630 
 631         return (0);
 632 err:
 633         dprintf("Pgrab_core: failed to read NT_PRSTATUS\n");
 634         return (-1);
 635 }
 636 
 637 #endif /* defined(__i386) || defined(__amd64) */
 638 
 639 static int
 640 note_psinfo(struct ps_prochandle *P, size_t nbytes)
 641 {
 642 #ifdef _LP64
 643         core_info_t *core = P->data;
 644 
 645         if (core->core_dmodel == PR_MODEL_ILP32) {
 646                 psinfo32_t ps32;
 647 
 648                 if (nbytes < sizeof (psinfo32_t) ||
 649                     read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32))
 650                         goto err;
 651 
 652                 psinfo_32_to_n(&ps32, &P->psinfo);
 653         } else
 654 #endif
 655         if (nbytes < sizeof (psinfo_t) ||
 656             read(P->asfd, &P->psinfo, sizeof (psinfo_t)) != sizeof (psinfo_t))
 657                 goto err;
 658 


1115 err:
1116         dprintf("Pgrab_core: failed to read NT_SPYMASTER\n");
1117         return (-1);
1118 }
1119 
1120 /*ARGSUSED*/
1121 static int
1122 note_notsup(struct ps_prochandle *P, size_t nbytes)
1123 {
1124         dprintf("skipping unsupported note type of size %ld bytes\n",
1125             (ulong_t)nbytes);
1126         return (0);
1127 }
1128 
1129 /*
1130  * Populate a table of function pointers indexed by Note type with our
1131  * functions to process each type of core file note:
1132  */
1133 static int (*nhdlrs[])(struct ps_prochandle *, size_t) = {
1134         note_notsup,            /*  0   unassigned              */
1135 #if defined(__i386) || defined(__amd64)
1136         note_linux_prstatus,            /*  1   NT_PRSTATUS (old)       */
1137 #else
1138         note_notsup,            /*  1   NT_PRSTATUS (old)       */
1139 #endif
1140         note_notsup,            /*  2   NT_PRFPREG (old)        */
1141 #if defined(__i386) || defined(__amd64)
1142         note_linux_psinfo,              /*  3   NT_PRPSINFO (old)       */
1143 #else
1144         note_notsup,            /*  3   NT_PRPSINFO (old)       */
1145 #endif
1146 #ifdef __sparc
1147         note_xreg,              /*  4   NT_PRXREG               */
1148 #else
1149         note_notsup,            /*  4   NT_PRXREG               */
1150 #endif
1151         note_platform,          /*  5   NT_PLATFORM             */
1152         note_auxv,              /*  6   NT_AUXV                 */
1153 #ifdef __sparc
1154         note_gwindows,          /*  7   NT_GWINDOWS             */
1155 #ifdef __sparcv9
1156         note_asrs,              /*  8   NT_ASRS                 */
1157 #else
1158         note_notsup,            /*  8   NT_ASRS                 */
1159 #endif
1160 #else
1161         note_notsup,            /*  7   NT_GWINDOWS             */
1162         note_notsup,            /*  8   NT_ASRS                 */
1163 #endif
1164 #if defined(__i386) || defined(__amd64)
1165         note_ldt,               /*  9   NT_LDT                  */


2199 
2200 /*
2201  * Main engine for core file initialization: given an fd for the core file
2202  * and an optional pathname, construct the ps_prochandle.  The aout_path can
2203  * either be a suggested executable pathname, or a suggested directory to
2204  * use as a possible current working directory.
2205  */
2206 struct ps_prochandle *
2207 Pfgrab_core(int core_fd, const char *aout_path, int *perr)
2208 {
2209         struct ps_prochandle *P;
2210         core_info_t *core_info;
2211         map_info_t *stk_mp, *brk_mp;
2212         const char *execname;
2213         char *interp;
2214         int i, notes, pagesize;
2215         uintptr_t addr, base_addr;
2216         struct stat64 stbuf;
2217         void *phbuf, *php;
2218         size_t nbytes;
2219 #if defined(__i386) || defined(__amd64)
2220         boolean_t from_linux = B_FALSE;
2221 #endif
2222 
2223         elf_file_t aout;
2224         elf_file_t core;
2225 
2226         Elf_Scn *scn, *intp_scn = NULL;
2227         Elf_Data *dp;
2228 
2229         GElf_Phdr phdr, note_phdr;
2230         GElf_Shdr shdr;
2231         GElf_Xword nleft;
2232 
2233         if (elf_version(EV_CURRENT) == EV_NONE) {
2234                 dprintf("libproc ELF version is more recent than libelf\n");
2235                 *perr = G_ELF;
2236                 return (NULL);
2237         }
2238 
2239         aout.e_elf = NULL;
2240         aout.e_fd = -1;
2241 


2449 
2450                 dprintf("Note hdr n_type=%u n_namesz=%u n_descsz=%u\n",
2451                     nhdr.n_type, nhdr.n_namesz, nhdr.n_descsz);
2452 
2453                 off = lseek64(P->asfd, (off64_t)0L, SEEK_CUR);
2454 
2455                 /*
2456                  * Invoke the note handler function from our table
2457                  */
2458                 if (nhdr.n_type < sizeof (nhdlrs) / sizeof (nhdlrs[0])) {
2459                         if (nhdlrs[nhdr.n_type](P, nhdr.n_descsz) < 0) {
2460                                 dprintf("handler for type %d returned < 0",
2461                                     nhdr.n_type);
2462                                 *perr = G_NOTE;
2463                                 goto err;
2464                         }
2465                         /*
2466                          * The presence of either of these notes indicates that
2467                          * the dump was generated on Linux.
2468                          */
2469 #if defined(__i386) || defined(__amd64)
2470                         if (nhdr.n_type == NT_PRSTATUS ||
2471                             nhdr.n_type == NT_PRPSINFO)
2472                                 from_linux = B_TRUE;
2473 #endif
2474                 } else {
2475                         (void) note_notsup(P, nhdr.n_descsz);
2476                 }
2477 
2478                 /*
2479                  * Seek past the current note data to the next Elf_Nhdr
2480                  */
2481                 descsz = P2ROUNDUP((off64_t)nhdr.n_descsz, (off64_t)4);
2482                 if (lseek64(P->asfd, off + descsz, SEEK_SET) == (off64_t)-1) {
2483                         dprintf("Pgrab_core: failed to seek to next nhdr\n");
2484                         *perr = G_STRANGE;
2485                         goto err;
2486                 }
2487 
2488                 /*
2489                  * Subtract the size of the header and its data from what
2490                  * we have left to process.
2491                  */
2492                 nleft -= sizeof (nhdr) + namesz + descsz;
2493         }
2494 
2495 #if defined(__i386) || defined(__amd64)
2496         if (from_linux) {
2497                 size_t tcount, pid;
2498                 lwp_info_t *lwp;
2499 
2500                 P->status.pr_dmodel = core_info->core_dmodel;
2501 
2502                 lwp = list_next(&core_info->core_lwp_head);
2503 
2504                 pid = P->status.pr_pid;
2505 
2506                 for (tcount = 0; tcount < core_info->core_nlwp;
2507                     tcount++, lwp = list_next(lwp)) {
2508                         dprintf("Linux thread with id %d\n", lwp->lwp_id);
2509 
2510                         /*
2511                          * In the case we don't have a valid psinfo (i.e. pid is
2512                          * 0, probably because of gdb creating the core) assume
2513                          * lowest pid count is the first thread (what if the
2514                          * next thread wraps the pid around?)
2515                          */


2529                 /*
2530                  * Consumers like mdb expect the first thread to actually have
2531                  * an id of 1, on linux that is actually the pid. Find the the
2532                  * thread with our process id, and set the id to 1
2533                  */
2534                 if ((lwp = lwpid2info(P, pid)) == NULL) {
2535                         dprintf("Couldn't find first thread\n");
2536                         *perr = G_STRANGE;
2537                         goto err;
2538                 }
2539 
2540                 dprintf("setting representative thread: %d\n", lwp->lwp_id);
2541 
2542                 lwp->lwp_id = 1;
2543                 lwp->lwp_status.pr_lwpid = 1;
2544 
2545                 /* set representative thread */
2546                 (void) memcpy(&P->status.pr_lwp, &lwp->lwp_status,
2547                     sizeof (P->status.pr_lwp));
2548         }
2549 #endif /* defined(__i386) || defined(__amd64) */
2550 
2551         if (nleft != 0) {
2552                 dprintf("Pgrab_core: note section malformed\n");
2553                 *perr = G_STRANGE;
2554                 goto err;
2555         }
2556 
2557         if ((pagesize = Pgetauxval(P, AT_PAGESZ)) == -1) {
2558                 pagesize = getpagesize();
2559                 dprintf("AT_PAGESZ missing; defaulting to %d\n", pagesize);
2560         }
2561 
2562         /*
2563          * Locate and label the mappings corresponding to the end of the
2564          * heap (MA_BREAK) and the base of the stack (MA_STACK).
2565          */
2566         if ((P->status.pr_brkbase != 0 || P->status.pr_brksize != 0) &&
2567             (brk_mp = Paddr2mptr(P, P->status.pr_brkbase +
2568             P->status.pr_brksize - 1)) != NULL)
2569                 brk_mp->map_pmap.pr_mflags |= MA_BREAK;