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: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Acked-by: Josh Poimboeuf <jpoimboe@redhat.com> Tested-by: Nick Desaulniers <ndesaulniers@google.com> Link: https://lkml.kernel.org/r/20210211173627.253273977@infradead.org
This commit is contained in:
Родитель
2ee0c36349
Коммит
ffc7e74f36
|
@ -446,9 +446,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:
|
||||
|
|
|
@ -2020,7 +2020,7 @@ static int update_cfi_state(struct instruction *insn,
|
|||
}
|
||||
|
||||
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
|
||||
|
@ -2217,7 +2217,7 @@ static int update_cfi_state(struct instruction *insn,
|
|||
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);
|
||||
|
@ -2358,26 +2358,6 @@ static int update_cfi_state(struct instruction *insn,
|
|||
|
||||
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",
|
||||
|
|
|
@ -35,7 +35,6 @@ enum op_dest_type {
|
|||
OP_DEST_MEM,
|
||||
OP_DEST_PUSH,
|
||||
OP_DEST_PUSHF,
|
||||
OP_DEST_LEAVE,
|
||||
};
|
||||
|
||||
struct op_dest {
|
||||
|
|
Загрузка…
Ссылка в новой задаче