DisasmCore.cpp revision 7de10baf03a4b6aaaf7bb0bc21db9d40b49a2ce1
00fa3bc989ffe84474e828c8b90b24284dcfdf0cvboxsync * VBox disassembler:
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsync * Core components
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsync * available from http://www.virtualbox.org. This file is free software;
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsync * you can redistribute it and/or modify it under the terms of the GNU
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsync * General Public License (GPL) as published by the Free Software
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsync * additional information or have any questions.
0c437bb10c61b229407a7517efde04dfe3b1e4a1vboxsync/*******************************************************************************
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync* Header Files *
0c437bb10c61b229407a7517efde04dfe3b1e4a1vboxsync*******************************************************************************/
ec21c063515d0931111f0c1f8d6f4bc8e7a6c882vboxsync/*******************************************************************************
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsync* Internal Functions *
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsync*******************************************************************************/
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsyncstatic int disCoreOne(PDISCPUSTATE pCpu, RTUINTPTR InstructionAddr, unsigned *pcbInstruction);
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsyncstatic void disasmAddString(char *psz, const char *pszString);
3e4aa8bbe164918330c1a06f89ead71c2ec4a621vboxsyncstatic void disasmAddStringF(char *psz, uint32_t cbString, const char *pszFormat, ...);
9347f1987dfb760943aba5a9ef094c6066901be3vboxsync# define disasmAddString(psz, pszString) do {} while (0)
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsync# define disasmAddStringF(psz, cbString, pszFormat...) do {} while (0) /* Arg wanna get rid of that warning */
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsyncstatic unsigned QueryModRM(RTUINTPTR pu8CodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu, unsigned *pSibInc = NULL);
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsyncstatic unsigned QueryModRM_SizeOnly(RTUINTPTR pu8CodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu, unsigned *pSibInc = NULL);
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsyncstatic void UseSIB(RTUINTPTR pu8CodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu);
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsyncstatic unsigned ParseSIB_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu);
faa31dfcb46e5e2fb9c2bf224d113a0ca136ddecvboxsync/*******************************************************************************
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsync* Global Variables *
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsync*******************************************************************************/
DISDECL(int) DISCoreOneEx(RTUINTPTR InstructionAddr, DISCPUMODE enmCpuMode, PFN_DIS_READBYTES pfnReadBytes, void *pvUser,
unsigned iByte = 0;
unsigned cbInc;
switch (opcode)
case OP_INVALID:
case OP_SEG:
case OP_LOCK:
case OP_ADDRSIZE:
case OP_OPSIZE:
pCpu->opmode = CPUMODE_16BIT; /* for 32 and 64 bits mode (there is no 32 bits operand size override prefix) */
case OP_REPE:
case OP_REPNE:
case OP_REX:
if (pcbInstruction)
return VINF_SUCCESS;
int size = 0;
bool fFiltered = false;
#ifndef DIS_CORE_ONLY
fFiltered = true;
return size;
int index;
#ifndef DIS_CORE_ONLY
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)
disasmAddStringF(szTemp, sizeof(szTemp), "%s+%s%s", ppszSIBBaseReg[base], ppszSIBIndexReg[index], szSIBScale[scale]);
unsigned SIB;
return size;
unsigned ParseSIB_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
unsigned SIB;
return size;
switch (vtype)
switch (vtype)
switch (mod)
switch (mod)
unsigned QueryModRM(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER 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 lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER 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 ParseIllegal(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
AssertFailed();
return size;
unsigned ParseModRM_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return size;
unsigned ParseModFence(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
unsigned ParseImmByte(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint8_t);
unsigned ParseImmByte_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint8_t);
unsigned ParseImmByteSX(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
if (pCpu->opmode == CPUMODE_32BIT) /** @todo In AMD64 mode we're ending up with 16-bit parvals now, see the disassembler _output_ for tstAsmSignExtend-1.asm. */
return sizeof(uint8_t);
unsigned ParseImmByteSX_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint8_t);
unsigned ParseImmUshort(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint16_t);
unsigned ParseImmUshort_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint16_t);
unsigned ParseImmUlong(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint32_t);
unsigned ParseImmUlong_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint32_t);
unsigned ParseImmQword(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
disasmAddStringF(&pParam->szParam[9], sizeof(pParam->szParam)-9, "%08Xh", (uint32_t)(pParam->parval >> 32));
return sizeof(uint64_t);
unsigned ParseImmQword_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint64_t);
return sizeof(uint32_t);
return sizeof(uint64_t);
return sizeof(uint16_t);
unsigned ParseImmV_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER 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 lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint16_t);
return sizeof(uint32_t);
unsigned ParseImmBRel(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
unsigned ParseImmBRel_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
unsigned ParseImmVRel(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(int32_t);
return sizeof(int64_t);
return sizeof(uint16_t);
unsigned ParseImmVRel_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(int32_t);
return sizeof(int64_t);
return sizeof(uint16_t);
unsigned ParseImmAddr(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "0%04X:0%08Xh", (uint32_t)(pParam->parval>>32), (uint32_t)pParam->parval);
return sizeof(uint32_t);
disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "[0%08X%08Xh]", (uint32_t)(pParam->disp64 >> 32), (uint32_t)pParam->disp64);
return sizeof(uint64_t);
disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "0%04X:0%04Xh", (uint32_t)(pParam->parval>>16), (uint16_t)pParam->parval );
return sizeof(uint32_t);
return sizeof(uint16_t);
unsigned ParseImmAddr_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint32_t);
return sizeof(uint64_t);
return sizeof(uint32_t);
return sizeof(uint16_t);
unsigned ParseFixedReg(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), (pCpu->addrmode == CPUMODE_32BIT) ? "DS:ESI" : "DS:SI");
disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), (pCpu->addrmode == CPUMODE_32BIT) ? "DS:ESI" : "DS:SI");
disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), (pCpu->addrmode == CPUMODE_32BIT) ? "ES:EDI" : "ES:DI");
disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), (pCpu->addrmode == CPUMODE_32BIT) ? "ES:EDI" : "ES:DI");
unsigned ParseTwoByteEsc(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return size;
unsigned ParseNopPause(RTUINTPTR pu8CodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
unsigned size = 0;
return size;
unsigned ParseImmGrpl(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return size;
unsigned ParseShiftGrp2(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
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_64[] = {"AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH", "R8L", "R9L", "R10L", "R11L", "R12L", "R13L", "R14L", "R15L"};
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};
void disasmModRMReg(PDISCPUSTATE pCpu, PCOPCODE pOp, unsigned idx, POP_PARAMETER pParam, int fRegAddr)
if (fRegAddr)
case CPUMODE_32BIT:
case CPUMODE_64BIT:
case CPUMODE_16BIT:
switch (subtype)
case OP_PARM_b:
case OP_PARM_w:
case OP_PARM_d:
case OP_PARM_q:
#ifdef IN_RING3
#ifdef IN_RING3
case CPUMODE_32BIT:
case CPUMODE_64BIT:
case CPUMODE_16BIT:
switch (subtype)
case OP_PARM_b:
case OP_PARM_w:
case OP_PARM_d:
case OP_PARM_q:
case OP_PARM_dq:
case OP_PARM_p:
case OP_PARM_s:
case OP_PARM_z:
disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "%s:", szModRMSegReg[pCpu->enmPrefixSeg]);
#ifndef IN_GC
int rc;
return temp;
#ifdef IN_RING0
int rc;
return temp;
#ifdef IN_RING0
int rc;
return temp;
#ifdef IN_RING0
int rc;
return temp;
#ifdef IN_RING0
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:
if (pCpu->param1.flags & (USE_BASE | USE_INDEX | USE_DISPLACEMENT32 | USE_DISPLACEMENT16 | USE_DISPLACEMENT8 | USE_RIPDISPLACEMENT32))