X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Finclude%2Fgeekos%2Fvmm_emulate.h;fp=palacios%2Finclude%2Fgeekos%2Fvmm_emulate.h;h=5c0c9c57fe888cf438cecea1968a09db55c6102e;hb=b85f79b8030114370851ed3422c078debe630570;hp=6a6c14428f86136f8edc25e1a31fc6bacc7d86d3;hpb=89d5928385ff776aaaf9c0957734a611c9f9880c;p=palacios.releases.git diff --git a/palacios/include/geekos/vmm_emulate.h b/palacios/include/geekos/vmm_emulate.h index 6a6c144..5c0c9c5 100644 --- a/palacios/include/geekos/vmm_emulate.h +++ b/palacios/include/geekos/vmm_emulate.h @@ -191,19 +191,23 @@ static inline addr_t decode_register(struct guest_gprs * gprs, char reg_code, re -static inline operand_type_t decode_operands16(struct guest_gprs * gprs, - char * modrm_instr, - addr_t * first_operand, - addr_t * second_operand, - reg_size_t reg_size) { +static inline operand_type_t decode_operands16(struct guest_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; 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; @@ -255,15 +259,20 @@ static inline operand_type_t decode_operands16(struct guest_gprs * gprs, break; } + + if (mod_mode == DISP8) { - base_addr += (uchar_t)*(modrm_instr + 1); + base_addr += (uchar_t)*(instr_cursor); + instr_cursor += 1; } else if (mod_mode == DISP16) { - base_addr += (ushort_t)*(modrm_instr + 1); + 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; @@ -271,12 +280,13 @@ static inline operand_type_t decode_operands16(struct guest_gprs * gprs, -static inline operand_type_t decode_operands32(struct guest_gprs * gprs, - char * modrm_instr, - addr_t * first_operand, - addr_t * second_operand, - reg_size_t reg_size) { - +static inline operand_type_t decode_operands32(struct guest_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 + char * instr_cursor = modrm_instr; struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr; addr_t base_addr = 0; @@ -284,6 +294,10 @@ static inline operand_type_t decode_operands32(struct guest_gprs * gprs, uint_t has_sib_byte = 0; operand_type_t addr_type = INVALID_OPERAND; + + + instr_cursor += 1; + if (modrm->mod == 3) { mod_mode = REG; addr_type = REG_OPERAND; @@ -341,6 +355,8 @@ static inline operand_type_t decode_operands32(struct guest_gprs * gprs, struct sib_byte * sib = (struct sib_byte *)(instr_cursor); int scale = 1; + instr_cursor += 1; + if (sib->scale == 1) { scale = 2; @@ -412,18 +428,21 @@ static inline operand_type_t decode_operands32(struct guest_gprs * gprs, } - instr_cursor += 1; 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;