DisasmReg.cpp revision 6d51216d13610f142b377a8e15c6c51adb83ba1b
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * VBox disassembler- Register Info Helpers.
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * Copyright (C) 2006-2012 Oracle Corporation
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * This file is part of VirtualBox Open Source Edition (OSE), as
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * available from http://www.virtualbox.org. This file is free software;
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * you can redistribute it and/or modify it under the terms of the GNU
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * General Public License (GPL) as published by the Free Software
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * Foundation, in version 2 as it comes in the "COPYING" file of the
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster/*******************************************************************************
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster* Header Files *
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster*******************************************************************************/
0a99555401a033704f1f171baab6db11fb5528f2Allan Foster/*******************************************************************************
5deb404a3d276c42ef3e4adef5e584211ab1e8ddjeff.schenk* Global Variables *
5deb404a3d276c42ef3e4adef5e584211ab1e8ddjeff.schenk*******************************************************************************/
5deb404a3d276c42ef3e4adef5e584211ab1e8ddjeff.schenk * Array for accessing 64-bit general registers in VMMREGFRAME structure
5deb404a3d276c42ef3e4adef5e584211ab1e8ddjeff.schenk * by register's index from disasm.
5deb404a3d276c42ef3e4adef5e584211ab1e8ddjeff.schenkstatic const unsigned g_aReg64Index[] =
5deb404a3d276c42ef3e4adef5e584211ab1e8ddjeff.schenk RT_OFFSETOF(CPUMCTXCORE, rax), /* DISGREG_RAX */
5deb404a3d276c42ef3e4adef5e584211ab1e8ddjeff.schenk RT_OFFSETOF(CPUMCTXCORE, rcx), /* DISGREG_RCX */
5deb404a3d276c42ef3e4adef5e584211ab1e8ddjeff.schenk RT_OFFSETOF(CPUMCTXCORE, rdx), /* DISGREG_RDX */
5deb404a3d276c42ef3e4adef5e584211ab1e8ddjeff.schenk RT_OFFSETOF(CPUMCTXCORE, rbx), /* DISGREG_RBX */
5deb404a3d276c42ef3e4adef5e584211ab1e8ddjeff.schenk RT_OFFSETOF(CPUMCTXCORE, rsp), /* DISGREG_RSP */
5deb404a3d276c42ef3e4adef5e584211ab1e8ddjeff.schenk RT_OFFSETOF(CPUMCTXCORE, rbp), /* DISGREG_RBP */
5deb404a3d276c42ef3e4adef5e584211ab1e8ddjeff.schenk RT_OFFSETOF(CPUMCTXCORE, rsi), /* DISGREG_RSI */
5deb404a3d276c42ef3e4adef5e584211ab1e8ddjeff.schenk RT_OFFSETOF(CPUMCTXCORE, rdi), /* DISGREG_RDI */
5deb404a3d276c42ef3e4adef5e584211ab1e8ddjeff.schenk RT_OFFSETOF(CPUMCTXCORE, r10), /* DISGREG_R10 */
5deb404a3d276c42ef3e4adef5e584211ab1e8ddjeff.schenk RT_OFFSETOF(CPUMCTXCORE, r11), /* DISGREG_R11 */
5deb404a3d276c42ef3e4adef5e584211ab1e8ddjeff.schenk RT_OFFSETOF(CPUMCTXCORE, r12), /* DISGREG_R12 */
5deb404a3d276c42ef3e4adef5e584211ab1e8ddjeff.schenk RT_OFFSETOF(CPUMCTXCORE, r13), /* DISGREG_R13 */
static const unsigned g_aReg32Index[] =
#define DIS_WRITE_REG32(p, idx, val) (*(uint64_t *)((char *)(p) + g_aReg32Index[idx]) = (uint32_t)val)
static const unsigned g_aReg16Index[] =
static const unsigned g_aReg8Index[] =
static const unsigned g_aRegSegIndex[] =
static const unsigned g_aRegHidSegIndex[] =
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:
case OP_PARM_dq:
return DISSELREG_SS;
return DISSELREG_DS;
case DISSELREG_ES:
case DISSELREG_CS:
case DISSELREG_SS:
case DISSELREG_DS:
case DISSELREG_FS:
case DISSELREG_GS:
AssertFailed();
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
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(PCCPUMCTXCORE pCtx, DISSELREG 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, PCDISSTATE pDis, PCDISOPPARAM pParam, PDISQPVPARAMVAL pParamVal, DISQPVWHICH parmtype)
if (RT_FAILURE(DISFetchReg8(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val8))) return VERR_INVALID_PARAMETER;
if (RT_FAILURE(DISFetchReg16(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val16))) return VERR_INVALID_PARAMETER;
if (RT_FAILURE(DISFetchReg32(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val32))) return VERR_INVALID_PARAMETER;
if (RT_FAILURE(DISFetchReg64(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val64))) return VERR_INVALID_PARAMETER;
AssertFailed();
return VERR_INVALID_PARAMETER;
if (RT_FAILURE(DISFetchReg16(pCtx, pParam->Index.idxGenReg, &val16))) return VERR_INVALID_PARAMETER;
if (RT_FAILURE(DISFetchReg32(pCtx, pParam->Index.idxGenReg, &val32))) return VERR_INVALID_PARAMETER;
if (RT_FAILURE(DISFetchReg64(pCtx, pParam->Index.idxGenReg, &val64))) return VERR_INVALID_PARAMETER;
AssertFailed();
return VINF_SUCCESS;
if (pParam->fUse & (DISUSE_REG_GEN8|DISUSE_REG_GEN16|DISUSE_REG_GEN32|DISUSE_REG_GEN64|DISUSE_REG_FP|DISUSE_REG_MMX|DISUSE_REG_XMM|DISUSE_REG_CR|DISUSE_REG_DBG|DISUSE_REG_SEG|DISUSE_REG_TEST))
// Caller needs to interpret the register according to the instruction (source/target, special value etc)
return VINF_SUCCESS;
if (RT_FAILURE(DISFetchReg8(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val8))) return VERR_INVALID_PARAMETER;
if (RT_FAILURE(DISFetchReg16(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val16))) return VERR_INVALID_PARAMETER;
if (RT_FAILURE(DISFetchReg32(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val32))) return VERR_INVALID_PARAMETER;
if (RT_FAILURE(DISFetchReg64(pCtx, pParam->Base.idxGenReg, &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->fUse & (DISUSE_IMMEDIATE16|DISUSE_IMMEDIATE16_REL|DISUSE_IMMEDIATE_ADDR_0_16|DISUSE_IMMEDIATE16_SX8))
AssertMsg(pParamVal->size == pParam->cb || ((pParam->cb == 1) && (pParam->fUse & DISUSE_IMMEDIATE16_SX8)), ("pParamVal->size %d vs %d EIP=%RX32\n", pParamVal->size, pParam->cb, pCtx->eip) );
if (pParam->fUse & (DISUSE_IMMEDIATE32|DISUSE_IMMEDIATE32_REL|DISUSE_IMMEDIATE_ADDR_0_32|DISUSE_IMMEDIATE32_SX8))
Assert(pParamVal->size == pParam->cb || ((pParam->cb == 1) && (pParam->fUse & DISUSE_IMMEDIATE32_SX8)) );
Assert(pParamVal->size == pParam->cb || ((pParam->cb == 1) && (pParam->fUse & DISUSE_IMMEDIATE64_SX8)) );
return VINF_SUCCESS;
DISDECL(int) DISQueryParamRegPtr(PCPUMCTXCORE pCtx, PCDISSTATE pDis, PCDISOPPARAM pParam, void **ppReg, size_t *pcbSize)
if (pParam->fUse & (DISUSE_REG_GEN8|DISUSE_REG_GEN16|DISUSE_REG_GEN32|DISUSE_REG_FP|DISUSE_REG_MMX|DISUSE_REG_XMM|DISUSE_REG_CR|DISUSE_REG_DBG|DISUSE_REG_SEG|DISUSE_REG_TEST))
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VERR_INVALID_PARAMETER;