support new syntax CS_OPT_SYNTAX_MASM for X86

This commit is contained in:
Nguyen Anh Quynh 2015-08-09 10:34:19 -07:00
parent a973ef618e
commit 62918abb60
5 changed files with 121 additions and 71 deletions

View File

@ -267,6 +267,86 @@ static void printRegName(SStream *OS, unsigned RegNo)
SStream_concat0(OS, getRegisterName(RegNo));
}
// for MASM syntax, 0x123 = 123h, 0xA123 = 0A123h
// this function tell us if we need to have prefix 0 in front of a number
static bool need_zero_prefix(uint64_t imm)
{
// find the first hex letter representing imm
while(imm > 0x10)
imm >>= 4;
if (imm < 0xa)
return false;
else // this need 0 prefix
return true;
}
static void printImm(int syntax, SStream *O, int64_t imm, bool positive)
{
if (positive) {
// always print this number in positive form
if (syntax == CS_OPT_SYNTAX_MASM) {
if (imm < 0) {
if (need_zero_prefix(imm))
SStream_concat(O, "0%"PRIx64"h", imm);
else
SStream_concat(O, "%"PRIx64"h", imm);
} else {
if (imm > HEX_THRESHOLD) {
if (need_zero_prefix(imm))
SStream_concat(O, "0%"PRIx64"h", imm);
else
SStream_concat(O, "%"PRIx64"h", imm);
} else
SStream_concat(O, "%"PRIu64, imm);
}
} else { // Intel syntax
if (imm < 0) {
SStream_concat(O, "0x%"PRIx64, imm);
} else {
if (imm > HEX_THRESHOLD)
SStream_concat(O, "0x%"PRIx64, imm);
else
SStream_concat(O, "%"PRIu64, imm);
}
}
} else {
if (syntax == CS_OPT_SYNTAX_MASM) {
if (imm < 0) {
if (imm < -HEX_THRESHOLD) {
if (need_zero_prefix(imm))
SStream_concat(O, "-0%"PRIx64"h", -imm);
else
SStream_concat(O, "-%"PRIx64"h", -imm);
} else
SStream_concat(O, "-%"PRIu64, -imm);
} else {
if (imm > HEX_THRESHOLD) {
if (need_zero_prefix(imm))
SStream_concat(O, "0%"PRIx64"h", imm);
else
SStream_concat(O, "%"PRIx64"h", imm);
} else
SStream_concat(O, "%"PRIu64, imm);
}
} else { // Intel syntax
if (imm < 0) {
if (imm < -HEX_THRESHOLD)
SStream_concat(O, "-0x%"PRIx64, -imm);
else
SStream_concat(O, "-%"PRIu64, -imm);
} else {
if (imm > HEX_THRESHOLD)
SStream_concat(O, "0x%"PRIx64, imm);
else
SStream_concat(O, "%"PRIu64, imm);
}
}
}
}
// local printOperand, without updating public operands
static void _printOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
@ -275,18 +355,7 @@ static void _printOperand(MCInst *MI, unsigned OpNo, SStream *O)
printRegName(O, MCOperand_getReg(Op));
} else if (MCOperand_isImm(Op)) {
int64_t imm = MCOperand_getImm(Op);
if (imm < 0) {
if (imm < -HEX_THRESHOLD)
SStream_concat(O, "-0x%"PRIx64, -imm);
else
SStream_concat(O, "-%"PRIu64, -imm);
} else {
if (imm > HEX_THRESHOLD)
SStream_concat(O, "0x%"PRIx64, imm);
else
SStream_concat(O, "%"PRIu64, imm);
}
printImm(MI->csh->syntax, O, imm, false);
}
}
@ -488,14 +557,11 @@ static void printMemOffset(MCInst *MI, unsigned Op, SStream *O)
int64_t imm = MCOperand_getImm(DispSpec);
if (MI->csh->detail)
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = imm;
if (imm < 0) {
SStream_concat(O, "0x%"PRIx64, arch_masks[MI->csh->mode] & imm);
} else {
if (imm > HEX_THRESHOLD)
SStream_concat(O, "0x%"PRIx64, imm);
else
SStream_concat(O, "%"PRIu64, imm);
}
if (imm < 0)
printImm(MI->csh->syntax, O, arch_masks[MI->csh->mode] & imm, true);
else
printImm(MI->csh->syntax, O, imm, true);
}
SStream_concat0(O, "]");
@ -512,10 +578,7 @@ static void printU8Imm(MCInst *MI, unsigned Op, SStream *O)
{
uint8_t val = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0xff;
if (val > HEX_THRESHOLD)
SStream_concat(O, "0x%x", val);
else
SStream_concat(O, "%u", val);
printImm(MI->csh->syntax, O, val, true);
if (MI->csh->detail) {
#ifndef CAPSTONE_DIET
@ -631,18 +694,11 @@ static void printPCRelImm(MCInst *MI, unsigned OpNo, SStream *O)
imm = imm & 0xffffffff;
}
if (imm < 0) {
SStream_concat(O, "0x%"PRIx64, imm);
} else {
// handle 16bit segment bound
if (MI->csh->mode == CS_MODE_16)
imm = imm & 0xffff;
if (MI->csh->mode == CS_MODE_16)
imm = imm & 0xffff;
printImm(MI->csh->syntax, O, imm, true);
if (imm > HEX_THRESHOLD)
SStream_concat(O, "0x%"PRIx64, imm);
else
SStream_concat(O, "%"PRIu64, imm);
}
if (MI->csh->detail) {
#ifndef CAPSTONE_DIET
uint8_t access[6];
@ -708,27 +764,13 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
switch(MI->flat_insn->id) {
default:
if (imm >= 0) {
if (imm > HEX_THRESHOLD)
SStream_concat(O, "0x%"PRIx64, imm);
else
SStream_concat(O, "%"PRIu64, imm);
} else {
if (imm < -HEX_THRESHOLD)
SStream_concat(O, "-0x%"PRIx64, -imm);
else
SStream_concat(O, "-%"PRIu64, -imm);
}
printImm(MI->csh->syntax, O, imm, false);
break;
case X86_INS_INT:
// do not print number in negative form
imm = imm & 0xff;
if (imm >= 0 && imm <= HEX_THRESHOLD)
SStream_concat(O, "%u", imm);
else
SStream_concat(O, "0x%x", imm);
printImm(MI->csh->syntax, O, imm, true);
break;
case X86_INS_AND:
@ -736,20 +778,20 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
case X86_INS_XOR:
// do not print number in negative form
if (imm >= 0 && imm <= HEX_THRESHOLD)
SStream_concat(O, "%u", imm);
printImm(MI->csh->syntax, O, imm, true);
else {
imm = arch_masks[opsize? opsize : MI->imm_size] & imm;
SStream_concat(O, "0x%"PRIx64, imm);
printImm(MI->csh->syntax, O, imm, true);
}
break;
case X86_INS_RET:
// RET imm16
if (imm >= 0 && imm <= HEX_THRESHOLD)
SStream_concat(O, "%u", imm);
printImm(MI->csh->syntax, O, imm, true);
else {
imm = 0xffff & imm;
SStream_concat(O, "0x%x", 0xffff & imm);
printImm(MI->csh->syntax, O, imm, true);
}
break;
}
@ -843,25 +885,18 @@ static void printMemReference(MCInst *MI, unsigned Op, SStream *O)
if (DispVal) {
if (NeedPlus) {
if (DispVal < 0) {
if (DispVal < -HEX_THRESHOLD)
SStream_concat(O, " - 0x%"PRIx64, -DispVal);
else
SStream_concat(O, " - %"PRIu64, -DispVal);
SStream_concat0(O, " - ");
printImm(MI->csh->syntax, O, -DispVal, true);
} else {
if (DispVal > HEX_THRESHOLD)
SStream_concat(O, " + 0x%"PRIx64, DispVal);
else
SStream_concat(O, " + %"PRIu64, DispVal);
SStream_concat0(O, " + ");
printImm(MI->csh->syntax, O, DispVal, true);
}
} else {
// memory reference to an immediate address
if (DispVal < 0) {
SStream_concat(O, "0x%"PRIx64, arch_masks[MI->csh->mode] & DispVal);
printImm(MI->csh->syntax, O, arch_masks[MI->csh->mode] & DispVal, true);
} else {
if (DispVal > HEX_THRESHOLD)
SStream_concat(O, "0x%"PRIx64, DispVal);
else
SStream_concat(O, "%"PRIu64, DispVal);
printImm(MI->csh->syntax, O, DispVal, true);
}
}

View File

@ -3055,7 +3055,7 @@ void op_addImm(MCInst *MI, int v)
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = v;
// if op_count > 0, then this operand's size is taken from the destination op
if (MI->csh->syntax == CS_OPT_SYNTAX_INTEL) {
if (MI->csh->syntax != CS_OPT_SYNTAX_ATT) {
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

View File

@ -65,8 +65,13 @@ static cs_err option(cs_struct *handle, cs_opt_type type, size_t value)
case CS_OPT_SYNTAX_DEFAULT:
case CS_OPT_SYNTAX_INTEL:
handle->printer = X86_Intel_printInst;
handle->syntax = CS_OPT_SYNTAX_INTEL;
handle->printer = X86_Intel_printInst;
break;
case CS_OPT_SYNTAX_MASM:
handle->printer = X86_Intel_printInst;
handle->syntax = value;
break;
case CS_OPT_SYNTAX_ATT:

View File

@ -154,6 +154,7 @@ typedef enum cs_opt_value {
CS_OPT_SYNTAX_INTEL, // X86 Intel asm syntax - default on X86 (CS_OPT_SYNTAX).
CS_OPT_SYNTAX_ATT, // X86 ATT asm syntax (CS_OPT_SYNTAX).
CS_OPT_SYNTAX_NOREGNAME, // Prints register name with only number (CS_OPT_SYNTAX)
CS_OPT_SYNTAX_MASM, // X86 Intel Masm syntax (CS_OPT_SYNTAX).
} cs_opt_value;
//> Common instruction operand types - to be consistent across all architectures.

View File

@ -32,7 +32,7 @@ static void test()
{
#ifdef CAPSTONE_HAS_X86
#define X86_CODE16 "\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00"
#define X86_CODE32 "\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00"
#define X86_CODE32 "\xba\xcd\xab\x00\x00\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00"
//#define X86_CODE32 "\x0f\xa7\xc0" // xstorerng
#define X86_CODE64 "\x55\x48\x8b\x05\xb8\x13\x00\x00"
#endif
@ -106,6 +106,15 @@ static void test()
sizeof(X86_CODE32) - 1,
"X86 32 (Intel syntax)"
},
{
CS_ARCH_X86,
CS_MODE_32,
(unsigned char*)X86_CODE32,
sizeof(X86_CODE32) - 1,
"X86 32 (MASM syntax)",
CS_OPT_SYNTAX,
CS_OPT_SYNTAX_MASM,
},
{
CS_ARCH_X86,
CS_MODE_64,