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("xed_reg=0x%x, cr0=0x%x\n", instr->first_operand.operand, &(info->ctrl_regs.cr0));
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;
145 PrintDebug("xed_reg=0x%x, eax=0x%x\n", instr->second_operand.operand, &(info->vm_regs.rax));
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 PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
180 PrintDebug("category: %s\n", xed_category_enum_t2str(xed_decoded_inst_get_category(&xed_instr)));;
181 PrintDebug("ISA-extension:%s\n ",xed_extension_enum_t2str(xed_decoded_inst_get_extension(&xed_instr)));
182 PrintDebug(" instruction-length: %d\n ", xed_decoded_inst_get_length(&xed_instr));
183 PrintDebug(" operand-size:%d\n ", xed_operand_values_get_effective_operand_width(xed_decoded_inst_operands_const(&xed_instr)));
184 PrintDebug("address-size:%d\n ", xed_operand_values_get_effective_address_width(xed_decoded_inst_operands_const(&xed_instr)));
185 PrintDebug("iform-enum-name:%s\n ",xed_iform_enum_t2str(xed_decoded_inst_get_iform_enum(&xed_instr)));
186 PrintDebug("iform-enum-name-dispatch (zero based):%d\n ", xed_decoded_inst_get_iform_enum_dispatch(&xed_instr));
187 PrintDebug("iclass-max-iform-dispatch: %d\n ", xed_iform_max_per_iclass(xed_decoded_inst_get_iclass(&xed_instr)));
190 // print_operands(&xed_instr);
193 // print_memops(&xed_instr);
196 //print_flags(&xed_instr);
199 //print_attributes(&xed_instr);*/
207 int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) {
213 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) {
216 case XED_REG_INVALID:
225 *v3_reg = (addr_t)&(info->vm_regs.rax);
229 *v3_reg = (addr_t)&(info->vm_regs.rax);
233 *v3_reg = (addr_t)&(info->vm_regs.rax);
237 *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
241 *v3_reg = (addr_t)&(info->vm_regs.rax);
246 *v3_reg = (addr_t)&(info->vm_regs.rcx);
250 *v3_reg = (addr_t)&(info->vm_regs.rcx);
254 *v3_reg = (addr_t)&(info->vm_regs.rcx);
258 *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
262 *v3_reg = (addr_t)&(info->vm_regs.rcx);
267 *v3_reg = (addr_t)&(info->vm_regs.rdx);
271 *v3_reg = (addr_t)&(info->vm_regs.rdx);
275 *v3_reg = (addr_t)&(info->vm_regs.rdx);
279 *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
283 *v3_reg = (addr_t)&(info->vm_regs.rdx);
288 *v3_reg = (addr_t)&(info->vm_regs.rbx);
292 *v3_reg = (addr_t)&(info->vm_regs.rbx);
296 *v3_reg = (addr_t)&(info->vm_regs.rbx);
300 *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
304 *v3_reg = (addr_t)&(info->vm_regs.rbx);
310 *v3_reg = (addr_t)&(info->vm_regs.rsp);
314 *v3_reg = (addr_t)&(info->vm_regs.rsp);
318 *v3_reg = (addr_t)&(info->vm_regs.rsp);
322 *v3_reg = (addr_t)&(info->vm_regs.rsp);
327 *v3_reg = (addr_t)&(info->vm_regs.rbp);
331 *v3_reg = (addr_t)&(info->vm_regs.rbp);
335 *v3_reg = (addr_t)&(info->vm_regs.rbp);
339 *v3_reg = (addr_t)&(info->vm_regs.rbp);
346 *v3_reg = (addr_t)&(info->vm_regs.rsi);
350 *v3_reg = (addr_t)&(info->vm_regs.rsi);
354 *v3_reg = (addr_t)&(info->vm_regs.rsi);
358 *v3_reg = (addr_t)&(info->vm_regs.rsi);
364 *v3_reg = (addr_t)&(info->vm_regs.rdi);
368 *v3_reg = (addr_t)&(info->vm_regs.rdi);
372 *v3_reg = (addr_t)&(info->vm_regs.rdi);
376 *v3_reg = (addr_t)&(info->vm_regs.rdi);
385 *v3_reg = (addr_t)&(info->rip);
389 *v3_reg = (addr_t)&(info->rip);
393 *v3_reg = (addr_t)&(info->rip);
398 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
402 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
406 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
411 *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
415 *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
419 *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
423 *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
427 *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
451 *v3_reg = (addr_t)&(info->segments.cs.selector);
455 *v3_reg = (addr_t)&(info->segments.ds.selector);
459 *v3_reg = (addr_t)&(info->segments.es.selector);
463 *v3_reg = (addr_t)&(info->segments.ss.selector);
467 *v3_reg = (addr_t)&(info->segments.fs.selector);
471 *v3_reg = (addr_t)&(info->segments.fs.selector);
480 PrintError("Segment selector operand... Don't know how to handle this...\n");
583 case XED_REG_STACKPUSH:
584 case XED_REG_STACKPOP:
590 case XED_REG_X87CONTROL:
591 case XED_REG_X87STATUS:
594 case XED_REG_X87PUSH:
596 case XED_REG_X87POP2:
631 static int get_opcode(xed_iform_enum_t iform, addr_t * opcode) {
634 case XED_IFORM_MOV_CR_GPR64_CR:
635 case XED_IFORM_MOV_CR_GPR32_CR:
636 *opcode = (addr_t)&V3_OPCODE_MOVCR2;
639 case XED_IFORM_MOV_CR_CR_GPR64:
640 case XED_IFORM_MOV_CR_CR_GPR32:
641 *opcode = (addr_t)&V3_OPCODE_MOV2CR;
645 case XED_IFORM_LMSW_GPR16:
646 *opcode = (addr_t)&V3_OPCODE_LMSW;
650 *opcode = (addr_t)&V3_OPCODE_CLTS;