DisasmCore.cpp revision 984cf3e37b9418d28b1ed1a3be9bede900c61e1d
6c6531128b39093daeac902a8705c0bdf15b31ccvboxsync * VBox disassembler:
f7b81dcd1a01325f5ca2806c2694b8f1d3b9eb4cvboxsync * Core components
f74e35c55b43bdbc2d2ac21d61ac77ab764deadcvboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
f74e35c55b43bdbc2d2ac21d61ac77ab764deadcvboxsync * available from http://www.virtualbox.org. This file is free software;
f74e35c55b43bdbc2d2ac21d61ac77ab764deadcvboxsync * you can redistribute it and/or modify it under the terms of the GNU
f74e35c55b43bdbc2d2ac21d61ac77ab764deadcvboxsync * General Public License (GPL) as published by the Free Software
f74e35c55b43bdbc2d2ac21d61ac77ab764deadcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
f74e35c55b43bdbc2d2ac21d61ac77ab764deadcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
f74e35c55b43bdbc2d2ac21d61ac77ab764deadcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
f74e35c55b43bdbc2d2ac21d61ac77ab764deadcvboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
f74e35c55b43bdbc2d2ac21d61ac77ab764deadcvboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
f74e35c55b43bdbc2d2ac21d61ac77ab764deadcvboxsync * additional information or have any questions.
f74e35c55b43bdbc2d2ac21d61ac77ab764deadcvboxsync/*******************************************************************************
f7b81dcd1a01325f5ca2806c2694b8f1d3b9eb4cvboxsync* Header Files *
f74e35c55b43bdbc2d2ac21d61ac77ab764deadcvboxsync*******************************************************************************/
f74e35c55b43bdbc2d2ac21d61ac77ab764deadcvboxsync/*******************************************************************************
f74e35c55b43bdbc2d2ac21d61ac77ab764deadcvboxsync* Internal Functions *
6c6531128b39093daeac902a8705c0bdf15b31ccvboxsync*******************************************************************************/
6c6531128b39093daeac902a8705c0bdf15b31ccvboxsyncstatic int disCoreOne(PDISCPUSTATE pCpu, RTUINTPTR InstructionAddr, unsigned *pcbInstruction);
2599750883f13b2a38c421dc073df83e2f9cdae6vboxsyncstatic void disasmAddString(char *psz, const char *pszString);
2599750883f13b2a38c421dc073df83e2f9cdae6vboxsyncstatic void disasmAddStringF(char *psz, uint32_t cbString, const char *pszFormat, ...);
f74e35c55b43bdbc2d2ac21d61ac77ab764deadcvboxsync# define disasmAddString(psz, pszString) do {} while (0)
f74e35c55b43bdbc2d2ac21d61ac77ab764deadcvboxsync# define disasmAddStringF(psz, cbString, pszFormat...) do {} while (0) /* Arg wanna get rid of that warning */
f74e35c55b43bdbc2d2ac21d61ac77ab764deadcvboxsyncstatic unsigned QueryModRM(RTUINTPTR pu8CodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu, unsigned *pSibInc = NULL);
2599750883f13b2a38c421dc073df83e2f9cdae6vboxsyncstatic unsigned QueryModRM_SizeOnly(RTUINTPTR pu8CodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu, unsigned *pSibInc = NULL);
f74e35c55b43bdbc2d2ac21d61ac77ab764deadcvboxsyncstatic void UseSIB(RTUINTPTR pu8CodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu);
f74e35c55b43bdbc2d2ac21d61ac77ab764deadcvboxsyncstatic unsigned ParseSIB_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu);
b4b896baff58dad1f81179386beed73197bf59bevboxsync/*******************************************************************************
f74e35c55b43bdbc2d2ac21d61ac77ab764deadcvboxsync* Global Variables *
f74e35c55b43bdbc2d2ac21d61ac77ab764deadcvboxsync*******************************************************************************/
b4b896baff58dad1f81179386beed73197bf59bevboxsync * Parses one instruction.
b4b896baff58dad1f81179386beed73197bf59bevboxsync * The result is found in pCpu.
b4b896baff58dad1f81179386beed73197bf59bevboxsync * @returns Success indicator.
c0704390ccf86cde88ad1e69dedf77d3e57aa15avboxsync * @param pCpu Pointer to cpu structure which has DISCPUSTATE::mode set correctly.
c0704390ccf86cde88ad1e69dedf77d3e57aa15avboxsync * @param InstructionAddr Pointer to the instruction to parse.
c0704390ccf86cde88ad1e69dedf77d3e57aa15avboxsync * @param pcbInstruction Where to store the size of the instruction.
c0704390ccf86cde88ad1e69dedf77d3e57aa15avboxsync * NULL is allowed.
978580e1feeb8eb42df0b6366b9c8bebbb9fb02cvboxsyncDISDECL(int) DISCoreOne(PDISCPUSTATE pCpu, RTUINTPTR InstructionAddr, unsigned *pcbInstruction)
978580e1feeb8eb42df0b6366b9c8bebbb9fb02cvboxsync * Reset instruction settings
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;
if (scale != 0)
disasmAddStringF(szTemp, sizeof(szTemp), "%s+%s%s", szSIBBaseReg[base], szSIBIndexReg[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)
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(uint16_t);
unsigned ParseImmV_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint32_t);
return sizeof(uint16_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(uint16_t);
unsigned ParseImmVRel_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(int32_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;
const char *szModRMReg8_64[] = {"AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH", "R8L", "R9L", "R10L", "R11L", "R12L", "R13L", "R14L", "R15L"};
const char *szModRMReg64[] = {"RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"};
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};
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
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:
#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