diff options
author | Peter Zijlstra <peterz@infradead.org> | 2021-03-26 16:12:13 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2021-04-02 12:46:15 +0200 |
commit | 7bd2a600f3e9d27286bbf23c83d599e9cc7cf245 (patch) | |
tree | 61dc66964ab8f58a54f6d2988bd9f346ee12a0b2 | |
parent | 43d5430ad74ef5156353af7aec352426ec7a8e57 (diff) | |
download | linux-7bd2a600f3e9d27286bbf23c83d599e9cc7cf245.tar.bz2 |
objtool: Cache instruction relocs
Track the reloc of instructions in the new instruction->reloc field
to avoid having to look them up again later.
( Technically x86 instructions can have two relocations, but not jumps
and calls, for which we're using this. )
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/20210326151300.195441549@infradead.org
-rw-r--r-- | tools/objtool/check.c | 28 | ||||
-rw-r--r-- | tools/objtool/include/objtool/check.h | 1 |
2 files changed, 23 insertions, 6 deletions
diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 77074db1fcda..1f4154f9b04b 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -797,6 +797,25 @@ __weak bool arch_is_retpoline(struct symbol *sym) return false; } +#define NEGATIVE_RELOC ((void *)-1L) + +static struct reloc *insn_reloc(struct objtool_file *file, struct instruction *insn) +{ + if (insn->reloc == NEGATIVE_RELOC) + return NULL; + + if (!insn->reloc) { + insn->reloc = find_reloc_by_dest_range(file->elf, insn->sec, + insn->offset, insn->len); + if (!insn->reloc) { + insn->reloc = NEGATIVE_RELOC; + return NULL; + } + } + + return insn->reloc; +} + /* * Find the destination instructions for all jumps. */ @@ -811,8 +830,7 @@ static int add_jump_destinations(struct objtool_file *file) if (!is_static_jump(insn)) continue; - reloc = find_reloc_by_dest_range(file->elf, insn->sec, - insn->offset, insn->len); + reloc = insn_reloc(file, insn); if (!reloc) { dest_sec = insn->sec; dest_off = arch_jump_destination(insn); @@ -944,8 +962,7 @@ static int add_call_destinations(struct objtool_file *file) if (insn->type != INSN_CALL) continue; - reloc = find_reloc_by_dest_range(file->elf, insn->sec, - insn->offset, insn->len); + reloc = insn_reloc(file, insn); if (!reloc) { dest_off = arch_jump_destination(insn); insn->call_dest = find_call_destination(insn->sec, dest_off); @@ -1144,8 +1161,7 @@ static int handle_group_alt(struct objtool_file *file, * alternatives code can adjust the relative offsets * accordingly. */ - alt_reloc = find_reloc_by_dest_range(file->elf, insn->sec, - insn->offset, insn->len); + alt_reloc = insn_reloc(file, insn); if (alt_reloc && !arch_support_alt_relocation(special_alt, insn, alt_reloc)) { diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/objtool/check.h index e5528ce3961a..56d50bc50c10 100644 --- a/tools/objtool/include/objtool/check.h +++ b/tools/objtool/include/objtool/check.h @@ -56,6 +56,7 @@ struct instruction { struct instruction *jump_dest; struct instruction *first_jump_src; struct reloc *jump_table; + struct reloc *reloc; struct list_head alts; struct symbol *func; struct list_head stack_ops; |