Skip to content

Commit 5303899

Browse files
author
Peter Zijlstra
committed
objtool: Optimize find_section_by_index()
In order to avoid a linear search (over 20k entries), add an section_hash to the elf object. This reduces objtool on vmlinux.o from a few minutes to around 45 seconds. Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Reviewed-by: Miroslav Benes <[email protected]> Acked-by: Josh Poimboeuf <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 1e11f3f commit 5303899

File tree

2 files changed

+10
-5
lines changed

2 files changed

+10
-5
lines changed

tools/objtool/elf.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ static struct section *find_section_by_index(struct elf *elf,
3838
{
3939
struct section *sec;
4040

41-
list_for_each_entry(sec, &elf->sections, list)
41+
hash_for_each_possible(elf->section_hash, sec, hash, idx)
4242
if (sec->idx == idx)
4343
return sec;
4444

@@ -166,8 +166,6 @@ static int read_sections(struct elf *elf)
166166
INIT_LIST_HEAD(&sec->rela_list);
167167
hash_init(sec->rela_hash);
168168

169-
list_add_tail(&sec->list, &elf->sections);
170-
171169
s = elf_getscn(elf->elf, i);
172170
if (!s) {
173171
WARN_ELF("elf_getscn");
@@ -201,6 +199,9 @@ static int read_sections(struct elf *elf)
201199
}
202200
}
203201
sec->len = sec->sh.sh_size;
202+
203+
list_add_tail(&sec->list, &elf->sections);
204+
hash_add(elf->section_hash, &sec->hash, sec->idx);
204205
}
205206

206207
if (stats)
@@ -439,6 +440,7 @@ struct elf *elf_read(const char *name, int flags)
439440
memset(elf, 0, sizeof(*elf));
440441

441442
hash_init(elf->symbol_hash);
443+
hash_init(elf->section_hash);
442444
INIT_LIST_HEAD(&elf->sections);
443445

444446
elf->fd = open(name, flags);
@@ -501,8 +503,6 @@ struct section *elf_create_section(struct elf *elf, const char *name,
501503
INIT_LIST_HEAD(&sec->rela_list);
502504
hash_init(sec->rela_hash);
503505

504-
list_add_tail(&sec->list, &elf->sections);
505-
506506
s = elf_newscn(elf->elf);
507507
if (!s) {
508508
WARN_ELF("elf_newscn");
@@ -579,6 +579,9 @@ struct section *elf_create_section(struct elf *elf, const char *name,
579579
shstrtab->len += strlen(name) + 1;
580580
shstrtab->changed = true;
581581

582+
list_add_tail(&sec->list, &elf->sections);
583+
hash_add(elf->section_hash, &sec->hash, sec->idx);
584+
582585
return sec;
583586
}
584587

tools/objtool/elf.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
struct section {
2727
struct list_head list;
28+
struct hlist_node hash;
2829
GElf_Shdr sh;
2930
struct list_head symbol_list;
3031
struct list_head rela_list;
@@ -71,6 +72,7 @@ struct elf {
7172
char *name;
7273
struct list_head sections;
7374
DECLARE_HASHTABLE(symbol_hash, 20);
75+
DECLARE_HASHTABLE(section_hash, 16);
7476
};
7577

7678

0 commit comments

Comments
 (0)