Skip to content

Commit

Permalink
add dedicated variables such as prefix2e, prefix36, prefix66, prefix6…
Browse files Browse the repository at this point in the history
…7, etc
  • Loading branch information
bughoho committed Oct 7, 2015
1 parent ee34e72 commit 2f0e215
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 72 deletions.
24 changes: 6 additions & 18 deletions arch/X86/X86Disassembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,12 @@ static bool translateSrcIndex(MCInst *mcInst, InternalInstruction *insn)
unsigned baseRegNo;

if (insn->mode == MODE_64BIT)
baseRegNo = insn->prefixPresent[0x67] ? X86_ESI : X86_RSI;
baseRegNo = insn->isPrefix67 ? X86_ESI : X86_RSI;
else if (insn->mode == MODE_32BIT)
baseRegNo = insn->prefixPresent[0x67] ? X86_SI : X86_ESI;
baseRegNo = insn->isPrefix67 ? X86_SI : X86_ESI;
else {
// assert(insn->mode == MODE_16BIT);
baseRegNo = insn->prefixPresent[0x67] ? X86_ESI : X86_SI;
baseRegNo = insn->isPrefix67 ? X86_ESI : X86_SI;
}

MCOperand_CreateReg0(mcInst, baseRegNo);
Expand All @@ -119,12 +119,12 @@ static bool translateDstIndex(MCInst *mcInst, InternalInstruction *insn)
unsigned baseRegNo;

if (insn->mode == MODE_64BIT)
baseRegNo = insn->prefixPresent[0x67] ? X86_EDI : X86_RDI;
baseRegNo = insn->isPrefix67 ? X86_EDI : X86_RDI;
else if (insn->mode == MODE_32BIT)
baseRegNo = insn->prefixPresent[0x67] ? X86_DI : X86_EDI;
baseRegNo = insn->isPrefix67 ? X86_DI : X86_EDI;
else {
// assert(insn->mode == MODE_16BIT);
baseRegNo = insn->prefixPresent[0x67] ? X86_EDI : X86_DI;
baseRegNo = insn->isPrefix67 ? X86_EDI : X86_DI;
}

