objtool: Add elf_create_reloc() helper
commit ef47cc01cb4abcd760d8ac66b9361d6ade4d0846 upstream. We have 4 instances of adding a relocation. Create a common helper to avoid growing even more. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Borislav Petkov <bp@suse.de> Signed-off-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: Miroslav Benes <mbenes@suse.cz> Link: https://lkml.kernel.org/r/20210326151259.817438847@infradead.org [bwh: Backported to 5.10: drop changes in create_mcount_loc_sections()] Signed-off-by: Ben Hutchings <ben@decadent.org.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
c9049cf480
commit
fcdb7926d3
@@ -262,32 +262,6 @@ struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, uns
|
||||
return find_reloc_by_dest_range(elf, sec, offset, 1);
|
||||
}
|
||||
|
||||
void insn_to_reloc_sym_addend(struct section *sec, unsigned long offset,
|
||||
struct reloc *reloc)
|
||||
{
|
||||
if (sec->sym) {
|
||||
reloc->sym = sec->sym;
|
||||
reloc->addend = offset;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The Clang assembler strips section symbols, so we have to reference
|
||||
* the function symbol instead:
|
||||
*/
|
||||
reloc->sym = find_symbol_containing(sec, offset);
|
||||
if (!reloc->sym) {
|
||||
/*
|
||||
* Hack alert. This happens when we need to reference the NOP
|
||||
* pad insn immediately after the function.
|
||||
*/
|
||||
reloc->sym = find_symbol_containing(sec, offset - 1);
|
||||
}
|
||||
|
||||
if (reloc->sym)
|
||||
reloc->addend = offset - reloc->sym->offset;
|
||||
}
|
||||
|
||||
static int read_sections(struct elf *elf)
|
||||
{
|
||||
Elf_Scn *s = NULL;
|
||||
@@ -524,14 +498,66 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void elf_add_reloc(struct elf *elf, struct reloc *reloc)
|
||||
int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset,
|
||||
unsigned int type, struct symbol *sym, int addend)
|
||||
{
|
||||
struct section *sec = reloc->sec;
|
||||
struct reloc *reloc;
|
||||
|
||||
list_add_tail(&reloc->list, &sec->reloc_list);
|
||||
reloc = malloc(sizeof(*reloc));
|
||||
if (!reloc) {
|
||||
perror("malloc");
|
||||
return -1;
|
||||
}
|
||||
memset(reloc, 0, sizeof(*reloc));
|
||||
|
||||
reloc->sec = sec->reloc;
|
||||
reloc->offset = offset;
|
||||
reloc->type = type;
|
||||
reloc->sym = sym;
|
||||
reloc->addend = addend;
|
||||
|
||||
list_add_tail(&reloc->list, &sec->reloc->reloc_list);
|
||||
elf_hash_add(elf->reloc_hash, &reloc->hash, reloc_hash(reloc));
|
||||
|
||||
sec->changed = true;
|
||||
sec->reloc->changed = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int elf_add_reloc_to_insn(struct elf *elf, struct section *sec,
|
||||
unsigned long offset, unsigned int type,
|
||||
struct section *insn_sec, unsigned long insn_off)
|
||||
{
|
||||
struct symbol *sym;
|
||||
int addend;
|
||||
|
||||
if (insn_sec->sym) {
|
||||
sym = insn_sec->sym;
|
||||
addend = insn_off;
|
||||
|
||||
} else {
|
||||
/*
|
||||
* The Clang assembler strips section symbols, so we have to
|
||||
* reference the function symbol instead:
|
||||
*/
|
||||
sym = find_symbol_containing(insn_sec, insn_off);
|
||||
if (!sym) {
|
||||
/*
|
||||
* Hack alert. This happens when we need to reference
|
||||
* the NOP pad insn immediately after the function.
|
||||
*/
|
||||
sym = find_symbol_containing(insn_sec, insn_off - 1);
|
||||
}
|
||||
|
||||
if (!sym) {
|
||||
WARN("can't find symbol containing %s+0x%lx", insn_sec->name, insn_off);
|
||||
return -1;
|
||||
}
|
||||
|
||||
addend = insn_off - sym->offset;
|
||||
}
|
||||
|
||||
return elf_add_reloc(elf, sec, offset, type, sym, addend);
|
||||
}
|
||||
|
||||
static int read_rel_reloc(struct section *sec, int i, struct reloc *reloc, unsigned int *symndx)
|
||||
|
Reference in New Issue
Block a user