2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
11 * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20 #ifdef __DECODER_TEST__
21 #include "vmm_decoder.h"
23 #include <xed/xed-interface.h>
29 #include <palacios/vmm_decoder.h>
30 #include <palacios/vmm_xed.h>
31 #include <xed/xed-interface.h>
32 #include <palacios/vm_guest.h>
33 #include <palacios/vmm.h>
40 #define PrintDebug(fmt, args...)
46 static uint_t tables_inited = 0;
49 #define GPR_REGISTER 0
50 #define SEGMENT_REGISTER 1
51 #define CTRL_REGISTER 2
52 #define DEBUG_REGISTER 3
56 /* Disgusting mask hack...
57 I can't think right now, so we'll do it this way...
59 static const ullong_t mask_1 = 0x00000000000000ffLL;
60 static const ullong_t mask_2 = 0x000000000000ffffLL;
61 static const ullong_t mask_4 = 0x00000000ffffffffLL;
62 static const ullong_t mask_8 = 0xffffffffffffffffLL;
65 #define MASK(val, length) ({ \
66 ullong_t mask = 0x0LL; \
83 struct memory_operand {
91 uint_t displacement_size;
92 ullong_t displacement;
98 static v3_op_type_t get_opcode(xed_iform_enum_t iform);
100 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);
101 static int get_memory_operand(struct guest_info * info, xed_decoded_inst_t * xed_instr, uint_t index, struct x86_operand * operand);
103 static int set_decoder_mode(struct guest_info * info, xed_state_t * state) {
104 switch (info->cpu_mode) {
106 if (state->mmode != XED_MACHINE_MODE_LEGACY_16) {
107 xed_state_init(state,
108 XED_MACHINE_MODE_LEGACY_16,
109 XED_ADDRESS_WIDTH_16b,
110 XED_ADDRESS_WIDTH_16b);
115 if (state->mmode != XED_MACHINE_MODE_LEGACY_32) {
116 xed_state_init(state,
117 XED_MACHINE_MODE_LEGACY_32,
118 XED_ADDRESS_WIDTH_32b,
119 XED_ADDRESS_WIDTH_32b);
123 if (state->mmode != XED_MACHINE_MODE_LONG_COMPAT_32) {
124 xed_state_init(state,
125 XED_MACHINE_MODE_LONG_COMPAT_32,
126 XED_ADDRESS_WIDTH_32b,
127 XED_ADDRESS_WIDTH_32b);
131 if (state->mmode != XED_MACHINE_MODE_LONG_64) {
132 PrintDebug("Setting decoder to long mode\n");
133 // state->mmode = XED_MACHINE_MODE_LONG_64;
134 //xed_state_set_machine_mode(state, XED_MACHINE_MODE_LONG_64);
135 xed_state_init(state,
136 XED_MACHINE_MODE_LONG_64,
137 XED_ADDRESS_WIDTH_64b,
138 XED_ADDRESS_WIDTH_64b);
142 PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
148 static int is_flags_reg(xed_reg_enum_t xed_reg) {
161 int v3_init_decoder(struct guest_info * info) {
162 // Global library initialization, only do it once
163 if (tables_inited == 0) {
168 xed_state_t * decoder_state = (xed_state_t *)V3_Malloc(sizeof(xed_state_t));
169 xed_state_zero(decoder_state);
170 xed_state_init(decoder_state,
171 XED_MACHINE_MODE_LEGACY_32,
172 XED_ADDRESS_WIDTH_32b,
173 XED_ADDRESS_WIDTH_32b);
175 info->decoder_state = decoder_state;
182 int v3_basic_mem_decode(struct guest_info * info, addr_t instr_ptr, struct basic_instr_info * instr_info) {
183 xed_decoded_inst_t xed_instr;
184 xed_error_enum_t xed_error;
187 if (set_decoder_mode(info, info->decoder_state) == -1) {
188 PrintError("Could not set decoder mode\n");
193 xed_decoded_inst_zero_set_mode(&xed_instr, info->decoder_state);
195 xed_error = xed_decode(&xed_instr,
196 REINTERPRET_CAST(const xed_uint8_t *, instr_ptr),
197 XED_MAX_INSTRUCTION_BYTES);
199 if (xed_error != XED_ERROR_NONE) {
200 PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
204 instr_info->instr_length = xed_decoded_inst_get_length(&xed_instr);
207 if (xed_decoded_inst_number_of_memory_operands(&xed_instr) == 0) {
208 PrintError("Tried to decode memory operation with no memory operands\n");
212 instr_info->op_size = xed_decoded_inst_get_memory_operand_length(&xed_instr, 0);
215 xed_category_enum_t cat = xed_decoded_inst_get_category(&xed_instr);
216 if (cat == XED_CATEGORY_STRINGOP) {
217 instr_info->str_op = 1;
219 instr_info->str_op = 0;
222 xed_operand_values_t * operands = xed_decoded_inst_operands(&xed_instr);
223 if (xed_operand_values_has_real_rep(operands)) {
224 instr_info->has_rep = 1;
226 instr_info->has_rep = 0;
233 static int decode_string_op(struct guest_info * info,
234 xed_decoded_inst_t * xed_instr, const xed_inst_t * xi,
235 struct x86_instr * instr) {
237 PrintDebug("String operation\n");
239 if (instr->op_type == V3_OP_MOVS) {
240 instr->num_operands = 2;
242 if (get_memory_operand(info, xed_instr, 0, &(instr->dst_operand)) == -1) {
243 PrintError("Could not get Destination memory operand\n");
247 if (get_memory_operand(info, xed_instr, 1, &(instr->src_operand)) == -1) {
248 PrintError("Could not get Source memory operand\n");
252 if (instr->prefixes.rep == 1) {
254 uint_t reg_length = 0;
256 xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG0), ®_addr, ®_length);
257 instr->str_op_length = MASK(*(addr_t *)reg_addr, reg_length);
259 instr->str_op_length = 1;
262 } else if (instr->op_type == V3_OP_STOS) {
263 instr->num_operands = 2;
265 if (get_memory_operand(info, xed_instr, 0, &(instr->dst_operand)) == -1) {
266 PrintError("Could not get Destination memory operand\n");
270 // STOS reads from rax
271 xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG0),
272 &(instr->src_operand.operand),
273 &(instr->src_operand.size));
274 instr->src_operand.type = REG_OPERAND;
276 if (instr->prefixes.rep == 1) {
278 uint_t reg_length = 0;
280 xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG1), ®_addr, ®_length);
281 instr->str_op_length = MASK(*(addr_t *)reg_addr, reg_length);
283 instr->str_op_length = 1;
287 PrintError("Unhandled String OP\n");
296 int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
297 xed_decoded_inst_t xed_instr;
298 xed_error_enum_t xed_error;
301 v3_get_prefixes((uchar_t *)instr_ptr, &(instr->prefixes));
303 if (set_decoder_mode(info, info->decoder_state) == -1) {
304 PrintError("Could not set decoder mode\n");
308 xed_decoded_inst_zero_set_mode(&xed_instr, info->decoder_state);
310 xed_error = xed_decode(&xed_instr,
311 REINTERPRET_CAST(const xed_uint8_t *, instr_ptr),
312 XED_MAX_INSTRUCTION_BYTES);
315 if (xed_error != XED_ERROR_NONE) {
316 PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
320 const xed_inst_t * xi = xed_decoded_inst_inst(&xed_instr);
322 instr->instr_length = xed_decoded_inst_get_length(&xed_instr);
325 xed_iform_enum_t iform = xed_decoded_inst_get_iform_enum(&xed_instr);
328 xed_iclass_enum_t iclass = xed_decoded_inst_get_iclass(&xed_instr);
330 PrintDebug("iform=%s, iclass=%s\n", xed_iform_enum_t2str(iform), xed_iclass_enum_t2str(iclass));
334 if ((instr->op_type = get_opcode(iform)) == V3_INVALID_OP) {
335 PrintError("Could not get opcode. (iform=%s)\n", xed_iform_enum_t2str(iform));
340 // We special case the string operations...
341 if (xed_decoded_inst_get_category(&xed_instr) == XED_CATEGORY_STRINGOP) {
342 instr->is_str_op = 1;
343 return decode_string_op(info, &xed_instr, xi, instr);
345 instr->is_str_op = 0;
346 instr->str_op_length = 0;
350 instr->num_operands = xed_decoded_inst_noperands(&xed_instr);
352 if (instr->num_operands > 3) {
353 PrintDebug("Special Case Not Handled\n");
356 } else if (instr->num_operands == 3) {
357 const xed_operand_t * op = xed_inst_operand(xi, 2);
358 xed_operand_enum_t op_enum = xed_operand_name(op);
360 if ((!xed_operand_is_register(op_enum)) ||
361 (!is_flags_reg(xed_decoded_inst_get_reg(&xed_instr, op_enum)))) {
363 PrintError("Special Case not handled\n");
370 //PrintDebug("Number of operands: %d\n", instr->num_operands);
371 //PrintDebug("INSTR length: %d\n", instr->instr_length);
374 if (instr->num_operands >= 1) {
375 const xed_operand_t * op = xed_inst_operand(xi, 0);
376 xed_operand_enum_t op_enum = xed_operand_name(op);
378 struct x86_operand * v3_op = NULL;
381 if (xed_operand_written(op)) {
382 v3_op = &(instr->dst_operand);
384 v3_op = &(instr->src_operand);
388 v3_op = &(instr->dst_operand);
390 if (xed_operand_is_register(op_enum)) {
391 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
392 int v3_reg_type = xed_reg_to_v3_reg(info,
397 if (v3_reg_type == -1) {
398 PrintError("First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
399 v3_op->type = INVALID_OPERAND;
401 } else if (v3_reg_type == SEGMENT_REGISTER) {
402 struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
403 v3_op->operand = (addr_t)&(seg_reg->selector);
406 v3_op->type = REG_OPERAND;
411 case XED_OPERAND_MEM0:
413 PrintDebug("Memory operand (1)\n");
414 if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
415 PrintError("Could not get first memory operand\n");
421 case XED_OPERAND_MEM1:
422 case XED_OPERAND_IMM1:
424 PrintError("Illegal Operand Order\n");
428 case XED_OPERAND_IMM0:
429 case XED_OPERAND_AGEN:
430 case XED_OPERAND_PTR:
431 case XED_OPERAND_RELBR:
433 PrintError("Unhandled Operand Type\n");
441 // set second operand
442 if (instr->num_operands >= 2) {
443 const xed_operand_t * op = xed_inst_operand(xi, 1);
444 // xed_operand_type_enum_t op_type = xed_operand_type(op);
445 xed_operand_enum_t op_enum = xed_operand_name(op);
447 struct x86_operand * v3_op;
450 if (xed_operand_written(op)) {
451 v3_op = &(instr->dst_operand);
453 v3_op = &(instr->src_operand);
456 v3_op = &(instr->src_operand);
458 if (xed_operand_is_register(op_enum)) {
459 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
460 int v3_reg_type = xed_reg_to_v3_reg(info,
464 if (v3_reg_type == -1) {
465 PrintError("Second operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
466 v3_op->type = INVALID_OPERAND;
468 } else if (v3_reg_type == SEGMENT_REGISTER) {
469 struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
470 v3_op->operand = (addr_t)&(seg_reg->selector);
473 v3_op->type = REG_OPERAND;
480 case XED_OPERAND_MEM0:
482 PrintDebug("Memory operand (2)\n");
483 if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
484 PrintError("Could not get first memory operand\n");
490 case XED_OPERAND_IMM0:
492 instr->src_operand.size = xed_decoded_inst_get_immediate_width(&xed_instr);
494 if (instr->src_operand.size > 4) {
495 PrintError("Unhandled 64 bit immediates\n");
498 instr->src_operand.operand = xed_decoded_inst_get_unsigned_immediate(&xed_instr);
500 instr->src_operand.type = IMM_OPERAND;
505 case XED_OPERAND_MEM1:
506 case XED_OPERAND_IMM1:
508 PrintError("Illegal Operand Order\n");
511 case XED_OPERAND_AGEN:
512 case XED_OPERAND_PTR:
513 case XED_OPERAND_RELBR:
515 PrintError("Unhandled Operand Type\n");
523 if (instr->num_operands >= 3) {
524 const xed_operand_t * op = xed_inst_operand(xi, 2);
525 xed_operand_type_enum_t op_type = xed_operand_type(op);
526 xed_operand_enum_t op_enum = xed_operand_name(op);
528 if (xed_operand_is_register(op_enum)) {
529 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
530 int v3_reg_type = xed_reg_to_v3_reg(info,
532 &(instr->third_operand.operand),
533 &(instr->third_operand.size));
535 if (v3_reg_type == -1) {
536 PrintError("Third operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
537 instr->third_operand.type = INVALID_OPERAND;
539 } else if (v3_reg_type == SEGMENT_REGISTER) {
540 struct v3_segment * seg_reg = (struct v3_segment *)(instr->third_operand.operand);
541 instr->third_operand.operand = (addr_t)&(seg_reg->selector);
545 instr->third_operand.type = REG_OPERAND;
549 PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
562 int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) {
571 static int get_memory_operand(struct guest_info * info, xed_decoded_inst_t * xed_instr, uint_t op_index, struct x86_operand * operand) {
572 struct memory_operand mem_op;
578 ullong_t displacement;
579 int addr_width = v3_get_addr_width(info);;
580 // struct v3_segment * seg_reg;
582 PrintDebug("Xen mode = %s\n", xed_machine_mode_enum_t2str(xed_state_get_machine_mode(info->decoder_state)));
583 PrintDebug("Address width: %s\n",
584 xed_address_width_enum_t2str(xed_state_get_address_width(info->decoder_state)));
585 PrintDebug("Stack Address width: %s\n",
586 xed_address_width_enum_t2str(xed_state_get_stack_address_width(info->decoder_state)));
590 memset((void*)&mem_op, '\0', sizeof(struct memory_operand));
592 xed_reg_enum_t xed_seg = xed_decoded_inst_get_seg_reg(xed_instr, op_index);
593 if (xed_seg != XED_REG_INVALID) {
594 struct v3_segment *tmp_segment;
595 if (xed_reg_to_v3_reg(info, xed_seg, (addr_t *)&tmp_segment, &(mem_op.segment_size)) == -1) {
596 PrintError("Unhandled Segment Register\n");
599 mem_op.segment = tmp_segment->base;
602 xed_reg_enum_t xed_base = xed_decoded_inst_get_base_reg(xed_instr, op_index);
603 if (xed_base != XED_REG_INVALID) {
605 if (xed_reg_to_v3_reg(info, xed_base, &base_reg, &(mem_op.base_size)) == -1) {
606 PrintError("Unhandled Base register\n");
609 mem_op.base = *(addr_t *)base_reg;
614 xed_reg_enum_t xed_idx = xed_decoded_inst_get_index_reg(xed_instr, op_index);
615 if ((op_index == 0) && (xed_idx != XED_REG_INVALID)) {
618 if (xed_reg_to_v3_reg(info, xed_idx, &index_reg, &(mem_op.index_size)) == -1) {
619 PrintError("Unhandled Index Register\n");
623 mem_op.index= *(addr_t *)index_reg;
625 xed_uint_t xed_scale = xed_decoded_inst_get_scale(xed_instr, op_index);
626 if (xed_scale != 0) {
627 mem_op.scale = xed_scale;
632 xed_uint_t disp_bits = xed_decoded_inst_get_memory_displacement_width(xed_instr, op_index);
634 xed_int64_t xed_disp = xed_decoded_inst_get_memory_displacement(xed_instr, op_index);
636 mem_op.displacement_size = disp_bits;
637 mem_op.displacement = xed_disp;
640 operand->type = MEM_OPERAND;
641 operand->size = xed_decoded_inst_get_memory_operand_length(xed_instr, op_index);
645 PrintDebug("Struct: Seg=%p (size=%d), base=%p, index=%p, scale=%p, displacement=%p (size=%d)\n",
646 (void *)mem_op.segment, mem_op.segment_size, (void*)mem_op.base, (void *)mem_op.index,
647 (void *)mem_op.scale, (void *)(addr_t)mem_op.displacement, mem_op.displacement_size);
650 PrintDebug("operand size: %d\n", operand->size);
652 seg = MASK(mem_op.segment, mem_op.segment_size);
653 base = MASK(mem_op.base, mem_op.base_size);
654 index = MASK(mem_op.index, mem_op.index_size);
655 scale = mem_op.scale;
657 // This is a horrendous hack...
658 // XED really screwed the pooch in calculating the displacement
659 if (v3_get_cpu_mode(info) == LONG) {
660 displacement = mem_op.displacement;
662 displacement = MASK(mem_op.displacement, mem_op.displacement_size);
665 PrintDebug("Seg=%p, base=%p, index=%p, scale=%p, displacement=%p\n",
666 (void *)seg, (void *)base, (void *)index, (void *)scale, (void *)(addr_t)displacement);
668 operand->operand = MASK((seg + base + (scale * index) + displacement), addr_width);
674 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) {
676 PrintDebug("Xed Register: %s\n", xed_reg_enum_t2str(xed_reg));
679 case XED_REG_INVALID:
688 *v3_reg = (addr_t)&(info->vm_regs.rax);
692 *v3_reg = (addr_t)&(info->vm_regs.rax);
696 *v3_reg = (addr_t)&(info->vm_regs.rax);
700 *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
704 *v3_reg = (addr_t)&(info->vm_regs.rax);
709 *v3_reg = (addr_t)&(info->vm_regs.rcx);
713 *v3_reg = (addr_t)&(info->vm_regs.rcx);
717 *v3_reg = (addr_t)&(info->vm_regs.rcx);
721 *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
725 *v3_reg = (addr_t)&(info->vm_regs.rcx);
730 *v3_reg = (addr_t)&(info->vm_regs.rdx);
734 *v3_reg = (addr_t)&(info->vm_regs.rdx);
738 *v3_reg = (addr_t)&(info->vm_regs.rdx);
742 *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
746 *v3_reg = (addr_t)&(info->vm_regs.rdx);
751 *v3_reg = (addr_t)&(info->vm_regs.rbx);
755 *v3_reg = (addr_t)&(info->vm_regs.rbx);
759 *v3_reg = (addr_t)&(info->vm_regs.rbx);
763 *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
767 *v3_reg = (addr_t)&(info->vm_regs.rbx);
773 *v3_reg = (addr_t)&(info->vm_regs.rsp);
777 *v3_reg = (addr_t)&(info->vm_regs.rsp);
781 *v3_reg = (addr_t)&(info->vm_regs.rsp);
785 *v3_reg = (addr_t)&(info->vm_regs.rsp);
790 *v3_reg = (addr_t)&(info->vm_regs.rbp);
794 *v3_reg = (addr_t)&(info->vm_regs.rbp);
798 *v3_reg = (addr_t)&(info->vm_regs.rbp);
802 *v3_reg = (addr_t)&(info->vm_regs.rbp);
809 *v3_reg = (addr_t)&(info->vm_regs.rsi);
813 *v3_reg = (addr_t)&(info->vm_regs.rsi);
817 *v3_reg = (addr_t)&(info->vm_regs.rsi);
821 *v3_reg = (addr_t)&(info->vm_regs.rsi);
827 *v3_reg = (addr_t)&(info->vm_regs.rdi);
831 *v3_reg = (addr_t)&(info->vm_regs.rdi);
835 *v3_reg = (addr_t)&(info->vm_regs.rdi);
839 *v3_reg = (addr_t)&(info->vm_regs.rdi);
848 *v3_reg = (addr_t)&(info->vm_regs.r8);
852 *v3_reg = (addr_t)&(info->vm_regs.r8);
856 *v3_reg = (addr_t)&(info->vm_regs.r8);
860 *v3_reg = (addr_t)&(info->vm_regs.r8);
865 *v3_reg = (addr_t)&(info->vm_regs.r9);
869 *v3_reg = (addr_t)&(info->vm_regs.r9);
873 *v3_reg = (addr_t)&(info->vm_regs.r9);
877 *v3_reg = (addr_t)&(info->vm_regs.r9);
882 *v3_reg = (addr_t)&(info->vm_regs.r10);
886 *v3_reg = (addr_t)&(info->vm_regs.r10);
890 *v3_reg = (addr_t)&(info->vm_regs.r10);
894 *v3_reg = (addr_t)&(info->vm_regs.r10);
899 *v3_reg = (addr_t)&(info->vm_regs.r11);
903 *v3_reg = (addr_t)&(info->vm_regs.r11);
907 *v3_reg = (addr_t)&(info->vm_regs.r11);
911 *v3_reg = (addr_t)&(info->vm_regs.r11);
916 *v3_reg = (addr_t)&(info->vm_regs.r12);
920 *v3_reg = (addr_t)&(info->vm_regs.r12);
924 *v3_reg = (addr_t)&(info->vm_regs.r12);
928 *v3_reg = (addr_t)&(info->vm_regs.r12);
933 *v3_reg = (addr_t)&(info->vm_regs.r13);
937 *v3_reg = (addr_t)&(info->vm_regs.r13);
941 *v3_reg = (addr_t)&(info->vm_regs.r13);
945 *v3_reg = (addr_t)&(info->vm_regs.r13);
950 *v3_reg = (addr_t)&(info->vm_regs.r14);
954 *v3_reg = (addr_t)&(info->vm_regs.r14);
958 *v3_reg = (addr_t)&(info->vm_regs.r14);
962 *v3_reg = (addr_t)&(info->vm_regs.r14);
967 *v3_reg = (addr_t)&(info->vm_regs.r15);
971 *v3_reg = (addr_t)&(info->vm_regs.r15);
975 *v3_reg = (addr_t)&(info->vm_regs.r15);
979 *v3_reg = (addr_t)&(info->vm_regs.r15);
988 *v3_reg = (addr_t)&(info->rip);
990 return CTRL_REGISTER;
992 *v3_reg = (addr_t)&(info->rip);
994 return CTRL_REGISTER;
996 *v3_reg = (addr_t)&(info->rip);
998 return CTRL_REGISTER;
1001 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
1003 return CTRL_REGISTER;
1004 case XED_REG_EFLAGS:
1005 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
1007 return CTRL_REGISTER;
1008 case XED_REG_RFLAGS:
1009 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
1011 return CTRL_REGISTER;
1014 *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
1016 return CTRL_REGISTER;
1018 *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
1020 return CTRL_REGISTER;
1022 *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
1024 return CTRL_REGISTER;
1026 *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
1028 return CTRL_REGISTER;
1030 *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
1032 return CTRL_REGISTER;
1054 *v3_reg = (addr_t)&(info->segments.cs);
1056 return SEGMENT_REGISTER;
1058 *v3_reg = (addr_t)&(info->segments.ds);
1060 return SEGMENT_REGISTER;
1062 *v3_reg = (addr_t)&(info->segments.es);
1064 return SEGMENT_REGISTER;
1066 *v3_reg = (addr_t)&(info->segments.ss);
1068 return SEGMENT_REGISTER;
1070 *v3_reg = (addr_t)&(info->segments.fs);
1072 return SEGMENT_REGISTER;
1074 *v3_reg = (addr_t)&(info->segments.gs);
1076 return SEGMENT_REGISTER;
1083 PrintError("Segment selector operand... Don't know how to handle this...\n");
1148 case XED_REG_STACKPUSH:
1149 case XED_REG_STACKPOP:
1152 case XED_REG_TSCAUX:
1155 case XED_REG_X87CONTROL:
1156 case XED_REG_X87STATUS:
1157 case XED_REG_X87TOP:
1158 case XED_REG_X87TAG:
1159 case XED_REG_X87PUSH:
1160 case XED_REG_X87POP:
1161 case XED_REG_X87POP2:
1196 static v3_op_type_t get_opcode(xed_iform_enum_t iform) {
1200 /* Control Instructions */
1202 case XED_IFORM_MOV_CR_GPR64_CR:
1203 case XED_IFORM_MOV_CR_GPR32_CR:
1204 return V3_OP_MOVCR2;
1206 case XED_IFORM_MOV_CR_CR_GPR64:
1207 case XED_IFORM_MOV_CR_CR_GPR32:
1208 return V3_OP_MOV2CR;
1210 case XED_IFORM_SMSW_GPRv:
1213 case XED_IFORM_LMSW_GPR16:
1216 case XED_IFORM_CLTS:
1219 case XED_IFORM_INVLPG_MEMb:
1220 return V3_OP_INVLPG;
1223 /* Data Instructions */
1226 case XED_IFORM_ADC_MEMv_GPRv:
1227 case XED_IFORM_ADC_MEMv_IMM:
1228 case XED_IFORM_ADC_MEMb_GPR8:
1229 case XED_IFORM_ADC_MEMb_IMM:
1231 case XED_IFORM_ADC_GPRv_MEMv:
1232 case XED_IFORM_ADC_GPR8_MEMb:
1236 case XED_IFORM_ADD_MEMv_GPRv:
1237 case XED_IFORM_ADD_MEMb_IMM:
1238 case XED_IFORM_ADD_MEMb_GPR8:
1239 case XED_IFORM_ADD_MEMv_IMM:
1241 case XED_IFORM_ADD_GPRv_MEMv:
1242 case XED_IFORM_ADD_GPR8_MEMb:
1246 case XED_IFORM_AND_MEMv_IMM:
1247 case XED_IFORM_AND_MEMb_GPR8:
1248 case XED_IFORM_AND_MEMv_GPRv:
1249 case XED_IFORM_AND_MEMb_IMM:
1251 case XED_IFORM_AND_GPR8_MEMb:
1252 case XED_IFORM_AND_GPRv_MEMv:
1256 case XED_IFORM_SUB_MEMv_IMM:
1257 case XED_IFORM_SUB_MEMb_GPR8:
1258 case XED_IFORM_SUB_MEMb_IMM:
1259 case XED_IFORM_SUB_MEMv_GPRv:
1261 case XED_IFORM_SUB_GPR8_MEMb:
1262 case XED_IFORM_SUB_GPRv_MEMv:
1266 case XED_IFORM_MOV_MEMv_GPRv:
1267 case XED_IFORM_MOV_MEMb_GPR8:
1268 case XED_IFORM_MOV_MEMb_AL:
1269 case XED_IFORM_MOV_MEMv_IMM:
1270 case XED_IFORM_MOV_MEMb_IMM:
1272 case XED_IFORM_MOV_GPRv_MEMv:
1273 case XED_IFORM_MOV_GPR8_MEMb:
1274 case XED_IFORM_MOV_AL_MEMb:
1279 case XED_IFORM_MOVZX_GPRv_MEMb:
1280 case XED_IFORM_MOVZX_GPRv_MEMw:
1284 case XED_IFORM_MOVSX_GPRv_MEMb:
1285 case XED_IFORM_MOVSX_GPRv_MEMw:
1290 case XED_IFORM_DEC_MEMv:
1291 case XED_IFORM_DEC_MEMb:
1294 case XED_IFORM_INC_MEMb:
1295 case XED_IFORM_INC_MEMv:
1299 case XED_IFORM_OR_MEMv_IMM:
1300 case XED_IFORM_OR_MEMb_IMM:
1301 case XED_IFORM_OR_MEMv_GPRv:
1302 case XED_IFORM_OR_MEMb_GPR8:
1304 case XED_IFORM_OR_GPRv_MEMv:
1305 case XED_IFORM_OR_GPR8_MEMb:
1309 case XED_IFORM_XOR_MEMv_GPRv:
1310 case XED_IFORM_XOR_MEMb_IMM:
1311 case XED_IFORM_XOR_MEMb_GPR8:
1312 case XED_IFORM_XOR_MEMv_IMM:
1314 case XED_IFORM_XOR_GPRv_MEMv:
1315 case XED_IFORM_XOR_GPR8_MEMb:
1318 case XED_IFORM_NEG_MEMb:
1319 case XED_IFORM_NEG_MEMv:
1322 case XED_IFORM_NOT_MEMv:
1323 case XED_IFORM_NOT_MEMb:
1326 case XED_IFORM_XCHG_MEMv_GPRv:
1327 case XED_IFORM_XCHG_MEMb_GPR8:
1330 case XED_IFORM_SETB_MEMb:
1333 case XED_IFORM_SETBE_MEMb:
1336 case XED_IFORM_SETL_MEMb:
1339 case XED_IFORM_SETLE_MEMb:
1342 case XED_IFORM_SETNB_MEMb:
1345 case XED_IFORM_SETNBE_MEMb:
1346 return V3_OP_SETNBE;
1348 case XED_IFORM_SETNL_MEMb:
1351 case XED_IFORM_SETNLE_MEMb:
1352 return V3_OP_SETNLE;
1354 case XED_IFORM_SETNO_MEMb:
1357 case XED_IFORM_SETNP_MEMb:
1360 case XED_IFORM_SETNS_MEMb:
1363 case XED_IFORM_SETNZ_MEMb:
1366 case XED_IFORM_SETO_MEMb:
1369 case XED_IFORM_SETP_MEMb:
1372 case XED_IFORM_SETS_MEMb:
1375 case XED_IFORM_SETZ_MEMb:
1378 case XED_IFORM_MOVSB:
1379 case XED_IFORM_MOVSW:
1380 case XED_IFORM_MOVSD:
1381 case XED_IFORM_MOVSQ:
1384 case XED_IFORM_STOSB:
1385 case XED_IFORM_STOSW:
1386 case XED_IFORM_STOSD:
1387 case XED_IFORM_STOSQ:
1392 return V3_INVALID_OP;