Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

authored by

Peter Zijlstra and committed by
Ingo Molnar
7bd2a600 43d5430a

+23 -6
+22 -6
tools/objtool/check.c
··· 797 797 return false; 798 798 } 799 799 800 + #define NEGATIVE_RELOC ((void *)-1L) 801 + 802 + static struct reloc *insn_reloc(struct objtool_file *file, struct instruction *insn) 803 + { 804 + if (insn->reloc == NEGATIVE_RELOC) 805 + return NULL; 806 + 807 + if (!insn->reloc) { 808 + insn->reloc = find_reloc_by_dest_range(file->elf, insn->sec, 809 + insn->offset, insn->len); 810 + if (!insn->reloc) { 811 + insn->reloc = NEGATIVE_RELOC; 812 + return NULL; 813 + } 814 + } 815 + 816 + return insn->reloc; 817 + } 818 + 800 819 /* 801 820 * Find the destination instructions for all jumps. 802 821 */ ··· 830 811 if (!is_static_jump(insn)) 831 812 continue; 832 813 833 - reloc = find_reloc_by_dest_range(file->elf, insn->sec, 834 - insn->offset, insn->len); 814 + reloc = insn_reloc(file, insn); 835 815 if (!reloc) { 836 816 dest_sec = insn->sec; 837 817 dest_off = arch_jump_destination(insn); ··· 962 944 if (insn->type != INSN_CALL) 963 945 continue; 964 946 965 - reloc = find_reloc_by_dest_range(file->elf, insn->sec, 966 - insn->offset, insn->len); 947 + reloc = insn_reloc(file, insn); 967 948 if (!reloc) { 968 949 dest_off = arch_jump_destination(insn); 969 950 insn->call_dest = find_call_destination(insn->sec, dest_off); ··· 1161 1144 * alternatives code can adjust the relative offsets 1162 1145 * accordingly. 1163 1146 */ 1164 - alt_reloc = find_reloc_by_dest_range(file->elf, insn->sec, 1165 - insn->offset, insn->len); 1147 + alt_reloc = insn_reloc(file, insn); 1166 1148 if (alt_reloc && 1167 1149 !arch_support_alt_relocation(special_alt, insn, alt_reloc)) { 1168 1150
+1
tools/objtool/include/objtool/check.h
··· 56 56 struct instruction *jump_dest; 57 57 struct instruction *first_jump_src; 58 58 struct reloc *jump_table; 59 + struct reloc *reloc; 59 60 struct list_head alts; 60 61 struct symbol *func; 61 62 struct list_head stack_ops;