MCOperand_CreateReg0(mcInst, baseRegNo);
Expand Down Expand Up @@ -791,18 +791,6 @@ bool X86_getInstruction(csh ud, const uint8_t *code, size_t code_len,
info.offset = address;

memset(&insn, 0, offsetof(InternalInstruction, reader));
//initialize some the necessary values
insn.prefixPresent[0x26] = 0;
insn.prefixPresent[0x2e] = 0;
insn.prefixPresent[0x36] = 0;
insn.prefixPresent[0x3e] = 0;
insn.prefixPresent[0x64] = 0;
insn.prefixPresent[0x65] = 0;
insn.prefixPresent[0x66] = 0;
insn.prefixPresent[0x67] = 0;
insn.prefixPresent[0xf0] = 0;
insn.prefixPresent[0xf2] = 0;
insn.prefixPresent[0xf3] = 0;

if (instr->flat_insn->detail) {
instr->flat_insn->detail->x86.op_count = 0;
Expand Down
192 changes: 142 additions & 50 deletions arch/X86/X86DisassemblerDecoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,8 +352,55 @@ CONSUME_FUNC(consumeUInt64, uint64_t)
static void setPrefixPresent(struct InternalInstruction *insn,
uint8_t prefix, uint64_t location)
{
insn->prefixPresent[prefix] = 1;
insn->prefixLocations[prefix] = location;
switch (prefix)
{
case 0x26:
insn->isPrefix26 = true;
insn->prefix26 = location;
break;
case 0x2e:
insn->isPrefix2e = true;
insn->prefix2e = location;
break;
case 0x36:
insn->isPrefix36 = true;
insn->prefix36 = location;
break;
case 0x3e:
insn->isPrefix3e = true;
insn->prefix3e = location;
break;
case 0x64:
insn->isPrefix64 = true;
insn->prefix64 = location;
break;
case 0x65:
insn->isPrefix65 = true;
insn->prefix65 = location;
break;
case 0x66:
insn->isPrefix66 = true;
insn->prefix66 = location;
break;
case 0x67:
insn->isPrefix67 = true;
insn->prefix67 = location;
break;
case 0xf0:
insn->isPrefixf0 = true;
insn->prefixf0 = location;
break;
case 0xf2:
insn->isPrefixf2 = true;
insn->prefixf2 = location;
break;
case 0xf3:
insn->isPrefixf3 = true;
insn->prefixf3 = location;
break;
default:
break;
}
}

/*
Expand All @@ -368,11 +415,56 @@ static void setPrefixPresent(struct InternalInstruction *insn,
static bool isPrefixAtLocation(struct InternalInstruction *insn, uint8_t prefix,
uint64_t location)
{
if (insn->prefixPresent[prefix] == 1 &&
insn->prefixLocations[prefix] == location)
return true;
else
return false;
switch (prefix)
{
case 0x26:
if (insn->isPrefix26 && insn->prefix26 == location)
return true;
break;
case 0x2e:
if (insn->isPrefix2e && insn->prefix2e == location)
return true;
break;
case 0x36:
if (insn->isPrefix36 && insn->prefix36 == location)
return true;
break;
case 0x3e:
if (insn->isPrefix3e && insn->prefix3e == location)
return true;
break;
case 0x64:
if (insn->isPrefix64 && insn->prefix64 == location)
return true;
break;
case 0x65:
if (insn->isPrefix65 && insn->prefix65 == location)
return true;
break;
case 0x66:
if (insn->isPrefix66 && insn->prefix66 == location)
return true;
break;
case 0x67:
if (insn->isPrefix67 && insn->prefix67 == location)
return true;
break;
case 0xf0:
if (insn->isPrefixf0 && insn->prefixf0 == location)
return true;
break;
case 0xf2:
if (insn->isPrefixf2 && insn->prefixf2 == location)
return true;
break;
case 0xf3:
if (insn->isPrefixf3 && insn->prefixf3 == location)
return true;
break;
default:
break;
}
return false;
}

/*
Expand Down Expand Up @@ -482,86 +574,86 @@ static int readPrefixes(struct InternalInstruction *insn)
case 0xf3: /* REP or REPE/REPZ */
case 0xf0: /* LOCK */
// only accept the last prefix
insn->prefixPresent[0xf2] = 0;
insn->prefixPresent[0xf3] = 0;
insn->prefixPresent[0xf0] = 0;
insn->isPrefixf2 = false;
insn->isPrefixf3 = false;
insn->isPrefixf0 = false;
setPrefixPresent(insn, byte, prefixLocation);
insn->prefix0 = byte;
break;
case 0x2e: /* CS segment override -OR- Branch not taken */
insn->segmentOverride = SEG_OVERRIDE_CS;
// only accept the last prefix
insn->prefixPresent[0x2e] = 0;
insn->prefixPresent[0x36] = 0;
insn->prefixPresent[0x3e] = 0;
insn->prefixPresent[0x26] = 0;
insn->prefixPresent[0x64] = 0;
insn->prefixPresent[0x65] = 0;
insn->isPrefix2e = false;
insn->isPrefix36 = false;
insn->isPrefix3e = false;
insn->isPrefix26 = false;
insn->isPrefix64 = false;
insn->isPrefix65 = false;

setPrefixPresent(insn, byte, prefixLocation);
insn->prefix1 = byte;
break;
case 0x36: /* SS segment override -OR- Branch taken */
insn->segmentOverride = SEG_OVERRIDE_SS;
// only accept the last prefix
insn->prefixPresent[0x2e] = 0;
insn->prefixPresent[0x36] = 0;
insn->prefixPresent[0x3e] = 0;
insn->prefixPresent[0x26] = 0;
insn->prefixPresent[0x64] = 0;
insn->prefixPresent[0x65] = 0;
insn->isPrefix2e = false;
insn->isPrefix36 = false;
insn->isPrefix3e = false;
insn->isPrefix26 = false;
insn->isPrefix64 = false;
insn->isPrefix65 = false;

setPrefixPresent(insn, byte, prefixLocation);
insn->prefix1 = byte;
break;
case 0x3e: /* DS segment override */
insn->segmentOverride = SEG_OVERRIDE_DS;
// only accept the last prefix
insn->prefixPresent[0x2e] = 0;
insn->prefixPresent[0x36] = 0;
insn->prefixPresent[0x3e] = 0;
insn->prefixPresent[0x26] = 0;
insn->prefixPresent[0x64] = 0;
insn->prefixPresent[0x65] = 0;
insn->isPrefix2e = false;
insn->isPrefix36 = false;
insn->isPrefix3e = false;
insn->isPrefix26 = false;
insn->isPrefix64 = false;
insn->isPrefix65 = false;

setPrefixPresent(insn, byte, prefixLocation);
insn->prefix1 = byte;
break;
case 0x26: /* ES segment override */
insn->segmentOverride = SEG_OVERRIDE_ES;
// only accept the last prefix
insn->prefixPresent[0x2e] = 0;
insn->prefixPresent[0x36] = 0;
insn->prefixPresent[0x3e] = 0;
insn->prefixPresent[0x26] = 0;
insn->prefixPresent[0x64] = 0;
insn->prefixPresent[0x65] = 0;
insn->isPrefix2e = false;
insn->isPrefix36 = false;
insn->isPrefix3e = false;
insn->isPrefix26 = false;
insn->isPrefix64 = false;
insn->isPrefix65 = false;

setPrefixPresent(insn, byte, prefixLocation);
insn->prefix1 = byte;
break;
case 0x64: /* FS segment override */
insn->segmentOverride = SEG_OVERRIDE_FS;
// only accept the last prefix
insn->prefixPresent[0x2e] = 0;
insn->prefixPresent[0x36] = 0;
insn->prefixPresent[0x3e] = 0;
insn->prefixPresent[0x26] = 0;
insn->prefixPresent[0x64] = 0;
insn->prefixPresent[0x65] = 0;
insn->isPrefix2e = false;
insn->isPrefix36 = false;
insn->isPrefix3e = false;
insn->isPrefix26 = false;
insn->isPrefix64 = false;
insn->isPrefix65 = false;

setPrefixPresent(insn, byte, prefixLocation);
insn->prefix1 = byte;
break;
case 0x65: /* GS segment override */
insn->segmentOverride = SEG_OVERRIDE_GS;
// only accept the last prefix
insn->prefixPresent[0x2e] = 0;
insn->prefixPresent[0x36] = 0;
insn->prefixPresent[0x3e] = 0;
insn->prefixPresent[0x26] = 0;
insn->prefixPresent[0x64] = 0;
insn->prefixPresent[0x65] = 0;
insn->isPrefix2e = false;
insn->isPrefix36 = false;
insn->isPrefix3e = false;
insn->isPrefix26 = false;
insn->isPrefix64 = false;
insn->isPrefix65 = false;

setPrefixPresent(insn, byte, prefixLocation);
insn->prefix1 = byte;
Expand Down Expand Up @@ -1179,7 +1271,7 @@ static int getID(struct InternalInstruction *insn)
}

/* The following clauses compensate for limitations of the tables. */
if ((insn->mode == MODE_16BIT || insn->prefixPresent[0x66]) &&
if ((insn->mode == MODE_16BIT || insn->isPrefix66) &&
!(attrMask & ATTR_OPSIZE)) {
/*
* The instruction tables make no distinction between instructions that
Expand Down Expand Up @@ -1207,7 +1299,7 @@ static int getID(struct InternalInstruction *insn)
}

if (is16BitEquivalent(instructionID, instructionIDWithOpsize) &&
(insn->mode == MODE_16BIT) ^ insn->prefixPresent[0x66]) {
(insn->mode == MODE_16BIT) ^ insn->isPrefix66) {
insn->instructionID = instructionIDWithOpsize;
insn->spec = specifierForUID(instructionIDWithOpsize);
} else {
Expand Down Expand Up @@ -2021,7 +2113,7 @@ static int readOperands(struct InternalInstruction *insn)
static bool checkPrefix(struct InternalInstruction *insn)
{
// LOCK prefix
if (insn->prefixPresent[0xf0]) {
if (insn->isPrefixf0) {
switch(insn->instructionID) {
default:
// invalid LOCK
Expand Down Expand Up @@ -2197,7 +2289,7 @@ static bool checkPrefix(struct InternalInstruction *insn)
}

// REPNE prefix
if (insn->prefixPresent[0xf2]) {
if (insn->isPrefixf2) {
// 0xf2 can be a part of instruction encoding, but not really a prefix.
// In such a case, clear it.
if (insn->twoByteEscape == 0x0f) {
Expand Down
28 changes: 24 additions & 4 deletions arch/X86/X86DisassemblerDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,30 @@ typedef struct InternalInstruction {
// from here, all members must be initialized to ZERO to work properly
uint8_t operandSize;
uint8_t prefix0, prefix1, prefix2, prefix3;
/* 1 if the prefix byte corresponding to the entry is present; 0 if not */
bool isPrefix26;
bool isPrefix2e;
bool isPrefix36;
bool isPrefix3e;
bool isPrefix64;
bool isPrefix65;
bool isPrefix66;
bool isPrefix67;
bool isPrefixf0;
bool isPrefixf2;
bool isPrefixf3;
/* contains the location (for use with the reader) of the prefix byte */
uint64_t prefix26;
uint64_t prefix2e;
uint64_t prefix36;
uint64_t prefix3e;
uint64_t prefix64;
uint64_t prefix65;
uint64_t prefix66;
uint64_t prefix67;
uint64_t prefixf0;
uint64_t prefixf2;
uint64_t prefixf3;
/* The value of the REX prefix, if present */
uint8_t rexPrefix;
/* The segment override type */
Expand Down Expand Up @@ -586,10 +610,6 @@ typedef struct InternalInstruction {
/* Reader interface (C) */
byteReader_t reader;

/* 1 if the prefix byte corresponding to the entry is present; 0 if not */
uint8_t prefixPresent[0x100];
/* contains the location (for use with the reader) of the prefix byte */
uint64_t prefixLocations[0x100];
/* Opaque value passed to the reader */
const void* readerArg;
/* The address of the next byte to read via the reader */
Expand Down

0 comments on commit 2f0e215

Please sign in to comment.