Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

objtool: Fix reloc_hash size

With CONFIG_DEBUG_INFO, DWARF creates a lot of relocations and
reloc_hash is woefully undersized, which can affect performance
significantly. Fix that.

Link: https://lore.kernel.org/r/38ef60dc8043270bf3b9dfd139ae2a30ca3f75cc.1685464332.git.jpoimboe@kernel.org
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>

+14 -10
+7 -9
tools/objtool/elf.c
··· 328 328 } 329 329 } 330 330 331 - if (sec->sh.sh_flags & SHF_EXECINSTR) 332 - elf->text_size += sec->sh.sh_size; 333 - 334 331 list_add_tail(&sec->list, &elf->sections); 335 332 elf_hash_add(section, &sec->hash, sec->idx); 336 333 elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name)); 334 + 335 + if (is_reloc_sec(sec)) 336 + elf->num_relocs += sec->sh.sh_size / sec->sh.sh_entsize; 337 337 } 338 338 339 339 if (opts.stats) { ··· 888 888 889 889 static int read_relocs(struct elf *elf) 890 890 { 891 - unsigned long nr_reloc, max_reloc = 0, tot_reloc = 0; 891 + unsigned long nr_reloc, max_reloc = 0; 892 892 struct section *rsec; 893 893 struct reloc *reloc; 894 894 unsigned int symndx; 895 895 struct symbol *sym; 896 896 int i; 897 897 898 - if (!elf_alloc_hash(reloc, elf->text_size / 16)) 898 + if (!elf_alloc_hash(reloc, elf->num_relocs)) 899 899 return -1; 900 900 901 901 list_for_each_entry(rsec, &elf->sections, list) { 902 - if ((rsec->sh.sh_type != SHT_RELA) && 903 - (rsec->sh.sh_type != SHT_REL)) 902 + if (!is_reloc_sec(rsec)) 904 903 continue; 905 904 906 905 rsec->base = find_section_by_index(elf, rsec->sh.sh_info); ··· 941 942 nr_reloc++; 942 943 } 943 944 max_reloc = max(max_reloc, nr_reloc); 944 - tot_reloc += nr_reloc; 945 945 } 946 946 947 947 if (opts.stats) { 948 948 printf("max_reloc: %lu\n", max_reloc); 949 - printf("tot_reloc: %lu\n", tot_reloc); 949 + printf("num_relocs: %lu\n", elf->num_relocs); 950 950 printf("reloc_bits: %d\n", elf->reloc_bits); 951 951 } 952 952
+7 -1
tools/objtool/include/objtool/elf.h
··· 90 90 int fd; 91 91 bool changed; 92 92 char *name; 93 - unsigned int text_size, num_files; 93 + unsigned int num_files; 94 94 struct list_head sections; 95 + unsigned long num_relocs; 95 96 96 97 int symbol_bits; 97 98 int symbol_name_bits; ··· 157 156 static inline size_t elf_rela_size(struct elf *elf) 158 157 { 159 158 return elf_addr_size(elf) == 4 ? sizeof(Elf32_Rela) : sizeof(Elf64_Rela); 159 + } 160 + 161 + static inline bool is_reloc_sec(struct section *sec) 162 + { 163 + return sec->sh.sh_type == SHT_RELA || sec->sh.sh_type == SHT_REL; 160 164 } 161 165 162 166 #define for_each_sec(file, sec) \