X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_xed.c;h=9b16078a06961b48d644ac0726cd3f504cc27d4c;hb=e5d7715c14a23e72d742d402d4e4cdf97ffab697;hp=e48a1b8c941c9f93a3950c2e7f53d84ecd4f9548;hpb=af355c370ac80f8e19d6375cb3070213c29a92eb;p=palacios.git diff --git a/palacios/src/palacios/vmm_xed.c b/palacios/src/palacios/vmm_xed.c index e48a1b8..9b16078 100644 --- a/palacios/src/palacios/vmm_xed.c +++ b/palacios/src/palacios/vmm_xed.c @@ -1,3 +1,22 @@ +/* + * This file is part of the Palacios Virtual Machine Monitor developed + * by the V3VEE Project with funding from the United States National + * Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. You can find out more at + * http://www.v3vee.org + * + * Copyright (c) 2008, Jack Lange + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Jack Lange + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + #ifdef __DECODER_TEST__ #include "vmm_decoder.h" #include "vmm_xed.h" @@ -11,8 +30,18 @@ #include #include + #endif + + +#ifndef DEBUG_XED +#undef PrintDebug +#define PrintDebug(fmt, args...) +#endif + + + static xed_state_t decoder_state; #define GPR_REGISTER 0 @@ -77,6 +106,7 @@ static int set_decoder_mode(struct guest_info * info, xed_state_t * state) { break; case PROTECTED: case PROTECTED_PAE: + case LONG_32_COMPAT: if (state->mmode != XED_MACHINE_MODE_LEGACY_32) { xed_state_init(state, XED_MACHINE_MODE_LEGACY_32, @@ -90,12 +120,13 @@ static int set_decoder_mode(struct guest_info * info, xed_state_t * state) { } break; default: + PrintError("Unsupported CPU mode: %d\n", info->cpu_mode); return -1; } return 0; } -int is_flags_reg(xed_reg_enum_t xed_reg) { +static int is_flags_reg(xed_reg_enum_t xed_reg) { switch (xed_reg) { case XED_REG_FLAGS: case XED_REG_EFLAGS: @@ -108,14 +139,15 @@ int is_flags_reg(xed_reg_enum_t xed_reg) { -int init_decoder() { +int v3_init_decoder() { xed_tables_init(); xed_state_zero(&decoder_state); return 0; } -int v3_basic_mem_decode(struct guest_info * info, addr_t instr_ptr, uint_t * size, uint_t * instr_length) { + +int v3_basic_mem_decode(struct guest_info * info, addr_t instr_ptr, struct basic_instr_info * instr_info) { xed_decoded_inst_t xed_instr; xed_error_enum_t xed_error; @@ -137,7 +169,7 @@ int v3_basic_mem_decode(struct guest_info * info, addr_t instr_ptr, uint_t * siz return -1; } - *instr_length = xed_decoded_inst_get_length(&xed_instr); + instr_info->instr_length = xed_decoded_inst_get_length(&xed_instr); if (xed_decoded_inst_number_of_memory_operands(&xed_instr) == 0) { @@ -145,7 +177,22 @@ int v3_basic_mem_decode(struct guest_info * info, addr_t instr_ptr, uint_t * siz return -1; } - *size = xed_decoded_inst_get_memory_operand_length(&xed_instr,0); + instr_info->op_size = xed_decoded_inst_get_memory_operand_length(&xed_instr, 0); + + + xed_category_enum_t cat = xed_decoded_inst_get_category(&xed_instr); + if (cat == XED_CATEGORY_STRINGOP) { + instr_info->str_op = 1; + } else { + instr_info->str_op = 0; + } + + xed_operand_values_t * operands = xed_decoded_inst_operands(&xed_instr); + if (xed_operand_values_has_real_rep(operands)) { + instr_info->has_rep = 1; + } else { + instr_info->has_rep = 0; + } return 0; } @@ -199,7 +246,7 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins if ((!xed_operand_is_register(op_enum)) || (!is_flags_reg(xed_decoded_inst_get_reg(&xed_instr, op_enum)))) { // special case - PrintDebug("Special Case not handled\n"); + PrintError("Special Case not handled\n"); return -1; } } @@ -209,7 +256,7 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins if (get_opcode(iform, &(instr->opcode)) == -1) { - PrintDebug("Could not get opcode. (iform=%s)\n", xed_iform_enum_t2str(iform)); + PrintError("Could not get opcode. (iform=%s)\n", xed_iform_enum_t2str(iform)); return -1; } @@ -383,7 +430,7 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins // set third operand if (instr->num_operands >= 3) { const xed_operand_t * op = xed_inst_operand(xi, 2); - // xed_operand_type_enum_t op_type = xed_operand_type(op); + xed_operand_type_enum_t op_type = xed_operand_type(op); xed_operand_enum_t op_enum = xed_operand_name(op); if (xed_operand_is_register(op_enum)) { @@ -407,7 +454,7 @@ int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * ins } else { - // PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type)); + PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type)); return -1; } @@ -940,6 +987,9 @@ static int get_opcode(xed_iform_enum_t iform, addr_t * opcode) { *opcode = (addr_t)&V3_OPCODE_MOV2CR; break; + case XED_IFORM_SMSW_GPRv: + *opcode = (addr_t)&V3_OPCODE_SMSW; + break; case XED_IFORM_LMSW_GPR16: *opcode = (addr_t)&V3_OPCODE_LMSW; @@ -949,6 +999,8 @@ static int get_opcode(xed_iform_enum_t iform, addr_t * opcode) { *opcode = (addr_t)&V3_OPCODE_CLTS; break; + + default: *opcode = 0; return -1;