From ad83318d09cb9729d8c0792e5e33f25102df7014 Mon Sep 17 00:00:00 2001 From: Hengqi Chen Date: Thu, 1 Jul 2021 21:16:15 +0800 Subject: [PATCH] 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]: https://github.com/iovisor/bcc/blob/v0.20.0/src/cc/bcc_syms.cc#L751-L764 [1]: https://github.com/iovisor/bcc/blob/v0.20.0/src/cc/bcc_elf.c#L723-L756 Signed-off-by: Hengqi Chen --- libbpf-tools/uprobe_helpers.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/libbpf-tools/uprobe_helpers.c b/libbpf-tools/uprobe_helpers.c index 9f6e3b54..953cea1a 100644 --- a/libbpf-tools/uprobe_helpers.c +++ b/libbpf-tools/uprobe_helpers.c @@ -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; -- 2.34.1