aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2021-02-09 21:41:13 +0100
committerPeter Zijlstra <peterz@infradead.org>2021-02-09 22:15:16 +0100
commitd8eb1dc19608bc9f50af54f22c638cdc55708bca (patch)
tree9c5b8a572bb66fe4810c9489268366b92a073390
parente8976d8c3e02eacb8e2fe7d4274f5dd72fb5c1c1 (diff)
downloadlinux-d8eb1dc19608bc9f50af54f22c638cdc55708bca.tar.gz
objtool,x86: Rewrite LEAVE
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
-rw-r--r--tools/objtool/arch/x86/decode.c14
-rw-r--r--tools/objtool/check.c22
-rw-r--r--tools/objtool/include/objtool/arch.h1
3 files changed, 12 insertions, 25 deletions
diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
index 61e61948012c3..dab087d7f67be 100644
--- a/tools/objtool/arch/x86/decode.c
+++ b/tools/objtool/arch/x86/decode.c
@@ -430,9 +430,17 @@ int arch_decode_instruction(const struct elf *elf, const struct section *sec,
* mov bp, sp
* pop bp
*/
- ADD_OP(op)
- op->dest.type = OP_DEST_LEAVE;
-
+ ADD_OP(op) {
+ op->src.type = OP_SRC_REG;
+ op->src.reg = CFI_BP;
+ op->dest.type = OP_DEST_REG;
+ op->dest.reg = CFI_SP;
+ }
+ ADD_OP(op) {
+ op->src.type = OP_SRC_POP;
+ op->dest.type = OP_DEST_REG;
+ op->dest.reg = CFI_BP;
+ }
break;
case 0xe3:
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 8e74210f42359..d6075c613bfa4 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -2101,7 +2101,7 @@ static int update_cfi_state(struct instruction *insn, struct cfi_state *cfi,
cfa->offset = 0;
cfi->drap_offset = -1;
- } else if (regs[op->dest.reg].offset == -cfi->stack_size) {
+ } else if (cfi->stack_size == -regs[op->dest.reg].offset) {
/* pop %reg */
restore_reg(cfi, op->dest.reg);
@@ -2242,26 +2242,6 @@ static int update_cfi_state(struct instruction *insn, struct cfi_state *cfi,
break;
- case OP_DEST_LEAVE:
- if ((!cfi->drap && cfa->base != CFI_BP) ||
- (cfi->drap && cfa->base != cfi->drap_reg)) {
- WARN_FUNC("leave instruction with modified stack frame",
- insn->sec, insn->offset);
- return -1;
- }
-
- /* leave (mov %rbp, %rsp; pop %rbp) */
-
- cfi->stack_size = -cfi->regs[CFI_BP].offset - 8;
- restore_reg(cfi, CFI_BP);
-
- if (!cfi->drap) {
- cfa->base = CFI_SP;
- cfa->offset -= 8;
- }
-
- break;
-
case OP_DEST_MEM:
if (op->src.type != OP_SRC_POP && op->src.type != OP_SRC_POPF) {
WARN_FUNC("unknown stack-related memory operation",
diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/objtool/arch.h
index 6ff0685f5cc5a..ff21f387712d3 100644
--- a/tools/objtool/include/objtool/arch.h
+++ b/tools/objtool/include/objtool/arch.h
@@ -35,7 +35,6 @@ enum op_dest_type {
OP_DEST_MEM,
OP_DEST_PUSH,
OP_DEST_PUSHF,
- OP_DEST_LEAVE,
};
struct op_dest {