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.

Reviewed by:	rpaulo
MFC after:	2 weeks
This commit is contained in:
Mark Johnston 2013-11-11 16:57:57 +00:00
parent 9d9df6f478
commit fbce8e1683

View File

@ -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 @@ proc_addr2sym(struct proc_handle *p, uintptr_t addr, char *name,
* 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;