summaryrefslogtreecommitdiffstats
path: root/lib/libproc
diff options
context:
space:
mode:
authormarkj <markj@FreeBSD.org>2013-12-27 23:00:56 +0000
committermarkj <markj@FreeBSD.org>2013-12-27 23:00:56 +0000
commit62fbf016fd74108bb236e85eb514ed800dfe2cb7 (patch)
tree8db68335d74c6d26ad811e1eb77e8a3e14bdf058 /lib/libproc
parentc911703d6097a13f755df22aa6d83f1f3fe3b386 (diff)
downloadFreeBSD-src-62fbf016fd74108bb236e85eb514ed800dfe2cb7.zip
FreeBSD-src-62fbf016fd74108bb236e85eb514ed800dfe2cb7.tar.gz
MFC r258000:
Consistently add the relocation offset only when the ELF type is not ET_EXEC. This fixes several problems with the DTrace pid provider not being able to match probes.
Diffstat (limited to 'lib/libproc')
-rw-r--r--lib/libproc/proc_sym.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/lib/libproc/proc_sym.c b/lib/libproc/proc_sym.c
index 87ac471..f848040 100644
--- a/lib/libproc/proc_sym.c
+++ b/lib/libproc/proc_sym.c
@@ -284,7 +284,10 @@ 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 (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) {
@@ -309,8 +312,6 @@ 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) {
DPRINTFX("ERROR: elf_getdata() failed: %s", elf_errmsg(-1));
goto err2;
@@ -465,7 +466,8 @@ proc_name2sym(struct proc_handle *p, const char *object, const char *symbol,
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;
}
@@ -475,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:
@@ -509,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;
@@ -525,6 +529,10 @@ proc_iter_symbyaddr(struct proc_handle *p, const char *object, int which,
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.
*/
@@ -575,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