summaryrefslogtreecommitdiff
path: root/usr/src/lib/libproc/common
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libproc/common')
-rw-r--r--usr/src/lib/libproc/common/Pcontrol.c2
-rw-r--r--usr/src/lib/libproc/common/Pcontrol.h1
-rw-r--r--usr/src/lib/libproc/common/Pcore.c65
-rw-r--r--usr/src/lib/libproc/common/libproc.h6
-rw-r--r--usr/src/lib/libproc/common/mapfile-vers2
-rw-r--r--usr/src/lib/libproc/common/proc_names.c3
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 */