Minor clean-up

This commit is contained in:
Alexis Engelke
2019-04-27 11:09:57 +02:00
parent db1ec271df
commit a7d4c7be9d

View File

@@ -39,9 +39,9 @@ typedef enum DecodeMode DecodeMode;
#define ENTRY_TABLE_VEX 6 #define ENTRY_TABLE_VEX 6
#define ENTRY_MASK 7 #define ENTRY_MASK 7
#define ENTRY_UNPACK(table,kind,decode_table,entry) do { \ #define ENTRY_UNPACK(table,kind,entry) do { \
uint16_t entry_copy = entry; \ uint16_t entry_copy = entry; \
table = (uint16_t*) &(decode_table)[entry_copy & ~7]; \ table = (uint16_t*) &_decode_table[entry_copy & ~7]; \
kind = entry_copy & ENTRY_MASK; \ kind = entry_copy & ENTRY_MASK; \
} while (0) } while (0)
@@ -323,9 +323,7 @@ fd_decode(const uint8_t* buffer, size_t len_sz, int mode_int, uintptr_t address,
&mandatory_prefix, &instr->segment, &vex_operand, &mandatory_prefix, &instr->segment, &vex_operand,
&opcode_escape); &opcode_escape);
if (UNLIKELY(retval < 0 || off + retval >= len)) if (UNLIKELY(retval < 0 || off + retval >= len))
{
return -1; return -1;
}
off += retval; off += retval;
uint32_t kind = ENTRY_TABLE256; uint32_t kind = ENTRY_TABLE256;
@@ -333,17 +331,17 @@ fd_decode(const uint8_t* buffer, size_t len_sz, int mode_int, uintptr_t address,
// "Legacy" walk through table and escape opcodes // "Legacy" walk through table and escape opcodes
if (LIKELY(opcode_escape < 0)) if (LIKELY(opcode_escape < 0))
while (kind == ENTRY_TABLE256 && LIKELY(off < len)) while (kind == ENTRY_TABLE256 && LIKELY(off < len))
ENTRY_UNPACK(table, kind, _decode_table, table[buffer[off++]]); ENTRY_UNPACK(table, kind, table[buffer[off++]]);
// VEX/EVEX compact escapes; the prefix precedes the single opcode byte // VEX/EVEX compact escapes; the prefix precedes the single opcode byte
else if (opcode_escape == 1 || opcode_escape == 2 || opcode_escape == 3) else if (opcode_escape == 1 || opcode_escape == 2 || opcode_escape == 3)
{ {
ENTRY_UNPACK(table, kind, _decode_table, table[0x0F]); ENTRY_UNPACK(table, kind, table[0x0F]);
if (opcode_escape == 2) if (opcode_escape == 2)
ENTRY_UNPACK(table, kind, _decode_table, table[0x38]); ENTRY_UNPACK(table, kind, table[0x38]);
if (opcode_escape == 3) if (opcode_escape == 3)
ENTRY_UNPACK(table, kind, _decode_table, table[0x3A]); ENTRY_UNPACK(table, kind, table[0x3A]);
if (LIKELY(off < len)) if (LIKELY(off < len))
ENTRY_UNPACK(table, kind, _decode_table, table[buffer[off++]]); ENTRY_UNPACK(table, kind, table[buffer[off++]]);
} }
else else
return -1; return -1;
@@ -363,7 +361,7 @@ fd_decode(const uint8_t* buffer, size_t len_sz, int mode_int, uintptr_t address,
else else
entry = table[(buffer[off] >> 3) & 7]; entry = table[(buffer[off] >> 3) & 7];
ENTRY_UNPACK(table, kind, _decode_table, entry); ENTRY_UNPACK(table, kind, entry);
} }
// Handle mandatory prefixes (which behave like an opcode ext.). // Handle mandatory prefixes (which behave like an opcode ext.).
@@ -376,7 +374,7 @@ fd_decode(const uint8_t* buffer, size_t len_sz, int mode_int, uintptr_t address,
// for the 0x66 prefix, which could otherwise override the operand // for the 0x66 prefix, which could otherwise override the operand
// size of general purpose registers. // size of general purpose registers.
prefixes &= ~(PREFIX_OPSZ | PREFIX_REPNZ | PREFIX_REP); prefixes &= ~(PREFIX_OPSZ | PREFIX_REPNZ | PREFIX_REP);
ENTRY_UNPACK(table, kind, _decode_table, table[index]); ENTRY_UNPACK(table, kind, table[index]);
} }
// For VEX prefix, we have to distinguish between VEX.W and VEX.L which may // For VEX prefix, we have to distinguish between VEX.W and VEX.L which may
@@ -386,13 +384,11 @@ fd_decode(const uint8_t* buffer, size_t len_sz, int mode_int, uintptr_t address,
uint8_t index = 0; uint8_t index = 0;
index |= prefixes & PREFIX_REXW ? (1 << 0) : 0; index |= prefixes & PREFIX_REXW ? (1 << 0) : 0;
index |= prefixes & PREFIX_VEXL ? (1 << 1) : 0; index |= prefixes & PREFIX_VEXL ? (1 << 1) : 0;
ENTRY_UNPACK(table, kind, _decode_table, table[index]); ENTRY_UNPACK(table, kind, table[index]);
} }
if (UNLIKELY(kind != ENTRY_INSTR)) if (UNLIKELY(kind != ENTRY_INSTR))
{
return -1; return -1;
}
struct InstrDesc* desc = (struct InstrDesc*) table; struct InstrDesc* desc = (struct InstrDesc*) table;
@@ -418,9 +414,7 @@ fd_decode(const uint8_t* buffer, size_t len_sz, int mode_int, uintptr_t address,
uint8_t vec_size = 16; uint8_t vec_size = 16;
if (prefixes & PREFIX_VEXL) if (prefixes & PREFIX_VEXL)
{
vec_size = 32; vec_size = 32;
}
// Compute address size. // Compute address size.
uint8_t addr_size = mode == DECODE_64 ? 8 : 4; uint8_t addr_size = mode == DECODE_64 ? 8 : 4;
@@ -449,20 +443,14 @@ fd_decode(const uint8_t* buffer, size_t len_sz, int mode_int, uintptr_t address,
if (DESC_HAS_MODRM(desc)) if (DESC_HAS_MODRM(desc))
{ {
FdOp* operand1 = &instr->operands[DESC_MODRM_IDX(desc)]; FdOp* operand1 = &instr->operands[DESC_MODRM_IDX(desc)];
FdOp* operand2 = NULL; FdOp* operand2 = NULL;
if (DESC_HAS_MODREG(desc)) if (DESC_HAS_MODREG(desc))
{
operand2 = &instr->operands[DESC_MODREG_IDX(desc)]; operand2 = &instr->operands[DESC_MODREG_IDX(desc)];
}
retval = decode_modrm(buffer + off, len - off, mode, instr, prefixes, retval = decode_modrm(buffer + off, len - off, mode, instr, prefixes,
operand1, operand2); operand1, operand2);
if (UNLIKELY(retval < 0)) if (UNLIKELY(retval < 0))
{
return -1; return -1;
}
off += retval; off += retval;
} }
else if (DESC_HAS_MODREG(desc)) else if (DESC_HAS_MODREG(desc))
@@ -520,73 +508,51 @@ fd_decode(const uint8_t* buffer, size_t len_sz, int mode_int, uintptr_t address,
uint8_t imm_size; uint8_t imm_size;
if (DESC_IMM_BYTE(desc)) if (DESC_IMM_BYTE(desc))
{
imm_size = 1; imm_size = 1;
}
else if (UNLIKELY(instr->type == FDI_RET_IMM)) else if (UNLIKELY(instr->type == FDI_RET_IMM))
{
imm_size = 2; imm_size = 2;
}
else if (UNLIKELY(instr->type == FDI_ENTER)) else if (UNLIKELY(instr->type == FDI_ENTER))
{
imm_size = 3; imm_size = 3;
}
#if defined(ARCH_X86_64) #if defined(ARCH_X86_64)
else if (mode == DECODE_64 && UNLIKELY(imm_control == 4)) else if (mode == DECODE_64 && UNLIKELY(imm_control == 4))
{
// Jumps are always 8 or 32 bit on x86-64. // Jumps are always 8 or 32 bit on x86-64.
imm_size = 4; imm_size = 4;
operand->size = 8;
}
#endif #endif
else if (prefixes & PREFIX_OPSZ) else if (prefixes & PREFIX_OPSZ)
{
imm_size = 2; imm_size = 2;
}
#if defined(ARCH_X86_64) #if defined(ARCH_X86_64)
else if (mode == DECODE_64 && (prefixes & PREFIX_REXW) && else if (mode == DECODE_64 && (prefixes & PREFIX_REXW) &&
instr->type == FDI_MOVABS_IMM) instr->type == FDI_MOVABS_IMM)
{
imm_size = 8; imm_size = 8;
}
#endif #endif
else else
{
imm_size = 4; imm_size = 4;
}
if (UNLIKELY(off + imm_size > len)) if (UNLIKELY(off + imm_size > len))
{
return -1; return -1;
}
if (imm_size == 1) if (imm_size == 1)
{
instr->imm = (int8_t) LOAD_LE_1(&buffer[off]); instr->imm = (int8_t) LOAD_LE_1(&buffer[off]);
}
else if (imm_size == 2) else if (imm_size == 2)
{
instr->imm = (int16_t) LOAD_LE_2(&buffer[off]); instr->imm = (int16_t) LOAD_LE_2(&buffer[off]);
}
else if (imm_size == 3) else if (imm_size == 3)
{
instr->imm = LOAD_LE_3(&buffer[off]); instr->imm = LOAD_LE_3(&buffer[off]);
}
else if (imm_size == 4) else if (imm_size == 4)
{
instr->imm = (int32_t) LOAD_LE_4(&buffer[off]); instr->imm = (int32_t) LOAD_LE_4(&buffer[off]);
}
#if defined(ARCH_X86_64) #if defined(ARCH_X86_64)
else if (imm_size == 8) else if (imm_size == 8)
{
instr->imm = (int64_t) LOAD_LE_8(&buffer[off]); instr->imm = (int64_t) LOAD_LE_8(&buffer[off]);
}
#endif #endif
off += imm_size; off += imm_size;
if (imm_control == 4) if (imm_control == 4)
{ {
instr->imm += instr->address + off; instr->imm += instr->address + off;
#if defined(ARCH_X86_64)
// On x86-64, jumps always have an operand size of 64 bit.
if (mode == DECODE_64)
operand->size = 8;
#endif
} }
if (UNLIKELY(imm_control == 5)) if (UNLIKELY(imm_control == 5))