add CS_OPT_UNSIGNED option to print immediate in unsigned form. only ARM is supported for now (issue #585)

This commit is contained in:
Nguyen Anh Quynh 2016-03-14 13:52:23 +08:00
parent 141804ab9a
commit a23f9d37ed
5 changed files with 50 additions and 79 deletions

View File

@ -34,6 +34,7 @@
#define GET_SUBTARGETINFO_ENUM
#include "ARMGenSubtargetInfo.inc"
static void printRegName(cs_struct *h, SStream *OS, unsigned RegNo);
// Autogenerated by tblgen.
@ -847,28 +848,14 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
imm += (int32_t)MI->address + 8;
}
if (imm >= 0) {
if (imm > HEX_THRESHOLD)
SStream_concat(O, "#0x%x", imm);
else
SStream_concat(O, "#%u", imm);
} else {
SStream_concat(O, "#0x%x", imm);
}
printUInt32Bang(O, imm);
} else {
switch(MI->flat_insn->id) {
default:
if (imm >= 0) {
if (imm > HEX_THRESHOLD)
SStream_concat(O, "#0x%x", imm);
else
SStream_concat(O, "#%u", imm);
} else {
if (imm < -HEX_THRESHOLD)
SStream_concat(O, "#-0x%x", -imm);
else
SStream_concat(O, "#-%u", -imm);
}
if (MI->csh->imm_unsigned)
printUInt32Bang(O, imm);
else
printInt32Bang(O, imm);
break;
case ARM_INS_AND:
case ARM_INS_ORR:
@ -876,10 +863,7 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
case ARM_INS_BIC:
case ARM_INS_MVN:
// do not print number in negative form
if (imm >= 0 && imm <= HEX_THRESHOLD)
SStream_concat(O, "#%u", imm);
else
SStream_concat(O, "#0x%x", imm);
printUInt32Bang(O, imm);
break;
}
}
@ -912,10 +896,7 @@ static void printThumbLdrLabelOperand(MCInst *MI, unsigned OpNum, SStream *O)
if (isSub) {
SStream_concat(O, "#-0x%x", -OffImm);
} else {
if (OffImm > HEX_THRESHOLD)
SStream_concat(O, "#0x%x", OffImm);
else
SStream_concat(O, "#%u", OffImm);
printUInt32Bang(O, OffImm);
}
SStream_concat0(O, "]");
@ -1386,10 +1367,7 @@ static void printBitfieldInvMaskImmOperand(MCInst *MI, unsigned OpNum, SStream *
int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb;
//assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
if (lsb > HEX_THRESHOLD)
SStream_concat(O, "#0x%x", lsb);
else
SStream_concat(O, "#%u", lsb);
printUInt32Bang(O, lsb);
if (width > HEX_THRESHOLD)
SStream_concat(O, ", #0x%x", width);
@ -1895,10 +1873,9 @@ static void printAdrLabelOperand(MCInst *MI, unsigned OpNum, SStream *O, unsigne
static void printThumbS4ImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
{
unsigned tmp = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum)) * 4;
if (tmp > HEX_THRESHOLD)
SStream_concat(O, "#0x%x", tmp);
else
SStream_concat(O, "#%u", tmp);
printUInt32Bang(O, tmp);
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
@ -1910,10 +1887,8 @@ static void printThumbSRImm(MCInst *MI, unsigned OpNum, SStream *O)
{
unsigned Imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
unsigned tmp = Imm == 0 ? 32 : Imm;
if (tmp > HEX_THRESHOLD)
SStream_concat(O, "#0x%x", tmp);
else
SStream_concat(O, "#%u", tmp);
printUInt32Bang(O, tmp);
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
@ -1988,10 +1963,7 @@ static void printThumbAddrModeImm5SOperand(MCInst *MI, unsigned Op, SStream *O,
if (ImmOffs) {
tmp = ImmOffs * Scale;
SStream_concat0(O, ", ");
if (tmp > HEX_THRESHOLD)
SStream_concat(O, "#0x%x", tmp);
else
SStream_concat(O, "#%u", tmp);
printUInt32Bang(O, tmp);
if (MI->csh->detail)
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = tmp;
}
@ -2184,10 +2156,7 @@ static void printT2AddrModeImm0_1020s4Operand(MCInst *MI, unsigned OpNum, SStrea
if (MCOperand_getImm(MO2)) {
SStream_concat0(O, ", ");
tmp = (unsigned int)MCOperand_getImm(MO2) * 4;
if (tmp > HEX_THRESHOLD)
SStream_concat(O, "#0x%x", tmp);
else
SStream_concat(O, "#%u", tmp);
printUInt32Bang(O, tmp);
if (MI->csh->detail)
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = tmp;
}
@ -2209,17 +2178,7 @@ static void printT2AddrModeImm8OffsetOperand(MCInst *MI,
MI->flat_insn->detail->arm.op_count++;
}
} else {
if (OffImm < 0) {
if (OffImm < -HEX_THRESHOLD)
SStream_concat(O, "#-0x%x", -OffImm);
else
SStream_concat(O, "#-%u", -OffImm);
} else {
if (OffImm > HEX_THRESHOLD)
SStream_concat(O, "#0x%x", OffImm);
else
SStream_concat(O, "#%u", OffImm);
}
printInt32Bang(O, OffImm);
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = OffImm;
@ -2245,17 +2204,7 @@ static void printT2AddrModeImm8s4OffsetOperand(MCInst *MI,
MI->flat_insn->detail->arm.op_count++;
}
} else {
if (OffImm < 0) {
if (OffImm < -HEX_THRESHOLD)
SStream_concat(O, "#-0x%x", -OffImm);
else
SStream_concat(O, "#-%u", -OffImm);
} else {
if (OffImm > HEX_THRESHOLD)
SStream_concat(O, "#0x%x", OffImm);
else
SStream_concat(O, "#%u", OffImm);
}
printInt32Bang(O, OffImm);
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = OffImm;
@ -2417,10 +2366,8 @@ static void printFBits16(MCInst *MI, unsigned OpNum, SStream *O)
unsigned tmp;
tmp = 16 - (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
if (tmp > HEX_THRESHOLD)
SStream_concat(O, "#0x%x", tmp);
else
SStream_concat(O, "#%u", tmp);
printUInt32Bang(O, tmp);
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
@ -2433,10 +2380,8 @@ static void printFBits32(MCInst *MI, unsigned OpNum, SStream *O)
unsigned tmp;
tmp = 32 - (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
if (tmp > HEX_THRESHOLD)
SStream_concat(O, "#0x%x", tmp);
else
SStream_concat(O, "#%u", tmp);
printUInt32Bang(O, tmp);
if (MI->csh->detail) {
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;

View File

@ -161,6 +161,7 @@ CS_OPT_MEM = 4 # Change engine's mode at run-time
CS_OPT_SKIPDATA = 5 # Skip data when disassembling
CS_OPT_SKIPDATA_SETUP = 6 # Setup user-defined function for SKIPDATA option
CS_OPT_MNEMONIC = 7 # Customize instruction mnemonic
CS_OPT_UNSIGNED = 8 # Print immediate in unsigned form
# Capstone option value
CS_OPT_OFF = 0 # Turn OFF an option - default option of CS_OPT_DETAIL
@ -771,6 +772,7 @@ class Cs(object):
self._syntax = None
self._detail = False # by default, do not produce instruction details
self._imm_unsigned = False # by default, print immediate operands as signed numbers
self._diet = cs_support(CS_SUPPORT_DIET)
self._x86reduce = cs_support(CS_SUPPORT_X86_REDUCE)
@ -900,6 +902,25 @@ class Cs(object):
self._detail = opt
# is detail mode enable?
@property
def imm_unsigned(self):
return self._imm_unsigned
# modify detail mode.
@imm_unsigned.setter
def imm_unsigned(self, opt): # opt is boolean type, so must be either 'True' or 'False'
if opt == False:
status = _cs.cs_option(self.csh, CS_OPT_UNSIGNED, CS_OPT_OFF)
else:
status = _cs.cs_option(self.csh, CS_OPT_UNSIGNED, CS_OPT_ON)
if status != CS_ERR_OK:
raise CsError(status)
# save detail
self._imm_unsigned = opt
# return disassembly mode of this engine.
@property
def mode(self):

4
cs.c
View File

@ -423,6 +423,10 @@ cs_err cs_option(csh ud, cs_opt_type type, size_t value)
default:
break;
case CS_OPT_UNSIGNED:
handle->imm_unsigned = (cs_opt_value)value;
return CS_ERR_OK;
case CS_OPT_DETAIL:
handle->detail = (cs_opt_value)value;
return CS_ERR_OK;

View File

@ -63,7 +63,7 @@ struct cs_struct {
PostPrinter_t post_printer;
cs_err errnum;
ARM_ITStatus ITBlock; // for Arm only
cs_opt_value detail;
cs_opt_value detail, imm_unsigned;
int syntax; // asm syntax for simple printer such as ARM, Mips & PPC
bool doing_mem; // handling memory operand in InstPrinter code
unsigned short *insn_cache; // index caching for mapping.c

View File

@ -151,11 +151,12 @@ typedef enum cs_opt_type {
CS_OPT_SKIPDATA, // Skip data when disassembling. Then engine is in SKIPDATA mode.
CS_OPT_SKIPDATA_SETUP, // Setup user-defined function for SKIPDATA option
CS_OPT_MNEMONIC, // Customize instruction mnemonic
CS_OPT_UNSIGNED, // print immediate operands in unsigned form
} cs_opt_type;
// Runtime option value (associated with option type above)
typedef enum cs_opt_value {
CS_OPT_OFF = 0, // Turn OFF an option - default option of CS_OPT_DETAIL, CS_OPT_SKIPDATA.
CS_OPT_OFF = 0, // Turn OFF an option - default for CS_OPT_DETAIL, CS_OPT_SKIPDATA, CS_OPT_UNSIGNED.
CS_OPT_ON = 3, // Turn ON an option (CS_OPT_DETAIL, CS_OPT_SKIPDATA).
CS_OPT_SYNTAX_DEFAULT = 0, // Default asm syntax (CS_OPT_SYNTAX).
CS_OPT_SYNTAX_INTEL, // X86 Intel asm syntax - default on X86 (CS_OPT_SYNTAX).