diff options
Diffstat (limited to 'lib/libproc/proc_sym.c')
-rw-r--r-- | lib/libproc/proc_sym.c | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/lib/libproc/proc_sym.c b/lib/libproc/proc_sym.c index 766ff73..dd52638 100644 --- a/lib/libproc/proc_sym.c +++ b/lib/libproc/proc_sym.c @@ -82,6 +82,21 @@ fail: strlcpy(buf, symbol, len); } +static int +find_dbg_obj(const char *path) +{ + int fd; + char dbg_path[PATH_MAX]; + + snprintf(dbg_path, sizeof(dbg_path), + "/usr/lib/debug/%s.debug", path); + fd = open(dbg_path, O_RDONLY); + if (fd >= 0) + return (fd); + else + return (open(path, O_RDONLY)); +} + static void proc_rdl2prmap(rd_loadobj_t *rdl, prmap_t *map) { @@ -153,9 +168,12 @@ proc_iter_objs(struct proc_handle *p, proc_map_f *func, void *cd) prmap_t map; char path[MAXPATHLEN]; char last[MAXPATHLEN]; + int error; if (p->nobjs == 0) return (-1); + + error = 0; memset(last, 0, sizeof(last)); for (i = 0; i < p->nobjs; i++) { rdl = &p->rdobjs[i]; @@ -169,11 +187,11 @@ proc_iter_objs(struct proc_handle *p, proc_map_f *func, void *cd) */ if (strcmp(path, last) == 0) continue; - (*func)(cd, &map, path); + if ((error = (*func)(cd, &map, path)) != 0) + break; strlcpy(last, path, sizeof(last)); } - - return (0); + return (error); } prmap_t * @@ -292,7 +310,7 @@ proc_addr2sym(struct proc_handle *p, uintptr_t addr, char *name, if ((map = proc_addr2map(p, addr)) == NULL) return (-1); - if ((fd = open(map->pr_mapname, O_RDONLY, 0)) < 0) { + if ((fd = find_dbg_obj(map->pr_mapname)) < 0) { DPRINTF("ERROR: open %s failed", map->pr_mapname); goto err0; } @@ -335,8 +353,8 @@ proc_addr2sym(struct proc_handle *p, uintptr_t addr, char *name, goto out; error = lookup_addr(e, symtabscn, symtabstridx, off, addr, &s, symcopy); - if (error == 0) - goto out; + if (error != 0) + goto err2; out: demangle(s, name, namesz); @@ -440,7 +458,7 @@ proc_name2sym(struct proc_handle *p, const char *object, const char *symbol, DPRINTFX("ERROR: couldn't find object %s", object); goto err0; } - if ((fd = open(map->pr_mapname, O_RDONLY, 0)) < 0) { + if ((fd = find_dbg_obj(map->pr_mapname)) < 0) { DPRINTF("ERROR: open %s failed", map->pr_mapname); goto err0; } @@ -501,13 +519,16 @@ ctf_file_t * proc_name2ctf(struct proc_handle *p, const char *name) { #ifndef NO_CTF + ctf_file_t *ctf; prmap_t *map; int error; if ((map = proc_name2map(p, name)) == NULL) return (NULL); - return (ctf_open(map->pr_mapname, &error)); + ctf = ctf_open(map->pr_mapname, &error); + free(map); + return (ctf); #else (void)p; (void)name; @@ -533,7 +554,7 @@ proc_iter_symbyaddr(struct proc_handle *p, const char *object, int which, if ((map = proc_name2map(p, object)) == NULL) return (-1); - if ((fd = open(map->pr_mapname, O_RDONLY)) < 0) { + if ((fd = find_dbg_obj(map->pr_mapname)) < 0) { DPRINTF("ERROR: open %s failed", map->pr_mapname); goto err0; } @@ -596,7 +617,8 @@ proc_iter_symbyaddr(struct proc_handle *p, const char *object, int which, s = elf_strptr(e, stridx, sym.st_name); if (ehdr.e_type != ET_EXEC) sym.st_value += map->pr_vaddr; - (*func)(cd, &sym, s); + if ((error = (*func)(cd, &sym, s)) != 0) + goto err2; } error = 0; err2: |