}
-int v3_basic_mem_decode(struct guest_info * info, addr_t instr_ptr, struct basic_instr_info * instr_info) {
- xed_decoded_inst_t xed_instr;
- xed_error_enum_t xed_error;
-
-
- if (set_decoder_mode(info, info->decoder_state) == -1) {
- PrintError("Could not set decoder mode\n");
- return -1;
- }
-
-
- xed_decoded_inst_zero_set_mode(&xed_instr, info->decoder_state);
-
- xed_error = xed_decode(&xed_instr,
- REINTERPRET_CAST(const xed_uint8_t *, instr_ptr),
- XED_MAX_INSTRUCTION_BYTES);
-
- if (xed_error != XED_ERROR_NONE) {
- PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
- return -1;
- }
-
- instr_info->instr_length = xed_decoded_inst_get_length(&xed_instr);
-
-
- if (xed_decoded_inst_number_of_memory_operands(&xed_instr) == 0) {
- PrintError("Tried to decode memory operation with no memory operands\n");
- return -1;
- }
-
- instr_info->op_size = xed_decoded_inst_get_memory_operand_length(&xed_instr, 0);
-
-
- xed_category_enum_t cat = xed_decoded_inst_get_category(&xed_instr);
- if (cat == XED_CATEGORY_STRINGOP) {
- instr_info->str_op = 1;
- } else {
- instr_info->str_op = 0;
- }
-
- xed_operand_values_t * operands = xed_decoded_inst_operands(&xed_instr);
- if (xed_operand_values_has_real_rep(operands)) {
- instr_info->has_rep = 1;
- } else {
- instr_info->has_rep = 0;
- }
-
- return 0;
-}
static int decode_string_op(struct guest_info * info,
addr_t reg_addr = 0;
uint_t reg_length = 0;
- xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG1), ®_addr, ®_length);
+ xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG1),
+ ®_addr, ®_length);
instr->str_op_length = MASK(*(addr_t *)reg_addr, reg_length);
} else {
instr->str_op_length = 1;
}
-int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) {
+int v3_encode(struct guest_info * info, struct x86_instr * instr, uint8_t * instr_buf) {
return -1;
}
index = MASK(mem_op.index, mem_op.index_size);
scale = mem_op.scale;
- // This is a horrendous hack...
- // XED really screwed the pooch in calculating the displacement
- if (cpu_mode == LONG) {
- displacement = mem_op.displacement;
- } else {
- displacement = MASK(mem_op.displacement, mem_op.displacement_size);
- }
+ // XED returns the displacement as a 2s complement signed number, but it can
+ // have different sizes, depending on the instruction encoding.
+ // we put that into a 64 bit unsigned (the unsigned doesn't matter since
+ // we only ever do 2s complement arithmetic on it. However, this means we
+ // need to sign-extend what XED provides through 64 bits.
+ displacement = mem_op.displacement;
+ displacement <<= 64 - mem_op.displacement_size * 8;
+ displacement = ((sllong_t)displacement) >> (64 - mem_op.displacement_size * 8);
+
PrintDebug("Seg=%p, base=%p, index=%p, scale=%p, displacement=%p\n",
(void *)seg, (void *)base, (void *)index, (void *)scale, (void *)(addr_t)displacement);
}
-static int xed_reg_to_v3_reg(struct guest_info * info, xed_reg_enum_t xed_reg, addr_t * v3_reg, uint_t * reg_len) {
+static int xed_reg_to_v3_reg(struct guest_info * info, xed_reg_enum_t xed_reg,
+ addr_t * v3_reg, uint_t * reg_len) {
PrintDebug("Xed Register: %s\n", xed_reg_enum_t2str(xed_reg));