1 #include <palacios/vmm_decoder.h>
2 #include <palacios/vmm_xed.h>
3 #include <xed/xed-interface.h>
4 #include <palacios/vm_guest.h>
6 static xed_state_t decoder_state;
9 // This returns a pointer to a V3_OPCODE_[*] array defined in vmm_decoder.h
10 static int get_opcode(xed_iform_enum_t iform, addr_t * opcode);
12 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);
15 static int set_decoder_mode(struct guest_info * info, xed_state_t * state) {
16 switch (info->cpu_mode) {
18 if (state->mmode != XED_MACHINE_MODE_LEGACY_16) {
20 XED_MACHINE_MODE_LEGACY_16,
21 XED_ADDRESS_WIDTH_16b,
22 XED_ADDRESS_WIDTH_16b);
27 if (state->mmode != XED_MACHINE_MODE_LEGACY_32) {
29 XED_MACHINE_MODE_LEGACY_32,
30 XED_ADDRESS_WIDTH_32b,
31 XED_ADDRESS_WIDTH_32b);
35 if (state->mmode != XED_MACHINE_MODE_LONG_64) {
36 state->mmode = XED_MACHINE_MODE_LONG_64;
51 xed_state_zero(&decoder_state);
56 int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
57 xed_decoded_inst_t xed_instr;
58 xed_error_enum_t xed_error;
62 if (set_decoder_mode(info, &decoder_state) == -1) {
63 PrintError("Could not set decoder mode\n");
69 xed_decoded_inst_zero_set_mode(&xed_instr, &decoder_state);
71 xed_error = xed_decode(&xed_instr,
72 REINTERPRET_CAST(const xed_uint8_t *, instr_ptr),
73 XED_MAX_INSTRUCTION_BYTES);
76 if (xed_error != XED_ERROR_NONE) {
77 PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
81 const xed_inst_t * xi = xed_decoded_inst_inst(&xed_instr);
83 instr->instr_length = xed_decoded_inst_get_length(&xed_instr);
84 instr->num_operands = xed_decoded_inst_noperands(&xed_instr);
86 xed_iform_enum_t iform = xed_decoded_inst_get_iform_enum(&xed_instr);
88 if (get_opcode(iform, &(instr->opcode)) == -1) {
89 PrintError("Could not get opcode. (iform=%s)\n", xed_iform_enum_t2str(iform));
95 PrintDebug("Number of operands: %d\n", instr->num_operands);
98 if (instr->num_operands >= 1) {
99 const xed_operand_t * op = xed_inst_operand(xi, 0);
100 xed_operand_type_enum_t op_type = xed_operand_type(op);
101 xed_operand_enum_t op_enum = xed_operand_name(op);
104 if (xed_operand_is_register(op_enum)) {
105 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
106 if (xed_reg_to_v3_reg(info,
108 &(instr->first_operand.operand),
109 &(instr->first_operand.size)) == -1) {
111 PrintError("First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
112 instr->first_operand.type = INVALID_OPERAND;
116 instr->first_operand.type = REG_OPERAND;
117 PrintDebug("xed_reg=0x%x, cr0=0x%x\n", instr->first_operand.operand, &(info->ctrl_regs.cr0));
120 PrintError("Unhandled first operand type %s\n", xed_operand_type_enum_t2str(op_type));
125 // set second operand
126 if (instr->num_operands >= 2) {
127 const xed_operand_t * op = xed_inst_operand(xi, 1);
128 xed_operand_type_enum_t op_type = xed_operand_type(op);
129 xed_operand_enum_t op_enum = xed_operand_name(op);
131 if (xed_operand_is_register(op_enum)) {
132 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
133 if (xed_reg_to_v3_reg(info,
135 &(instr->second_operand.operand),
136 &(instr->second_operand.size)) == -1) {
138 PrintError("Second operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
139 instr->second_operand.type = INVALID_OPERAND;
143 instr->second_operand.type = REG_OPERAND;
144 PrintDebug("xed_reg=0x%x, eax=0x%x\n", instr->second_operand.operand, &(info->vm_regs.rax));
147 PrintError("Unhandled second operand type %s\n", xed_operand_type_enum_t2str(op_type));
153 if (instr->num_operands >= 3) {
154 const xed_operand_t * op = xed_inst_operand(xi, 2);
155 xed_operand_type_enum_t op_type = xed_operand_type(op);
156 xed_operand_enum_t op_enum = xed_operand_name(op);
158 if (xed_operand_is_register(op_enum)) {
159 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
160 if (xed_reg_to_v3_reg(info,
162 &(instr->third_operand.operand),
163 &(instr->third_operand.size)) == -1) {
165 PrintError("Third operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
166 instr->third_operand.type = INVALID_OPERAND;
169 instr->third_operand.type = REG_OPERAND;
171 PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
179 PrintDebug("category: %s\n", xed_category_enum_t2str(xed_decoded_inst_get_category(&xed_instr)));;
180 PrintDebug("ISA-extension:%s\n ",xed_extension_enum_t2str(xed_decoded_inst_get_extension(&xed_instr)));
181 PrintDebug(" instruction-length: %d\n ", xed_decoded_inst_get_length(&xed_instr));
182 PrintDebug(" operand-size:%d\n ", xed_operand_values_get_effective_operand_width(xed_decoded_inst_operands_const(&xed_instr)));
183 PrintDebug("address-size:%d\n ", xed_operand_values_get_effective_address_width(xed_decoded_inst_operands_const(&xed_instr)));
184 PrintDebug("iform-enum-name:%s\n ",xed_iform_enum_t2str(xed_decoded_inst_get_iform_enum(&xed_instr)));
185 PrintDebug("iform-enum-name-dispatch (zero based):%d\n ", xed_decoded_inst_get_iform_enum_dispatch(&xed_instr));
186 PrintDebug("iclass-max-iform-dispatch: %d\n ", xed_iform_max_per_iclass(xed_decoded_inst_get_iclass(&xed_instr)));
189 // print_operands(&xed_instr);
192 // print_memops(&xed_instr);
195 //print_flags(&xed_instr);
198 //print_attributes(&xed_instr);*/
206 int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) {
212 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) {
215 case XED_REG_INVALID:
224 *v3_reg = (addr_t)&(info->vm_regs.rax);
228 *v3_reg = (addr_t)&(info->vm_regs.rax);
232 *v3_reg = (addr_t)&(info->vm_regs.rax);
236 *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
240 *v3_reg = (addr_t)&(info->vm_regs.rax);
245 *v3_reg = (addr_t)&(info->vm_regs.rcx);
249 *v3_reg = (addr_t)&(info->vm_regs.rcx);
253 *v3_reg = (addr_t)&(info->vm_regs.rcx);
257 *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
261 *v3_reg = (addr_t)&(info->vm_regs.rcx);
266 *v3_reg = (addr_t)&(info->vm_regs.rdx);
270 *v3_reg = (addr_t)&(info->vm_regs.rdx);
274 *v3_reg = (addr_t)&(info->vm_regs.rdx);
278 *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
282 *v3_reg = (addr_t)&(info->vm_regs.rdx);
287 *v3_reg = (addr_t)&(info->vm_regs.rbx);
291 *v3_reg = (addr_t)&(info->vm_regs.rbx);
295 *v3_reg = (addr_t)&(info->vm_regs.rbx);
299 *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
303 *v3_reg = (addr_t)&(info->vm_regs.rbx);
309 *v3_reg = (addr_t)&(info->vm_regs.rsp);
313 *v3_reg = (addr_t)&(info->vm_regs.rsp);
317 *v3_reg = (addr_t)&(info->vm_regs.rsp);
321 *v3_reg = (addr_t)&(info->vm_regs.rsp);
326 *v3_reg = (addr_t)&(info->vm_regs.rbp);
330 *v3_reg = (addr_t)&(info->vm_regs.rbp);
334 *v3_reg = (addr_t)&(info->vm_regs.rbp);
338 *v3_reg = (addr_t)&(info->vm_regs.rbp);
345 *v3_reg = (addr_t)&(info->vm_regs.rsi);
349 *v3_reg = (addr_t)&(info->vm_regs.rsi);
353 *v3_reg = (addr_t)&(info->vm_regs.rsi);
357 *v3_reg = (addr_t)&(info->vm_regs.rsi);
363 *v3_reg = (addr_t)&(info->vm_regs.rdi);
367 *v3_reg = (addr_t)&(info->vm_regs.rdi);
371 *v3_reg = (addr_t)&(info->vm_regs.rdi);
375 *v3_reg = (addr_t)&(info->vm_regs.rdi);
384 *v3_reg = (addr_t)&(info->rip);
388 *v3_reg = (addr_t)&(info->rip);
392 *v3_reg = (addr_t)&(info->rip);
397 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
401 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
405 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
410 *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
414 *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
418 *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
422 *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
426 *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
450 *v3_reg = (addr_t)&(info->segments.cs.selector);
454 *v3_reg = (addr_t)&(info->segments.ds.selector);
458 *v3_reg = (addr_t)&(info->segments.es.selector);
462 *v3_reg = (addr_t)&(info->segments.ss.selector);
466 *v3_reg = (addr_t)&(info->segments.fs.selector);
470 *v3_reg = (addr_t)&(info->segments.fs.selector);
479 PrintError("Segment selector operand... Don't know how to handle this...\n");
582 case XED_REG_STACKPUSH:
583 case XED_REG_STACKPOP:
589 case XED_REG_X87CONTROL:
590 case XED_REG_X87STATUS:
593 case XED_REG_X87PUSH:
595 case XED_REG_X87POP2:
630 static int get_opcode(xed_iform_enum_t iform, addr_t * opcode) {
633 case XED_IFORM_MOV_CR_GPR64_CR:
634 case XED_IFORM_MOV_CR_GPR32_CR:
635 *opcode = (addr_t)&V3_OPCODE_MOVCR2;
638 case XED_IFORM_MOV_CR_CR_GPR64:
639 case XED_IFORM_MOV_CR_CR_GPR32:
640 *opcode = (addr_t)&V3_OPCODE_MOV2CR;