History

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.

Josh Poimboeuf committed 6 months ago

Commit a375e321 parent 5f49ec81 file · +4 −3Browse files

Unified · Split

tools/objtool/elf.c+4−3
@@ -315,8 +315,9 @@ struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *nam · 314 unmodified lines
315 return NULL;315 return NULL;
316}316}
317 317
318/* If there are multiple matches, return the first one in the range */
318struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec,319struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec,
319 unsigned long offset, unsigned int len)320 unsigned long offset, unsigned int len)
320{321{
321 struct reloc *reloc, *r = NULL;322 struct reloc *reloc, *r = NULL;
322 struct section *rsec;323 struct section *rsec;
@@ -338,11 +339,11 @@ struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *se · 15 unmodified lines
338 r = reloc;339 r = reloc;
339 }340 }
340 }341 }
341 if (r)342 if (r && (reloc_offset(r) & OFFSET_STRIDE_MASK) == o)
342 return r;343 return r;
343 }344 }
344 345
345 return NULL;346 return r;
346}347}
347 348
348struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset)349struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset)