diff options
author | rpaulo <rpaulo@FreeBSD.org> | 2010-08-21 11:50:53 +0000 |
---|---|---|
committer | rpaulo <rpaulo@FreeBSD.org> | 2010-08-21 11:50:53 +0000 |
commit | b325e69c9282072ea3b203319017abc400db4771 (patch) | |
tree | ae5b6066f0143ecb034e8de394e160841cd4f84f /cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c | |
parent | 232561a60dcdeeffd316d29086bb31f2e12d7591 (diff) | |
download | FreeBSD-src-b325e69c9282072ea3b203319017abc400db4771.zip FreeBSD-src-b325e69c9282072ea3b203319017abc400db4771.tar.gz |
Add libdtrace support for tracing userland programs.
Summary of changes:
* Implement a compatibility shim between Solaris libproc and our
libproc and remove several ifdefs because of this.
* Port the drti to FreeBSD.
* Implement the missing DOODAD sections
* Link with libproc and librtld_db
* Support for ustack, jstack and uregs (by sson@)
* Misc bugfixing
When writing the SUWN_dof section, we had to resort to building the ELF
file layout by "hand". This is the job of libelf, but our libelf doesn't
support this yet. When libelf is fixed, we can remove the code under
#ifdef BROKEN_LIBELF.
Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c')
-rw-r--r-- | cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c | 83 |
1 files changed, 21 insertions, 62 deletions
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c index a754d9c..52b0eb9 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c @@ -40,6 +40,9 @@ #include <dt_program.h> #include <dt_pid.h> #include <dt_string.h> +#if !defined(sun) +#include <libproc_compat.h> +#endif typedef struct dt_pid_probe { dtrace_hdl_t *dpp_dtp; @@ -142,7 +145,6 @@ dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func) pp->dpp_obj); if (!isdash && gmatch("return", pp->dpp_name)) { -#ifdef DOODAD if (dt_pid_create_return_probe(pp->dpp_pr, dtp, ftp, symp, pp->dpp_stret) < 0) { return (dt_pid_error(dtp, pcb, dpr, ftp, @@ -150,20 +152,17 @@ dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func) "for '%s': %s", func, dtrace_errmsg(dtp, dtrace_errno(dtp)))); } -#endif nmatches++; } if (!isdash && gmatch("entry", pp->dpp_name)) { -#ifdef DOODAD if (dt_pid_create_entry_probe(pp->dpp_pr, dtp, ftp, symp) < 0) { return (dt_pid_error(dtp, pcb, dpr, ftp, D_PROC_CREATEFAIL, "failed to create entry probe " "for '%s': %s", func, dtrace_errmsg(dtp, dtrace_errno(dtp)))); } -#endif nmatches++; } @@ -182,10 +181,8 @@ dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func) (u_longlong_t)off, func)); } -#ifdef DOODAD err = dt_pid_create_offset_probe(pp->dpp_pr, pp->dpp_dtp, ftp, symp, off); -#endif if (err == DT_PROC_ERR) { return (dt_pid_error(dtp, pcb, dpr, ftp, @@ -203,7 +200,6 @@ dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func) nmatches++; } else if (glob && !isdash) { -#ifdef DOODAD if (dt_pid_create_glob_offset_probes(pp->dpp_pr, pp->dpp_dtp, ftp, symp, pp->dpp_name) < 0) { return (dt_pid_error(dtp, pcb, dpr, ftp, @@ -211,7 +207,6 @@ dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func) "failed to create offset probes in '%s': %s", func, dtrace_errmsg(dtp, dtrace_errno(dtp)))); } -#endif nmatches++; } @@ -279,7 +274,6 @@ dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj) pp->dpp_obj = obj; else pp->dpp_obj++; - #if defined(sun) if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret1", &sym, NULL) == 0) @@ -305,25 +299,10 @@ dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj) else pp->dpp_stret[3] = 0; #else - if (proc_name2sym(pp->dpp_pr, obj, ".stret1", &sym) == 0) - pp->dpp_stret[0] = sym.st_value; - else - pp->dpp_stret[0] = 0; - - if (proc_name2sym(pp->dpp_pr, obj, ".stret2", &sym) == 0) - pp->dpp_stret[1] = sym.st_value; - else - pp->dpp_stret[1] = 0; - - if (proc_name2sym(pp->dpp_pr, obj, ".stret4", &sym) == 0) - pp->dpp_stret[2] = sym.st_value; - else - pp->dpp_stret[2] = 0; - - if (proc_name2sym(pp->dpp_pr, obj, ".stret8", &sym) == 0) - pp->dpp_stret[3] = sym.st_value; - else - pp->dpp_stret[3] = 0; + pp->dpp_stret[0] = 0; + pp->dpp_stret[1] = 0; + pp->dpp_stret[2] = 0; + pp->dpp_stret[3] = 0; #endif dt_dprintf("%s stret %llx %llx %llx %llx\n", obj, @@ -345,12 +324,8 @@ dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj) * just fail silently in the hopes that some other object will * contain the desired symbol. */ -#if defined(sun) if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, pp->dpp_func, &sym, NULL) != 0) { -#else - if (proc_name2sym(pp->dpp_pr, obj, pp->dpp_func, &sym) != 0) { -#endif if (strcmp("-", pp->dpp_func) == 0) { sym.st_name = 0; sym.st_info = @@ -390,16 +365,11 @@ dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj) return (0); #endif -#if defined(sun) (void) Plookup_by_addr(pp->dpp_pr, sym.st_value, pp->dpp_func, -#else - (void) proc_addr2sym(pp->dpp_pr, sym.st_value, pp->dpp_func, -#endif DTRACE_FUNCNAMELEN, &sym); return (dt_pid_per_sym(pp, &sym, pp->dpp_func)); } else { -#ifdef DOODAD uint_t nmatches = pp->dpp_nmatches; if (Psymbol_iter_by_addr(pp->dpp_pr, obj, PR_SYMTAB, @@ -415,7 +385,6 @@ dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj) BIND_ANY | TYPE_FUNC, dt_pid_sym_filt, pp) == 1) return (1); } -#endif } return (0); @@ -459,14 +428,16 @@ dt_pid_mod_filt(void *arg, const prmap_t *pmp, const char *obj) static const prmap_t * dt_pid_fix_mod(dtrace_probedesc_t *pdp, struct ps_prochandle *P) { -#ifdef DOODAD char m[MAXPATHLEN]; +#if defined(sun) Lmid_t lmid = PR_LMID_EVERY; - const char *obj; +#else + Lmid_t lmid = 0; #endif + const char *obj; const prmap_t *pmp; -#ifdef DOODAD +#if defined(sun) /* * Pick apart the link map from the library name. */ @@ -487,10 +458,14 @@ dt_pid_fix_mod(dtrace_probedesc_t *pdp, struct ps_prochandle *P) } else { obj = pdp->dtpd_mod; } +#else + obj = pdp->dtpd_mod; +#endif if ((pmp = Plmid_to_map(P, lmid, obj)) == NULL) return (NULL); +#if defined(sun) (void) Pobjname(P, pmp->pr_vaddr, m, sizeof (m)); if ((obj = strrchr(m, '/')) == NULL) obj = &m[0]; @@ -498,11 +473,9 @@ dt_pid_fix_mod(dtrace_probedesc_t *pdp, struct ps_prochandle *P) obj++; (void) Plmid(P, pmp->pr_vaddr, &lmid); +#endif dt_pid_objname(pdp->dtpd_mod, sizeof (pdp->dtpd_mod), lmid, obj); -#else -pmp = NULL; -#endif return (pmp); } @@ -544,13 +517,8 @@ dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, pp.dpp_mod = pdp->dtpd_mod; (void) strcpy(pdp->dtpd_mod, "a.out"); } else if (strisglob(pp.dpp_mod) || -#if defined(sun) (aout = Pname_to_map(pp.dpp_pr, "a.out")) == NULL || (pmp = Pname_to_map(pp.dpp_pr, pp.dpp_mod)) == NULL || -#else - (aout = proc_name2map(pp.dpp_pr, "a.out")) == NULL || - (pmp = proc_name2map(pp.dpp_pr, pp.dpp_mod)) == NULL || -#endif aout->pr_vaddr != pmp->pr_vaddr) { return (dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_LIB, "only the a.out module is valid with the " @@ -569,7 +537,6 @@ dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, * to iterate over each module and compare its name against the * pattern. An empty module name is treated as '*'. */ -#ifdef DOODAD if (strisglob(pp.dpp_mod)) { ret = Pobject_iter(pp.dpp_pr, dt_pid_mod_filt, &pp); } else { @@ -590,7 +557,6 @@ dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, ret = dt_pid_per_mod(&pp, pmp, obj); } } -#endif return (ret); } @@ -616,12 +582,8 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname) * run the code to instantiate these providers. */ for (i = 0; i < 2; i++) { -#if defined(sun) if (Pxlookup_by_name(P, PR_LMID_EVERY, oname, syms[i], &sym, &sip) != 0) { -#else - if (proc_name2sym(P, oname, syms[i], &sym) != 0) { -#endif continue; } @@ -632,13 +594,11 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname) dt_dprintf("lookup of %s succeeded for %s\n", syms[i], mname); -#ifdef DOODAD if (Pread(P, &e_type, sizeof (e_type), pmp->pr_vaddr + offsetof(Elf64_Ehdr, e_type)) != sizeof (e_type)) { dt_dprintf("read of ELF header failed"); continue; } -#endif dh.dofhp_dof = sym.st_value; dh.dofhp_addr = (e_type == ET_EXEC) ? 0 : pmp->pr_vaddr; @@ -650,7 +610,7 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname) 0, mname); #endif -#ifdef DOODAD +#if defined(sun) if (fd == -1 && (fd = pr_open(P, "/dev/dtrace/helper", O_RDWR, 0)) < 0) { dt_dprintf("pr_open of helper device failed: %s\n", @@ -663,7 +623,7 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname) #endif } -#ifdef DOODAD +#if defined(sun) if (fd != -1) (void) pr_close(P, fd); #endif @@ -679,9 +639,9 @@ dt_pid_create_usdt_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, int ret = 0; assert(DT_MUTEX_HELD(&dpr->dpr_lock)); - -#ifdef DOODAD +#if defined(sun) (void) Pupdate_maps(P); +#endif if (Pobject_iter(P, dt_pid_usdt_mapping, P) != 0) { ret = -1; (void) dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_USDT, @@ -692,7 +652,6 @@ dt_pid_create_usdt_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, (int)proc_getpid(P), strerror(errno)); #endif } -#endif /* * Put the module name in its canonical form. |