summaryrefslogtreecommitdiffstats
path: root/lib/libproc
diff options
context:
space:
mode:
authormarkj <markj@FreeBSD.org>2014-10-03 23:20:37 +0000
committermarkj <markj@FreeBSD.org>2014-10-03 23:20:37 +0000
commit91d5d12d67db05be29b36096bcb90e39e1541fae (patch)
treee5d14bcbe841b9c2e8e073a1970aa1c856236b02 /lib/libproc
parentb089d064397fe71608574f13f2e413d9e5c2786a (diff)
downloadFreeBSD-src-91d5d12d67db05be29b36096bcb90e39e1541fae.zip
FreeBSD-src-91d5d12d67db05be29b36096bcb90e39e1541fae.tar.gz
Hook up support for userland CTF support in DTrace. This required some
modifications to libproc to support fetching the CTF info for a given file. With this change, dtrace(1) is able to resolve type info for function and USDT probe arguments, and function return values. In particular, the args[n] syntax should now work for referencing arguments of userland probes, provided that the requisite CTF info is available. The uctf tests pass if the test programs are compiled with CTF info. The current infrastructure around the DTrace test suite doesn't support this yet. Differential Revision: https://reviews.freebsd.org/D891 MFC after: 1 month Relnotes: yes Sponsored by: EMC / Isilon Storage Division
Diffstat (limited to 'lib/libproc')
-rw-r--r--lib/libproc/Makefile13
-rw-r--r--lib/libproc/libproc.h13
-rw-r--r--lib/libproc/proc_sym.c41
-rw-r--r--lib/libproc/tests/proc_test.c10
4 files changed, 65 insertions, 12 deletions
diff --git a/lib/libproc/Makefile b/lib/libproc/Makefile
index d665dc4..8a0f4b2 100644
--- a/lib/libproc/Makefile
+++ b/lib/libproc/Makefile
@@ -25,7 +25,18 @@ LDADD+= -lsupc++
DPADD+= ${LIBSTDCPLUSPLUS}
.endif
-SHLIB_MAJOR= 2
+.if ${MK_CDDL} != "no"
+LDADD+= -lctf
+DPADD+= ${LIBCTF}
+IGNORE_PRAGMA= YES
+CFLAGS+= -I${.CURDIR}/../../cddl/contrib/opensolaris/lib/libctf/common \
+ -I${.CURDIR}/../../sys/cddl/contrib/opensolaris/uts/common \
+ -I${.CURDIR}/../../sys/cddl/compat/opensolaris
+.else
+CFLAGS+= -DNO_CTF
+.endif
+
+SHLIB_MAJOR= 3
MAN=
diff --git a/lib/libproc/libproc.h b/lib/libproc/libproc.h
index be77e4b..5d81c2b 100644
--- a/lib/libproc/libproc.h
+++ b/lib/libproc/libproc.h
@@ -37,6 +37,7 @@
#include <rtld_db.h>
#include <limits.h>
+struct ctf_file;
struct proc_handle;
typedef void (*proc_child_func)(void *);
@@ -67,6 +68,11 @@ typedef struct prmap {
#define MA_NOCOREDUMP 0x20
} prmap_t;
+typedef struct prsyminfo {
+ u_int prs_lmid; /* Map id. */
+ u_int prs_id; /* Symbol id. */
+} prsyminfo_t;
+
typedef int proc_map_f(void *, const prmap_t *, const char *);
typedef int proc_sym_f(void *, const GElf_Sym *, const char *);
@@ -125,7 +131,9 @@ int proc_create(const char *, char * const *, proc_child_func *, void *,
struct proc_handle **);
int proc_detach(struct proc_handle *, int);
int proc_getflags(struct proc_handle *);
-int proc_name2sym(struct proc_handle *, const char *, const char *, GElf_Sym *);
+int proc_name2sym(struct proc_handle *, const char *, const char *,
+ GElf_Sym *, prsyminfo_t *);
+struct ctf_file *proc_name2ctf(struct proc_handle *, const char *);
int proc_setflags(struct proc_handle *, int);
int proc_state(struct proc_handle *);
pid_t proc_getpid(struct proc_handle *);
@@ -133,8 +141,7 @@ int proc_wstatus(struct proc_handle *);
int proc_getwstat(struct proc_handle *);
char * proc_signame(int, char *, size_t);
int proc_read(struct proc_handle *, void *, size_t, size_t);
-const lwpstatus_t *
- proc_getlwpstatus(struct proc_handle *);
+const lwpstatus_t *proc_getlwpstatus(struct proc_handle *);
void proc_free(struct proc_handle *);
rd_agent_t *proc_rdagent(struct proc_handle *);
void proc_updatesyms(struct proc_handle *);
diff --git a/lib/libproc/proc_sym.c b/lib/libproc/proc_sym.c
index f5301e6..d570215 100644
--- a/lib/libproc/proc_sym.c
+++ b/lib/libproc/proc_sym.c
@@ -32,6 +32,10 @@
__FBSDID("$FreeBSD$");
#include <sys/types.h>
+#ifndef NO_CTF
+#include <sys/ctf.h>
+#include <sys/ctf_api.h>
+#endif
#include <sys/user.h>
#include <assert.h>
@@ -42,10 +46,17 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#ifndef NO_CTF
+#include <libctf.h>
+#endif
#include <libutil.h>
#include "_libproc.h"
+#ifdef NO_CTF
+typedef struct ctf_file ctf_file_t;
+#endif
+
#ifndef NO_CXA_DEMANGLE
extern char *__cxa_demangle(const char *, char *, size_t *, int *);
#endif /* NO_CXA_DEMANGLE */
@@ -389,7 +400,7 @@ proc_name2map(struct proc_handle *p, const char *name)
*/
static int
lookup_name(Elf *e, Elf_Scn *scn, u_long stridx, const char *symbol,
- GElf_Sym *symcopy)
+ GElf_Sym *symcopy, prsyminfo_t *si)
{
GElf_Sym sym;
Elf_Data *data;
@@ -404,6 +415,8 @@ lookup_name(Elf *e, Elf_Scn *scn, u_long stridx, const char *symbol,
s = elf_strptr(e, stridx, sym.st_name);
if (s != NULL && strcmp(s, symbol) == 0) {
memcpy(symcopy, &sym, sizeof(*symcopy));
+ if (si != NULL)
+ si->prs_id = i;
return (0);
}
}
@@ -412,7 +425,7 @@ lookup_name(Elf *e, Elf_Scn *scn, u_long stridx, const char *symbol,
int
proc_name2sym(struct proc_handle *p, const char *object, const char *symbol,
- GElf_Sym *symcopy)
+ GElf_Sym *symcopy, prsyminfo_t *si)
{
Elf *e;
Elf_Scn *scn, *dynsymscn = NULL, *symtabscn = NULL;
@@ -462,11 +475,11 @@ proc_name2sym(struct proc_handle *p, const char *object, const char *symbol,
* First look up the symbol in the dynsymtab, and fall back to the
* symtab if the lookup fails.
*/
- error = lookup_name(e, dynsymscn, dynsymstridx, symbol, symcopy);
+ error = lookup_name(e, dynsymscn, dynsymstridx, symbol, symcopy, si);
if (error == 0)
goto out;
- error = lookup_name(e, symtabscn, symtabstridx, symbol, symcopy);
+ error = lookup_name(e, symtabscn, symtabstridx, symbol, symcopy, si);
if (error == 0)
goto out;
@@ -484,6 +497,26 @@ err0:
return (error);
}
+ctf_file_t *
+proc_name2ctf(struct proc_handle *p, const char *name)
+{
+#ifndef NO_CTF
+ prmap_t *map;
+ int error;
+
+ if ((map = proc_name2map(p, name)) == NULL) {
+ DPRINTFX("ERROR: couldn't find object %s", object);
+ return (NULL);
+ }
+
+ return (ctf_open(map->pr_mapname, &error));
+#else
+ (void)p;
+ (void)name;
+ return (NULL);
+#endif
+}
+
int
proc_iter_symbyaddr(struct proc_handle *p, const char *object, int which,
int mask, proc_sym_f *func, void *cd)
diff --git a/lib/libproc/tests/proc_test.c b/lib/libproc/tests/proc_test.c
index 60f1f04..0242b5b 100644
--- a/lib/libproc/tests/proc_test.c
+++ b/lib/libproc/tests/proc_test.c
@@ -227,6 +227,7 @@ ATF_TC_HEAD(map_alias_name2sym, tc)
ATF_TC_BODY(map_alias_name2sym, tc)
{
GElf_Sym sym1, sym2;
+ prsyminfo_t si1, si2;
struct proc_handle *phdl;
int error;
@@ -239,14 +240,15 @@ ATF_TC_BODY(map_alias_name2sym, tc)
* Make sure that "target_prog:main" and "a.out:main" return the same
* symbol.
*/
- error = proc_name2sym(phdl, target_prog_file, "main", &sym1);
+ error = proc_name2sym(phdl, target_prog_file, "main", &sym1, &si1);
ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up 'main' via %s",
target_prog_file);
- error = proc_name2sym(phdl, aout_object, "main", &sym2);
+ error = proc_name2sym(phdl, aout_object, "main", &sym2, &si2);
ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up 'main' via %s",
aout_object);
ATF_CHECK_EQ(memcmp(&sym1, &sym2, sizeof(sym1)), 0);
+ ATF_CHECK_EQ(si1.prs_id, si2.prs_id);
ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");
@@ -271,11 +273,11 @@ ATF_TC_BODY(symbol_lookup, tc)
phdl = start_prog(tc, false);
- error = proc_name2sym(phdl, target_prog_file, "main", &main_sym);
+ error = proc_name2sym(phdl, target_prog_file, "main", &main_sym, NULL);
ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up 'main'");
error = proc_name2sym(phdl, ldelf_object, "r_debug_state",
- &r_debug_state_sym);
+ &r_debug_state_sym, NULL);
ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up 'r_debug_state'");
set_bkpt(phdl, r_debug_state_sym.st_value, &saved);
OpenPOWER on IntegriCloud