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);
decode_gpr(gprs, modrm->rm, operand);
} else {
+ struct v3_segment * seg = NULL;
operand->type = MEM_OPERAND;
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);
}
// 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;
decode_gpr(gprs, modrm->rm, operand);
} else {
+ struct v3_segment * seg = NULL;
operand->type = MEM_OPERAND;
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);
}
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;
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");
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");
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");
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");