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>
38 #ifndef V3_CONFIG_DEBUG_DECODER
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; \
84 struct memory_operand {
92 uint_t displacement_size;
93 ullong_t displacement;
99 static v3_op_type_t get_opcode(xed_iform_enum_t iform);
101 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);
102 static int get_memory_operand(struct guest_info * info, xed_decoded_inst_t * xed_instr, uint_t index, struct x86_operand * operand);
104 static int set_decoder_mode(struct guest_info * info, xed_state_t * state) {
105 switch (v3_get_vm_cpu_mode(info)) {
107 if (state->mmode != XED_MACHINE_MODE_LEGACY_16) {
108 xed_state_init(state,
109 XED_MACHINE_MODE_LEGACY_16,
110 XED_ADDRESS_WIDTH_16b,
111 XED_ADDRESS_WIDTH_16b);
116 if (state->mmode != XED_MACHINE_MODE_LEGACY_32) {
117 xed_state_init(state,
118 XED_MACHINE_MODE_LEGACY_32,
119 XED_ADDRESS_WIDTH_32b,
120 XED_ADDRESS_WIDTH_32b);
124 if (state->mmode != XED_MACHINE_MODE_LONG_COMPAT_32) {
125 xed_state_init(state,
126 XED_MACHINE_MODE_LONG_COMPAT_32,
127 XED_ADDRESS_WIDTH_32b,
128 XED_ADDRESS_WIDTH_32b);
132 if (state->mmode != XED_MACHINE_MODE_LONG_64) {
133 PrintDebug(info->vm_info, info, "Setting decoder to long mode\n");
134 // state->mmode = XED_MACHINE_MODE_LONG_64;
135 //xed_state_set_machine_mode(state, XED_MACHINE_MODE_LONG_64);
136 xed_state_init(state,
137 XED_MACHINE_MODE_LONG_64,
138 XED_ADDRESS_WIDTH_64b,
139 XED_ADDRESS_WIDTH_64b);
143 PrintError(info->vm_info, info, "Unsupported CPU mode: %d\n", info->cpu_mode);
150 static int is_flags_reg(xed_reg_enum_t xed_reg) {
162 int v3_init_decoder(struct guest_info * info) {
163 // Global library initialization, only do it once
164 if (tables_inited == 0) {
169 xed_state_t * decoder_state = (xed_state_t *)V3_Malloc(sizeof(xed_state_t));
171 if (!decoder_state) {
172 PrintError(info->vm_info, info, "Cannot allocate in initializing decoder\n");
176 xed_state_zero(decoder_state);
177 xed_state_init(decoder_state,
178 XED_MACHINE_MODE_LEGACY_32,
179 XED_ADDRESS_WIDTH_32b,
180 XED_ADDRESS_WIDTH_32b);
182 info->decoder_state = decoder_state;
189 int v3_deinit_decoder(struct guest_info * core) {
190 V3_Free(core->decoder_state);
198 static int decode_string_op(struct guest_info * info,
199 xed_decoded_inst_t * xed_instr, const xed_inst_t * xi,
200 struct x86_instr * instr) {
202 PrintDebug(info->vm_info, info, "String operation\n");
204 if (instr->op_type == V3_OP_MOVS) {
205 instr->num_operands = 2;
207 if (get_memory_operand(info, xed_instr, 0, &(instr->dst_operand)) == -1) {
208 PrintError(info->vm_info, info, "Could not get Destination memory operand\n");
213 if (get_memory_operand(info, xed_instr, 1, &(instr->src_operand)) == -1) {
214 PrintError(info->vm_info, info, "Could not get Source memory operand\n");
218 instr->dst_operand.write = 1;
219 instr->src_operand.read = 1;
221 if (instr->prefixes.rep == 1) {
223 uint_t reg_length = 0;
225 xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG0), ®_addr, ®_length);
226 instr->str_op_length = MASK(*(addr_t *)reg_addr, reg_length);
228 instr->str_op_length = 1;
231 } else if (instr->op_type == V3_OP_STOS) {
232 instr->num_operands = 2;
234 if (get_memory_operand(info, xed_instr, 0, &(instr->dst_operand)) == -1) {
235 PrintError(info->vm_info, info, "Could not get Destination memory operand\n");
239 // STOS reads from rax
240 xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG0),
241 &(instr->src_operand.operand),
242 &(instr->src_operand.size));
243 instr->src_operand.type = REG_OPERAND;
245 instr->src_operand.read = 1;
246 instr->dst_operand.write = 1;
248 if (instr->prefixes.rep == 1) {
250 uint_t reg_length = 0;
252 xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG1),
253 ®_addr, ®_length);
254 instr->str_op_length = MASK(*(addr_t *)reg_addr, reg_length);
256 instr->str_op_length = 1;
260 PrintError(info->vm_info, info, "Unhandled String OP\n");
269 int v3_disasm(struct guest_info * info, void *instr_ptr, addr_t * rip, int mark) {
273 xed_decoded_inst_t xed_instr;
274 xed_error_enum_t xed_error;
276 /* disassemble the specified instruction */
277 if (set_decoder_mode(info, info->decoder_state) == -1) {
278 PrintError(info->vm_info, info, "Could not set decoder mode\n");
282 xed_decoded_inst_zero_set_mode(&xed_instr, info->decoder_state);
284 xed_error = xed_decode(&xed_instr,
285 REINTERPRET_CAST(const xed_uint8_t *, instr_ptr),
286 XED_MAX_INSTRUCTION_BYTES);
288 if (xed_error != XED_ERROR_NONE) {
289 PrintError(info->vm_info, info, "Xed error: %s\n", xed_error_enum_t2str(xed_error));
293 /* obtain string representation in AT&T syntax */
294 if (!xed_format_att(&xed_instr, buffer, sizeof(buffer), *rip)) {
295 PrintError(info->vm_info, info, "Xed error: cannot disaaemble\n");
299 /* print address, opcode bytes and the disassembled instruction */
300 length = xed_decoded_inst_get_length(&xed_instr);
301 V3_Print(info->vm_info, info, "0x%p %c ", (void *) *rip, mark ? '*' : ' ');
302 for (i = 0; i < length; i++) {
303 unsigned char b = ((unsigned char *) instr_ptr)[i];
304 V3_Print(info->vm_info, info, "%x%x ", b >> 4, b & 0xf);
307 V3_Print(info->vm_info, info, " ");
309 V3_Print(info->vm_info, info, "%s\n", buffer);
311 /* move on to next instruction */
318 int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
319 xed_decoded_inst_t xed_instr;
320 xed_error_enum_t xed_error;
322 memset(instr, 0, sizeof(struct x86_instr));
325 v3_get_prefixes((uchar_t *)instr_ptr, &(instr->prefixes));
327 if (set_decoder_mode(info, info->decoder_state) == -1) {
328 PrintError(info->vm_info, info, "Could not set decoder mode\n");
332 xed_decoded_inst_zero_set_mode(&xed_instr, info->decoder_state);
334 xed_error = xed_decode(&xed_instr,
335 REINTERPRET_CAST(const xed_uint8_t *, instr_ptr),
336 XED_MAX_INSTRUCTION_BYTES);
339 if (xed_error != XED_ERROR_NONE) {
340 PrintError(info->vm_info, info, "Xed error: %s\n", xed_error_enum_t2str(xed_error));
344 const xed_inst_t * xi = xed_decoded_inst_inst(&xed_instr);
346 instr->instr_length = xed_decoded_inst_get_length(&xed_instr);
349 xed_iform_enum_t iform = xed_decoded_inst_get_iform_enum(&xed_instr);
351 #ifdef V3_CONFIG_DEBUG_DECODER
352 xed_iclass_enum_t iclass = xed_decoded_inst_get_iclass(&xed_instr);
354 PrintDebug(info->vm_info, info, "iform=%s, iclass=%s\n", xed_iform_enum_t2str(iform), xed_iclass_enum_t2str(iclass));
358 if ((instr->op_type = get_opcode(iform)) == V3_INVALID_OP) {
359 PrintError(info->vm_info, info, "Could not get opcode. (iform=%s)\n", xed_iform_enum_t2str(iform));
364 // We special case the string operations...
365 if (xed_decoded_inst_get_category(&xed_instr) == XED_CATEGORY_STRINGOP) {
366 instr->is_str_op = 1;
367 return decode_string_op(info, &xed_instr, xi, instr);
369 instr->is_str_op = 0;
370 instr->str_op_length = 0;
373 instr->num_operands = xed_decoded_inst_noperands(&xed_instr);
376 if (instr->num_operands > 3) {
377 PrintDebug(info->vm_info, info, "Special Case Not Handled (more than 3 operands) (iform=%s)\n", xed_iform_enum_t2str(iform)
380 } else if (instr->num_operands == 3) {
381 const xed_operand_t * op = xed_inst_operand(xi, 2);
382 xed_operand_enum_t op_enum = xed_operand_name(op);
384 if ((!xed_operand_is_register(op_enum)) ||
385 (!is_flags_reg(xed_decoded_inst_get_reg(&xed_instr, op_enum)))) {
387 PrintError(info->vm_info, info, "Special Case not handled (iform=%s)\n", xed_iform_enum_t2str(iform));
393 //PrintDebug(info->vm_info, info, "Number of operands: %d\n", instr->num_operands);
394 //PrintDebug(info->vm_info, info, "INSTR length: %d\n", instr->instr_length);
397 if (instr->num_operands >= 1) {
398 const xed_operand_t * op = xed_inst_operand(xi, 0);
399 xed_operand_enum_t op_enum = xed_operand_name(op);
401 struct x86_operand * v3_op = NULL;
404 if (xed_operand_written(op)) {
405 v3_op = &(instr->dst_operand);
407 v3_op = &(instr->src_operand);
411 v3_op = &(instr->dst_operand);
413 if (xed_operand_is_register(op_enum)) {
414 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
415 int v3_reg_type = xed_reg_to_v3_reg(info,
420 if (v3_reg_type == -1) {
421 PrintError(info->vm_info, info, "First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
422 v3_op->type = INVALID_OPERAND;
424 } else if (v3_reg_type == SEGMENT_REGISTER) {
425 struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
426 v3_op->operand = (addr_t)&(seg_reg->selector);
429 v3_op->type = REG_OPERAND;
434 case XED_OPERAND_MEM0:
436 PrintDebug(info->vm_info, info, "Memory operand (1)\n");
437 if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
438 PrintError(info->vm_info, info, "Could not get first memory operand\n");
444 case XED_OPERAND_MEM1:
445 case XED_OPERAND_IMM1:
447 PrintError(info->vm_info, info, "Illegal Operand Order\n");
451 case XED_OPERAND_IMM0:
453 v3_op->size = xed_decoded_inst_get_immediate_width(&xed_instr);
455 if (v3_op->size > 4) {
456 PrintError(info->vm_info, info, "Unhandled 64 bit immediates\n");
459 v3_op->operand = xed_decoded_inst_get_unsigned_immediate(&xed_instr);
461 v3_op->type = IMM_OPERAND;
465 case XED_OPERAND_AGEN:
466 case XED_OPERAND_PTR:
467 case XED_OPERAND_RELBR:
469 PrintError(info->vm_info, info, "Unhandled Operand Type\n");
474 // V3_Print(info->vm_info, info, "Operand 0 mode: %s\n", xed_operand_action_enum_t2str(xed_operand_rw(op)));
477 if (xed_operand_read(op)) {
481 if (xed_operand_written(op)) {
487 // set second operand
488 if (instr->num_operands >= 2) {
489 const xed_operand_t * op = xed_inst_operand(xi, 1);
490 // xed_operand_type_enum_t op_type = xed_operand_type(op);
491 xed_operand_enum_t op_enum = xed_operand_name(op);
493 struct x86_operand * v3_op;
496 if (xed_operand_written(op)) {
497 v3_op = &(instr->dst_operand);
499 v3_op = &(instr->src_operand);
502 v3_op = &(instr->src_operand);
505 if (xed_operand_is_register(op_enum)) {
506 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
507 int v3_reg_type = xed_reg_to_v3_reg(info,
511 if (v3_reg_type == -1) {
512 PrintError(info->vm_info, info, "Second operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
513 v3_op->type = INVALID_OPERAND;
515 } else if (v3_reg_type == SEGMENT_REGISTER) {
516 struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
517 v3_op->operand = (addr_t)&(seg_reg->selector);
520 v3_op->type = REG_OPERAND;
524 case XED_OPERAND_MEM0:
526 PrintDebug(info->vm_info, info, "Memory operand (2)\n");
527 if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
528 PrintError(info->vm_info, info, "Could not get first memory operand\n");
534 case XED_OPERAND_IMM0:
536 instr->src_operand.size = xed_decoded_inst_get_immediate_width(&xed_instr);
538 if (instr->src_operand.size > 4) {
539 PrintError(info->vm_info, info, "Unhandled 64 bit immediates\n");
542 instr->src_operand.operand = xed_decoded_inst_get_unsigned_immediate(&xed_instr);
544 instr->src_operand.type = IMM_OPERAND;
549 case XED_OPERAND_MEM1:
550 case XED_OPERAND_IMM1:
552 PrintError(info->vm_info, info, "Illegal Operand Order\n");
555 case XED_OPERAND_AGEN:
556 case XED_OPERAND_PTR:
557 case XED_OPERAND_RELBR:
559 PrintError(info->vm_info, info, "Unhandled Operand Type\n");
564 // V3_Print(info->vm_info, info, "Operand 1 mode: %s\n", xed_operand_action_enum_t2str(xed_operand_rw(op)));
566 if (xed_operand_read(op)) {
570 if (xed_operand_written(op)) {
577 if (instr->num_operands >= 3) {
578 const xed_operand_t * op = xed_inst_operand(xi, 2);
579 xed_operand_type_enum_t op_type = xed_operand_type(op);
580 xed_operand_enum_t op_enum = xed_operand_name(op);
584 if (xed_operand_is_register(op_enum)) {
585 xed_reg_enum_t xed_reg = xed_decoded_inst_get_reg(&xed_instr, op_enum);
586 int v3_reg_type = xed_reg_to_v3_reg(info,
588 &(instr->third_operand.operand),
589 &(instr->third_operand.size));
591 if (v3_reg_type == -1) {
592 PrintError(info->vm_info, info, "Third operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
593 instr->third_operand.type = INVALID_OPERAND;
595 } else if (v3_reg_type == SEGMENT_REGISTER) {
596 struct v3_segment * seg_reg = (struct v3_segment *)(instr->third_operand.operand);
597 instr->third_operand.operand = (addr_t)&(seg_reg->selector);
601 instr->third_operand.type = REG_OPERAND;
603 PrintDebug(info->vm_info, info, "Operand 2 mode: %s\n", xed_operand_action_enum_t2str(xed_operand_rw(op)));
606 if (xed_operand_read(op)) {
607 instr->third_operand.read = 1;
610 if (xed_operand_written(op)) {
611 instr->third_operand.write = 1;
615 PrintError(info->vm_info, info, "Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
616 instr->num_operands = 2;
624 int v3_encode(struct guest_info * info, struct x86_instr * instr, uint8_t * instr_buf) {
633 static int get_memory_operand(struct guest_info * info, xed_decoded_inst_t * xed_instr, uint_t op_index, struct x86_operand * operand) {
634 struct memory_operand mem_op;
640 ullong_t displacement;
641 int addr_width = v3_get_addr_width(info);
642 v3_cpu_mode_t cpu_mode = v3_get_vm_cpu_mode(info);
643 // struct v3_segment * seg_reg;
645 PrintDebug(info->vm_info, info, "Xed mode = %s\n", xed_machine_mode_enum_t2str(xed_state_get_machine_mode(info->decoder_state)));
646 PrintDebug(info->vm_info, info, "Address width: %s\n",
647 xed_address_width_enum_t2str(xed_state_get_address_width(info->decoder_state)));
648 PrintDebug(info->vm_info, info, "Stack Address width: %s\n",
649 xed_address_width_enum_t2str(xed_state_get_stack_address_width(info->decoder_state)));
653 memset((void*)&mem_op, '\0', sizeof(struct memory_operand));
655 xed_reg_enum_t xed_seg = xed_decoded_inst_get_seg_reg(xed_instr, op_index);
656 if (xed_seg != XED_REG_INVALID) {
657 struct v3_segment *tmp_segment;
658 if (xed_reg_to_v3_reg(info, xed_seg, (addr_t *)&tmp_segment, &(mem_op.segment_size)) == -1) {
659 PrintError(info->vm_info, info, "Unhandled Segment Register\n");
662 mem_op.segment = tmp_segment->base;
665 xed_reg_enum_t xed_base = xed_decoded_inst_get_base_reg(xed_instr, op_index);
666 if (xed_base != XED_REG_INVALID) {
668 if (xed_reg_to_v3_reg(info, xed_base, &base_reg, &(mem_op.base_size)) == -1) {
669 PrintError(info->vm_info, info, "Unhandled Base register\n");
672 mem_op.base = *(addr_t *)base_reg;
677 xed_reg_enum_t xed_idx = xed_decoded_inst_get_index_reg(xed_instr, op_index);
678 if ((op_index == 0) && (xed_idx != XED_REG_INVALID)) {
681 if (xed_reg_to_v3_reg(info, xed_idx, &index_reg, &(mem_op.index_size)) == -1) {
682 PrintError(info->vm_info, info, "Unhandled Index Register\n");
686 mem_op.index= *(addr_t *)index_reg;
688 xed_uint_t xed_scale = xed_decoded_inst_get_scale(xed_instr, op_index);
689 if (xed_scale != 0) {
690 mem_op.scale = xed_scale;
695 xed_uint_t disp_bits = xed_decoded_inst_get_memory_displacement_width(xed_instr, op_index);
697 xed_int64_t xed_disp = xed_decoded_inst_get_memory_displacement(xed_instr, op_index);
699 mem_op.displacement_size = disp_bits;
700 mem_op.displacement = xed_disp;
703 operand->type = MEM_OPERAND;
704 operand->size = xed_decoded_inst_get_memory_operand_length(xed_instr, op_index);
708 PrintDebug(info->vm_info, info, "Struct: Seg=%p (size=%d), base=%p, index=%p, scale=%p, displacement=%p (size=%d)\n",
709 (void *)mem_op.segment, mem_op.segment_size, (void*)mem_op.base, (void *)mem_op.index,
710 (void *)mem_op.scale, (void *)(addr_t)mem_op.displacement, mem_op.displacement_size);
713 PrintDebug(info->vm_info, info, "operand size: %d\n", operand->size);
715 seg = MASK(mem_op.segment, mem_op.segment_size);
716 base = MASK(mem_op.base, mem_op.base_size);
717 index = MASK(mem_op.index, mem_op.index_size);
718 scale = mem_op.scale;
720 // XED returns the displacement as a 2s complement signed number, but it can
721 // have different sizes, depending on the instruction encoding.
722 // we put that into a 64 bit unsigned (the unsigned doesn't matter since
723 // we only ever do 2s complement arithmetic on it. However, this means we
724 // need to sign-extend what XED provides through 64 bits.
725 displacement = mem_op.displacement;
726 displacement <<= 64 - mem_op.displacement_size * 8;
727 displacement = ((sllong_t)displacement) >> (64 - mem_op.displacement_size * 8);
730 PrintDebug(info->vm_info, info, "Seg=%p, base=%p, index=%p, scale=%p, displacement=%p\n",
731 (void *)seg, (void *)base, (void *)index, (void *)scale, (void *)(addr_t)displacement);
733 if (cpu_mode == REAL) {
734 operand->operand = seg + MASK((base + (scale * index) + displacement), addr_width);
736 operand->operand = MASK((seg + base + (scale * index) + displacement), addr_width);
743 static int xed_reg_to_v3_reg(struct guest_info * info, xed_reg_enum_t xed_reg,
744 addr_t * v3_reg, uint_t * reg_len) {
746 PrintDebug(info->vm_info, info, "Xed Register: %s\n", xed_reg_enum_t2str(xed_reg));
749 case XED_REG_INVALID:
758 *v3_reg = (addr_t)&(info->vm_regs.rax);
762 *v3_reg = (addr_t)&(info->vm_regs.rax);
766 *v3_reg = (addr_t)&(info->vm_regs.rax);
770 *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
774 *v3_reg = (addr_t)&(info->vm_regs.rax);
779 *v3_reg = (addr_t)&(info->vm_regs.rcx);
783 *v3_reg = (addr_t)&(info->vm_regs.rcx);
787 *v3_reg = (addr_t)&(info->vm_regs.rcx);
791 *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
795 *v3_reg = (addr_t)&(info->vm_regs.rcx);
800 *v3_reg = (addr_t)&(info->vm_regs.rdx);
804 *v3_reg = (addr_t)&(info->vm_regs.rdx);
808 *v3_reg = (addr_t)&(info->vm_regs.rdx);
812 *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
816 *v3_reg = (addr_t)&(info->vm_regs.rdx);
821 *v3_reg = (addr_t)&(info->vm_regs.rbx);
825 *v3_reg = (addr_t)&(info->vm_regs.rbx);
829 *v3_reg = (addr_t)&(info->vm_regs.rbx);
833 *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
837 *v3_reg = (addr_t)&(info->vm_regs.rbx);
843 *v3_reg = (addr_t)&(info->vm_regs.rsp);
847 *v3_reg = (addr_t)&(info->vm_regs.rsp);
851 *v3_reg = (addr_t)&(info->vm_regs.rsp);
855 *v3_reg = (addr_t)&(info->vm_regs.rsp);
860 *v3_reg = (addr_t)&(info->vm_regs.rbp);
864 *v3_reg = (addr_t)&(info->vm_regs.rbp);
868 *v3_reg = (addr_t)&(info->vm_regs.rbp);
872 *v3_reg = (addr_t)&(info->vm_regs.rbp);
879 *v3_reg = (addr_t)&(info->vm_regs.rsi);
883 *v3_reg = (addr_t)&(info->vm_regs.rsi);
887 *v3_reg = (addr_t)&(info->vm_regs.rsi);
891 *v3_reg = (addr_t)&(info->vm_regs.rsi);
897 *v3_reg = (addr_t)&(info->vm_regs.rdi);
901 *v3_reg = (addr_t)&(info->vm_regs.rdi);
905 *v3_reg = (addr_t)&(info->vm_regs.rdi);
909 *v3_reg = (addr_t)&(info->vm_regs.rdi);
918 *v3_reg = (addr_t)&(info->vm_regs.r8);
922 *v3_reg = (addr_t)&(info->vm_regs.r8);
926 *v3_reg = (addr_t)&(info->vm_regs.r8);
930 *v3_reg = (addr_t)&(info->vm_regs.r8);
935 *v3_reg = (addr_t)&(info->vm_regs.r9);
939 *v3_reg = (addr_t)&(info->vm_regs.r9);
943 *v3_reg = (addr_t)&(info->vm_regs.r9);
947 *v3_reg = (addr_t)&(info->vm_regs.r9);
952 *v3_reg = (addr_t)&(info->vm_regs.r10);
956 *v3_reg = (addr_t)&(info->vm_regs.r10);
960 *v3_reg = (addr_t)&(info->vm_regs.r10);
964 *v3_reg = (addr_t)&(info->vm_regs.r10);
969 *v3_reg = (addr_t)&(info->vm_regs.r11);
973 *v3_reg = (addr_t)&(info->vm_regs.r11);
977 *v3_reg = (addr_t)&(info->vm_regs.r11);
981 *v3_reg = (addr_t)&(info->vm_regs.r11);
986 *v3_reg = (addr_t)&(info->vm_regs.r12);
990 *v3_reg = (addr_t)&(info->vm_regs.r12);
994 *v3_reg = (addr_t)&(info->vm_regs.r12);
998 *v3_reg = (addr_t)&(info->vm_regs.r12);
1000 return GPR_REGISTER;
1003 *v3_reg = (addr_t)&(info->vm_regs.r13);
1005 return GPR_REGISTER;
1007 *v3_reg = (addr_t)&(info->vm_regs.r13);
1009 return GPR_REGISTER;
1011 *v3_reg = (addr_t)&(info->vm_regs.r13);
1013 return GPR_REGISTER;
1015 *v3_reg = (addr_t)&(info->vm_regs.r13);
1017 return GPR_REGISTER;
1020 *v3_reg = (addr_t)&(info->vm_regs.r14);
1022 return GPR_REGISTER;
1024 *v3_reg = (addr_t)&(info->vm_regs.r14);
1026 return GPR_REGISTER;
1028 *v3_reg = (addr_t)&(info->vm_regs.r14);
1030 return GPR_REGISTER;
1032 *v3_reg = (addr_t)&(info->vm_regs.r14);
1034 return GPR_REGISTER;
1037 *v3_reg = (addr_t)&(info->vm_regs.r15);
1039 return GPR_REGISTER;
1041 *v3_reg = (addr_t)&(info->vm_regs.r15);
1043 return GPR_REGISTER;
1045 *v3_reg = (addr_t)&(info->vm_regs.r15);
1047 return GPR_REGISTER;
1049 *v3_reg = (addr_t)&(info->vm_regs.r15);
1051 return GPR_REGISTER;
1058 *v3_reg = (addr_t)&(info->rip);
1060 return CTRL_REGISTER;
1062 *v3_reg = (addr_t)&(info->rip);
1064 return CTRL_REGISTER;
1066 *v3_reg = (addr_t)&(info->rip);
1068 return CTRL_REGISTER;
1071 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
1073 return CTRL_REGISTER;
1074 case XED_REG_EFLAGS:
1075 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
1077 return CTRL_REGISTER;
1078 case XED_REG_RFLAGS:
1079 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
1081 return CTRL_REGISTER;
1084 *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
1086 return CTRL_REGISTER;
1088 *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
1090 return CTRL_REGISTER;
1092 *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
1094 return CTRL_REGISTER;
1096 *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
1098 return CTRL_REGISTER;
1100 // TODO FIX: Peter says this should actually look like:
1101 // ((info->ctrl_regs.apic_tpr >> 4) & 0xf)
1102 // but this isn't straightforward since it doesn't
1103 // make an lvalue (need to create temporary).
1104 // Committing simple fix below to fix build. We are
1105 // never going to use xed going forward anyway, so
1106 // this doesn't matter.
1107 *v3_reg = (addr_t)&(info->ctrl_regs.apic_tpr);
1109 return CTRL_REGISTER;
1131 *v3_reg = (addr_t)&(info->segments.cs);
1133 return SEGMENT_REGISTER;
1135 *v3_reg = (addr_t)&(info->segments.ds);
1137 return SEGMENT_REGISTER;
1139 *v3_reg = (addr_t)&(info->segments.es);
1141 return SEGMENT_REGISTER;
1143 *v3_reg = (addr_t)&(info->segments.ss);
1145 return SEGMENT_REGISTER;
1147 *v3_reg = (addr_t)&(info->segments.fs);
1149 return SEGMENT_REGISTER;
1151 *v3_reg = (addr_t)&(info->segments.gs);
1153 return SEGMENT_REGISTER;
1160 PrintError(info->vm_info, info, "Segment selector operand... Don't know how to handle this...\n");
1225 case XED_REG_STACKPUSH:
1226 case XED_REG_STACKPOP:
1229 case XED_REG_TSCAUX:
1232 case XED_REG_X87CONTROL:
1233 case XED_REG_X87STATUS:
1234 case XED_REG_X87TOP:
1235 case XED_REG_X87TAG:
1236 case XED_REG_X87PUSH:
1237 case XED_REG_X87POP:
1238 case XED_REG_X87POP2:
1273 static v3_op_type_t get_opcode(xed_iform_enum_t iform) {
1277 /* Control Instructions */
1279 case XED_IFORM_MOV_CR_GPR64_CR:
1280 case XED_IFORM_MOV_CR_GPR32_CR:
1281 return V3_OP_MOVCR2;
1283 case XED_IFORM_MOV_CR_CR_GPR64:
1284 case XED_IFORM_MOV_CR_CR_GPR32:
1285 return V3_OP_MOV2CR;
1287 case XED_IFORM_SMSW_GPRv:
1290 case XED_IFORM_LMSW_GPR16:
1293 case XED_IFORM_CLTS:
1296 case XED_IFORM_INVLPG_MEMb:
1297 return V3_OP_INVLPG;
1299 case XED_IFORM_INT_IMM:
1303 /* Data Instructions */
1306 case XED_IFORM_ADC_MEMv_GPRv:
1307 case XED_IFORM_ADC_MEMv_IMM:
1308 case XED_IFORM_ADC_MEMb_GPR8:
1309 case XED_IFORM_ADC_MEMb_IMM:
1311 case XED_IFORM_ADC_GPRv_MEMv:
1312 case XED_IFORM_ADC_GPR8_MEMb:
1316 case XED_IFORM_ADD_MEMv_GPRv:
1317 case XED_IFORM_ADD_MEMb_IMM:
1318 case XED_IFORM_ADD_MEMb_GPR8:
1319 case XED_IFORM_ADD_MEMv_IMM:
1321 case XED_IFORM_ADD_GPRv_MEMv:
1322 case XED_IFORM_ADD_GPR8_MEMb:
1326 case XED_IFORM_AND_MEMv_IMM:
1327 case XED_IFORM_AND_MEMb_GPR8:
1328 case XED_IFORM_AND_MEMv_GPRv:
1329 case XED_IFORM_AND_MEMb_IMM:
1331 case XED_IFORM_AND_GPR8_MEMb:
1332 case XED_IFORM_AND_GPRv_MEMv:
1336 case XED_IFORM_SUB_MEMv_IMM:
1337 case XED_IFORM_SUB_MEMb_GPR8:
1338 case XED_IFORM_SUB_MEMb_IMM:
1339 case XED_IFORM_SUB_MEMv_GPRv:
1341 case XED_IFORM_SUB_GPR8_MEMb:
1342 case XED_IFORM_SUB_GPRv_MEMv:
1346 case XED_IFORM_MOV_MEMv_GPRv:
1347 case XED_IFORM_MOV_MEMb_GPR8:
1348 case XED_IFORM_MOV_MEMv_OrAX:
1349 case XED_IFORM_MOV_MEMb_AL:
1350 case XED_IFORM_MOV_MEMv_IMM:
1351 case XED_IFORM_MOV_MEMb_IMM:
1353 case XED_IFORM_MOV_GPRv_MEMv:
1354 case XED_IFORM_MOV_GPR8_MEMb:
1355 case XED_IFORM_MOV_OrAX_MEMv:
1356 case XED_IFORM_MOV_AL_MEMb:
1361 case XED_IFORM_MOVZX_GPRv_MEMb:
1362 case XED_IFORM_MOVZX_GPRv_MEMw:
1366 case XED_IFORM_MOVSX_GPRv_MEMb:
1367 case XED_IFORM_MOVSX_GPRv_MEMw:
1372 case XED_IFORM_DEC_MEMv:
1373 case XED_IFORM_DEC_MEMb:
1376 case XED_IFORM_INC_MEMb:
1377 case XED_IFORM_INC_MEMv:
1381 case XED_IFORM_OR_MEMv_IMM:
1382 case XED_IFORM_OR_MEMb_IMM:
1383 case XED_IFORM_OR_MEMv_GPRv:
1384 case XED_IFORM_OR_MEMb_GPR8:
1386 case XED_IFORM_OR_GPRv_MEMv:
1387 case XED_IFORM_OR_GPR8_MEMb:
1391 case XED_IFORM_XOR_MEMv_GPRv:
1392 case XED_IFORM_XOR_MEMb_IMM:
1393 case XED_IFORM_XOR_MEMb_GPR8:
1394 case XED_IFORM_XOR_MEMv_IMM:
1396 case XED_IFORM_XOR_GPRv_MEMv:
1397 case XED_IFORM_XOR_GPR8_MEMb:
1400 case XED_IFORM_NEG_MEMb:
1401 case XED_IFORM_NEG_MEMv:
1404 case XED_IFORM_NOT_MEMv:
1405 case XED_IFORM_NOT_MEMb:
1408 case XED_IFORM_XCHG_MEMv_GPRv:
1409 case XED_IFORM_XCHG_MEMb_GPR8:
1412 case XED_IFORM_SETB_MEMb:
1415 case XED_IFORM_SETBE_MEMb:
1418 case XED_IFORM_SETL_MEMb:
1421 case XED_IFORM_SETLE_MEMb:
1424 case XED_IFORM_SETNB_MEMb:
1427 case XED_IFORM_SETNBE_MEMb:
1428 return V3_OP_SETNBE;
1430 case XED_IFORM_SETNL_MEMb:
1433 case XED_IFORM_SETNLE_MEMb:
1434 return V3_OP_SETNLE;
1436 case XED_IFORM_SETNO_MEMb:
1439 case XED_IFORM_SETNP_MEMb:
1442 case XED_IFORM_SETNS_MEMb:
1445 case XED_IFORM_SETNZ_MEMb:
1448 case XED_IFORM_SETO_MEMb:
1451 case XED_IFORM_SETP_MEMb:
1454 case XED_IFORM_SETS_MEMb:
1457 case XED_IFORM_SETZ_MEMb:
1460 case XED_IFORM_MOVSB:
1461 case XED_IFORM_MOVSW:
1462 case XED_IFORM_MOVSD:
1463 case XED_IFORM_MOVSQ:
1466 case XED_IFORM_STOSB:
1467 case XED_IFORM_STOSW:
1468 case XED_IFORM_STOSD:
1469 case XED_IFORM_STOSQ:
1474 return V3_INVALID_OP;