From 65ea47dcf4f936987a5fbf839c97acea00f4f196 Mon Sep 17 00:00:00 2001 From: Julien Thierry Date: Fri, 27 Mar 2020 15:28:47 +0000 Subject: objtool: Support multiple stack_op per instruction Instruction sets can include more or less complex operations which might not fit the currently defined set of stack_ops. Combining more than one stack_op provides more flexibility to describe the behaviour of an instruction. This also reduces the need to define new stack_ops specific to a single instruction set. Allow instruction decoders to generate multiple stack_op per instruction. Signed-off-by: Julien Thierry Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Miroslav Benes Reviewed-by: Alexandre Chartre Acked-by: Josh Poimboeuf Link: https://lkml.kernel.org/r/20200327152847.15294-11-jthierry@redhat.com Signed-off-by: Ingo Molnar --- tools/objtool/arch/x86/decode.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'tools/objtool/arch') diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c index 7ce8650cf085..199b4084a13c 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -80,13 +80,15 @@ unsigned long arch_jump_destination(struct instruction *insn) int arch_decode_instruction(struct elf *elf, struct section *sec, unsigned long offset, unsigned int maxlen, unsigned int *len, enum insn_type *type, - unsigned long *immediate, struct stack_op *op) + unsigned long *immediate, + struct list_head *ops_list) { struct insn insn; int x86_64, sign; unsigned char op1, op2, rex = 0, rex_b = 0, rex_r = 0, rex_w = 0, rex_x = 0, modrm = 0, modrm_mod = 0, modrm_rm = 0, modrm_reg = 0, sib = 0; + struct stack_op *op; x86_64 = is_x86_64(elf); if (x86_64 == -1) @@ -127,6 +129,10 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, if (insn.sib.nbytes) sib = insn.sib.bytes[0]; + op = calloc(1, sizeof(*op)); + if (!op) + return -1; + switch (op1) { case 0x1: @@ -488,6 +494,11 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, *immediate = insn.immediate.nbytes ? insn.immediate.value : 0; + if (*type == INSN_STACK) + list_add_tail(&op->list, ops_list); + else + free(op); + return 0; } -- cgit v1.2.3