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.c11
-rw-r--r--usr/src/lib/libproc/common/Pcontrol.h1
-rw-r--r--usr/src/lib/libproc/common/Psymtab.c64
3 files changed, 74 insertions, 2 deletions
diff --git a/usr/src/lib/libproc/common/Pcontrol.c b/usr/src/lib/libproc/common/Pcontrol.c
index 90ce97c191..7e7c254bfc 100644
--- a/usr/src/lib/libproc/common/Pcontrol.c
+++ b/usr/src/lib/libproc/common/Pcontrol.c
@@ -349,10 +349,16 @@ static const ps_ops_t P_live_ops = {
void
_libproc_init(void)
{
+ const char *root;
+
_libproc_debug = getenv("LIBPROC_DEBUG") != NULL;
_libproc_no_qsort = getenv("LIBPROC_NO_QSORT") != NULL;
_libproc_incore_elf = getenv("LIBPROC_INCORE_ELF") != NULL;
+ if ((root = zone_get_nroot()) != NULL)
+ (void) snprintf(procfs_path, sizeof (procfs_path), "%s/proc",
+ root);
+
(void) sigfillset(&blockable_sigs);
(void) sigdelset(&blockable_sigs, SIGKILL);
(void) sigdelset(&blockable_sigs, SIGSTOP);
@@ -1798,6 +1804,9 @@ prldump(const char *caller, lwpstatus_t *lsp)
case PR_SUSPENDED:
dprintf("%s: SUSPENDED\n", caller);
break;
+ case PR_BRAND:
+ dprintf("%s: BRANDPRIVATE (%d)\n", caller, lsp->pr_what);
+ break;
default:
dprintf("%s: Unknown\n", caller);
break;
@@ -1977,6 +1986,7 @@ Pstopstatus(struct ps_prochandle *P,
case PR_FAULTED:
case PR_JOBCONTROL:
case PR_SUSPENDED:
+ case PR_BRAND:
break;
default:
errno = EPROTO;
@@ -3551,6 +3561,7 @@ Lstopstatus(struct ps_lwphandle *L,
case PR_FAULTED:
case PR_JOBCONTROL:
case PR_SUSPENDED:
+ case PR_BRAND:
break;
default:
errno = EPROTO;
diff --git a/usr/src/lib/libproc/common/Pcontrol.h b/usr/src/lib/libproc/common/Pcontrol.h
index b5de8ccd50..d701140173 100644
--- a/usr/src/lib/libproc/common/Pcontrol.h
+++ b/usr/src/lib/libproc/common/Pcontrol.h
@@ -128,6 +128,7 @@ typedef struct file_info { /* symbol information for a mapped file */
size_t file_shstrsz; /* section header string table size */
uintptr_t *file_saddrs; /* section header addresses */
uint_t file_nsaddrs; /* number of section header addresses */
+ boolean_t file_cvt; /* Have we tried to convert this? */
} file_info_t;
typedef struct map_info { /* description of an address space mapping */
diff --git a/usr/src/lib/libproc/common/Psymtab.c b/usr/src/lib/libproc/common/Psymtab.c
index b92e5a7d56..7527c7e10c 100644
--- a/usr/src/lib/libproc/common/Psymtab.c
+++ b/usr/src/lib/libproc/common/Psymtab.c
@@ -742,6 +742,65 @@ Pname_to_loadobj(struct ps_prochandle *P, const char *name)
return (Plmid_to_loadobj(P, PR_LMID_EVERY, name));
}
+/*
+ * We've been given a file_info_t which doesn't have any CTF. However, it may
+ * have information that's in a format that we could convert if on the fly.
+ * We'll first try to convert the alternate debug file, if present, and then
+ * move onto the default file. The reason we prefer the alternate debug file is
+ * that if both exist, then it likely has any usable debugging information.
+ */
+static ctf_file_t *
+Pconvert_file_ctf(file_info_t *fptr)
+{
+ int err;
+ ctf_convert_t *cch;
+ ctf_file_t *fp;
+ char errmsg[1024];
+
+ /*
+ * Provide an opt in.
+ */
+ if (getenv("LIBPROC_CTFCONVERT") == NULL)
+ return (NULL);
+
+ /*
+ * If we've already attempted to call this, then that's it. No reason to
+ * pretend we'll be more successful again another time.
+ */
+ if (fptr->file_cvt == B_TRUE)
+ return (NULL);
+
+ cch = ctf_convert_init(&err);
+ if (cch == NULL)
+ return (NULL);
+
+ fptr->file_cvt = B_TRUE;
+
+ fp = NULL;
+ if (fptr->file_dbgelf != NULL) {
+ fp = ctf_elfconvert(cch, fptr->file_fd, fptr->file_dbgelf, &err,
+ errmsg, sizeof (errmsg));
+ if (fp == NULL) {
+ dprintf("failed to convert %s: %s\n", fptr->file_pname,
+ err == ECTF_CONVBKERR ? errmsg : ctf_errmsg(err));
+ }
+ }
+ if (fp == NULL) {
+ fp = ctf_elfconvert(cch, fptr->file_fd, fptr->file_elf, &err,
+ errmsg, sizeof (errmsg));
+ if (fp == NULL) {
+ dprintf("failed to convert %s: %s\n", fptr->file_pname,
+ err == ECTF_CONVBKERR ? errmsg : ctf_errmsg(err));
+ }
+ }
+ if (fp != NULL) {
+ fptr->file_ctfp = fp;
+ }
+
+ ctf_convert_fini(cch);
+ return (NULL);
+}
+
ctf_file_t *
Pbuild_file_ctf(struct ps_prochandle *P, file_info_t *fptr)
{
@@ -754,8 +813,9 @@ Pbuild_file_ctf(struct ps_prochandle *P, file_info_t *fptr)
Pbuild_file_symtab(P, fptr);
- if (fptr->file_ctf_size == 0)
- return (NULL);
+ if (fptr->file_ctf_size == 0) {
+ return (Pconvert_file_ctf(fptr));
+ }
symp = fptr->file_ctf_dyn ? &fptr->file_dynsym : &fptr->file_symtab;
if (symp->sym_data_pri == NULL)