objtool: Improve reloc hash size guestimate
authorPeter Zijlstra <peterz@infradead.org>
Fri, 11 Jun 2021 06:33:36 +0000 (08:33 +0200)
committerPeter Zijlstra <peterz@infradead.org>
Mon, 14 Jun 2021 12:05:36 +0000 (14:05 +0200)
Nathan reported that LLVM ThinLTO builds have a performance regression
with commit 25cf0d8aa2a3 ("objtool: Rewrite hashtable sizing"). Sami
was quick to note that this is due to their use of -ffunction-sections.

As a result the .text section is small and basing the number of relocs
off of that no longer works. Instead have read_sections() compute the
sum of all SHF_EXECINSTR sections and use that.

Fixes: 25cf0d8aa2a3 ("objtool: Rewrite hashtable sizing")
Reported-by: Nathan Chancellor <nathan@kernel.org>
Debugged-by: Sami Tolvanen <samitolvanen@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: Nathan Chancellor <nathan@kernel.org>
Link: https://lkml.kernel.org/r/YMJpGLuGNsGtA5JJ@hirez.programming.kicks-ass.net
tools/objtool/elf.c
tools/objtool/include/objtool/elf.h

index a8a0ee2..2371ccc 100644 (file)
@@ -288,6 +288,9 @@ static int read_sections(struct elf *elf)
                }
                sec->len = sec->sh.sh_size;
 
+               if (sec->sh.sh_flags & SHF_EXECINSTR)
+                       elf->text_size += sec->len;
+
                list_add_tail(&sec->list, &elf->sections);
                elf_hash_add(section, &sec->hash, sec->idx);
                elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name));
@@ -581,13 +584,7 @@ static int read_relocs(struct elf *elf)
        unsigned int symndx;
        unsigned long nr_reloc, max_reloc = 0, tot_reloc = 0;
 
-       sec = find_section_by_name(elf, ".text");
-       if (!sec) {
-               WARN("no .text");
-               return -1;
-       }
-
-       if (!elf_alloc_hash(reloc, sec->len / 16))
+       if (!elf_alloc_hash(reloc, elf->text_size / 16))
                return -1;
 
        list_for_each_entry(sec, &elf->sections, list) {
index 9008275..e343950 100644 (file)
@@ -83,6 +83,7 @@ struct elf {
        int fd;
        bool changed;
        char *name;
+       unsigned int text_size;
        struct list_head sections;
 
        int symbol_bits;