x86_emulate.c

来自「xen虚拟机源代码安装包」· C语言 代码 · 共 1,781 行 · 第 1/5 页

C
1,781
字号
/****************************************************************************** * x86_emulate.c *  * Generic x86 (32-bit and 64-bit) instruction decoder and emulator. *  * Copyright (c) 2005-2007 Keir Fraser * Copyright (c) 2005-2007 XenSource Inc. *  * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. *  * This program 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 General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *//* Operand sizes: 8-bit operands or specified/overridden size. */#define ByteOp      (1<<0) /* 8-bit operands. *//* Destination operand type. */#define DstBitBase  (0<<1) /* Memory operand, bit string. */#define ImplicitOps (1<<1) /* Implicit in opcode. No generic decode. */#define DstReg      (2<<1) /* Register operand. */#define DstMem      (3<<1) /* Memory operand. */#define DstMask     (3<<1)/* Source operand type. */#define SrcNone     (0<<3) /* No source operand. */#define SrcImplicit (0<<3) /* Source operand is implicit in the opcode. */#define SrcReg      (1<<3) /* Register operand. */#define SrcMem      (2<<3) /* Memory operand. */#define SrcMem16    (3<<3) /* Memory operand (16-bit). */#define SrcImm      (4<<3) /* Immediate operand. */#define SrcImmByte  (5<<3) /* 8-bit sign-extended immediate operand. */#define SrcMask     (7<<3)/* Generic ModRM decode. */#define ModRM       (1<<6)/* Destination is only written; never read. */#define Mov         (1<<7)static uint8_t opcode_table[256] = {    /* 0x00 - 0x07 */    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,    ByteOp|DstReg|SrcImm, DstReg|SrcImm, ImplicitOps, ImplicitOps,    /* 0x08 - 0x0F */    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,    ByteOp|DstReg|SrcImm, DstReg|SrcImm, ImplicitOps, 0,    /* 0x10 - 0x17 */    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,    ByteOp|DstReg|SrcImm, DstReg|SrcImm, ImplicitOps, ImplicitOps,    /* 0x18 - 0x1F */    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,    ByteOp|DstReg|SrcImm, DstReg|SrcImm, ImplicitOps, ImplicitOps,    /* 0x20 - 0x27 */    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,    ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps,    /* 0x28 - 0x2F */    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,    ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps,    /* 0x30 - 0x37 */    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,    ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps,    /* 0x38 - 0x3F */    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,    ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps,    /* 0x40 - 0x4F */    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    /* 0x50 - 0x5F */    ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,    ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,    ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,    ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,    /* 0x60 - 0x67 */    ImplicitOps, ImplicitOps, DstReg|SrcMem|ModRM, DstReg|SrcMem16|ModRM|Mov,    0, 0, 0, 0,    /* 0x68 - 0x6F */    ImplicitOps|Mov, DstReg|SrcImm|ModRM|Mov,    ImplicitOps|Mov, DstReg|SrcImmByte|ModRM|Mov,    ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,    /* 0x70 - 0x77 */    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    /* 0x78 - 0x7F */    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    /* 0x80 - 0x87 */    ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImm|ModRM,    ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM,    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,    /* 0x88 - 0x8F */    ByteOp|DstMem|SrcReg|ModRM|Mov, DstMem|SrcReg|ModRM|Mov,    ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,    DstMem|SrcReg|ModRM|Mov, DstReg|SrcNone|ModRM,    DstReg|SrcMem|ModRM|Mov, DstMem|SrcNone|ModRM|Mov,    /* 0x90 - 0x97 */    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    /* 0x98 - 0x9F */    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    /* 0xA0 - 0xA7 */    ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,    ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,    ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,    ByteOp|ImplicitOps, ImplicitOps,    /* 0xA8 - 0xAF */    ByteOp|DstReg|SrcImm, DstReg|SrcImm,    ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,    ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,    ByteOp|ImplicitOps, ImplicitOps,    /* 0xB0 - 0xB7 */    ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov,    ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov,    ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov,    ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov,    /* 0xB8 - 0xBF */    DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov,    DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov,    /* 0xC0 - 0xC7 */    ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM,    ImplicitOps, ImplicitOps,    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,    ByteOp|DstMem|SrcImm|ModRM|Mov, DstMem|SrcImm|ModRM|Mov,    /* 0xC8 - 0xCF */    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    /* 0xD0 - 0xD7 */    ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM,    ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM,    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    /* 0xD8 - 0xDF */    ImplicitOps|ModRM|Mov, ImplicitOps|ModRM|Mov,    ImplicitOps|ModRM|Mov, ImplicitOps|ModRM|Mov,    ImplicitOps|ModRM|Mov, ImplicitOps|ModRM|Mov,    ImplicitOps|ModRM|Mov, ImplicitOps|ModRM|Mov,    /* 0xE0 - 0xE7 */    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    /* 0xE8 - 0xEF */    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    /* 0xF0 - 0xF7 */    0, ImplicitOps, 0, 0,    ImplicitOps, ImplicitOps,    ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM,    /* 0xF8 - 0xFF */    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    ImplicitOps, ImplicitOps, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM};static uint8_t twobyte_table[256] = {    /* 0x00 - 0x07 */    0, ImplicitOps|ModRM, 0, 0, 0, 0, ImplicitOps, 0,    /* 0x08 - 0x0F */    ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps|ModRM, 0, 0,    /* 0x10 - 0x17 */    0, 0, 0, 0, 0, 0, 0, 0,    /* 0x18 - 0x1F */    ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM,    ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM,    /* 0x20 - 0x27 */    ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM,    0, 0, 0, 0,    /* 0x28 - 0x2F */    0, 0, 0, 0, 0, 0, 0, 0,    /* 0x30 - 0x37 */    ImplicitOps, ImplicitOps, ImplicitOps, 0, 0, 0, 0, 0,    /* 0x38 - 0x3F */    0, 0, 0, 0, 0, 0, 0, 0,    /* 0x40 - 0x47 */    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,    /* 0x48 - 0x4F */    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,    /* 0x50 - 0x5F */    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /* 0x60 - 0x6F */    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM,    /* 0x70 - 0x7F */    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM,    /* 0x80 - 0x87 */    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    /* 0x88 - 0x8F */    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    /* 0x90 - 0x97 */    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,    /* 0x98 - 0x9F */    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,    /* 0xA0 - 0xA7 */    ImplicitOps, ImplicitOps, ImplicitOps, DstBitBase|SrcReg|ModRM,    DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, 0,    /* 0xA8 - 0xAF */    ImplicitOps, ImplicitOps, 0, DstBitBase|SrcReg|ModRM,    DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, DstReg|SrcMem|ModRM,    /* 0xB0 - 0xB7 */    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,    DstReg|SrcMem|ModRM|Mov, DstBitBase|SrcReg|ModRM,    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,    ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,    /* 0xB8 - 0xBF */    0, 0, DstBitBase|SrcImmByte|ModRM, DstBitBase|SrcReg|ModRM,    DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,    ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,    /* 0xC0 - 0xC7 */    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, 0,    0, 0, 0, ImplicitOps|ModRM,    /* 0xC8 - 0xCF */    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,    /* 0xD0 - 0xDF */    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /* 0xE0 - 0xEF */    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /* 0xF0 - 0xFF */    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};/* Type, address-of, and value of an instruction's operand. */struct operand {    enum { OP_REG, OP_MEM, OP_IMM, OP_NONE } type;    unsigned int bytes;    /* Up to 128-byte operand value, addressable as ulong or uint32_t[]. */    union {        unsigned long val;        uint32_t bigval[4];    };    /* Up to 128-byte operand value, addressable as ulong or uint32_t[]. */    union {        unsigned long orig_val;        uint32_t orig_bigval[4];    };    union {        /* OP_REG: Pointer to register field. */        unsigned long *reg;        /* OP_MEM: Segment and offset. */        struct {            enum x86_segment seg;            unsigned long    off;        } mem;    };};/* MSRs. */#define MSR_TSC   0x10/* Control register flags. */#define CR0_PE    (1<<0)#define CR4_TSD   (1<<2)/* EFLAGS bit definitions. */#define EFLG_VIP  (1<<20)#define EFLG_VIF  (1<<19)#define EFLG_AC   (1<<18)#define EFLG_VM   (1<<17)#define EFLG_RF   (1<<16)#define EFLG_NT   (1<<14)#define EFLG_IOPL (3<<12)#define EFLG_OF   (1<<11)#define EFLG_DF   (1<<10)#define EFLG_IF   (1<<9)#define EFLG_TF   (1<<8)#define EFLG_SF   (1<<7)#define EFLG_ZF   (1<<6)#define EFLG_AF   (1<<4)#define EFLG_PF   (1<<2)#define EFLG_CF   (1<<0)/* Exception definitions. */#define EXC_DE  0#define EXC_DB  1#define EXC_BP  3#define EXC_OF  4#define EXC_BR  5#define EXC_UD  6#define EXC_TS 10#define EXC_NP 11#define EXC_SS 12#define EXC_GP 13#define EXC_PF 14#define EXC_MF 16/* * Instruction emulation: * Most instructions are emulated directly via a fragment of inline assembly * code. This allows us to save/restore EFLAGS and thus very easily pick up * any modified flags. */#if defined(__x86_64__)#define _LO32 "k"          /* force 32-bit operand */#define _STK  "%%rsp"      /* stack pointer */#define _BYTES_PER_LONG "8"#elif defined(__i386__)#define _LO32 ""           /* force 32-bit operand */#define _STK  "%%esp"      /* stack pointer */#define _BYTES_PER_LONG "4"#endif/* * These EFLAGS bits are restored from saved value during emulation, and * any changes are written back to the saved value after emulation. */#define EFLAGS_MASK (EFLG_OF|EFLG_SF|EFLG_ZF|EFLG_AF|EFLG_PF|EFLG_CF)/* Before executing instruction: restore necessary bits in EFLAGS. */#define _PRE_EFLAGS(_sav, _msk, _tmp)                           \/* EFLAGS = (_sav & _msk) | (EFLAGS & ~_msk); _sav &= ~_msk; */ \"movl %"_sav",%"_LO32 _tmp"; "                                  \"push %"_tmp"; "                                                \"push %"_tmp"; "                                                \"movl %"_msk",%"_LO32 _tmp"; "                                  \"andl %"_LO32 _tmp",("_STK"); "                                 \"pushf; "                                                       \"notl %"_LO32 _tmp"; "                                          \"andl %"_LO32 _tmp",("_STK"); "                                 \"andl %"_LO32 _tmp",2*"_BYTES_PER_LONG"("_STK"); "              \"pop  %"_tmp"; "                                                \"orl  %"_LO32 _tmp",("_STK"); "                                 \"popf; "                                                        \"pop  %"_sav"; "/* After executing instruction: write-back necessary bits in EFLAGS. */#define _POST_EFLAGS(_sav, _msk, _tmp)          \/* _sav |= EFLAGS & _msk; */                    \

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?