From: Jack Lange Date: Wed, 23 Jul 2008 03:21:16 +0000 (+0000) Subject: moved xed around to setup the decoder interface X-Git-Tag: vmmhack1-ramdisk-boot-iso-puppy~50 X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=f224dad455ede0cdeadb60d0e428afcc869a4b2d moved xed around to setup the decoder interface --- diff --git a/palacios/include/palacios/vm_guest.h b/palacios/include/palacios/vm_guest.h index e2d94c4..9083b62 100644 --- a/palacios/include/palacios/vm_guest.h +++ b/palacios/include/palacios/vm_guest.h @@ -127,9 +127,6 @@ void PrintV3Segments(struct guest_info * info); void PrintV3CtrlRegs(struct guest_info * info); void PrintV3GPRs(struct guest_info * info); -#else - - #endif diff --git a/palacios/include/palacios/vmm.h b/palacios/include/palacios/vmm.h index 306b103..9fbc895 100644 --- a/palacios/include/palacios/vmm.h +++ b/palacios/include/palacios/vmm.h @@ -121,7 +121,7 @@ #define V3_Hook_Interrupt(irq, opaque) \ ({ \ - int ret = 0; \ + int ret = 0; \ extern struct vmm_os_hooks * os_hooks; \ if ((os_hooks) && (os_hooks)->hook_interrupt) { \ ret = (os_hooks)->hook_interrupt(irq, opaque); \ @@ -156,13 +156,6 @@ typedef enum v3_cpu_arch {V3_INVALID_CPU, V3_SVM_CPU, V3_SVM_REV3_CPU, V3_VMX_CP #endif //!__V3VEE__ -/* - #ifdef __V3VEE__ - typedef struct guest_info v3_guest_t; - #else - typedef void v3_guest_t; - #endif -*/ // @@ -213,8 +206,6 @@ struct vmm_os_hooks { - // Filled in by initialization - }; diff --git a/palacios/include/palacios/vmm_decoder.h b/palacios/include/palacios/vmm_decoder.h index ef08031..4d956b4 100644 --- a/palacios/include/palacios/vmm_decoder.h +++ b/palacios/include/palacios/vmm_decoder.h @@ -1,5 +1,8 @@ #ifndef __VMM_EMULATE_H #define __VMM_EMULATE_H + +#ifdef __V3VEE__ + #include #include @@ -8,11 +11,12 @@ * We can parse out the instruction prefixes, as well as decode the operands */ -typedef enum {INVALID_OPERAND, REG_OPERAND, MEM_OPERAND} operand_type_t; -int parse(); + +typedef enum {INVALID_OPERAND, REG_OPERAND, MEM_OPERAND} operand_type_t; + struct x86_operand { addr_t operand; uint_t size; @@ -20,22 +24,68 @@ struct x86_operand { }; struct x86_prefix_list { - uint_t lock : 1; + uint_t lock : 1; // 0xF0 + uint_t repne : 1; // 0xF2 + uint_t repnz : 1; // 0xF2 + uint_t rep : 1; // 0xF3 + uint_t repe : 1; // 0xF3 + uint_t repz : 1; // 0xF3 + uint_t cs_override : 1; // 0x2E + uint_t ss_override : 1; // 0x36 + uint_t ds_override : 1; // 0x3E + uint_t es_override : 1; // 0x26 + uint_t fs_override : 1; // 0x64 + uint_t gs_override : 1; // 0x65 + uint_t br_not_taken : 1; // 0x2E + uint_t br_takend : 1; // 0x3E + uint_t op_size : 1; // 0x66 + uint_t addr_size : 1; // 0x67 }; -/* This parses an instruction + +struct x86_instr { + uint_t instr_length; // output + addr_t opcode; // output + uint_t opcode_length; // output + struct x86_prefix_list prefixes; // output + struct x86_operand src_operand; // output + struct x86_operand dst_operand; // output + struct x86_operand extra_operand; +}; + + + /************************/ + /* EXTERNAL DECODER API */ +/************************/ +/* + This is an External API definition that must be implemented by a decoder +*/ + +/* + * Decodes an instruction * All addresses in arguments are in the host address space + * instr_ptr is the host address of the instruction + * IMPORTANT: make sure the instr_ptr is in contiguous host memory + * ie. Copy it to a buffer before the call */ -int v3_parse_instr(struct guest_info * info, // input - char * instr_ptr, // input - uint_t * instr_length, // output - addr_t * opcode, // output - uint_t * opcode_length, // output - struct x86_prefix_list * prefixes, // output - struct x86_operand * src_operand, // output - struct x86_operand * dst_operand, // output - struct x86_operand * extra_operand); // output - +int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr); + +/* + * Encodes an instruction + * All addresses in arguments are in the host address space + * The instruction is encoded from the struct, and copied into a 15 byte host buffer + * referenced by instr_buf + * any unused bytes at the end of instr_buf will be filled with nops + * IMPORTANT: instr_buf must be allocated and 15 bytes long + */ +int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf); + + + + + + + /* @@ -503,5 +553,7 @@ static inline operand_type_t decode_operands32(struct v3_gprs * gprs, // input/o +#endif // !__V3VEE__ + #endif diff --git a/palacios/include/palacios/vmm_xed.h b/palacios/include/palacios/vmm_xed.h new file mode 100644 index 0000000..ff460c5 --- /dev/null +++ b/palacios/include/palacios/vmm_xed.h @@ -0,0 +1,10 @@ +#ifndef __VMM_XED_H__ +#define __VMM_XED_H__ + +#ifdef __V3VEE__ + + + +#endif // ! __V3VEE__ + +#endif diff --git a/palacios/src/palacios/vmm_decoder.c b/palacios/src/palacios/vmm_decoder.c index a67887e..6884d33 100644 --- a/palacios/src/palacios/vmm_decoder.c +++ b/palacios/src/palacios/vmm_decoder.c @@ -1,86 +1,2 @@ #include -#if VMM_XED -#include -#endif - -int parse() { -#if !VMM_XED - PrintDebug("XED is not included in this kernel\n"); -#else - xed_state_t dstate; - xed_decoded_inst_t xedd; - xed_uint_t i, length; - xed_uint8_t itext[100] = {0x01,0x00,0x00,0x00,0x12,0x00,0x55,0x48,0x89,0xe5,0x48,0x89,0x7d,0xf8,0x89,0x75,0xf4,0x89,0x55,0xf0,0x89,0x4d,0xec,0x48,0x8b,0x55,0xf8,0x8b,0x45,0xf4,0x89,0x02,0x48,0x8b,0x55,0xf8,0x8b,0x45,0xf0,0x89,0x42,0x04,0x48,0x8b,0x55,0xf8,0x8b,0x45,0xec,0x89,0x42,0x08,0xc9,0xc3,0x55,0x48,0x89,0xe5,0x48,0x89,0x7d,0xf8,0x48,0x8b,0x45,0xf8,0x8b,0x40,0x08,0xc9,0xc3,0x90,0x0}; - xed_bool_t long_mode = true; - unsigned int first_argv; - int num; - - - for (i=0, num=1; i<100; i += length, num++){ - xed_tables_init(); - xed_state_zero(&dstate); - //if (argc > 2 && strcmp(argv[1], "-64") == 0) - long_mode = true; - - if (long_mode) { - first_argv = 2; - dstate.mmode=XED_MACHINE_MODE_LONG_64; - } - else { - first_argv=1; - xed_state_init(&dstate, - XED_MACHINE_MODE_LEGACY_32, - XED_ADDRESS_WIDTH_32b, - XED_ADDRESS_WIDTH_32b); - } - - xed_decoded_inst_zero_set_mode(&xedd, &dstate); - xed_error_enum_t xed_error = xed_decode(&xedd, - REINTERPRET_CAST(const xed_uint8_t*,&itext[i]), - XED_MAX_INSTRUCTION_BYTES); - switch(xed_error) { - case XED_ERROR_NONE: - break; - case XED_ERROR_BUFFER_TOO_SHORT: - PrintDebug("Not enough bytes provided\n"); - return 1; - case XED_ERROR_GENERAL_ERROR: - PrintDebug("Could not decode given input.\n"); - return 1; - default: - PrintDebug("Unhandled error code \n"); - return 1;; - } - - length = xed_decoded_inst_get_length (&xedd); - - PrintDebug("\nThe %dth instruction:", num); - - PrintDebug("\ncategory: "); - PrintDebug(" %s\n", xed_category_enum_t2str(xed_decoded_inst_get_category(&xedd)));; - PrintDebug("ISA-extension:%s\n ",xed_extension_enum_t2str(xed_decoded_inst_get_extension(&xedd))); - PrintDebug(" instruction-length: %d\n ", xed_decoded_inst_get_length(&xedd)); - PrintDebug(" operand-size:%d\n ", xed_operand_values_get_effective_operand_width(xed_decoded_inst_operands_const(&xedd))); - PrintDebug("address-size:%d\n ", xed_operand_values_get_effective_address_width(xed_decoded_inst_operands_const(&xedd))); - PrintDebug("iform-enum-name:%s\n ",xed_iform_enum_t2str(xed_decoded_inst_get_iform_enum(&xedd))); - PrintDebug("iform-enum-name-dispatch (zero based):%d\n ", xed_decoded_inst_get_iform_enum_dispatch(&xedd)); - PrintDebug("iclass-max-iform-dispatch: %d\n ", xed_iform_max_per_iclass(xed_decoded_inst_get_iclass(&xedd))); - - // operands - // print_operands(&xedd); - - // memops - // print_memops(&xedd); - - // flags - //print_flags(&xedd); - - // attributes - //print_attributes(&xedd);*/ - } - -#endif - - return 0; -} diff --git a/palacios/src/palacios/vmm_xed.c b/palacios/src/palacios/vmm_xed.c new file mode 100644 index 0000000..8dce816 --- /dev/null +++ b/palacios/src/palacios/vmm_xed.c @@ -0,0 +1,89 @@ +#include +#include + + + +int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) { + + xed_state_t dstate; + xed_decoded_inst_t xedd; + xed_uint_t i, length; + xed_uint8_t itext[100] = {0x01,0x00,0x00,0x00,0x12,0x00,0x55,0x48,0x89,0xe5,0x48,0x89,0x7d,0xf8,0x89,0x75,0xf4,0x89,0x55,0xf0,0x89,0x4d,0xec,0x48,0x8b,0x55,0xf8,0x8b,0x45,0xf4,0x89,0x02,0x48,0x8b,0x55,0xf8,0x8b,0x45,0xf0,0x89,0x42,0x04,0x48,0x8b,0x55,0xf8,0x8b,0x45,0xec,0x89,0x42,0x08,0xc9,0xc3,0x55,0x48,0x89,0xe5,0x48,0x89,0x7d,0xf8,0x48,0x8b,0x45,0xf8,0x8b,0x40,0x08,0xc9,0xc3,0x90,0x0}; + xed_bool_t long_mode = true; + unsigned int first_argv; + int num; + + + for (i=0, num=1; i<100; i += length, num++){ + xed_tables_init(); + xed_state_zero(&dstate); + //if (argc > 2 && strcmp(argv[1], "-64") == 0) + long_mode = true; + + if (long_mode) { + first_argv = 2; + dstate.mmode=XED_MACHINE_MODE_LONG_64; + } + else { + first_argv=1; + xed_state_init(&dstate, + XED_MACHINE_MODE_LEGACY_32, + XED_ADDRESS_WIDTH_32b, + XED_ADDRESS_WIDTH_32b); + } + + xed_decoded_inst_zero_set_mode(&xedd, &dstate); + xed_error_enum_t xed_error = xed_decode(&xedd, + REINTERPRET_CAST(const xed_uint8_t*,&itext[i]), + XED_MAX_INSTRUCTION_BYTES); + switch(xed_error) { + case XED_ERROR_NONE: + break; + case XED_ERROR_BUFFER_TOO_SHORT: + PrintDebug("Not enough bytes provided\n"); + return 1; + case XED_ERROR_GENERAL_ERROR: + PrintDebug("Could not decode given input.\n"); + return 1; + default: + PrintDebug("Unhandled error code \n"); + return 1;; + } + + length = xed_decoded_inst_get_length (&xedd); + + PrintDebug("\nThe %dth instruction:", num); + + PrintDebug("\ncategory: "); + PrintDebug(" %s\n", xed_category_enum_t2str(xed_decoded_inst_get_category(&xedd)));; + PrintDebug("ISA-extension:%s\n ",xed_extension_enum_t2str(xed_decoded_inst_get_extension(&xedd))); + PrintDebug(" instruction-length: %d\n ", xed_decoded_inst_get_length(&xedd)); + PrintDebug(" operand-size:%d\n ", xed_operand_values_get_effective_operand_width(xed_decoded_inst_operands_const(&xedd))); + PrintDebug("address-size:%d\n ", xed_operand_values_get_effective_address_width(xed_decoded_inst_operands_const(&xedd))); + PrintDebug("iform-enum-name:%s\n ",xed_iform_enum_t2str(xed_decoded_inst_get_iform_enum(&xedd))); + PrintDebug("iform-enum-name-dispatch (zero based):%d\n ", xed_decoded_inst_get_iform_enum_dispatch(&xedd)); + PrintDebug("iclass-max-iform-dispatch: %d\n ", xed_iform_max_per_iclass(xed_decoded_inst_get_iclass(&xedd))); + + // operands + // print_operands(&xedd); + + // memops + // print_memops(&xedd); + + // flags + //print_flags(&xedd); + + // attributes + //print_attributes(&xedd);*/ + } + + + + return -1; +} + + +int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) { + + return -1; +}