]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
objtool: Cache instruction relocs
authorPeter Zijlstra <peterz@infradead.org>
Fri, 26 Mar 2021 15:12:13 +0000 (16:12 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Jul 2022 09:26:17 +0000 (11:26 +0200)
commit 7bd2a600f3e9d27286bbf23c83d599e9cc7cf245 upstream.

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
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
tools/objtool/check.c
tools/objtool/check.h

index f87a8782c8173660075840828234cdffa39ff0ca..6d62ad940fce18a6c9115b8038f8ebe6384ffc23 100644 (file)
@@ -754,6 +754,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.
  */
@@ -768,8 +787,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);
@@ -901,8 +919,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);
@@ -1085,8 +1102,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)) {
 
index e0ae2fc13e67f12440328f7f9f3716616dda08b6..ca3259eebac88102a6708ac4cc77c2fa4a1616e9 100644 (file)
@@ -55,6 +55,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;