mirror of
https://github.com/capstone-engine/capstone.git
synced 2025-02-01 11:36:36 +00:00
x86: provide size for X86_OP_IMM operand. thank Gabriel Quadros for some suggestions
This commit is contained in:
parent
e1aba1703f
commit
f1ec52628e
1
MCInst.c
1
MCInst.c
@ -14,6 +14,7 @@ void MCInst_Init(MCInst *inst)
|
||||
{
|
||||
inst->OpcodePub = 0;
|
||||
inst->size = 0;
|
||||
inst->has_imm = 0;
|
||||
}
|
||||
|
||||
void MCInst_clear(MCInst *inst)
|
||||
|
6
MCInst.h
6
MCInst.h
@ -90,10 +90,11 @@ MCOperand *MCOperand_CreateImm1(MCInst *inst, int64_t Val);
|
||||
/// MCInst - Instances of this class represent a single low-level machine
|
||||
/// instruction.
|
||||
struct MCInst {
|
||||
unsigned Opcode;
|
||||
MCOperand Operands[48];
|
||||
unsigned OpcodePub;
|
||||
unsigned size; // number of operands
|
||||
int has_imm; // indicate this instruction has an X86_OP_IMM operand - used for ATT syntax
|
||||
unsigned Opcode;
|
||||
MCOperand Operands[48];
|
||||
cs_insn *flat_insn; // insn to be exposed to public
|
||||
uint64_t address; // address of this insn
|
||||
cs_struct *csh; // save the main csh
|
||||
@ -103,6 +104,7 @@ struct MCInst {
|
||||
// A prefix byte gets value 0 when irrelevant.
|
||||
// This is copied from cs_x86 struct
|
||||
uint8_t x86_prefix[4];
|
||||
uint8_t imm_size; // immediate size for X86_OP_IMM operand
|
||||
};
|
||||
|
||||
void MCInst_Init(MCInst *inst);
|
||||
|
@ -456,6 +456,7 @@ static void printPCRelImm(MCInst *MI, unsigned OpNo, SStream *O)
|
||||
}
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
|
||||
MI->has_imm = 1;
|
||||
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm;
|
||||
MI->flat_insn->detail->x86.op_count++;
|
||||
}
|
||||
@ -498,6 +499,7 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
|
||||
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = imm;
|
||||
} else {
|
||||
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
|
||||
MI->has_imm = 1;
|
||||
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm;
|
||||
MI->flat_insn->detail->x86.op_count++;
|
||||
}
|
||||
@ -596,6 +598,7 @@ void X86_ATT_printInst(MCInst *MI, SStream *OS, void *info)
|
||||
{
|
||||
char *mnem;
|
||||
x86_reg reg;
|
||||
int i;
|
||||
|
||||
// Try to print any aliases first.
|
||||
mnem = printAliasInstr(MI, OS, NULL);
|
||||
@ -604,6 +607,17 @@ void X86_ATT_printInst(MCInst *MI, SStream *OS, void *info)
|
||||
else
|
||||
printInstruction(MI, OS, NULL);
|
||||
|
||||
if (MI->has_imm) {
|
||||
// if op_count > 1, then this operand's size is taken from the destination op
|
||||
if (MI->flat_insn->detail->x86.op_count > 1) {
|
||||
for (i = 0; i < MI->flat_insn->detail->x86.op_count; i++) {
|
||||
if (MI->flat_insn->detail->x86.operands[i].type == X86_OP_IMM)
|
||||
MI->flat_insn->detail->x86.operands[i].size = MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count - 1].size;
|
||||
}
|
||||
} else
|
||||
MI->flat_insn->detail->x86.operands[0].size = MI->imm_size;
|
||||
}
|
||||
|
||||
if (MI->csh->detail) {
|
||||
// special instruction needs to supply register op
|
||||
// first op can be embedded in the asm by llvm.
|
||||
|
@ -746,10 +746,11 @@ bool X86_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
||||
|
||||
result = (!translateInstruction(instr, &insn)) ? true : false;
|
||||
if (result) {
|
||||
if (handle->detail)
|
||||
if (handle->detail) {
|
||||
update_pub_insn(instr->flat_insn, &insn, instr->x86_prefix);
|
||||
else {
|
||||
// copy all prefixes
|
||||
instr->imm_size = insn.immSize;
|
||||
} else {
|
||||
// still copy all prefixes
|
||||
instr->x86_prefix[0] = insn.prefix0;
|
||||
instr->x86_prefix[1] = insn.prefix1;
|
||||
instr->x86_prefix[2] = insn.prefix2;
|
||||
|
@ -714,27 +714,32 @@ static int readPrefixes(struct InternalInstruction* insn)
|
||||
insn->addressSize = (hasAdSize ? 4 : 2);
|
||||
insn->displacementSize = (hasAdSize ? 4 : 2);
|
||||
insn->immediateSize = (hasOpSize ? 4 : 2);
|
||||
insn->immSize = (hasOpSize ? 4 : 2);
|
||||
} else if (insn->mode == MODE_32BIT) {
|
||||
insn->registerSize = (hasOpSize ? 2 : 4);
|
||||
insn->addressSize = (hasAdSize ? 2 : 4);
|
||||
insn->displacementSize = (hasAdSize ? 2 : 4);
|
||||
insn->immediateSize = (hasOpSize ? 2 : 4);
|
||||
insn->immSize = (hasOpSize ? 2 : 4);
|
||||
} else if (insn->mode == MODE_64BIT) {
|
||||
if (insn->rexPrefix && wFromREX(insn->rexPrefix)) {
|
||||
insn->registerSize = 8;
|
||||
insn->addressSize = (hasAdSize ? 4 : 8);
|
||||
insn->displacementSize = 4;
|
||||
insn->immediateSize = 4;
|
||||
insn->immSize = 4;
|
||||
} else if (insn->rexPrefix) {
|
||||
insn->registerSize = (hasOpSize ? 2 : 4);
|
||||
insn->addressSize = (hasAdSize ? 4 : 8);
|
||||
insn->displacementSize = (hasOpSize ? 2 : 4);
|
||||
insn->immediateSize = (hasOpSize ? 2 : 4);
|
||||
insn->immSize = (hasOpSize ? 2 : 4);
|
||||
} else {
|
||||
insn->registerSize = (hasOpSize ? 2 : 4);
|
||||
insn->addressSize = (hasAdSize ? 4 : 8);
|
||||
insn->displacementSize = (hasOpSize ? 2 : 4);
|
||||
insn->immediateSize = (hasOpSize ? 2 : 4);
|
||||
insn->immSize = (hasOpSize ? 4 : 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -621,6 +621,8 @@ typedef struct InternalInstruction {
|
||||
uint8_t displacementSize;
|
||||
uint8_t immediateSize;
|
||||
|
||||
uint8_t immSize; // immediate size for X86_OP_IMM operand
|
||||
|
||||
/* Offsets from the start of the instruction to the pieces of data, which is
|
||||
needed to find relocation entries for adding symbolic operands */
|
||||
uint8_t displacementOffset;
|
||||
|
@ -515,6 +515,11 @@ static void printPCRelImm(MCInst *MI, unsigned OpNo, SStream *O)
|
||||
}
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
|
||||
// if op_count > 0, then this operand's size is taken from the destination op
|
||||
if (MI->flat_insn->detail->x86.op_count > 0)
|
||||
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->flat_insn->detail->x86.operands[0].size;
|
||||
else
|
||||
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->imm_size;
|
||||
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm;
|
||||
MI->flat_insn->detail->x86.op_count++;
|
||||
}
|
||||
@ -556,6 +561,10 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
|
||||
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = imm;
|
||||
} else {
|
||||
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
|
||||
if (MI->flat_insn->detail->x86.op_count > 0)
|
||||
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->flat_insn->detail->x86.operands[0].size;
|
||||
else
|
||||
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->imm_size;
|
||||
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm;
|
||||
MI->flat_insn->detail->x86.op_count++;
|
||||
}
|
||||
|
@ -115,10 +115,7 @@ public class TestX86 {
|
||||
System.out.printf("\t\toperands[%d].avx_bcast: %d\n", c, i.avx_bcast);
|
||||
}
|
||||
|
||||
// Operand size is irrlevant for X86_OP_IMM operand
|
||||
if (i.type != X86_OP_IMM) {
|
||||
System.out.printf("\t\toperands[%d].size: %d\n", c, i.size);
|
||||
}
|
||||
System.out.printf("\t\toperands[%d].size: %d\n", c, i.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,9 +103,7 @@ def print_insn_detail(mode, insn):
|
||||
if i.avx_bcast != X86_AVX_BCAST_INVALID:
|
||||
print("\t\toperands[%u].avx_bcast: %u" % (c, i.avx_bcast))
|
||||
|
||||
# Operand size is irrlevant for X86_OP_IMM operand
|
||||
if i.type != X86_OP_IMM:
|
||||
print("\t\toperands[%u].size: %u" % (c, i.size))
|
||||
print("\t\toperands[%u].size: %u" % (c, i.size))
|
||||
|
||||
|
||||
# ## Test class Cs
|
||||
|
@ -113,9 +113,7 @@ static void print_insn_detail(csh ud, cs_mode mode, cs_insn *ins)
|
||||
if (op->avx_bcast != X86_AVX_BCAST_INVALID)
|
||||
printf("\t\toperands[%u].avx_bcast: %u\n", i, op->avx_bcast);
|
||||
|
||||
// the size is irrelevant for X86_OP_IMM
|
||||
if (op->type != X86_OP_IMM)
|
||||
printf("\t\toperands[%u].size: %u\n", i, op->size);
|
||||
printf("\t\toperands[%u].size: %u\n", i, op->size);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
Loading…
x
Reference in New Issue
Block a user