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

*** 23,32 **** --- 23,33 ---- * Use is subject to license terms. */ /* * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. */ #include <sys/types.h> #include <sys/utsname.h> #include <sys/sysmacros.h>
*** 109,148 **** } return (n - resid); } static ssize_t ! Pread_core(struct ps_prochandle *P, void *buf, size_t n, uintptr_t addr) { return (core_rw(P, buf, n, addr, pread64)); } static ssize_t ! Pwrite_core(struct ps_prochandle *P, const void *buf, size_t n, uintptr_t addr) { return (core_rw(P, (void *)buf, n, addr, (ssize_t (*)(int, void *, size_t, off64_t)) pwrite64)); } ! static const ps_rwops_t P_core_ops = { Pread_core, Pwrite_core }; /* * Return the lwp_info_t for the given lwpid. If no such lwpid has been * encountered yet, allocate a new structure and return a pointer to it. * Create a list of lwp_info_t structures sorted in decreasing lwp_id order. */ static lwp_info_t * lwpid2info(struct ps_prochandle *P, lwpid_t id) { ! lwp_info_t *lwp = list_next(&P->core->core_lwp_head); lwp_info_t *next; uint_t i; ! for (i = 0; i < P->core->core_nlwp; i++, lwp = list_next(lwp)) { if (lwp->lwp_id == id) { ! P->core->core_lwp = lwp; return (lwp); } if (lwp->lwp_id < id) { break; } --- 110,332 ---- } return (n - resid); } + /*ARGSUSED*/ static ssize_t ! Pread_core(struct ps_prochandle *P, void *buf, size_t n, uintptr_t addr, ! void *data) { return (core_rw(P, buf, n, addr, pread64)); } + /*ARGSUSED*/ static ssize_t ! Pwrite_core(struct ps_prochandle *P, const void *buf, size_t n, uintptr_t addr, ! void *data) { return (core_rw(P, (void *)buf, n, addr, (ssize_t (*)(int, void *, size_t, off64_t)) pwrite64)); } ! /*ARGSUSED*/ ! static int ! Pcred_core(struct ps_prochandle *P, prcred_t *pcrp, int ngroups, void *data) ! { ! core_info_t *core = data; + if (core->core_cred != NULL) { + /* + * Avoid returning more supplementary group data than the + * caller has allocated in their buffer. We expect them to + * check pr_ngroups afterward and potentially call us again. + */ + ngroups = MIN(ngroups, core->core_cred->pr_ngroups); + + (void) memcpy(pcrp, core->core_cred, + sizeof (prcred_t) + (ngroups - 1) * sizeof (gid_t)); + + return (0); + } + + errno = ENODATA; + return (-1); + } + + /*ARGSUSED*/ + static int + Ppriv_core(struct ps_prochandle *P, prpriv_t **pprv, void *data) + { + core_info_t *core = data; + + if (core->core_priv == NULL) { + errno = ENODATA; + return (-1); + } + + *pprv = malloc(core->core_priv_size); + if (*pprv == NULL) { + return (-1); + } + + (void) memcpy(*pprv, core->core_priv, core->core_priv_size); + return (0); + } + + /*ARGSUSED*/ + static const psinfo_t * + Ppsinfo_core(struct ps_prochandle *P, psinfo_t *psinfo, void *data) + { + return (&P->psinfo); + } + + /*ARGSUSED*/ + static void + Pfini_core(struct ps_prochandle *P, void *data) + { + core_info_t *core = data; + + if (core != NULL) { + extern void __priv_free_info(void *); + lwp_info_t *nlwp, *lwp = list_next(&core->core_lwp_head); + int i; + + for (i = 0; i < core->core_nlwp; i++, lwp = nlwp) { + nlwp = list_next(lwp); + #ifdef __sparc + if (lwp->lwp_gwins != NULL) + free(lwp->lwp_gwins); + if (lwp->lwp_xregs != NULL) + free(lwp->lwp_xregs); + if (lwp->lwp_asrs != NULL) + free(lwp->lwp_asrs); + #endif + free(lwp); + } + + if (core->core_platform != NULL) + free(core->core_platform); + if (core->core_uts != NULL) + free(core->core_uts); + if (core->core_cred != NULL) + free(core->core_cred); + if (core->core_priv != NULL) + free(core->core_priv); + if (core->core_privinfo != NULL) + __priv_free_info(core->core_privinfo); + if (core->core_ppii != NULL) + free(core->core_ppii); + if (core->core_zonename != NULL) + free(core->core_zonename); + #if defined(__i386) || defined(__amd64) + if (core->core_ldt != NULL) + free(core->core_ldt); + #endif + + free(core); + } + } + + /*ARGSUSED*/ + static char * + Pplatform_core(struct ps_prochandle *P, char *s, size_t n, void *data) + { + core_info_t *core = data; + + if (core->core_platform == NULL) { + errno = ENODATA; + return (NULL); + } + (void) strncpy(s, core->core_platform, n - 1); + s[n - 1] = '\0'; + return (s); + } + + /*ARGSUSED*/ + static int + Puname_core(struct ps_prochandle *P, struct utsname *u, void *data) + { + core_info_t *core = data; + + if (core->core_uts == NULL) { + errno = ENODATA; + return (-1); + } + (void) memcpy(u, core->core_uts, sizeof (struct utsname)); + return (0); + } + + /*ARGSUSED*/ + static char * + Pzonename_core(struct ps_prochandle *P, char *s, size_t n, void *data) + { + core_info_t *core = data; + + if (core->core_zonename == NULL) { + errno = ENODATA; + return (NULL); + } + (void) strlcpy(s, core->core_zonename, n); + return (s); + } + + #if defined(__i386) || defined(__amd64) + /*ARGSUSED*/ + static int + Pldt_core(struct ps_prochandle *P, struct ssd *pldt, int nldt, void *data) + { + core_info_t *core = data; + + if (pldt == NULL || nldt == 0) + return (core->core_nldt); + + if (core->core_ldt != NULL) { + nldt = MIN(nldt, core->core_nldt); + + (void) memcpy(pldt, core->core_ldt, + nldt * sizeof (struct ssd)); + + return (nldt); + } + + errno = ENODATA; + return (-1); + } + #endif + + static const ps_ops_t P_core_ops = { + .pop_pread = Pread_core, + .pop_pwrite = Pwrite_core, + .pop_cred = Pcred_core, + .pop_priv = Ppriv_core, + .pop_psinfo = Ppsinfo_core, + .pop_fini = Pfini_core, + .pop_platform = Pplatform_core, + .pop_uname = Puname_core, + .pop_zonename = Pzonename_core, + #if defined(__i386) || defined(__amd64) + .pop_ldt = Pldt_core + #endif + }; + /* * Return the lwp_info_t for the given lwpid. If no such lwpid has been * encountered yet, allocate a new structure and return a pointer to it. * Create a list of lwp_info_t structures sorted in decreasing lwp_id order. */ static lwp_info_t * lwpid2info(struct ps_prochandle *P, lwpid_t id) { ! core_info_t *core = P->data; ! lwp_info_t *lwp = list_next(&core->core_lwp_head); lwp_info_t *next; uint_t i; ! for (i = 0; i < core->core_nlwp; i++, lwp = list_next(lwp)) { if (lwp->lwp_id == id) { ! core->core_lwp = lwp; return (lwp); } if (lwp->lwp_id < id) { break; }
*** 153,164 **** return (NULL); list_link(lwp, next); lwp->lwp_id = id; ! P->core->core_lwp = lwp; ! P->core->core_nlwp++; return (lwp); } /* --- 337,348 ---- return (NULL); list_link(lwp, next); lwp->lwp_id = id; ! core->core_lwp = lwp; ! core->core_nlwp++; return (lwp); } /*
*** 173,183 **** static int note_pstatus(struct ps_prochandle *P, size_t nbytes) { #ifdef _LP64 ! if (P->core->core_dmodel == PR_MODEL_ILP32) { pstatus32_t ps32; if (nbytes < sizeof (pstatus32_t) || read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32)) goto err; --- 357,369 ---- static int note_pstatus(struct ps_prochandle *P, size_t nbytes) { #ifdef _LP64 ! core_info_t *core = P->data; ! ! if (core->core_dmodel == PR_MODEL_ILP32) { pstatus32_t ps32; if (nbytes < sizeof (pstatus32_t) || read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32)) goto err;
*** 205,215 **** { lwp_info_t *lwp; lwpstatus_t lps; #ifdef _LP64 ! if (P->core->core_dmodel == PR_MODEL_ILP32) { lwpstatus32_t l32; if (nbytes < sizeof (lwpstatus32_t) || read(P->asfd, &l32, sizeof (l32)) != sizeof (l32)) goto err; --- 391,403 ---- { lwp_info_t *lwp; lwpstatus_t lps; #ifdef _LP64 ! core_info_t *core = P->data; ! ! if (core->core_dmodel == PR_MODEL_ILP32) { lwpstatus32_t l32; if (nbytes < sizeof (lwpstatus32_t) || read(P->asfd, &l32, sizeof (l32)) != sizeof (l32)) goto err;
*** 244,254 **** static int note_psinfo(struct ps_prochandle *P, size_t nbytes) { #ifdef _LP64 ! if (P->core->core_dmodel == PR_MODEL_ILP32) { psinfo32_t ps32; if (nbytes < sizeof (psinfo32_t) || read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32)) goto err; --- 432,444 ---- static int note_psinfo(struct ps_prochandle *P, size_t nbytes) { #ifdef _LP64 ! core_info_t *core = P->data; ! ! if (core->core_dmodel == PR_MODEL_ILP32) { psinfo32_t ps32; if (nbytes < sizeof (psinfo32_t) || read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32)) goto err;
*** 276,286 **** { lwp_info_t *lwp; lwpsinfo_t lps; #ifdef _LP64 ! if (P->core->core_dmodel == PR_MODEL_ILP32) { lwpsinfo32_t l32; if (nbytes < sizeof (lwpsinfo32_t) || read(P->asfd, &l32, sizeof (l32)) != sizeof (l32)) goto err; --- 466,478 ---- { lwp_info_t *lwp; lwpsinfo_t lps; #ifdef _LP64 ! core_info_t *core = P->data; ! ! if (core->core_dmodel == PR_MODEL_ILP32) { lwpsinfo32_t l32; if (nbytes < sizeof (lwpsinfo32_t) || read(P->asfd, &l32, sizeof (l32)) != sizeof (l32)) goto err;
*** 326,360 **** } static int note_platform(struct ps_prochandle *P, size_t nbytes) { char *plat; ! if (P->core->core_platform != NULL) return (0); /* Already seen */ if (nbytes != 0 && ((plat = malloc(nbytes + 1)) != NULL)) { if (read(P->asfd, plat, nbytes) != nbytes) { dprintf("Pgrab_core: failed to read NT_PLATFORM\n"); free(plat); return (-1); } plat[nbytes - 1] = '\0'; ! P->core->core_platform = plat; } return (0); } static int note_utsname(struct ps_prochandle *P, size_t nbytes) { size_t ubytes = sizeof (struct utsname); struct utsname *utsp; ! if (P->core->core_uts != NULL || nbytes < ubytes) return (0); /* Already seen or bad size */ if ((utsp = malloc(ubytes)) == NULL) return (-1); --- 518,554 ---- } static int note_platform(struct ps_prochandle *P, size_t nbytes) { + core_info_t *core = P->data; char *plat; ! if (core->core_platform != NULL) return (0); /* Already seen */ if (nbytes != 0 && ((plat = malloc(nbytes + 1)) != NULL)) { if (read(P->asfd, plat, nbytes) != nbytes) { dprintf("Pgrab_core: failed to read NT_PLATFORM\n"); free(plat); return (-1); } plat[nbytes - 1] = '\0'; ! core->core_platform = plat; } return (0); } static int note_utsname(struct ps_prochandle *P, size_t nbytes) { + core_info_t *core = P->data; size_t ubytes = sizeof (struct utsname); struct utsname *utsp; ! if (core->core_uts != NULL || nbytes < ubytes) return (0); /* Already seen or bad size */ if ((utsp = malloc(ubytes)) == NULL) return (-1);
*** 370,404 **** dprintf("uts.release = \"%s\"\n", utsp->release); dprintf("uts.version = \"%s\"\n", utsp->version); dprintf("uts.machine = \"%s\"\n", utsp->machine); } ! P->core->core_uts = utsp; return (0); } static int note_content(struct ps_prochandle *P, size_t nbytes) { core_content_t content; ! if (sizeof (P->core->core_content) != nbytes) return (-1); if (read(P->asfd, &content, sizeof (content)) != sizeof (content)) return (-1); ! P->core->core_content = content; dprintf("core content = %llx\n", content); return (0); } static int note_cred(struct ps_prochandle *P, size_t nbytes) { prcred_t *pcrp; int ngroups; const size_t min_size = sizeof (prcred_t) - sizeof (gid_t); /* --- 564,600 ---- dprintf("uts.release = \"%s\"\n", utsp->release); dprintf("uts.version = \"%s\"\n", utsp->version); dprintf("uts.machine = \"%s\"\n", utsp->machine); } ! core->core_uts = utsp; return (0); } static int note_content(struct ps_prochandle *P, size_t nbytes) { + core_info_t *core = P->data; core_content_t content; ! if (sizeof (core->core_content) != nbytes) return (-1); if (read(P->asfd, &content, sizeof (content)) != sizeof (content)) return (-1); ! core->core_content = content; dprintf("core content = %llx\n", content); return (0); } static int note_cred(struct ps_prochandle *P, size_t nbytes) { + core_info_t *core = P->data; prcred_t *pcrp; int ngroups; const size_t min_size = sizeof (prcred_t) - sizeof (gid_t); /*
*** 405,415 **** * We allow for prcred_t notes that are actually smaller than a * prcred_t since the last member isn't essential if there are * no group memberships. This allows for more flexibility when it * comes to slightly malformed -- but still valid -- notes. */ ! if (P->core->core_cred != NULL || nbytes < min_size) return (0); /* Already seen or bad size */ ngroups = (nbytes - min_size) / sizeof (gid_t); nbytes = sizeof (prcred_t) + (ngroups - 1) * sizeof (gid_t); --- 601,611 ---- * We allow for prcred_t notes that are actually smaller than a * prcred_t since the last member isn't essential if there are * no group memberships. This allows for more flexibility when it * comes to slightly malformed -- but still valid -- notes. */ ! if (core->core_cred != NULL || nbytes < min_size) return (0); /* Already seen or bad size */ ngroups = (nbytes - min_size) / sizeof (gid_t); nbytes = sizeof (prcred_t) + (ngroups - 1) * sizeof (gid_t);
*** 426,447 **** dprintf("pr_ngroups = %d; resetting to %d based on note size\n", pcrp->pr_ngroups, ngroups); pcrp->pr_ngroups = ngroups; } ! P->core->core_cred = pcrp; return (0); } #if defined(__i386) || defined(__amd64) static int note_ldt(struct ps_prochandle *P, size_t nbytes) { struct ssd *pldt; uint_t nldt; ! if (P->core->core_ldt != NULL || nbytes < sizeof (struct ssd)) return (0); /* Already seen or bad size */ nldt = nbytes / sizeof (struct ssd); nbytes = nldt * sizeof (struct ssd); --- 622,644 ---- dprintf("pr_ngroups = %d; resetting to %d based on note size\n", pcrp->pr_ngroups, ngroups); pcrp->pr_ngroups = ngroups; } ! core->core_cred = pcrp; return (0); } #if defined(__i386) || defined(__amd64) static int note_ldt(struct ps_prochandle *P, size_t nbytes) { + core_info_t *core = P->data; struct ssd *pldt; uint_t nldt; ! if (core->core_ldt != NULL || nbytes < sizeof (struct ssd)) return (0); /* Already seen or bad size */ nldt = nbytes / sizeof (struct ssd); nbytes = nldt * sizeof (struct ssd);
*** 452,473 **** dprintf("Pgrab_core: failed to read NT_LDT\n"); free(pldt); return (-1); } ! P->core->core_ldt = pldt; ! P->core->core_nldt = nldt; return (0); } #endif /* __i386 */ static int note_priv(struct ps_prochandle *P, size_t nbytes) { prpriv_t *pprvp; ! if (P->core->core_priv != NULL || nbytes < sizeof (prpriv_t)) return (0); /* Already seen or bad size */ if ((pprvp = malloc(nbytes)) == NULL) return (-1); --- 649,671 ---- dprintf("Pgrab_core: failed to read NT_LDT\n"); free(pldt); return (-1); } ! core->core_ldt = pldt; ! core->core_nldt = nldt; return (0); } #endif /* __i386 */ static int note_priv(struct ps_prochandle *P, size_t nbytes) { + core_info_t *core = P->data; prpriv_t *pprvp; ! if (core->core_priv != NULL || nbytes < sizeof (prpriv_t)) return (0); /* Already seen or bad size */ if ((pprvp = malloc(nbytes)) == NULL) return (-1);
*** 475,496 **** dprintf("Pgrab_core: failed to read NT_PRPRIV\n"); free(pprvp); return (-1); } ! P->core->core_priv = pprvp; ! P->core->core_priv_size = nbytes; return (0); } static int note_priv_info(struct ps_prochandle *P, size_t nbytes) { extern void *__priv_parse_info(); priv_impl_info_t *ppii; ! if (P->core->core_privinfo != NULL || nbytes < sizeof (priv_impl_info_t)) return (0); /* Already seen or bad size */ if ((ppii = malloc(nbytes)) == NULL) return (-1); --- 673,695 ---- dprintf("Pgrab_core: failed to read NT_PRPRIV\n"); free(pprvp); return (-1); } ! core->core_priv = pprvp; ! core->core_priv_size = nbytes; return (0); } static int note_priv_info(struct ps_prochandle *P, size_t nbytes) { + core_info_t *core = P->data; extern void *__priv_parse_info(); priv_impl_info_t *ppii; ! if (core->core_privinfo != NULL || nbytes < sizeof (priv_impl_info_t)) return (0); /* Already seen or bad size */ if ((ppii = malloc(nbytes)) == NULL) return (-1);
*** 500,520 **** dprintf("Pgrab_core: failed to read NT_PRPRIVINFO\n"); free(ppii); return (-1); } ! P->core->core_privinfo = __priv_parse_info(ppii); ! P->core->core_ppii = ppii; return (0); } static int note_zonename(struct ps_prochandle *P, size_t nbytes) { char *zonename; ! if (P->core->core_zonename != NULL) return (0); /* Already seen */ if (nbytes != 0) { if ((zonename = malloc(nbytes)) == NULL) return (-1); --- 699,720 ---- dprintf("Pgrab_core: failed to read NT_PRPRIVINFO\n"); free(ppii); return (-1); } ! core->core_privinfo = __priv_parse_info(ppii); ! core->core_ppii = ppii; return (0); } static int note_zonename(struct ps_prochandle *P, size_t nbytes) { + core_info_t *core = P->data; char *zonename; ! if (core->core_zonename != NULL) return (0); /* Already seen */ if (nbytes != 0) { if ((zonename = malloc(nbytes)) == NULL) return (-1);
*** 522,532 **** dprintf("Pgrab_core: failed to read NT_ZONENAME\n"); free(zonename); return (-1); } zonename[nbytes - 1] = '\0'; ! P->core->core_zonename = zonename; } return (0); } --- 722,732 ---- dprintf("Pgrab_core: failed to read NT_ZONENAME\n"); free(zonename); return (-1); } zonename[nbytes - 1] = '\0'; ! core->core_zonename = zonename; } return (0); }
*** 534,544 **** note_auxv(struct ps_prochandle *P, size_t nbytes) { size_t n, i; #ifdef _LP64 ! if (P->core->core_dmodel == PR_MODEL_ILP32) { auxv32_t *a32; n = nbytes / sizeof (auxv32_t); nbytes = n * sizeof (auxv32_t); a32 = alloca(nbytes); --- 734,746 ---- note_auxv(struct ps_prochandle *P, size_t nbytes) { size_t n, i; #ifdef _LP64 ! core_info_t *core = P->data; ! ! if (core->core_dmodel == PR_MODEL_ILP32) { auxv32_t *a32; n = nbytes / sizeof (auxv32_t); nbytes = n * sizeof (auxv32_t); a32 = alloca(nbytes);
*** 592,602 **** #ifdef __sparc static int note_xreg(struct ps_prochandle *P, size_t nbytes) { ! lwp_info_t *lwp = P->core->core_lwp; size_t xbytes = sizeof (prxregset_t); prxregset_t *xregs; if (lwp == NULL || lwp->lwp_xregs != NULL || nbytes < xbytes) return (0); /* No lwp yet, already seen, or bad size */ --- 794,805 ---- #ifdef __sparc static int note_xreg(struct ps_prochandle *P, size_t nbytes) { ! core_info_t *core = P->data; ! lwp_info_t *lwp = core->core_lwp; size_t xbytes = sizeof (prxregset_t); prxregset_t *xregs; if (lwp == NULL || lwp->lwp_xregs != NULL || nbytes < xbytes) return (0); /* No lwp yet, already seen, or bad size */
*** 615,625 **** } static int note_gwindows(struct ps_prochandle *P, size_t nbytes) { ! lwp_info_t *lwp = P->core->core_lwp; if (lwp == NULL || lwp->lwp_gwins != NULL || nbytes == 0) return (0); /* No lwp yet or already seen or no data */ if ((lwp->lwp_gwins = malloc(sizeof (gwindows_t))) == NULL) --- 818,829 ---- } static int note_gwindows(struct ps_prochandle *P, size_t nbytes) { ! core_info_t *core = P->data; ! lwp_info_t *lwp = core->core_lwp; if (lwp == NULL || lwp->lwp_gwins != NULL || nbytes == 0) return (0); /* No lwp yet or already seen or no data */ if ((lwp->lwp_gwins = malloc(sizeof (gwindows_t))) == NULL)
*** 630,640 **** * actually saved, we just read up to the minimum of the note size * and the size of the gwindows_t type. It doesn't matter if the read * fails since we have to zero out gwindows first anyway. */ #ifdef _LP64 ! if (P->core->core_dmodel == PR_MODEL_ILP32) { gwindows32_t g32; (void) memset(&g32, 0, sizeof (g32)); (void) read(P->asfd, &g32, MIN(nbytes, sizeof (g32))); gwindows_32_to_n(&g32, lwp->lwp_gwins); --- 834,844 ---- * actually saved, we just read up to the minimum of the note size * and the size of the gwindows_t type. It doesn't matter if the read * fails since we have to zero out gwindows first anyway. */ #ifdef _LP64 ! if (core->core_dmodel == PR_MODEL_ILP32) { gwindows32_t g32; (void) memset(&g32, 0, sizeof (g32)); (void) read(P->asfd, &g32, MIN(nbytes, sizeof (g32))); gwindows_32_to_n(&g32, lwp->lwp_gwins);
*** 652,662 **** #ifdef __sparcv9 static int note_asrs(struct ps_prochandle *P, size_t nbytes) { ! lwp_info_t *lwp = P->core->core_lwp; int64_t *asrs; if (lwp == NULL || lwp->lwp_asrs != NULL || nbytes < sizeof (asrset_t)) return (0); /* No lwp yet, already seen, or bad size */ --- 856,867 ---- #ifdef __sparcv9 static int note_asrs(struct ps_prochandle *P, size_t nbytes) { ! core_info_t *core = P->data; ! lwp_info_t *lwp = core->core_lwp; int64_t *asrs; if (lwp == NULL || lwp->lwp_asrs != NULL || nbytes < sizeof (asrset_t)) return (0); /* No lwp yet, already seen, or bad size */
*** 677,687 **** static int note_spymaster(struct ps_prochandle *P, size_t nbytes) { #ifdef _LP64 ! if (P->core->core_dmodel == PR_MODEL_ILP32) { psinfo32_t ps32; if (nbytes < sizeof (psinfo32_t) || read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32)) goto err; --- 882,894 ---- static int note_spymaster(struct ps_prochandle *P, size_t nbytes) { #ifdef _LP64 ! core_info_t *core = P->data; ! ! if (core->core_dmodel == PR_MODEL_ILP32) { psinfo32_t ps32; if (nbytes < sizeof (psinfo32_t) || read(P->asfd, &ps32, sizeof (ps32)) != sizeof (ps32)) goto err;
*** 828,837 **** --- 1035,1045 ---- * PT_LOAD program header. We fill in more information on the mapping later. */ static int core_add_mapping(struct ps_prochandle *P, GElf_Phdr *php) { + core_info_t *core = P->data; prmap_t pmap; dprintf("mapping base %llx filesz %llu memsz %llu offset %llu\n", (u_longlong_t)php->p_vaddr, (u_longlong_t)php->p_filesz, (u_longlong_t)php->p_memsz, (u_longlong_t)php->p_offset);
*** 843,853 **** * If Pgcore() or elfcore() fail to write a mapping, they will set * PF_SUNW_FAILURE in the Phdr and try to stash away the errno for us. */ if (php->p_flags & PF_SUNW_FAILURE) { core_report_mapping(P, php); ! } else if (php->p_filesz != 0 && php->p_offset >= P->core->core_size) { Perror_printf(P, "core file may be corrupt -- data for mapping " "at %p is missing\n", (void *)(uintptr_t)php->p_vaddr); dprintf("core file may be corrupt -- data for mapping " "at %p is missing\n", (void *)(uintptr_t)php->p_vaddr); } --- 1051,1061 ---- * If Pgcore() or elfcore() fail to write a mapping, they will set * PF_SUNW_FAILURE in the Phdr and try to stash away the errno for us. */ if (php->p_flags & PF_SUNW_FAILURE) { core_report_mapping(P, php); ! } else if (php->p_filesz != 0 && php->p_offset >= core->core_size) { Perror_printf(P, "core file may be corrupt -- data for mapping " "at %p is missing\n", (void *)(uintptr_t)php->p_vaddr); dprintf("core file may be corrupt -- data for mapping " "at %p is missing\n", (void *)(uintptr_t)php->p_vaddr); }
*** 1479,1488 **** --- 1687,1697 ---- * and attempt to construct a symbol table for the load object. */ static int core_iter_mapping(const rd_loadobj_t *rlp, struct ps_prochandle *P) { + core_info_t *core = P->data; char lname[PATH_MAX], buf[PATH_MAX]; file_info_t *fp; map_info_t *mp; if (Pread_string(P, lname, PATH_MAX, (off_t)rlp->rl_nameaddr) <= 0) {
*** 1506,1524 **** * file_info_new() will try to use its section headers to * identify any other mappings that belong to this load object. */ if ((fp = mp->map_file) == NULL && (fp = file_info_new(P, mp)) == NULL) { ! P->core->core_errno = errno; dprintf("failed to malloc mapping data\n"); return (0); /* Abort */ } fp->file_map = mp; /* Create a local copy of the load object representation */ if ((fp->file_lo = calloc(1, sizeof (rd_loadobj_t))) == NULL) { ! P->core->core_errno = errno; dprintf("failed to malloc mapping data\n"); return (0); /* Abort */ } *fp->file_lo = *rlp; --- 1715,1733 ---- * file_info_new() will try to use its section headers to * identify any other mappings that belong to this load object. */ if ((fp = mp->map_file) == NULL && (fp = file_info_new(P, mp)) == NULL) { ! core->core_errno = errno; dprintf("failed to malloc mapping data\n"); return (0); /* Abort */ } fp->file_map = mp; /* Create a local copy of the load object representation */ if ((fp->file_lo = calloc(1, sizeof (rd_loadobj_t))) == NULL) { ! core->core_errno = errno; dprintf("failed to malloc mapping data\n"); return (0); /* Abort */ } *fp->file_lo = *rlp;
*** 1781,1790 **** --- 1990,2000 ---- */ struct ps_prochandle * Pfgrab_core(int core_fd, const char *aout_path, int *perr) { struct ps_prochandle *P; + core_info_t *core_info; map_info_t *stk_mp, *brk_mp; const char *execname; char *interp; int i, notes, pagesize; uintptr_t addr, base_addr;
*** 1846,1856 **** P->statfd = -1; P->agentctlfd = -1; P->agentstatfd = -1; P->zoneroot = NULL; P->info_valid = 1; ! P->ops = &P_core_ops; Pinitsym(P); /* * Fstat and open the core file and make sure it is a valid ELF core. --- 2056,2066 ---- P->statfd = -1; P->agentctlfd = -1; P->agentstatfd = -1; P->zoneroot = NULL; P->info_valid = 1; ! Pinit_ops(&P->ops, &P_core_ops); Pinitsym(P); /* * Fstat and open the core file and make sure it is a valid ELF core.
*** 1865,1896 **** /* * Allocate and initialize a core_info_t to hang off the ps_prochandle * structure. We keep all core-specific information in this structure. */ ! if ((P->core = calloc(1, sizeof (core_info_t))) == NULL) { *perr = G_STRANGE; goto err; } ! list_link(&P->core->core_lwp_head, NULL); ! P->core->core_size = stbuf.st_size; /* * In the days before adjustable core file content, this was the * default core file content. For new core files, this value will * be overwritten by the NT_CONTENT note section. */ ! P->core->core_content = CC_CONTENT_STACK | CC_CONTENT_HEAP | CC_CONTENT_DATA | CC_CONTENT_RODATA | CC_CONTENT_ANON | CC_CONTENT_SHANON; switch (core.e_hdr.e_ident[EI_CLASS]) { case ELFCLASS32: ! P->core->core_dmodel = PR_MODEL_ILP32; break; case ELFCLASS64: ! P->core->core_dmodel = PR_MODEL_LP64; break; default: *perr = G_FORMAT; goto err; } --- 2075,2107 ---- /* * Allocate and initialize a core_info_t to hang off the ps_prochandle * structure. We keep all core-specific information in this structure. */ ! if ((core_info = calloc(1, sizeof (core_info_t))) == NULL) { *perr = G_STRANGE; goto err; } ! P->data = core_info; ! list_link(&core_info->core_lwp_head, NULL); ! core_info->core_size = stbuf.st_size; /* * In the days before adjustable core file content, this was the * default core file content. For new core files, this value will * be overwritten by the NT_CONTENT note section. */ ! core_info->core_content = CC_CONTENT_STACK | CC_CONTENT_HEAP | CC_CONTENT_DATA | CC_CONTENT_RODATA | CC_CONTENT_ANON | CC_CONTENT_SHANON; switch (core.e_hdr.e_ident[EI_CLASS]) { case ELFCLASS32: ! core_info->core_dmodel = PR_MODEL_ILP32; break; case ELFCLASS64: ! core_info->core_dmodel = PR_MODEL_LP64; break; default: *perr = G_FORMAT; goto err; }
*** 2112,2122 **** dp->d_size != 0) { dprintf(".interp = <%s>\n", (char *)dp->d_buf); interp = dp->d_buf; } else if (base_addr != (uintptr_t)-1L) { ! if (P->core->core_dmodel == PR_MODEL_LP64) interp = "/usr/lib/64/ld.so.1"; else interp = "/usr/lib/ld.so.1"; dprintf(".interp section is missing or could not be read; " --- 2323,2333 ---- dp->d_size != 0) { dprintf(".interp = <%s>\n", (char *)dp->d_buf); interp = dp->d_buf; } else if (base_addr != (uintptr_t)-1L) { ! if (core_info->core_dmodel == PR_MODEL_LP64) interp = "/usr/lib/64/ld.so.1"; else interp = "/usr/lib/ld.so.1"; dprintf(".interp section is missing or could not be read; "
*** 2227,2238 **** if ((P->rap = rd_new(P)) != NULL) { (void) rd_loadobj_iter(P->rap, (rl_iter_f *) core_iter_mapping, P); ! if (P->core->core_errno != 0) { ! errno = P->core->core_errno; *perr = G_STRANGE; goto err; } } else dprintf("failed to initialize rtld_db agent\n"); --- 2438,2449 ---- if ((P->rap = rd_new(P)) != NULL) { (void) rd_loadobj_iter(P->rap, (rl_iter_f *) core_iter_mapping, P); ! if (core_info->core_errno != 0) { ! errno = core_info->core_errno; *perr = G_STRANGE; goto err; } } else dprintf("failed to initialize rtld_db agent\n");