diff options
Diffstat (limited to 'usr/src/lib/libproc/common')
-rw-r--r-- | usr/src/lib/libproc/common/Pcontrol.c | 2 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/Pcontrol.h | 1 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/Pcore.c | 65 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/libproc.h | 6 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/mapfile-vers | 2 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/proc_names.c | 3 |
6 files changed, 78 insertions, 1 deletions
diff --git a/usr/src/lib/libproc/common/Pcontrol.c b/usr/src/lib/libproc/common/Pcontrol.c index b68adfb044..eda2737d91 100644 --- a/usr/src/lib/libproc/common/Pcontrol.c +++ b/usr/src/lib/libproc/common/Pcontrol.c @@ -1318,6 +1318,8 @@ Psecflags(struct ps_prochandle *P, prsecflags_t **psf) if ((ret = P->ops.pop_secflags(P, psf, P->data)) == 0) { if ((*psf)->pr_version != PRSECFLAGS_VERSION_1) { + free(*psf); + *psf = NULL; errno = EINVAL; return (-1); } diff --git a/usr/src/lib/libproc/common/Pcontrol.h b/usr/src/lib/libproc/common/Pcontrol.h index 550b6779dd..6121a7e79b 100644 --- a/usr/src/lib/libproc/common/Pcontrol.h +++ b/usr/src/lib/libproc/common/Pcontrol.h @@ -172,6 +172,7 @@ typedef struct core_info { /* information specific to core files */ priv_impl_info_t *core_ppii; /* NOTE entry for core_privinfo */ char *core_zonename; /* zone name from core file */ prsecflags_t *core_secflags; /* secflags from core file */ + prupanic_t *core_upanic; /* upanic from core file */ #if defined(__i386) || defined(__amd64) struct ssd *core_ldt; /* LDT entries from core file */ uint_t core_nldt; /* number of LDT entries in core file */ diff --git a/usr/src/lib/libproc/common/Pcore.c b/usr/src/lib/libproc/common/Pcore.c index cd539876b1..39424fad67 100644 --- a/usr/src/lib/libproc/common/Pcore.c +++ b/usr/src/lib/libproc/common/Pcore.c @@ -245,6 +245,8 @@ Pfini_core(struct ps_prochandle *P, void *data) free(core->core_zonename); if (core->core_secflags != NULL) free(core->core_secflags); + if (core->core_upanic != NULL) + free(core->core_upanic); #ifdef __x86 if (core->core_ldt != NULL) free(core->core_ldt); @@ -1201,6 +1203,34 @@ err: return (-1); } +static int +note_upanic(struct ps_prochandle *P, size_t nbytes) +{ + core_info_t *core = P->data; + prupanic_t *pru; + + if (core->core_upanic != NULL) + return (0); + + if (sizeof (*pru) != nbytes) { + dprintf("Pgrab_core: NT_UPANIC changed size." + " Need to handle a version change?\n"); + return (-1); + } + + if (nbytes != 0 && ((pru = malloc(nbytes)) != NULL)) { + if (read(P->asfd, pru, nbytes) != nbytes) { + dprintf("Pgrab_core: failed to read NT_UPANIC\n"); + free(pru); + return (-1); + } + + core->core_upanic = pru; + } + + return (0); +} + /*ARGSUSED*/ static int note_notsup(struct ps_prochandle *P, size_t nbytes) @@ -1266,6 +1296,7 @@ static int (*nhdlrs[])(struct ps_prochandle *, size_t) = { note_spymaster, /* 23 NT_SPYMASTER */ note_secflags, /* 24 NT_SECFLAGS */ note_lwpname, /* 25 NT_LWPNAME */ + note_upanic /* 26 NT_UPANIC */ }; static void @@ -2880,3 +2911,37 @@ Pgrab_core(const char *core, const char *aout, int gflag, int *perr) return (NULL); } + +int +Pupanic(struct ps_prochandle *P, prupanic_t **pru) +{ + core_info_t *core; + + if (P->state != PS_DEAD) { + errno = ENODATA; + return (-1); + } + + core = P->data; + if (core->core_upanic == NULL) { + errno = ENOENT; + return (-1); + } + + if (core->core_upanic->pru_version != PRUPANIC_VERSION_1) { + errno = EINVAL; + return (-1); + } + + if ((*pru = calloc(1, sizeof (prupanic_t))) == NULL) + return (-1); + (void) memcpy(*pru, core->core_upanic, sizeof (prupanic_t)); + + return (0); +} + +void +Pupanic_free(prupanic_t *pru) +{ + free(pru); +} diff --git a/usr/src/lib/libproc/common/libproc.h b/usr/src/lib/libproc/common/libproc.h index cdf789a621..a73f8af647 100644 --- a/usr/src/lib/libproc/common/libproc.h +++ b/usr/src/lib/libproc/common/libproc.h @@ -792,6 +792,12 @@ extern int proc_finistdio(void); typedef int proc_fdinfo_f(void *, const prfdinfo_t *); extern int Pfdinfo_iter(struct ps_prochandle *, proc_fdinfo_f *, void *); +/* + * NT_UPANIC information. + */ +extern int Pupanic(struct ps_prochandle *, prupanic_t **); +extern void Pupanic_free(prupanic_t *); + #ifdef __cplusplus } #endif diff --git a/usr/src/lib/libproc/common/mapfile-vers b/usr/src/lib/libproc/common/mapfile-vers index 1da5918393..61934de499 100644 --- a/usr/src/lib/libproc/common/mapfile-vers +++ b/usr/src/lib/libproc/common/mapfile-vers @@ -307,6 +307,8 @@ SYMBOL_VERSION SUNWprivate_1.1 { Punsetflags; Pupdate_maps; Pupdate_syms; + Pupanic; + Pupanic_free; Pwait; Pwrite; Pxcreate; diff --git a/usr/src/lib/libproc/common/proc_names.c b/usr/src/lib/libproc/common/proc_names.c index 314b01fbcd..65332da273 100644 --- a/usr/src/lib/libproc/common/proc_names.c +++ b/usr/src/lib/libproc/common/proc_names.c @@ -24,6 +24,7 @@ * Copyright (c) 2015, Joyent, Inc. All rights reserved. * Copyright 2019, Carlos Neira <cneirabustos@gmail.com> * Copyright 2019 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2020 Oxide Computer Company */ #include <stdio.h> @@ -241,7 +242,7 @@ static const char *const systable[] = { "writev", /* 122 */ "preadv", /* 123 */ "pwritev", /* 124 */ - NULL, /* 125 */ + "upanic", /* 125 */ "getrandom", /* 126 */ "mmapobj", /* 127 */ "setrlimit", /* 128 */ |