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);
100 case XED_OPERAND_TYPE_REG:
102 xed_operand_enum_t op_enum = xed_operand_name(op);
103 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
104 if (xed_reg_to_v3_reg(info,
106 &(instr->dst_operand.operand),
107 &(instr->dst_operand.size)) == -1) {
109 PrintError("First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
113 case XED_OPERAND_TYPE_INVALID:
114 case XED_OPERAND_TYPE_ERROR:
115 case XED_OPERAND_TYPE_IMM:
116 case XED_OPERAND_TYPE_IMM_CONST:
117 case XED_OPERAND_TYPE_NT_LOOKUP_FN:
118 case XED_OPERAND_TYPE_LAST:
119 PrintError("Unhandled first operand type %s\n", xed_operand_type_enum_t2str(op_type));
124 // set second operand
125 if (instr->num_operands >= 2) {
126 const xed_operand_t * op = xed_inst_operand(xi, 0);
127 xed_operand_type_enum_t op_type = xed_operand_type(op);
130 case XED_OPERAND_TYPE_REG:
132 xed_operand_enum_t op_enum = xed_operand_name(op);
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->src_operand.operand),
137 &(instr->src_operand.size)) == -1) {
139 PrintError("Second operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
143 case XED_OPERAND_TYPE_INVALID:
144 case XED_OPERAND_TYPE_ERROR:
145 case XED_OPERAND_TYPE_IMM:
146 case XED_OPERAND_TYPE_IMM_CONST:
147 case XED_OPERAND_TYPE_NT_LOOKUP_FN:
148 case XED_OPERAND_TYPE_LAST:
149 PrintError("Unhandled second operand type %s\n", xed_operand_type_enum_t2str(op_type));
155 if (instr->num_operands >= 3) {
156 const xed_operand_t * op = xed_inst_operand(xi, 0);
157 xed_operand_type_enum_t op_type = xed_operand_type(op);
160 case XED_OPERAND_TYPE_REG:
162 xed_operand_enum_t op_enum = xed_operand_name(op);
163 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
164 if (xed_reg_to_v3_reg(info,
166 &(instr->extra_operand.operand),
167 &(instr->extra_operand.size)) == -1) {
169 PrintError("Third operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
173 case XED_OPERAND_TYPE_INVALID:
174 case XED_OPERAND_TYPE_ERROR:
175 case XED_OPERAND_TYPE_IMM:
176 case XED_OPERAND_TYPE_IMM_CONST:
177 case XED_OPERAND_TYPE_NT_LOOKUP_FN:
178 case XED_OPERAND_TYPE_LAST:
179 PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
187 PrintDebug("category: %s\n", xed_category_enum_t2str(xed_decoded_inst_get_category(&xed_instr)));;
188 PrintDebug("ISA-extension:%s\n ",xed_extension_enum_t2str(xed_decoded_inst_get_extension(&xed_instr)));
189 PrintDebug(" instruction-length: %d\n ", xed_decoded_inst_get_length(&xed_instr));
190 PrintDebug(" operand-size:%d\n ", xed_operand_values_get_effective_operand_width(xed_decoded_inst_operands_const(&xed_instr)));
191 PrintDebug("address-size:%d\n ", xed_operand_values_get_effective_address_width(xed_decoded_inst_operands_const(&xed_instr)));
192 PrintDebug("iform-enum-name:%s\n ",xed_iform_enum_t2str(xed_decoded_inst_get_iform_enum(&xed_instr)));
193 PrintDebug("iform-enum-name-dispatch (zero based):%d\n ", xed_decoded_inst_get_iform_enum_dispatch(&xed_instr));
194 PrintDebug("iclass-max-iform-dispatch: %d\n ", xed_iform_max_per_iclass(xed_decoded_inst_get_iclass(&xed_instr)));
197 // print_operands(&xed_instr);
200 // print_memops(&xed_instr);
203 //print_flags(&xed_instr);
206 //print_attributes(&xed_instr);*/
214 int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) {
220 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) {
223 case XED_REG_INVALID:
232 *v3_reg = (addr_t)&(info->vm_regs.rax);
236 *v3_reg = (addr_t)&(info->vm_regs.rax);
240 *v3_reg = (addr_t)&(info->vm_regs.rax);
244 *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
248 *v3_reg = (addr_t)&(info->vm_regs.rax);
253 *v3_reg = (addr_t)&(info->vm_regs.rcx);
257 *v3_reg = (addr_t)&(info->vm_regs.rcx);
261 *v3_reg = (addr_t)&(info->vm_regs.rcx);
265 *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
269 *v3_reg = (addr_t)&(info->vm_regs.rcx);
274 *v3_reg = (addr_t)&(info->vm_regs.rdx);
278 *v3_reg = (addr_t)&(info->vm_regs.rdx);
282 *v3_reg = (addr_t)&(info->vm_regs.rdx);
286 *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
290 *v3_reg = (addr_t)&(info->vm_regs.rdx);
295 *v3_reg = (addr_t)&(info->vm_regs.rbx);
299 *v3_reg = (addr_t)&(info->vm_regs.rbx);
303 *v3_reg = (addr_t)&(info->vm_regs.rbx);
307 *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
311 *v3_reg = (addr_t)&(info->vm_regs.rbx);
317 *v3_reg = (addr_t)&(info->vm_regs.rsp);
321 *v3_reg = (addr_t)&(info->vm_regs.rsp);
325 *v3_reg = (addr_t)&(info->vm_regs.rsp);
329 *v3_reg = (addr_t)&(info->vm_regs.rsp);
334 *v3_reg = (addr_t)&(info->vm_regs.rbp);
338 *v3_reg = (addr_t)&(info->vm_regs.rbp);
342 *v3_reg = (addr_t)&(info->vm_regs.rbp);
346 *v3_reg = (addr_t)&(info->vm_regs.rbp);
353 *v3_reg = (addr_t)&(info->vm_regs.rsi);
357 *v3_reg = (addr_t)&(info->vm_regs.rsi);
361 *v3_reg = (addr_t)&(info->vm_regs.rsi);
365 *v3_reg = (addr_t)&(info->vm_regs.rsi);
371 *v3_reg = (addr_t)&(info->vm_regs.rdi);
375 *v3_reg = (addr_t)&(info->vm_regs.rdi);
379 *v3_reg = (addr_t)&(info->vm_regs.rdi);
383 *v3_reg = (addr_t)&(info->vm_regs.rdi);
392 *v3_reg = (addr_t)&(info->rip);
396 *v3_reg = (addr_t)&(info->rip);
400 *v3_reg = (addr_t)&(info->rip);
405 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
409 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
413 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
418 *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
422 *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
426 *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
430 *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
434 *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
458 *v3_reg = (addr_t)&(info->segments.cs.selector);
462 *v3_reg = (addr_t)&(info->segments.ds.selector);
466 *v3_reg = (addr_t)&(info->segments.es.selector);
470 *v3_reg = (addr_t)&(info->segments.ss.selector);
474 *v3_reg = (addr_t)&(info->segments.fs.selector);
478 *v3_reg = (addr_t)&(info->segments.fs.selector);
487 PrintError("Segment selector operand... Don't know how to handle this...\n");
590 case XED_REG_STACKPUSH:
591 case XED_REG_STACKPOP:
597 case XED_REG_X87CONTROL:
598 case XED_REG_X87STATUS:
601 case XED_REG_X87PUSH:
603 case XED_REG_X87POP2: