X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_xed.c;h=e48a1b8c941c9f93a3950c2e7f53d84ecd4f9548;hb=af355c370ac80f8e19d6375cb3070213c29a92eb;hp=036501dea200fdb1480f0b8ea1232ac308781a34;hpb=46b4b9240f7a7130660eceaf380f3f248f041fee;p=palacios.git diff --git a/palacios/src/palacios/vmm_xed.c b/palacios/src/palacios/vmm_xed.c index 036501d..e48a1b8 100644 --- a/palacios/src/palacios/vmm_xed.c +++ b/palacios/src/palacios/vmm_xed.c @@ -1,14 +1,69 @@ +#ifdef __DECODER_TEST__ +#include "vmm_decoder.h" +#include "vmm_xed.h" +#include +#include "vm_guest.h" +#include "test.h" +#else #include #include #include #include +#include -static xed_state_t decoder_state; +#endif +static xed_state_t decoder_state; +#define GPR_REGISTER 0 +#define SEGMENT_REGISTER 1 +#define CTRL_REGISTER 2 +#define DEBUG_REGISTER 3 + + + +/* Disgusting mask hack... + I can't think right now, so we'll do it this way... +*/ +static const ullong_t mask_1 = 0x00000000000000ffLL; +static const ullong_t mask_2 = 0x000000000000ffffLL; +static const ullong_t mask_4 = 0x00000000ffffffffLL; +static const ullong_t mask_8 = 0xffffffffffffffffLL; + + +#define MASK(val, length) ({ \ + ullong_t mask = 0x0LL; \ + switch (length) { \ + case 1: \ + mask = mask_1; \ + case 2: \ + mask = mask_2; \ + case 4: \ + mask = mask_4; \ + case 8: \ + mask = mask_8; \ + } \ + val & mask;}) \ + +struct memory_operand { + uint_t segment_size; + addr_t segment; + uint_t base_size; + addr_t base; + uint_t index_size; + addr_t index; + addr_t scale; + uint_t displacement_size; + ullong_t displacement; +}; + + + +// This returns a pointer to a V3_OPCODE_[*] array defined in vmm_decoder.h +static int get_opcode(xed_iform_enum_t iform, addr_t * opcode); 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 get_memory_operand(struct guest_info * info, xed_decoded_inst_t * xed_instr, uint_t index, struct x86_operand * operand); static int set_decoder_mode(struct guest_info * info, xed_state_t * state) { switch (info->cpu_mode) { @@ -40,7 +95,16 @@ static int set_decoder_mode(struct guest_info * info, xed_state_t * state) { return 0; } - +int is_flags_reg(xed_reg_enum_t xed_reg) { + switch (xed_reg) { + case XED_REG_FLAGS: + case XED_REG_EFLAGS: + case XED_REG_RFLAGS: + return 1; + default: + return 0; + } +} @@ -51,6 +115,43 @@ int init_decoder() { } +int v3_basic_mem_decode(struct guest_info * info, addr_t instr_ptr, uint_t * size, uint_t * instr_length) { + xed_decoded_inst_t xed_instr; + xed_error_enum_t xed_error; + + + if (set_decoder_mode(info, &decoder_state) == -1) { + PrintError("Could not set decoder mode\n"); + return -1; + } + + + xed_decoded_inst_zero_set_mode(&xed_instr, &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_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; + } + + *size = xed_decoded_inst_get_memory_operand_length(&xed_instr,0); + + return 0; +} + + + int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) { xed_decoded_inst_t xed_instr; xed_error_enum_t xed_error; @@ -66,16 +167,9 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins xed_decoded_inst_zero_set_mode(&xed_instr, &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) { @@ -88,126 +182,241 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins instr->instr_length = xed_decoded_inst_get_length(&xed_instr); instr->num_operands = xed_decoded_inst_noperands(&xed_instr); + xed_iform_enum_t iform = xed_decoded_inst_get_iform_enum(&xed_instr); + + + PrintDebug("iform=%s\n", xed_iform_enum_t2str(iform)); + + + if (instr->num_operands > 3) { + PrintDebug("Special Case Not Handled\n"); + return -1; + // special case + } else if (instr->num_operands == 3) { + const xed_operand_t * op = xed_inst_operand(xi, 2); + xed_operand_enum_t op_enum = xed_operand_name(op); + + if ((!xed_operand_is_register(op_enum)) || + (!is_flags_reg(xed_decoded_inst_get_reg(&xed_instr, op_enum)))) { + // special case + PrintDebug("Special Case not handled\n"); + return -1; + } + } + - PrintDebug("Number of operands: %d\n", instr->num_operands); + + + + if (get_opcode(iform, &(instr->opcode)) == -1) { + PrintDebug("Could not get opcode. (iform=%s)\n", xed_iform_enum_t2str(iform)); + return -1; + } + + + + + //PrintDebug("Number of operands: %d\n", instr->num_operands); + //PrintDebug("INSTR length: %d\n", instr->instr_length); // set first operand if (instr->num_operands >= 1) { const xed_operand_t * op = xed_inst_operand(xi, 0); - xed_operand_type_enum_t op_type = xed_operand_type(op); - - switch (op_type) { - case XED_OPERAND_TYPE_REG: - { - xed_operand_enum_t op_enum = xed_operand_name(op); - xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum); - if (xed_reg_to_v3_reg(info, - xed_reg, - &(instr->dst_operand.operand), - &(instr->dst_operand.size)) == -1) { - - PrintError("First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg)); - return -1; + xed_operand_enum_t op_enum = xed_operand_name(op); + + struct x86_operand * v3_op = NULL; + + if (xed_operand_written(op)) { + v3_op = &(instr->dst_operand); + } else { + v3_op = &(instr->src_operand); + } + + + if (xed_operand_is_register(op_enum)) { + xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum); + int v3_reg_type = xed_reg_to_v3_reg(info, + xed_reg, + &(v3_op->operand), + &(v3_op->size)); + + if (v3_reg_type == -1) { + PrintError("First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg)); + v3_op->type = INVALID_OPERAND; + return -1; + } else if (v3_reg_type == SEGMENT_REGISTER) { + struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand); + v3_op->operand = (addr_t)&(seg_reg->selector); + } + + v3_op->type = REG_OPERAND; + } else { + + switch (op_enum) { + + case XED_OPERAND_MEM0: + { + /* + struct x86_operand * operand = &(instr->dst_operand); + + if (xed_decoded_inst_mem_read(&xed_instr, 0)) { + operand = &(instr->src_operand); + } else if (xed_decoded_inst_mem_written(&xed_instr, 0)) { + operand = &(instr->dst_operand); + } + */ + + if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) { + PrintError("Could not get first memory operand\n"); + return -1; + } } + break; + + case XED_OPERAND_MEM1: + case XED_OPERAND_IMM1: + // illegal + PrintError("Illegal Operand Order\n"); + return -1; + + + case XED_OPERAND_IMM0: + case XED_OPERAND_AGEN: + case XED_OPERAND_PTR: + case XED_OPERAND_RELBR: + default: + PrintError("Unhandled Operand Type\n"); + return -1; + + } - case XED_OPERAND_TYPE_INVALID: - case XED_OPERAND_TYPE_ERROR: - case XED_OPERAND_TYPE_IMM: - case XED_OPERAND_TYPE_IMM_CONST: - case XED_OPERAND_TYPE_NT_LOOKUP_FN: - case XED_OPERAND_TYPE_LAST: - PrintError("Unhandled first operand type %s\n", xed_operand_type_enum_t2str(op_type)); - return -1; } } // set second operand if (instr->num_operands >= 2) { - const xed_operand_t * op = xed_inst_operand(xi, 0); - xed_operand_type_enum_t op_type = xed_operand_type(op); + const xed_operand_t * op = xed_inst_operand(xi, 1); + // xed_operand_type_enum_t op_type = xed_operand_type(op); + xed_operand_enum_t op_enum = xed_operand_name(op); + + struct x86_operand * v3_op; + + if (xed_operand_written(op)) { + v3_op = &(instr->dst_operand); + } else { + v3_op = &(instr->src_operand); + } + + + if (xed_operand_is_register(op_enum)) { + xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum); + int v3_reg_type = xed_reg_to_v3_reg(info, + xed_reg, + &(v3_op->operand), + &(v3_op->size)); + if (v3_reg_type == -1) { + PrintError("Second operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg)); + v3_op->type = INVALID_OPERAND; + return -1; + } else if (v3_reg_type == SEGMENT_REGISTER) { + struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand); + v3_op->operand = (addr_t)&(seg_reg->selector); + } + + v3_op->type = REG_OPERAND; - switch (op_type) { - case XED_OPERAND_TYPE_REG: - { - xed_operand_enum_t op_enum = xed_operand_name(op); - xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum); - if (xed_reg_to_v3_reg(info, - xed_reg, - &(instr->src_operand.operand), - &(instr->src_operand.size)) == -1) { - - PrintError("Second operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg)); - return -1; + + } else { + + switch (op_enum) { + + case XED_OPERAND_MEM0: + { + + /* + if (xed_decoded_inst_mem_read(&xed_instr, 0)) { + v3_op = &(instr->src_operand); + } else if (xed_decoded_inst_mem_written(&xed_instr, 0)) { + v3_op = &(instr->dst_operand); + } + */ + + if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) { + PrintError("Could not get first memory operand\n"); + return -1; + } } + break; + + case XED_OPERAND_IMM0: + { + instr->src_operand.size = xed_decoded_inst_get_immediate_width(&xed_instr); + + if (instr->src_operand.size > 4) { + PrintError("Unhandled 64 bit immediates\n"); + return -1; + } + instr->src_operand.operand = xed_decoded_inst_get_unsigned_immediate(&xed_instr); + + instr->src_operand.type = IMM_OPERAND; + + } + break; + + case XED_OPERAND_MEM1: + case XED_OPERAND_IMM1: + // illegal + PrintError("Illegal Operand Order\n"); + return -1; + + case XED_OPERAND_AGEN: + case XED_OPERAND_PTR: + case XED_OPERAND_RELBR: + default: + PrintError("Unhandled Operand Type\n"); + return -1; } - case XED_OPERAND_TYPE_INVALID: - case XED_OPERAND_TYPE_ERROR: - case XED_OPERAND_TYPE_IMM: - case XED_OPERAND_TYPE_IMM_CONST: - case XED_OPERAND_TYPE_NT_LOOKUP_FN: - case XED_OPERAND_TYPE_LAST: - PrintError("Unhandled second operand type %s\n", xed_operand_type_enum_t2str(op_type)); - return -1; } + } // set third operand if (instr->num_operands >= 3) { - const xed_operand_t * op = xed_inst_operand(xi, 0); - xed_operand_type_enum_t op_type = xed_operand_type(op); - - switch (op_type) { - case XED_OPERAND_TYPE_REG: - { - xed_operand_enum_t op_enum = xed_operand_name(op); - xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum); - if (xed_reg_to_v3_reg(info, - xed_reg, - &(instr->extra_operand.operand), - &(instr->extra_operand.size)) == -1) { - - PrintError("Third operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg)); - return -1; - } + const xed_operand_t * op = xed_inst_operand(xi, 2); + // xed_operand_type_enum_t op_type = xed_operand_type(op); + xed_operand_enum_t op_enum = xed_operand_name(op); + + if (xed_operand_is_register(op_enum)) { + xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum); + int v3_reg_type = xed_reg_to_v3_reg(info, + xed_reg, + &(instr->third_operand.operand), + &(instr->third_operand.size)); + + if (v3_reg_type == -1) { + PrintError("Third operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg)); + instr->third_operand.type = INVALID_OPERAND; + return -1; + } else if (v3_reg_type == SEGMENT_REGISTER) { + struct v3_segment * seg_reg = (struct v3_segment *)(instr->third_operand.operand); + instr->third_operand.operand = (addr_t)&(seg_reg->selector); } - case XED_OPERAND_TYPE_INVALID: - case XED_OPERAND_TYPE_ERROR: - case XED_OPERAND_TYPE_IMM: - case XED_OPERAND_TYPE_IMM_CONST: - case XED_OPERAND_TYPE_NT_LOOKUP_FN: - case XED_OPERAND_TYPE_LAST: - PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type)); + + + instr->third_operand.type = REG_OPERAND; + + + } else { + // PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type)); return -1; } } - /* - PrintDebug("category: %s\n", xed_category_enum_t2str(xed_decoded_inst_get_category(&xed_instr)));; - PrintDebug("ISA-extension:%s\n ",xed_extension_enum_t2str(xed_decoded_inst_get_extension(&xed_instr))); - PrintDebug(" instruction-length: %d\n ", xed_decoded_inst_get_length(&xed_instr)); - PrintDebug(" operand-size:%d\n ", xed_operand_values_get_effective_operand_width(xed_decoded_inst_operands_const(&xed_instr))); - PrintDebug("address-size:%d\n ", xed_operand_values_get_effective_address_width(xed_decoded_inst_operands_const(&xed_instr))); - PrintDebug("iform-enum-name:%s\n ",xed_iform_enum_t2str(xed_decoded_inst_get_iform_enum(&xed_instr))); - PrintDebug("iform-enum-name-dispatch (zero based):%d\n ", xed_decoded_inst_get_iform_enum_dispatch(&xed_instr)); - PrintDebug("iclass-max-iform-dispatch: %d\n ", xed_iform_max_per_iclass(xed_decoded_inst_get_iclass(&xed_instr))); - */ - // operands - // print_operands(&xed_instr); - - // memops - // print_memops(&xed_instr); - - // flags - //print_flags(&xed_instr); - - // attributes - //print_attributes(&xed_instr);*/ - - return -1; + return 0; } @@ -217,6 +426,95 @@ int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_b } + + + +static int get_memory_operand(struct guest_info * info, xed_decoded_inst_t * xed_instr, uint_t op_index, struct x86_operand * operand) { + struct memory_operand mem_op; + + addr_t seg; + addr_t base; + addr_t scale; + addr_t index; + ullong_t displacement; + // struct v3_segment * seg_reg; + + + + + memset((void*)&mem_op, '\0', sizeof(struct memory_operand)); + + xed_reg_enum_t xed_seg = xed_decoded_inst_get_seg_reg(xed_instr, op_index); + if (xed_seg != XED_REG_INVALID) { + struct v3_segment *tmp_segment; + if (xed_reg_to_v3_reg(info, xed_seg, (addr_t *)&tmp_segment, &(mem_op.segment_size)) == -1) { + PrintError("Unhandled Segment Register\n"); + return -1; + } + mem_op.segment = tmp_segment->base; + } + + xed_reg_enum_t xed_base = xed_decoded_inst_get_base_reg(xed_instr, op_index); + if (xed_base != XED_REG_INVALID) { + addr_t base_reg; + if (xed_reg_to_v3_reg(info, xed_base, &base_reg, &(mem_op.base_size)) == -1) { + PrintError("Unhandled Base register\n"); + return -1; + } + mem_op.base = *(addr_t *)base_reg; + } + + + + xed_reg_enum_t xed_idx = xed_decoded_inst_get_index_reg(xed_instr, op_index); + if ((op_index == 0) && (xed_idx != XED_REG_INVALID)) { + addr_t index_reg; + + if (xed_reg_to_v3_reg(info, xed_idx, &index_reg, &(mem_op.index_size)) == -1) { + PrintError("Unhandled Index Register\n"); + return -1; + } + + mem_op.index= *(addr_t *)index_reg; + + xed_uint_t xed_scale = xed_decoded_inst_get_scale(xed_instr, op_index); + if (xed_scale != 0) { + mem_op.scale = xed_scale; + } + } + + + xed_uint_t disp_bits = xed_decoded_inst_get_memory_displacement_width(xed_instr, op_index); + if (disp_bits) { + xed_int64_t xed_disp = xed_decoded_inst_get_memory_displacement(xed_instr, op_index); + + mem_op.displacement_size = disp_bits / 8; + mem_op.displacement = xed_disp; + + } + + operand->type = MEM_OPERAND; + operand->size = xed_decoded_inst_get_memory_operand_length(xed_instr, op_index); + + + + PrintDebug("Struct: Seg=%x, base=%x, index=%x, scale=%x, displacement=%x\n", + mem_op.segment, mem_op.base, mem_op.index, mem_op.scale, mem_op.displacement); + + + seg = mem_op.segment; + base = MASK(mem_op.base, mem_op.base_size); + index = MASK(mem_op.index, mem_op.index_size); + scale = mem_op.scale; + displacement = MASK(mem_op.displacement, mem_op.displacement_size); + + PrintDebug("Seg=%x, base=%x, index=%x, scale=%x, displacement=%x\n", seg, base, index, scale, displacement); + + operand->operand = seg + base + (scale * index) + displacement; + return 0; +} + + 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) { switch (xed_reg) { @@ -231,158 +529,158 @@ static int xed_reg_to_v3_reg(struct guest_info * info, xed_reg_enum_t xed_reg, a case XED_REG_RAX: *v3_reg = (addr_t)&(info->vm_regs.rax); *reg_len = 8; - break; + return GPR_REGISTER; case XED_REG_EAX: *v3_reg = (addr_t)&(info->vm_regs.rax); *reg_len = 4; - break; + return GPR_REGISTER; case XED_REG_AX: *v3_reg = (addr_t)&(info->vm_regs.rax); *reg_len = 2; - break; + return GPR_REGISTER; case XED_REG_AH: *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1; *reg_len = 1; - break; + return GPR_REGISTER; case XED_REG_AL: *v3_reg = (addr_t)&(info->vm_regs.rax); *reg_len = 1; - break; + return GPR_REGISTER; case XED_REG_RCX: *v3_reg = (addr_t)&(info->vm_regs.rcx); *reg_len = 8; - break; + return GPR_REGISTER; case XED_REG_ECX: *v3_reg = (addr_t)&(info->vm_regs.rcx); *reg_len = 4; - break; + return GPR_REGISTER; case XED_REG_CX: *v3_reg = (addr_t)&(info->vm_regs.rcx); *reg_len = 2; - break; + return GPR_REGISTER; case XED_REG_CH: *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1; *reg_len = 1; - break; + return GPR_REGISTER; case XED_REG_CL: *v3_reg = (addr_t)&(info->vm_regs.rcx); *reg_len = 1; - break; + return GPR_REGISTER; case XED_REG_RDX: *v3_reg = (addr_t)&(info->vm_regs.rdx); *reg_len = 8; - break; + return GPR_REGISTER; case XED_REG_EDX: *v3_reg = (addr_t)&(info->vm_regs.rdx); *reg_len = 4; - break; + return GPR_REGISTER; case XED_REG_DX: *v3_reg = (addr_t)&(info->vm_regs.rdx); *reg_len = 2; - break; + return GPR_REGISTER; case XED_REG_DH: *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1; *reg_len = 1; - break; + return GPR_REGISTER; case XED_REG_DL: *v3_reg = (addr_t)&(info->vm_regs.rdx); *reg_len = 1; - break; + return GPR_REGISTER; case XED_REG_RBX: *v3_reg = (addr_t)&(info->vm_regs.rbx); *reg_len = 8; - break; + return GPR_REGISTER; case XED_REG_EBX: *v3_reg = (addr_t)&(info->vm_regs.rbx); *reg_len = 4; - break; + return GPR_REGISTER; case XED_REG_BX: *v3_reg = (addr_t)&(info->vm_regs.rbx); *reg_len = 2; - break; + return GPR_REGISTER; case XED_REG_BH: *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1; *reg_len = 1; - break; + return GPR_REGISTER; case XED_REG_BL: *v3_reg = (addr_t)&(info->vm_regs.rbx); *reg_len = 1; - break; + return GPR_REGISTER; case XED_REG_RSP: *v3_reg = (addr_t)&(info->vm_regs.rsp); *reg_len = 8; - break; + return GPR_REGISTER; case XED_REG_ESP: *v3_reg = (addr_t)&(info->vm_regs.rsp); *reg_len = 4; - break; + return GPR_REGISTER; case XED_REG_SP: *v3_reg = (addr_t)&(info->vm_regs.rsp); *reg_len = 2; - break; + return GPR_REGISTER; case XED_REG_SPL: *v3_reg = (addr_t)&(info->vm_regs.rsp); *reg_len = 1; - break; + return GPR_REGISTER; case XED_REG_RBP: *v3_reg = (addr_t)&(info->vm_regs.rbp); *reg_len = 8; - break; + return GPR_REGISTER; case XED_REG_EBP: *v3_reg = (addr_t)&(info->vm_regs.rbp); *reg_len = 4; - break; + return GPR_REGISTER; case XED_REG_BP: *v3_reg = (addr_t)&(info->vm_regs.rbp); *reg_len = 2; - break; + return GPR_REGISTER; case XED_REG_BPL: *v3_reg = (addr_t)&(info->vm_regs.rbp); *reg_len = 1; - break; + return GPR_REGISTER; case XED_REG_RSI: *v3_reg = (addr_t)&(info->vm_regs.rsi); *reg_len = 8; - break; + return GPR_REGISTER; case XED_REG_ESI: *v3_reg = (addr_t)&(info->vm_regs.rsi); *reg_len = 4; - break; + return GPR_REGISTER; case XED_REG_SI: *v3_reg = (addr_t)&(info->vm_regs.rsi); *reg_len = 2; - break; + return GPR_REGISTER; case XED_REG_SIL: *v3_reg = (addr_t)&(info->vm_regs.rsi); *reg_len = 1; - break; + return GPR_REGISTER; case XED_REG_RDI: *v3_reg = (addr_t)&(info->vm_regs.rdi); *reg_len = 8; - break; + return GPR_REGISTER; case XED_REG_EDI: *v3_reg = (addr_t)&(info->vm_regs.rdi); *reg_len = 4; - break; + return GPR_REGISTER; case XED_REG_DI: *v3_reg = (addr_t)&(info->vm_regs.rdi); *reg_len = 2; - break; + return GPR_REGISTER; case XED_REG_DIL: *v3_reg = (addr_t)&(info->vm_regs.rdi); *reg_len = 1; - break; + return GPR_REGISTER; /* @@ -391,49 +689,49 @@ static int xed_reg_to_v3_reg(struct guest_info * info, xed_reg_enum_t xed_reg, a case XED_REG_RIP: *v3_reg = (addr_t)&(info->rip); *reg_len = 8; - break; + return CTRL_REGISTER; case XED_REG_EIP: *v3_reg = (addr_t)&(info->rip); *reg_len = 4; - break; + return CTRL_REGISTER; case XED_REG_IP: *v3_reg = (addr_t)&(info->rip); *reg_len = 2; - break; + return CTRL_REGISTER; case XED_REG_FLAGS: *v3_reg = (addr_t)&(info->ctrl_regs.rflags); *reg_len = 2; - break; + return CTRL_REGISTER; case XED_REG_EFLAGS: *v3_reg = (addr_t)&(info->ctrl_regs.rflags); *reg_len = 4; - break; + return CTRL_REGISTER; case XED_REG_RFLAGS: *v3_reg = (addr_t)&(info->ctrl_regs.rflags); *reg_len = 8; - break; + return CTRL_REGISTER; case XED_REG_CR0: *v3_reg = (addr_t)&(info->ctrl_regs.cr0); *reg_len = 4; - break; + return CTRL_REGISTER; case XED_REG_CR2: *v3_reg = (addr_t)&(info->ctrl_regs.cr2); *reg_len = 4; - break; + return CTRL_REGISTER; case XED_REG_CR3: *v3_reg = (addr_t)&(info->ctrl_regs.cr3); *reg_len = 4; - break; + return CTRL_REGISTER; case XED_REG_CR4: *v3_reg = (addr_t)&(info->ctrl_regs.cr4); *reg_len = 4; - break; + return CTRL_REGISTER; case XED_REG_CR8: *v3_reg = (addr_t)&(info->ctrl_regs.cr8); *reg_len = 4; - break; + return CTRL_REGISTER; case XED_REG_CR1: case XED_REG_CR5: @@ -455,29 +753,23 @@ static int xed_reg_to_v3_reg(struct guest_info * info, xed_reg_enum_t xed_reg, a * SEGMENT REGS */ case XED_REG_CS: - *v3_reg = (addr_t)&(info->segments.cs.selector); - *reg_len = 16; - break; + *v3_reg = (addr_t)&(info->segments.cs); + return SEGMENT_REGISTER; case XED_REG_DS: - *v3_reg = (addr_t)&(info->segments.ds.selector); - *reg_len = 16; - break; + *v3_reg = (addr_t)&(info->segments.ds); + return SEGMENT_REGISTER; case XED_REG_ES: - *v3_reg = (addr_t)&(info->segments.es.selector); - *reg_len = 16; - break; + *v3_reg = (addr_t)&(info->segments.es); + return SEGMENT_REGISTER; case XED_REG_SS: - *v3_reg = (addr_t)&(info->segments.ss.selector); - *reg_len = 16; - break; + *v3_reg = (addr_t)&(info->segments.ss); + return SEGMENT_REGISTER; case XED_REG_FS: - *v3_reg = (addr_t)&(info->segments.fs.selector); - *reg_len = 16; - break; + *v3_reg = (addr_t)&(info->segments.fs); + return SEGMENT_REGISTER; case XED_REG_GS: - *v3_reg = (addr_t)&(info->segments.fs.selector); - *reg_len = 16; - break; + *v3_reg = (addr_t)&(info->segments.gs); + return SEGMENT_REGISTER; case XED_REG_GDTR: @@ -632,3 +924,35 @@ static int xed_reg_to_v3_reg(struct guest_info * info, xed_reg_enum_t xed_reg, a return 0; } + + + +static int get_opcode(xed_iform_enum_t iform, addr_t * opcode) { + + switch (iform) { + case XED_IFORM_MOV_CR_GPR64_CR: + case XED_IFORM_MOV_CR_GPR32_CR: + *opcode = (addr_t)&V3_OPCODE_MOVCR2; + break; + + case XED_IFORM_MOV_CR_CR_GPR64: + case XED_IFORM_MOV_CR_CR_GPR32: + *opcode = (addr_t)&V3_OPCODE_MOV2CR; + break; + + + case XED_IFORM_LMSW_GPR16: + *opcode = (addr_t)&V3_OPCODE_LMSW; + break; + + case XED_IFORM_CLTS: + *opcode = (addr_t)&V3_OPCODE_CLTS; + break; + + default: + *opcode = 0; + return -1; + } + + return 0; +}