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);
96 PrintDebug("INSTR length: %d\n", instr->instr_length);
99 if (instr->num_operands >= 1) {
100 const xed_operand_t * op = xed_inst_operand(xi, 0);
101 xed_operand_type_enum_t op_type = xed_operand_type(op);
102 xed_operand_enum_t op_enum = xed_operand_name(op);
105 if (xed_operand_is_register(op_enum)) {
106 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
107 if (xed_reg_to_v3_reg(info,
109 &(instr->first_operand.operand),
110 &(instr->first_operand.size)) == -1) {
112 PrintError("First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
113 instr->first_operand.type = INVALID_OPERAND;
117 instr->first_operand.type = REG_OPERAND;
118 PrintDebug("First Operand: xed_reg=0x%x\n", instr->first_operand.operand);
121 PrintError("Unhandled first operand type %s\n", xed_operand_type_enum_t2str(op_type));
126 // set second operand
127 if (instr->num_operands >= 2) {
128 const xed_operand_t * op = xed_inst_operand(xi, 1);
129 xed_operand_type_enum_t op_type = xed_operand_type(op);
130 xed_operand_enum_t op_enum = xed_operand_name(op);
132 if (xed_operand_is_register(op_enum)) {
133 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
134 if (xed_reg_to_v3_reg(info,
136 &(instr->second_operand.operand),
137 &(instr->second_operand.size)) == -1) {
139 PrintError("Second operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
140 instr->second_operand.type = INVALID_OPERAND;
144 instr->second_operand.type = REG_OPERAND;
146 PrintDebug("Second Operand: xed_reg=0x%x\n", instr->second_operand.operand);
148 PrintError("Unhandled second operand type %s\n", xed_operand_type_enum_t2str(op_type));
154 if (instr->num_operands >= 3) {
155 const xed_operand_t * op = xed_inst_operand(xi, 2);
156 xed_operand_type_enum_t op_type = xed_operand_type(op);
157 xed_operand_enum_t op_enum = xed_operand_name(op);
159 if (xed_operand_is_register(op_enum)) {
160 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
161 if (xed_reg_to_v3_reg(info,
163 &(instr->third_operand.operand),
164 &(instr->third_operand.size)) == -1) {
166 PrintError("Third operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
167 instr->third_operand.type = INVALID_OPERAND;
170 instr->third_operand.type = REG_OPERAND;
172 PrintDebug("Third Operand: xed_reg=0x%x\n", instr->third_operand.operand);
174 PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
182 PrintDebug("category: %s\n", xed_category_enum_t2str(xed_decoded_inst_get_category(&xed_instr)));;
183 PrintDebug("ISA-extension:%s\n ",xed_extension_enum_t2str(xed_decoded_inst_get_extension(&xed_instr)));
184 PrintDebug(" instruction-length: %d\n ", xed_decoded_inst_get_length(&xed_instr));
185 PrintDebug(" operand-size:%d\n ", xed_operand_values_get_effective_operand_width(xed_decoded_inst_operands_const(&xed_instr)));
186 PrintDebug("address-size:%d\n ", xed_operand_values_get_effective_address_width(xed_decoded_inst_operands_const(&xed_instr)));
187 PrintDebug("iform-enum-name:%s\n ",xed_iform_enum_t2str(xed_decoded_inst_get_iform_enum(&xed_instr)));
188 PrintDebug("iform-enum-name-dispatch (zero based):%d\n ", xed_decoded_inst_get_iform_enum_dispatch(&xed_instr));
189 PrintDebug("iclass-max-iform-dispatch: %d\n ", xed_iform_max_per_iclass(xed_decoded_inst_get_iclass(&xed_instr)));
192 // print_operands(&xed_instr);
195 // print_memops(&xed_instr);
198 //print_flags(&xed_instr);
201 //print_attributes(&xed_instr);*/
209 int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) {
215 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) {
218 case XED_REG_INVALID:
227 *v3_reg = (addr_t)&(info->vm_regs.rax);
231 *v3_reg = (addr_t)&(info->vm_regs.rax);
235 *v3_reg = (addr_t)&(info->vm_regs.rax);
239 *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
243 *v3_reg = (addr_t)&(info->vm_regs.rax);
248 *v3_reg = (addr_t)&(info->vm_regs.rcx);
252 *v3_reg = (addr_t)&(info->vm_regs.rcx);
256 *v3_reg = (addr_t)&(info->vm_regs.rcx);
260 *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
264 *v3_reg = (addr_t)&(info->vm_regs.rcx);
269 *v3_reg = (addr_t)&(info->vm_regs.rdx);
273 *v3_reg = (addr_t)&(info->vm_regs.rdx);
277 *v3_reg = (addr_t)&(info->vm_regs.rdx);
281 *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
285 *v3_reg = (addr_t)&(info->vm_regs.rdx);
290 *v3_reg = (addr_t)&(info->vm_regs.rbx);
294 *v3_reg = (addr_t)&(info->vm_regs.rbx);
298 *v3_reg = (addr_t)&(info->vm_regs.rbx);
302 *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
306 *v3_reg = (addr_t)&(info->vm_regs.rbx);
312 *v3_reg = (addr_t)&(info->vm_regs.rsp);
316 *v3_reg = (addr_t)&(info->vm_regs.rsp);
320 *v3_reg = (addr_t)&(info->vm_regs.rsp);
324 *v3_reg = (addr_t)&(info->vm_regs.rsp);
329 *v3_reg = (addr_t)&(info->vm_regs.rbp);
333 *v3_reg = (addr_t)&(info->vm_regs.rbp);
337 *v3_reg = (addr_t)&(info->vm_regs.rbp);
341 *v3_reg = (addr_t)&(info->vm_regs.rbp);
348 *v3_reg = (addr_t)&(info->vm_regs.rsi);
352 *v3_reg = (addr_t)&(info->vm_regs.rsi);
356 *v3_reg = (addr_t)&(info->vm_regs.rsi);
360 *v3_reg = (addr_t)&(info->vm_regs.rsi);
366 *v3_reg = (addr_t)&(info->vm_regs.rdi);
370 *v3_reg = (addr_t)&(info->vm_regs.rdi);
374 *v3_reg = (addr_t)&(info->vm_regs.rdi);
378 *v3_reg = (addr_t)&(info->vm_regs.rdi);
387 *v3_reg = (addr_t)&(info->rip);
391 *v3_reg = (addr_t)&(info->rip);
395 *v3_reg = (addr_t)&(info->rip);
400 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
404 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
408 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
413 *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
417 *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
421 *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
425 *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
429 *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
453 *v3_reg = (addr_t)&(info->segments.cs.selector);
457 *v3_reg = (addr_t)&(info->segments.ds.selector);
461 *v3_reg = (addr_t)&(info->segments.es.selector);
465 *v3_reg = (addr_t)&(info->segments.ss.selector);
469 *v3_reg = (addr_t)&(info->segments.fs.selector);
473 *v3_reg = (addr_t)&(info->segments.fs.selector);
482 PrintError("Segment selector operand... Don't know how to handle this...\n");
585 case XED_REG_STACKPUSH:
586 case XED_REG_STACKPOP:
592 case XED_REG_X87CONTROL:
593 case XED_REG_X87STATUS:
596 case XED_REG_X87PUSH:
598 case XED_REG_X87POP2:
633 static int get_opcode(xed_iform_enum_t iform, addr_t * opcode) {
636 case XED_IFORM_MOV_CR_GPR64_CR:
637 case XED_IFORM_MOV_CR_GPR32_CR:
638 *opcode = (addr_t)&V3_OPCODE_MOVCR2;
641 case XED_IFORM_MOV_CR_CR_GPR64:
642 case XED_IFORM_MOV_CR_CR_GPR32:
643 *opcode = (addr_t)&V3_OPCODE_MOV2CR;
647 case XED_IFORM_LMSW_GPR16:
648 *opcode = (addr_t)&V3_OPCODE_LMSW;
652 *opcode = (addr_t)&V3_OPCODE_CLTS;