diff options
author | markj <markj@FreeBSD.org> | 2014-10-03 23:20:37 +0000 |
---|---|---|
committer | markj <markj@FreeBSD.org> | 2014-10-03 23:20:37 +0000 |
commit | 91d5d12d67db05be29b36096bcb90e39e1541fae (patch) | |
tree | e5d14bcbe841b9c2e8e073a1970aa1c856236b02 /lib/libproc/proc_sym.c | |
parent | b089d064397fe71608574f13f2e413d9e5c2786a (diff) | |
download | FreeBSD-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/proc_sym.c')
-rw-r--r-- | lib/libproc/proc_sym.c | 41 |
1 files changed, 37 insertions, 4 deletions
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) |