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 <jthierry@redhat.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Miroslav Benes <mbenes@suse.cz> Reviewed-by: Alexandre Chartre <alexandre.chartre@oracle.com> Acked-by: Josh Poimboeuf <jpoimboe@redhat.com> Link: https://lkml.kernel.org/r/20200327152847.15294-11-jthierry@redhat.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
committed by
Ingo Molnar
parent
1ee444700e
commit
65ea47dcf4
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user