Skip to content

Commit

Permalink
symbol:Fix load_dynsymtab to support no-plt
Browse files Browse the repository at this point in the history
`load_dynsymtab` only loaded the dynamic symbols from `dynsym` and
PLTs(`.rel(a).plt` and `.plt`). this commit fixes it to call the
`arch_load_dynsymtab_noplt` in the `load_dynsymtab`, so it also loads the
dynamic symbols from the `rel(a).dyn`, which normally saves the symbols
in case of no-plt option.

Signed-off-by: ChoKyuWon <[email protected]>
  • Loading branch information
ChoKyuWon committed Sep 16, 2023
1 parent 3e2cd6b commit 028f43b
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 25 deletions.
20 changes: 15 additions & 5 deletions arch/x86_64/symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,11 @@ int arch_load_dynsymtab_noplt(struct uftrace_symtab *dsymtab, struct uftrace_elf

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) {
if (strcmp(elf_get_name(elf, &sec_iter, sec_iter.shdr.sh_name), ".rela.dyn") == 0) {
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));
pr_dbg2("found rela.dyn section with %ld entry.\n",
sec_iter.shdr.sh_entsize);

reloc_start = rel_iter.shdr.sh_addr + offset;
reloc_entsize = rel_iter.shdr.sh_entsize;
Expand All @@ -53,6 +52,8 @@ int arch_load_dynsymtab_noplt(struct uftrace_symtab *dsymtab, struct uftrace_elf
struct uftrace_symbol *sym;
int symidx;
char *name;
size_t k;
bool found = false;

symidx = elf_rel_symbol(&rel_iter.rela);
if (symidx == 0)
Expand All @@ -76,6 +77,15 @@ int arch_load_dynsymtab_noplt(struct uftrace_symtab *dsymtab, struct uftrace_elf
dsymtab->nr_alloc += grow;
dsymtab->sym = xrealloc(dsymtab->sym, dsymtab->nr_alloc * sizeof(*sym));
}
name = elf_get_name(elf, &sym_iter, sym_iter.sym.st_name);
for (k = 0; k <= noplt_skip_nr; k++) {
if (strcmp(name, noplt_skip_syms[k]) == 0) {
found = true;
break;
}
}
if (found)
continue;

sym = &dsymtab->sym[dsymtab->nr_sym++];

Expand All @@ -84,7 +94,6 @@ int arch_load_dynsymtab_noplt(struct uftrace_symtab *dsymtab, struct uftrace_elf
sym->size = reloc_entsize;
sym->type = ST_PLT_FUNC;

name = elf_get_name(elf, &sym_iter, sym_iter.sym.st_name);
if (flags & SYMTAB_FL_DEMANGLE)
sym->name = demangle(name);
else
Expand All @@ -93,6 +102,7 @@ int arch_load_dynsymtab_noplt(struct uftrace_symtab *dsymtab, struct uftrace_elf
pr_dbg3("[%zd] %c %lx + %-5u %s\n", dsymtab->nr_sym, sym->type, sym->addr,
sym->size, sym->name);
}
sort_dynsymtab(dsymtab);

return dsymtab->nr_sym;
}
Expand Down
43 changes: 23 additions & 20 deletions utils/symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,10 +472,11 @@ static int load_dyn_symbol(struct uftrace_symtab *dsymtab, int sym_idx, unsigned
return 1;
}

static void sort_dynsymtab(struct uftrace_symtab *dsymtab)
void sort_dynsymtab(struct uftrace_symtab *dsymtab)
{
unsigned i, k;

if (dsymtab->nr_sym == 0)
return;
dsymtab->nr_alloc = dsymtab->nr_sym;
dsymtab->sym = xrealloc(dsymtab->sym, dsymtab->nr_sym * sizeof(*dsymtab->sym));

Expand Down Expand Up @@ -643,24 +644,6 @@ int load_elf_dynsymtab(struct uftrace_symtab *dsymtab, struct uftrace_elf_data *
return ret;
}

static int load_dynsymtab(struct uftrace_symtab *dsymtab, const char *filename,
unsigned long offset, unsigned long flags)
{
int ret;
struct uftrace_elf_data elf;

if (elf_init(filename, &elf) < 0) {
pr_dbg("error during open symbol file: %s: %m\n", filename);
return -1;
}

pr_dbg3("loading dynamic symbols from %s (offset: %#lx)\n", filename, offset);
ret = load_elf_dynsymtab(dsymtab, &elf, offset, flags);

elf_finish(&elf);
return ret;
}

static void merge_symtabs(struct uftrace_symtab *left, struct uftrace_symtab *right)
{
size_t nr_sym = left->nr_sym + right->nr_sym;
Expand Down Expand Up @@ -714,6 +697,26 @@ static void merge_symtabs(struct uftrace_symtab *left, struct uftrace_symtab *ri
left->name_sorted = true;
}

static int load_dynsymtab(struct uftrace_symtab *dsymtab, const char *filename,
unsigned long offset, unsigned long flags)
{
struct uftrace_symtab dsymtab_noplt = {};
struct uftrace_elf_data elf;

if (elf_init(filename, &elf) < 0) {
pr_dbg("error during open symbol file: %s: %m\n", filename);
return -1;
}

pr_dbg3("loading dynamic symbols from %s (offset: %#lx)\n", filename, offset);
load_elf_dynsymtab(dsymtab, &elf, offset, flags);
arch_load_dynsymtab_noplt(&dsymtab_noplt, &elf, offset, flags);
merge_symtabs(dsymtab, &dsymtab_noplt);

elf_finish(&elf);
return dsymtab->nr_sym;
}

static int update_symtab_using_dynsym(struct uftrace_symtab *symtab, const char *filename,
unsigned long offset, unsigned long flags)
{
Expand Down
1 change: 1 addition & 0 deletions utils/symbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ struct uftrace_module *load_module_symtab(struct uftrace_sym_info *sinfo, const
char *build_id);
void save_module_symtabs(const char *dirname);
void unload_module_symtabs(void);
void sort_dynsymtab(struct uftrace_symtab *dsymtab);

enum uftrace_trace_type {
TRACE_ERROR = -1,
Expand Down

0 comments on commit 028f43b

Please sign in to comment.