Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


initial checking of internal decoder
Jack Lange [Fri, 4 Mar 2011 22:05:14 +0000 (16:05 -0600)]
Kconfig
palacios/include/palacios/vmm_decoder.h
palacios/include/palacios/vmm_ss_emulator.h [deleted file]
palacios/lib/i386/Makefile
palacios/lib/x86_64/Makefile
palacios/src/palacios/Makefile
palacios/src/palacios/vmm.c
palacios/src/palacios/vmm_decoder.c
palacios/src/palacios/vmm_ss_emulator.c [deleted file]
palacios/src/palacios/vmm_v3dec.c [new file with mode: 0644]
palacios/src/palacios/vmm_xed.c

diff --git a/Kconfig b/Kconfig
index 06f962b..6c11bac 100644 (file)
--- a/Kconfig
+++ b/Kconfig
@@ -63,6 +63,22 @@ config DEBUG_INFO
        help
          Compiles the Palacios library with debugging symbols
 
+choice 
+       prompt "X86 decoder"
+       default XED
+
+config XED
+       bool "XED decoder library"
+       help
+          This uses the XED decoder library from pintools 
+
+config V3_DECODER
+       bool "Internal Palacios decoder"
+       help
+           This selects the internal V3Vee x86 decoder
+
+
+endchoice
 
 menu "Supported host OS features"
       
index 3f71036..81cf0b0 100644 (file)
@@ -79,15 +79,6 @@ struct x86_instr {
 };
 
 
-struct basic_instr_info {
-    uint_t instr_length;
-    uint_t op_size;
-    uint_t str_op    : 1;
-    uint_t has_rep : 1;
-};
-
-
-
 /************************/
 /* EXTERNAL DECODER API */
 /************************/
@@ -122,86 +113,12 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins
 int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf);
 
 
-/*
- * Gets the operand size for a memory operation
- *
- */
-int v3_basic_mem_decode(struct guest_info * info, addr_t instr_ptr, struct basic_instr_info * instr_info);
-
-
 
 /* Removes a rep prefix in place */
 void v3_strip_rep_prefix(uchar_t * instr, int length);
 void v3_get_prefixes(uchar_t * instr, struct x86_prefixes * prefixes);
 
 
-/* 
- * JRL: Some of this was taken from the Xen sources... 
- */
-
-#define PACKED __attribute__((packed))
-
-#define MODRM_MOD(x) ((x >> 6) & 0x3)
-#define MODRM_REG(x) ((x >> 3) & 0x7)
-#define MODRM_RM(x)  (x & 0x7)
-
-struct modrm_byte {
-    uint_t rm   :   3 PACKED;
-    uint_t reg  :   3 PACKED;
-    uint_t mod  :   2 PACKED;
-};
-
-
-#define SIB_BASE(x) ((x >> 6) & 0x3)
-#define SIB_INDEX(x) ((x >> 3) & 0x7)
-#define SIB_SCALE(x) (x & 0x7)
-
-struct sib_byte {
-    uint_t base     :   3 PACKED;
-    uint_t index    :   3 PACKED;
-    uint_t scale    :   2 PACKED;
-};
-
-
-
-#define MAKE_INSTR(nm, ...) static  const uchar_t V3_OPCODE_##nm[] = { __VA_ARGS__ }
-
-/* 
- * Here's how it works:
- * First byte: Length. 
- * Following bytes: Opcode bytes. 
- * Special case: Last byte, if zero, doesn't need to match. 
- */
-MAKE_INSTR(INVD,   2, 0x0f, 0x08);
-MAKE_INSTR(CPUID,  2, 0x0f, 0xa2);
-MAKE_INSTR(RDMSR,  2, 0x0f, 0x32);
-MAKE_INSTR(WRMSR,  2, 0x0f, 0x30);
-MAKE_INSTR(RDTSC,  2, 0x0f, 0x31);
-MAKE_INSTR(RDTSCP, 3, 0x0f, 0x01, 0xf9);
-MAKE_INSTR(CLI,    1, 0xfa);
-MAKE_INSTR(STI,    1, 0xfb);
-MAKE_INSTR(RDPMC,  2, 0x0f, 0x33);
-MAKE_INSTR(CLGI,   3, 0x0f, 0x01, 0xdd);
-MAKE_INSTR(STGI,   3, 0x0f, 0x01, 0xdc);
-MAKE_INSTR(VMRUN,  3, 0x0f, 0x01, 0xd8);
-MAKE_INSTR(VMLOAD, 3, 0x0f, 0x01, 0xda);
-MAKE_INSTR(VMSAVE, 3, 0x0f, 0x01, 0xdb);
-MAKE_INSTR(VMCALL, 3, 0x0f, 0x01, 0xd9);
-MAKE_INSTR(PAUSE,  2, 0xf3, 0x90);
-MAKE_INSTR(SKINIT, 3, 0x0f, 0x01, 0xde);
-MAKE_INSTR(MOV2CR, 3, 0x0f, 0x22, 0x00);
-MAKE_INSTR(MOVCR2, 3, 0x0f, 0x20, 0x00);
-MAKE_INSTR(MOV2DR, 3, 0x0f, 0x23, 0x00);
-MAKE_INSTR(MOVDR2, 3, 0x0f, 0x21, 0x00);
-MAKE_INSTR(PUSHF,  1, 0x9c);
-MAKE_INSTR(POPF,   1, 0x9d);
-MAKE_INSTR(RSM,    2, 0x0f, 0xaa);
-MAKE_INSTR(INVLPG, 3, 0x0f, 0x01, 0x00);
-MAKE_INSTR(INVLPGA,3, 0x0f, 0x01, 0xdf);
-MAKE_INSTR(HLT,    1, 0xf4);
-MAKE_INSTR(CLTS,   2, 0x0f, 0x06);
-MAKE_INSTR(LMSW,   3, 0x0f, 0x01, 0x00);
-MAKE_INSTR(SMSW,   3, 0x0f, 0x01, 0x00);
 
 
 #define PREFIX_LOCK         0xF0
