Handle address size overrides

This commit is contained in:
Alexis Engelke
2019-01-13 14:27:04 +01:00
parent 80458e3288
commit d1110fae6a
2 changed files with 18 additions and 18 deletions

View File

@@ -610,6 +610,13 @@ decode(const uint8_t* buffer, int len, DecodeMode mode, Instr* instr)
vec_size = 32; vec_size = 32;
} }
// Compute address size.
uint8_t addr_size_log = mode == DECODE_64 ? 4 : 3;
if (prefixes & PREFIX_ADDRSZ)
addr_size_log -= 1;
instr->addr_size = addr_size_log;
uint8_t addr_size = (1 << addr_size_log) >> 1;
uint8_t operand_sizes[4] = { uint8_t operand_sizes[4] = {
0, 1 << desc->gp_fixed_operand_size, op_size, vec_size 0, 1 << desc->gp_fixed_operand_size, op_size, vec_size
}; };
@@ -680,29 +687,20 @@ decode(const uint8_t* buffer, int len, DecodeMode mode, Instr* instr)
operand->reg = REG_NONE; operand->reg = REG_NONE;
operand->size = op_size; operand->size = op_size;
instr->scale = 0; instr->scale = 0;
// TODO: Address size overrides
if (UNLIKELY(off + addr_size > len))
return -1;
#if defined(ARCH_386) #if defined(ARCH_386)
if (mode == DECODE_32) if (addr_size == 2)
{ instr->disp = LOAD_LE_2(&buffer[off]);
if (UNLIKELY(off + 4 > len)) #endif
{ if (addr_size == 4)
return -1;
}
instr->disp = LOAD_LE_4(&buffer[off]); instr->disp = LOAD_LE_4(&buffer[off]);
off += 4;
}
#endif
#if defined(ARCH_X86_64) #if defined(ARCH_X86_64)
if (mode == DECODE_64) if (addr_size == 8)
{
if (UNLIKELY(off + 8 > len))
{
return -1;
}
instr->disp = LOAD_LE_8(&buffer[off]); instr->disp = LOAD_LE_8(&buffer[off]);
off += 8;
}
#endif #endif
off += addr_size;
} }
else if (UNLIKELY(imm_control != 0)) else if (UNLIKELY(imm_control != 0))
{ {

View File

@@ -118,6 +118,7 @@ struct Instr
struct Operand operands[4]; struct Operand operands[4];
uint8_t segment : 3; uint8_t segment : 3;
uint8_t width : 3; uint8_t width : 3;
uint8_t addr_size : 2;
/** /**
* Encoded as 1 << (scale - 1) **or** no scaled register at all if zero. * Encoded as 1 << (scale - 1) **or** no scaled register at all if zero.
@@ -137,6 +138,7 @@ typedef struct Instr Instr;
#define INSTR_SEGMENT(instr) ((instr)->segment) #define INSTR_SEGMENT(instr) ((instr)->segment)
#define INSTR_WIDTH(instr) ((1 << (instr)->width) >> 1) #define INSTR_WIDTH(instr) ((1 << (instr)->width) >> 1)
#define INSTR_ADDRSZ(instr) ((1 << (instr)->addr_size) >> 1)
#define INSTR_HAS_REP(instr) ((instr)->prefixes & PREFIX_REP) #define INSTR_HAS_REP(instr) ((instr)->prefixes & PREFIX_REP)
#define INSTR_HAS_REPNZ(instr) ((instr)->prefixes & PREFIX_REPNZ) #define INSTR_HAS_REPNZ(instr) ((instr)->prefixes & PREFIX_REPNZ)
#define INSTR_HAS_LOCK(instr) ((instr)->prefixes & PREFIX_LOCK) #define INSTR_HAS_LOCK(instr) ((instr)->prefixes & PREFIX_LOCK)