Skip to content

Commit

Permalink
x86: print imm with proper size for CS_OPT_UNSIGNED
Browse files Browse the repository at this point in the history
  • Loading branch information
aquynh committed Feb 13, 2019
1 parent 4ac429d commit 5f9c033
Showing 1 changed file with 52 additions and 20 deletions.
72 changes: 52 additions & 20 deletions arch/X86/X86IntelInstPrinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,12 +373,28 @@ static bool need_zero_prefix(uint64_t imm)
return true;
}

static void printImm(int syntax, SStream *O, int64_t imm, bool positive)
static void printImm(MCInst *MI, SStream *O, int64_t imm, bool positive)
{
if (positive) {
// always print this number in positive form
if (syntax == CS_OPT_SYNTAX_MASM) {
if (MI->csh->syntax == CS_OPT_SYNTAX_MASM) {
if (imm < 0) {
if (MI->op1_size) {
switch(MI->op1_size) {
default:
break;
case 1:
imm &= 0xff;
break;
case 2:
imm &= 0xffff;
break;
case 4:
imm &= 0xffffffff;
break;
}
}

if (imm == 0x8000000000000000LL) // imm == -imm
SStream_concat0(O, "8000000000000000h");
else if (need_zero_prefix(imm))
Expand All @@ -396,6 +412,22 @@ static void printImm(int syntax, SStream *O, int64_t imm, bool positive)
}
} else { // Intel syntax
if (imm < 0) {
if (MI->op1_size) {
switch(MI->op1_size) {
default:
break;
case 1:
imm &= 0xff;
break;
case 2:
imm &= 0xffff;
break;
case 4:
imm &= 0xffffffff;
break;
}
}

SStream_concat(O, "0x%"PRIx64, imm);
} else {
if (imm > HEX_THRESHOLD)
Expand All @@ -405,7 +437,7 @@ static void printImm(int syntax, SStream *O, int64_t imm, bool positive)
}
}
} else {
if (syntax == CS_OPT_SYNTAX_MASM) {
if (MI->csh->syntax == CS_OPT_SYNTAX_MASM) {
if (imm < 0) {
if (imm == 0x8000000000000000LL) // imm == -imm
SStream_concat0(O, "8000000000000000h");
Expand Down Expand Up @@ -452,7 +484,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);
printImm(MI->csh->syntax, O, imm, MI->csh->imm_unsigned);
printImm(MI, O, imm, MI->csh->imm_unsigned);
}
}

Expand Down Expand Up @@ -661,9 +693,9 @@ static void printMemOffset(MCInst *MI, unsigned Op, SStream *O)
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = imm;

if (imm < 0)
printImm(MI->csh->syntax, O, arch_masks[MI->csh->mode] & imm, true);
printImm(MI, O, arch_masks[MI->csh->mode] & imm, true);
else
printImm(MI->csh->syntax, O, imm, true);
printImm(MI, O, imm, true);
}

SStream_concat0(O, "]");
Expand All @@ -680,7 +712,7 @@ static void printU8Imm(MCInst *MI, unsigned Op, SStream *O)
{
uint8_t val = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0xff;

printImm(MI->csh->syntax, O, val, true);
printImm(MI, O, val, true);

if (MI->csh->detail) {
#ifndef CAPSTONE_DIET
Expand Down Expand Up @@ -825,7 +857,7 @@ static void printPCRelImm(MCInst *MI, unsigned OpNo, SStream *O)
if (MI->Opcode == X86_CALLpcrel16 || MI->Opcode == X86_JMP_2)
imm = imm & 0xffff;

printImm(MI->csh->syntax, O, imm, true);
printImm(MI, O, imm, true);

if (MI->csh->detail) {
#ifndef CAPSTONE_DIET
Expand Down Expand Up @@ -897,20 +929,20 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
// printf(">>> id = %u\n", MI->flat_insn->id);
switch(MI->flat_insn->id) {
default:
printImm(MI->csh->syntax, O, imm, MI->csh->imm_unsigned);
printImm(MI, O, imm, MI->csh->imm_unsigned);
break;

case X86_INS_MOVABS:
// do not print number in negative form
printImm(MI->csh->syntax, O, imm, true);
printImm(MI, O, imm, true);
break;

case X86_INS_IN:
case X86_INS_OUT:
case X86_INS_INT:
// do not print number in negative form
imm = imm & 0xff;
printImm(MI->csh->syntax, O, imm, true);
printImm(MI, O, imm, true);
break;

case X86_INS_LCALL:
Expand All @@ -920,29 +952,29 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
imm = imm & 0xffff;
opsize = 2;
}
printImm(MI->csh->syntax, O, imm, true);
printImm(MI, O, imm, true);
break;

case X86_INS_AND:
case X86_INS_OR:
case X86_INS_XOR:
// do not print number in negative form
if (imm >= 0 && imm <= HEX_THRESHOLD)
printImm(MI->csh->syntax, O, imm, true);
printImm(MI, O, imm, true);
else {
imm = arch_masks[opsize? opsize : MI->imm_size] & imm;
printImm(MI->csh->syntax, O, imm, true);
printImm(MI, O, imm, true);
}
break;

case X86_INS_RET:
case X86_INS_RETF:
// RET imm16
if (imm >= 0 && imm <= HEX_THRESHOLD)
printImm(MI->csh->syntax, O, imm, true);
printImm(MI, O, imm, true);
else {
imm = 0xffff & imm;
printImm(MI->csh->syntax, O, imm, true);
printImm(MI, O, imm, true);
}
break;
}
Expand Down Expand Up @@ -1042,17 +1074,17 @@ static void printMemReference(MCInst *MI, unsigned Op, SStream *O)
if (NeedPlus) {
if (DispVal < 0) {
SStream_concat0(O, " - ");
printImm(MI->csh->syntax, O, -DispVal, true);
printImm(MI, O, -DispVal, true);
} else {
SStream_concat0(O, " + ");
printImm(MI->csh->syntax, O, DispVal, true);
printImm(MI, O, DispVal, true);
}
} else {
// memory reference to an immediate address
if (DispVal < 0) {
printImm(MI->csh->syntax, O, arch_masks[MI->csh->mode] & DispVal, true);
printImm(MI, O, arch_masks[MI->csh->mode] & DispVal, true);
} else {
printImm(MI->csh->syntax, O, DispVal, true);
printImm(MI, O, DispVal, true);
}
}

Expand Down

0 comments on commit 5f9c033

Please sign in to comment.