From a375e327b63e0da29b82a92b569bfdf4628fa38a Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Tue, 21 Apr 2026 07:21:19 -0700 Subject: [PATCH] objtool: Fix reloc hash collision in find_reloc_by_dest_range() In find_reloc_by_dest_range(), hash collisions can cause a high-offset relocation to appear when probing a low-offset hash bucket. Only return early when the best match found so far genuinely belongs to the current bucket (its offset is within the bucket's stride range). Otherwise, continue scanning later buckets which may contain lower-offset matches. This ensures the first reloc in the range gets returned. Fixes: 74b873e49d92 ("objtool: Optimize find_rela_by_dest_range()") Acked-by: Peter Zijlstra (Intel) Acked-by: Song Liu Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 5a20dab683dd2..f41280e454ca4 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -315,8 +315,9 @@ struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *nam return NULL; } +/* If there are multiple matches, return the first one in the range */ struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec, - unsigned long offset, unsigned int len) + unsigned long offset, unsigned int len) { struct reloc *reloc, *r = NULL; struct section *rsec; @@ -338,11 +339,11 @@ struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *se r = reloc; } } - if (r) + if (r && (reloc_offset(r) & OFFSET_STRIDE_MASK) == o) return r; } - return NULL; + return r; } struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset) -- 2.47.3