Commit ffc7e74f authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar

objtool,x86: Rewrite LEAVE

Since we can now have multiple stack-ops per instruction, we don't
need to special case LEAVE and can simply emit the composite
operations.
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
Acked-by: default avatarJosh Poimboeuf <jpoimboe@redhat.com>
Tested-by: default avatarNick Desaulniers <ndesaulniers@google.com>
Link: https://lkml.kernel.org/r/20210211173627.253273977@infradead.org
parent 2ee0c363
...@@ -446,9 +446,17 @@ int arch_decode_instruction(const struct elf *elf, const struct section *sec, ...@@ -446,9 +446,17 @@ int arch_decode_instruction(const struct elf *elf, const struct section *sec,
* mov bp, sp * mov bp, sp
* pop bp * pop bp
*/ */
ADD_OP(op) ADD_OP(op) {
op->dest.type = OP_DEST_LEAVE; 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; break;
case 0xe3: case 0xe3:
......
...@@ -2020,7 +2020,7 @@ static int update_cfi_state(struct instruction *insn, ...@@ -2020,7 +2020,7 @@ static int update_cfi_state(struct instruction *insn,
} }
else if (op->src.reg == CFI_BP && op->dest.reg == CFI_SP && else if (op->src.reg == CFI_BP && op->dest.reg == CFI_SP &&
cfa->base == CFI_BP) { (cfa->base == CFI_BP || cfa->base == cfi->drap_reg)) {
/* /*
* mov %rbp, %rsp * mov %rbp, %rsp
...@@ -2217,7 +2217,7 @@ static int update_cfi_state(struct instruction *insn, ...@@ -2217,7 +2217,7 @@ static int update_cfi_state(struct instruction *insn,
cfa->offset = 0; cfa->offset = 0;
cfi->drap_offset = -1; 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 */ /* pop %reg */
restore_reg(cfi, op->dest.reg); restore_reg(cfi, op->dest.reg);
...@@ -2358,26 +2358,6 @@ static int update_cfi_state(struct instruction *insn, ...@@ -2358,26 +2358,6 @@ static int update_cfi_state(struct instruction *insn,
break; 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: case OP_DEST_MEM:
if (op->src.type != OP_SRC_POP && op->src.type != OP_SRC_POPF) { if (op->src.type != OP_SRC_POP && op->src.type != OP_SRC_POPF) {
WARN_FUNC("unknown stack-related memory operation", WARN_FUNC("unknown stack-related memory operation",
......
...@@ -35,7 +35,6 @@ enum op_dest_type { ...@@ -35,7 +35,6 @@ enum op_dest_type {
OP_DEST_MEM, OP_DEST_MEM,
OP_DEST_PUSH, OP_DEST_PUSH,
OP_DEST_PUSHF, OP_DEST_PUSHF,
OP_DEST_LEAVE,
}; };
struct op_dest { struct op_dest {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment