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");