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 segment offsets to memory operand calculations
Jack Lange [Tue, 8 Mar 2011 02:53:50 +0000 (20:53 -0600)]
palacios/include/palacios/vmm_instr_decoder.h
palacios/src/palacios/vmm_v3dec.c

index 2958f4f..207da43 100644 (file)
@@ -418,16 +418,17 @@ static inline int decode_gpr(struct v3_gprs * gprs,
            val;                                                        \
        })
 
-static  int decode_rm_operand16(struct v3_gprs * gprs, 
-                                     char * modrm_instr, 
-                                     struct x86_operand * operand, 
-                                     uint8_t * reg_code) { 
+static  int decode_rm_operand16(struct guest_info * core,
+                               uint8_t * modrm_instr, 
+                               struct x86_instr * instr,
+                               struct x86_operand * operand, 
+                               uint8_t * reg_code) { 
 
-    
+    struct v3_gprs * gprs = &(core->vm_regs);
     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
     addr_t base_addr = 0;
     modrm_mode_t mod_mode = 0;
-    char * instr_cursor = modrm_instr;
+    uint8_t * instr_cursor = modrm_instr;
 
     //  PrintDebug("ModRM mod=%d\n", modrm->mod);
     
@@ -442,6 +443,7 @@ static  int decode_rm_operand16(struct v3_gprs * gprs,
        decode_gpr(gprs, modrm->rm, operand);
 
     } else {
+       struct v3_segment * seg = NULL;
 
        operand->type = MEM_OPERAND;
 
@@ -495,7 +497,23 @@ static  int decode_rm_operand16(struct v3_gprs * gprs,
            instr_cursor += 2;
        }
     
-       operand->operand = base_addr;
+       
+       // get appropriate segment
+       if (instr->prefixes.cs_override) {
+           seg = &(core->segments.cs);
+       } else if (instr->prefixes.es_override) {
+           seg = &(core->segments.es);
+       } else if (instr->prefixes.ss_override) {
+           seg = &(core->segments.ss);
+       } else if (instr->prefixes.fs_override) {
+           seg = &(core->segments.fs);
+       } else if (instr->prefixes.gs_override) {
+           seg = &(core->segments.gs);
+       } else {
+           seg = &(core->segments.ds);
+       }
+       
+       operand->operand = get_addr_linear(core, base_addr, seg);
     }
 
 
@@ -504,12 +522,14 @@ static  int decode_rm_operand16(struct v3_gprs * gprs,
 
 
 // returns num_bytes parsed
-static int decode_rm_operand32(struct v3_gprs * gprs,      // input/output
-                              uint8_t * modrm_instr,        // input
+static int decode_rm_operand32(struct guest_info * core, 
+                              uint8_t * modrm_instr,  
+                              struct x86_instr * instr,
                               struct x86_operand * operand, 
                               uint8_t * reg_code) {
-    
-    uchar_t * instr_cursor = modrm_instr;
+
+    struct v3_gprs * gprs = &(core->vm_regs);
+    uint8_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;
@@ -527,6 +547,7 @@ static int decode_rm_operand32(struct v3_gprs * gprs,      // input/output
        decode_gpr(gprs, modrm->rm, operand);
 
     } else {
+       struct v3_segment * seg = NULL;
 
        operand->type = MEM_OPERAND;
 
@@ -647,8 +668,22 @@ static int decode_rm_operand32(struct v3_gprs * gprs,      // input/output
            instr_cursor += 4;
        }
     
-
-       operand->operand = base_addr;
+       // get appropriate segment
+       if (instr->prefixes.cs_override) {
+           seg = &(core->segments.cs);
+       } else if (instr->prefixes.es_override) {
+           seg = &(core->segments.es);
+       } else if (instr->prefixes.ss_override) {
+           seg = &(core->segments.ss);
+       } else if (instr->prefixes.fs_override) {
+           seg = &(core->segments.fs);
+       } else if (instr->prefixes.gs_override) {
+           seg = &(core->segments.gs);
+       } else {
+           seg = &(core->segments.ds);
+       }
+       
+       operand->operand = get_addr_linear(core, base_addr, seg);
     }
 
 
@@ -661,15 +696,16 @@ static int decode_rm_operand32(struct v3_gprs * gprs,      // input/output
 
 static int decode_rm_operand(struct guest_info * core, 
                             uint8_t * instr_ptr,        // input
+                            struct x86_instr * instr,
                             struct x86_operand * operand, 
                             uint8_t * reg_code) {
     
     v3_cpu_mode_t mode = v3_get_vm_cpu_mode(core);
 
     if (mode == REAL) {
-       return decode_rm_operand16(&(core->vm_regs), instr_ptr, operand, reg_code);
+       return decode_rm_operand16(core, instr_ptr, instr, operand, reg_code);
     } else if ((mode == PROTECTED) || (mode == PROTECTED_PAE)) {
-       return decode_rm_operand32(&(core->vm_regs), instr_ptr, operand, reg_code);
+       return decode_rm_operand32(core, instr_ptr, instr, operand, reg_code);
     } else {
        PrintError("Invalid CPU_MODE (%d)\n", mode);
        return -1;
index 60acddb..47a2487 100644 (file)
@@ -140,7 +140,7 @@ static int parse_operands(struct guest_info * core, uint8_t * instr_ptr,
 
            instr->dst_operand.size = operand_width;
 
-           ret = decode_rm_operand(core, instr_ptr, &(instr->dst_operand), &reg_code);
+           ret = decode_rm_operand(core, instr_ptr, instr, &(instr->dst_operand), &reg_code);
 
            if (ret == -1) {
                PrintError("Error decoding operand\n");
@@ -187,7 +187,7 @@ static int parse_operands(struct guest_info * core, uint8_t * instr_ptr,
 
            instr->dst_operand.size = operand_width;
 
-           ret = decode_rm_operand(core, instr_ptr, &(instr->dst_operand), &reg_code);
+           ret = decode_rm_operand(core, instr_ptr, instr, &(instr->dst_operand), &reg_code);
 
            if (ret == -1) {
                PrintError("Error decoding operand\n");
@@ -221,7 +221,7 @@ static int parse_operands(struct guest_info * core, uint8_t * instr_ptr,
            uint8_t reg_code = 0;
            instr->src_operand.size = operand_width;
 
-           ret = decode_rm_operand(core, instr_ptr, &(instr->src_operand), &reg_code);
+           ret = decode_rm_operand(core, instr_ptr, instr, &(instr->src_operand), &reg_code);
 
            if (ret == -1) {
                PrintError("Error decoding operand\n");
@@ -247,7 +247,7 @@ static int parse_operands(struct guest_info * core, uint8_t * instr_ptr,
            uint8_t reg_code = 0;
            instr->src_operand.size = operand_width;
 
-           ret = decode_rm_operand(core, instr_ptr, &(instr->src_operand), &reg_code);
+           ret = decode_rm_operand(core, instr_ptr, instr, &(instr->src_operand), &reg_code);
 
            if (ret == -1) {
                PrintError("Error decoding operand\n");