libbpf-tools: fix uprobe helper get_elf_func_offset
get_elf_func_offset didn't work properly when use with
statically linked binary. It seems like not subtract the
base load address cause the problem. This commits fixes
that like BCC does. see [0] and [1].
[0]:
[1]:
@@ -228,13 +228,18 @@ off_t get_elf_func_offset(const char *path, const char *func)
Elf *e;
Elf_Scn *scn;
Elf_Data *data;
+ GElf_Ehdr ehdr;
GElf_Shdr shdr[1];
+ GElf_Phdr phdr;
GElf_Sym sym[1];
- size_t shstrndx;
+ size_t shstrndx, nhdrs;
char *n;
e = open_elf(path, &fd);
+ if (!gelf_getehdr(e, &ehdr))
+ goto out;
+
if (elf_getshdrstrndx(e, &shstrndx) != 0)
goto out;
@@ -254,12 +259,30 @@ off_t get_elf_func_offset(const char *path, const char *func)
continue;
if (!strcmp(n, func)) {
ret = sym->st_value;
- goto out;
+ goto check;
}
}
}
}
+check:
+ if (ehdr.e_type == ET_EXEC || ehdr.e_type == ET_DYN) {
+ if (elf_getphdrnum(e, &nhdrs) != 0) {
+ ret = -1;
+ goto out;
+ }
+ for (i = 0; i < (int)nhdrs; i++) {
+ if (!gelf_getphdr(e, i, &phdr))
+ continue;
+ if (phdr.p_type != PT_LOAD || !(phdr.p_flags & PF_X))
+ continue;
+ if (phdr.p_vaddr <= ret && ret < (phdr.p_vaddr + phdr.p_memsz)) {
+ ret = ret - phdr.p_vaddr + phdr.p_offset;
+ goto out;
+ }
+ }
+ ret = -1;
+ }
out:
close_elf(e, fd);
return ret;
