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:
Peter Zijlstra
2021-03-26 16:12:07 +01:00
committed by Greg Kroah-Hartman
parent c9049cf480
commit fcdb7926d3
4 changed files with 79 additions and 90 deletions

View File

@@ -81,37 +81,20 @@ static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi)
}
static int write_orc_entry(struct elf *elf, struct section *orc_sec,
struct section *ip_rsec, unsigned int idx,
struct section *ip_sec, unsigned int idx,
struct section *insn_sec, unsigned long insn_off,
struct orc_entry *o)
{
struct orc_entry *orc;
struct reloc *reloc;
/* populate ORC data */
orc = (struct orc_entry *)orc_sec->data->d_buf + idx;
memcpy(orc, o, sizeof(*orc));
/* populate reloc for ip */
reloc = malloc(sizeof(*reloc));
if (!reloc) {
perror("malloc");
if (elf_add_reloc_to_insn(elf, ip_sec, idx * sizeof(int), R_X86_64_PC32,
insn_sec, insn_off))
return -1;
}
memset(reloc, 0, sizeof(*reloc));
insn_to_reloc_sym_addend(insn_sec, insn_off, reloc);
if (!reloc->sym) {
WARN("missing symbol for insn at offset 0x%lx",
insn_off);
return -1;
}
reloc->type = R_X86_64_PC32;
reloc->offset = idx * sizeof(int);
reloc->sec = ip_rsec;
elf_add_reloc(elf, reloc);
return 0;
}
@@ -150,7 +133,7 @@ static unsigned long alt_group_len(struct alt_group *alt_group)
int orc_create(struct objtool_file *file)
{
struct section *sec, *ip_rsec, *orc_sec;
struct section *sec, *orc_sec;
unsigned int nr = 0, idx = 0;
struct orc_list_entry *entry;
struct list_head orc_list;
@@ -239,13 +222,12 @@ int orc_create(struct objtool_file *file)
sec = elf_create_section(file->elf, ".orc_unwind_ip", 0, sizeof(int), nr);
if (!sec)
return -1;
ip_rsec = elf_create_reloc_section(file->elf, sec, SHT_RELA);
if (!ip_rsec)
if (!elf_create_reloc_section(file->elf, sec, SHT_RELA))
return -1;
/* Write ORC entries to sections: */
list_for_each_entry(entry, &orc_list, list) {
if (write_orc_entry(file->elf, orc_sec, ip_rsec, idx++,
if (write_orc_entry(file->elf, orc_sec, sec, idx++,
entry->insn_sec, entry->insn_off,
&entry->orc))
return -1;