DisasmCore.cpp revision 648982590db1ce026d79418ef7bc2d4439890f2e
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * VBox Disassembler - Core Components.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Copyright (C) 2006-2012 Oracle Corporation
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * available from http://www.virtualbox.org. This file is free software;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * you can redistribute it and/or modify it under the terms of the GNU
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * General Public License (GPL) as published by the Free Software
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/*******************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync* Header Files *
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync*******************************************************************************/
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/*******************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync* Internal Functions *
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync*******************************************************************************/
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic int disInstrWorker(PDISCPUSTATE pCpu, RTUINTPTR uInstrAddr, PCDISOPCODE paOneByteMap, uint32_t *pcbInstr);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic unsigned disParseInstruction(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISCPUSTATE pCpu);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic unsigned QueryModRM(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu, unsigned *pSibInc = NULL);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic unsigned QueryModRM_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu, unsigned *pSibInc = NULL);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic void UseSIB(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic unsigned ParseSIB_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic void disasmModRMReg(PDISCPUSTATE pCpu, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam, int fRegAddr);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic void disasmModRMReg16(PDISCPUSTATE pCpu, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic void disasmModRMSReg(PDISCPUSTATE pCpu, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic void disValidateLockSequence(PDISCPUSTATE pCpu);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/* Read functions */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic uint8_t disReadByte(PDISCPUSTATE pCpu, RTUINTPTR pAddress);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic uint16_t disReadWord(PDISCPUSTATE pCpu, RTUINTPTR pAddress);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic uint32_t disReadDWord(PDISCPUSTATE pCpu, RTUINTPTR pAddress);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic uint64_t disReadQWord(PDISCPUSTATE pCpu, RTUINTPTR pAddress);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic DECLCALLBACK(int) disReadBytesDefault(PDISCPUSTATE pCpu, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/** @name Parsers
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync/** Floating point parsing */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/*******************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync* Global Variables *
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync*******************************************************************************/
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/** Parser opcode table for full disassembly. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic PFNDISPARSE const g_apfnFullDisasm[IDX_ParseMax] =
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/** Parser opcode table for only calculating instruction size. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic PFNDISPARSE const g_apfnCalcSize[IDX_ParseMax] =
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Parses one guest instruction.
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * The result is found in pCpu and pcbInstr.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @returns VBox status code.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param pvInstr Address of the instruction to decode. This is a
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * real address in the current context that can be
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * accessed without faulting. (Consider
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * DISInstrWithReader if this isn't the case.)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param enmCpuMode The CPU mode. DISCPUMODE_32BIT, DISCPUMODE_16BIT, or DISCPUMODE_64BIT.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param pfnReadBytes Callback for reading instruction bytes.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param pvUser User argument for the instruction reader. (Ends up in apvUserData[0].)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param pCpu Pointer to cpu structure. Will be initialized.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param pcbInstr Where to store the size of the instruction.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * NULL is allowed. This is also stored in
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * PDISCPUSTATE::opsize.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncDISDECL(int) DISInstr(const void *pvInstr, DISCPUMODE enmCpuMode, PDISCPUSTATE pCpu, uint32_t *pcbInstr)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return DISInstEx((uintptr_t)pvInstr, enmCpuMode, DISOPTYPE_ALL, NULL /*pfnReadBytes*/, NULL /*pvUser*/, pCpu, pcbInstr);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Parses one guest instruction.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * The result is found in pCpu and pcbInstr.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @returns VBox status code.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param uInstrAddr Address of the instruction to decode. What this means
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * is left to the pfnReadBytes function.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param enmCpuMode The CPU mode. DISCPUMODE_32BIT, DISCPUMODE_16BIT, or DISCPUMODE_64BIT.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param pfnReadBytes Callback for reading instruction bytes.
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * @param pvUser User argument for the instruction reader. (Ends up in apvUserData[0].)
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * @param pCpu Pointer to cpu structure. Will be initialized.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param pcbInstr Where to store the size of the instruction.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * NULL is allowed. This is also stored in
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * PDISCPUSTATE::opsize.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncDISDECL(int) DISInstrWithReader(RTUINTPTR uInstrAddr, DISCPUMODE enmCpuMode, PFNDISREADBYTES pfnReadBytes, void *pvUser,
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return DISInstEx(uInstrAddr, enmCpuMode, DISOPTYPE_ALL, pfnReadBytes, pvUser, pCpu, pcbInstr);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Disassembles on instruction, details in @a pCpu and length in @a pcbInstr.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @returns VBox status code.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param uInstrAddr Address of the instruction to decode. What this means
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * is left to the pfnReadBytes function.
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * @param enmCpuMode The CPU mode. DISCPUMODE_32BIT, DISCPUMODE_16BIT, or DISCPUMODE_64BIT.
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * @param pfnReadBytes Callback for reading instruction bytes.
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * @param fFilter Instruction type filter.
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * @param pvUser User argument for the instruction reader. (Ends up in apvUserData[0].)
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * @param pCpu Pointer to CPU structure. With the exception of
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * DISCPUSTATE::apvUserData[1] and
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * DISCPUSTATE::apvUserData[2], the structure will be
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * completely initialized by this API, i.e. no input is
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * taken from it.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param pcbInstr Where to store the size of the instruction. (This
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * is also stored in PDISCPUSTATE::opsize.) Optional.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncDISDECL(int) DISInstEx(RTUINTPTR uInstrAddr, DISCPUMODE enmCpuMode, uint32_t fFilter,
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Initialize the CPU state.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Note! The RT_BZERO make ASSUMPTIONS about the placement of apvUserData.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync RT_BZERO(pCpu, RT_OFFSETOF(DISCPUSTATE, apvUserData));
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync pCpu->pfnReadBytes = pfnReadBytes ? pfnReadBytes : disReadBytesDefault;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return disInstrWorker(pCpu, uInstrAddr, paOneByteMap, pcbInstr);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Internal worker for DISInstEx.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @returns VBox status code.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param pCpu Initialized cpu state.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param paOneByteMap The one byte opcode map to use.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param uInstrAddr Instruction address.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param pcbInstr Where to store the instruction size. Can be NULL.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic int disInstrWorker(PDISCPUSTATE pCpu, RTUINTPTR uInstrAddr, PCDISOPCODE paOneByteMap, uint32_t *pcbInstr)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Parse byte by byte.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync unsigned iByte = 0;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync uint8_t codebyte = disReadByte(pCpu, uInstrAddr+iByte);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* Hardcoded assumption about OP_* values!! */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* The REX prefix must precede the opcode byte(s). Any other placement is ignored. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /** Last prefix byte (for SSE2 extension tables); don't include the REX prefix */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync // segment override prefix byte
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync pCpu->idxSegPrefix = (DIS_SELREG)(paOneByteMap[codebyte].param1 - OP_PARM_REG_SEG_START);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* Segment prefixes for CS, DS, ES and SS are ignored in long mode. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync continue; //fetch the next byte
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync // lock prefix byte
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync continue; //fetch the next byte
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync // address size override prefix byte
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync continue; //fetch the next byte
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync // operand size override prefix byte
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync pCpu->opmode = DISCPUMODE_16BIT; /* for 32 and 64 bits mode (there is no 32 bits operand size override prefix) */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync continue; //fetch the next byte
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync // rep and repne are not really prefixes, but we'll treat them as such
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync continue; //fetch the next byte
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync continue; //fetch the next byte
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* REX prefix byte */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync pCpu->prefix_rex = DISPREFIX_REX_OP_2_FLAGS(paOneByteMap[codebyte].param1);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync pCpu->opmode = DISCPUMODE_64BIT; /* overrides size prefix byte */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync continue; //fetch the next byte
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync cbInc = disParseInstruction(uInstrAddr + iByte, &paOneByteMap[pCpu->opcode], pCpu);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync AssertMsg(pCpu->opsize == iByte || RT_FAILURE_NP(pCpu->rc), ("%u %u\n", pCpu->opsize, iByte));
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//*****************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//*****************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic unsigned disParseInstruction(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISCPUSTATE pCpu)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync bool fFiltered = false;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync // Store the opcode format string for disasmPrintf
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Apply filter to instruction type to determine if a full disassembly is required.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Note! Multibyte opcodes are always marked harmless until the final byte.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* Not filtered out -> full disassembly */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync // Should contain the parameter type on input
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* Correct the operand size if the instruction is marked as forced or default 64 bits */
09127e6ed46502ff8a6a521713ee8ace53667683vboxsync /* Forced 32 bits operand size for certain instructions (mov crx, mov drx). */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync size += pCpu->pfnDisasmFnTable[pOp->idxParse1](uCodePtr, pOp, &pCpu->param1, pCpu);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync if (fFiltered == false) pCpu->param1.cb = DISGetParamSize(pCpu, &pCpu->param1);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync size += pCpu->pfnDisasmFnTable[pOp->idxParse2](uCodePtr+size, pOp, &pCpu->param2, pCpu);
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync if (fFiltered == false) pCpu->param2.cb = DISGetParamSize(pCpu, &pCpu->param2);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync size += pCpu->pfnDisasmFnTable[pOp->idxParse3](uCodePtr+size, pOp, &pCpu->param3, pCpu);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync if (fFiltered == false) pCpu->param3.cb = DISGetParamSize(pCpu, &pCpu->param3);
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync // else simple one byte instruction
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//*****************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/* Floating point opcode parsing */
int index;
unsigned size = 0;
unsigned ModRM;
return size;
static const char *szSIBBaseReg64[16] = {"RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"};
static const char *szSIBIndexReg64[16]= {"RAX", "RCX", "RDX", "RBX", NULL, "RBP", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"};
const char **ppszSIBIndexReg;
const char **ppszSIBBaseReg;
if (scale != 0)
unsigned SIB;
return size;
unsigned ParseSIB_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
unsigned SIB;
return size;
switch (vtype)
switch (vtype)
switch (mod)
switch (mod)
unsigned QueryModRM(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu, unsigned *pSibInc)
unsigned sibinc;
unsigned size = 0;
if (!pSibInc)
*pSibInc = 0;
switch (mod)
size += sizeof(char);
switch (mod)
size += sizeof(char);
return size;
unsigned QueryModRM_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu, unsigned *pSibInc)
unsigned sibinc;
unsigned size = 0;
if (!pSibInc)
*pSibInc = 0;
switch (mod)
size += sizeof(char);
switch (mod)
size += sizeof(char);
return size;
AssertFailed();
* This instruction is always treated as a register-to-register (MOD = 11) instruction, regardless of the
return size;
unsigned ParseModRM_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
* This instruction is always treated as a register-to-register (MOD = 11) instruction, regardless of the
return size;
return sizeof(uint8_t);
unsigned ParseImmByte_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
return sizeof(uint8_t);
return sizeof(uint8_t);
unsigned ParseImmByteSX_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
return sizeof(uint8_t);
return sizeof(uint16_t);
unsigned ParseImmUshort_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
return sizeof(uint16_t);
return sizeof(uint32_t);
unsigned ParseImmUlong_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
return sizeof(uint32_t);
return sizeof(uint64_t);
unsigned ParseImmQword_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
return sizeof(uint64_t);
return sizeof(uint32_t);
return sizeof(uint64_t);
return sizeof(uint16_t);
unsigned ParseImmV_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
return sizeof(uint32_t);
return sizeof(uint64_t);
return sizeof(uint16_t);
return sizeof(uint16_t);
return sizeof(uint32_t);
unsigned ParseImmZ_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
return sizeof(uint16_t);
return sizeof(uint32_t);
unsigned ParseImmBRel_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
return sizeof(int32_t);
return sizeof(int32_t);
return sizeof(int16_t);
unsigned ParseImmVRel_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
return sizeof(int16_t);
return sizeof(int32_t);
return sizeof(uint32_t);
return sizeof(uint64_t);
return sizeof(uint32_t);
return sizeof(uint16_t);
unsigned ParseImmAddr_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
return sizeof(uint32_t);
return sizeof(uint64_t);
return sizeof(uint32_t);
return sizeof(uint16_t);
return sizeof(uint32_t);
unsigned ParseImmAddrF_SizeOnly(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
return sizeof(uint32_t);
unsigned ParseTwoByteEsc(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
return size;
unsigned ParseThreeByteEsc4(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
return size;
unsigned ParseThreeByteEsc5(RTUINTPTR uCodePtr, PCDISOPCODE pOp, PDISOPPARAM pParam, PDISCPUSTATE pCpu)
return size;
unsigned size = 0;
return size;
return size;
int idx;
return sizeof(uint8_t);
return size;
return size;
return size;
return size;
#ifdef DEBUG_Sander
#ifdef DEBUG_Sander /* bird, 2005-06-28: Alex is getting this during full installation of win2ksp4. */
return size;
return size;
return size;
return size;
return size;
return size;
return size;
return size;
return size;
return size;
return size;
static const char *szModRMReg8[] = {"AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH", "R8B", "R9B", "R10B", "R11B", "R12B", "R13B", "R14B", "R15B", "SPL", "BPL", "SIL", "DIL"};
static const char *szModRMReg16[] = {"AX", "CX", "DX", "BX", "SP", "BP", "SI", "DI", "R8W", "R9W", "R10W", "R11W", "R12W", "R13W", "R14W", "R15W"};
static const char *szModRMReg32[] = {"EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI", "R8D", "R9D", "R10D", "R11D", "R12D", "R13D", "R14D", "R15D"};
static const char *szModRMReg64[] = {"RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"};
static const char *szModRMReg1616[8] = {"BX+SI", "BX+DI", "BP+SI", "BP+DI", "SI", "DI", "BP", "BX"};
static const int BaseModRMReg16[8] = { USE_REG_BX, USE_REG_BX, USE_REG_BP, USE_REG_BP, USE_REG_SI, USE_REG_DI, USE_REG_BP, USE_REG_BX};
static void disasmModRMReg(PDISCPUSTATE pCpu, PCDISOPCODE pOp, unsigned idx, PDISOPPARAM pParam, int fRegAddr)
if (fRegAddr)
case DISCPUMODE_32BIT:
case DISCPUMODE_64BIT:
case DISCPUMODE_16BIT:
switch (subtype)
case OP_PARM_b:
case OP_PARM_w:
case OP_PARM_d:
case OP_PARM_q:
DECL_NO_INLINE(static, void)
AssertMsgFailed(("%RTptr LB %zx off=%RTptr (%.*Rhxs)", uAddress, cbSrc, off, cbInstr, pCpu->abInstr));
AssertMsgFailed(("%RTptr LB %zx off=%RTptr (%.16Rhxs)", uAddress, cbSrc, off, cbInstr, pCpu->abInstr));
AssertMsgFailed(("%RTptr LB %zx off=%RTptr (%.*Rhxs)", uAddress, cbSrc, off, sizeof(pCpu->abInstr), pCpu->abInstr));
DECLCALLBACK(int) disReadBytesDefault(PDISCPUSTATE pCpu, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)
#ifdef IN_RING0
return VERR_DIS_NO_READ_CALLBACK;
return VINF_SUCCESS;
return bTemp;
uTemp.u = 0;
return uTemp.u;
uTemp.u = 0;
return uTemp.u;
uTemp.u = 0;
return uTemp.u;
case OP_BTC:
case OP_BTR:
case OP_BTS:
case OP_CMPXCHG:
case OP_XADD:
case OP_ADC:
case OP_ADD:
case OP_AND:
case OP_DEC:
case OP_INC:
case OP_NEG:
case OP_NOT:
case OP_OR:
case OP_SBB:
case OP_SUB:
case OP_XCHG:
case OP_XOR: