tools/objtool/elf.c | 47 ++++++++++++++++++----------- tools/objtool/include/objtool/elf.h | 1 + 2 files changed, 30 insertions(+), 18 deletions(-)
From 2a33e583c87e3283706f346f9d59aac20653b7fd Mon Sep 17 00:00:00 2001
Message-ID: <2a33e583c87e3283706f346f9d59aac20653b7fd.1746662991.git.jpoimboe@kernel.org>
From: Josh Poimboeuf <jpoimboe@kernel.org>
Date: Wed, 7 May 2025 16:56:55 -0700
Subject: [PATCH] objtool: Speed up SHT_GROUP reindexing
After elf_update_group_sh_info() was introduced, a prototype version of
"objtool klp diff" went from taking ~1s to several minutes, due to
looping almost endlessly in elf_update_group_sh_info() while creating
thousands of local symbols in a file with thousands of sections.
Dramatically improve the performance by marking all symbols' correlated
SHT_GROUP sections while reading the object. That way there's no need
to search for it every time a symbol gets reindexed.
Fixes: 2cb291596e2c ("objtool: Fix up st_info in COMDAT group section")
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/elf.c | 47 ++++++++++++++++++-----------
tools/objtool/include/objtool/elf.h | 1 +
2 files changed, 30 insertions(+), 18 deletions(-)
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 8dffe68d705c..ca5d77db692a 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -572,28 +572,32 @@ static int read_symbols(struct elf *elf)
return -1;
}
-/*
- * @sym's idx has changed. Update the sh_info in group sections.
- */
-static void elf_update_group_sh_info(struct elf *elf, Elf32_Word symtab_idx,
- Elf32_Word new_idx, Elf32_Word old_idx)
+static int mark_group_syms(struct elf *elf)
{
- struct section *sec;
+ struct section *symtab, *sec;
+ struct symbol *sym;
+
+ symtab = find_section_by_name(elf, ".symtab");
+ if (!symtab) {
+ ERROR("no .symtab");
+ return -1;
+ }
list_for_each_entry(sec, &elf->sections, list) {
- if (sec->sh.sh_type != SHT_GROUP)
- continue;
- if (sec->sh.sh_link == symtab_idx &&
- sec->sh.sh_info == old_idx) {
- sec->sh.sh_info = new_idx;
- mark_sec_changed(elf, sec, true);
- /*
- * Each ELF group should have a unique symbol key.
- * Return early on match.
- */
- return;
+ if (sec->sh.sh_type == SHT_GROUP &&
+ sec->sh.sh_link == symtab->idx) {
+ sym = find_symbol_by_index(elf, sec->sh.sh_info);
+ if (!sym) {
+ ERROR("%s: can't find SHT_GROUP signature symbol",
+ sec->name);
+ return -1;
+ }
+
+ sym->group_sec = sec;
}
}
+
+ return 0;
}
/*
@@ -787,7 +791,11 @@ __elf_create_symbol(struct elf *elf, struct symbol *sym)
if (elf_update_sym_relocs(elf, old))
return NULL;
- elf_update_group_sh_info(elf, symtab->idx, new_idx, first_non_local);
+ if (old->group_sec) {
+ old->group_sec->sh.sh_info = new_idx;
+ mark_sec_changed(elf, old->group_sec, true);
+ }
+
new_idx = first_non_local;
}
@@ -1060,6 +1068,9 @@ struct elf *elf_open_read(const char *name, int flags)
if (read_symbols(elf))
goto err;
+ if (mark_group_syms(elf))
+ goto err;
+
if (read_relocs(elf))
goto err;
diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h
index c7c4e87ebe88..0a2fa3ac0079 100644
--- a/tools/objtool/include/objtool/elf.h
+++ b/tools/objtool/include/objtool/elf.h
@@ -72,6 +72,7 @@ struct symbol {
u8 ignore : 1;
struct list_head pv_target;
struct reloc *relocs;
+ struct section *group_sec;
};
struct reloc {
--
2.49.0
On Wed, May 07, 2025 at 05:11:03PM -0700, Josh Poimboeuf wrote: > From 2a33e583c87e3283706f346f9d59aac20653b7fd Mon Sep 17 00:00:00 2001 > Message-ID: <2a33e583c87e3283706f346f9d59aac20653b7fd.1746662991.git.jpoimboe@kernel.org> > From: Josh Poimboeuf <jpoimboe@kernel.org> > Date: Wed, 7 May 2025 16:56:55 -0700 > Subject: [PATCH] objtool: Speed up SHT_GROUP reindexing Urgh, sorry about the patch formatting, the above can obviously be dropped. -- Josh
On Wed, May 07, 2025 at 05:11:53PM -0700, Josh Poimboeuf wrote: > On Wed, May 07, 2025 at 05:11:03PM -0700, Josh Poimboeuf wrote: > > From 2a33e583c87e3283706f346f9d59aac20653b7fd Mon Sep 17 00:00:00 2001 > > Message-ID: <2a33e583c87e3283706f346f9d59aac20653b7fd.1746662991.git.jpoimboe@kernel.org> > > From: Josh Poimboeuf <jpoimboe@kernel.org> > > Date: Wed, 7 May 2025 16:56:55 -0700 > > Subject: [PATCH] objtool: Speed up SHT_GROUP reindexing > > Urgh, sorry about the patch formatting, the above can obviously be > dropped. No worries, my script did it almost right :-) Patch seems sane to me; I'll go stick it into objtool/core. Rong if you could verify your case still work correctly that would be appreciated.
On Thu, May 8, 2025 at 8:27 AM Peter Zijlstra <peterz@infradead.org> wrote: > > On Wed, May 07, 2025 at 05:11:53PM -0700, Josh Poimboeuf wrote: > > On Wed, May 07, 2025 at 05:11:03PM -0700, Josh Poimboeuf wrote: > > > From 2a33e583c87e3283706f346f9d59aac20653b7fd Mon Sep 17 00:00:00 2001 > > > Message-ID: <2a33e583c87e3283706f346f9d59aac20653b7fd.1746662991.git.jpoimboe@kernel.org> > > > From: Josh Poimboeuf <jpoimboe@kernel.org> > > > Date: Wed, 7 May 2025 16:56:55 -0700 > > > Subject: [PATCH] objtool: Speed up SHT_GROUP reindexing > > > > Urgh, sorry about the patch formatting, the above can obviously be > > dropped. > > No worries, my script did it almost right :-) > > Patch seems sane to me; I'll go stick it into objtool/core. Rong if you > could verify your case still work correctly that would be appreciated. I tested the patch, and it works for me. I also looked at the patch. It assumes there is only one .symtab section. In general, there can be multiple symtab sections in an ELF file. But this (i.e. one symtab) most likely holds for the kernel. Tested-by: Rong Xu <xur@google.com> Thanks, -Rong >
© 2016 - 2025 Red Hat, Inc.