|
@@ -520,7 +520,9 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
|
|
|
nr_syms = shdr.sh_size / shdr.sh_entsize;
|
|
|
|
|
|
memset(&sym, 0, sizeof(sym));
|
|
|
-
|
|
|
+ self->prelinked = elf_section_by_name(elf, &ehdr, &shdr,
|
|
|
+ ".gnu.prelink_undo",
|
|
|
+ NULL) != NULL;
|
|
|
elf_symtab__for_each_symbol(syms, nr_syms, index, sym) {
|
|
|
struct symbol *f;
|
|
|
u64 obj_start;
|
|
@@ -535,11 +537,13 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
|
|
|
gelf_getshdr(sec, &shdr);
|
|
|
obj_start = sym.st_value;
|
|
|
|
|
|
- if (verbose >= 2)
|
|
|
- printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n",
|
|
|
- (u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset);
|
|
|
+ if (self->prelinked) {
|
|
|
+ if (verbose >= 2)
|
|
|
+ printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n",
|
|
|
+ (u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset);
|
|
|
|
|
|
- sym.st_value -= shdr.sh_addr - shdr.sh_offset;
|
|
|
+ sym.st_value -= shdr.sh_addr - shdr.sh_offset;
|
|
|
+ }
|
|
|
|
|
|
f = symbol__new(sym.st_value, sym.st_size,
|
|
|
elf_sym__name(&sym, symstrs),
|
|
@@ -573,6 +577,8 @@ int dso__load(struct dso *self, symbol_filter_t filter, int verbose)
|
|
|
if (!name)
|
|
|
return -1;
|
|
|
|
|
|
+ self->prelinked = 0;
|
|
|
+
|
|
|
if (strncmp(self->name, "/tmp/perf-", 10) == 0)
|
|
|
return dso__load_perf_map(self, filter, verbose);
|
|
|
|