Commit b09e43b4 authored by Teng Qin's avatar Teng Qin

Iterate through all load section when resolving name

parent a8f6db91
......@@ -505,42 +505,6 @@ exit:
return err;
}
static int loadaddr(Elf *e, uint64_t *addr) {
size_t phnum, i;
if (elf_getphdrnum(e, &phnum) != 0)
return -1;
for (i = 0; i < phnum; ++i) {
GElf_Phdr header;
if (!gelf_getphdr(e, (int)i, &header))
continue;
if (header.p_type != PT_LOAD)
continue;
*addr = (uint64_t)header.p_vaddr;
return 0;
}
return -1;
}
int bcc_elf_loadaddr(const char *path, uint64_t *address) {
Elf *e;
int fd, res;
if (openelf(path, &e, &fd) < 0)
return -1;
res = loadaddr(e, address);
elf_end(e);
close(fd);
return res;
}
int bcc_elf_get_type(const char *path) {
Elf *e;
GElf_Ehdr hdr;
......
......@@ -51,7 +51,6 @@ int bcc_elf_foreach_usdt(const char *path, bcc_elf_probecb callback,
int bcc_elf_foreach_load_section(const char *path,
bcc_elf_load_sectioncb callback,
void *payload);
int bcc_elf_loadaddr(const char *path, uint64_t *address);
// Iterate over symbol table of a binary module
// Parameter "option" points to a bcc_symbol_option struct to indicate wheather
// and how to use debuginfo file, and what types of symbols to load.
......
......@@ -416,11 +416,24 @@ static int _find_sym(const char *symname, uint64_t addr, uint64_t,
return 0;
}
struct load_addr_t {
uint64_t target_addr;
uint64_t binary_addr;
};
int _find_load(uint64_t v_addr, uint64_t mem_sz, uint64_t file_offset,
void *payload) {
struct load_addr_t *addr = static_cast<load_addr_t *>(payload);
if (addr->target_addr >= v_addr && addr->target_addr < (v_addr + mem_sz)) {
addr->binary_addr = addr->target_addr - v_addr + file_offset;
return -1;
}
return 0;
}
int bcc_resolve_symname(const char *module, const char *symname,
const uint64_t addr, int pid,
struct bcc_symbol_option *option,
struct bcc_symbol *sym) {
uint64_t load_addr;
static struct bcc_symbol_option default_option = {
.use_debug_file = 1,
.check_debug_file_crc = 1,
......@@ -437,29 +450,37 @@ int bcc_resolve_symname(const char *module, const char *symname,
} else {
sym->module = bcc_procutils_which_so(module, pid);
}
if (sym->module == NULL)
return -1;
ProcMountNSGuard g(pid);
if (bcc_elf_loadaddr(sym->module, &load_addr) < 0)
goto invalid_module;
sym->name = symname;
sym->offset = addr;
if (option == NULL)
option = &default_option;
if (sym->name && sym->offset == 0x0)
if (bcc_elf_foreach_sym(sym->module, _find_sym, option, sym) < 0)
goto invalid_module;
if (sym->offset == 0x0)
goto invalid_module;
sym->offset = (sym->offset - load_addr);
// For executable (ET_EXEC) binaries, translate the virtual address
// to physical address in the binary file.
// For shared object binaries (ET_DYN), the address from symbol table should
// already be physical address in the binary file.
if (bcc_elf_get_type(sym->module) == ET_EXEC) {
struct load_addr_t addr = {
.target_addr = sym->offset,
.binary_addr = 0x0,
};
if (bcc_elf_foreach_load_section(sym->module, &_find_load, &addr) < 0)
goto invalid_module;
if (!addr.binary_addr)
goto invalid_module;
sym->offset = addr.binary_addr;
}
return 0;
invalid_module:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment