summaryrefslogtreecommitdiffstats
path: root/lib/libproc/proc_sym.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libproc/proc_sym.c')
-rw-r--r--lib/libproc/proc_sym.c58
1 files changed, 33 insertions, 25 deletions
diff --git a/lib/libproc/proc_sym.c b/lib/libproc/proc_sym.c
index 2dd21fe..2338895 100644
--- a/lib/libproc/proc_sym.c
+++ b/lib/libproc/proc_sym.c
@@ -96,7 +96,7 @@ proc_objname(struct proc_handle *p, uintptr_t addr, char *objname,
for (i = 0; i < p->nobjs; i++) {
rdl = &p->rdobjs[i];
- if (addr >= rdl->rdl_saddr && addr <= rdl->rdl_eaddr) {
+ if (addr >= rdl->rdl_saddr && addr < rdl->rdl_eaddr) {
strlcpy(objname, rdl->rdl_path, objnamesz);
return (objname);
}
@@ -176,7 +176,7 @@ proc_addr2map(struct proc_handle *p, uintptr_t addr)
kve = kves + i;
if (kve->kve_type == KVME_TYPE_VNODE)
lastvn = i;
- if (addr >= kve->kve_start && addr <= kve->kve_end) {
+ if (addr >= kve->kve_start && addr < kve->kve_end) {
if ((map = malloc(sizeof(*map))) == NULL) {
free(kves);
return (NULL);
@@ -209,7 +209,7 @@ proc_addr2map(struct proc_handle *p, uintptr_t addr)
for (i = 0; i < p->nobjs; i++) {
rdl = &p->rdobjs[i];
- if (addr >= rdl->rdl_saddr && addr <= rdl->rdl_eaddr) {
+ if (addr >= rdl->rdl_saddr && addr < rdl->rdl_eaddr) {
if ((map = malloc(sizeof(*map))) == NULL)
return (NULL);
proc_rdl2prmap(rdl, map);
@@ -238,16 +238,16 @@ proc_addr2sym(struct proc_handle *p, uintptr_t addr, char *name,
if ((map = proc_addr2map(p, addr)) == NULL)
return (-1);
- if (!map->pr_mapname || (fd = open(map->pr_mapname, O_RDONLY, 0)) < 0) {
- warn("ERROR: open %s failed", map->pr_mapname);
+ if ((fd = open(map->pr_mapname, O_RDONLY, 0)) < 0) {
+ DPRINTF("ERROR: open %s failed", map->pr_mapname);
goto err0;
}
if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
- warn("ERROR: elf_begin() failed");
+ DPRINTFX("ERROR: elf_begin() failed: %s", elf_errmsg(-1));
goto err1;
}
if (gelf_getehdr(e, &ehdr) == NULL) {
- warn("ERROR: gelf_getehdr() failed");
+ DPRINTFX("ERROR: gelf_getehdr() failed: %s", elf_errmsg(-1));
goto err2;
}
/*
@@ -275,7 +275,7 @@ proc_addr2sym(struct proc_handle *p, uintptr_t addr, char *name,
* Then look up the string name in STRTAB (.dynstr)
*/
if ((data = elf_getdata(dynsymscn, NULL)) == NULL) {
- DPRINTF("ERROR: elf_getdata() failed");
+ DPRINTFX("ERROR: elf_getdata() failed: %s", elf_errmsg(-1));
goto symtab;
}
i = 0;
@@ -284,8 +284,11 @@ proc_addr2sym(struct proc_handle *p, uintptr_t addr, char *name,
* Calculate the address mapped to the virtual memory
* by rtld.
*/
- rsym = map->pr_vaddr + sym.st_value;
- if (addr >= rsym && addr <= (rsym + sym.st_size)) {
+ if (ehdr.e_type != ET_EXEC)
+ rsym = map->pr_vaddr + sym.st_value;
+ else
+ rsym = sym.st_value;
+ if (addr >= rsym && addr < rsym + sym.st_size) {
s = elf_strptr(e, dynsymstridx, sym.st_name);
if (s) {
if (s[0] == '_' && s[1] == 'Z' && s[2])
@@ -309,10 +312,8 @@ symtab:
* Iterate over the Symbols Table to find the symbol.
* Then look up the string name in STRTAB (.dynstr)
*/
- if (symtabscn == NULL)
- goto err2;
if ((data = elf_getdata(symtabscn, NULL)) == NULL) {
- DPRINTF("ERROR: elf_getdata() failed");
+ DPRINTFX("ERROR: elf_getdata() failed: %s", elf_errmsg(-1));
goto err2;
}
i = 0;
@@ -325,7 +326,7 @@ symtab:
rsym = map->pr_vaddr + sym.st_value;
else
rsym = sym.st_value;
- if (addr >= rsym && addr <= (rsym + sym.st_size)) {
+ if (addr >= rsym && addr < rsym + sym.st_size) {
s = elf_strptr(e, symtabstridx, sym.st_name);
if (s) {
if (s[0] == '_' && s[1] == 'Z' && s[2])
@@ -420,7 +421,7 @@ proc_name2sym(struct proc_handle *p, const char *object, const char *symbol,
unsigned long symtabstridx = 0, dynsymstridx = 0;
if ((map = proc_name2map(p, object)) == NULL) {
- DPRINTF("ERROR: couldn't find object %s", object);
+ DPRINTFX("ERROR: couldn't find object %s", object);
goto err0;
}
if ((fd = open(map->pr_mapname, O_RDONLY, 0)) < 0) {
@@ -428,11 +429,11 @@ proc_name2sym(struct proc_handle *p, const char *object, const char *symbol,
goto err0;
}
if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
- warn("ERROR: elf_begin() failed");
+ DPRINTFX("ERROR: elf_begin() failed: %s", elf_errmsg(-1));
goto err1;
}
if (gelf_getehdr(e, &ehdr) == NULL) {
- warn("ERROR: gelf_getehdr() failed");
+ DPRINTFX("ERROR: gelf_getehdr() failed: %s", elf_errmsg(-1));
goto err2;
}
/*
@@ -460,13 +461,13 @@ proc_name2sym(struct proc_handle *p, const char *object, const char *symbol,
* Then look up the string name in STRTAB (.dynstr)
*/
if ((data = elf_getdata(dynsymscn, NULL))) {
- DPRINTF("ERROR: elf_getdata() failed");
i = 0;
while (gelf_getsym(data, i++, &sym) != NULL) {
s = elf_strptr(e, dynsymstridx, sym.st_name);
if (s && strcmp(s, symbol) == 0) {
memcpy(symcopy, &sym, sizeof(sym));
- symcopy->st_value = map->pr_vaddr + sym.st_value;
+ if (ehdr.e_type != ET_EXEC)
+ symcopy->st_value += map->pr_vaddr;
error = 0;
goto out;
}
@@ -476,20 +477,21 @@ proc_name2sym(struct proc_handle *p, const char *object, const char *symbol,
* Iterate over the Symbols Table to find the symbol.
* Then look up the string name in STRTAB (.dynstr)
*/
- if (symtabscn == NULL)
- goto err2;
if ((data = elf_getdata(symtabscn, NULL))) {
i = 0;
while (gelf_getsym(data, i++, &sym) != NULL) {
s = elf_strptr(e, symtabstridx, sym.st_name);
if (s && strcmp(s, symbol) == 0) {
memcpy(symcopy, &sym, sizeof(sym));
+ if (ehdr.e_type != ET_EXEC)
+ symcopy->st_value += map->pr_vaddr;
error = 0;
goto out;
}
}
}
out:
+ DPRINTFX("found addr 0x%lx for %s", symcopy->st_value, symbol);
err2:
elf_end(e);
err1:
@@ -510,6 +512,7 @@ proc_iter_symbyaddr(struct proc_handle *p, const char *object, int which,
prmap_t *map;
Elf_Scn *scn, *foundscn = NULL;
Elf_Data *data;
+ GElf_Ehdr ehdr;
GElf_Shdr shdr;
GElf_Sym sym;
unsigned long stridx = -1;
@@ -519,13 +522,17 @@ 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) {
- warn("ERROR: open %s failed", map->pr_mapname);
+ DPRINTF("ERROR: open %s failed", map->pr_mapname);
goto err0;
}
if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
- warn("ERROR: elf_begin() failed");
+ DPRINTFX("ERROR: elf_begin() failed: %s", elf_errmsg(-1));
goto err1;
}
+ if (gelf_getehdr(e, &ehdr) == NULL) {
+ DPRINTFX("ERROR: gelf_getehdr() failed: %s", elf_errmsg(-1));
+ goto err2;
+ }
/*
* Find the section we are looking for.
*/
@@ -546,7 +553,7 @@ proc_iter_symbyaddr(struct proc_handle *p, const char *object, int which,
return (-1);
stridx = shdr.sh_link;
if ((data = elf_getdata(foundscn, NULL)) == NULL) {
- DPRINTF("ERROR: elf_getdata() failed");
+ DPRINTFX("ERROR: elf_getdata() failed: %s", elf_errmsg(-1));
goto err2;
}
i = 0;
@@ -576,7 +583,8 @@ proc_iter_symbyaddr(struct proc_handle *p, const char *object, int which,
(mask & TYPE_FILE) == 0)
continue;
s = elf_strptr(e, stridx, sym.st_name);
- sym.st_value += map->pr_vaddr;
+ if (ehdr.e_type != ET_EXEC)
+ sym.st_value += map->pr_vaddr;
(*func)(cd, &sym, s);
}
error = 0;
OpenPOWER on IntegriCloud