x86: provide size for X86_OP_IMM operand. thank Gabriel Quadros for some suggestions

This commit is contained in:
Nguyen Anh Quynh 2014-06-25 22:03:18 +08:00
parent e1aba1703f
commit f1ec52628e
10 changed files with 42 additions and 15 deletions

View File

@ -14,6 +14,7 @@ void MCInst_Init(MCInst *inst)
{
inst->OpcodePub = 0;
inst->size = 0;
inst->has_imm = 0;
}
void MCInst_clear(MCInst *inst)

View File

@ -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);

View File

@ -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.

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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++;
}

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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");