1 #ifdef __DECODER_TEST__
2 #include "vmm_decoder.h"
4 #include <xed/xed-interface.h>
8 #include <palacios/vmm_decoder.h>
9 #include <palacios/vmm_xed.h>
10 #include <xed/xed-interface.h>
11 #include <palacios/vm_guest.h>
12 #include <palacios/vmm.h>
16 static xed_state_t decoder_state;
18 #define GPR_REGISTER 0
19 #define SEGMENT_REGISTER 1
20 #define CTRL_REGISTER 2
21 #define DEBUG_REGISTER 3
25 /* Disgusting mask hack...
26 I can't think right now, so we'll do it this way...
28 static const ullong_t mask_1 = 0x00000000000000ffLL;
29 static const ullong_t mask_2 = 0x000000000000ffffLL;
30 static const ullong_t mask_4 = 0x00000000ffffffffLL;
31 static const ullong_t mask_8 = 0xffffffffffffffffLL;
34 #define MASK(val, length) ({ \
35 ullong_t mask = 0x0LL; \
48 struct memory_operand {
56 uint_t displacement_size;
57 ullong_t displacement;
62 // This returns a pointer to a V3_OPCODE_[*] array defined in vmm_decoder.h
63 static int get_opcode(xed_iform_enum_t iform, addr_t * opcode);
65 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);
66 static int get_memory_operand(struct guest_info * info, xed_decoded_inst_t * xed_instr, uint_t index, struct x86_operand * operand);
68 static int set_decoder_mode(struct guest_info * info, xed_state_t * state) {
69 switch (info->cpu_mode) {
71 if (state->mmode != XED_MACHINE_MODE_LEGACY_16) {
73 XED_MACHINE_MODE_LEGACY_16,
74 XED_ADDRESS_WIDTH_16b,
75 XED_ADDRESS_WIDTH_16b);
80 if (state->mmode != XED_MACHINE_MODE_LEGACY_32) {
82 XED_MACHINE_MODE_LEGACY_32,
83 XED_ADDRESS_WIDTH_32b,
84 XED_ADDRESS_WIDTH_32b);
88 if (state->mmode != XED_MACHINE_MODE_LONG_64) {
89 state->mmode = XED_MACHINE_MODE_LONG_64;
98 int is_flags_reg(xed_reg_enum_t xed_reg) {
113 xed_state_zero(&decoder_state);
118 int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
119 xed_decoded_inst_t xed_instr;
120 xed_error_enum_t xed_error;
124 if (set_decoder_mode(info, &decoder_state) == -1) {
125 PrintError("Could not set decoder mode\n");
131 xed_decoded_inst_zero_set_mode(&xed_instr, &decoder_state);
133 xed_error = xed_decode(&xed_instr,
134 REINTERPRET_CAST(const xed_uint8_t *, instr_ptr),
135 XED_MAX_INSTRUCTION_BYTES);
138 if (xed_error != XED_ERROR_NONE) {
139 PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
143 const xed_inst_t * xi = xed_decoded_inst_inst(&xed_instr);
145 instr->instr_length = xed_decoded_inst_get_length(&xed_instr);
146 instr->num_operands = xed_decoded_inst_noperands(&xed_instr);
148 xed_iform_enum_t iform = xed_decoded_inst_get_iform_enum(&xed_instr);
151 PrintDebug("iform=%s\n", xed_iform_enum_t2str(iform));
154 if (instr->num_operands > 3) {
155 PrintDebug("Special Case Not Handled\n");
158 } else if (instr->num_operands == 3) {
159 const xed_operand_t * op = xed_inst_operand(xi, 2);
160 xed_operand_enum_t op_enum = xed_operand_name(op);
162 if ((!xed_operand_is_register(op_enum)) ||
163 (!is_flags_reg(xed_decoded_inst_get_reg(&xed_instr, op_enum)))) {
165 PrintDebug("Special Case not handled\n");
174 if (get_opcode(iform, &(instr->opcode)) == -1) {
175 PrintDebug("Could not get opcode. (iform=%s)\n", xed_iform_enum_t2str(iform));
182 //PrintDebug("Number of operands: %d\n", instr->num_operands);
183 //PrintDebug("INSTR length: %d\n", instr->instr_length);
186 if (instr->num_operands >= 1) {
187 const xed_operand_t * op = xed_inst_operand(xi, 0);
188 xed_operand_enum_t op_enum = xed_operand_name(op);
190 struct x86_operand * v3_op = NULL;
192 if (xed_operand_written(op)) {
193 v3_op = &(instr->dst_operand);
195 v3_op = &(instr->src_operand);
199 if (xed_operand_is_register(op_enum)) {
200 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
201 int v3_reg_type = xed_reg_to_v3_reg(info,
206 if (v3_reg_type == -1) {
207 PrintError("First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
208 v3_op->type = INVALID_OPERAND;
210 } else if (v3_reg_type == SEGMENT_REGISTER) {
211 struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
212 v3_op->operand = (addr_t)&(seg_reg->selector);
215 v3_op->type = REG_OPERAND;
220 case XED_OPERAND_MEM0:
223 struct x86_operand * operand = &(instr->dst_operand);
225 if (xed_decoded_inst_mem_read(&xed_instr, 0)) {
226 operand = &(instr->src_operand);
227 } else if (xed_decoded_inst_mem_written(&xed_instr, 0)) {
228 operand = &(instr->dst_operand);
232 if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
233 PrintError("Could not get first memory operand\n");
239 case XED_OPERAND_MEM1:
240 case XED_OPERAND_IMM1:
242 PrintError("Illegal Operand Order\n");
246 case XED_OPERAND_IMM0:
247 case XED_OPERAND_AGEN:
248 case XED_OPERAND_PTR:
249 case XED_OPERAND_RELBR:
251 PrintError("Unhandled Operand Type\n");
259 // set second operand
260 if (instr->num_operands >= 2) {
261 const xed_operand_t * op = xed_inst_operand(xi, 1);
262 // xed_operand_type_enum_t op_type = xed_operand_type(op);
263 xed_operand_enum_t op_enum = xed_operand_name(op);
265 struct x86_operand * v3_op;
267 if (xed_operand_written(op)) {
268 v3_op = &(instr->dst_operand);
270 v3_op = &(instr->src_operand);
274 if (xed_operand_is_register(op_enum)) {
275 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
276 int v3_reg_type = xed_reg_to_v3_reg(info,
280 if (v3_reg_type == -1) {
281 PrintError("Second operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
282 v3_op->type = INVALID_OPERAND;
284 } else if (v3_reg_type == SEGMENT_REGISTER) {
285 struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
286 v3_op->operand = (addr_t)&(seg_reg->selector);
289 v3_op->type = REG_OPERAND;
296 case XED_OPERAND_MEM0:
300 if (xed_decoded_inst_mem_read(&xed_instr, 0)) {
301 v3_op = &(instr->src_operand);
302 } else if (xed_decoded_inst_mem_written(&xed_instr, 0)) {
303 v3_op = &(instr->dst_operand);
307 if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
308 PrintError("Could not get first memory operand\n");
314 case XED_OPERAND_IMM0:
316 instr->src_operand.size = xed_decoded_inst_get_immediate_width(&xed_instr);
318 if (instr->src_operand.size > 4) {
319 PrintError("Unhandled 64 bit immediates\n");
322 instr->src_operand.operand = xed_decoded_inst_get_unsigned_immediate(&xed_instr);
324 instr->src_operand.type = IMM_OPERAND;
329 case XED_OPERAND_MEM1:
330 case XED_OPERAND_IMM1:
332 PrintError("Illegal Operand Order\n");
335 case XED_OPERAND_AGEN:
336 case XED_OPERAND_PTR:
337 case XED_OPERAND_RELBR:
339 PrintError("Unhandled Operand Type\n");
347 if (instr->num_operands >= 3) {
348 const xed_operand_t * op = xed_inst_operand(xi, 2);
349 // xed_operand_type_enum_t op_type = xed_operand_type(op);
350 xed_operand_enum_t op_enum = xed_operand_name(op);
352 if (xed_operand_is_register(op_enum)) {
353 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
354 int v3_reg_type = xed_reg_to_v3_reg(info,
356 &(instr->third_operand.operand),
357 &(instr->third_operand.size));
359 if (v3_reg_type == -1) {
360 PrintError("Third operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
361 instr->third_operand.type = INVALID_OPERAND;
363 } else if (v3_reg_type == SEGMENT_REGISTER) {
364 struct v3_segment * seg_reg = (struct v3_segment *)(instr->third_operand.operand);
365 instr->third_operand.operand = (addr_t)&(seg_reg->selector);
369 instr->third_operand.type = REG_OPERAND;
373 // PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
386 int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) {
395 static int get_memory_operand(struct guest_info * info, xed_decoded_inst_t * xed_instr, uint_t op_index, struct x86_operand * operand) {
396 struct memory_operand mem_op;
402 ullong_t displacement;
403 // struct v3_segment * seg_reg;
408 memset((void*)&mem_op, '\0', sizeof(struct memory_operand));
410 xed_reg_enum_t xed_seg = xed_decoded_inst_get_seg_reg(xed_instr, op_index);
411 if (xed_seg != XED_REG_INVALID) {
412 struct v3_segment *tmp_segment;
413 if (xed_reg_to_v3_reg(info, xed_seg, (addr_t *)&tmp_segment, &(mem_op.segment_size)) == -1) {
414 PrintError("Unhandled Segment Register\n");
417 mem_op.segment = tmp_segment->base;
420 xed_reg_enum_t xed_base = xed_decoded_inst_get_base_reg(xed_instr, op_index);
421 if (xed_base != XED_REG_INVALID) {
423 if (xed_reg_to_v3_reg(info, xed_base, &base_reg, &(mem_op.base_size)) == -1) {
424 PrintError("Unhandled Base register\n");
427 mem_op.base = *(addr_t *)base_reg;
432 xed_reg_enum_t xed_idx = xed_decoded_inst_get_index_reg(xed_instr, op_index);
433 if ((op_index == 0) && (xed_idx != XED_REG_INVALID)) {
436 if (xed_reg_to_v3_reg(info, xed_idx, &index_reg, &(mem_op.index_size)) == -1) {
437 PrintError("Unhandled Index Register\n");
441 mem_op.index= *(addr_t *)index_reg;
443 xed_uint_t xed_scale = xed_decoded_inst_get_scale(xed_instr, op_index);
444 if (xed_scale != 0) {
445 mem_op.scale = xed_scale;
450 xed_uint_t disp_bits = xed_decoded_inst_get_memory_displacement_width(xed_instr, op_index);
452 xed_int64_t xed_disp = xed_decoded_inst_get_memory_displacement(xed_instr, op_index);
454 mem_op.displacement_size = disp_bits / 8;
455 mem_op.displacement = xed_disp;
459 operand->type = MEM_OPERAND;
460 operand->size = xed_decoded_inst_get_memory_operand_length(xed_instr, op_index);
464 PrintDebug("Struct: Seg=%x, base=%x, index=%x, scale=%x, displacement=%x\n",
465 mem_op.segment, mem_op.base, mem_op.index, mem_op.scale, mem_op.displacement);
468 seg = mem_op.segment;
469 base = MASK(mem_op.base, mem_op.base_size);
470 index = MASK(mem_op.index, mem_op.index_size);
471 scale = mem_op.scale;
472 displacement = MASK(mem_op.displacement, mem_op.displacement_size);
474 PrintDebug("Seg=%x, base=%x, index=%x, scale=%x, displacement=%x\n", seg, base, index, scale, displacement);
476 operand->operand = seg + base + (scale * index) + displacement;
481 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) {
484 case XED_REG_INVALID:
493 *v3_reg = (addr_t)&(info->vm_regs.rax);
497 *v3_reg = (addr_t)&(info->vm_regs.rax);
501 *v3_reg = (addr_t)&(info->vm_regs.rax);
505 *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
509 *v3_reg = (addr_t)&(info->vm_regs.rax);
514 *v3_reg = (addr_t)&(info->vm_regs.rcx);
518 *v3_reg = (addr_t)&(info->vm_regs.rcx);
522 *v3_reg = (addr_t)&(info->vm_regs.rcx);
526 *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
530 *v3_reg = (addr_t)&(info->vm_regs.rcx);
535 *v3_reg = (addr_t)&(info->vm_regs.rdx);
539 *v3_reg = (addr_t)&(info->vm_regs.rdx);
543 *v3_reg = (addr_t)&(info->vm_regs.rdx);
547 *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
551 *v3_reg = (addr_t)&(info->vm_regs.rdx);
556 *v3_reg = (addr_t)&(info->vm_regs.rbx);
560 *v3_reg = (addr_t)&(info->vm_regs.rbx);
564 *v3_reg = (addr_t)&(info->vm_regs.rbx);
568 *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
572 *v3_reg = (addr_t)&(info->vm_regs.rbx);
578 *v3_reg = (addr_t)&(info->vm_regs.rsp);
582 *v3_reg = (addr_t)&(info->vm_regs.rsp);
586 *v3_reg = (addr_t)&(info->vm_regs.rsp);
590 *v3_reg = (addr_t)&(info->vm_regs.rsp);
595 *v3_reg = (addr_t)&(info->vm_regs.rbp);
599 *v3_reg = (addr_t)&(info->vm_regs.rbp);
603 *v3_reg = (addr_t)&(info->vm_regs.rbp);
607 *v3_reg = (addr_t)&(info->vm_regs.rbp);
614 *v3_reg = (addr_t)&(info->vm_regs.rsi);
618 *v3_reg = (addr_t)&(info->vm_regs.rsi);
622 *v3_reg = (addr_t)&(info->vm_regs.rsi);
626 *v3_reg = (addr_t)&(info->vm_regs.rsi);
632 *v3_reg = (addr_t)&(info->vm_regs.rdi);
636 *v3_reg = (addr_t)&(info->vm_regs.rdi);
640 *v3_reg = (addr_t)&(info->vm_regs.rdi);
644 *v3_reg = (addr_t)&(info->vm_regs.rdi);
653 *v3_reg = (addr_t)&(info->rip);
655 return CTRL_REGISTER;
657 *v3_reg = (addr_t)&(info->rip);
659 return CTRL_REGISTER;
661 *v3_reg = (addr_t)&(info->rip);
663 return CTRL_REGISTER;
666 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
668 return CTRL_REGISTER;
670 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
672 return CTRL_REGISTER;
674 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
676 return CTRL_REGISTER;
679 *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
681 return CTRL_REGISTER;
683 *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
685 return CTRL_REGISTER;
687 *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
689 return CTRL_REGISTER;
691 *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
693 return CTRL_REGISTER;
695 *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
697 return CTRL_REGISTER;
719 *v3_reg = (addr_t)&(info->segments.cs);
720 return SEGMENT_REGISTER;
722 *v3_reg = (addr_t)&(info->segments.ds);
723 return SEGMENT_REGISTER;
725 *v3_reg = (addr_t)&(info->segments.es);
726 return SEGMENT_REGISTER;
728 *v3_reg = (addr_t)&(info->segments.ss);
729 return SEGMENT_REGISTER;
731 *v3_reg = (addr_t)&(info->segments.fs);
732 return SEGMENT_REGISTER;
734 *v3_reg = (addr_t)&(info->segments.gs);
735 return SEGMENT_REGISTER;
742 PrintError("Segment selector operand... Don't know how to handle this...\n");
845 case XED_REG_STACKPUSH:
846 case XED_REG_STACKPOP:
852 case XED_REG_X87CONTROL:
853 case XED_REG_X87STATUS:
856 case XED_REG_X87PUSH:
858 case XED_REG_X87POP2:
893 static int get_opcode(xed_iform_enum_t iform, addr_t * opcode) {
896 case XED_IFORM_MOV_CR_GPR64_CR:
897 case XED_IFORM_MOV_CR_GPR32_CR:
898 *opcode = (addr_t)&V3_OPCODE_MOVCR2;
901 case XED_IFORM_MOV_CR_CR_GPR64:
902 case XED_IFORM_MOV_CR_CR_GPR32:
903 *opcode = (addr_t)&V3_OPCODE_MOV2CR;
907 case XED_IFORM_LMSW_GPR16:
908 *opcode = (addr_t)&V3_OPCODE_LMSW;
912 *opcode = (addr_t)&V3_OPCODE_CLTS;