diff options
Diffstat (limited to 'src/VBox/VMM/VMMR3/DBGFStack.cpp')
| -rw-r--r-- | src/VBox/VMM/VMMR3/DBGFStack.cpp | 101 |
1 files changed, 53 insertions, 48 deletions
diff --git a/src/VBox/VMM/VMMR3/DBGFStack.cpp b/src/VBox/VMM/VMMR3/DBGFStack.cpp index f01a6438..b6244e72 100644 --- a/src/VBox/VMM/VMMR3/DBGFStack.cpp +++ b/src/VBox/VMM/VMMR3/DBGFStack.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -25,6 +25,7 @@ #include <VBox/vmm/mm.h> #include "DBGFInternal.h" #include <VBox/vmm/vm.h> +#include <VBox/vmm/uvm.h> #include <VBox/err.h> #include <VBox/log.h> #include <iprt/param.h> @@ -37,9 +38,9 @@ /** * Read stack memory. */ -DECLINLINE(int) dbgfR3Read(PVM pVM, VMCPUID idCpu, void *pvBuf, PCDBGFADDRESS pSrcAddr, size_t cb, size_t *pcbRead) +DECLINLINE(int) dbgfR3Read(PUVM pUVM, VMCPUID idCpu, void *pvBuf, PCDBGFADDRESS pSrcAddr, size_t cb, size_t *pcbRead) { - int rc = DBGFR3MemRead(pVM, idCpu, pSrcAddr, pvBuf, cb); + int rc = DBGFR3MemRead(pUVM, idCpu, pSrcAddr, pvBuf, cb); if (RT_FAILURE(rc)) { /* fallback: byte by byte and zero the ones we fail to read. */ @@ -47,7 +48,7 @@ DECLINLINE(int) dbgfR3Read(PVM pVM, VMCPUID idCpu, void *pvBuf, PCDBGFADDRESS pS for (cbRead = 0; cbRead < cb; cbRead++) { DBGFADDRESS Addr = *pSrcAddr; - rc = DBGFR3MemRead(pVM, idCpu, DBGFR3AddrAdd(&Addr, cbRead), (uint8_t *)pvBuf + cbRead, 1); + rc = DBGFR3MemRead(pUVM, idCpu, DBGFR3AddrAdd(&Addr, cbRead), (uint8_t *)pvBuf + cbRead, 1); if (RT_FAILURE(rc)) break; } @@ -76,7 +77,7 @@ DECLINLINE(int) dbgfR3Read(PVM pVM, VMCPUID idCpu, void *pvBuf, PCDBGFADDRESS pS * @todo Add AMD64 support (needs teaming up with the module management for * unwind tables). */ -static int dbgfR3StackWalk(PVM pVM, VMCPUID idCpu, RTDBGAS hAs, PDBGFSTACKFRAME pFrame) +static int dbgfR3StackWalk(PUVM pUVM, VMCPUID idCpu, RTDBGAS hAs, PDBGFSTACKFRAME pFrame) { /* * Stop if we got a read error in the previous run. @@ -135,7 +136,7 @@ static int dbgfR3StackWalk(PVM pVM, VMCPUID idCpu, RTDBGAS hAs, PDBGFSTACKFRAME uArgs.pb = u.pb + cbStackItem + cbRetAddr; Assert(DBGFADDRESS_IS_VALID(&pFrame->AddrFrame)); - int rc = dbgfR3Read(pVM, idCpu, u.pv, + int rc = dbgfR3Read(pUVM, idCpu, u.pv, pFrame->fFlags & DBGFSTACKFRAME_FLAGS_ALL_VALID ? &pFrame->AddrReturnFrame : &pFrame->AddrFrame, @@ -155,8 +156,9 @@ static int dbgfR3StackWalk(PVM pVM, VMCPUID idCpu, RTDBGAS hAs, PDBGFSTACKFRAME /* Current PC - set by caller, just find symbol & line. */ if (DBGFADDRESS_IS_VALID(&pFrame->AddrPC)) { - pFrame->pSymPC = DBGFR3AsSymbolByAddrA(pVM, hAs, &pFrame->AddrPC, NULL /*offDisp*/, NULL /*phMod*/); - pFrame->pLinePC = DBGFR3LineByAddrAlloc(pVM, pFrame->AddrPC.FlatPtr, NULL); + pFrame->pSymPC = DBGFR3AsSymbolByAddrA(pUVM, hAs, &pFrame->AddrPC, RTDBGSYMADDR_FLAGS_LESS_OR_EQUAL, + NULL /*poffDisp*/, NULL /*phMod*/); + pFrame->pLinePC = DBGFR3AsLineByAddrA(pUVM, hAs, &pFrame->AddrPC, NULL /*poffDisp*/, NULL /*phMod*/); } } else /* 2nd and subsequent steps */ @@ -202,7 +204,7 @@ static int dbgfR3StackWalk(PVM pVM, VMCPUID idCpu, RTDBGAS hAs, PDBGFSTACKFRAME pFrame->AddrReturnPC.off = *uRet.pu16; } else - DBGFR3AddrFromFlat(pVM, &pFrame->AddrReturnPC, *uRet.pu16); + DBGFR3AddrFromFlat(pUVM, &pFrame->AddrReturnPC, *uRet.pu16); break; case DBGFRETURNTYPE_NEAR32: if (DBGFADDRESS_IS_VALID(&pFrame->AddrReturnPC)) @@ -211,7 +213,7 @@ static int dbgfR3StackWalk(PVM pVM, VMCPUID idCpu, RTDBGAS hAs, PDBGFSTACKFRAME pFrame->AddrReturnPC.off = *uRet.pu32; } else - DBGFR3AddrFromFlat(pVM, &pFrame->AddrReturnPC, *uRet.pu32); + DBGFR3AddrFromFlat(pUVM, &pFrame->AddrReturnPC, *uRet.pu32); break; case DBGFRETURNTYPE_NEAR64: if (DBGFADDRESS_IS_VALID(&pFrame->AddrReturnPC)) @@ -220,39 +222,40 @@ static int dbgfR3StackWalk(PVM pVM, VMCPUID idCpu, RTDBGAS hAs, PDBGFSTACKFRAME pFrame->AddrReturnPC.off = *uRet.pu64; } else - DBGFR3AddrFromFlat(pVM, &pFrame->AddrReturnPC, *uRet.pu64); + DBGFR3AddrFromFlat(pUVM, &pFrame->AddrReturnPC, *uRet.pu64); break; case DBGFRETURNTYPE_FAR16: - DBGFR3AddrFromSelOff(pVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[1], uRet.pu16[0]); + DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[1], uRet.pu16[0]); break; case DBGFRETURNTYPE_FAR32: - DBGFR3AddrFromSelOff(pVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]); + DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]); break; case DBGFRETURNTYPE_FAR64: - DBGFR3AddrFromSelOff(pVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[4], uRet.pu64[0]); + DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[4], uRet.pu64[0]); break; case DBGFRETURNTYPE_IRET16: - DBGFR3AddrFromSelOff(pVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[1], uRet.pu16[0]); + DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[1], uRet.pu16[0]); break; case DBGFRETURNTYPE_IRET32: - DBGFR3AddrFromSelOff(pVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]); + DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]); break; case DBGFRETURNTYPE_IRET32_PRIV: - DBGFR3AddrFromSelOff(pVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]); + DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]); break; case DBGFRETURNTYPE_IRET32_V86: - DBGFR3AddrFromSelOff(pVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]); + DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]); break; case DBGFRETURNTYPE_IRET64: - DBGFR3AddrFromSelOff(pVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[4], uRet.pu64[0]); + DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[4], uRet.pu64[0]); break; default: AssertMsgFailed(("enmReturnType=%d\n", pFrame->enmReturnType)); return VERR_INVALID_PARAMETER; } - pFrame->pSymReturnPC = DBGFR3AsSymbolByAddrA(pVM, hAs, &pFrame->AddrReturnPC, NULL /*offDisp*/, NULL /*phMod*/); - pFrame->pLineReturnPC = DBGFR3LineByAddrAlloc(pVM, pFrame->AddrReturnPC.FlatPtr, NULL); + pFrame->pSymReturnPC = DBGFR3AsSymbolByAddrA(pUVM, hAs, &pFrame->AddrReturnPC, RTDBGSYMADDR_FLAGS_LESS_OR_EQUAL, + NULL /*poffDisp*/, NULL /*phMod*/); + pFrame->pLineReturnPC = DBGFR3AsLineByAddrA(pUVM, hAs, &pFrame->AddrReturnPC, NULL /*poffDisp*/, NULL /*phMod*/); /* * Frame bitness flag. @@ -277,7 +280,7 @@ static int dbgfR3StackWalk(PVM pVM, VMCPUID idCpu, RTDBGAS hAs, PDBGFSTACKFRAME /** * Walks the entire stack allocating memory as we walk. */ -static DECLCALLBACK(int) dbgfR3StackWalkCtxFull(PVM pVM, VMCPUID idCpu, PCCPUMCTXCORE pCtxCore, RTDBGAS hAs, +static DECLCALLBACK(int) dbgfR3StackWalkCtxFull(PUVM pUVM, VMCPUID idCpu, PCCPUMCTXCORE pCtxCore, RTDBGAS hAs, DBGFCODETYPE enmCodeType, PCDBGFADDRESS pAddrFrame, PCDBGFADDRESS pAddrStack, @@ -286,7 +289,7 @@ static DECLCALLBACK(int) dbgfR3StackWalkCtxFull(PVM pVM, VMCPUID idCpu, PCCPUMCT PCDBGFSTACKFRAME *ppFirstFrame) { /* alloc first frame. */ - PDBGFSTACKFRAME pCur = (PDBGFSTACKFRAME)MMR3HeapAllocZ(pVM, MM_TAG_DBGF_STACK, sizeof(*pCur)); + PDBGFSTACKFRAME pCur = (PDBGFSTACKFRAME)MMR3HeapAllocZU(pUVM, MM_TAG_DBGF_STACK, sizeof(*pCur)); if (!pCur) return VERR_NO_MEMORY; @@ -300,9 +303,9 @@ static DECLCALLBACK(int) dbgfR3StackWalkCtxFull(PVM pVM, VMCPUID idCpu, PCCPUMCT if (pAddrPC) pCur->AddrPC = *pAddrPC; else if (enmCodeType != DBGFCODETYPE_GUEST) - DBGFR3AddrFromFlat(pVM, &pCur->AddrPC, pCtxCore->rip); + DBGFR3AddrFromFlat(pUVM, &pCur->AddrPC, pCtxCore->rip); else - rc = DBGFR3AddrFromSelOff(pVM, idCpu, &pCur->AddrPC, pCtxCore->cs.Sel, pCtxCore->rip); + rc = DBGFR3AddrFromSelOff(pUVM, idCpu, &pCur->AddrPC, pCtxCore->cs.Sel, pCtxCore->rip); if (RT_SUCCESS(rc)) { if (enmReturnType == DBGFRETURNTYPE_INVALID) @@ -328,7 +331,7 @@ static DECLCALLBACK(int) dbgfR3StackWalkCtxFull(PVM pVM, VMCPUID idCpu, PCCPUMCT fAddrMask = UINT64_MAX; else { - PVMCPU pVCpu = VMMGetCpuById(pVM, idCpu); + PVMCPU pVCpu = VMMGetCpuById(pUVM->pVM, idCpu); CPUMMODE CpuMode = CPUMGetGuestMode(pVCpu); if (CpuMode == CPUMMODE_REAL) fAddrMask = UINT16_MAX; @@ -342,16 +345,16 @@ static DECLCALLBACK(int) dbgfR3StackWalkCtxFull(PVM pVM, VMCPUID idCpu, PCCPUMCT if (pAddrStack) pCur->AddrStack = *pAddrStack; else if (enmCodeType != DBGFCODETYPE_GUEST) - DBGFR3AddrFromFlat(pVM, &pCur->AddrStack, pCtxCore->rsp & fAddrMask); + DBGFR3AddrFromFlat(pUVM, &pCur->AddrStack, pCtxCore->rsp & fAddrMask); else - rc = DBGFR3AddrFromSelOff(pVM, idCpu, &pCur->AddrStack, pCtxCore->ss.Sel, pCtxCore->rsp & fAddrMask); + rc = DBGFR3AddrFromSelOff(pUVM, idCpu, &pCur->AddrStack, pCtxCore->ss.Sel, pCtxCore->rsp & fAddrMask); if (pAddrFrame) pCur->AddrFrame = *pAddrFrame; else if (enmCodeType != DBGFCODETYPE_GUEST) - DBGFR3AddrFromFlat(pVM, &pCur->AddrFrame, pCtxCore->rbp & fAddrMask); + DBGFR3AddrFromFlat(pUVM, &pCur->AddrFrame, pCtxCore->rbp & fAddrMask); else if (RT_SUCCESS(rc)) - rc = DBGFR3AddrFromSelOff(pVM, idCpu, &pCur->AddrFrame, pCtxCore->ss.Sel, pCtxCore->rbp & fAddrMask); + rc = DBGFR3AddrFromSelOff(pUVM, idCpu, &pCur->AddrFrame, pCtxCore->ss.Sel, pCtxCore->rbp & fAddrMask); } else pCur->enmReturnType = enmReturnType; @@ -360,7 +363,7 @@ static DECLCALLBACK(int) dbgfR3StackWalkCtxFull(PVM pVM, VMCPUID idCpu, PCCPUMCT * The first frame. */ if (RT_SUCCESS(rc)) - rc = dbgfR3StackWalk(pVM, idCpu, hAs, pCur); + rc = dbgfR3StackWalk(pUVM, idCpu, hAs, pCur); if (RT_FAILURE(rc)) { DBGFR3StackWalkEnd(pCur); @@ -374,12 +377,12 @@ static DECLCALLBACK(int) dbgfR3StackWalkCtxFull(PVM pVM, VMCPUID idCpu, PCCPUMCT while (!(pCur->fFlags & (DBGFSTACKFRAME_FLAGS_LAST | DBGFSTACKFRAME_FLAGS_MAX_DEPTH | DBGFSTACKFRAME_FLAGS_LOOP))) { /* try walk. */ - rc = dbgfR3StackWalk(pVM, idCpu, hAs, &Next); + rc = dbgfR3StackWalk(pUVM, idCpu, hAs, &Next); if (RT_FAILURE(rc)) break; /* add the next frame to the chain. */ - PDBGFSTACKFRAME pNext = (PDBGFSTACKFRAME)MMR3HeapAlloc(pVM, MM_TAG_DBGF_STACK, sizeof(*pNext)); + PDBGFSTACKFRAME pNext = (PDBGFSTACKFRAME)MMR3HeapAllocU(pUVM, MM_TAG_DBGF_STACK, sizeof(*pNext)); if (!pNext) { DBGFR3StackWalkEnd(pCur); @@ -414,7 +417,7 @@ static DECLCALLBACK(int) dbgfR3StackWalkCtxFull(PVM pVM, VMCPUID idCpu, PCCPUMCT * Common worker for DBGFR3StackWalkBeginGuestEx, DBGFR3StackWalkBeginHyperEx, * DBGFR3StackWalkBeginGuest and DBGFR3StackWalkBeginHyper. */ -static int dbgfR3StackWalkBeginCommon(PVM pVM, +static int dbgfR3StackWalkBeginCommon(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFADDRESS pAddrFrame, @@ -427,14 +430,16 @@ static int dbgfR3StackWalkBeginCommon(PVM pVM, * Validate parameters. */ *ppFirstFrame = NULL; + UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); + PVM pVM = pUVM->pVM; VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID); if (pAddrFrame) - AssertReturn(DBGFR3AddrIsValid(pVM, pAddrFrame), VERR_INVALID_PARAMETER); + AssertReturn(DBGFR3AddrIsValid(pUVM, pAddrFrame), VERR_INVALID_PARAMETER); if (pAddrStack) - AssertReturn(DBGFR3AddrIsValid(pVM, pAddrStack), VERR_INVALID_PARAMETER); + AssertReturn(DBGFR3AddrIsValid(pUVM, pAddrStack), VERR_INVALID_PARAMETER); if (pAddrPC) - AssertReturn(DBGFR3AddrIsValid(pVM, pAddrPC), VERR_INVALID_PARAMETER); + AssertReturn(DBGFR3AddrIsValid(pUVM, pAddrPC), VERR_INVALID_PARAMETER); AssertReturn(enmReturnType >= DBGFRETURNTYPE_INVALID && enmReturnType < DBGFRETURNTYPE_END, VERR_INVALID_PARAMETER); /* @@ -459,9 +464,9 @@ static int dbgfR3StackWalkBeginCommon(PVM pVM, default: AssertFailedReturn(VERR_INVALID_PARAMETER); } - return VMR3ReqPriorityCallWait(pVM, idCpu, (PFNRT)dbgfR3StackWalkCtxFull, 10, - pVM, idCpu, pCtxCore, hAs, enmCodeType, - pAddrFrame, pAddrStack, pAddrPC, enmReturnType, ppFirstFrame); + return VMR3ReqPriorityCallWaitU(pUVM, idCpu, (PFNRT)dbgfR3StackWalkCtxFull, 10, + pUVM, idCpu, pCtxCore, hAs, enmCodeType, + pAddrFrame, pAddrStack, pAddrPC, enmReturnType, ppFirstFrame); } @@ -475,7 +480,7 @@ static int dbgfR3StackWalkBeginCommon(PVM pVM, * @returns VINF_SUCCESS on success. * @returns VERR_NO_MEMORY if we're out of memory. * - * @param pVM Pointer to the VM. + * @param pUVM The user mode VM handle. * @param idCpu The ID of the virtual CPU which stack we want to walk. * @param enmCodeType Code type * @param pAddrFrame Frame address to start at. (Optional) @@ -484,7 +489,7 @@ static int dbgfR3StackWalkBeginCommon(PVM pVM, * @param enmReturnType The return address type. (Optional) * @param ppFirstFrame Where to return the pointer to the first info frame. */ -VMMR3DECL(int) DBGFR3StackWalkBeginEx(PVM pVM, +VMMR3DECL(int) DBGFR3StackWalkBeginEx(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFADDRESS pAddrFrame, @@ -493,7 +498,7 @@ VMMR3DECL(int) DBGFR3StackWalkBeginEx(PVM pVM, DBGFRETURNTYPE enmReturnType, PCDBGFSTACKFRAME *ppFirstFrame) { - return dbgfR3StackWalkBeginCommon(pVM, idCpu, enmCodeType, pAddrFrame, pAddrStack, pAddrPC, enmReturnType, ppFirstFrame); + return dbgfR3StackWalkBeginCommon(pUVM, idCpu, enmCodeType, pAddrFrame, pAddrStack, pAddrPC, enmReturnType, ppFirstFrame); } @@ -507,14 +512,14 @@ VMMR3DECL(int) DBGFR3StackWalkBeginEx(PVM pVM, * @returns VINF_SUCCESS on success. * @returns VERR_NO_MEMORY if we're out of memory. * - * @param pVM Pointer to the VM. + * @param pUVM The user mode VM handle. * @param idCpu The ID of the virtual CPU which stack we want to walk. * @param enmCodeType Code type * @param ppFirstFrame Where to return the pointer to the first info frame. */ -VMMR3DECL(int) DBGFR3StackWalkBegin(PVM pVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFSTACKFRAME *ppFirstFrame) +VMMR3DECL(int) DBGFR3StackWalkBegin(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFSTACKFRAME *ppFirstFrame) { - return dbgfR3StackWalkBeginCommon(pVM, idCpu, enmCodeType, NULL, NULL, NULL, DBGFRETURNTYPE_INVALID, ppFirstFrame); + return dbgfR3StackWalkBeginCommon(pUVM, idCpu, enmCodeType, NULL, NULL, NULL, DBGFRETURNTYPE_INVALID, ppFirstFrame); } /** @@ -578,8 +583,8 @@ VMMR3DECL(void) DBGFR3StackWalkEnd(PCDBGFSTACKFRAME pFirstFrame) RTDbgSymbolFree(pCur->pSymPC); RTDbgSymbolFree(pCur->pSymReturnPC); - DBGFR3LineFree(pCur->pLinePC); - DBGFR3LineFree(pCur->pLineReturnPC); + RTDbgLineFree(pCur->pLinePC); + RTDbgLineFree(pCur->pLineReturnPC); pCur->pNextInternal = NULL; pCur->pFirstInternal = NULL; |
