From: Jack Lange Date: Tue, 8 Mar 2011 02:53:50 +0000 (-0600) Subject: added segment offsets to memory operand calculations X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=fe9b69407ae9ac7aeb6a9d1500c89d48953864ac;p=palacios-OLD.git added segment offsets to memory operand calculations --- diff --git a/palacios/include/palacios/vmm_instr_decoder.h b/palacios/include/palacios/vmm_instr_decoder.h index 2958f4f..207da43 100644 --- a/palacios/include/palacios/vmm_instr_decoder.h +++ b/palacios/include/palacios/vmm_instr_decoder.h @@ -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; diff --git a/palacios/src/palacios/vmm_v3dec.c b/palacios/src/palacios/vmm_v3dec.c index 60acddb..47a2487 100644 --- a/palacios/src/palacios/vmm_v3dec.c +++ b/palacios/src/palacios/vmm_v3dec.c @@ -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), ®_code); + ret = decode_rm_operand(core, instr_ptr, instr, &(instr->dst_operand), ®_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), ®_code); + ret = decode_rm_operand(core, instr_ptr, instr, &(instr->dst_operand), ®_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), ®_code); + ret = decode_rm_operand(core, instr_ptr, instr, &(instr->src_operand), ®_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), ®_code); + ret = decode_rm_operand(core, instr_ptr, instr, &(instr->src_operand), ®_code); if (ret == -1) { PrintError("Error decoding operand\n");