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.


added initial 64 bit decoding support
Jack Lange [Thu, 10 Mar 2011 18:37:32 +0000 (12:37 -0600)]
palacios/include/palacios/vmm_decoder.h
palacios/include/palacios/vmm_instr_decoder.h
palacios/src/palacios/vmm_v3dec.c

index 7f05064..c03de83 100644 (file)
@@ -62,6 +62,13 @@ struct x86_prefixes {
     uint_t br_taken   : 1;  // 0x3E
     uint_t op_size     : 1;  // 0x66
     uint_t addr_size   : 1;  // 0x67
+       struct  {
+               uint_t rm        : 1;  // REX.B
+               uint_t sib_idx   : 1;  // REX.X
+               uint_t reg       : 1;  // REX.R
+               uint_t op_size   : 1;  // REX.W
+               uint8_t rsvd     : 4;
+       } __attribute__((packed)) rex;
 } __attribute__((packed));
 
 
@@ -119,7 +126,6 @@ void v3_strip_rep_prefix(uint8_t * instr, int length);
 uint8_t v3_get_prefixes(uint8_t * instr, struct x86_prefixes * prefixes);
 
 
-
 void v3_print_instr(struct x86_instr * instr);
 
 
index 1c292a3..aa106b6 100644 (file)
@@ -140,11 +140,16 @@ static int get_addr_width(struct guest_info * info, struct x86_instr * instr) {
     switch (v3_get_vm_cpu_mode(info)) {
        case REAL:
            return (instr->prefixes.addr_size) ? 4 : 2;
+       case LONG:
+               return 8;
        case PROTECTED:
        case PROTECTED_PAE:
-           return (instr->prefixes.addr_size) ? 2 : 4;
        case LONG_32_COMPAT:
-       case LONG:
+               if (info->segments.cs.db) {
+                       return (instr->prefixes.addr_size) ? 2 : 4;
+               } else {
+                       return (instr->prefixes.addr_size) ? 4 : 2;
+               }                       
        default:
            PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
            return -1;
@@ -251,14 +256,22 @@ static int get_operand_width(struct guest_info * info, struct x86_instr * instr,
        case OR_IMM2SX_8:
        case SUB_IMM2SX_8:
        case XOR_IMM2SX_8:
-           switch (v3_get_vm_cpu_mode(info)) {
+       switch (v3_get_vm_cpu_mode(info)) {
                case REAL:
                    return (instr->prefixes.op_size) ? 4 : 2;
+               case LONG:
+                       if (instr->prefixes.rex.op_size) {
+                               return 8;
+                       }
                case PROTECTED:
                case PROTECTED_PAE:
-                   return (instr->prefixes.op_size) ? 2 : 4;
                case LONG_32_COMPAT:
-               case LONG:
+                       if (info->segments.cs.db) {
+                               // default is 32
+                               return (instr->prefixes.op_size) ? 2 : 4;
+                       } else {
+                               return (instr->prefixes.op_size) ? 4 : 2;
+                       }
                default:
                    PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
                    return -1;
@@ -271,9 +284,11 @@ static int get_operand_width(struct guest_info * info, struct x86_instr * instr,
                    return 0;
                case PROTECTED:
                case PROTECTED_PAE:
-                   return 4;
                case LONG_32_COMPAT:
+
+                       return 4;
                case LONG:
+                       return 8;
                default:
                    PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
                    return -1;
@@ -286,9 +301,10 @@ static int get_operand_width(struct guest_info * info, struct x86_instr * instr,
                    return 2;
                case PROTECTED:
                case PROTECTED_PAE:
-                   return 4;
                case LONG_32_COMPAT:
+                       return 4;
                case LONG:
+                       return 8;
                default:
                    PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
                    return -1;
@@ -302,9 +318,11 @@ static int get_operand_width(struct guest_info * info, struct x86_instr * instr,
                case REAL:
                case PROTECTED:
                case PROTECTED_PAE:
-                   return 4;
                case LONG_32_COMPAT:
+
+                       return 4;
                case LONG:
+                       return 8;
                default:
                    PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
                    return -1;
@@ -746,7 +764,13 @@ static int decode_rm_operand32(struct guest_info * core,
 }
 
 
-
+int decode_rm_operand64(struct guest_info * core, uint8_t * instr_ptr, 
+                                       struct x86_instr * instr, struct x86_operand * operand, 
+                                       uint8_t * reg_code) {
+                                       
+                                       
+       return 0;
+}
 
 
 static int decode_rm_operand(struct guest_info * core, 
@@ -759,8 +783,10 @@ static int decode_rm_operand(struct guest_info * core,
 
     if (mode == REAL) {
        return decode_rm_operand16(core, instr_ptr, instr, operand, reg_code);
-    } else if ((mode == PROTECTED) || (mode == PROTECTED_PAE)) {
+    } else if ((mode == PROTECTED) || (mode == PROTECTED_PAE) || (mode == LONG_32_COMPAT)) {
        return decode_rm_operand32(core, instr_ptr, instr, operand, reg_code);
+       } else if (mode == LONG) {
+               return decode_rm_operand64(core, instr_ptr, instr, operand, reg_code);
     } else {
        PrintError("Invalid CPU_MODE (%d)\n", mode);
        return -1;
index 7dd716e..0b0d7a4 100644 (file)
@@ -78,7 +78,13 @@ int v3_decode(struct guest_info * core, addr_t instr_ptr, struct x86_instr * ins
     length = v3_get_prefixes((uint8_t *)instr_ptr, &(instr->prefixes));
 
 
-    // check for REX prefix
+       // REX prefix
+       if (v3_get_vm_cpu_mode(core) == LONG) {
+           if ((*(uint8_t *)(instr_ptr + length) & 0xf0) == 0x40) {
+                       *(uint8_t *)&(instr->prefixes.rex) = *(uint8_t *)(instr_ptr + length);
+                       length += 1;
+               }
+       }
 
 
     form = op_code_to_form((uint8_t *)(instr_ptr + length), &length);