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.


Fix xed build error
[palacios.git] / palacios / src / palacios / vmm_xed.c
index 2118a93..1b783f0 100644 (file)
@@ -35,7 +35,7 @@
 
 
 
-#ifndef DEBUG_XED
+#ifndef V3_CONFIG_DEBUG_DECODER
 #undef PrintDebug
 #define PrintDebug(fmt, args...)
 #endif
@@ -102,7 +102,7 @@ static int xed_reg_to_v3_reg(struct guest_info * info, xed_reg_enum_t xed_reg, a
 static int get_memory_operand(struct guest_info * info,  xed_decoded_inst_t * xed_instr, uint_t index, struct x86_operand * operand);
 
 static int set_decoder_mode(struct guest_info * info, xed_state_t * state) {
-    switch (info->cpu_mode) {
+    switch (v3_get_vm_cpu_mode(info)) {
        case REAL:
            if (state->mmode != XED_MACHINE_MODE_LEGACY_16) {
                xed_state_init(state,
@@ -130,7 +130,7 @@ static int set_decoder_mode(struct guest_info * info, xed_state_t * state) {
            break;
        case LONG:
            if (state->mmode != XED_MACHINE_MODE_LONG_64) {
-               PrintDebug("Setting decoder to long mode\n");
+               PrintDebug(info->vm_info, info, "Setting decoder to long mode\n");
                //      state->mmode = XED_MACHINE_MODE_LONG_64;
                //xed_state_set_machine_mode(state, XED_MACHINE_MODE_LONG_64);
                xed_state_init(state,
@@ -140,24 +140,24 @@ static int set_decoder_mode(struct guest_info * info, xed_state_t * state) {
            }
            break;
        default:
-           PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
+           PrintError(info->vm_info, info, "Unsupported CPU mode: %d\n", info->cpu_mode);
            return -1;
     }
     return 0;
 }
 
-static int is_flags_reg(xed_reg_enum_t xed_reg) {
-    switch (xed_reg) {
-       case XED_REG_FLAGS:
-       case XED_REG_EFLAGS:
-       case XED_REG_RFLAGS:
-           return 1;
-       default:
-           return 0;
-    }
-}
-
-
+/*
+  static int is_flags_reg(xed_reg_enum_t xed_reg) {
+  switch (xed_reg) {
+  case XED_REG_FLAGS:
+  case XED_REG_EFLAGS:
+  case XED_REG_RFLAGS:
+  return 1;
+  default:
+  return 0;
+  }
+  }
+*/
 
 int v3_init_decoder(struct guest_info * info) {
     // Global library initialization, only do it once
@@ -167,6 +167,12 @@ int v3_init_decoder(struct guest_info * info) {
     }
 
     xed_state_t * decoder_state = (xed_state_t *)V3_Malloc(sizeof(xed_state_t));
+
+    if (!decoder_state) {
+       PrintError(info->vm_info, info, "Cannot allocate in initializing decoder\n");
+       return -1;
+    }
+
     xed_state_zero(decoder_state);
     xed_state_init(decoder_state,
                   XED_MACHINE_MODE_LEGACY_32, 
@@ -180,76 +186,38 @@ int v3_init_decoder(struct guest_info * info) {
 
 
 
-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;
-    }
+int v3_deinit_decoder(struct guest_info * core) {
+    V3_Free(core->decoder_state);
 
     return 0;
 }
 
 
+
+
 static int decode_string_op(struct guest_info * info, 
                            xed_decoded_inst_t * xed_instr,  const xed_inst_t * xi,
                            struct x86_instr * instr) {
 
-    PrintDebug("String operation\n");
+    PrintDebug(info->vm_info, info, "String operation\n");
 
     if (instr->op_type == V3_OP_MOVS) {
        instr->num_operands = 2;
 
        if (get_memory_operand(info, xed_instr, 0, &(instr->dst_operand)) == -1) {
-           PrintError("Could not get Destination memory operand\n");
+           PrintError(info->vm_info, info, "Could not get Destination memory operand\n");
            return -1;
        }
 
+
        if (get_memory_operand(info, xed_instr, 1, &(instr->src_operand)) == -1) {
-           PrintError("Could not get Source memory operand\n");
+           PrintError(info->vm_info, info, "Could not get Source memory operand\n");
            return -1;
        }
 
+       instr->dst_operand.write = 1;
+       instr->src_operand.read = 1;
+
        if (instr->prefixes.rep == 1) {
            addr_t reg_addr = 0;
            uint_t reg_length = 0;
@@ -264,7 +232,7 @@ static int decode_string_op(struct guest_info * info,
        instr->num_operands = 2;
 
        if (get_memory_operand(info, xed_instr, 0, &(instr->dst_operand)) == -1) {
-           PrintError("Could not get Destination memory operand\n");
+           PrintError(info->vm_info, info, "Could not get Destination memory operand\n");
            return -1;
        }
 
@@ -274,21 +242,74 @@ static int decode_string_op(struct guest_info * info,
                          &(instr->src_operand.size));
        instr->src_operand.type = REG_OPERAND;
     
+       instr->src_operand.read = 1;
+       instr->dst_operand.write = 1;
+
        if (instr->prefixes.rep == 1) {
            addr_t reg_addr = 0;
            uint_t reg_length = 0;
 
-           xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG1), &reg_addr, &reg_length);
+           xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG1), 
+                             &reg_addr, &reg_length);
            instr->str_op_length = MASK(*(addr_t *)reg_addr, reg_length);
        } else {
            instr->str_op_length = 1;
        }
 
     } else {
-       PrintError("Unhandled String OP\n");
+       PrintError(info->vm_info, info, "Unhandled String OP\n");
+       return -1;
+    }
+
+    return 0;
+}
+
+
+
+int v3_disasm(struct guest_info * info, void *instr_ptr, addr_t * rip, int mark) {
+    char buffer[256];
+    int i;
+    unsigned length;
+    xed_decoded_inst_t xed_instr;
+    xed_error_enum_t xed_error;
+
+    /* disassemble the specified instruction */
+    if (set_decoder_mode(info, info->decoder_state) == -1) {
+       PrintError(info->vm_info, info, "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(info->vm_info, info, "Xed error: %s\n", xed_error_enum_t2str(xed_error));
        return -1;
     }
 
+    /* obtain string representation in AT&T syntax */
+    if (!xed_format_att(&xed_instr, buffer, sizeof(buffer), *rip)) {
+       PrintError(info->vm_info, info, "Xed error: cannot disaaemble\n");
+       return -1;
+    }
+
+    /* print address, opcode bytes and the disassembled instruction */
+    length = xed_decoded_inst_get_length(&xed_instr);
+    V3_Print(info->vm_info, info, "0x%p %c ", (void *) *rip, mark ? '*' : ' ');
+    for (i = 0; i < length; i++) {
+       unsigned char b = ((unsigned char *) instr_ptr)[i];
+       V3_Print(info->vm_info, info, "%x%x ", b >> 4, b & 0xf);
+    }
+    while (i++ < 8) {
+       V3_Print(info->vm_info, info, "   ");
+    }
+    V3_Print(info->vm_info, info, "%s\n", buffer);
+
+    /* move on to next instruction */
+    *rip += length;
     return 0;
 }
 
@@ -298,11 +319,13 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins
     xed_decoded_inst_t xed_instr;
     xed_error_enum_t xed_error;
 
+    memset(instr, 0, sizeof(struct x86_instr));
+
 
     v3_get_prefixes((uchar_t *)instr_ptr, &(instr->prefixes));
 
     if (set_decoder_mode(info, info->decoder_state) == -1) {
-       PrintError("Could not set decoder mode\n");
+       PrintError(info->vm_info, info, "Could not set decoder mode\n");
        return -1;
     }
 
@@ -314,7 +337,7 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins
 
 
     if (xed_error != XED_ERROR_NONE) {
-       PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
+       PrintError(info->vm_info, info, "Xed error: %s\n", xed_error_enum_t2str(xed_error));
        return -1;
     }
 
@@ -325,15 +348,15 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins
 
     xed_iform_enum_t iform = xed_decoded_inst_get_iform_enum(&xed_instr);
 
-#ifdef DEBUG_XED
+#ifdef V3_CONFIG_DEBUG_DECODER
     xed_iclass_enum_t iclass = xed_decoded_inst_get_iclass(&xed_instr);
 
-    PrintDebug("iform=%s, iclass=%s\n", xed_iform_enum_t2str(iform), xed_iclass_enum_t2str(iclass));
+    PrintDebug(info->vm_info, info, "iform=%s, iclass=%s\n", xed_iform_enum_t2str(iform), xed_iclass_enum_t2str(iclass));
 #endif
 
 
     if ((instr->op_type = get_opcode(iform)) == V3_INVALID_OP) {
-       PrintError("Could not get opcode. (iform=%s)\n", xed_iform_enum_t2str(iform));
+       PrintError(info->vm_info, info, "Could not get opcode. (iform=%s)\n", xed_iform_enum_t2str(iform));
        return -1;
     }
 
@@ -347,29 +370,28 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins
        instr->str_op_length = 0;
     }
 
-
     instr->num_operands = xed_decoded_inst_noperands(&xed_instr);
 
-    if (instr->num_operands > 3) {
-       PrintDebug("Special Case Not Handled\n");
-       return -1;
-       // special case
-    } else if (instr->num_operands == 3) {
-       const xed_operand_t * op = xed_inst_operand(xi, 2);
-       xed_operand_enum_t op_enum = xed_operand_name(op);
-
-       if ((!xed_operand_is_register(op_enum)) ||
-           (!is_flags_reg(xed_decoded_inst_get_reg(&xed_instr, op_enum)))) {
-           // special case
-           PrintError("Special Case not handled (iform=%s)\n", xed_iform_enum_t2str(iform));
-           return -1;
-       }
-    }
-
-
-
-    //PrintDebug("Number of operands: %d\n", instr->num_operands);
-    //PrintDebug("INSTR length: %d\n", instr->instr_length);
+    /*
+      if (instr->num_operands > 3) {
+      PrintDebug(info->vm_info, info, "Special Case Not Handled (more than 3 operands) (iform=%s)\n", xed_iform_enum_t2str(iform)
+      return -1;
+      // special case
+      } else if (instr->num_operands == 3) {
+      const xed_operand_t * op = xed_inst_operand(xi, 2);
+      xed_operand_enum_t op_enum = xed_operand_name(op);
+      
+      if ((!xed_operand_is_register(op_enum)) ||
+      (!is_flags_reg(xed_decoded_inst_get_reg(&xed_instr, op_enum)))) {
+      // special case
+      PrintError(info->vm_info, info, "Special Case not handled (iform=%s)\n", xed_iform_enum_t2str(iform));
+      return -1;
+      }
+      }
+    */
+
+    //PrintDebug(info->vm_info, info, "Number of operands: %d\n", instr->num_operands);
+    //PrintDebug(info->vm_info, info, "INSTR length: %d\n", instr->instr_length);
 
     // set first operand
     if (instr->num_operands >= 1) {
@@ -396,7 +418,7 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins
                                                &(v3_op->size));
 
            if (v3_reg_type == -1) {
-               PrintError("First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
+               PrintError(info->vm_info, info, "First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
                v3_op->type = INVALID_OPERAND;
                return -1;
            } else if (v3_reg_type == SEGMENT_REGISTER) {
@@ -411,9 +433,9 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins
 
                case XED_OPERAND_MEM0:
                    {
-                       PrintDebug("Memory operand (1)\n");
+                       PrintDebug(info->vm_info, info, "Memory operand (1)\n");
                        if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
-                           PrintError("Could not get first memory operand\n");
+                           PrintError(info->vm_info, info, "Could not get first memory operand\n");
                            return -1;
                        }
                    }
@@ -422,21 +444,44 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins
                case XED_OPERAND_MEM1:
                case XED_OPERAND_IMM1:
                    // illegal
-                   PrintError("Illegal Operand Order\n");
+                   PrintError(info->vm_info, info, "Illegal Operand Order\n");
                    return -1;
 
 
                case XED_OPERAND_IMM0:
+                   {
+                v3_op->size = xed_decoded_inst_get_immediate_width(&xed_instr);
+
+                if (v3_op->size > 4) {
+                    PrintError(info->vm_info, info, "Unhandled 64 bit immediates\n");
+                    return -1;
+                }
+                v3_op->operand = xed_decoded_inst_get_unsigned_immediate(&xed_instr);
+
+                v3_op->type = IMM_OPERAND;
+
+                   }
+                   break;
                case XED_OPERAND_AGEN:
                case XED_OPERAND_PTR:
                case XED_OPERAND_RELBR:
                default:
-                   PrintError("Unhandled Operand Type\n");
+                   PrintError(info->vm_info, info, "Unhandled Operand Type\n");
                    return -1;
+           }
+       }
 
+//     V3_Print(info->vm_info, info, "Operand 0 mode: %s\n", xed_operand_action_enum_t2str(xed_operand_rw(op)));
 
-           }
+
+       if (xed_operand_read(op)) {
+           v3_op->read = 1;
+       }
+
+       if (xed_operand_written(op)) {
+           v3_op->write = 1;
        }
+
     }
 
     // set second operand
@@ -456,6 +501,7 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins
        */
        v3_op = &(instr->src_operand);
 
+
        if (xed_operand_is_register(op_enum)) {
            xed_reg_enum_t xed_reg =  xed_decoded_inst_get_reg(&xed_instr, op_enum);
            int v3_reg_type = xed_reg_to_v3_reg(info, 
@@ -463,7 +509,7 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins
                                                &(v3_op->operand), 
                                                &(v3_op->size));
            if (v3_reg_type == -1) {
-               PrintError("Second operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
+               PrintError(info->vm_info, info, "Second operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
                v3_op->type = INVALID_OPERAND;
                return -1;
            } else if (v3_reg_type == SEGMENT_REGISTER) {
@@ -472,17 +518,14 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins
            }
 
            v3_op->type = REG_OPERAND;
-    
-
        } else {
-
            switch (op_enum) {
 
                case XED_OPERAND_MEM0:
                    {
-                       PrintDebug("Memory operand (2)\n");
+                       PrintDebug(info->vm_info, info, "Memory operand (2)\n");
                        if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
-                           PrintError("Could not get first memory operand\n");
+                           PrintError(info->vm_info, info, "Could not get first memory operand\n");
                            return -1;
                        }
                    }
@@ -493,7 +536,7 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins
                        instr->src_operand.size = xed_decoded_inst_get_immediate_width(&xed_instr);
 
                        if (instr->src_operand.size > 4) {
-                           PrintError("Unhandled 64 bit immediates\n");
+                           PrintError(info->vm_info, info, "Unhandled 64 bit immediates\n");
                            return -1;
                        }
                        instr->src_operand.operand = xed_decoded_inst_get_unsigned_immediate(&xed_instr);
@@ -506,18 +549,28 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins
                case XED_OPERAND_MEM1:
                case XED_OPERAND_IMM1:
                    // illegal
-                   PrintError("Illegal Operand Order\n");
+                   PrintError(info->vm_info, info, "Illegal Operand Order\n");
                    return -1;
        
                case XED_OPERAND_AGEN:
                case XED_OPERAND_PTR:
                case XED_OPERAND_RELBR:
                default:
-                   PrintError("Unhandled Operand Type\n");
+                   PrintError(info->vm_info, info, "Unhandled Operand Type\n");
                    return -1;
            }
        }
 
+//     V3_Print(info->vm_info, info, "Operand 1 mode: %s\n", xed_operand_action_enum_t2str(xed_operand_rw(op)));
+
+       if (xed_operand_read(op)) {
+           v3_op->read = 1;
+       }
+
+       if (xed_operand_written(op)) {
+           v3_op->write = 1;
+       }
+
     }
 
     // set third operand
@@ -526,6 +579,8 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins
        xed_operand_type_enum_t op_type = xed_operand_type(op);
        xed_operand_enum_t op_enum = xed_operand_name(op);
 
+
+
        if (xed_operand_is_register(op_enum)) {
            xed_reg_enum_t xed_reg =  xed_decoded_inst_get_reg(&xed_instr, op_enum);
            int v3_reg_type = xed_reg_to_v3_reg(info, 
@@ -534,7 +589,7 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins
                                                &(instr->third_operand.size));
 
            if (v3_reg_type == -1) {
-               PrintError("Third operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
+               PrintError(info->vm_info, info, "Third operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
                instr->third_operand.type = INVALID_OPERAND;
                return -1;
            } else if (v3_reg_type == SEGMENT_REGISTER) {
@@ -545,22 +600,28 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins
 
            instr->third_operand.type = REG_OPERAND;
 
-
-       } else {
-           PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
-           return -1;
-       }
+           PrintDebug(info->vm_info, info, "Operand 2 mode: %s\n", xed_operand_action_enum_t2str(xed_operand_rw(op)));
 
 
-    }
+           if (xed_operand_read(op)) {
+               instr->third_operand.read = 1;
+           }
 
+           if (xed_operand_written(op)) {
+               instr->third_operand.write = 1;
+           }
 
+       } else {
+           PrintError(info->vm_info, info, "Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
+           instr->num_operands = 2;
+       }
+    }
 
     return 0;
 }
 
 
-int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) {
+int v3_encode(struct guest_info * info, struct x86_instr * instr, uint8_t * instr_buf) {
 
     return -1;
 }
@@ -577,13 +638,14 @@ static int get_memory_operand(struct guest_info * info,  xed_decoded_inst_t * xe
     addr_t scale;
     addr_t index;
     ullong_t displacement;
-    int addr_width = v3_get_addr_width(info);;
+    int addr_width = v3_get_addr_width(info);
+    v3_cpu_mode_t cpu_mode = v3_get_vm_cpu_mode(info);
     // struct v3_segment * seg_reg;
 
-    PrintDebug("Xen mode = %s\n", xed_machine_mode_enum_t2str(xed_state_get_machine_mode(info->decoder_state)));
-    PrintDebug("Address width: %s\n",
+    PrintDebug(info->vm_info, info, "Xed mode = %s\n", xed_machine_mode_enum_t2str(xed_state_get_machine_mode(info->decoder_state)));
+    PrintDebug(info->vm_info, info, "Address width: %s\n",
               xed_address_width_enum_t2str(xed_state_get_address_width(info->decoder_state)));
-    PrintDebug("Stack Address width: %s\n",
+    PrintDebug(info->vm_info, info, "Stack Address width: %s\n",
               xed_address_width_enum_t2str(xed_state_get_stack_address_width(info->decoder_state)));
 
   
@@ -594,7 +656,7 @@ static int get_memory_operand(struct guest_info * info,  xed_decoded_inst_t * xe
     if (xed_seg != XED_REG_INVALID) {
        struct v3_segment *tmp_segment;
        if (xed_reg_to_v3_reg(info, xed_seg, (addr_t *)&tmp_segment, &(mem_op.segment_size)) == -1) {
-           PrintError("Unhandled Segment Register\n");
+           PrintError(info->vm_info, info, "Unhandled Segment Register\n");
            return -1;
        }
        mem_op.segment = tmp_segment->base;
@@ -604,7 +666,7 @@ static int get_memory_operand(struct guest_info * info,  xed_decoded_inst_t * xe
     if (xed_base != XED_REG_INVALID) {
        addr_t base_reg;
        if (xed_reg_to_v3_reg(info, xed_base, &base_reg, &(mem_op.base_size)) == -1) {
-           PrintError("Unhandled Base register\n");
+           PrintError(info->vm_info, info, "Unhandled Base register\n");
            return -1;
        }
        mem_op.base = *(addr_t *)base_reg;
@@ -617,7 +679,7 @@ static int get_memory_operand(struct guest_info * info,  xed_decoded_inst_t * xe
        addr_t index_reg;
     
        if (xed_reg_to_v3_reg(info, xed_idx, &index_reg, &(mem_op.index_size)) == -1) {
-           PrintError("Unhandled Index Register\n");
+           PrintError(info->vm_info, info, "Unhandled Index Register\n");
            return -1;
        }
 
@@ -643,38 +705,45 @@ static int get_memory_operand(struct guest_info * info,  xed_decoded_inst_t * xe
   
   
 
-    PrintDebug("Struct: Seg=%p (size=%d), base=%p, index=%p, scale=%p, displacement=%p (size=%d)\n", 
+    PrintDebug(info->vm_info, info, "Struct: Seg=%p (size=%d), base=%p, index=%p, scale=%p, displacement=%p (size=%d)\n", 
               (void *)mem_op.segment, mem_op.segment_size, (void*)mem_op.base, (void *)mem_op.index, 
               (void *)mem_op.scale, (void *)(addr_t)mem_op.displacement, mem_op.displacement_size);
 
 
-    PrintDebug("operand size: %d\n", operand->size);
+    PrintDebug(info->vm_info, info, "operand size: %d\n", operand->size);
 
     seg = MASK(mem_op.segment, mem_op.segment_size);
     base = MASK(mem_op.base, mem_op.base_size);
     index = MASK(mem_op.index, mem_op.index_size);
     scale = mem_op.scale;
 
-    // This is a horrendous hack...
-    // XED really screwed the pooch in calculating the displacement
-    if (v3_get_cpu_mode(info) == LONG) {
-       displacement = mem_op.displacement;
-    } else {
-       displacement = MASK(mem_op.displacement, mem_op.displacement_size);
-    }
+    // XED returns the displacement as a 2s complement signed number, but it can
+    // have different sizes, depending on the instruction encoding.
+    // we put that into a 64 bit unsigned (the unsigned doesn't matter since
+    // we only ever do 2s complement arithmetic on it.   However, this means we
+    // need to sign-extend what XED provides through 64 bits.
+    displacement = mem_op.displacement;
+    displacement <<= 64 - mem_op.displacement_size * 8;
+    displacement = ((sllong_t)displacement) >> (64 - mem_op.displacement_size * 8);
+    
 
-    PrintDebug("Seg=%p, base=%p, index=%p, scale=%p, displacement=%p\n", 
+    PrintDebug(info->vm_info, info, "Seg=%p, base=%p, index=%p, scale=%p, displacement=%p\n", 
               (void *)seg, (void *)base, (void *)index, (void *)scale, (void *)(addr_t)displacement);
   
-    operand->operand = MASK((seg + base + (scale * index) + displacement), addr_width);
+    if (cpu_mode == REAL) {
+       operand->operand = seg +  MASK((base + (scale * index) + displacement), addr_width);
+    } else {
+       operand->operand = MASK((seg + base + (scale * index) + displacement), addr_width);
+    }
 
     return 0;
 }
 
 
-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) {
+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) {
 
-    PrintDebug("Xed Register: %s\n", xed_reg_enum_t2str(xed_reg));
+    PrintDebug(info->vm_info, info, "Xed Register: %s\n", xed_reg_enum_t2str(xed_reg));
 
     switch (xed_reg) {
        case XED_REG_INVALID:
@@ -1028,7 +1097,7 @@ static int xed_reg_to_v3_reg(struct guest_info * info, xed_reg_enum_t xed_reg, a
            *reg_len = 4;
            return CTRL_REGISTER;
        case XED_REG_CR8:
-           *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
+           *v3_reg = (addr_t)&(info->ctrl_regs.apic_tpr);
            *reg_len = 4;
            return CTRL_REGISTER;
 
@@ -1081,7 +1150,7 @@ static int xed_reg_to_v3_reg(struct guest_info * info, xed_reg_enum_t xed_reg, a
        case XED_REG_LDTR:
        case XED_REG_IDTR:
        case XED_REG_TR:
-           PrintError("Segment selector operand... Don't know how to handle this...\n");
+           PrintError(info->vm_info, info, "Segment selector operand... Don't know how to handle this...\n");
            return -1;
 
            /* 
@@ -1220,6 +1289,9 @@ static v3_op_type_t get_opcode(xed_iform_enum_t iform) {
        case XED_IFORM_INVLPG_MEMb:
            return V3_OP_INVLPG;
 
+    case XED_IFORM_INT_IMM:
+        return V3_OP_INT;
+
 
            /* Data Instructions */