From nobody Sat Jun 13 22:15:52 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 79276481FA8; Tue, 5 May 2026 10:56:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777978609; cv=none; b=CPl/Uv++apP6IUlSMGmBKc/q3M8A9Lzz0n+yr5hmyirWia6PenpapPMZVAoQOUKqw4UIglLG4Anx1bNbI8s/EvPkQwQxAhPsCnXh1B++eziy9v531mFYyu7uagTjIIDRm+ByNLl+nDo/CJedgP+o2h/rq5KV3yuiGD4775umEGQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777978609; c=relaxed/simple; bh=IbITFrnYE8gU4AaZNOaUVJrhvgU7CACSAvykcy6GU4E=; h=Date:From:To:Subject:Cc:MIME-Version:Message-ID:Content-Type; b=YrUzidyqOrc4EsrZ95hjhvEEdd99zZ0KTLIZRI6TGN4VxHGg4VcMFYhnrCcniki1YoiawSMqs1xto+iTXLTB0PtVC50796sZ0+t8VH7WT+qgkfcPJfuyR2J+MhMaoz07Bj1QpS+pd4orKCx+HbjZ5iB9YO7tJZO8aAp7ipJsEKg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=0mTDne9L; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=e0dLx2Xn; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="0mTDne9L"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="e0dLx2Xn" Date: Tue, 05 May 2026 10:56:44 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1777978605; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=bExvj9HeZM+Zh2GdLFheJOJ+ynPxA0yOnSpG5MTJVQ8=; b=0mTDne9LC93Ai+Sob/bIHfpfmV/XLmG0guZ46nGha4ScEFvnoC18PEcMzNRzXhEEs+fPGz f4DLQJNg52abckSWJtBkSEGlOr3OqhH6UhVM1gRvLctdjd9tk4nS39QzkPZwjaCwq5yNVC v8RIky11iOp8B547RYeitMFa1yaEzxvIRCBFCWrfmUdV3yqRSBlHBf5WF35RllNRCZJCYp vSMTcIhIjrQbUeTSO3gtWGHFmR+kUg6ijwuiLNdxyV1FYgMaznBmPYhtKbcQUP99m/0R6A Ep0h3+VsT/SePNdSFOFYVBurO5m9oVds0T4qn/ZqTpkdzSb+US0aumujP06VQA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1777978605; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=bExvj9HeZM+Zh2GdLFheJOJ+ynPxA0yOnSpG5MTJVQ8=; b=e0dLx2XnS4lr3vTHK48q/5la4hmXXMOYmbbLLVN+VQlp3v1XLyXPfWi7DV0ZkPf/mWD7Gp 6lm+TksBCsW8iSCQ== From: "tip-bot2 for Josh Poimboeuf" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: objtool/core] objtool: Replace iterator callback with for_each_sym_by_mangled_name() Cc: Song Liu , Miroslav Benes , Josh Poimboeuf , x86@kernel.org, linux-kernel@vger.kernel.org Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <177797860415.424702.5413697816947267042.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Precedence: bulk Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The following commit has been merged into the objtool/core branch of tip: Commit-ID: 0333b7399587ee0aaa863ed0d13a00a6c7c64068 Gitweb: https://git.kernel.org/tip/0333b7399587ee0aaa863ed0d13a00a6c= 7c64068 Author: Josh Poimboeuf AuthorDate: Sun, 12 Apr 2026 22:41:23 -07:00 Committer: Josh Poimboeuf CommitterDate: Mon, 04 May 2026 21:16:00 -07:00 objtool: Replace iterator callback with for_each_sym_by_mangled_name() Convert the callback-based iterate_sym_by_demangled_name() with a new for_each_sym_by_demangled_name() macro. This eliminates the callback struct/function and makes the code more compact and readable. Acked-by: Song Liu Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 68 +++++++--------------------- tools/objtool/include/objtool/elf.h | 32 +++++++++++-- tools/objtool/klp-diff.c | 42 +++++------------ 3 files changed, 60 insertions(+), 82 deletions(-) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index f3df2bd..dc39132 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -27,27 +27,16 @@ =20 static ssize_t demangled_name_len(const char *name); =20 -static inline u32 str_hash(const char *str) -{ - return jhash(str, strlen(str), 0); -} - -static inline u32 str_hash_demangled(const char *str) +u32 str_hash_demangled(const char *str) { return jhash(str, demangled_name_len(str), 0); } =20 -#define __elf_table(name) (elf->name##_hash) -#define __elf_bits(name) (elf->name##_bits) - -#define __elf_table_entry(name, key) \ - __elf_table(name)[hash_min(key, __elf_bits(name))] - #define elf_hash_add(name, node, key) \ ({ \ struct elf_hash_node *__node =3D node; \ - __node->next =3D __elf_table_entry(name, key); \ - __elf_table_entry(name, key) =3D __node; \ + __node->next =3D __elf_table_entry(elf, name, key); \ + __elf_table_entry(elf, name, key) =3D __node; \ }) =20 static inline void __elf_hash_del(struct elf_hash_node *node, @@ -69,30 +58,20 @@ static inline void __elf_hash_del(struct elf_hash_node = *node, } =20 #define elf_hash_del(name, node, key) \ - __elf_hash_del(node, &__elf_table_entry(name, key)) - -#define elf_list_entry(ptr, type, member) \ -({ \ - typeof(ptr) __ptr =3D (ptr); \ - __ptr ? container_of(__ptr, type, member) : NULL; \ -}) - -#define elf_hash_for_each_possible(name, obj, member, key) \ - for (obj =3D elf_list_entry(__elf_table_entry(name, key), typeof(*obj), m= ember); \ - obj; \ - obj =3D elf_list_entry(obj->member.next, typeof(*(obj)), member)) + __elf_hash_del(node, &__elf_table_entry(elf, name, key)) =20 #define elf_alloc_hash(name, size) \ ({ \ - __elf_bits(name) =3D max(10, ilog2(size)); \ - __elf_table(name) =3D mmap(NULL, sizeof(struct elf_hash_node *) << __elf_= bits(name), \ + __elf_bits(elf, name) =3D max(10, ilog2(size)); \ + __elf_table(elf, name) =3D mmap(NULL, \ + sizeof(struct elf_hash_node *) << __elf_bits(elf, name), \ PROT_READ|PROT_WRITE, \ MAP_PRIVATE|MAP_ANON, -1, 0); \ - if (__elf_table(name) =3D=3D (void *)-1L) { \ + if (__elf_table(elf, name) =3D=3D (void *)-1L) { \ ERROR_GLIBC("mmap fail " #name); \ - __elf_table(name) =3D NULL; \ + __elf_table(elf, name) =3D NULL; \ } \ - __elf_table(name); \ + __elf_table(elf, name); \ }) =20 static inline unsigned long __sym_start(struct symbol *s) @@ -141,7 +120,7 @@ struct section *find_section_by_name(const struct elf *= elf, const char *name) { struct section *sec; =20 - elf_hash_for_each_possible(section_name, sec, name_hash, str_hash(name)) { + elf_hash_for_each_possible(elf, section_name, sec, name_hash, str_hash(na= me)) { if (!strcmp(sec->name, name)) return sec; } @@ -154,7 +133,7 @@ static struct section *find_section_by_index(struct elf= *elf, { struct section *sec; =20 - elf_hash_for_each_possible(section, sec, hash, idx) { + elf_hash_for_each_possible(elf, section, sec, hash, idx) { if (sec->idx =3D=3D idx) return sec; } @@ -166,7 +145,7 @@ static struct symbol *find_symbol_by_index(struct elf *= elf, unsigned int idx) { struct symbol *sym; =20 - elf_hash_for_each_possible(symbol, sym, hash, idx) { + elf_hash_for_each_possible(elf, symbol, sym, hash, idx) { if (sym->idx =3D=3D idx) return sym; } @@ -285,7 +264,7 @@ struct symbol *find_symbol_by_name(const struct elf *el= f, const char *name) { struct symbol *sym; =20 - elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(name)) { + elf_hash_for_each_possible(elf, symbol_name, sym, name_hash, str_hash(nam= e)) { if (!strcmp(sym->name, name)) return sym; } @@ -300,7 +279,7 @@ static struct symbol *find_local_symbol_by_file_and_nam= e(const struct elf *elf, { struct symbol *sym; =20 - elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash_demangle= d(name)) { + elf_hash_for_each_possible(elf, symbol_name, sym, name_hash, str_hash_dem= angled(name)) { if (sym->bind =3D=3D STB_LOCAL && sym->file =3D=3D file && !strcmp(sym->name, name)) { return sym; @@ -314,7 +293,7 @@ struct symbol *find_global_symbol_by_name(const struct = elf *elf, const char *nam { struct symbol *sym; =20 - elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash_demangle= d(name)) { + elf_hash_for_each_possible(elf, symbol_name, sym, name_hash, str_hash_dem= angled(name)) { if (!strcmp(sym->name, name) && !is_local_sym(sym)) return sym; } @@ -322,19 +301,6 @@ struct symbol *find_global_symbol_by_name(const struct= elf *elf, const char *nam return NULL; } =20 -void iterate_global_symbol_by_demangled_name(const struct elf *elf, - const char *demangled_name, - void (*process)(struct symbol *sym, void *data), - void *data) -{ - struct symbol *sym; - - elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(demangle= d_name)) { - if (!strcmp(sym->demangled_name, demangled_name) && !is_local_sym(sym)) - process(sym, data); - } -} - struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct secti= on *sec, unsigned long offset, unsigned int len) { @@ -347,7 +313,7 @@ struct reloc *find_reloc_by_dest_range(const struct elf= *elf, struct section *se return NULL; =20 for_offset_range(o, offset, offset + len) { - elf_hash_for_each_possible(reloc, reloc, hash, + elf_hash_for_each_possible(elf, reloc, reloc, hash, sec_offset_hash(rsec, o)) { if (reloc->sec !=3D rsec) continue; diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index 25573e5..b142984 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -21,6 +21,13 @@ #define SEC_NAME_LEN 1024 #define SYM_NAME_LEN 512 =20 +static inline u32 str_hash(const char *str) +{ + return jhash(str, strlen(str), 0); +} + +u32 str_hash_demangled(const char *str); + #define bswap_if_needed(elf, val) __bswap_if_needed(&elf->ehdr, val) =20 #ifdef LIBELF_USE_DEPRECATED @@ -130,6 +137,23 @@ struct elf { struct symbol *symbol_data; }; =20 +#define __elf_table(elf, name) ((elf)->name##_hash) +#define __elf_bits(elf, name) ((elf)->name##_bits) + +#define __elf_table_entry(elf, name, key) \ + __elf_table(elf, name)[hash_min(key, __elf_bits(elf, name))] + +#define elf_list_entry(ptr, type, member) \ +({ \ + typeof(ptr) __ptr =3D (ptr); \ + __ptr ? container_of(__ptr, type, member) : NULL; \ +}) + +#define elf_hash_for_each_possible(elf, name, obj, member, key) \ + for (obj =3D elf_list_entry(__elf_table_entry(elf, name, key), typeof(*ob= j), member); \ + obj; \ + obj =3D elf_list_entry(obj->member.next, typeof(*(obj)), member)) + struct elf *elf_open_read(const char *name, int flags); struct elf *elf_create_file(GElf_Ehdr *ehdr, const char *name); =20 @@ -186,9 +210,6 @@ struct symbol *find_func_by_offset(struct section *sec,= unsigned long offset); struct symbol *find_symbol_by_offset(struct section *sec, unsigned long of= fset); struct symbol *find_symbol_by_name(const struct elf *elf, const char *name= ); struct symbol *find_global_symbol_by_name(const struct elf *elf, const cha= r *name); -void iterate_global_symbol_by_demangled_name(const struct elf *elf, const = char *demangled_name, - void (*process)(struct symbol *sym, void *data), - void *data); struct symbol *find_symbol_containing(const struct section *sec, unsigned = long offset); int find_symbol_hole_containing(const struct section *sec, unsigned long o= ffset); struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *se= c, unsigned long offset); @@ -468,6 +489,11 @@ static inline void set_sym_next_reloc(struct reloc *re= loc, struct reloc *next) #define for_each_sym_continue(elf, sym) \ list_for_each_entry_continue(sym, &elf->symbols, global_list) =20 +#define for_each_sym_by_demangled_name(elf, name, sym) \ + elf_hash_for_each_possible(elf, symbol_name, sym, name_hash, \ + str_hash(name)) \ + if (strcmp(sym->demangled_name, name)) {} else + #define rsec_next_reloc(rsec, reloc) \ reloc_idx(reloc) < sec_num_entries(rsec) - 1 ? reloc + 1 : NULL =20 diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 0653bf6..30ce234 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -46,11 +46,6 @@ static const struct option klp_diff_options[] =3D { =20 static DEFINE_HASHTABLE(exports, 15); =20 -static inline u32 str_hash(const char *str) -{ - return jhash(str, strlen(str), 0); -} - static char *escape_str(const char *orig) { size_t len =3D 0; @@ -396,22 +391,6 @@ static bool dont_correlate(struct symbol *sym) is_special_section_aux(sym->sec); } =20 -struct process_demangled_name_data { - struct symbol *ret; - int count; -}; - -static void process_demangled_name(struct symbol *sym, void *d) -{ - struct process_demangled_name_data *data =3D d; - - if (sym->twin) - return; - - data->count++; - data->ret =3D sym; -} - /* * When there is no full name match, try match demangled_name. This would * match original foo.llvm.123 to patched foo.llvm.456. @@ -423,16 +402,23 @@ static void process_demangled_name(struct symbol *sym= , void *d) static int find_global_symbol_by_demangled_name(struct elf *elf, struct sy= mbol *sym, struct symbol **out_sym) { - struct process_demangled_name_data data =3D {}; + struct symbol *sym2, *result =3D NULL; + int count =3D 0; + + for_each_sym_by_demangled_name(elf, sym->demangled_name, sym2) { + if (is_local_sym(sym2) || sym2->twin) + continue; =20 - iterate_global_symbol_by_demangled_name(elf, sym->demangled_name, - process_demangled_name, - &data); - if (data.count > 1) { - ERROR("Multiple (%d) correlation candidates for %s", data.count, sym->na= me); + count++; + result =3D sym2; + } + + if (count > 1) { + ERROR("Multiple (%d) correlation candidates for %s", count, sym->name); return -1; } - *out_sym =3D data.ret; + + *out_sym =3D result; return 0; } =20