Before we can move this function out of the wrapper and into wordsize-independent code we need to return the relocation symbol information in a size-independent fashion. Previously we compared the raw info bits but that requires passing around an unsigned long. Instead we just use a pointer to the objtool struct symbol which callers can use as-needed.
Reported-by: Kamalesh Babulal <kamal...@linux.vnet.ibm.com> Signed-off-by: Matt Helsley <mhels...@vmware.com> Co-developed-by: Kamalesh Babulal <kamal...@linux.vnet.ibm.com> Co-developed-by: Peter Zijlstra <pet...@infradead.org> -- Thanks to Kamalesh Babulal for reporting this problem and suggesting a fix. Thanks to Peter Zijlstra for recommending an enhancement to the fix. --- tools/objtool/recordmcount.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/objtool/recordmcount.h b/tools/objtool/recordmcount.h index df8384f8e9e7..6ac120aa45af 100644 --- a/tools/objtool/recordmcount.h +++ b/tools/objtool/recordmcount.h @@ -271,7 +271,7 @@ static int append_func(Elf_Ehdr *const ehdr, return elf_write(lf); } -static unsigned get_mcountsym(struct reloc *reloc) +static struct symbol *get_mcountsym(struct reloc *reloc) { struct symbol *sym = reloc->sym; char const *symname = sym->name; @@ -283,8 +283,8 @@ static unsigned get_mcountsym(struct reloc *reloc) if (strcmp(mcount, symname) == 0 || (altmcount && strcmp(altmcount, symname) == 0) || (strcmp(fentry, symname) == 0)) - return GELF_R_INFO(reloc->sym->idx, reloc->type); - return 0; + return sym; + return NULL; } /* @@ -303,14 +303,14 @@ static uint_t *sift_rel_mcount(uint_t *mlocp, uint_t *const mloc0 = mlocp; Elf_Rel *mrelp = *mrelpp; unsigned int rel_entsize = rels->sh.sh_entsize; - unsigned mcountsym = 0; + struct symbol *mcountsym = NULL; struct reloc *reloc; list_for_each_entry(reloc, &rels->reloc_list, list) { if (!mcountsym) mcountsym = get_mcountsym(reloc); - if (mcountsym == GELF_R_INFO(reloc->sym->idx, reloc->type) && !is_fake_mcount(reloc)) { + if (mcountsym == reloc->sym && !is_fake_mcount(reloc)) { uint_t const addend = _w(reloc->offset - recval + mcount_adjust); mrelp->r_offset = _w(offbase @@ -342,7 +342,7 @@ static int nop_mcount(struct section * const rels, + (void *)ehdr); struct reloc *reloc; Elf_Shdr const *const shdr = &shdr0[rels->sh.sh_info]; - unsigned mcountsym = 0; + struct symbol *mcountsym = NULL; int once = 0; list_for_each_entry(reloc, &rels->reloc_list, list) { @@ -351,7 +351,7 @@ static int nop_mcount(struct section * const rels, if (!mcountsym) mcountsym = get_mcountsym(reloc); - if (mcountsym == GELF_R_INFO(reloc->sym->idx, reloc->type) && !is_fake_mcount(reloc)) { + if (mcountsym == reloc->sym && !is_fake_mcount(reloc)) { if (make_nop) { ret = make_nop((void *)ehdr, _w(shdr->sh_offset) + reloc->offset); if (ret < 0) -- 2.20.1