Commit 698a0d1a authored by Adrian Hunter's avatar Adrian Hunter Committed by Arnaldo Carvalho de Melo

perf symbols: Add symbol for .plt header

perf expands the _init symbol over .plt because there are no PLT symbols
at that point, but then dso__synthesize_plt_symbols() creates them.

Fix by truncating the previous symbol and inserting a symbol for .plt
header.

Example:

 Before:

   $ perf test --dso `which uname` -v Symbols
    74: Symbols                                                         :
   --- start ---
   test child forked, pid 191028
   Problems creating module maps, continuing anyway...
   Testing /usr/bin/uname
   Overlapping symbols:
    2000-25f0 g _init
    2040-2050 g free@plt
   test child finished with -1
   ---- end ----
   Symbols: FAILED!
   $ perf test --dso `which uname` -vv Symbols 2>/tmp/cmp1.txt

 After:

   $ perf test --dso `which uname` -v Symbols
    74: Symbols                                                         :
   --- start ---
   test child forked, pid 194291
   Testing /usr/bin/uname
   test child finished with 0
   ---- end ----
   Symbols: Ok
   $ perf test --dso `which uname` -vv Symbols 2>/tmp/cmp2.txt
   $ diff /tmp/cmp1.txt /tmp/cmp2.txt
   4,5c4
   < test child forked, pid 191031
   < Problems creating module maps, continuing anyway...
   ---
   > test child forked, pid 194296
   9c8,9
   <  2000-25f0 g _init
   ---
   >  2000-2030 g _init
   >  2030-2040 g .plt
   100,103c100
   < Overlapping symbols:
   <  2000-25f0 g _init
   <  2040-2050 g free@plt
   < test child finished with -1
   ---
   > test child finished with 0
   105c102
   < Symbols: FAILED!
   ---
   > Symbols: Ok
   $
Signed-off-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Tested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: default avatarIan Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: https://lore.kernel.org/r/20230120123456.12449-8-adrian.hunter@intel.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 5fec9b17
...@@ -389,6 +389,27 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss) ...@@ -389,6 +389,27 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss)
elf = ss->elf; elf = ss->elf;
ehdr = ss->ehdr; ehdr = ss->ehdr;
if (!elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL))
return 0;
/*
* A symbol from a previous section (e.g. .init) can have been expanded
* by symbols__fixup_end() to overlap .plt. Truncate it before adding
* a symbol for .plt header.
*/
f = dso__find_symbol_nocache(dso, shdr_plt.sh_offset);
if (f && f->start < shdr_plt.sh_offset && f->end > shdr_plt.sh_offset)
f->end = shdr_plt.sh_offset;
if (!get_plt_sizes(dso, &ehdr, &shdr_plt, &plt_header_size, &plt_entry_size))
return 0;
/* Add a symbol for .plt header */
f = symbol__new(shdr_plt.sh_offset, plt_header_size, STB_GLOBAL, STT_FUNC, ".plt");
if (!f)
goto out_elf_end;
symbols__insert(&dso->symbols, f);
scn_dynsym = ss->dynsym; scn_dynsym = ss->dynsym;
shdr_dynsym = ss->dynshdr; shdr_dynsym = ss->dynshdr;
dynsym_idx = ss->dynsym_idx; dynsym_idx = ss->dynsym_idx;
...@@ -408,9 +429,6 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss) ...@@ -408,9 +429,6 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss)
if (shdr_rel_plt.sh_link != dynsym_idx) if (shdr_rel_plt.sh_link != dynsym_idx)
goto out_elf_end; goto out_elf_end;
if (elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL) == NULL)
goto out_elf_end;
/* /*
* Fetch the relocation section to find the idxes to the GOT * Fetch the relocation section to find the idxes to the GOT
* and the symbols in the .dynsym they refer to. * and the symbols in the .dynsym they refer to.
...@@ -436,8 +454,6 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss) ...@@ -436,8 +454,6 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss)
nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize; nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize;
plt_offset = shdr_plt.sh_offset; plt_offset = shdr_plt.sh_offset;
if (!get_plt_sizes(dso, &ehdr, &shdr_plt, &plt_header_size, &plt_entry_size))
return 0;
plt_offset += plt_header_size; plt_offset += plt_header_size;
if (shdr_rel_plt.sh_type == SHT_RELA) { if (shdr_rel_plt.sh_type == SHT_RELA) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment