Skip to content

Commit

Permalink
x86: save prefixes to avoid expensive copying loop. based on idea of …
Browse files Browse the repository at this point in the history
…Dang Hoang Vu
  • Loading branch information
aquynh committed Jun 4, 2014
1 parent b76233c commit 46b6693
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 10 deletions.
2 changes: 1 addition & 1 deletion MCInst.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ struct MCInst {
// (Optional) instruction prefix, which can be up to 5 bytes.
// A prefix byte gets value 0 when irrelevant.
// This is copied from cs_x86 struct
uint8_t x86_prefix[5];
uint8_t x86_prefix[4];
bool x86_lock_rep; // does this X86 insn contain LOCK/REP prefix?
};

Expand Down
18 changes: 9 additions & 9 deletions arch/X86/X86Disassembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,11 @@ static void update_pub_insn(cs_insn_flat *pub, InternalInstruction *inter, uint8
}
}

prefixes[0] = inter->prefix0;
prefixes[1] = inter->prefix1;
prefixes[2] = inter->prefix2;
prefixes[3] = inter->prefix3;

pub->x86.segment = x86_map_segment(inter->segmentOverride);

if (inter->vectorExtensionType > 0)
Expand Down Expand Up @@ -759,22 +764,17 @@ bool X86_getInstruction(csh ud, const uint8_t *code, size_t code_len,

return false;
} else {
int i, c;

*size = (uint16_t)insn.length;
result = (!translateInstruction(instr, &insn)) ? true : false;
if (result) {
if (handle->detail)
update_pub_insn(&instr->flat_insn, &insn, instr->x86_prefix);
else {
// copy all prefixes
c = 0;
for(i = 0; i < 0x100; i++) {
if (insn.prefixPresent[i] > 0) {
instr->x86_prefix[c] = i;
c++;
}
}
instr->x86_prefix[0] = insn.prefix0;
instr->x86_prefix[1] = insn.prefix1;
instr->x86_prefix[2] = insn.prefix2;
instr->x86_prefix[3] = insn.prefix3;
}

instr->x86_lock_rep = insn.x86_lock_rep;
Expand Down
4 changes: 4 additions & 0 deletions arch/X86/X86DisassemblerDecoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,7 @@ static int readPrefixes(struct InternalInstruction* insn)
dbgprintf(insn, "Redundant Group 1 prefix");
prefixGroups[0] = TRUE;
setPrefixPresent(insn, byte, prefixLocation);
insn->prefix0 = byte;
break;
case 0x2e: /* CS segment override -OR- Branch not taken */
case 0x36: /* SS segment override -OR- Branch taken */
Expand Down Expand Up @@ -501,20 +502,23 @@ static int readPrefixes(struct InternalInstruction* insn)
insn->prefixPresent[0x64] = 0;
insn->prefixPresent[0x65] = 0;
setPrefixPresent(insn, byte, prefixLocation);
insn->prefix1 = byte;
break;
case 0x66: /* Operand-size override */
if (prefixGroups[2])
dbgprintf(insn, "Redundant Group 3 prefix");
prefixGroups[2] = TRUE;
hasOpSize = TRUE;
setPrefixPresent(insn, byte, prefixLocation);
insn->prefix2 = byte;
break;
case 0x67: /* Address-size override */
if (prefixGroups[3])
dbgprintf(insn, "Redundant Group 4 prefix");
prefixGroups[3] = TRUE;
hasAdSize = TRUE;
setPrefixPresent(insn, byte, prefixLocation);
insn->prefix3 = byte;
break;
default: /* Not a prefix byte */
isPrefix = FALSE;
Expand Down
1 change: 1 addition & 0 deletions arch/X86/X86DisassemblerDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,7 @@ typedef struct InternalInstruction {

/* 1 if the prefix byte corresponding to the entry is present; 0 if not */
uint8_t prefixPresent[0x100];
uint8_t prefix0, prefix1, prefix2, prefix3;
/* contains the location (for use with the reader) of the prefix byte */
uint64_t prefixLocations[0x100];
/* The value of the vector extension prefix(EVEX/VEX/XOP), if present */
Expand Down

0 comments on commit 46b6693

Please sign in to comment.