1 /* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
2 /* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
5 #ifdef __DECODER_TEST__
6 #include "vmm_decoder.h"
8 #include <xed/xed-interface.h>
12 #include <palacios/vmm_decoder.h>
13 #include <palacios/vmm_xed.h>
14 #include <xed/xed-interface.h>
15 #include <palacios/vm_guest.h>
16 #include <palacios/vmm.h>
21 static xed_state_t decoder_state;
23 #define GPR_REGISTER 0
24 #define SEGMENT_REGISTER 1
25 #define CTRL_REGISTER 2
26 #define DEBUG_REGISTER 3
30 /* Disgusting mask hack...
31 I can't think right now, so we'll do it this way...
33 static const ullong_t mask_1 = 0x00000000000000ffLL;
34 static const ullong_t mask_2 = 0x000000000000ffffLL;
35 static const ullong_t mask_4 = 0x00000000ffffffffLL;
36 static const ullong_t mask_8 = 0xffffffffffffffffLL;
39 #define MASK(val, length) ({ \
40 ullong_t mask = 0x0LL; \
53 struct memory_operand {
61 uint_t displacement_size;
62 ullong_t displacement;
67 // This returns a pointer to a V3_OPCODE_[*] array defined in vmm_decoder.h
68 static int get_opcode(xed_iform_enum_t iform, addr_t * opcode);
70 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);
71 static int get_memory_operand(struct guest_info * info, xed_decoded_inst_t * xed_instr, uint_t index, struct x86_operand * operand);
73 static int set_decoder_mode(struct guest_info * info, xed_state_t * state) {
74 switch (info->cpu_mode) {
76 if (state->mmode != XED_MACHINE_MODE_LEGACY_16) {
78 XED_MACHINE_MODE_LEGACY_16,
79 XED_ADDRESS_WIDTH_16b,
80 XED_ADDRESS_WIDTH_16b);
85 if (state->mmode != XED_MACHINE_MODE_LEGACY_32) {
87 XED_MACHINE_MODE_LEGACY_32,
88 XED_ADDRESS_WIDTH_32b,
89 XED_ADDRESS_WIDTH_32b);
93 if (state->mmode != XED_MACHINE_MODE_LONG_64) {
94 state->mmode = XED_MACHINE_MODE_LONG_64;
103 int is_flags_reg(xed_reg_enum_t xed_reg) {
118 xed_state_zero(&decoder_state);
124 int v3_basic_mem_decode(struct guest_info * info, addr_t instr_ptr, struct basic_instr_info * instr_info) {
125 xed_decoded_inst_t xed_instr;
126 xed_error_enum_t xed_error;
129 if (set_decoder_mode(info, &decoder_state) == -1) {
130 PrintError("Could not set decoder mode\n");
135 xed_decoded_inst_zero_set_mode(&xed_instr, &decoder_state);
137 xed_error = xed_decode(&xed_instr,
138 REINTERPRET_CAST(const xed_uint8_t *, instr_ptr),
139 XED_MAX_INSTRUCTION_BYTES);
141 if (xed_error != XED_ERROR_NONE) {
142 PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
146 instr_info->instr_length = xed_decoded_inst_get_length(&xed_instr);
149 if (xed_decoded_inst_number_of_memory_operands(&xed_instr) == 0) {
150 PrintError("Tried to decode memory operation with no memory operands\n");
154 instr_info->op_size = xed_decoded_inst_get_memory_operand_length(&xed_instr, 0);
157 xed_category_enum_t cat = xed_decoded_inst_get_category(&xed_instr);
158 if (cat == XED_CATEGORY_STRINGOP) {
159 instr_info->str_op = 1;
161 instr_info->str_op = 0;
164 xed_operand_values_t * operands = xed_decoded_inst_operands(&xed_instr);
165 if (xed_operand_values_has_real_rep(operands)) {
166 instr_info->has_rep = 1;
168 instr_info->has_rep = 0;
176 int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
177 xed_decoded_inst_t xed_instr;
178 xed_error_enum_t xed_error;
182 if (set_decoder_mode(info, &decoder_state) == -1) {
183 PrintError("Could not set decoder mode\n");
189 xed_decoded_inst_zero_set_mode(&xed_instr, &decoder_state);
191 xed_error = xed_decode(&xed_instr,
192 REINTERPRET_CAST(const xed_uint8_t *, instr_ptr),
193 XED_MAX_INSTRUCTION_BYTES);
196 if (xed_error != XED_ERROR_NONE) {
197 PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
201 const xed_inst_t * xi = xed_decoded_inst_inst(&xed_instr);
203 instr->instr_length = xed_decoded_inst_get_length(&xed_instr);
204 instr->num_operands = xed_decoded_inst_noperands(&xed_instr);
206 xed_iform_enum_t iform = xed_decoded_inst_get_iform_enum(&xed_instr);
209 PrintDebug("iform=%s\n", xed_iform_enum_t2str(iform));
212 if (instr->num_operands > 3) {
213 PrintDebug("Special Case Not Handled\n");
216 } else if (instr->num_operands == 3) {
217 const xed_operand_t * op = xed_inst_operand(xi, 2);
218 xed_operand_enum_t op_enum = xed_operand_name(op);
220 if ((!xed_operand_is_register(op_enum)) ||
221 (!is_flags_reg(xed_decoded_inst_get_reg(&xed_instr, op_enum)))) {
223 PrintDebug("Special Case not handled\n");
232 if (get_opcode(iform, &(instr->opcode)) == -1) {
233 PrintDebug("Could not get opcode. (iform=%s)\n", xed_iform_enum_t2str(iform));
240 //PrintDebug("Number of operands: %d\n", instr->num_operands);
241 //PrintDebug("INSTR length: %d\n", instr->instr_length);
244 if (instr->num_operands >= 1) {
245 const xed_operand_t * op = xed_inst_operand(xi, 0);
246 xed_operand_enum_t op_enum = xed_operand_name(op);
248 struct x86_operand * v3_op = NULL;
250 if (xed_operand_written(op)) {
251 v3_op = &(instr->dst_operand);
253 v3_op = &(instr->src_operand);
257 if (xed_operand_is_register(op_enum)) {
258 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
259 int v3_reg_type = xed_reg_to_v3_reg(info,
264 if (v3_reg_type == -1) {
265 PrintError("First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
266 v3_op->type = INVALID_OPERAND;
268 } else if (v3_reg_type == SEGMENT_REGISTER) {
269 struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
270 v3_op->operand = (addr_t)&(seg_reg->selector);
273 v3_op->type = REG_OPERAND;
278 case XED_OPERAND_MEM0:
281 struct x86_operand * operand = &(instr->dst_operand);
283 if (xed_decoded_inst_mem_read(&xed_instr, 0)) {
284 operand = &(instr->src_operand);
285 } else if (xed_decoded_inst_mem_written(&xed_instr, 0)) {
286 operand = &(instr->dst_operand);
290 if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
291 PrintError("Could not get first memory operand\n");
297 case XED_OPERAND_MEM1:
298 case XED_OPERAND_IMM1:
300 PrintError("Illegal Operand Order\n");
304 case XED_OPERAND_IMM0:
305 case XED_OPERAND_AGEN:
306 case XED_OPERAND_PTR:
307 case XED_OPERAND_RELBR:
309 PrintError("Unhandled Operand Type\n");
317 // set second operand
318 if (instr->num_operands >= 2) {
319 const xed_operand_t * op = xed_inst_operand(xi, 1);
320 // xed_operand_type_enum_t op_type = xed_operand_type(op);
321 xed_operand_enum_t op_enum = xed_operand_name(op);
323 struct x86_operand * v3_op;
325 if (xed_operand_written(op)) {
326 v3_op = &(instr->dst_operand);
328 v3_op = &(instr->src_operand);
332 if (xed_operand_is_register(op_enum)) {
333 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
334 int v3_reg_type = xed_reg_to_v3_reg(info,
338 if (v3_reg_type == -1) {
339 PrintError("Second operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
340 v3_op->type = INVALID_OPERAND;
342 } else if (v3_reg_type == SEGMENT_REGISTER) {
343 struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
344 v3_op->operand = (addr_t)&(seg_reg->selector);
347 v3_op->type = REG_OPERAND;
354 case XED_OPERAND_MEM0:
358 if (xed_decoded_inst_mem_read(&xed_instr, 0)) {
359 v3_op = &(instr->src_operand);
360 } else if (xed_decoded_inst_mem_written(&xed_instr, 0)) {
361 v3_op = &(instr->dst_operand);
365 if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
366 PrintError("Could not get first memory operand\n");
372 case XED_OPERAND_IMM0:
374 instr->src_operand.size = xed_decoded_inst_get_immediate_width(&xed_instr);
376 if (instr->src_operand.size > 4) {
377 PrintError("Unhandled 64 bit immediates\n");
380 instr->src_operand.operand = xed_decoded_inst_get_unsigned_immediate(&xed_instr);
382 instr->src_operand.type = IMM_OPERAND;
387 case XED_OPERAND_MEM1:
388 case XED_OPERAND_IMM1:
390 PrintError("Illegal Operand Order\n");
393 case XED_OPERAND_AGEN:
394 case XED_OPERAND_PTR:
395 case XED_OPERAND_RELBR:
397 PrintError("Unhandled Operand Type\n");
405 if (instr->num_operands >= 3) {
406 const xed_operand_t * op = xed_inst_operand(xi, 2);
407 // xed_operand_type_enum_t op_type = xed_operand_type(op);
408 xed_operand_enum_t op_enum = xed_operand_name(op);
410 if (xed_operand_is_register(op_enum)) {
411 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
412 int v3_reg_type = xed_reg_to_v3_reg(info,
414 &(instr->third_operand.operand),
415 &(instr->third_operand.size));
417 if (v3_reg_type == -1) {
418 PrintError("Third operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
419 instr->third_operand.type = INVALID_OPERAND;
421 } else if (v3_reg_type == SEGMENT_REGISTER) {
422 struct v3_segment * seg_reg = (struct v3_segment *)(instr->third_operand.operand);
423 instr->third_operand.operand = (addr_t)&(seg_reg->selector);
427 instr->third_operand.type = REG_OPERAND;
431 // PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
444 int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) {
453 static int get_memory_operand(struct guest_info * info, xed_decoded_inst_t * xed_instr, uint_t op_index, struct x86_operand * operand) {
454 struct memory_operand mem_op;
460 ullong_t displacement;
461 // struct v3_segment * seg_reg;
466 memset((void*)&mem_op, '\0', sizeof(struct memory_operand));
468 xed_reg_enum_t xed_seg = xed_decoded_inst_get_seg_reg(xed_instr, op_index);
469 if (xed_seg != XED_REG_INVALID) {
470 struct v3_segment *tmp_segment;
471 if (xed_reg_to_v3_reg(info, xed_seg, (addr_t *)&tmp_segment, &(mem_op.segment_size)) == -1) {
472 PrintError("Unhandled Segment Register\n");
475 mem_op.segment = tmp_segment->base;
478 xed_reg_enum_t xed_base = xed_decoded_inst_get_base_reg(xed_instr, op_index);
479 if (xed_base != XED_REG_INVALID) {
481 if (xed_reg_to_v3_reg(info, xed_base, &base_reg, &(mem_op.base_size)) == -1) {
482 PrintError("Unhandled Base register\n");
485 mem_op.base = *(addr_t *)base_reg;
490 xed_reg_enum_t xed_idx = xed_decoded_inst_get_index_reg(xed_instr, op_index);
491 if ((op_index == 0) && (xed_idx != XED_REG_INVALID)) {
494 if (xed_reg_to_v3_reg(info, xed_idx, &index_reg, &(mem_op.index_size)) == -1) {
495 PrintError("Unhandled Index Register\n");
499 mem_op.index= *(addr_t *)index_reg;
501 xed_uint_t xed_scale = xed_decoded_inst_get_scale(xed_instr, op_index);
502 if (xed_scale != 0) {
503 mem_op.scale = xed_scale;
508 xed_uint_t disp_bits = xed_decoded_inst_get_memory_displacement_width(xed_instr, op_index);
510 xed_int64_t xed_disp = xed_decoded_inst_get_memory_displacement(xed_instr, op_index);
512 mem_op.displacement_size = disp_bits / 8;
513 mem_op.displacement = xed_disp;
517 operand->type = MEM_OPERAND;
518 operand->size = xed_decoded_inst_get_memory_operand_length(xed_instr, op_index);
522 PrintDebug("Struct: Seg=%x, base=%x, index=%x, scale=%x, displacement=%x\n",
523 mem_op.segment, mem_op.base, mem_op.index, mem_op.scale, mem_op.displacement);
526 seg = mem_op.segment;
527 base = MASK(mem_op.base, mem_op.base_size);
528 index = MASK(mem_op.index, mem_op.index_size);
529 scale = mem_op.scale;
530 displacement = MASK(mem_op.displacement, mem_op.displacement_size);
532 PrintDebug("Seg=%x, base=%x, index=%x, scale=%x, displacement=%x\n", seg, base, index, scale, displacement);
534 operand->operand = seg + base + (scale * index) + displacement;
539 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) {
542 case XED_REG_INVALID:
551 *v3_reg = (addr_t)&(info->vm_regs.rax);
555 *v3_reg = (addr_t)&(info->vm_regs.rax);
559 *v3_reg = (addr_t)&(info->vm_regs.rax);
563 *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
567 *v3_reg = (addr_t)&(info->vm_regs.rax);
572 *v3_reg = (addr_t)&(info->vm_regs.rcx);
576 *v3_reg = (addr_t)&(info->vm_regs.rcx);
580 *v3_reg = (addr_t)&(info->vm_regs.rcx);
584 *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
588 *v3_reg = (addr_t)&(info->vm_regs.rcx);
593 *v3_reg = (addr_t)&(info->vm_regs.rdx);
597 *v3_reg = (addr_t)&(info->vm_regs.rdx);
601 *v3_reg = (addr_t)&(info->vm_regs.rdx);
605 *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
609 *v3_reg = (addr_t)&(info->vm_regs.rdx);
614 *v3_reg = (addr_t)&(info->vm_regs.rbx);
618 *v3_reg = (addr_t)&(info->vm_regs.rbx);
622 *v3_reg = (addr_t)&(info->vm_regs.rbx);
626 *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
630 *v3_reg = (addr_t)&(info->vm_regs.rbx);
636 *v3_reg = (addr_t)&(info->vm_regs.rsp);
640 *v3_reg = (addr_t)&(info->vm_regs.rsp);
644 *v3_reg = (addr_t)&(info->vm_regs.rsp);
648 *v3_reg = (addr_t)&(info->vm_regs.rsp);
653 *v3_reg = (addr_t)&(info->vm_regs.rbp);
657 *v3_reg = (addr_t)&(info->vm_regs.rbp);
661 *v3_reg = (addr_t)&(info->vm_regs.rbp);
665 *v3_reg = (addr_t)&(info->vm_regs.rbp);
672 *v3_reg = (addr_t)&(info->vm_regs.rsi);
676 *v3_reg = (addr_t)&(info->vm_regs.rsi);
680 *v3_reg = (addr_t)&(info->vm_regs.rsi);
684 *v3_reg = (addr_t)&(info->vm_regs.rsi);
690 *v3_reg = (addr_t)&(info->vm_regs.rdi);
694 *v3_reg = (addr_t)&(info->vm_regs.rdi);
698 *v3_reg = (addr_t)&(info->vm_regs.rdi);
702 *v3_reg = (addr_t)&(info->vm_regs.rdi);
711 *v3_reg = (addr_t)&(info->rip);
713 return CTRL_REGISTER;
715 *v3_reg = (addr_t)&(info->rip);
717 return CTRL_REGISTER;
719 *v3_reg = (addr_t)&(info->rip);
721 return CTRL_REGISTER;
724 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
726 return CTRL_REGISTER;
728 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
730 return CTRL_REGISTER;
732 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
734 return CTRL_REGISTER;
737 *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
739 return CTRL_REGISTER;
741 *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
743 return CTRL_REGISTER;
745 *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
747 return CTRL_REGISTER;
749 *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
751 return CTRL_REGISTER;
753 *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
755 return CTRL_REGISTER;
777 *v3_reg = (addr_t)&(info->segments.cs);
778 return SEGMENT_REGISTER;
780 *v3_reg = (addr_t)&(info->segments.ds);
781 return SEGMENT_REGISTER;
783 *v3_reg = (addr_t)&(info->segments.es);
784 return SEGMENT_REGISTER;
786 *v3_reg = (addr_t)&(info->segments.ss);
787 return SEGMENT_REGISTER;
789 *v3_reg = (addr_t)&(info->segments.fs);
790 return SEGMENT_REGISTER;
792 *v3_reg = (addr_t)&(info->segments.gs);
793 return SEGMENT_REGISTER;
800 PrintError("Segment selector operand... Don't know how to handle this...\n");
903 case XED_REG_STACKPUSH:
904 case XED_REG_STACKPOP:
910 case XED_REG_X87CONTROL:
911 case XED_REG_X87STATUS:
914 case XED_REG_X87PUSH:
916 case XED_REG_X87POP2:
951 static int get_opcode(xed_iform_enum_t iform, addr_t * opcode) {
954 case XED_IFORM_MOV_CR_GPR64_CR:
955 case XED_IFORM_MOV_CR_GPR32_CR:
956 *opcode = (addr_t)&V3_OPCODE_MOVCR2;
959 case XED_IFORM_MOV_CR_CR_GPR64:
960 case XED_IFORM_MOV_CR_CR_GPR32:
961 *opcode = (addr_t)&V3_OPCODE_MOV2CR;
965 case XED_IFORM_LMSW_GPR16:
966 *opcode = (addr_t)&V3_OPCODE_LMSW;
970 *opcode = (addr_t)&V3_OPCODE_CLTS;