@@ -221,7 +138,7 @@ MAKE_INSTR(SMSW,   3, 0x0f, 0x01, 0x00);
 #define PREFIX_OP_SIZE      0x66
 #define PREFIX_ADDR_SIZE    0x67
 
-int v3_opcode_cmp(const uchar_t * op1, const uchar_t * op2);
+
 
 
 static inline int is_prefix_byte(uchar_t byte) {
@@ -267,6 +184,7 @@ static inline v3_reg_t get_gpr_mask(struct guest_info * info) {
 }
 
 
+
 static inline addr_t get_addr_linear(struct guest_info * info, addr_t addr, struct v3_segment * seg) {
     switch (info->cpu_mode) {
        case REAL:
@@ -294,328 +212,6 @@ static inline addr_t get_addr_linear(struct guest_info * info, addr_t addr, stru
 }
 
 
-typedef enum {INVALID_ADDR_TYPE, REG, DISP0, DISP8, DISP16, DISP32} modrm_mode_t;
-typedef enum {INVALID_REG_SIZE, REG64, REG32, REG16, REG8} reg_size_t;
-
-
-
-
-
-
-struct v3_gprs;
-
-static inline addr_t decode_register(struct v3_gprs * gprs, char reg_code, reg_size_t reg_size) {
-    addr_t reg_addr;
-
-    switch (reg_code) {
-       case 0:
-           reg_addr = (addr_t)&(gprs->rax);
-           break;
-       case 1:
-           reg_addr = (addr_t)&(gprs->rcx);
-           break;
-       case 2:
-           reg_addr = (addr_t)&(gprs->rdx);
-           break;
-       case 3:
-           reg_addr = (addr_t)&(gprs->rbx);
-           break;
-       case 4:
-           if (reg_size == REG8) {
-               reg_addr = (addr_t)&(gprs->rax) + 1;
-           } else {
-               reg_addr = (addr_t)&(gprs->rsp);
-           }
-           break;
-       case 5:
-           if (reg_size == REG8) {
-               reg_addr = (addr_t)&(gprs->rcx) + 1;
-           } else {
-               reg_addr = (addr_t)&(gprs->rbp);
-           }
-           break;
-       case 6:
-           if (reg_size == REG8) {
-               reg_addr = (addr_t)&(gprs->rdx) + 1;
-           } else {
-               reg_addr = (addr_t)&(gprs->rsi);
-           }
-           break;
-       case 7:
-           if (reg_size == REG8) {
-               reg_addr = (addr_t)&(gprs->rbx) + 1;
-           } else {
-               reg_addr = (addr_t)&(gprs->rdi);
-           }
-           break;
-       default:
-           reg_addr = 0;
-           break;
-    }
-
-    return reg_addr;
-}
-
-
-
-static inline v3_operand_type_t decode_operands16(struct v3_gprs * gprs, // input/output
-                                                 char * modrm_instr,       // input
-                                                 int * offset,             // output
-                                                 addr_t * first_operand,   // output
-                                                 addr_t * second_operand,  // output
-                                                 reg_size_t reg_size) {    // input
-  
-    struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
-    addr_t base_addr = 0;
-    modrm_mode_t mod_mode = 0;
-    v3_operand_type_t addr_type = INVALID_OPERAND;
-    char * instr_cursor = modrm_instr;
-
-    //  PrintDebug("ModRM mod=%d\n", modrm->mod);
-
-    instr_cursor += 1;
-
-    if (modrm->mod == 3) {
-       mod_mode = REG;
-       addr_type = REG_OPERAND;
-       //PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
-
-       *first_operand = decode_register(gprs, modrm->rm, reg_size);
-
-    } else {
-
-       addr_type = MEM_OPERAND;
-
-       if (modrm->mod == 0) {
-           mod_mode = DISP0;
-       } else if (modrm->mod == 1) {
-           mod_mode = DISP8;
-       } else if (modrm->mod == 2) {
-           mod_mode = DISP16;
-       }
-
-       switch (modrm->rm) {
-           case 0:
-               base_addr = gprs->rbx + gprs->rsi;
-               break;
-           case 1:
-               base_addr = gprs->rbx + gprs->rdi;
-               break;
-           case 2:
-               base_addr = gprs->rbp + gprs->rsi;
-               break;
-           case 3:
-               base_addr = gprs->rbp + gprs->rdi;
-               break;
-           case 4:
-               base_addr = gprs->rsi;
-               break;
-           case 5:
-               base_addr = gprs->rdi;
-               break;
-           case 6:
-               if (modrm->mod == 0) {
-                   base_addr = 0;
-                   mod_mode = DISP16;
-               } else {
-                   base_addr = gprs->rbp;
-               }
-               break;
-           case 7:
-               base_addr = gprs->rbx;
-               break;
-       }
-
-
-
-       if (mod_mode == DISP8) {
-           base_addr += (uchar_t)*(instr_cursor);
-           instr_cursor += 1;
-       } else if (mod_mode == DISP16) {
-           base_addr += (ushort_t)*(instr_cursor);
-           instr_cursor += 2;
-       }
-    
-       *first_operand = base_addr;
-    }
-
-    *offset +=  (instr_cursor - modrm_instr);
-    *second_operand = decode_register(gprs, modrm->reg, reg_size);
-
-    return addr_type;
-}
-
-
-
-static inline v3_operand_type_t decode_operands32(struct v3_gprs * gprs, // input/output
-                                                 uchar_t * modrm_instr,       // input
-                                                 int * offset,             // output
-                                                 addr_t * first_operand,   // output
-                                                 addr_t * second_operand,  // output
-                                                 reg_size_t reg_size) {    // input
-  
-    uchar_t * instr_cursor = modrm_instr;
-    struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
-    addr_t base_addr = 0;
-    modrm_mode_t mod_mode = 0;
-    uint_t has_sib_byte = 0;
-    v3_operand_type_t addr_type = INVALID_OPERAND;
-
-
-
-    instr_cursor += 1;
-
-    if (modrm->mod == 3) {
-       mod_mode = REG;
-       addr_type = REG_OPERAND;
-    
-       //    PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
-
-       *first_operand = decode_register(gprs, modrm->rm, reg_size);
-
-    } else {
-
-       addr_type = MEM_OPERAND;
-
-       if (modrm->mod == 0) {
-           mod_mode = DISP0;
-       } else if (modrm->mod == 1) {
-           mod_mode = DISP8;
-       } else if (modrm->mod == 2) {
-           mod_mode = DISP32;
-       }
-    
-       switch (modrm->rm) {
-           case 0:
-               base_addr = gprs->rax;
-               break;
-           case 1:
-               base_addr = gprs->rcx;
-               break;
-           case 2:
-               base_addr = gprs->rdx;
-               break;
-           case 3:
-               base_addr = gprs->rbx;
-               break;
-           case 4:
-               has_sib_byte = 1;
-               break;
-           case 5:
-               if (modrm->mod == 0) {
-                   base_addr = 0;
-                   mod_mode = DISP32;
-               } else {
-                   base_addr = gprs->rbp;
-               }
-               break;
-           case 6:
-               base_addr = gprs->rsi;
-               break;
-           case 7:
-               base_addr = gprs->rdi;
-               break;
-       }
-
-       if (has_sib_byte) {
-           instr_cursor += 1;
-           struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
-           int scale = 1;
-
-           instr_cursor += 1;
-
-
-           if (sib->scale == 1) {
-               scale = 2;
-           } else if (sib->scale == 2) {
-               scale = 4;
-           } else if (sib->scale == 3) {
-               scale = 8;
-           }
-
-
-           switch (sib->index) {
-               case 0:
-                   base_addr = gprs->rax;
-                   break;
-               case 1:
-                   base_addr = gprs->rcx;
-                   break;
-               case 2:
-                   base_addr = gprs->rdx;
-                   break;
-               case 3:
-                   base_addr = gprs->rbx;
-                   break;
-               case 4:
-                   base_addr = 0;
-                   break;
-               case 5:
-                   base_addr = gprs->rbp;
-                   break;
-               case 6:
-                   base_addr = gprs->rsi;
-                   break;
-               case 7:
-                   base_addr = gprs->rdi;
-                   break;
-           }
-
-           base_addr *= scale;
-
-
-           switch (sib->base) {
-               case 0:
-                   base_addr += gprs->rax;
-                   break;
-               case 1:
-                   base_addr += gprs->rcx;
-                   break;
-               case 2:
-                   base_addr += gprs->rdx;
-                   break;
-               case 3:
-                   base_addr += gprs->rbx;
-                   break;
-               case 4:
-                   base_addr += gprs->rsp;
-                   break;
-               case 5:
-                   if (modrm->mod != 0) {
-                       base_addr += gprs->rbp;
-                   }
-                   break;
-               case 6:
-                   base_addr += gprs->rsi;
-                   break;
-               case 7:
-                   base_addr += gprs->rdi;
-                   break;
-           }
-
-       } 
-
-
-       if (mod_mode == DISP8) {
-           base_addr += (uchar_t)*(instr_cursor);
-           instr_cursor += 1;
-       } else if (mod_mode == DISP32) {
-           base_addr += (uint_t)*(instr_cursor);
-           instr_cursor += 4;
-       }
-    
-
-       *first_operand = base_addr;
-    }
-
-    *offset += (instr_cursor - modrm_instr);
-
-    *second_operand = decode_register(gprs, modrm->reg, reg_size);
-
-    return addr_type;
-}
-
-
 
 #endif // !__V3VEE__
 
diff --git a/palacios/include/palacios/vmm_ss_emulator.h b/palacios/include/palacios/vmm_ss_emulator.h
deleted file mode 100644 (file)
index 173cddd..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National 
- * Science Foundation and the Department of Energy.  
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico.  You can find out more at 
- * http://www.v3vee.org
- *
- * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software.  You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#ifndef __VMM_EMULATOR_H__
-#define __VMM_EMULATOR_H__
-
-#ifdef __V3VEE__
-
-#include <palacios/vmm_list.h>
-#include <palacios/vmm_shadow_paging.h>
-#include <palacios/vmm_paging.h>
-
-
-
-
-
-
-
-
-struct emulation_state {
-
-    uint_t running : 1;
-    uint_t instr_length;
-
-    uint_t tf_enabled : 1;
-};
-
-
-int v3_init_emulator(struct guest_info * info);
-
-
-int v3_emulation_exit_handler(struct guest_info * info);
-
-int v3_emulate_memory_write(struct guest_info * info, addr_t fault_gva,
-                           int (*write)(addr_t write_addr, void * src, uint_t length, void * priv_data), 
-                           addr_t write_addr, void * private_data);
-int v3_emulate_memory_read(struct guest_info * info, addr_t fault_gva, 
-                          int (*read)(addr_t read_addr, void * dst, uint_t length, void * priv_data), 
-                          addr_t read_addr, void * private_data);
-
-
-#endif // !__V3VEE__
-
-#endif
index 788a68c..439cd66 100644 (file)
@@ -1,2 +1,2 @@
-obj-y := libxed.a \
-        v3-xed-compat.o 
+obj-$(CONFIG_XED) :=   libxed.a \
+                       v3-xed-compat.o 
index 1ece18e..c77a270 100644 (file)
@@ -1,2 +1,2 @@
-obj-y := libxed32e.a \
-        v3-xed-compat.o
+obj-$(CONFIG_XED) :=   libxed32e.a \
+                       v3-xed-compat.o
index 8e44ae5..756b020 100644 (file)
@@ -28,7 +28,6 @@ obj-y := \
        vmm_string.o \
        vmm_time.o \
        vmm_util.o \
-       vmm_xed.o \
        vmm_binaries.o \
        vmm_cpuid.o \
        vmm_xml.o \
@@ -39,6 +38,10 @@ obj-y := \
        vmm_mtrr.o \
 
 
+
+obj-$(CONFIG_XED) +=   vmm_xed.o
+obj-$(CONFIG_V3_DECODER) += vmm_v3dec.o
+
 obj-$(CONFIG_SVM) +=    svm.o \
                        svm_io.o \
                        svm_lowlevel.o \
index c890fda..7b38e2d 100644 (file)
@@ -266,7 +266,8 @@ int v3_start_vm(struct v3_vm_info * vm, unsigned int cpu_mask) {
 
 
     if (vm->num_cores > avail_cores) {
-       PrintError("Attempted to start a VM with too many cores (vm->num_cores = %d, avail_cores = %d, MAX=%d)\n", vm->num_cores, avail_cores, MAX_CORES);
+       PrintError("Attempted to start a VM with too many cores (vm->num_cores = %d, avail_cores = %d, MAX=%d)\n", 
+                  vm->num_cores, avail_cores, MAX_CORES);
        return -1;
     }
 
index 4b88e67..1d9e178 100644 (file)
 #include <palacios/vmm_decoder.h>
 
 
-int v3_opcode_cmp(const uchar_t * op1, const uchar_t * op2) {
-    if (op1[0] != op2[0]) {
-       return op1[0] - op2[0];;
-    } else {
-       return memcmp(op1 + 1, op2 + 1, op1[0]);
-    }
-}
+
 
 
 void v3_get_prefixes(uchar_t * instr, struct x86_prefixes * prefixes) {
diff --git a/palacios/src/palacios/vmm_ss_emulator.c b/palacios/src/palacios/vmm_ss_emulator.c
deleted file mode 100644 (file)
index de50876..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/* 
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National 
- * Science Foundation and the Department of Energy.  
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico.  You can find out more at 
- * http://www.v3vee.org
- *
- * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software.  You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#include <palacios/vmm.h>
-#include <palacios/vmm_emulator.h>
-#include <palacios/vm_guest_mem.h>
-#include <palacios/vmm_decoder.h>
-#include <palacios/vmm_debug.h>
-#include <palacios/vmcb.h>
-#include <palacios/vmm_ctrl_regs.h>
-
-
-#ifndef CONFIG_DEBUG_EMULATOR
-#undef PrintDebug
-#define PrintDebug(fmt, args...)
-#endif
-
-
-int v3_init_emulator(struct guest_info * info) {
-
-
-    emulator->tf_enabled = 0;
-
-    return 0;
-}
-
-
-
-
-
-
-
-
-
-
-static int set_stepping(struct guest_info * info) {
-    vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
-    ctrl_area->exceptions.db = 1;
-
-    info->emulator.tf_enabled = ((struct rflags *)&(info->ctrl_regs.rflags))->tf;
-
-    ((struct rflags *)&(info->ctrl_regs.rflags))->tf = 1;
-
-    return 0;
-}
-
-
-static int unset_stepping(struct guest_info * info) {
-    vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
-    ctrl_area->exceptions.db = 0;
-
-    ((struct rflags *)&(info->ctrl_regs.rflags))->tf = info->emulator.tf_enabled;
-
-    if (info->emulator.tf_enabled) {
-       // Inject breakpoint exception into guest
-    }
-
-    return 0;
-
-}
-
-
-int v3_emulate_memory_read(struct guest_info * info, addr_t read_gva, 
-                          int (*read)(addr_t read_addr, void * dst, uint_t length, void * priv_data), 
-                          addr_t read_gpa, void * private_data) {
-    struct basic_instr_info instr_info;
-    uchar_t instr[15];
-    int ret;
-    addr_t data_addr_offset = PAGE_OFFSET(read_gva);
-    PrintDebug("Emulating Read\n");
-
-    if (info->mem_mode == PHYSICAL_MEM) { 
-       ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
-    } else { 
-       ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
-    }
-
-    if (ret == -1) {
-       PrintError("Could not read guest memory\n");
-       return -1;
-    }
-
-#ifdef CONFIG_DEBUG_EMULATOR
-    PrintDebug("Instr (15 bytes) at %p:\n", (void *)(addr_t)instr);
-    PrintTraceMemDump(instr, 15);
-#endif  
-
-
-    if (v3_basic_mem_decode(info, (addr_t)instr, &instr_info) == -1) {
-       PrintError("Could not do a basic memory instruction decode\n");
-       V3_Free(data_page);
-       return -1;
-    }
-
-    // Read the data directly onto the emulated page
-    ret = read(read_gpa, (void *)(data_page->page_addr + data_addr_offset), instr_info.op_size, private_data);
-    if ((ret == -1) || ((uint_t)ret != instr_info.op_size)) {
-       PrintError("Read error in emulator\n");
-       return -1;
-    }
-
-
-    // setup_code_page(info, instr, &instr_info);
-    set_stepping(info);
-
-    info->emulator.running = 1;
-    info->run_state = VM_EMULATING;
-    info->emulator.instr_length = instr_info.instr_length;
-
-    return 0;
-}
-
-
-
-int v3_emulate_memory_write(struct guest_info * info, addr_t write_gva,
-                           int (*write)(addr_t write_addr, void * src, uint_t length, void * priv_data), 
-                           addr_t write_gpa, void * private_data) {
-
-    struct basic_instr_info instr_info;
-    uchar_t instr[15];
-    int ret;
-    addr_t data_addr_offset = PAGE_OFFSET(write_gva);
-    int i;
-
-    PrintDebug("Emulating Write for instruction at 0x%p\n", (void *)(addr_t)(info->rip));
-
-    if (info->mem_mode == PHYSICAL_MEM) { 
-       ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
-    } else { 
-       ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
-    }
-
-
-  
-    if (v3_basic_mem_decode(info, (addr_t)instr, &instr_info) == -1) {
-       PrintError("Could not do a basic memory instruction decode\n");
-       V3_Free(write_op);
-       V3_Free(data_page);
-       return -1;
-    }
-
-    if (instr_info.has_rep==1) { 
-       PrintDebug("Emulated instruction has rep\n");
-    }
-
-
-    if (info->emulator.running == 0) {
-       //    setup_code_page(info, instr, &instr_info);
-       set_stepping(info);
-       info->emulator.running = 1;
-       info->run_state = VM_EMULATING;
-       info->emulator.instr_length = instr_info.instr_length;
-    }
-
-    return 0;
-}
-
-
-// end emulation
-int v3_emulation_exit_handler(struct guest_info * info) {
-  
-    unset_stepping(info);
-
-
-    PrintDebug("returning from emulation\n");
-
-    return 0;
-}
diff --git a/palacios/src/palacios/vmm_v3dec.c b/palacios/src/palacios/vmm_v3dec.c
new file mode 100644 (file)
index 0000000..78cb8b6
--- /dev/null
@@ -0,0 +1,819 @@
+/* 
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National 
+ * Science Foundation and the Department of Energy.  
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico.  You can find out more at 
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#include <palacios/vmm_decoder.h>
+
+
+/* .... Giant fucking switch tables */
+
+
+
+#define MODRM_MOD(x) (((x) >> 6) & 0x3)
+#define MODRM_REG(x) (((x) >> 3) & 0x7)
+#define MODRM_RM(x)  ((x) & 0x7)
+
+struct modrm_byte {
+    uint_t rm   :   3;
+    uint_t reg  :   3;
+    uint_t mod  :   2;
+} __attribute__((packed));
+
+
+#define SIB_BASE(x) (((x) >> 6) & 0x3)
+#define SIB_INDEX(x) (((x) >> 3) & 0x7)
+#define SIB_SCALE(x) ((x) & 0x7)
+
+struct sib_byte {
+    uint_t base     :   3;
+    uint_t index    :   3;
+    uint_t scale    :   2;
+} __attribute__((packed));
+
+
+
+
+typedef enum {
+    INVALID_INSTR,
+    LMSW,
+    SMSW,
+    CLTS,
+    INVLPG,
+
+    MOV_CR2,
+    MOV_2CR,
+    MOV_DR2,
+    MOV_2DR,
+    MOV_SR2,
+    MOV_2SR,
+
+    MOV_2GPR_8,
+    MOV_2GPR,
+    MOV_GPR2_8,
+    MOV_GPR2,
+    MOV_MEM2AL_8,
+    MOV_MEM2AX,
+    MOV_AL2MEM_8,
+    MOV_AX2MEM,
+    MOV_IMM2_8,
+    MOV_IMM2,
+
+    MOVS_8,
+    MOVS,
+    MOVSX_8,
+    MOVSX,
+    MOVZX_8,
+    MOVZX,
+
+    HLT,
+    PUSHF,
+    POPF,
+
+    ADC_2MEM_8,
+    ADC_2MEM,
+    ADC_MEM2_8,
+    ADC_MEM2,
+    ADC_IMM2_8,
+    ADC_IMM2,
+    ADC_IMM2SX_8,
+    ADD_IMM2_8,
+    ADD_IMM2,
+    ADD_IMM2SX_8,
+    ADD_2MEM_8,
+    ADD_2MEM,
+    ADD_MEM2_8,
+    ADD_MEM2,
+    AND_MEM2_8,
+    AND_MEM2,
+    AND_2MEM_8,
+    AND_2MEM,
+    AND_IMM2_8,
+    AND_IMM2,
+    AND_IMM2SX_8,
+    OR_2MEM_8,
+    OR_2MEM,
+    OR_MEM2_8,
+    OR_MEM2,
+    OR_IMM2_8,
+    OR_IMM2,
+    OR_IMM2SX_8,
+    SUB_2MEM_8,
+    SUB_2MEM,
+    SUB_MEM2_8,
+    SUB_MEM2,
+    SUB_IMM2_8,
+    SUB_IMM2,
+    SUB_IMM2SX_8,
+    XOR_2MEM_8,
+    XOR_2MEM,
+    XOR_MEM2_8,
+    XOR_MEM2,
+    XOR_IMM2_8,
+    XOR_IMM2,
+    XOR_IMM2SX_8,
+
+    INC_8,
+    INC,
+    DEC_8,
+    DEC,
+    NEG_8,
+    NEG, 
+    NOT_8,
+    NOT,
+    XCHG_8,
+    XCHG,
+
+    SETB,
+    SETBE,
+    SETL,
+    SETLE,
+    SETNB,
+    SETNBE,
+    SETNL,
+    SETNLE,
+    SETNO,
+    SETNP,
+    SETNS,
+    SETNZ,
+    SETP,
+    SETS,
+    SETZ,
+    SETO,
+
+    STOS_8,
+    STOS
+} op_form_t;
+
+static op_form_t op_code_to_form(uint8_t * instr);
+
+
+
+typedef enum {INVALID_ADDR_TYPE, REG, DISP0, DISP8, DISP16, DISP32} modrm_mode_t;
+typedef enum {INVALID_REG_SIZE, REG64, REG32, REG16, REG8} reg_size_t;
+
+
+struct v3_gprs;
+
+static inline addr_t decode_register(struct v3_gprs * gprs, char reg_code, reg_size_t reg_size) {
+    addr_t reg_addr;
+
+    switch (reg_code) {
+       case 0:
+           reg_addr = (addr_t)&(gprs->rax);
+           break;
+       case 1:
+           reg_addr = (addr_t)&(gprs->rcx);
+           break;
+       case 2:
+           reg_addr = (addr_t)&(gprs->rdx);
+           break;
+       case 3:
+           reg_addr = (addr_t)&(gprs->rbx);
+           break;
+       case 4:
+           if (reg_size == REG8) {
+               reg_addr = (addr_t)&(gprs->rax) + 1;
+           } else {
+               reg_addr = (addr_t)&(gprs->rsp);
+           }
+           break;
+       case 5:
+           if (reg_size == REG8) {
+               reg_addr = (addr_t)&(gprs->rcx) + 1;
+           } else {
+               reg_addr = (addr_t)&(gprs->rbp);
+           }
+           break;
+       case 6:
+           if (reg_size == REG8) {
+               reg_addr = (addr_t)&(gprs->rdx) + 1;
+           } else {
+               reg_addr = (addr_t)&(gprs->rsi);
+           }
+           break;
+       case 7:
+           if (reg_size == REG8) {
+               reg_addr = (addr_t)&(gprs->rbx) + 1;
+           } else {
+               reg_addr = (addr_t)&(gprs->rdi);
+           }
+           break;
+       default:
+           reg_addr = 0;
+           break;
+    }
+
+    return reg_addr;
+}
+
+
+
+static inline v3_operand_type_t decode_operands16(struct v3_gprs * gprs, // input/output
+                                                 char * modrm_instr,       // input
+                                                 int * offset,             // output
+                                                 addr_t * first_operand,   // output
+                                                 addr_t * second_operand,  // output
+                                                 reg_size_t reg_size) {    // input
+  
+    struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
+    addr_t base_addr = 0;
+    modrm_mode_t mod_mode = 0;
+    v3_operand_type_t addr_type = INVALID_OPERAND;
+    char * instr_cursor = modrm_instr;
+
+    //  PrintDebug("ModRM mod=%d\n", modrm->mod);
+
+    instr_cursor += 1;
+
+    if (modrm->mod == 3) {
+       mod_mode = REG;
+       addr_type = REG_OPERAND;
+       //PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
+
+       *first_operand = decode_register(gprs, modrm->rm, reg_size);
+
+    } else {
+
+       addr_type = MEM_OPERAND;
+
+       if (modrm->mod == 0) {
+           mod_mode = DISP0;
+       } else if (modrm->mod == 1) {
+           mod_mode = DISP8;
+       } else if (modrm->mod == 2) {
+           mod_mode = DISP16;
+       }
+
+       switch (modrm->rm) {
+           case 0:
+               base_addr = gprs->rbx + gprs->rsi;
+               break;
+           case 1:
+               base_addr = gprs->rbx + gprs->rdi;
+               break;
+           case 2:
+               base_addr = gprs->rbp + gprs->rsi;
+               break;
+           case 3:
+               base_addr = gprs->rbp + gprs->rdi;
+               break;
+           case 4:
+               base_addr = gprs->rsi;
+               break;
+           case 5:
+               base_addr = gprs->rdi;
+               break;
+           case 6:
+               if (modrm->mod == 0) {
+                   base_addr = 0;
+                   mod_mode = DISP16;
+               } else {
+                   base_addr = gprs->rbp;
+               }
+               break;
+           case 7:
+               base_addr = gprs->rbx;
+               break;
+       }
+
+
+
+       if (mod_mode == DISP8) {
+           base_addr += (uchar_t)*(instr_cursor);
+           instr_cursor += 1;
+       } else if (mod_mode == DISP16) {
+           base_addr += (ushort_t)*(instr_cursor);
+           instr_cursor += 2;
+       }
+    
+       *first_operand = base_addr;
+    }
+
+    *offset +=  (instr_cursor - modrm_instr);
+    *second_operand = decode_register(gprs, modrm->reg, reg_size);
+
+    return addr_type;
+}
+
+
+
+static inline v3_operand_type_t decode_operands32(struct v3_gprs * gprs, // input/output
+                                                 uchar_t * modrm_instr,       // input
+                                                 int * offset,             // output
+                                                 addr_t * first_operand,   // output
+                                                 addr_t * second_operand,  // output
+                                                 reg_size_t reg_size) {    // input
+  
+    uchar_t * instr_cursor = modrm_instr;
+    struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
+    addr_t base_addr = 0;
+    modrm_mode_t mod_mode = 0;
+    uint_t has_sib_byte = 0;
+    v3_operand_type_t addr_type = INVALID_OPERAND;
+
+
+
+    instr_cursor += 1;
+
+    if (modrm->mod == 3) {
+       mod_mode = REG;
+       addr_type = REG_OPERAND;
+    
+       //    PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
+
+       *first_operand = decode_register(gprs, modrm->rm, reg_size);
+
+    } else {
+
+       addr_type = MEM_OPERAND;
+
+       if (modrm->mod == 0) {
+           mod_mode = DISP0;
+       } else if (modrm->mod == 1) {
+           mod_mode = DISP8;
+       } else if (modrm->mod == 2) {
+           mod_mode = DISP32;
+       }
+    
+       switch (modrm->rm) {
+           case 0:
+               base_addr = gprs->rax;
+               break;
+           case 1:
+               base_addr = gprs->rcx;
+               break;
+           case 2:
+               base_addr = gprs->rdx;
+               break;
+           case 3:
+               base_addr = gprs->rbx;
+               break;
+           case 4:
+               has_sib_byte = 1;
+               break;
+           case 5:
+               if (modrm->mod == 0) {
+                   base_addr = 0;
+                   mod_mode = DISP32;
+               } else {
+                   base_addr = gprs->rbp;
+               }
+               break;
+           case 6:
+               base_addr = gprs->rsi;
+               break;
+           case 7:
+               base_addr = gprs->rdi;
+               break;
+       }
+
+       if (has_sib_byte) {
+           instr_cursor += 1;
+           struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
+           int scale = 1;
+
+           instr_cursor += 1;
+
+
+           if (sib->scale == 1) {
+               scale = 2;
+           } else if (sib->scale == 2) {
+               scale = 4;
+           } else if (sib->scale == 3) {
+               scale = 8;
+           }
+
+
+           switch (sib->index) {
+               case 0:
+                   base_addr = gprs->rax;
+                   break;
+               case 1:
+                   base_addr = gprs->rcx;
+                   break;
+               case 2:
+                   base_addr = gprs->rdx;
+                   break;
+               case 3:
+                   base_addr = gprs->rbx;
+                   break;
+               case 4:
+                   base_addr = 0;
+                   break;
+               case 5:
+                   base_addr = gprs->rbp;
+                   break;
+               case 6:
+                   base_addr = gprs->rsi;
+                   break;
+               case 7:
+                   base_addr = gprs->rdi;
+                   break;
+           }
+
+           base_addr *= scale;
+
+
+           switch (sib->base) {
+               case 0:
+                   base_addr += gprs->rax;
+                   break;
+               case 1:
+                   base_addr += gprs->rcx;
+                   break;
+               case 2:
+                   base_addr += gprs->rdx;
+                   break;
+               case 3:
+                   base_addr += gprs->rbx;
+                   break;
+               case 4:
+                   base_addr += gprs->rsp;
+                   break;
+               case 5:
+                   if (modrm->mod != 0) {
+                       base_addr += gprs->rbp;
+                   }
+                   break;
+               case 6:
+                   base_addr += gprs->rsi;
+                   break;
+               case 7:
+                   base_addr += gprs->rdi;
+                   break;
+           }
+
+       } 
+
+
+       if (mod_mode == DISP8) {
+           base_addr += (uchar_t)*(instr_cursor);
+           instr_cursor += 1;
+       } else if (mod_mode == DISP32) {
+           base_addr += (uint_t)*(instr_cursor);
+           instr_cursor += 4;
+       }
+    
+
+       *first_operand = base_addr;
+    }
+
+    *offset += (instr_cursor - modrm_instr);
+
+    *second_operand = decode_register(gprs, modrm->reg, reg_size);
+
+    return addr_type;
+}
+
+
+
+static inline op_form_t op_code_to_form_0f(uint8_t * instr) {
+    switch (instr[1]) {
+       case 0x01: {
+           struct modrm_byte * modrm = (struct modrm_byte *)&(instr[2]);
+
+           switch (modrm->reg) {
+               case 4:
+                   return SMSW;
+               case 6:
+                   return LMSW;
+               case 7:
+                   return INVLPG;
+               default:
+                   return INVALID_INSTR;
+           }
+       }
+
+       case 0x06:
+           return CLTS;
+       case 0x20:
+           return MOV_CR2;
+       case 0x21:
+           return MOV_DR2;
+
+       case 0x22:
+           return MOV_2CR;
+       case 0x23:
+           return MOV_2DR;
+
+       case 0x90:
+           return SETO;
+       case 0x91:
+           return SETNO;
+       case 0x92:
+           return SETB;
+       case 0x93:
+           return SETNB;
+       case 0x94:
+           return SETZ;
+       case 0x95:
+           return SETNZ;
+       case 0x96:
+           return SETBE;
+       case 0x97:
+           return SETNBE;
+       case 0x98:
+           return SETS;
+       case 0x99:
+           return SETNS;
+       case 0x9a:
+           return SETP;
+       case 0x9b:
+           return SETNP;
+       case 0x9c:
+           return SETL;
+       case 0x9d:
+           return SETNL;
+       case 0x9e:
+           return SETLE;
+       case 0x9f:
+           return SETNLE;
+
+       case 0xb6:
+           return MOVZX_8;
+       case 0xb7:
+           return MOVZX;
+
+       case 0xbe:
+           return MOVSX_8;
+       case 0xbf:
+           return MOVSX;
+           
+
+       default:
+           return INVALID_INSTR;
+    }
+}
+
+
+static op_form_t op_code_to_form(uint8_t * instr) {
+    switch (instr[0]) {
+       case 0x00:
+           return ADD_2MEM_8;
+       case 0x01:
+           return ADD_2MEM;
+       case 0x02:
+           return ADD_MEM2_8;
+       case 0x03:
+           return ADD_MEM2;
+
+       case 0x08:
+           return OR_2MEM_8;
+       case 0x09:
+           return OR_2MEM;
+       case 0x0a:
+           return OR_MEM2_8;
+       case 0x0b:
+           return OR_MEM2;
+
+
+       case 0x0f:
+           return op_code_to_form_0f(instr);
+
+       case 0x10:
+           return ADC_2MEM_8;
+       case 0x11:
+           return ADC_2MEM;
+       case 0x12:
+           return ADC_MEM2_8;
+       case 0x13:
+           return ADC_MEM2;
+
+       case 0x20:
+           return AND_2MEM_8; 
+       case 0x21:
+           return AND_2MEM;
+       case 0x22:
+           return AND_MEM2_8;
+       case 0x23:
+           return AND_MEM2;
+
+       case 0x28:
+           return SUB_2MEM_8;
+       case 0x29:
+           return SUB_2MEM;
+       case 0x2a:
+           return SUB_MEM2_8;
+       case 0x2b:
+           return SUB_MEM2;
+
+
+       case 0x30:
+           return XOR_2MEM_8;
+       case 0x31:
+           return XOR_2MEM;
+       case 0x32:
+           return XOR_MEM2_8;
+       case 0x33:
+           return XOR_MEM2;
+
+       case 0x80:{
+           struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
+
+           switch (modrm->reg) {
+               case 0:
+                   return ADD_IMM2_8;
+               case 1:
+                   return OR_IMM2_8;
+               case 2:
+                   return ADC_IMM2_8;
+               case 4:
+                   return AND_IMM2_8;
+               case 5:
+                   return SUB_IMM2_8;
+               case 6:
+                   return XOR_IMM2_8;
+               default:
+                   return INVALID_INSTR;
+           }
+       }
+       case 0x81: {
+           struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
+           
+           switch (modrm->reg) {
+               case 0:
+                   return ADD_IMM2;
+               case 1:
+                   return OR_IMM2;
+               case 2:
+                   return ADC_IMM2;
+               case 4:
+                   return AND_IMM2;
+               case 5:
+                   return SUB_IMM2;
+               case 6:
+                   return XOR_IMM2;
+               default:
+                   return INVALID_INSTR;
+           }
+       }
+       case 0x83: {
+           struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
+
+           switch (modrm->reg) {
+               case 0:
+                   return ADD_IMM2SX_8;
+               case 1:
+                   return OR_IMM2SX_8;
+               case 2:
+                   return ADC_IMM2SX_8;
+               case 4:
+                   return AND_IMM2SX_8;
+               case 5:
+                   return SUB_IMM2SX_8;
+               case 6:
+                   return XOR_IMM2SX_8;
+               default:
+                   return INVALID_INSTR;
+           }
+       }
+
+       case 0x86:
+           return XCHG_8;
+       case 0x87:
+           return XCHG;
+       case 0x88:
+           return MOV_2GPR_8;
+       case 0x89:
+           return MOV_2GPR;
+       case 0x8a:
+           return MOV_GPR2_8;
+       case 0x8b:
+           return MOV_GPR2;
+           
+       case 0x8c:
+           return MOV_SR2;
+       case 0x8e:
+           return MOV_2SR;
+
+
+       case 0x9c:
+           return PUSHF;
+       case 0x9d:
+           return POPF;
+
+       case 0xa0:
+           return MOV_MEM2AL_8;
+       case 0xa1:
+           return MOV_MEM2AX;
+       case 0xa2:
+           return MOV_AL2MEM_8;
+       case 0xa3:
+           return MOV_AX2MEM;
+
+       case 0xa4:
+           return MOVS_8;
+       case 0xa5:
+           return MOVS;
+
+       case 0xaa:
+           return STOS_8;
+       case 0xab:
+           return STOS;
+
+       case 0xc6:
+           return MOV_IMM2_8;
+       case 0xc7:
+           return MOV_IMM2;
+
+       case 0xf4:
+           return HLT;
+
+
+       case 0xf6: {
+           struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
+
+           switch (modrm->reg) {
+               case 2:
+                   return NOT_8;
+               case 3:
+                   return NEG_8;
+               default:
+                   return INVALID_INSTR;
+           }
+       }
+       case 0xf7: {
+           struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
+
+           switch (modrm->reg) {
+               case 2:
+                   return NOT;
+               case 3:
+                   return NEG;
+               default:
+                   return INVALID_INSTR;
+           }
+       }
+           
+
+       case 0xfe: {
+           struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
+
+           switch (modrm->reg) {
+               case 0:
+                   return INC_8;
+               case 1:
+                   return DEC_8;
+               default:
+                   return INVALID_INSTR;
+           }
+       }
+
+       case 0xff: {
+           struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
+
+           switch (modrm->reg) {
+               case 0:
+                   return INC;
+               case 1:
+                   return DEC;
+               default:
+                   return INVALID_INSTR;
+           }
+       }
+
+       default:
+           return INVALID_INSTR;
+    }
+}
+
+int v3_disasm(struct guest_info * info, void *instr_ptr, addr_t * rip, int mark) {
+    return 0;
+}
+
+
+
+int v3_init_decoder(struct guest_info * core) { 
+    return 0;
+}
+
+
+int v3_deinit_decoder(struct guest_info * core) {
+    return 0;
+}
+
+
+int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) {
+    return 0;
+}
+
+int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
+    op_code_to_form((void *)instr_ptr);
+
+    return 0;
+}
index f140d1a..e23ace0 100644 (file)
@@ -187,55 +187,6 @@ int v3_deinit_decoder(struct guest_info * core) {
 }
 
 
-int v3_basic_mem_decode(struct guest_info * info, addr_t instr_ptr, struct basic_instr_info * instr_info) {
-    xed_decoded_inst_t xed_instr;
-    xed_error_enum_t xed_error;
-  
-
-    if (set_decoder_mode(info, info->decoder_state) == -1) {
-       PrintError("Could not set decoder mode\n");
-       return -1;
-    }
-
-
-    xed_decoded_inst_zero_set_mode(&xed_instr, info->decoder_state);
-
-    xed_error = xed_decode(&xed_instr, 
-                          REINTERPRET_CAST(const xed_uint8_t *, instr_ptr), 
-                          XED_MAX_INSTRUCTION_BYTES);
-
-    if (xed_error != XED_ERROR_NONE) {
-       PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
-       return -1;
-    }
-
-    instr_info->instr_length = xed_decoded_inst_get_length(&xed_instr);
-
-
-    if (xed_decoded_inst_number_of_memory_operands(&xed_instr) == 0) {
-       PrintError("Tried to decode memory operation with no memory operands\n");
-       return -1;
-    }
-
-    instr_info->op_size = xed_decoded_inst_get_memory_operand_length(&xed_instr, 0);
-
-
-    xed_category_enum_t cat = xed_decoded_inst_get_category(&xed_instr);
-    if (cat == XED_CATEGORY_STRINGOP) {
-       instr_info->str_op = 1;
-    } else {
-       instr_info->str_op = 0;
-    }
-
-    xed_operand_values_t * operands = xed_decoded_inst_operands(&xed_instr);
-    if (xed_operand_values_has_real_rep(operands)) {
-       instr_info->has_rep = 1;
-    } else {
-       instr_info->has_rep = 0;
-    }
-
-    return 0;
-}
 
 
 static int decode_string_op(struct guest_info * info,