Messages in this thread Patch in this message | | | From | Thomas Gleixner <> | Subject | [patch 06/38] objtool: Allow GS relative relocs | Date | Sun, 17 Jul 2022 01:17:19 +0200 (CEST) |
| |
From: Peter Zijlstra <peterz@infradead.org>
Objtool doesn't currently much like per-cpu usage in alternatives:
arch/x86/entry/entry_64.o: warning: objtool: .altinstr_replacement+0xf: unsupported relocation in alternatives section f: 65 c7 04 25 00 00 00 00 00 00 00 80 movl $0x80000000,%gs:0x0 13: R_X86_64_32S __x86_call_depth
Allow this.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- tools/objtool/arch/x86/decode.c | 26 +++++++++++++++++++++----- tools/objtool/check.c | 6 ++---- tools/objtool/include/objtool/arch.h | 4 +--- tools/objtool/include/objtool/check.h | 20 +++++++++++--------- 4 files changed, 35 insertions(+), 21 deletions(-)
--- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -103,24 +103,37 @@ unsigned long arch_jump_destination(stru #define rm_is_mem(reg) (mod_is_mem() && !is_RIP() && rm_is(reg)) #define rm_is_reg(reg) (mod_is_reg() && modrm_rm == (reg)) -static bool has_notrack_prefix(struct insn *insn) +static bool has_prefix(struct insn *insn, u8 prefix) { int i; for (i = 0; i < insn->prefixes.nbytes; i++) { - if (insn->prefixes.bytes[i] == 0x3e) + if (insn->prefixes.bytes[i] == prefix) return true; } return false; } +static bool has_notrack_prefix(struct insn *insn) +{ + return has_prefix(insn, 0x3e); +} + +static bool has_gs_prefix(struct insn *insn) +{ + return has_prefix(insn, 0x65); +} + int arch_decode_instruction(struct objtool_file *file, const struct section *sec, unsigned long offset, unsigned int maxlen, - unsigned int *len, enum insn_type *type, - unsigned long *immediate, - struct list_head *ops_list) + struct instruction *instruction) { + struct list_head *ops_list = &instruction->stack_ops; + unsigned long *immediate = &instruction->immediate; + enum insn_type *type = &instruction->type; + unsigned int *len = &instruction->len; + const struct elf *elf = file->elf; struct insn insn; int x86_64, ret; @@ -149,6 +162,9 @@ int arch_decode_instruction(struct objto if (insn.vex_prefix.nbytes) return 0; + if (has_gs_prefix(&insn)) + instruction->alt_reloc_safe = 1; + prefix = insn.prefixes.bytes[0]; op1 = insn.opcode.bytes[0]; --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -396,9 +396,7 @@ static int decode_instructions(struct ob ret = arch_decode_instruction(file, sec, offset, sec->sh.sh_size - offset, - &insn->len, &insn->type, - &insn->immediate, - &insn->stack_ops); + insn); if (ret) goto err; @@ -1620,7 +1618,7 @@ static int handle_group_alt(struct objto * accordingly. */ alt_reloc = insn_reloc(file, insn); - if (alt_reloc && + if (alt_reloc && !insn->alt_reloc_safe && !arch_support_alt_relocation(special_alt, insn, alt_reloc)) { WARN_FUNC("unsupported relocation in alternatives section", --- a/tools/objtool/include/objtool/arch.h +++ b/tools/objtool/include/objtool/arch.h @@ -73,9 +73,7 @@ void arch_initial_func_cfi_state(struct int arch_decode_instruction(struct objtool_file *file, const struct section *sec, unsigned long offset, unsigned int maxlen, - unsigned int *len, enum insn_type *type, - unsigned long *immediate, - struct list_head *ops_list); + struct instruction *insn); bool arch_callee_saved_reg(unsigned char reg); --- a/tools/objtool/include/objtool/check.h +++ b/tools/objtool/include/objtool/check.h @@ -47,15 +47,17 @@ struct instruction { unsigned long immediate; u16 dead_end : 1, - ignore : 1, - ignore_alts : 1, - hint : 1, - save : 1, - restore : 1, - retpoline_safe : 1, - noendbr : 1, - entry : 1; - /* 7 bit hole */ + ignore : 1, + ignore_alts : 1, + hint : 1, + save : 1, + restore : 1, + retpoline_safe : 1, + noendbr : 1, + entry : 1, + alt_reloc_safe : 1; + + /* 6 bit hole */ s8 instr; u8 visited;
| |