]> git.itanic.dy.fi Git - linux-stable/commitdiff
perf symbols: Allow for .plt without header
authorAdrian Hunter <adrian.hunter@intel.com>
Tue, 31 Jan 2023 13:16:22 +0000 (15:16 +0200)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 2 Feb 2023 00:51:31 +0000 (21:51 -0300)
A static executable can have a .plt due to the presence of IFUNCs.  In
that case the .plt does not have a header. Check for whether there is a
header by comparing the number of entries to the number of relocation
entries.

Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Link: https://lore.kernel.org/r/20230131131625.6964-7-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/symbol-elf.c

index a002fc0bea03e4bccfb6fb2f15c1c4ad504de777..8f7802097c72390ae67bf6b4b31b6e5c4a49df9a 100644 (file)
@@ -489,6 +489,7 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss)
        Elf *elf;
        int nr = 0, err = -1;
        struct rel_info ri = { .is_rela = false };
+       bool lazy_plt;
 
        elf = ss->elf;
        ehdr = ss->ehdr;
@@ -523,8 +524,10 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss)
                plt_sym->end = plt_sym->start + shdr_plt.sh_size;
                /* Use .plt.sec offset */
                plt_offset = plt_sec_shdr.sh_offset;
+               lazy_plt = false;
        } else {
-               plt_offset = shdr_plt.sh_offset + plt_header_size;
+               plt_offset = shdr_plt.sh_offset;
+               lazy_plt = true;
        }
 
        scn_dynsym = ss->dynsym;
@@ -577,6 +580,17 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss)
 
        ri.is_rela = shdr_rel_plt.sh_type == SHT_RELA;
 
+       if (lazy_plt) {
+               /*
+                * Assume a .plt with the same number of entries as the number
+                * of relocation entries is not lazy and does not have a header.
+                */
+               if (ri.nr_entries * plt_entry_size == shdr_plt.sh_size)
+                       dso__delete_symbol(dso, plt_sym);
+               else
+                       plt_offset += plt_header_size;
+       }
+
        /*
         * x86 doesn't insert IFUNC relocations in .plt order, so sort to get
         * back in order.