Minor clean-up
This commit is contained in:
66
decode.c
66
decode.c
@@ -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))
|
||||||
|
|||||||
Reference in New Issue
Block a user