mirror of
https://github.com/capstone-engine/capstone.git
synced 2025-02-10 16:42:54 +00:00
add CS_OPT_UNSIGNED option to print immediate in unsigned form. only ARM is supported for now (issue #585)
This commit is contained in:
parent
141804ab9a
commit
a23f9d37ed
@ -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;
|
||||
|
@ -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
4
cs.c
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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).
|
||||
|
Loading…
x
Reference in New Issue
Block a user