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;
10 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);
13 static int set_decoder_mode(struct guest_info * info, xed_state_t * state) {
14 switch (info->cpu_mode) {
16 if (state->mmode != XED_MACHINE_MODE_LEGACY_16) {
18 XED_MACHINE_MODE_LEGACY_16,
19 XED_ADDRESS_WIDTH_16b,
20 XED_ADDRESS_WIDTH_16b);
25 if (state->mmode != XED_MACHINE_MODE_LEGACY_32) {
27 XED_MACHINE_MODE_LEGACY_32,
28 XED_ADDRESS_WIDTH_32b,
29 XED_ADDRESS_WIDTH_32b);
33 if (state->mmode != XED_MACHINE_MODE_LONG_64) {
34 state->mmode = XED_MACHINE_MODE_LONG_64;
49 xed_state_zero(&decoder_state);
54 int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
55 xed_decoded_inst_t xed_instr;
56 xed_error_enum_t xed_error;
60 if (set_decoder_mode(info, &decoder_state) == -1) {
61 PrintError("Could not set decoder mode\n");
67 xed_decoded_inst_zero_set_mode(&xed_instr, &decoder_state);
72 xed_error = xed_decode(&xed_instr,
73 REINTERPRET_CAST(const xed_uint8_t *, instr_ptr),
74 XED_MAX_INSTRUCTION_BYTES);
81 if (xed_error != XED_ERROR_NONE) {
82 PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
86 const xed_inst_t * xi = xed_decoded_inst_inst(&xed_instr);
88 instr->instr_length = xed_decoded_inst_get_length(&xed_instr);
89 instr->num_operands = xed_decoded_inst_noperands(&xed_instr);
92 PrintDebug("Number of operands: %d\n", instr->num_operands);
95 if (instr->num_operands >= 1) {
96 const xed_operand_t * op = xed_inst_operand(xi, 0);
97 xed_operand_type_enum_t op_type = xed_operand_type(op);
98 xed_operand_enum_t op_enum = xed_operand_name(op);
101 if (xed_operand_is_register(op_enum)) {
102 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
103 if (xed_reg_to_v3_reg(info,
105 &(instr->dst_operand.operand),
106 &(instr->dst_operand.size)) == -1) {
108 PrintError("First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
112 PrintDebug("xed_reg=0x%x, cr0=0x%x\n", instr->dst_operand.operand, &(info->ctrl_regs.cr0));
115 PrintError("Unhandled first operand type %s\n", xed_operand_type_enum_t2str(op_type));
120 // set second operand
121 if (instr->num_operands >= 2) {
122 const xed_operand_t * op = xed_inst_operand(xi, 1);
123 xed_operand_type_enum_t op_type = xed_operand_type(op);
124 xed_operand_enum_t op_enum = xed_operand_name(op);
126 if (xed_operand_is_register(op_enum)) {
127 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
128 if (xed_reg_to_v3_reg(info,
130 &(instr->src_operand.operand),
131 &(instr->src_operand.size)) == -1) {
133 PrintError("Second operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
136 PrintDebug("xed_reg=0x%x, eax=0x%x\n", instr->src_operand.operand, &(info->vm_regs.rax));
139 PrintError("Unhandled second operand type %s\n", xed_operand_type_enum_t2str(op_type));
145 if (instr->num_operands >= 3) {
146 const xed_operand_t * op = xed_inst_operand(xi, 2);
147 xed_operand_type_enum_t op_type = xed_operand_type(op);
148 xed_operand_enum_t op_enum = xed_operand_name(op);
150 if (xed_operand_is_register(op_enum)) {
151 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
152 if (xed_reg_to_v3_reg(info,
154 &(instr->extra_operand.operand),
155 &(instr->extra_operand.size)) == -1) {
157 PrintError("Third operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
161 PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
169 PrintDebug("category: %s\n", xed_category_enum_t2str(xed_decoded_inst_get_category(&xed_instr)));;
170 PrintDebug("ISA-extension:%s\n ",xed_extension_enum_t2str(xed_decoded_inst_get_extension(&xed_instr)));
171 PrintDebug(" instruction-length: %d\n ", xed_decoded_inst_get_length(&xed_instr));
172 PrintDebug(" operand-size:%d\n ", xed_operand_values_get_effective_operand_width(xed_decoded_inst_operands_const(&xed_instr)));
173 PrintDebug("address-size:%d\n ", xed_operand_values_get_effective_address_width(xed_decoded_inst_operands_const(&xed_instr)));
174 PrintDebug("iform-enum-name:%s\n ",xed_iform_enum_t2str(xed_decoded_inst_get_iform_enum(&xed_instr)));
175 PrintDebug("iform-enum-name-dispatch (zero based):%d\n ", xed_decoded_inst_get_iform_enum_dispatch(&xed_instr));
176 PrintDebug("iclass-max-iform-dispatch: %d\n ", xed_iform_max_per_iclass(xed_decoded_inst_get_iclass(&xed_instr)));
179 // print_operands(&xed_instr);
182 // print_memops(&xed_instr);
185 //print_flags(&xed_instr);
188 //print_attributes(&xed_instr);*/
196 int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) {
202 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) {
205 case XED_REG_INVALID:
214 *v3_reg = (addr_t)&(info->vm_regs.rax);
218 *v3_reg = (addr_t)&(info->vm_regs.rax);
222 *v3_reg = (addr_t)&(info->vm_regs.rax);
226 *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
230 *v3_reg = (addr_t)&(info->vm_regs.rax);
235 *v3_reg = (addr_t)&(info->vm_regs.rcx);
239 *v3_reg = (addr_t)&(info->vm_regs.rcx);
243 *v3_reg = (addr_t)&(info->vm_regs.rcx);
247 *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
251 *v3_reg = (addr_t)&(info->vm_regs.rcx);
256 *v3_reg = (addr_t)&(info->vm_regs.rdx);
260 *v3_reg = (addr_t)&(info->vm_regs.rdx);
264 *v3_reg = (addr_t)&(info->vm_regs.rdx);
268 *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
272 *v3_reg = (addr_t)&(info->vm_regs.rdx);
277 *v3_reg = (addr_t)&(info->vm_regs.rbx);
281 *v3_reg = (addr_t)&(info->vm_regs.rbx);
285 *v3_reg = (addr_t)&(info->vm_regs.rbx);
289 *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
293 *v3_reg = (addr_t)&(info->vm_regs.rbx);
299 *v3_reg = (addr_t)&(info->vm_regs.rsp);
303 *v3_reg = (addr_t)&(info->vm_regs.rsp);
307 *v3_reg = (addr_t)&(info->vm_regs.rsp);
311 *v3_reg = (addr_t)&(info->vm_regs.rsp);
316 *v3_reg = (addr_t)&(info->vm_regs.rbp);
320 *v3_reg = (addr_t)&(info->vm_regs.rbp);
324 *v3_reg = (addr_t)&(info->vm_regs.rbp);
328 *v3_reg = (addr_t)&(info->vm_regs.rbp);
335 *v3_reg = (addr_t)&(info->vm_regs.rsi);
339 *v3_reg = (addr_t)&(info->vm_regs.rsi);
343 *v3_reg = (addr_t)&(info->vm_regs.rsi);
347 *v3_reg = (addr_t)&(info->vm_regs.rsi);
353 *v3_reg = (addr_t)&(info->vm_regs.rdi);
357 *v3_reg = (addr_t)&(info->vm_regs.rdi);
361 *v3_reg = (addr_t)&(info->vm_regs.rdi);
365 *v3_reg = (addr_t)&(info->vm_regs.rdi);
374 *v3_reg = (addr_t)&(info->rip);
378 *v3_reg = (addr_t)&(info->rip);
382 *v3_reg = (addr_t)&(info->rip);
387 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
391 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
395 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
400 *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
404 *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
408 *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
412 *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
416 *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
440 *v3_reg = (addr_t)&(info->segments.cs.selector);
444 *v3_reg = (addr_t)&(info->segments.ds.selector);
448 *v3_reg = (addr_t)&(info->segments.es.selector);
452 *v3_reg = (addr_t)&(info->segments.ss.selector);
456 *v3_reg = (addr_t)&(info->segments.fs.selector);
460 *v3_reg = (addr_t)&(info->segments.fs.selector);
469 PrintError("Segment selector operand... Don't know how to handle this...\n");
572 case XED_REG_STACKPUSH:
573 case XED_REG_STACKPOP:
579 case XED_REG_X87CONTROL:
580 case XED_REG_X87STATUS:
583 case XED_REG_X87PUSH:
585 case XED_REG_X87POP2: