From: Alexander Kudryavtsev Date: Mon, 30 Jan 2012 15:29:16 +0000 (+0400) Subject: Integration of QUIX86 decoder libraries. Debug and optimized versions. X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=3d68a569e5122ebb366d426d1e69f657a4201408;p=palacios.releases.git Integration of QUIX86 decoder libraries. Debug and optimized versions. --- diff --git a/Kconfig b/Kconfig index 8518fd8..0fb4b9a 100644 --- a/Kconfig +++ b/Kconfig @@ -102,6 +102,16 @@ config V3_DECODER help This selects the internal V3Vee x86 decoder +config QUIX86 + bool "QUIX86 decoder" + help + This selects the QUIX86 decoder library + +config QUIX86_DEBUG + bool "QUIX86 decoder debug version" + help + This selects the QUIX86 decoder library compiled w/o optimization + and with debug info endchoice diff --git a/palacios/include/quix86/quix86.h b/palacios/include/quix86/quix86.h new file mode 100644 index 0000000..8530962 --- /dev/null +++ b/palacios/include/quix86/quix86.h @@ -0,0 +1,2049 @@ +/* +------------------------------------------------------------------------+ + | quix86 | + +------------------------------------------------------------------------+ + | This file is part of quix86, an x86-64 instruction decoder. | + | | + | Copyright (C) 2011 Institute for System Programming of Russian Academy | + | of Sciences. | + | | + | Contact e-mail: . | + | | + | quix86 is free software: you can redistribute it and/or modify it | + | under the terms of the GNU Lesser General Public License as published | + | by the Free Software Foundation, either version 3 of the License, or | + | (at your option) any later version. | + | | + | quix86 is distributed in the hope that it will be useful, but WITHOUT | + | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | + | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | + | License for more details. | + | | + | You should have received a copy of the GNU Lesser General Public | + | License along with quix86. If not, see . | + +------------------------------------------------------------------------+ */ + +#ifndef QUIX86_H +#define QUIX86_H + +/* Provide definitions for INT8..INT64 and UINT8..UINT64. */ +#ifdef _MSC_VER + /* Definitions for INT8..INT64. */ +# define QX86_INT8 __int8 +# define QX86_INT16 __int16 +# define QX86_INT32 __int32 +# define QX86_INT64 __int64 + + /* Definitions for UINT8..UINT64. */ +# define QX86_UINT8 unsigned __int8 +# define QX86_UINT16 unsigned __int16 +# define QX86_UINT32 unsigned __int32 +# define QX86_UINT64 unsigned __int64 +#else + /* No built-in types. See if we have one of the standard headers. */ +# if defined(HAVE_INTTYPES_H) || defined(HAVE_STDINT_H) + /* Prefer as it's somewhat smaller. */ +# ifdef HAVE_STDINT_H + /* Include . */ +# include +# else + /* Include instead. */ +# include +# endif + + /* Definitions for INT8..INT64. */ +# define QX86_INT8 int8_t +# define QX86_INT16 int16_t +# define QX86_INT32 int32_t +# define QX86_INT64 int64_t + + /* Definitions for UINT8..UINT64. */ +# define QX86_UINT8 uint8_t +# define QX86_UINT16 uint16_t +# define QX86_UINT32 uint32_t +# define QX86_UINT64 uint64_t +# else + /* Likely definitions for INT8..INT64. */ +# define QX86_INT8 signed char +# define QX86_INT16 short +# define QX86_INT32 int +# define QX86_INT64 long long + + /* Likely definitions for UINT8..UINT64. */ +# define QX86_UINT8 unsigned char +# define QX86_UINT16 unsigned short +# define QX86_UINT32 unsigned int +# define QX86_UINT64 unsigned long long +# endif +#endif + +/* Provide wrappers around const and inline for compilers that don't support + C99. */ +#ifdef _MSC_VER + /* Microsoft Visual C is not C99-conformant. Use alternative keywords. */ +# define QX86_CONST const +# define QX86_INLINE __inline +# define QX86_RESTRICT /* ILB */ +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + /* C99 supported. */ +# define QX86_CONST const +# define QX86_INLINE inline +# define QX86_RESTRICT restrict +#elif defined(__GNUC__) && (__GNUC__ >= 4) + /* GNU C supported. */ +# define QX86_CONST const +# define QX86_INLINE inline +# define QX86_RESTRICT restrict +#elif defined(__cplusplus) + /* C++ mode supports const and inline. */ +# define QX86_CONST const +# define QX86_INLINE inline +# define QX86_RESTRICT /* ILB */ +#else + /* Assume none of the qualifiers is supported. */ +# define QX86_CONST /* ILB */ +# define QX86_INLINE /* ILB */ +# define QX86_RESTRICT /* ILB */ +#endif + +/* Wrap declarations in extern "C" if needed. */ +#ifdef __cplusplus + /* Need wrapper. */ +# define QX86_EXTERN_C extern "C" +#else + /* No wrapper required. */ +# define QX86_EXTERN_C /* ILB */ +#endif + +/** + * 8-bit signed integer type. + * + * \author icee + * \since 1.0 + */ +typedef QX86_INT8 qx86_int8; + +/** + * 16-bit signed integer type. + * + * \author icee + * \since 1.0 + */ +typedef QX86_INT16 qx86_int16; + +/** + * 32-bit signed integer type. + * + * \author icee + * \since 1.0 + */ +typedef QX86_INT32 qx86_int32; + +/** + * 64-bit signed integer type. + * + * \author icee + * \since 1.0 + */ +typedef QX86_INT64 qx86_int64; + +/** + * 8-bit unsigned integer type. + * + * \author icee + * \since 1.0 + */ +typedef QX86_UINT8 qx86_uint8; + +/** + * 16-bit unsigned integer type. + * + * \author icee + * \since 1.0 + */ +typedef QX86_UINT16 qx86_uint16; + +/** + * 32-bit unsigned integer type. + * + * \author icee + * \since 1.0 + */ +typedef QX86_UINT32 qx86_uint32; + +/** + * 64-bit unsigned integer type. + * + * \author icee + * \since 1.0 + */ +typedef QX86_UINT64 qx86_uint64; + +/* Public API structure declarations. */ +typedef struct qx86_amode qx86_amode; +typedef struct qx86_ctx qx86_ctx; +typedef struct qx86_insn qx86_insn; +typedef struct qx86_insn_attributes qx86_insn_attributes; +typedef struct qx86_insn_modifiers qx86_insn_modifiers; +typedef struct qx86_print_options_intel qx86_print_options_intel; +typedef struct qx86_mtab_item qx86_mtab_item; +typedef struct qx86_opcode_map qx86_opcode_map; +typedef struct qx86_opcode_map_item qx86_opcode_map_item; +typedef struct qx86_operand qx86_operand; +typedef struct qx86_operand_far_pointer qx86_operand_far_pointer; +typedef struct qx86_operand_form qx86_operand_form; +typedef struct qx86_operand_form_amode qx86_operand_form_amode; +typedef struct qx86_operand_form_rtuple qx86_operand_form_rtuple; +typedef struct qx86_operand_immediate qx86_operand_immediate; +typedef struct qx86_operand_jump_offset qx86_operand_jump_offset; +typedef struct qx86_operand_memory qx86_operand_memory; +typedef struct qx86_operand_register qx86_operand_register; +typedef struct qx86_print_item qx86_print_item; +typedef struct qx86_rtab_item qx86_rtab_item; +typedef struct qx86_rtuple qx86_rtuple; +typedef struct qx86_stuple qx86_stuple; + +/* Public API union declarations. */ +typedef union qx86_operand_union qx86_operand_union; +typedef union qx86_operand_form_union qx86_operand_form_union; + +/* Public API enumerations. */ + + +/** + * Enumeration of x86 instruction defects. + * + * \author icee + * \since 1.0 + */ +enum +{ + QX86_DEFECT_NONE = 0, + + QX86_DEFECT_MODRM_MOD_NOT_3 = 1 << 0, + QX86_DEFECT_MODRM_MOD_3 = 1 << 1 +}; + + + +/** + * Enumeration of x86 displacement sizes. + * + * \author icee + * \since 1.0 + */ +enum +{ + QX86_DISP_NONE = 0, + QX86_DISP_8 = 1, + QX86_DISP_16 = 2, + QX86_DISP_32 = 4, + QX86_DISP_64 = 8, + + QX86_DISP_INVALID = 3 +}; + + + +/** + * Enumeration of quix86 error codes. + * + * \author icee + * \since 1.0 + */ +enum +{ + QX86_SUCCESS = 0, + + QX86_E_INTERNAL = 1, + QX86_E_API = 2, + + QX86_E_INSN_INCOMPLETE = 3, + QX86_E_INSN_UNDEFINED = 4, + + QX86_E_INSUFFICIENT_BUFFER = 5, + + QX86_E_CALLBACK = 6, + + QX86_E_COUNT = 7 +}; + + + +/** + * Enumeration of instruction classes. + * + * An instruction can belong to multiple instruction classes at the same time. + * + * \author icee + * \since 1.0 + */ +enum +{ + QX86_ICLASS_NONE = 0, + + QX86_ICLASS_CONDITIONAL_EXECUTION = 1 << 0, + + QX86_ICLASS_TRANSFER = 1 << 1, + QX86_ICLASS_TRANSFER_LINKED = 1 << 2, + QX86_ICLASS_TRANSFER_LINKED_BACK = 1 << 3, + QX86_ICLASS_TRANSFER_SERVICE = 1 << 4 +}; + + + +/** + * Architectural limits of the x86. + * + * \author icee + * \since 1.0 + */ +enum +{ + QX86_IMMEDIATE_SIZE_MAX = 8, + QX86_INSN_SIZE_MAX = 15, + QX86_OPERAND_NMAX = 4 +}; + + +/** + * Enumeration of x86 instruction mnemonics. + * + * \author icee + * \since 1.0 + */ +enum qx86_mnemonic +{ + QX86_MNEMONIC_NONE = 0, + + /* Enumerators are sorted based on their names. */ + QX86_MNEMONIC_AAA = 1, + QX86_MNEMONIC_AAD = 2, + QX86_MNEMONIC_AAM = 3, + QX86_MNEMONIC_AAS = 4, + QX86_MNEMONIC_ADC = 5, + QX86_MNEMONIC_ADD = 6, + QX86_MNEMONIC_ADDPD = 7, + QX86_MNEMONIC_ADDPS = 8, + QX86_MNEMONIC_ADDSD = 9, + QX86_MNEMONIC_ADDSS = 10, + QX86_MNEMONIC_ADDSUBPD = 11, + QX86_MNEMONIC_ADDSUBPS = 12, + QX86_MNEMONIC_AESDEC = 13, + QX86_MNEMONIC_AESDECLAST = 14, + QX86_MNEMONIC_AESENC = 15, + QX86_MNEMONIC_AESENCLAST = 16, + QX86_MNEMONIC_AESIMC = 17, + QX86_MNEMONIC_AESKEYGENASSIST = 18, + QX86_MNEMONIC_AND = 19, + QX86_MNEMONIC_ANDNPD = 20, + QX86_MNEMONIC_ANDNPS = 21, + QX86_MNEMONIC_ANDPD = 22, + QX86_MNEMONIC_ANDPS = 23, + QX86_MNEMONIC_ARPL = 24, + QX86_MNEMONIC_BLENDPD = 25, + QX86_MNEMONIC_BLENDPS = 26, + QX86_MNEMONIC_BLENDVPD = 27, + QX86_MNEMONIC_BLENDVPS = 28, + QX86_MNEMONIC_BOUND = 29, + QX86_MNEMONIC_BSF = 30, + QX86_MNEMONIC_BSR = 31, + QX86_MNEMONIC_BSWAP = 32, + QX86_MNEMONIC_BT = 33, + QX86_MNEMONIC_BTC = 34, + QX86_MNEMONIC_BTR = 35, + QX86_MNEMONIC_BTS = 36, + QX86_MNEMONIC_CALL = 37, + QX86_MNEMONIC_CALLF = 38, + QX86_MNEMONIC_CBW = 39, + QX86_MNEMONIC_CDQ = 40, + QX86_MNEMONIC_CDQE = 41, + QX86_MNEMONIC_CLC = 42, + QX86_MNEMONIC_CLD = 43, + QX86_MNEMONIC_CLFLUSH = 44, + QX86_MNEMONIC_CLGI = 45, + QX86_MNEMONIC_CLI = 46, + QX86_MNEMONIC_CLTS = 47, + QX86_MNEMONIC_CMC = 48, + QX86_MNEMONIC_CMOVA = 49, + QX86_MNEMONIC_CMOVAE = 50, + QX86_MNEMONIC_CMOVB = 51, + QX86_MNEMONIC_CMOVBE = 52, + QX86_MNEMONIC_CMOVG = 53, + QX86_MNEMONIC_CMOVGE = 54, + QX86_MNEMONIC_CMOVL = 55, + QX86_MNEMONIC_CMOVLE = 56, + QX86_MNEMONIC_CMOVNO = 57, + QX86_MNEMONIC_CMOVNP = 58, + QX86_MNEMONIC_CMOVNS = 59, + QX86_MNEMONIC_CMOVNZ = 60, + QX86_MNEMONIC_CMOVO = 61, + QX86_MNEMONIC_CMOVP = 62, + QX86_MNEMONIC_CMOVS = 63, + QX86_MNEMONIC_CMOVZ = 64, + QX86_MNEMONIC_CMP = 65, + QX86_MNEMONIC_CMPPD = 66, + QX86_MNEMONIC_CMPPS = 67, + QX86_MNEMONIC_CMPSB = 68, + QX86_MNEMONIC_CMPSD = 69, + QX86_MNEMONIC_CMPSD_SSE = 70, + QX86_MNEMONIC_CMPSQ = 71, + QX86_MNEMONIC_CMPSS = 72, + QX86_MNEMONIC_CMPSW = 73, + QX86_MNEMONIC_CMPXCHG = 74, + QX86_MNEMONIC_CMPXCHG16B = 75, + QX86_MNEMONIC_CMPXCHG8B = 76, + QX86_MNEMONIC_COMISD = 77, + QX86_MNEMONIC_COMISS = 78, + QX86_MNEMONIC_CPUID = 79, + QX86_MNEMONIC_CQO = 80, + QX86_MNEMONIC_CRC32 = 81, + QX86_MNEMONIC_CVTDQ2PD = 82, + QX86_MNEMONIC_CVTDQ2PS = 83, + QX86_MNEMONIC_CVTPD2DQ = 84, + QX86_MNEMONIC_CVTPD2PI = 85, + QX86_MNEMONIC_CVTPD2PS = 86, + QX86_MNEMONIC_CVTPI2PD = 87, + QX86_MNEMONIC_CVTPI2PS = 88, + QX86_MNEMONIC_CVTPS2DQ = 89, + QX86_MNEMONIC_CVTPS2PD = 90, + QX86_MNEMONIC_CVTPS2PI = 91, + QX86_MNEMONIC_CVTSD2SI = 92, + QX86_MNEMONIC_CVTSD2SS = 93, + QX86_MNEMONIC_CVTSI2SD = 94, + QX86_MNEMONIC_CVTSI2SS = 95, + QX86_MNEMONIC_CVTSS2SD = 96, + QX86_MNEMONIC_CVTSS2SI = 97, + QX86_MNEMONIC_CVTTPD2DQ = 98, + QX86_MNEMONIC_CVTTPD2PI = 99, + QX86_MNEMONIC_CVTTPS2DQ = 100, + QX86_MNEMONIC_CVTTPS2PI = 101, + QX86_MNEMONIC_CVTTSD2SI = 102, + QX86_MNEMONIC_CVTTSS2SI = 103, + QX86_MNEMONIC_CWD = 104, + QX86_MNEMONIC_CWDE = 105, + QX86_MNEMONIC_DAA = 106, + QX86_MNEMONIC_DAS = 107, + QX86_MNEMONIC_DEC = 108, + QX86_MNEMONIC_DIV = 109, + QX86_MNEMONIC_DIVPD = 110, + QX86_MNEMONIC_DIVPS = 111, + QX86_MNEMONIC_DIVSD = 112, + QX86_MNEMONIC_DIVSS = 113, + QX86_MNEMONIC_DPPD = 114, + QX86_MNEMONIC_DPPS = 115, + QX86_MNEMONIC_EMMS = 116, + QX86_MNEMONIC_ENTER = 117, + QX86_MNEMONIC_EXTRACTPS = 118, + QX86_MNEMONIC_EXTRQ = 119, + QX86_MNEMONIC_F2XM1 = 120, + QX86_MNEMONIC_FABS = 121, + QX86_MNEMONIC_FADD = 122, + QX86_MNEMONIC_FADDP = 123, + QX86_MNEMONIC_FBLD = 124, + QX86_MNEMONIC_FBSTP = 125, + QX86_MNEMONIC_FCHS = 126, + QX86_MNEMONIC_FCMOVB = 127, + QX86_MNEMONIC_FCMOVBE = 128, + QX86_MNEMONIC_FCMOVE = 129, + QX86_MNEMONIC_FCMOVNB = 130, + QX86_MNEMONIC_FCMOVNBE = 131, + QX86_MNEMONIC_FCMOVNE = 132, + QX86_MNEMONIC_FCMOVNU = 133, + QX86_MNEMONIC_FCMOVU = 134, + QX86_MNEMONIC_FCOM = 135, + QX86_MNEMONIC_FCOMI = 136, + QX86_MNEMONIC_FCOMIP = 137, + QX86_MNEMONIC_FCOMP = 138, + QX86_MNEMONIC_FCOMPP = 139, + QX86_MNEMONIC_FCOS = 140, + QX86_MNEMONIC_FDECSTP = 141, + QX86_MNEMONIC_FDIV = 142, + QX86_MNEMONIC_FDIVP = 143, + QX86_MNEMONIC_FDIVR = 144, + QX86_MNEMONIC_FDIVRP = 145, + QX86_MNEMONIC_FEMMS = 146, + QX86_MNEMONIC_FFREE = 147, + QX86_MNEMONIC_FIADD = 148, + QX86_MNEMONIC_FICOM = 149, + QX86_MNEMONIC_FICOMP = 150, + QX86_MNEMONIC_FIDIV = 151, + QX86_MNEMONIC_FIDIVR = 152, + QX86_MNEMONIC_FILD = 153, + QX86_MNEMONIC_FIMUL = 154, + QX86_MNEMONIC_FINCSTP = 155, + QX86_MNEMONIC_FIST = 156, + QX86_MNEMONIC_FISTP = 157, + QX86_MNEMONIC_FISTTP = 158, + QX86_MNEMONIC_FISUB = 159, + QX86_MNEMONIC_FISUBR = 160, + QX86_MNEMONIC_FLD = 161, + QX86_MNEMONIC_FLD1 = 162, + QX86_MNEMONIC_FLDCW = 163, + QX86_MNEMONIC_FLDENV = 164, + QX86_MNEMONIC_FLDL2E = 165, + QX86_MNEMONIC_FLDL2T = 166, + QX86_MNEMONIC_FLDLG2 = 167, + QX86_MNEMONIC_FLDLN2 = 168, + QX86_MNEMONIC_FLDPI = 169, + QX86_MNEMONIC_FLDZ = 170, + QX86_MNEMONIC_FMUL = 171, + QX86_MNEMONIC_FMULP = 172, + QX86_MNEMONIC_FNCLEX = 173, + QX86_MNEMONIC_FNINIT = 174, + QX86_MNEMONIC_FNOP = 175, + QX86_MNEMONIC_FNSAVE = 176, + QX86_MNEMONIC_FNSTCW = 177, + QX86_MNEMONIC_FNSTENV = 178, + QX86_MNEMONIC_FNSTSW = 179, + QX86_MNEMONIC_FPATAN = 180, + QX86_MNEMONIC_FPREM = 181, + QX86_MNEMONIC_FPREM1 = 182, + QX86_MNEMONIC_FPTAN = 183, + QX86_MNEMONIC_FRNDINT = 184, + QX86_MNEMONIC_FRSTOR = 185, + QX86_MNEMONIC_FSCALE = 186, + QX86_MNEMONIC_FSIN = 187, + QX86_MNEMONIC_FSINCOS = 188, + QX86_MNEMONIC_FSQRT = 189, + QX86_MNEMONIC_FST = 190, + QX86_MNEMONIC_FSTP = 191, + QX86_MNEMONIC_FSUB = 192, + QX86_MNEMONIC_FSUBP = 193, + QX86_MNEMONIC_FSUBR = 194, + QX86_MNEMONIC_FSUBRP = 195, + QX86_MNEMONIC_FTST = 196, + QX86_MNEMONIC_FUCOM = 197, + QX86_MNEMONIC_FUCOMI = 198, + QX86_MNEMONIC_FUCOMIP = 199, + QX86_MNEMONIC_FUCOMP = 200, + QX86_MNEMONIC_FUCOMPP = 201, + QX86_MNEMONIC_FWAIT = 202, + QX86_MNEMONIC_FXAM = 203, + QX86_MNEMONIC_FXCH = 204, + QX86_MNEMONIC_FXRSTOR = 205, + QX86_MNEMONIC_FXSAVE = 206, + QX86_MNEMONIC_FXTRACT = 207, + QX86_MNEMONIC_FYL2X = 208, + QX86_MNEMONIC_FYL2XP1 = 209, + QX86_MNEMONIC_GETSEC = 210, + QX86_MNEMONIC_HADDPD = 211, + QX86_MNEMONIC_HADDPS = 212, + QX86_MNEMONIC_HLT = 213, + QX86_MNEMONIC_HSUBPD = 214, + QX86_MNEMONIC_HSUBPS = 215, + QX86_MNEMONIC_IDIV = 216, + QX86_MNEMONIC_IMUL = 217, + QX86_MNEMONIC_IN = 218, + QX86_MNEMONIC_INC = 219, + QX86_MNEMONIC_INSB = 220, + QX86_MNEMONIC_INSD = 221, + QX86_MNEMONIC_INSERTPS = 222, + QX86_MNEMONIC_INSERTQ = 223, + QX86_MNEMONIC_INSW = 224, + QX86_MNEMONIC_INT = 225, + QX86_MNEMONIC_INT1 = 226, + QX86_MNEMONIC_INT3 = 227, + QX86_MNEMONIC_INTO = 228, + QX86_MNEMONIC_INVD = 229, + QX86_MNEMONIC_INVEPT = 230, + QX86_MNEMONIC_INVLPG = 231, + QX86_MNEMONIC_INVLPGA = 232, + QX86_MNEMONIC_INVVPID = 233, + QX86_MNEMONIC_IRET = 234, + QX86_MNEMONIC_IRETD = 235, + QX86_MNEMONIC_IRETQ = 236, + QX86_MNEMONIC_JA = 237, + QX86_MNEMONIC_JAE = 238, + QX86_MNEMONIC_JB = 239, + QX86_MNEMONIC_JBE = 240, + QX86_MNEMONIC_JCXZ = 241, + QX86_MNEMONIC_JECXZ = 242, + QX86_MNEMONIC_JG = 243, + QX86_MNEMONIC_JGE = 244, + QX86_MNEMONIC_JL = 245, + QX86_MNEMONIC_JLE = 246, + QX86_MNEMONIC_JMP = 247, + QX86_MNEMONIC_JMPF = 248, + QX86_MNEMONIC_JNO = 249, + QX86_MNEMONIC_JNP = 250, + QX86_MNEMONIC_JNS = 251, + QX86_MNEMONIC_JNZ = 252, + QX86_MNEMONIC_JO = 253, + QX86_MNEMONIC_JP = 254, + QX86_MNEMONIC_JRCXZ = 255, + QX86_MNEMONIC_JS = 256, + QX86_MNEMONIC_JZ = 257, + QX86_MNEMONIC_LAHF = 258, + QX86_MNEMONIC_LAR = 259, + QX86_MNEMONIC_LCS = 260, + QX86_MNEMONIC_LDDQU = 261, + QX86_MNEMONIC_LDMXCSR = 262, + QX86_MNEMONIC_LDS = 263, + QX86_MNEMONIC_LEA = 264, + QX86_MNEMONIC_LEAVE = 265, + QX86_MNEMONIC_LES = 266, + QX86_MNEMONIC_LFENCE = 267, + QX86_MNEMONIC_LFS = 268, + QX86_MNEMONIC_LGDT = 269, + QX86_MNEMONIC_LGS = 270, + QX86_MNEMONIC_LIDT = 271, + QX86_MNEMONIC_LLDT = 272, + QX86_MNEMONIC_LMSW = 273, + QX86_MNEMONIC_LODSB = 274, + QX86_MNEMONIC_LODSD = 275, + QX86_MNEMONIC_LODSQ = 276, + QX86_MNEMONIC_LODSW = 277, + QX86_MNEMONIC_LOOP = 278, + QX86_MNEMONIC_LOOPNZ = 279, + QX86_MNEMONIC_LOOPZ = 280, + QX86_MNEMONIC_LSL = 281, + QX86_MNEMONIC_LSS = 282, + QX86_MNEMONIC_LTR = 283, + QX86_MNEMONIC_LZCNT = 284, + QX86_MNEMONIC_MASKMOVDQU = 285, + QX86_MNEMONIC_MASKMOVQ = 286, + QX86_MNEMONIC_MAXPD = 287, + QX86_MNEMONIC_MAXPS = 288, + QX86_MNEMONIC_MAXSD = 289, + QX86_MNEMONIC_MAXSS = 290, + QX86_MNEMONIC_MFENCE = 291, + QX86_MNEMONIC_MINPD = 292, + QX86_MNEMONIC_MINPS = 293, + QX86_MNEMONIC_MINSD = 294, + QX86_MNEMONIC_MINSS = 295, + QX86_MNEMONIC_MONITOR = 296, + QX86_MNEMONIC_MOV = 297, + QX86_MNEMONIC_MOVAPD = 298, + QX86_MNEMONIC_MOVAPS = 299, + QX86_MNEMONIC_MOVBE = 300, + QX86_MNEMONIC_MOVD = 301, + QX86_MNEMONIC_MOVDDUP = 302, + QX86_MNEMONIC_MOVDQ2Q = 303, + QX86_MNEMONIC_MOVDQA = 304, + QX86_MNEMONIC_MOVDQU = 305, + QX86_MNEMONIC_MOVHLPS = 306, + QX86_MNEMONIC_MOVHPD = 307, + QX86_MNEMONIC_MOVHPS = 308, + QX86_MNEMONIC_MOVLHPS = 309, + QX86_MNEMONIC_MOVLPD = 310, + QX86_MNEMONIC_MOVLPS = 311, + QX86_MNEMONIC_MOVMSKPD = 312, + QX86_MNEMONIC_MOVMSKPS = 313, + QX86_MNEMONIC_MOVNTDQ = 314, + QX86_MNEMONIC_MOVNTDQA = 315, + QX86_MNEMONIC_MOVNTI = 316, + QX86_MNEMONIC_MOVNTPD = 317, + QX86_MNEMONIC_MOVNTPS = 318, + QX86_MNEMONIC_MOVNTQ = 319, + QX86_MNEMONIC_MOVNTSD = 320, + QX86_MNEMONIC_MOVNTSS = 321, + QX86_MNEMONIC_MOVQ = 322, + QX86_MNEMONIC_MOVQ2DQ = 323, + QX86_MNEMONIC_MOVSB = 324, + QX86_MNEMONIC_MOVSD = 325, + QX86_MNEMONIC_MOVSD_SSE = 326, + QX86_MNEMONIC_MOVSHDUP = 327, + QX86_MNEMONIC_MOVSLDUP = 328, + QX86_MNEMONIC_MOVSQ = 329, + QX86_MNEMONIC_MOVSS = 330, + QX86_MNEMONIC_MOVSW = 331, + QX86_MNEMONIC_MOVSX = 332, + QX86_MNEMONIC_MOVSXD = 333, + QX86_MNEMONIC_MOVUPD = 334, + QX86_MNEMONIC_MOVUPS = 335, + QX86_MNEMONIC_MOVZX = 336, + QX86_MNEMONIC_MPSADBW = 337, + QX86_MNEMONIC_MUL = 338, + QX86_MNEMONIC_MULPD = 339, + QX86_MNEMONIC_MULPS = 340, + QX86_MNEMONIC_MULSD = 341, + QX86_MNEMONIC_MULSS = 342, + QX86_MNEMONIC_MWAIT = 343, + QX86_MNEMONIC_NEG = 344, + QX86_MNEMONIC_NOP = 345, + QX86_MNEMONIC_NOT = 346, + QX86_MNEMONIC_OR = 347, + QX86_MNEMONIC_ORPD = 348, + QX86_MNEMONIC_ORPS = 349, + QX86_MNEMONIC_OUT = 350, + QX86_MNEMONIC_OUTSB = 351, + QX86_MNEMONIC_OUTSD = 352, + QX86_MNEMONIC_OUTSW = 353, + QX86_MNEMONIC_PABSB = 354, + QX86_MNEMONIC_PABSD = 355, + QX86_MNEMONIC_PABSW = 356, + QX86_MNEMONIC_PACKSSDW = 357, + QX86_MNEMONIC_PACKSSWB = 358, + QX86_MNEMONIC_PACKUSDW = 359, + QX86_MNEMONIC_PACKUSWB = 360, + QX86_MNEMONIC_PADDB = 361, + QX86_MNEMONIC_PADDD = 362, + QX86_MNEMONIC_PADDQ = 363, + QX86_MNEMONIC_PADDSB = 364, + QX86_MNEMONIC_PADDSW = 365, + QX86_MNEMONIC_PADDUSB = 366, + QX86_MNEMONIC_PADDUSW = 367, + QX86_MNEMONIC_PADDW = 368, + QX86_MNEMONIC_PALIGNR = 369, + QX86_MNEMONIC_PAND = 370, + QX86_MNEMONIC_PANDN = 371, + QX86_MNEMONIC_PAUSE = 372, + QX86_MNEMONIC_PAVGB = 373, + QX86_MNEMONIC_PAVGUSB = 374, + QX86_MNEMONIC_PAVGW = 375, + QX86_MNEMONIC_PBLENDVB = 376, + QX86_MNEMONIC_PBLENDW = 377, + QX86_MNEMONIC_PCLMULQDQ = 378, + QX86_MNEMONIC_PCMPEQB = 379, + QX86_MNEMONIC_PCMPEQD = 380, + QX86_MNEMONIC_PCMPEQQ = 381, + QX86_MNEMONIC_PCMPEQW = 382, + QX86_MNEMONIC_PCMPESTRI = 383, + QX86_MNEMONIC_PCMPESTRM = 384, + QX86_MNEMONIC_PCMPGTB = 385, + QX86_MNEMONIC_PCMPGTD = 386, + QX86_MNEMONIC_PCMPGTQ = 387, + QX86_MNEMONIC_PCMPGTW = 388, + QX86_MNEMONIC_PCMPISTRI = 389, + QX86_MNEMONIC_PCMPISTRM = 390, + QX86_MNEMONIC_PEXTRB = 391, + QX86_MNEMONIC_PEXTRD = 392, + QX86_MNEMONIC_PEXTRQ = 393, + QX86_MNEMONIC_PEXTRW = 394, + QX86_MNEMONIC_PF2ID = 395, + QX86_MNEMONIC_PF2IW = 396, + QX86_MNEMONIC_PFACC = 397, + QX86_MNEMONIC_PFADD = 398, + QX86_MNEMONIC_PFCMPEQ = 399, + QX86_MNEMONIC_PFCMPGE = 400, + QX86_MNEMONIC_PFCMPGT = 401, + QX86_MNEMONIC_PFMAX = 402, + QX86_MNEMONIC_PFMIN = 403, + QX86_MNEMONIC_PFMUL = 404, + QX86_MNEMONIC_PFNACC = 405, + QX86_MNEMONIC_PFPNACC = 406, + QX86_MNEMONIC_PFRCP = 407, + QX86_MNEMONIC_PFRCPIT1 = 408, + QX86_MNEMONIC_PFRCPIT2 = 409, + QX86_MNEMONIC_PFRSQIT1 = 410, + QX86_MNEMONIC_PFRSQRT = 411, + QX86_MNEMONIC_PFSUB = 412, + QX86_MNEMONIC_PFSUBR = 413, + QX86_MNEMONIC_PHADDD = 414, + QX86_MNEMONIC_PHADDSW = 415, + QX86_MNEMONIC_PHADDW = 416, + QX86_MNEMONIC_PHMINPOSUW = 417, + QX86_MNEMONIC_PHSUBD = 418, + QX86_MNEMONIC_PHSUBSW = 419, + QX86_MNEMONIC_PHSUBW = 420, + QX86_MNEMONIC_PI2FD = 421, + QX86_MNEMONIC_PI2FW = 422, + QX86_MNEMONIC_PINSRB = 423, + QX86_MNEMONIC_PINSRD = 424, + QX86_MNEMONIC_PINSRQ = 425, + QX86_MNEMONIC_PINSRW = 426, + QX86_MNEMONIC_PMADDUBSW = 427, + QX86_MNEMONIC_PMADDWD = 428, + QX86_MNEMONIC_PMAXSB = 429, + QX86_MNEMONIC_PMAXSD = 430, + QX86_MNEMONIC_PMAXSW = 431, + QX86_MNEMONIC_PMAXUB = 432, + QX86_MNEMONIC_PMAXUD = 433, + QX86_MNEMONIC_PMAXUW = 434, + QX86_MNEMONIC_PMINSB = 435, + QX86_MNEMONIC_PMINSD = 436, + QX86_MNEMONIC_PMINSW = 437, + QX86_MNEMONIC_PMINUB = 438, + QX86_MNEMONIC_PMINUD = 439, + QX86_MNEMONIC_PMINUW = 440, + QX86_MNEMONIC_PMOVMSKB = 441, + QX86_MNEMONIC_PMOVSXBD = 442, + QX86_MNEMONIC_PMOVSXBQ = 443, + QX86_MNEMONIC_PMOVSXBW = 444, + QX86_MNEMONIC_PMOVSXDQ = 445, + QX86_MNEMONIC_PMOVSXWD = 446, + QX86_MNEMONIC_PMOVSXWQ = 447, + QX86_MNEMONIC_PMOVZXBD = 448, + QX86_MNEMONIC_PMOVZXBQ = 449, + QX86_MNEMONIC_PMOVZXBW = 450, + QX86_MNEMONIC_PMOVZXDQ = 451, + QX86_MNEMONIC_PMOVZXWD = 452, + QX86_MNEMONIC_PMOVZXWQ = 453, + QX86_MNEMONIC_PMULDQ = 454, + QX86_MNEMONIC_PMULHRSW = 455, + QX86_MNEMONIC_PMULHRW = 456, + QX86_MNEMONIC_PMULHUW = 457, + QX86_MNEMONIC_PMULHW = 458, + QX86_MNEMONIC_PMULLD = 459, + QX86_MNEMONIC_PMULLW = 460, + QX86_MNEMONIC_PMULUDQ = 461, + QX86_MNEMONIC_POP = 462, + QX86_MNEMONIC_POPA = 463, + QX86_MNEMONIC_POPAD = 464, + QX86_MNEMONIC_POPCNT = 465, + QX86_MNEMONIC_POPF = 466, + QX86_MNEMONIC_POPFD = 467, + QX86_MNEMONIC_POPFQ = 468, + QX86_MNEMONIC_POR = 469, + QX86_MNEMONIC_PREFETCH = 470, + QX86_MNEMONIC_PREFETCHNTA = 471, + QX86_MNEMONIC_PREFETCHT0 = 472, + QX86_MNEMONIC_PREFETCHT1 = 473, + QX86_MNEMONIC_PREFETCHT2 = 474, + QX86_MNEMONIC_PREFETCHW = 475, + QX86_MNEMONIC_PSADBW = 476, + QX86_MNEMONIC_PSHUFB = 477, + QX86_MNEMONIC_PSHUFD = 478, + QX86_MNEMONIC_PSHUFHW = 479, + QX86_MNEMONIC_PSHUFLW = 480, + QX86_MNEMONIC_PSHUFW = 481, + QX86_MNEMONIC_PSIGNB = 482, + QX86_MNEMONIC_PSIGND = 483, + QX86_MNEMONIC_PSIGNW = 484, + QX86_MNEMONIC_PSLLD = 485, + QX86_MNEMONIC_PSLLDQ = 486, + QX86_MNEMONIC_PSLLQ = 487, + QX86_MNEMONIC_PSLLW = 488, + QX86_MNEMONIC_PSRAD = 489, + QX86_MNEMONIC_PSRAW = 490, + QX86_MNEMONIC_PSRLD = 491, + QX86_MNEMONIC_PSRLDQ = 492, + QX86_MNEMONIC_PSRLQ = 493, + QX86_MNEMONIC_PSRLW = 494, + QX86_MNEMONIC_PSUBB = 495, + QX86_MNEMONIC_PSUBD = 496, + QX86_MNEMONIC_PSUBQ = 497, + QX86_MNEMONIC_PSUBSB = 498, + QX86_MNEMONIC_PSUBSW = 499, + QX86_MNEMONIC_PSUBUSB = 500, + QX86_MNEMONIC_PSUBUSW = 501, + QX86_MNEMONIC_PSUBW = 502, + QX86_MNEMONIC_PSWAPD = 503, + QX86_MNEMONIC_PTEST = 504, + QX86_MNEMONIC_PUNPCKHBW = 505, + QX86_MNEMONIC_PUNPCKHDQ = 506, + QX86_MNEMONIC_PUNPCKHQDQ = 507, + QX86_MNEMONIC_PUNPCKHWD = 508, + QX86_MNEMONIC_PUNPCKLBW = 509, + QX86_MNEMONIC_PUNPCKLDQ = 510, + QX86_MNEMONIC_PUNPCKLQDQ = 511, + QX86_MNEMONIC_PUNPCKLWD = 512, + QX86_MNEMONIC_PUSH = 513, + QX86_MNEMONIC_PUSHA = 514, + QX86_MNEMONIC_PUSHAD = 515, + QX86_MNEMONIC_PUSHF = 516, + QX86_MNEMONIC_PUSHFD = 517, + QX86_MNEMONIC_PUSHFQ = 518, + QX86_MNEMONIC_PXOR = 519, + QX86_MNEMONIC_RCL = 520, + QX86_MNEMONIC_RCPPS = 521, + QX86_MNEMONIC_RCPSS = 522, + QX86_MNEMONIC_RCR = 523, + QX86_MNEMONIC_RDMSR = 524, + QX86_MNEMONIC_RDPMC = 525, + QX86_MNEMONIC_RDTSC = 526, + QX86_MNEMONIC_RDTSCP = 527, + QX86_MNEMONIC_RET = 528, + QX86_MNEMONIC_RETF = 529, + QX86_MNEMONIC_ROL = 530, + QX86_MNEMONIC_ROR = 531, + QX86_MNEMONIC_ROUNDPD = 532, + QX86_MNEMONIC_ROUNDPS = 533, + QX86_MNEMONIC_ROUNDSD = 534, + QX86_MNEMONIC_ROUNDSS = 535, + QX86_MNEMONIC_RSM = 536, + QX86_MNEMONIC_RSQRTPS = 537, + QX86_MNEMONIC_RSQRTSS = 538, + QX86_MNEMONIC_SAHF = 539, + QX86_MNEMONIC_SALC = 540, + QX86_MNEMONIC_SAR = 541, + QX86_MNEMONIC_SBB = 542, + QX86_MNEMONIC_SCASB = 543, + QX86_MNEMONIC_SCASD = 544, + QX86_MNEMONIC_SCASQ = 545, + QX86_MNEMONIC_SCASW = 546, + QX86_MNEMONIC_SETA = 547, + QX86_MNEMONIC_SETAE = 548, + QX86_MNEMONIC_SETB = 549, + QX86_MNEMONIC_SETBE = 550, + QX86_MNEMONIC_SETG = 551, + QX86_MNEMONIC_SETGE = 552, + QX86_MNEMONIC_SETL = 553, + QX86_MNEMONIC_SETLE = 554, + QX86_MNEMONIC_SETNO = 555, + QX86_MNEMONIC_SETNP = 556, + QX86_MNEMONIC_SETNS = 557, + QX86_MNEMONIC_SETNZ = 558, + QX86_MNEMONIC_SETO = 559, + QX86_MNEMONIC_SETP = 560, + QX86_MNEMONIC_SETS = 561, + QX86_MNEMONIC_SETZ = 562, + QX86_MNEMONIC_SFENCE = 563, + QX86_MNEMONIC_SGDT = 564, + QX86_MNEMONIC_SHL = 565, + QX86_MNEMONIC_SHLD = 566, + QX86_MNEMONIC_SHR = 567, + QX86_MNEMONIC_SHRD = 568, + QX86_MNEMONIC_SHUFPD = 569, + QX86_MNEMONIC_SHUFPS = 570, + QX86_MNEMONIC_SIDT = 571, + QX86_MNEMONIC_SKINIT = 572, + QX86_MNEMONIC_SLDT = 573, + QX86_MNEMONIC_SMSW = 574, + QX86_MNEMONIC_SQRTPD = 575, + QX86_MNEMONIC_SQRTPS = 576, + QX86_MNEMONIC_SQRTSD = 577, + QX86_MNEMONIC_SQRTSS = 578, + QX86_MNEMONIC_STC = 579, + QX86_MNEMONIC_STD = 580, + QX86_MNEMONIC_STGI = 581, + QX86_MNEMONIC_STI = 582, + QX86_MNEMONIC_STMXCSR = 583, + QX86_MNEMONIC_STOSB = 584, + QX86_MNEMONIC_STOSD = 585, + QX86_MNEMONIC_STOSQ = 586, + QX86_MNEMONIC_STOSW = 587, + QX86_MNEMONIC_STR = 588, + QX86_MNEMONIC_SUB = 589, + QX86_MNEMONIC_SUBPD = 590, + QX86_MNEMONIC_SUBPS = 591, + QX86_MNEMONIC_SUBSD = 592, + QX86_MNEMONIC_SUBSS = 593, + QX86_MNEMONIC_SWAPGS = 594, + QX86_MNEMONIC_SYSCALL = 595, + QX86_MNEMONIC_SYSENTER = 596, + QX86_MNEMONIC_SYSEXIT = 597, + QX86_MNEMONIC_SYSRET = 598, + QX86_MNEMONIC_TEST = 599, + QX86_MNEMONIC_UCOMISD = 600, + QX86_MNEMONIC_UCOMISS = 601, + QX86_MNEMONIC_UD2 = 602, + QX86_MNEMONIC_UNPCKHPD = 603, + QX86_MNEMONIC_UNPCKHPS = 604, + QX86_MNEMONIC_UNPCKLPD = 605, + QX86_MNEMONIC_UNPCKLPS = 606, + QX86_MNEMONIC_VERR = 607, + QX86_MNEMONIC_VERW = 608, + QX86_MNEMONIC_VMCALL = 609, + QX86_MNEMONIC_VMCLEAR = 610, + QX86_MNEMONIC_VMLAUNCH = 611, + QX86_MNEMONIC_VMLOAD = 612, + QX86_MNEMONIC_VMMCALL = 613, + QX86_MNEMONIC_VMPTRLD = 614, + QX86_MNEMONIC_VMPTRST = 615, + QX86_MNEMONIC_VMREAD = 616, + QX86_MNEMONIC_VMRESUME = 617, + QX86_MNEMONIC_VMRUN = 618, + QX86_MNEMONIC_VMSAVE = 619, + QX86_MNEMONIC_VMWRITE = 620, + QX86_MNEMONIC_VMXOFF = 621, + QX86_MNEMONIC_VMXON = 622, + QX86_MNEMONIC_WBINVD = 623, + QX86_MNEMONIC_WRMSR = 624, + QX86_MNEMONIC_XADD = 625, + QX86_MNEMONIC_XCHG = 626, + QX86_MNEMONIC_XGETBV = 627, + QX86_MNEMONIC_XLAT = 628, + QX86_MNEMONIC_XOR = 629, + QX86_MNEMONIC_XORPD = 630, + QX86_MNEMONIC_XORPS = 631, + QX86_MNEMONIC_XRSTOR = 632, + QX86_MNEMONIC_XSAVE = 633, + QX86_MNEMONIC_XSETBV = 634, + + QX86_MNEMONIC_COUNT = 635 +}; + + +/** + * Enumeration of mnemonic attributes. + * + * \author icee + * \since 1.0 + */ +enum +{ + QX86_MATTRIBUTE_NONE = 0, + QX86_MATTRIBUTE_REP = 1 << 0, + QX86_MATTRIBUTE_REPZ = 1 << 1, + QX86_MATTRIBUTE_DEFAULT_SIZE_64 = 1 << 2, + QX86_MATTRIBUTE_FIXED_SIZE_64 = 1 << 3, + QX86_MATTRIBUTE_INTERLOCKABLE = 1 << 4, + QX86_MATTRIBUTE_IMPLICIT_LOCK = 1 << 5 +}; + + + +/** + * Enumeration of ModRM fields. + * + * \author icee + * \since 1.0 + */ +enum +{ + QX86_MODRM_FIELD_NONE = 0, + + QX86_MODRM_FIELD_MOD = 1 << 0, + QX86_MODRM_FIELD_REG = 1 << 2, + QX86_MODRM_FIELD_RM = 1 << 3 +}; + + + +/** + * Enumeration of x86 opcode escapes. + * + * \author icee + * \since 1.0 + */ +enum +{ + QX86_OPCODE_ESCAPE_NONE = 0, + + QX86_OPCODE_ESCAPE_0F = 1, + QX86_OPCODE_ESCAPE_0F_38 = 2, + QX86_OPCODE_ESCAPE_0F_3A = 3, + + QX86_OPCODE_ESCAPE_COUNT = 4 +}; + + + +/** + * Enumeration of opcode map indexes. + * + * \author icee + * \since 1.0 + */ +enum +{ + QX86_OPCODE_MAP_INDEX_NONE = 0, + + QX86_OPCODE_MAP_INDEX_NB = 1, + QX86_OPCODE_MAP_INDEX_PB = 2, + + QX86_OPCODE_MAP_INDEX_AS = 3, + QX86_OPCODE_MAP_INDEX_CS = 4, + QX86_OPCODE_MAP_INDEX_OS = 5, + + QX86_OPCODE_MAP_INDEX_SP = 6, + + QX86_OPCODE_MAP_INDEX_MOD = 7, + QX86_OPCODE_MAP_INDEX_REG = 8, + QX86_OPCODE_MAP_INDEX_RM = 9, + + QX86_OPCODE_MAP_INDEX_COUNT = 10 +}; + + + +/** + * Enumeration of opcode map item codes. + * + * \author icee + * \since 1.0 + */ +enum +{ + QX86_OPCODE_MAP_ITEM_CODE_NONE = -0, + QX86_OPCODE_MAP_ITEM_CODE_LINK = -1, + QX86_OPCODE_MAP_ITEM_CODE_PREFIX = -2 +}; + + + +/** + * Enumeration of x86 operand attributes. + * + * \author icee + * \since 1.0 + */ +enum +{ + QX86_OPERAND_ATTRIBUTE_NONE = 0, + + QX86_OPERAND_ATTRIBUTE_READ = 1, + QX86_OPERAND_ATTRIBUTE_WRITTEN = 2, + QX86_OPERAND_ATTRIBUTE_READWRITTEN = 3, + + QX86_OPERAND_ATTRIBUTE_RW_CERTAIN = 4 +}; + + + +/** + * Enumeration of x86 operand form types. + * + * \author icee + * \since 1.0 + */ +enum +{ + QX86_OPERAND_FORM_TYPE_NONE = 0, + + QX86_OPERAND_FORM_TYPE_AMODE = 1, + QX86_OPERAND_FORM_TYPE_IMPLICIT_1 = 2, + QX86_OPERAND_FORM_TYPE_RTUPLE = 3, + + QX86_OPERAND_FORM_COUNT = 4 +}; + + + +/** + * Enumeration of x86 operand types. + * + * \author icee + * \since 1.0 + */ +enum +{ + QX86_OPERAND_TYPE_NONE = 0, + + QX86_OPERAND_TYPE_FAR_POINTER = 1, + QX86_OPERAND_TYPE_IMMEDIATE = 2, + QX86_OPERAND_TYPE_JUMP_OFFSET = 3, + QX86_OPERAND_TYPE_MEMORY = 4, + QX86_OPERAND_TYPE_REGISTER = 5, + + QX86_OPERAND_TYPE_COUNT = 6 +}; + + + +/** + * Enumeration of x86 register classes. + * + * \author icee + * \since 1.0 + */ +enum +{ + QX86_RCLASS_NONE = 0, + QX86_RCLASS_IP = 1, + QX86_RCLASS_FLAGS = 2, + QX86_RCLASS_RESERVED_3 = 3, + + QX86_RCLASS_REG8 = 4, + QX86_RCLASS_REG16 = 5, + QX86_RCLASS_REG32 = 6, + QX86_RCLASS_REG64 = 7, + + QX86_RCLASS_CREG = 8, + QX86_RCLASS_DREG = 9, + QX86_RCLASS_SREG = 10, + QX86_RCLASS_RESERVED_11 = 11, + + QX86_RCLASS_X87 = 12, + QX86_RCLASS_MMX = 13, + QX86_RCLASS_XMM = 14, + QX86_RCLASS_YMM = 15, + + QX86_RCLASS_COUNT = 16 +}; + + + +/** + * Enumeration of x86 registers. + * + * \author icee + * \since 1.0 + */ +enum +{ + QX86_REGISTER_NONE = 0, + QX86_REGISTER_INVALID = 1, + QX86_REGISTER_SPECIAL = 2, + QX86_REGISTER_RESERVED_3 = 3, + + QX86_REGISTER_RESERVED_4 = 4, + QX86_REGISTER_IP = 5, + QX86_REGISTER_EIP = 6, + QX86_REGISTER_RIP = 7, + + QX86_REGISTER_RESERVED_8 = 8, + QX86_REGISTER_FLAGS = 9, + QX86_REGISTER_EFLAGS = 10, + QX86_REGISTER_RFLAGS = 11, + + QX86_REGISTER_AH = 12, + QX86_REGISTER_CH = 13, + QX86_REGISTER_DH = 14, + QX86_REGISTER_BH = 15, + + QX86_REGISTER_AL = 16, + QX86_REGISTER_CL = 17, + QX86_REGISTER_DL = 18, + QX86_REGISTER_BL = 19, + QX86_REGISTER_SPL = 20, + QX86_REGISTER_BPL = 21, + QX86_REGISTER_SIL = 22, + QX86_REGISTER_DIL = 23, + QX86_REGISTER_R8B = 24, + QX86_REGISTER_R9B = 25, + QX86_REGISTER_R10B = 26, + QX86_REGISTER_R11B = 27, + QX86_REGISTER_R12B = 28, + QX86_REGISTER_R13B = 29, + QX86_REGISTER_R14B = 30, + QX86_REGISTER_R15B = 31, + + QX86_REGISTER_AX = 32, + QX86_REGISTER_CX = 33, + QX86_REGISTER_DX = 34, + QX86_REGISTER_BX = 35, + QX86_REGISTER_SP = 36, + QX86_REGISTER_BP = 37, + QX86_REGISTER_SI = 38, + QX86_REGISTER_DI = 39, + QX86_REGISTER_R8W = 40, + QX86_REGISTER_R9W = 41, + QX86_REGISTER_R10W = 42, + QX86_REGISTER_R11W = 43, + QX86_REGISTER_R12W = 44, + QX86_REGISTER_R13W = 45, + QX86_REGISTER_R14W = 46, + QX86_REGISTER_R15W = 47, + + QX86_REGISTER_EAX = 48, + QX86_REGISTER_ECX = 49, + QX86_REGISTER_EDX = 50, + QX86_REGISTER_EBX = 51, + QX86_REGISTER_ESP = 52, + QX86_REGISTER_EBP = 53, + QX86_REGISTER_ESI = 54, + QX86_REGISTER_EDI = 55, + QX86_REGISTER_R8D = 56, + QX86_REGISTER_R9D = 57, + QX86_REGISTER_R10D = 58, + QX86_REGISTER_R11D = 59, + QX86_REGISTER_R12D = 60, + QX86_REGISTER_R13D = 61, + QX86_REGISTER_R14D = 62, + QX86_REGISTER_R15D = 63, + + QX86_REGISTER_RAX = 64, + QX86_REGISTER_RCX = 65, + QX86_REGISTER_RDX = 66, + QX86_REGISTER_RBX = 67, + QX86_REGISTER_RSP = 68, + QX86_REGISTER_RBP = 69, + QX86_REGISTER_RSI = 70, + QX86_REGISTER_RDI = 71, + QX86_REGISTER_R8 = 72, + QX86_REGISTER_R9 = 73, + QX86_REGISTER_R10 = 74, + QX86_REGISTER_R11 = 75, + QX86_REGISTER_R12 = 76, + QX86_REGISTER_R13 = 77, + QX86_REGISTER_R14 = 78, + QX86_REGISTER_R15 = 79, + + QX86_REGISTER_CR0 = 80, + QX86_REGISTER_CR1 = 81, + QX86_REGISTER_CR2 = 82, + QX86_REGISTER_CR3 = 83, + QX86_REGISTER_CR4 = 84, + QX86_REGISTER_CR5 = 85, + QX86_REGISTER_CR6 = 86, + QX86_REGISTER_CR7 = 87, + QX86_REGISTER_CR8 = 88, + QX86_REGISTER_CR9 = 89, + QX86_REGISTER_CR10 = 90, + QX86_REGISTER_CR11 = 91, + QX86_REGISTER_CR12 = 92, + QX86_REGISTER_CR13 = 93, + QX86_REGISTER_CR14 = 94, + QX86_REGISTER_CR15 = 95, + + QX86_REGISTER_DR0 = 96, + QX86_REGISTER_DR1 = 97, + QX86_REGISTER_DR2 = 98, + QX86_REGISTER_DR3 = 99, + QX86_REGISTER_DR4 = 100, + QX86_REGISTER_DR5 = 101, + QX86_REGISTER_DR6 = 102, + QX86_REGISTER_DR7 = 103, + QX86_REGISTER_DR8 = 104, + QX86_REGISTER_DR9 = 105, + QX86_REGISTER_DR10 = 106, + QX86_REGISTER_DR11 = 107, + QX86_REGISTER_DR12 = 108, + QX86_REGISTER_DR13 = 109, + QX86_REGISTER_DR14 = 110, + QX86_REGISTER_DR15 = 111, + + QX86_REGISTER_ES = 112, + QX86_REGISTER_CS = 113, + QX86_REGISTER_SS = 114, + QX86_REGISTER_DS = 115, + QX86_REGISTER_FS = 116, + QX86_REGISTER_GS = 117, + QX86_REGISTER_SR6 = 118, + QX86_REGISTER_SR7 = 119, + + QX86_REGISTER_ST0 = 120, + QX86_REGISTER_ST1 = 121, + QX86_REGISTER_ST2 = 122, + QX86_REGISTER_ST3 = 123, + QX86_REGISTER_ST4 = 124, + QX86_REGISTER_ST5 = 125, + QX86_REGISTER_ST6 = 126, + QX86_REGISTER_ST7 = 127, + + QX86_REGISTER_FPR0 = 128, + QX86_REGISTER_FPR1 = 129, + QX86_REGISTER_FPR2 = 130, + QX86_REGISTER_FPR3 = 131, + QX86_REGISTER_FPR4 = 132, + QX86_REGISTER_FPR5 = 133, + QX86_REGISTER_FPR6 = 134, + QX86_REGISTER_FPR7 = 135, + + QX86_REGISTER_MMX0 = 136, + QX86_REGISTER_MMX1 = 137, + QX86_REGISTER_MMX2 = 138, + QX86_REGISTER_MMX3 = 139, + QX86_REGISTER_MMX4 = 140, + QX86_REGISTER_MMX5 = 141, + QX86_REGISTER_MMX6 = 142, + QX86_REGISTER_MMX7 = 143, + + QX86_REGISTER_XMM0 = 144, + QX86_REGISTER_XMM1 = 145, + QX86_REGISTER_XMM2 = 146, + QX86_REGISTER_XMM3 = 147, + QX86_REGISTER_XMM4 = 148, + QX86_REGISTER_XMM5 = 149, + QX86_REGISTER_XMM6 = 150, + QX86_REGISTER_XMM7 = 151, + QX86_REGISTER_XMM8 = 152, + QX86_REGISTER_XMM9 = 153, + QX86_REGISTER_XMM10 = 154, + QX86_REGISTER_XMM11 = 155, + QX86_REGISTER_XMM12 = 156, + QX86_REGISTER_XMM13 = 157, + QX86_REGISTER_XMM14 = 158, + QX86_REGISTER_XMM15 = 159, + + QX86_REGISTER_YMM0 = 160, + QX86_REGISTER_YMM1 = 161, + QX86_REGISTER_YMM2 = 162, + QX86_REGISTER_YMM3 = 163, + QX86_REGISTER_YMM4 = 164, + QX86_REGISTER_YMM5 = 165, + QX86_REGISTER_YMM6 = 166, + QX86_REGISTER_YMM7 = 167, + QX86_REGISTER_YMM8 = 168, + QX86_REGISTER_YMM9 = 169, + QX86_REGISTER_YMM10 = 170, + QX86_REGISTER_YMM11 = 171, + QX86_REGISTER_YMM12 = 172, + QX86_REGISTER_YMM13 = 173, + QX86_REGISTER_YMM14 = 174, + QX86_REGISTER_YMM15 = 175, + + QX86_REGISTER_COUNT = 176 +}; + + + +/** + * Enumeration of ModRM and SIB scale values. + * + * \author icee + * \since 1.0 + */ +enum +{ + QX86_SCALE_NONE = 0, + QX86_SCALE_X2 = 1, + QX86_SCALE_X4 = 2, + QX86_SCALE_X8 = 3, + QX86_SCALE_INVALID = 4 +}; + + + +/** + * Enumeration of x86 code, address, operand, and stack sizes. + * + * \author icee + * \since 1.0 + */ +enum +{ + QX86_SIZE_16 = 0, + QX86_SIZE_32 = 1, + QX86_SIZE_64 = 2, + QX86_SIZE_INVALID = 3, + QX86_SIZE_MASK = 3 +}; + + + +/** + * Enumeration of x86 subregisters. + * + * \author icee + * \since 1.0 + */ +enum +{ + QX86_SUBREG_NONE = 0, + + QX86_SUBREG_BASE = 1, + QX86_SUBREG_LIMIT = 2, + QX86_SUBREG_FLAGS = 3, + + QX86_SUBREG_COUNT = 4 +}; + + +/* Public API structures. */ + + +/** + * Addressing mode definition structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_amode +{ + QX86_CONST char * referenceName; + QX86_CONST char * name; + + qx86_uint8 modrmField; + qx86_uint8 rclass; + + int (*decodeFunc)(qx86_insn *, int); +}; + + + +/** + * Callback function definition. + * + * \author icee + * \since 1.0 + */ +typedef int (*qx86_callback)(void *data, int rindex, int subreg, unsigned char *value); + + + +/** + * Decode context structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_ctx +{ + qx86_uint8 * ptr; + int ptrSize; + + int pumpIndex; +}; + + + + + +/** + * Instruction attributes definition structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_insn_attributes +{ + qx86_uint8 addressSize; + qx86_uint8 addressSizeOverridden; + + qx86_uint8 operandSize; + qx86_uint8 operandSizeOverridden; + + qx86_uint8 interlocked; +}; + + + +/** + * Instruction modifiers definition structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_insn_modifiers +{ + qx86_uint8 modrm; + qx86_int8 modrmIndex; + + qx86_uint8 sib; + qx86_int8 sibIndex; + + qx86_uint8 rex; + qx86_int8 rexIndex; + + qx86_uint8 prefixSize; + + qx86_uint8 escape; + qx86_uint8 opcodePrefix; + + /* XXX: values 0x00, 0xF2, 0xF3. */ + qx86_uint8 repeatPrefix; + + int sriOverride; + + qx86_uint8 extendedB; + qx86_uint8 extendedR; + qx86_uint8 extendedX; +}; + + + + + + + +/** + * Far pointer instruction operand definition structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_operand_far_pointer +{ + qx86_uint8 offset[QX86_IMMEDIATE_SIZE_MAX]; + qx86_uint8 offsetSize; + + qx86_uint8 selector[2]; +}; + + + +/** + * Immediate instruction operand definition structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_operand_immediate +{ + qx86_uint8 value[QX86_IMMEDIATE_SIZE_MAX]; + qx86_uint8 valueSize; +}; + + + +/** + * Jump offset instruction operand definition structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_operand_jump_offset +{ + qx86_uint8 offset[QX86_IMMEDIATE_SIZE_MAX]; + qx86_uint8 offsetSize; +}; + + + +/** + * Memory instruction operand definition structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_operand_memory +{ + int sri; + int bri; + int iri; + + int scale; + + qx86_uint8 disp[QX86_IMMEDIATE_SIZE_MAX]; + qx86_uint8 dispSize; +}; + + + +/** + * Register instruction operand definition structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_operand_register +{ + int rindex; +}; + + +/** + * Instruction operand definition union. + * + * \author icee + * \since 1.0 + */ +union qx86_operand_union +{ + qx86_operand_far_pointer f; + qx86_operand_immediate i; + qx86_operand_jump_offset j; + qx86_operand_memory m; + qx86_operand_register r; +}; + + +/** + * Instruction operand definition structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_operand +{ + qx86_uint8 ot; + + int attributes; + int size; + + qx86_operand_union u; +}; + + +/** + * Instruction definition structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_insn +{ + qx86_uint8 rawSize; + qx86_uint8 raw[QX86_INSN_SIZE_MAX]; + + int processorMode; + + int mnemonic; + qx86_int8 operandCount; + + qx86_operand operands[QX86_OPERAND_NMAX]; + qx86_operand_form * operandForms[QX86_OPERAND_NMAX]; + + qx86_insn_attributes attributes; + qx86_insn_modifiers modifiers; + + qx86_uint8 iclass; + qx86_uint8 defects; + + qx86_callback callback; + void * data; +}; + + + +/** + * Mnemonic table item definition structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_mtab_item +{ + QX86_CONST char * referenceName; + QX86_CONST char * name; + + qx86_uint8 attributes; + qx86_uint8 iclass; + + int demoted; + int promoted; + + // TODO: AT&T print. +}; + + + +/** + * Opcode map definition structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_opcode_map +{ + qx86_uint8 index; + qx86_uint8 limit; + + qx86_opcode_map_item * items; +}; + + + + + + + + + +/** + * Addressing mode instruction operand form definition structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_operand_form_amode +{ + qx86_amode * amode; + qx86_stuple * stuple; +}; + + + +/** + * Register tuple instruction operand form definition structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_operand_form_rtuple +{ + qx86_rtuple * rtuple; +}; + + +/** + * Instruction operand form definition union. + * + * \author icee + * \since 1.0 + */ +union qx86_operand_form_union +{ + QX86_CONST void * initializer[2]; + + qx86_operand_form_amode a; + qx86_operand_form_rtuple r; +}; + + +/** + * Instruction operand form definition structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_operand_form +{ + int ft; + int attributes; + qx86_operand_form_union u; +}; + + +/** + * Opcode map item definition structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_opcode_map_item +{ + int code; + qx86_opcode_map * link; + + int operandCount; + qx86_operand_form operandForms[QX86_OPERAND_NMAX]; +}; + + + +/** + * Print item definition structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_print_item +{ + QX86_CONST qx86_uint8 * number; + int numberSize; + + QX86_CONST char * string; +}; + + + +/** + * Intel print options structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_print_options_intel +{ + int flipCase : 1; +}; + + + +/** + * Register table item definition structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_rtab_item +{ + QX86_CONST char * referenceName; + QX86_CONST char * name; + + qx86_uint8 rclass; + qx86_uint8 size; +}; + + + +/** + * Register tuple definition structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_rtuple +{ + QX86_CONST char * referenceName; + QX86_CONST char * name; + + int rindexes[12]; +}; + + + +/** + * Size tuple definition structure. + * + * \author icee + * \since 1.0 + */ +struct qx86_stuple +{ + QX86_CONST char * referenceName; + QX86_CONST char * name; + + QX86_CONST char * atoms[4]; + int sizes[4]; +}; + + +/** + * Extract the mod ModRM field value. + * + * \param modrm + * ModRM octet value. + * + * \return ModRM mod field value. + * + * \author icee + * \since 1.0 + */ +#define QX86_MODRM_MOD(modrm) ((qx86_uint8) ((modrm) >> 6)) + +/** + * Extract the reg ModRM field value. + * + * \param modrm + * ModRM octet value. + * + * \return ModRM reg field value. + * + * \author icee + * \since 1.0 + */ +#define QX86_MODRM_REG(modrm) ((qx86_uint8) (((modrm) >> 3) & 7)) + +/** + * Extract the r/m ModRM field value. + * + * \param modrm + * ModRM octet value. + * + * \return ModRM rm field value. + * + * \author icee + * \since 1.0 + */ +#define QX86_MODRM_RM(modrm) ((qx86_uint8) ((modrm) & 7)) + +/** + * Extract the b REX field value. + * + * \param rex + * REX octet value. + * + * \return REX b field value. + * + * \author icee + * \since 1.0 + */ +#define QX86_REX_B(rex) ((qx86_uint8) (0 != ((rex) & 1))) + +/** + * Extract the r REX field value. + * + * \param rex + * REX octet value. + * + * \return REX r field value. + * + * \author icee + * \since 1.0 + */ +#define QX86_REX_R(rex) ((qx86_uint8) (0 != ((rex) & 4))) + +/** + * Extract the w REX field value. + * + * \param rex + * REX octet value. + * + * \return REX w field value. + * + * \author icee + * \since 1.0 + */ +#define QX86_REX_W(rex) ((qx86_uint8) (0 != ((rex) & 8))) + +/** + * Extract the x REX field value. + * + * \param rex + * REX octet value. + * + * \return REX x field value. + * + * \author icee + * \since 1.0 + */ +#define QX86_REX_X(rex) ((qx86_uint8) (0 != ((rex) & 2))) + +/** + * Extract the base SIB field value. + * + * \param sib + * SIB octet value. + * + * \return SIB base field value. + * + * \author icee + * \since 1.0 + */ +#define QX86_SIB_BASE(sib) ((qx86_uint8) ((sib) & 7)) + +/** + * Extract the index SIB field value. + * + * \param sib + * SIB octet value. + * + * \return SIB index field value. + * + * \author icee + * \since 1.0 + */ +#define QX86_SIB_INDEX(sib) ((qx86_uint8) (((sib) >> 3) & 7)) + +/** + * Extract the scale SIB field value. + * + * \param sib + * SIB octet value. + * + * \return SIB scale field value. + * + * \author icee + * \since 1.0 + */ +#define QX86_SIB_SCALE(sib) ((qx86_uint8) ((sib) >> 6)) + +/** + * Convert a #qx86_size enumerator to number of octets. The \a size value must + * be valid. + * + * \param size + * A #qx86_size enumerator. + * + * \return Number of octets. + * + * \author icee + * \since 1.0 + */ +#define QX86_SIZE_OCTETS(size) (2 << (size)) + +/* XXX XXX XXX */ +extern QX86_CONST qx86_mtab_item qx86_mtab[QX86_MNEMONIC_COUNT]; +extern QX86_CONST qx86_rtab_item qx86_rtab[QX86_REGISTER_COUNT]; + +/** + * Calculate effective address of an x86 memory operand. + * + * TODO: documentation. + * + * \author icee + * \since 1.0 + */ +QX86_EXTERN_C int +qx86_calculate_effective_address(QX86_CONST qx86_insn *insn, int operandIndex, qx86_uint64 *address); + +/** + * Calculate linear address of an x86 memory operand. + * + * TODO: documentation. + * + * \author icee + * \since 1.0 + */ +QX86_EXTERN_C int +qx86_calculate_linear_address(QX86_CONST qx86_insn *insn, int operandIndex, qx86_uint64 *address); + +/** + * Decode an x86 instruction. + * + * TODO: documentation. + * + * \author icee + * \since 1.0 + */ +QX86_EXTERN_C int +qx86_decode(qx86_insn *insn, int processorMode, QX86_CONST void *ptr, int ptrSize); + +/** + * Print a decoded x86 instruction using the Intel format. + * + * TODO: documentation. + * + * \param insn + * Instruction to print. + * \param options + * Printer options. + * \param[out] buffer + * Pre-allocated buffer to print to. + * \param[in,out] bufferSize + * TODO. + * + * \return TODO. + * + * \author icee + * \since 1.0 + */ +QX86_EXTERN_C int +qx86_print_intel(QX86_CONST qx86_insn *insn, QX86_CONST qx86_print_options_intel *options, char *buffer, int *bufferSize); + +#endif diff --git a/palacios/lib/i386/Makefile b/palacios/lib/i386/Makefile index 2579781..1f9fb68 100644 --- a/palacios/lib/i386/Makefile +++ b/palacios/lib/i386/Makefile @@ -1,4 +1,8 @@ obj-y := null.o obj-$(V3_CONFIG_XED) := libxed.a \ - v3-xed-compat.o + v3-xed-compat.o + +obj-$(V3_CONFIG_QUIX86) := libquix86.a + +obj-$(V3_CONFIG_QUIX86_DEBUG) := libquix86_debug.a diff --git a/palacios/lib/i386/libquix86.a b/palacios/lib/i386/libquix86.a new file mode 100644 index 0000000..f5e0b2d Binary files /dev/null and b/palacios/lib/i386/libquix86.a differ diff --git a/palacios/lib/i386/libquix86_debug.a b/palacios/lib/i386/libquix86_debug.a new file mode 100644 index 0000000..0aa7b1e Binary files /dev/null and b/palacios/lib/i386/libquix86_debug.a differ diff --git a/palacios/lib/x86_64/Makefile b/palacios/lib/x86_64/Makefile index 8853e97..84ddcc5 100644 --- a/palacios/lib/x86_64/Makefile +++ b/palacios/lib/x86_64/Makefile @@ -2,3 +2,7 @@ obj-y := null.o obj-$(V3_CONFIG_XED) := libxed32e.a \ v3-xed-compat.o + +obj-$(V3_CONFIG_QUIX86) := libquix86.a + +obj-$(V3_CONFIG_QUIX86_DEBUG) := libquix86_debug.a diff --git a/palacios/lib/x86_64/libquix86.a b/palacios/lib/x86_64/libquix86.a new file mode 100644 index 0000000..441db57 Binary files /dev/null and b/palacios/lib/x86_64/libquix86.a differ diff --git a/palacios/lib/x86_64/libquix86_debug.a b/palacios/lib/x86_64/libquix86_debug.a new file mode 100644 index 0000000..6dfa9b5 Binary files /dev/null and b/palacios/lib/x86_64/libquix86_debug.a differ diff --git a/palacios/src/palacios/Makefile b/palacios/src/palacios/Makefile index 14a1c29..af67c65 100644 --- a/palacios/src/palacios/Makefile +++ b/palacios/src/palacios/Makefile @@ -41,6 +41,9 @@ obj-y := \ obj-$(V3_CONFIG_XED) += vmm_xed.o obj-$(V3_CONFIG_V3_DECODER) += vmm_v3dec.o +obj-$(V3_CONFIG_QUIX86) += vmm_quix86.o +obj-$(V3_CONFIG_QUIX86_DEBUG) += vmm_quix86.o + obj-$(V3_CONFIG_SVM) += svm.o \ svm_io.o \ diff --git a/palacios/src/palacios/vmm_quix86.c b/palacios/src/palacios/vmm_quix86.c new file mode 100644 index 0000000..fd64626 --- /dev/null +++ b/palacios/src/palacios/vmm_quix86.c @@ -0,0 +1,930 @@ +/* + * 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) 2011, Jack Lange + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Alexander Kudryavtsev + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifndef V3_CONFIG_DEBUG_DECODER +#undef PrintDebug +#define PrintDebug(fmt, args...) +#endif + +#define GPR_REGISTER 0 +#define SEGMENT_REGISTER 1 +#define CTRL_REGISTER 2 +#define DEBUG_REGISTER 3 + +// QUIX86 does not have to be initialised or deinitialised. +int v3_init_decoder(struct guest_info * core) { + return 0; +} +int v3_deinit_decoder(struct guest_info * core) { + return 0; +} + +static int get_opcode(qx86_insn *inst); +static int qx86_register_to_v3_reg(struct guest_info * info, int qx86_reg, + addr_t * v3_reg, uint_t * reg_len); + +static int decode_string_op(struct guest_info * info, + const qx86_insn * qx86_inst, struct x86_instr * instr) +{ + int status = 0; + PrintDebug("String operation\n"); + + if (instr->prefixes.rep == 1) { + uint64_t a_mask = ~(~0ULL << + (QX86_SIZE_OCTETS(qx86_inst->attributes.addressSize) * 8)); + + instr->str_op_length = info->vm_regs.rcx & a_mask; + } else { + instr->str_op_length = 1; + } + + + if (instr->op_type == V3_OP_MOVS) { + instr->num_operands = 2; + + if((status = qx86_calculate_linear_address(qx86_inst, 0, + (qx86_uint64*)&instr->dst_operand.operand)) != QX86_SUCCESS) { + PrintError("Could not get destination memory operand: " + "qx86_calculate_linear_address: %d\n", status); + return -1; + } + + if((status = qx86_calculate_linear_address(qx86_inst, 1, + (qx86_uint64*)&instr->src_operand.operand)) != QX86_SUCCESS) { + PrintError("Could not get source memory operand: " + "qx86_calculate_linear_address: %d\n", status); + return -1; + } + + instr->dst_operand.write = 1; + instr->src_operand.read = 1; + + } else if (instr->op_type == V3_OP_STOS) { + instr->num_operands = 2; + + if((status = qx86_calculate_linear_address(qx86_inst, 0, + (qx86_uint64*)&instr->dst_operand.operand)) != QX86_SUCCESS) { + PrintError("Could not get destination memory operand: " + "qx86_calculate_linear_address: %d\n", status); + return -1; + } + + // STOS reads from rax + qx86_register_to_v3_reg(info, + qx86_inst->operands[1].u.r.rindex, + &(instr->src_operand.operand), &(instr->src_operand.size)); + instr->src_operand.type = REG_OPERAND; + + instr->src_operand.read = 1; + instr->dst_operand.write = 1; + + } else { + PrintError("Unhandled String OP\n"); + return -1; + } + + return 0; +} + +static int callback(void *data, int rindex, int subreg, unsigned char *value) { + void* reg_addr = 0; + uint_t reg_size; + + struct guest_info *info = (struct guest_info*)data; + int v3_reg_type = qx86_register_to_v3_reg(info, + rindex, + (addr_t*)®_addr, ®_size); + + if(v3_reg_type == -1) { + PrintError("Callback failed to get register index %d\n", rindex); + return 0; + } + + *(uint64_t*)value = 0; + switch(subreg) { + case QX86_SUBREG_BASE: + *(uint64_t*)value = ((struct v3_segment*)reg_addr)->base; + break; + case QX86_SUBREG_LIMIT: + *(uint32_t*)value = ((struct v3_segment*)reg_addr)->limit; + break; + case QX86_SUBREG_FLAGS: + PrintError("Callback doesn't know how to give flags.\n"); + return 0; + case QX86_SUBREG_NONE: { + switch(qx86_rtab[rindex].size) { + case 1: *(uint8_t* )value = *(uint8_t* )reg_addr; break; + case 2: *(uint16_t*)value = *(uint16_t*)reg_addr; break; + case 4: *(uint32_t*)value = *(uint32_t*)reg_addr; break; + case 8: *(uint64_t*)value = *(uint64_t*)reg_addr; break; + } + break; + } + } + + return 1; +} + +static inline int qx86_op_to_v3_op(struct guest_info *info, qx86_insn *qx86_insn, + int op_num, struct x86_operand * v3_op) { + int status = 0; + qx86_operand *qx86_op = &qx86_insn->operands[op_num]; + if (qx86_op->ot == QX86_OPERAND_TYPE_REGISTER) { + int v3_reg_type = qx86_register_to_v3_reg(info, + qx86_op->u.r.rindex, + &(v3_op->operand), &(v3_op->size)); + + if (v3_reg_type == -1) { + PrintError("Operand %d is an Unhandled Operand: %s\n", op_num, + qx86_rtab[qx86_op->u.r.rindex].name); + v3_op->type = INVALID_OPERAND; + return -1; + } else if (v3_reg_type == SEGMENT_REGISTER) { + struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand); + v3_op->operand = (addr_t)&(seg_reg->selector); + } + v3_op->type = REG_OPERAND; + + } else if(qx86_op->ot == QX86_OPERAND_TYPE_MEMORY) { + PrintDebug("Memory operand (%d)\n", op_num); + if((status = qx86_calculate_linear_address(qx86_insn, op_num, + (qx86_uint64*)&v3_op->operand)) != QX86_SUCCESS) { + PrintError("Could not get memory operand %d: " + "qx86_calculate_linear_address() returns %d\n", op_num, status); + return -1; + } + v3_op->type = MEM_OPERAND; + v3_op->size = qx86_op->size; + + } else if(qx86_op->ot == QX86_OPERAND_TYPE_IMMEDIATE) { + v3_op->size = qx86_op->u.i.valueSize; + + if (v3_op->size > 4) { + PrintError("Unhandled 64 bit immediates\n"); + return -1; + } + v3_op->operand = (addr_t)*(uint64_t*)qx86_op->u.i.value; + v3_op->type = IMM_OPERAND; + + } else { + PrintError("Unhandled Operand %d Type %d\n", op_num, qx86_op->ot); + return -1; + } + + if (qx86_op->attributes & QX86_OPERAND_ATTRIBUTE_READ) { + v3_op->read = 1; + } + if (qx86_op->attributes & QX86_OPERAND_ATTRIBUTE_WRITTEN) { + v3_op->write = 1; + } + return 0; +} + +int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) { + int proc_mode; + qx86_insn qx86_inst; + uint8_t inst_buf[QX86_INSN_SIZE_MAX]; + + memset(instr, 0, sizeof(struct x86_instr)); + memset(&qx86_inst, 0, sizeof(qx86_inst)); + + v3_get_prefixes((uchar_t *)instr_ptr, &(instr->prefixes)); + + switch(v3_get_vm_cpu_mode(info)) { + case REAL: case LONG_16_COMPAT: + proc_mode = QX86_SIZE_16; break; + case PROTECTED: case PROTECTED_PAE: case LONG_32_COMPAT: + proc_mode = QX86_SIZE_32; break; + case LONG: + proc_mode = QX86_SIZE_64; break; + default: + PrintError("Unsupported CPU mode: %d\n", info->cpu_mode); + return -1; + } + + int left_in_page = 0x1000 - (instr_ptr & 0xfff); + if(left_in_page < QX86_INSN_SIZE_MAX) { + addr_t instr_ptr2; + int status = 0; + + if (info->mem_mode == PHYSICAL_MEM) { + status = v3_gpa_to_hva(info, get_addr_linear(info, + (info->rip & ~0xfffULL) + 0x1000, &(info->segments.cs)), &instr_ptr2); + } else { + status = v3_gva_to_hva(info, get_addr_linear(info, + (info->rip & ~0xfffULL) + 0x1000, &(info->segments.cs)), &instr_ptr2); + } + if (status == -1) { + PrintError("Could not translate Instruction Address at second stage " + "translation (%p)\n", (void *)(addr_t)info->rip); + return -1; + } + + if(((instr_ptr & ~0xfffUL) + 0x1000) != instr_ptr2) { + PrintError("Note: physical page non-contiguous\n"); + memcpy(inst_buf, (const void*)instr_ptr, left_in_page); + memcpy(inst_buf + left_in_page, (const void*)instr_ptr2, + QX86_INSN_SIZE_MAX - left_in_page); + instr_ptr = (addr_t)inst_buf; + } // in other case, address space is contiguous and everything is OK + } + + qx86_inst.callback = callback; + qx86_inst.data = info; + + int status = qx86_decode(&qx86_inst, proc_mode, + (const void*)instr_ptr, QX86_INSN_SIZE_MAX); + if(status != QX86_SUCCESS) { + PrintError("qx86_decode() returned %d\n", status); + return -1; + } + + instr->instr_length = qx86_inst.rawSize; + + if ((instr->op_type = get_opcode(&qx86_inst)) == V3_INVALID_OP) { + PrintError("Could not get opcode. (mnemonic=%s)\n", + qx86_mtab[qx86_inst.mnemonic].name); + return -1; + } + + if(instr->op_type == V3_OP_MOVS || instr->op_type == V3_OP_STOS) { + instr->is_str_op = 1; + return decode_string_op(info, &qx86_inst, instr); + } else { + instr->is_str_op = 0; + instr->str_op_length = 0; + } + + instr->num_operands = qx86_inst.operandCount; + + // set first operand + if (instr->num_operands >= 1) { + if (qx86_op_to_v3_op(info, &qx86_inst, 0, &instr->dst_operand) != 0) + return -1; + } + + // set second operand + if (instr->num_operands >= 2) { + if (qx86_op_to_v3_op(info, &qx86_inst, 1, &instr->src_operand) != 0) + return -1; + } + + // set third operand + if (instr->num_operands >= 3) { + if (qx86_op_to_v3_op(info, &qx86_inst, 2, &instr->third_operand) != 0) + return -1; + } + +#ifdef V3_CONFIG_DEBUG_DECODER + qx86_print_options_intel opt; + char buf[128]; + int buf_sz = 128; + if(qx86_print_intel(&qx86_inst, &opt, buf, &buf_sz) != QX86_SUCCESS) { + PrintDebug("Print failed!\n"); + } else { + PrintDebug("Instruction (%p): %s\n", (void*)info->rip, buf); + } + PrintDebug("Operands: dst %p src %p 3rd %p\n", (void*)instr->dst_operand.operand, + (void*)instr->src_operand.operand, (void*)instr->third_operand.operand); +#endif + return 0; +} + +static int get_opcode(qx86_insn *inst) { + switch (inst->mnemonic) { +#define IS_CR(op) inst->operands[op].ot == QX86_OPERAND_TYPE_REGISTER && \ + qx86_rtab[inst->operands[op].u.r.rindex].rclass == QX86_RCLASS_CREG + + /* MOV cases */ + case QX86_MNEMONIC_MOV: { + if(inst->operands[0].ot == QX86_OPERAND_TYPE_MEMORY + || inst->operands[1].ot == QX86_OPERAND_TYPE_MEMORY) + return V3_OP_MOV; + if(IS_CR(0)) + return V3_OP_MOV2CR; + if(IS_CR(1)) + return V3_OP_MOVCR2; + + PrintError("Bad operand types for MOV: %d %d\n", inst->operands[0].ot, + inst->operands[1].ot); + return V3_INVALID_OP; + } + + /* Control Instructions */ + case QX86_MNEMONIC_SMSW: + return V3_OP_SMSW; + + case QX86_MNEMONIC_LMSW: + return V3_OP_LMSW; + + case QX86_MNEMONIC_CLTS: + return V3_OP_CLTS; + + case QX86_MNEMONIC_INVLPG: + return V3_OP_INVLPG; + + /* Data Instructions */ + case QX86_MNEMONIC_ADC: + return V3_OP_ADC; + + case QX86_MNEMONIC_ADD: + return V3_OP_ADD; + + case QX86_MNEMONIC_AND: + return V3_OP_AND; + + case QX86_MNEMONIC_SUB: + return V3_OP_SUB; + + + case QX86_MNEMONIC_MOVZX: + return V3_OP_MOVZX; + + case QX86_MNEMONIC_MOVSX: + return V3_OP_MOVSX; + + + case QX86_MNEMONIC_DEC: + return V3_OP_DEC; + + case QX86_MNEMONIC_INC: + return V3_OP_INC; + + case QX86_MNEMONIC_OR: + return V3_OP_OR; + + case QX86_MNEMONIC_XOR: + return V3_OP_XOR; + + case QX86_MNEMONIC_NEG: + return V3_OP_NEG; + + case QX86_MNEMONIC_NOT: + return V3_OP_NOT; + + case QX86_MNEMONIC_XCHG: + return V3_OP_XCHG; + + case QX86_MNEMONIC_SETB: + return V3_OP_SETB; + + case QX86_MNEMONIC_SETBE: + return V3_OP_SETBE; + + case QX86_MNEMONIC_SETL: + return V3_OP_SETL; + + case QX86_MNEMONIC_SETLE: + return V3_OP_SETLE; + + case QX86_MNEMONIC_SETAE: + return V3_OP_SETNB; + + case QX86_MNEMONIC_SETA: + return V3_OP_SETNBE; + + case QX86_MNEMONIC_SETGE: + return V3_OP_SETNL; + + case QX86_MNEMONIC_SETG: + return V3_OP_SETNLE; + + case QX86_MNEMONIC_SETNO: + return V3_OP_SETNO; + + case QX86_MNEMONIC_SETNP: + return V3_OP_SETNP; + + case QX86_MNEMONIC_SETNS: + return V3_OP_SETNS; + + case QX86_MNEMONIC_SETNZ: + return V3_OP_SETNZ; + + case QX86_MNEMONIC_SETO: + return V3_OP_SETO; + + case QX86_MNEMONIC_SETP: + return V3_OP_SETP; + + case QX86_MNEMONIC_SETS: + return V3_OP_SETS; + + case QX86_MNEMONIC_SETZ: + return V3_OP_SETZ; + + case QX86_MNEMONIC_MOVSB: + case QX86_MNEMONIC_MOVSW: + case QX86_MNEMONIC_MOVSD: + case QX86_MNEMONIC_MOVSQ: + return V3_OP_MOVS; + + case QX86_MNEMONIC_STOSB: + case QX86_MNEMONIC_STOSW: + case QX86_MNEMONIC_STOSD: + case QX86_MNEMONIC_STOSQ: + return V3_OP_STOS; + + + default: + return V3_INVALID_OP; + } +} + +static int qx86_register_to_v3_reg(struct guest_info * info, int qx86_reg, + addr_t * v3_reg, uint_t * reg_len) { + PrintDebug("qx86 Register: %s\n", qx86_rtab[qx86_reg].name); + + switch (qx86_reg) { + case QX86_REGISTER_INVALID: + *v3_reg = 0; + *reg_len = 0; + return -1; + + case QX86_REGISTER_RAX: + *v3_reg = (addr_t)&(info->vm_regs.rax); + *reg_len = 8; + return GPR_REGISTER; + case QX86_REGISTER_EAX: + *v3_reg = (addr_t)&(info->vm_regs.rax); + *reg_len = 4; + return GPR_REGISTER; + case QX86_REGISTER_AX: + *v3_reg = (addr_t)&(info->vm_regs.rax); + *reg_len = 2; + return GPR_REGISTER; + case QX86_REGISTER_AH: + *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1; + *reg_len = 1; + return GPR_REGISTER; + case QX86_REGISTER_AL: + *v3_reg = (addr_t)&(info->vm_regs.rax); + *reg_len = 1; + return GPR_REGISTER; + + case QX86_REGISTER_RCX: + *v3_reg = (addr_t)&(info->vm_regs.rcx); + *reg_len = 8; + return GPR_REGISTER; + case QX86_REGISTER_ECX: + *v3_reg = (addr_t)&(info->vm_regs.rcx); + *reg_len = 4; + return GPR_REGISTER; + case QX86_REGISTER_CX: + *v3_reg = (addr_t)&(info->vm_regs.rcx); + *reg_len = 2; + return GPR_REGISTER; + case QX86_REGISTER_CH: + *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1; + *reg_len = 1; + return GPR_REGISTER; + case QX86_REGISTER_CL: + *v3_reg = (addr_t)&(info->vm_regs.rcx); + *reg_len = 1; + return GPR_REGISTER; + + case QX86_REGISTER_RDX: + *v3_reg = (addr_t)&(info->vm_regs.rdx); + *reg_len = 8; + return GPR_REGISTER; + case QX86_REGISTER_EDX: + *v3_reg = (addr_t)&(info->vm_regs.rdx); + *reg_len = 4; + return GPR_REGISTER; + case QX86_REGISTER_DX: + *v3_reg = (addr_t)&(info->vm_regs.rdx); + *reg_len = 2; + return GPR_REGISTER; + case QX86_REGISTER_DH: + *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1; + *reg_len = 1; + return GPR_REGISTER; + case QX86_REGISTER_DL: + *v3_reg = (addr_t)&(info->vm_regs.rdx); + *reg_len = 1; + return GPR_REGISTER; + + case QX86_REGISTER_RBX: + *v3_reg = (addr_t)&(info->vm_regs.rbx); + *reg_len = 8; + return GPR_REGISTER; + case QX86_REGISTER_EBX: + *v3_reg = (addr_t)&(info->vm_regs.rbx); + *reg_len = 4; + return GPR_REGISTER; + case QX86_REGISTER_BX: + *v3_reg = (addr_t)&(info->vm_regs.rbx); + *reg_len = 2; + return GPR_REGISTER; + case QX86_REGISTER_BH: + *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1; + *reg_len = 1; + return GPR_REGISTER; + case QX86_REGISTER_BL: + *v3_reg = (addr_t)&(info->vm_regs.rbx); + *reg_len = 1; + return GPR_REGISTER; + + + case QX86_REGISTER_RSP: + *v3_reg = (addr_t)&(info->vm_regs.rsp); + *reg_len = 8; + return GPR_REGISTER; + case QX86_REGISTER_ESP: + *v3_reg = (addr_t)&(info->vm_regs.rsp); + *reg_len = 4; + return GPR_REGISTER; + case QX86_REGISTER_SP: + *v3_reg = (addr_t)&(info->vm_regs.rsp); + *reg_len = 2; + return GPR_REGISTER; + case QX86_REGISTER_SPL: + *v3_reg = (addr_t)&(info->vm_regs.rsp); + *reg_len = 1; + return GPR_REGISTER; + + case QX86_REGISTER_RBP: + *v3_reg = (addr_t)&(info->vm_regs.rbp); + *reg_len = 8; + return GPR_REGISTER; + case QX86_REGISTER_EBP: + *v3_reg = (addr_t)&(info->vm_regs.rbp); + *reg_len = 4; + return GPR_REGISTER; + case QX86_REGISTER_BP: + *v3_reg = (addr_t)&(info->vm_regs.rbp); + *reg_len = 2; + return GPR_REGISTER; + case QX86_REGISTER_BPL: + *v3_reg = (addr_t)&(info->vm_regs.rbp); + *reg_len = 1; + return GPR_REGISTER; + + + + case QX86_REGISTER_RSI: + *v3_reg = (addr_t)&(info->vm_regs.rsi); + *reg_len = 8; + return GPR_REGISTER; + case QX86_REGISTER_ESI: + *v3_reg = (addr_t)&(info->vm_regs.rsi); + *reg_len = 4; + return GPR_REGISTER; + case QX86_REGISTER_SI: + *v3_reg = (addr_t)&(info->vm_regs.rsi); + *reg_len = 2; + return GPR_REGISTER; + case QX86_REGISTER_SIL: + *v3_reg = (addr_t)&(info->vm_regs.rsi); + *reg_len = 1; + return GPR_REGISTER; + + + case QX86_REGISTER_RDI: + *v3_reg = (addr_t)&(info->vm_regs.rdi); + *reg_len = 8; + return GPR_REGISTER; + case QX86_REGISTER_EDI: + *v3_reg = (addr_t)&(info->vm_regs.rdi); + *reg_len = 4; + return GPR_REGISTER; + case QX86_REGISTER_DI: + *v3_reg = (addr_t)&(info->vm_regs.rdi); + *reg_len = 2; + return GPR_REGISTER; + case QX86_REGISTER_DIL: + *v3_reg = (addr_t)&(info->vm_regs.rdi); + *reg_len = 1; + return GPR_REGISTER; + + + + + + case QX86_REGISTER_R8: + *v3_reg = (addr_t)&(info->vm_regs.r8); + *reg_len = 8; + return GPR_REGISTER; + case QX86_REGISTER_R8D: + *v3_reg = (addr_t)&(info->vm_regs.r8); + *reg_len = 4; + return GPR_REGISTER; + case QX86_REGISTER_R8W: + *v3_reg = (addr_t)&(info->vm_regs.r8); + *reg_len = 2; + return GPR_REGISTER; + case QX86_REGISTER_R8B: + *v3_reg = (addr_t)&(info->vm_regs.r8); + *reg_len = 1; + return GPR_REGISTER; + + case QX86_REGISTER_R9: + *v3_reg = (addr_t)&(info->vm_regs.r9); + *reg_len = 8; + return GPR_REGISTER; + case QX86_REGISTER_R9D: + *v3_reg = (addr_t)&(info->vm_regs.r9); + *reg_len = 4; + return GPR_REGISTER; + case QX86_REGISTER_R9W: + *v3_reg = (addr_t)&(info->vm_regs.r9); + *reg_len = 2; + return GPR_REGISTER; + case QX86_REGISTER_R9B: + *v3_reg = (addr_t)&(info->vm_regs.r9); + *reg_len = 1; + return GPR_REGISTER; + + case QX86_REGISTER_R10: + *v3_reg = (addr_t)&(info->vm_regs.r10); + *reg_len = 8; + return GPR_REGISTER; + case QX86_REGISTER_R10D: + *v3_reg = (addr_t)&(info->vm_regs.r10); + *reg_len = 4; + return GPR_REGISTER; + case QX86_REGISTER_R10W: + *v3_reg = (addr_t)&(info->vm_regs.r10); + *reg_len = 2; + return GPR_REGISTER; + case QX86_REGISTER_R10B: + *v3_reg = (addr_t)&(info->vm_regs.r10); + *reg_len = 1; + return GPR_REGISTER; + + case QX86_REGISTER_R11: + *v3_reg = (addr_t)&(info->vm_regs.r11); + *reg_len = 8; + return GPR_REGISTER; + case QX86_REGISTER_R11D: + *v3_reg = (addr_t)&(info->vm_regs.r11); + *reg_len = 4; + return GPR_REGISTER; + case QX86_REGISTER_R11W: + *v3_reg = (addr_t)&(info->vm_regs.r11); + *reg_len = 2; + return GPR_REGISTER; + case QX86_REGISTER_R11B: + *v3_reg = (addr_t)&(info->vm_regs.r11); + *reg_len = 1; + return GPR_REGISTER; + + case QX86_REGISTER_R12: + *v3_reg = (addr_t)&(info->vm_regs.r12); + *reg_len = 8; + return GPR_REGISTER; + case QX86_REGISTER_R12D: + *v3_reg = (addr_t)&(info->vm_regs.r12); + *reg_len = 4; + return GPR_REGISTER; + case QX86_REGISTER_R12W: + *v3_reg = (addr_t)&(info->vm_regs.r12); + *reg_len = 2; + return GPR_REGISTER; + case QX86_REGISTER_R12B: + *v3_reg = (addr_t)&(info->vm_regs.r12); + *reg_len = 1; + return GPR_REGISTER; + + case QX86_REGISTER_R13: + *v3_reg = (addr_t)&(info->vm_regs.r13); + *reg_len = 8; + return GPR_REGISTER; + case QX86_REGISTER_R13D: + *v3_reg = (addr_t)&(info->vm_regs.r13); + *reg_len = 4; + return GPR_REGISTER; + case QX86_REGISTER_R13W: + *v3_reg = (addr_t)&(info->vm_regs.r13); + *reg_len = 2; + return GPR_REGISTER; + case QX86_REGISTER_R13B: + *v3_reg = (addr_t)&(info->vm_regs.r13); + *reg_len = 1; + return GPR_REGISTER; + + case QX86_REGISTER_R14: + *v3_reg = (addr_t)&(info->vm_regs.r14); + *reg_len = 8; + return GPR_REGISTER; + case QX86_REGISTER_R14D: + *v3_reg = (addr_t)&(info->vm_regs.r14); + *reg_len = 4; + return GPR_REGISTER; + case QX86_REGISTER_R14W: + *v3_reg = (addr_t)&(info->vm_regs.r14); + *reg_len = 2; + return GPR_REGISTER; + case QX86_REGISTER_R14B: + *v3_reg = (addr_t)&(info->vm_regs.r14); + *reg_len = 1; + return GPR_REGISTER; + + case QX86_REGISTER_R15: + *v3_reg = (addr_t)&(info->vm_regs.r15); + *reg_len = 8; + return GPR_REGISTER; + case QX86_REGISTER_R15D: + *v3_reg = (addr_t)&(info->vm_regs.r15); + *reg_len = 4; + return GPR_REGISTER; + case QX86_REGISTER_R15W: + *v3_reg = (addr_t)&(info->vm_regs.r15); + *reg_len = 2; + return GPR_REGISTER; + case QX86_REGISTER_R15B: + *v3_reg = (addr_t)&(info->vm_regs.r15); + *reg_len = 1; + return GPR_REGISTER; + + + case QX86_REGISTER_RIP: + *v3_reg = (addr_t)&(info->rip); + *reg_len = 8; + return CTRL_REGISTER; + case QX86_REGISTER_EIP: + *v3_reg = (addr_t)&(info->rip); + *reg_len = 4; + return CTRL_REGISTER; + case QX86_REGISTER_IP: + *v3_reg = (addr_t)&(info->rip); + *reg_len = 2; + return CTRL_REGISTER; + + case QX86_REGISTER_FLAGS: + *v3_reg = (addr_t)&(info->ctrl_regs.rflags); + *reg_len = 2; + return CTRL_REGISTER; + case QX86_REGISTER_EFLAGS: + *v3_reg = (addr_t)&(info->ctrl_regs.rflags); + *reg_len = 4; + return CTRL_REGISTER; + case QX86_REGISTER_RFLAGS: + *v3_reg = (addr_t)&(info->ctrl_regs.rflags); + *reg_len = 8; + return CTRL_REGISTER; + + case QX86_REGISTER_CR0: + *v3_reg = (addr_t)&(info->ctrl_regs.cr0); + *reg_len = 4; + return CTRL_REGISTER; + case QX86_REGISTER_CR2: + *v3_reg = (addr_t)&(info->ctrl_regs.cr2); + *reg_len = 4; + return CTRL_REGISTER; + case QX86_REGISTER_CR3: + *v3_reg = (addr_t)&(info->ctrl_regs.cr3); + *reg_len = 4; + return CTRL_REGISTER; + case QX86_REGISTER_CR4: + *v3_reg = (addr_t)&(info->ctrl_regs.cr4); + *reg_len = 4; + return CTRL_REGISTER; + case QX86_REGISTER_CR8: + *v3_reg = (addr_t)&(info->ctrl_regs.cr8); + *reg_len = 4; + return CTRL_REGISTER; + + case QX86_REGISTER_CR1: + case QX86_REGISTER_CR5: + case QX86_REGISTER_CR6: + case QX86_REGISTER_CR7: + case QX86_REGISTER_CR9: + case QX86_REGISTER_CR10: + case QX86_REGISTER_CR11: + case QX86_REGISTER_CR12: + case QX86_REGISTER_CR13: + case QX86_REGISTER_CR14: + case QX86_REGISTER_CR15: + return -1; + + + case QX86_REGISTER_CS: + *v3_reg = (addr_t)&(info->segments.cs); + *reg_len = 8; + return SEGMENT_REGISTER; + case QX86_REGISTER_DS: + *v3_reg = (addr_t)&(info->segments.ds); + *reg_len = 8; + return SEGMENT_REGISTER; + case QX86_REGISTER_ES: + *v3_reg = (addr_t)&(info->segments.es); + *reg_len = 8; + return SEGMENT_REGISTER; + case QX86_REGISTER_SS: + *v3_reg = (addr_t)&(info->segments.ss); + *reg_len = 8; + return SEGMENT_REGISTER; + case QX86_REGISTER_FS: + *v3_reg = (addr_t)&(info->segments.fs); + *reg_len = 8; + return SEGMENT_REGISTER; + case QX86_REGISTER_GS: + *v3_reg = (addr_t)&(info->segments.gs); + *reg_len = 8; + return SEGMENT_REGISTER; + + + case QX86_REGISTER_DR0: + case QX86_REGISTER_DR1: + case QX86_REGISTER_DR2: + case QX86_REGISTER_DR3: + case QX86_REGISTER_DR4: + case QX86_REGISTER_DR5: + case QX86_REGISTER_DR6: + case QX86_REGISTER_DR7: + case QX86_REGISTER_DR8: + case QX86_REGISTER_DR9: + case QX86_REGISTER_DR10: + case QX86_REGISTER_DR11: + case QX86_REGISTER_DR12: + case QX86_REGISTER_DR13: + case QX86_REGISTER_DR14: + case QX86_REGISTER_DR15: + return -1; + + + case QX86_REGISTER_XMM0: + case QX86_REGISTER_XMM1: + case QX86_REGISTER_XMM2: + case QX86_REGISTER_XMM3: + case QX86_REGISTER_XMM4: + case QX86_REGISTER_XMM5: + case QX86_REGISTER_XMM6: + case QX86_REGISTER_XMM7: + case QX86_REGISTER_XMM8: + case QX86_REGISTER_XMM9: + case QX86_REGISTER_XMM10: + case QX86_REGISTER_XMM11: + case QX86_REGISTER_XMM12: + case QX86_REGISTER_XMM13: + case QX86_REGISTER_XMM14: + case QX86_REGISTER_XMM15: + + case QX86_REGISTER_YMM0: + case QX86_REGISTER_YMM1: + case QX86_REGISTER_YMM2: + case QX86_REGISTER_YMM3: + case QX86_REGISTER_YMM4: + case QX86_REGISTER_YMM5: + case QX86_REGISTER_YMM6: + case QX86_REGISTER_YMM7: + case QX86_REGISTER_YMM8: + case QX86_REGISTER_YMM9: + case QX86_REGISTER_YMM10: + case QX86_REGISTER_YMM11: + case QX86_REGISTER_YMM12: + case QX86_REGISTER_YMM13: + case QX86_REGISTER_YMM14: + case QX86_REGISTER_YMM15: + + case QX86_REGISTER_MMX0: + case QX86_REGISTER_MMX1: + case QX86_REGISTER_MMX2: + case QX86_REGISTER_MMX3: + case QX86_REGISTER_MMX4: + case QX86_REGISTER_MMX5: + case QX86_REGISTER_MMX6: + case QX86_REGISTER_MMX7: + + case QX86_REGISTER_ST0: + case QX86_REGISTER_ST1: + case QX86_REGISTER_ST2: + case QX86_REGISTER_ST3: + case QX86_REGISTER_ST4: + case QX86_REGISTER_ST5: + case QX86_REGISTER_ST6: + case QX86_REGISTER_ST7: + return -1; + + } + + + return 0; +}