DisasmReg.cpp revision e3e7d748172761a1d90c71103a98a9aa7f876420
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * VBox disassembler:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Core components
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * available from http://www.virtualbox.org. This file is free software;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * you can redistribute it and/or modify it under the terms of the GNU
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * General Public License (GPL) as published by the Free Software
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * additional information or have any questions.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync/*******************************************************************************
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync* Header Files *
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync*******************************************************************************/
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/*******************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync* Global Variables *
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync*******************************************************************************/
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Array for accessing 64-bit general registers in VMMREGFRAME structure
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * by register's index from disasm.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic const unsigned g_aReg64Index[] =
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Macro for accessing 64-bit general purpose registers in CPUMCTXCORE structure.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#define DIS_READ_REG64(p, idx) (*(uint64_t *)((char *)(p) + g_aReg64Index[idx]))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#define DIS_WRITE_REG64(p, idx, val) (*(uint64_t *)((char *)(p) + g_aReg64Index[idx]) = val)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#define DIS_PTR_REG64(p, idx) ( (uint64_t *)((char *)(p) + g_aReg64Index[idx]))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Array for accessing 32-bit general registers in VMMREGFRAME structure
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * by register's index from disasm.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic const unsigned g_aReg32Index[] =
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Macro for accessing 32-bit general purpose registers in CPUMCTXCORE structure.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#define DIS_READ_REG32(p, idx) (*(uint32_t *)((char *)(p) + g_aReg32Index[idx]))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#define DIS_WRITE_REG32(p, idx, val) (*(uint32_t *)((char *)(p) + g_aReg32Index[idx]) = val)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#define DIS_PTR_REG32(p, idx) ( (uint32_t *)((char *)(p) + g_aReg32Index[idx]))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Array for accessing 16-bit general registers in CPUMCTXCORE structure
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * by register's index from disasm.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic const unsigned g_aReg16Index[] =
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Macro for accessing 16-bit general purpose registers in CPUMCTXCORE structure.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#define DIS_READ_REG16(p, idx) (*(uint16_t *)((char *)(p) + g_aReg16Index[idx]))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#define DIS_WRITE_REG16(p, idx, val) (*(uint16_t *)((char *)(p) + g_aReg16Index[idx]) = val)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#define DIS_PTR_REG16(p, idx) ( (uint16_t *)((char *)(p) + g_aReg16Index[idx]))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Array for accessing 8-bit general registers in CPUMCTXCORE structure
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * by register's index from disasm.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic const unsigned g_aReg8Index[] =
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RT_OFFSETOF(CPUMCTXCORE, eax) + 1, /* USE_REG_AH */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RT_OFFSETOF(CPUMCTXCORE, ecx) + 1, /* USE_REG_CH */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RT_OFFSETOF(CPUMCTXCORE, edx) + 1, /* USE_REG_DH */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Macro for accessing 8-bit general purpose registers in CPUMCTXCORE structure.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#define DIS_READ_REG8(p, idx) (*(uint8_t *)((char *)(p) + g_aReg8Index[idx]))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#define DIS_WRITE_REG8(p, idx, val) (*(uint8_t *)((char *)(p) + g_aReg8Index[idx]) = val)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#define DIS_PTR_REG8(p, idx) ( (uint8_t *)((char *)(p) + g_aReg8Index[idx]))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Array for accessing segment registers in CPUMCTXCORE structure
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * by register's index from disasm.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic const unsigned g_aRegSegIndex[] =
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic const unsigned g_aRegHidSegIndex[] =
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Macro for accessing segment registers in CPUMCTXCORE structure.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#define DIS_READ_REGSEG(p, idx) (*((uint16_t *)((char *)(p) + g_aRegSegIndex[idx])))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#define DIS_WRITE_REGSEG(p, idx, val) (*((uint16_t *)((char *)(p) + g_aRegSegIndex[idx])) = val)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync//*****************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync//*****************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncDISDECL(int) DISGetParamSize(PDISCPUSTATE pCpu, POP_PARAMETER pParam)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync subtype = (pCpu->opmode == CPUMODE_32BIT) ? OP_PARM_d : OP_PARM_w;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync else //@todo dangerous!!!
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync//*****************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync//*****************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncDISDECL(int) DISDetectSegReg(PDISCPUSTATE pCpu, POP_PARAMETER pParam)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Use specified SEG: prefix. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Guess segment register by parameter type. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (pParam->flags & (USE_REG_GEN32|USE_REG_GEN64|USE_REG_GEN16))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (pParam->base.reg_gen == USE_REG_ESP || pParam->base.reg_gen == USE_REG_EBP)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Default is use DS: for data access. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync//*****************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync//*****************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncDISDECL(uint8_t) DISQuerySegPrefixByte(PDISCPUSTATE pCpu)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return 0x26;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return 0x2E;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return 0x36;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return 0x3E;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return 0x64;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync return 0x65;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Returns the value of the specified 8 bits general purpose register
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncDISDECL(int) DISFetchReg8(PCPUMCTXCORE pCtx, unsigned reg8, uint8_t *pVal)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertReturn(reg8 < ELEMENTS(g_aReg8Index), VERR_INVALID_PARAMETER);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Returns the value of the specified 16 bits general purpose register
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncDISDECL(int) DISFetchReg16(PCPUMCTXCORE pCtx, unsigned reg16, uint16_t *pVal)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertReturn(reg16 < ELEMENTS(g_aReg16Index), VERR_INVALID_PARAMETER);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Returns the value of the specified 32 bits general purpose register
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncDISDECL(int) DISFetchReg32(PCPUMCTXCORE pCtx, unsigned reg32, uint32_t *pVal)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertReturn(reg32 < ELEMENTS(g_aReg32Index), VERR_INVALID_PARAMETER);
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
* Returns the value of the specified segment register including a pointer to the hidden register in the supplied cpu context
DISDECL(int) DISFetchRegSegEx(PCPUMCTXCORE pCtx, unsigned sel, RTSEL *pVal, CPUMSELREGHID **ppSelHidReg)
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
DISDECL(int) DISQueryParamVal(PCPUMCTXCORE pCtx, PDISCPUSTATE pCpu, POP_PARAMETER pParam, POP_PARAMVAL pParamVal, PARAM_TYPE parmtype)
if (VBOX_FAILURE(DISFetchReg8(pCtx, pParam->base.reg_gen, &pParamVal->val.val8))) return VERR_INVALID_PARAMETER;
if (VBOX_FAILURE(DISFetchReg16(pCtx, pParam->base.reg_gen, &pParamVal->val.val16))) return VERR_INVALID_PARAMETER;
if (VBOX_FAILURE(DISFetchReg32(pCtx, pParam->base.reg_gen, &pParamVal->val.val32))) return VERR_INVALID_PARAMETER;
if (VBOX_FAILURE(DISFetchReg64(pCtx, pParam->base.reg_gen, &pParamVal->val.val64))) return VERR_INVALID_PARAMETER;
AssertFailed();
return VERR_INVALID_PARAMETER;
if (VBOX_FAILURE(DISFetchReg32(pCtx, pParam->index.reg_gen, &val32))) return VERR_INVALID_PARAMETER;
AssertFailed();
AssertFailed();
return VINF_SUCCESS;
if (pParam->flags & (USE_REG_GEN8|USE_REG_GEN16|USE_REG_GEN32|USE_REG_GEN64|USE_REG_FP|USE_REG_MMX|USE_REG_XMM|USE_REG_CR|USE_REG_DBG|USE_REG_SEG|USE_REG_TEST))
// Caller needs to interpret the register according to the instruction (source/target, special value etc)
return VINF_SUCCESS;
if (VBOX_FAILURE(DISFetchReg8(pCtx, pParam->base.reg_gen, &pParamVal->val.val8))) return VERR_INVALID_PARAMETER;
if (VBOX_FAILURE(DISFetchReg16(pCtx, pParam->base.reg_gen, &pParamVal->val.val16))) return VERR_INVALID_PARAMETER;
if (VBOX_FAILURE(DISFetchReg32(pCtx, pParam->base.reg_gen, &pParamVal->val.val32))) return VERR_INVALID_PARAMETER;
if (VBOX_FAILURE(DISFetchReg64(pCtx, pParam->base.reg_gen, &pParamVal->val.val64))) return VERR_INVALID_PARAMETER;
// Caller needs to interpret the register according to the instruction (source/target, special value etc)
return VINF_SUCCESS;
if (pParam->flags & (USE_IMMEDIATE16|USE_IMMEDIATE16_REL|USE_IMMEDIATE_ADDR_0_16|USE_IMMEDIATE16_SX8))
AssertMsg(pParamVal->size == pParam->size || ((pParam->size == 1) && (pParam->flags & USE_IMMEDIATE16_SX8)), ("pParamVal->size %d vs %d EIP=%VGv\n", pParamVal->size, pParam->size, pCtx->eip) );
if (pParam->flags & (USE_IMMEDIATE32|USE_IMMEDIATE32_REL|USE_IMMEDIATE_ADDR_0_32|USE_IMMEDIATE32_SX8))
Assert(pParamVal->size == pParam->size || ((pParam->size == 1) && (pParam->flags & USE_IMMEDIATE32_SX8)) );
return VINF_SUCCESS;
DISDECL(int) DISQueryParamRegPtr(PCPUMCTXCORE pCtx, PDISCPUSTATE pCpu, POP_PARAMETER pParam, void **ppReg, size_t *pcbSize)
if (pParam->flags & (USE_REG_GEN8|USE_REG_GEN16|USE_REG_GEN32|USE_REG_FP|USE_REG_MMX|USE_REG_XMM|USE_REG_CR|USE_REG_DBG|USE_REG_SEG|USE_REG_TEST))
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VERR_INVALID_PARAMETER;