Open honggyukim opened 4 years ago
The -fno-plt
compiled binary shows the same problem even if it's executed in a different machine such as Ubuntu 18.04.
Here are the binaries.
-fno-plt
compiled binary: t-abc-no-plt.txtThe problem can be easily reproduced with t-abc-no-plt
.
I think one problem is that we assume there's only one RELA section in no-plt binary which is not the case in this binary. Although the binary is built with -fno-plt there is a .PLT in it. This leads us to the second problem, that is, we assume that -fno-plt is used if we do not find .PLT in the binary. Which is not true, in this binary at least. Here is a quick and dirty (very very dirty) patch that gives insight about the problem.
diff --git a/arch/x86_64/symbol.c b/arch/x86_64/symbol.c
index fed7de95..60dd961b 100644
--- a/arch/x86_64/symbol.c
+++ b/arch/x86_64/symbol.c
@@ -27,15 +27,17 @@ int arch_load_dynsymtab_noplt(struct symtab *dsymtab,
unsigned grow = SYMTAB_GROW;
unsigned long reloc_start = 0;
size_t reloc_entsize = 0;
+ char *sec_name;
memset(dsymtab, 0, sizeof(*dsymtab));
/* assumes there's only one RELA section (rela.dyn) for no-plt binary */
elf_for_each_shdr(elf, &sec_iter) {
- if (sec_iter.shdr.sh_type == SHT_RELA) {
+ sec_name = elf_get_name(elf, &sec_iter, sec_iter.shdr.sh_name);
+ if (sec_iter.shdr.sh_type == SHT_RELA && !strcmp(sec_name, ".rela.dyn")) {
memcpy(&rel_iter, &sec_iter, sizeof(sec_iter));
pr_dbg2("found RELA section: %s\n",
- elf_get_name(elf, &sec_iter, sec_iter.shdr.sh_name));
+ sec_name);
reloc_start = rel_iter.shdr.sh_addr + offset;
reloc_entsize = rel_iter.shdr.sh_entsize;
diff --git a/libmcount/plthook.c b/libmcount/plthook.c
index 2ce62cce..7f43b625 100644
--- a/libmcount/plthook.c
+++ b/libmcount/plthook.c
@@ -199,7 +199,7 @@ static int find_got(struct uftrace_elf_data *elf,
}
}
- if (!plt_found) {
+ if (1) {
pd = mcount_arch_hook_no_plt(elf, modname, offset);
if (pd == NULL)
pr_dbg2("no PLTGOT found.. ignoring...\n");
diff --git a/utils/symbol.c b/utils/symbol.c
index 1cfacdb0..d14931ae 100644
--- a/utils/symbol.c
+++ b/utils/symbol.c
@@ -549,7 +549,7 @@ int load_elf_dynsymtab(struct symtab *dsymtab, struct uftrace_elf_data *elf,
goto out;
}
- if (rel_type == SHT_NULL) {
+ if (1) {
arch_load_dynsymtab_noplt(dsymtab, elf, offset, flags);
goto out_sort;
}
In Ubuntu 19.04, I compiled a simple binary as follows:
Their tracing result is different and uftrace cannot trace library calls for
-fno-plt
compiled binary.It makes
t212_noplt_libcall
failed.Here is GCC compiler info.