summaryrefslogtreecommitdiff
path: root/src/VBox/VMM/VMMR3/DBGFAddrSpace.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2014-03-26 19:21:20 +0000
committer <>2014-05-08 15:03:54 +0000
commitfb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch)
treec2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/VMM/VMMR3/DBGFAddrSpace.cpp
parent58ed4748338f9466599adfc8a9171280ed99e23f (diff)
downloadVirtualBox-master.tar.gz
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/VMM/VMMR3/DBGFAddrSpace.cpp')
-rw-r--r--src/VBox/VMM/VMMR3/DBGFAddrSpace.cpp750
1 files changed, 476 insertions, 274 deletions
diff --git a/src/VBox/VMM/VMMR3/DBGFAddrSpace.cpp b/src/VBox/VMM/VMMR3/DBGFAddrSpace.cpp
index 3861be8f..dbc2c00f 100644
--- a/src/VBox/VMM/VMMR3/DBGFAddrSpace.cpp
+++ b/src/VBox/VMM/VMMR3/DBGFAddrSpace.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008 Oracle Corporation
+ * Copyright (C) 2008-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;
@@ -38,9 +38,14 @@
*******************************************************************************/
#define LOG_GROUP LOG_GROUP_DBGF
#include <VBox/vmm/dbgf.h>
+#include <VBox/vmm/hm.h>
#include <VBox/vmm/pdmapi.h>
#include <VBox/vmm/mm.h>
+#ifdef VBOX_WITH_RAW_MODE
+# include <VBox/vmm/patm.h>
+#endif
#include "DBGFInternal.h"
+#include <VBox/vmm/uvm.h>
#include <VBox/vmm/vm.h>
#include <VBox/err.h>
#include <VBox/log.h>
@@ -49,6 +54,7 @@
#include <iprt/assert.h>
#include <iprt/ctype.h>
#include <iprt/env.h>
+#include <iprt/mem.h>
#include <iprt/path.h>
#include <iprt/param.h>
@@ -78,10 +84,10 @@ typedef DBGFASDBNODE *PDBGFASDBNODE;
*/
typedef struct DBGFR3ASLOADOPENDATA
{
- const char *pszModName;
- RTGCUINTPTR uSubtrahend;
- uint32_t fFlags;
- RTDBGMOD hMod;
+ const char *pszModName;
+ RTGCUINTPTR uSubtrahend;
+ uint32_t fFlags;
+ RTDBGMOD hMod;
} DBGFR3ASLOADOPENDATA;
/**
@@ -100,30 +106,30 @@ typedef FNDBGFR3ASSEARCHOPEN *PFNDBGFR3ASSEARCHOPEN;
* Defined Constants And Macros *
*******************************************************************************/
/** Locks the address space database for writing. */
-#define DBGF_AS_DB_LOCK_WRITE(pVM) \
+#define DBGF_AS_DB_LOCK_WRITE(pUVM) \
do { \
- int rcSem = RTSemRWRequestWrite((pVM)->dbgf.s.hAsDbLock, RT_INDEFINITE_WAIT); \
+ int rcSem = RTSemRWRequestWrite((pUVM)->dbgf.s.hAsDbLock, RT_INDEFINITE_WAIT); \
AssertRC(rcSem); \
} while (0)
/** Unlocks the address space database after writing. */
-#define DBGF_AS_DB_UNLOCK_WRITE(pVM) \
+#define DBGF_AS_DB_UNLOCK_WRITE(pUVM) \
do { \
- int rcSem = RTSemRWReleaseWrite((pVM)->dbgf.s.hAsDbLock); \
+ int rcSem = RTSemRWReleaseWrite((pUVM)->dbgf.s.hAsDbLock); \
AssertRC(rcSem); \
} while (0)
/** Locks the address space database for reading. */
-#define DBGF_AS_DB_LOCK_READ(pVM) \
+#define DBGF_AS_DB_LOCK_READ(pUVM) \
do { \
- int rcSem = RTSemRWRequestRead((pVM)->dbgf.s.hAsDbLock, RT_INDEFINITE_WAIT); \
+ int rcSem = RTSemRWRequestRead((pUVM)->dbgf.s.hAsDbLock, RT_INDEFINITE_WAIT); \
AssertRC(rcSem); \
} while (0)
/** Unlocks the address space database after reading. */
-#define DBGF_AS_DB_UNLOCK_READ(pVM) \
+#define DBGF_AS_DB_UNLOCK_READ(pUVM) \
do { \
- int rcSem = RTSemRWReleaseRead((pVM)->dbgf.s.hAsDbLock); \
+ int rcSem = RTSemRWReleaseRead((pUVM)->dbgf.s.hAsDbLock); \
AssertRC(rcSem); \
} while (0)
@@ -133,14 +139,86 @@ typedef FNDBGFR3ASSEARCHOPEN *PFNDBGFR3ASSEARCHOPEN;
* Initializes the address space parts of DBGF.
*
* @returns VBox status code.
- * @param pVM Pointer to the VM.
+ * @param pUVM The user mode VM handle.
*/
-int dbgfR3AsInit(PVM pVM)
+int dbgfR3AsInit(PUVM pUVM)
{
+ Assert(pUVM->pVM);
+
/*
* Create the semaphore.
*/
- int rc = RTSemRWCreate(&pVM->dbgf.s.hAsDbLock);
+ int rc = RTSemRWCreate(&pUVM->dbgf.s.hAsDbLock);
+ AssertRCReturn(rc, rc);
+
+ /*
+ * Create the debugging config instance and set it up, defaulting to
+ * deferred loading in order to keep things fast.
+ */
+ rc = RTDbgCfgCreate(&pUVM->dbgf.s.hDbgCfg, NULL, true /*fNativePaths*/);
+ AssertRCReturn(rc, rc);
+ rc = RTDbgCfgChangeUInt(pUVM->dbgf.s.hDbgCfg, RTDBGCFGPROP_FLAGS, RTDBGCFGOP_PREPEND,
+ RTDBGCFG_FLAGS_DEFERRED);
+ AssertRCReturn(rc, rc);
+
+ static struct
+ {
+ RTDBGCFGPROP enmProp;
+ const char *pszEnvName;
+ const char *pszCfgName;
+ } const s_aProps[] =
+ {
+ { RTDBGCFGPROP_FLAGS, "VBOXDBG_FLAGS", "Flags" },
+ { RTDBGCFGPROP_PATH, "VBOXDBG_PATH", "Path" },
+ { RTDBGCFGPROP_SUFFIXES, "VBOXDBG_SUFFIXES", "Suffixes" },
+ { RTDBGCFGPROP_SRC_PATH, "VBOXDBG_SRC_PATH", "SrcPath" },
+ };
+ PCFGMNODE pCfgDbgf = CFGMR3GetChild(CFGMR3GetRootU(pUVM), "/DBGF");
+ for (unsigned i = 0; i < RT_ELEMENTS(s_aProps); i++)
+ {
+ char szEnvValue[8192];
+ rc = RTEnvGetEx(RTENV_DEFAULT, s_aProps[i].pszEnvName, szEnvValue, sizeof(szEnvValue), NULL);
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTDbgCfgChangeString(pUVM->dbgf.s.hDbgCfg, s_aProps[i].enmProp, RTDBGCFGOP_PREPEND, szEnvValue);
+ if (RT_FAILURE(rc))
+ return VMR3SetError(pUVM, rc, RT_SRC_POS,
+ "DBGF Config Error: %s=%s -> %Rrc", s_aProps[i].pszEnvName, szEnvValue, rc);
+ }
+ else if (rc != VERR_ENV_VAR_NOT_FOUND)
+ return VMR3SetError(pUVM, rc, RT_SRC_POS,
+ "DBGF Config Error: Error querying env.var. %s: %Rrc", s_aProps[i].pszEnvName, rc);
+
+ char *pszCfgValue;
+ rc = CFGMR3QueryStringAllocDef(pCfgDbgf, s_aProps[i].pszCfgName, &pszCfgValue, NULL);
+ if (RT_FAILURE(rc))
+ return VMR3SetError(pUVM, rc, RT_SRC_POS,
+ "DBGF Config Error: Querying /DBGF/%s -> %Rrc", s_aProps[i].pszCfgName, rc);
+ if (pszCfgValue)
+ {
+ rc = RTDbgCfgChangeString(pUVM->dbgf.s.hDbgCfg, s_aProps[i].enmProp, RTDBGCFGOP_PREPEND, pszCfgValue);
+ if (RT_FAILURE(rc))
+ return VMR3SetError(pUVM, rc, RT_SRC_POS,
+ "DBGF Config Error: /DBGF/%s=%s -> %Rrc", s_aProps[i].pszCfgName, pszCfgValue, rc);
+ }
+ }
+
+ /*
+ * Prepend the NoArch and VBoxDbgSyms directories to the path.
+ */
+ char szPath[RTPATH_MAX];
+ rc = RTPathAppPrivateNoArch(szPath, sizeof(szPath));
+ AssertRCReturn(rc, rc);
+#ifdef RT_OS_DARWIN
+ rc = RTPathAppend(szPath, sizeof(szPath), "../Resources/VBoxDbgSyms/");
+#else
+ rc = RTDbgCfgChangeString(pUVM->dbgf.s.hDbgCfg, RTDBGCFGPROP_PATH, RTDBGCFGOP_PREPEND, szPath);
+ AssertRCReturn(rc, rc);
+
+ rc = RTPathAppend(szPath, sizeof(szPath), "VBoxDbgSyms/");
+#endif
+ AssertRCReturn(rc, rc);
+ rc = RTDbgCfgChangeString(pUVM->dbgf.s.hDbgCfg, RTDBGCFGPROP_PATH, RTDBGCFGOP_PREPEND, szPath);
AssertRCReturn(rc, rc);
/*
@@ -149,36 +227,36 @@ int dbgfR3AsInit(PVM pVM)
RTDBGAS hDbgAs;
rc = RTDbgAsCreate(&hDbgAs, 0, RTGCPTR_MAX, "Global");
AssertRCReturn(rc, rc);
- rc = DBGFR3AsAdd(pVM, hDbgAs, NIL_RTPROCESS);
+ rc = DBGFR3AsAdd(pUVM, hDbgAs, NIL_RTPROCESS);
AssertRCReturn(rc, rc);
RTDbgAsRetain(hDbgAs);
- pVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_GLOBAL)] = hDbgAs;
+ pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_GLOBAL)] = hDbgAs;
RTDbgAsRetain(hDbgAs);
- pVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_KERNEL)] = hDbgAs;
+ pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_KERNEL)] = hDbgAs;
rc = RTDbgAsCreate(&hDbgAs, 0, RTGCPHYS_MAX, "Physical");
AssertRCReturn(rc, rc);
- rc = DBGFR3AsAdd(pVM, hDbgAs, NIL_RTPROCESS);
+ rc = DBGFR3AsAdd(pUVM, hDbgAs, NIL_RTPROCESS);
AssertRCReturn(rc, rc);
RTDbgAsRetain(hDbgAs);
- pVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_PHYS)] = hDbgAs;
+ pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_PHYS)] = hDbgAs;
rc = RTDbgAsCreate(&hDbgAs, 0, RTRCPTR_MAX, "HyperRawMode");
AssertRCReturn(rc, rc);
- rc = DBGFR3AsAdd(pVM, hDbgAs, NIL_RTPROCESS);
+ rc = DBGFR3AsAdd(pUVM, hDbgAs, NIL_RTPROCESS);
AssertRCReturn(rc, rc);
RTDbgAsRetain(hDbgAs);
- pVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_RC)] = hDbgAs;
+ pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_RC)] = hDbgAs;
RTDbgAsRetain(hDbgAs);
- pVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_RC_AND_GC_GLOBAL)] = hDbgAs;
+ pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_RC_AND_GC_GLOBAL)] = hDbgAs;
rc = RTDbgAsCreate(&hDbgAs, 0, RTR0PTR_MAX, "HyperRing0");
AssertRCReturn(rc, rc);
- rc = DBGFR3AsAdd(pVM, hDbgAs, NIL_RTPROCESS);
+ rc = DBGFR3AsAdd(pUVM, hDbgAs, NIL_RTPROCESS);
AssertRCReturn(rc, rc);
RTDbgAsRetain(hDbgAs);
- pVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_R0)] = hDbgAs;
+ pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_R0)] = hDbgAs;
return VINF_SUCCESS;
}
@@ -206,25 +284,25 @@ static DECLCALLBACK(int) dbgfR3AsTermDestroyNode(PAVLPVNODECORE pNode, void *pvI
/**
* Terminates the address space parts of DBGF.
*
- * @param pVM Pointer to the VM.
+ * @param pUVM The user mode VM handle.
*/
-void dbgfR3AsTerm(PVM pVM)
+void dbgfR3AsTerm(PUVM pUVM)
{
/*
* Create the semaphore.
*/
- int rc = RTSemRWDestroy(pVM->dbgf.s.hAsDbLock);
+ int rc = RTSemRWDestroy(pUVM->dbgf.s.hAsDbLock);
AssertRC(rc);
- pVM->dbgf.s.hAsDbLock = NIL_RTSEMRW;
+ pUVM->dbgf.s.hAsDbLock = NIL_RTSEMRW;
/*
* Release all the address spaces.
*/
- RTAvlPVDestroy(&pVM->dbgf.s.AsHandleTree, dbgfR3AsTermDestroyNode, NULL);
- for (size_t i = 0; i < RT_ELEMENTS(pVM->dbgf.s.ahAsAliases); i++)
+ RTAvlPVDestroy(&pUVM->dbgf.s.AsHandleTree, dbgfR3AsTermDestroyNode, NULL);
+ for (size_t i = 0; i < RT_ELEMENTS(pUVM->dbgf.s.ahAsAliases); i++)
{
- RTDbgAsRelease(pVM->dbgf.s.ahAsAliases[i]);
- pVM->dbgf.s.ahAsAliases[i] = NIL_RTDBGAS;
+ RTDbgAsRelease(pUVM->dbgf.s.ahAsAliases[i]);
+ pUVM->dbgf.s.ahAsAliases[i] = NIL_RTDBGAS;
}
}
@@ -232,13 +310,89 @@ void dbgfR3AsTerm(PVM pVM)
/**
* Relocates the RC address space.
*
- * @param pVM Pointer to the VM.
- * @param offDelta The relocation delta.
+ * @param pUVM The user mode VM handle.
+ * @param offDelta The relocation delta.
+ */
+void dbgfR3AsRelocate(PUVM pUVM, RTGCUINTPTR offDelta)
+{
+ /*
+ * We will relocate the raw-mode context modules by offDelta if they have
+ * been injected into the the DBGF_AS_RC map.
+ */
+ if ( pUVM->dbgf.s.afAsAliasPopuplated[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_RC)]
+ && offDelta != 0)
+ {
+ RTDBGAS hAs = pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_RC)];
+
+ /* Take a snapshot of the modules as we might have overlapping
+ addresses between the previous and new mapping. */
+ RTDbgAsLockExcl(hAs);
+ uint32_t cModules = RTDbgAsModuleCount(hAs);
+ if (cModules > 0 && cModules < _4K)
+ {
+ struct DBGFASRELOCENTRY
+ {
+ RTDBGMOD hDbgMod;
+ RTRCPTR uOldAddr;
+ } *paEntries = (struct DBGFASRELOCENTRY *)RTMemTmpAllocZ(sizeof(paEntries[0]) * cModules);
+ if (paEntries)
+ {
+ /* Snapshot. */
+ for (uint32_t i = 0; i < cModules; i++)
+ {
+ paEntries[i].hDbgMod = RTDbgAsModuleByIndex(hAs, i);
+ AssertLogRelMsg(paEntries[i].hDbgMod != NIL_RTDBGMOD, ("iModule=%#x\n", i));
+
+ RTDBGASMAPINFO aMappings[1] = { { 0, 0 } };
+ uint32_t cMappings = 1;
+ int rc = RTDbgAsModuleQueryMapByIndex(hAs, i, &aMappings[0], &cMappings, 0 /*fFlags*/);
+ if (RT_SUCCESS(rc) && cMappings == 1 && aMappings[0].iSeg == NIL_RTDBGSEGIDX)
+ paEntries[i].uOldAddr = (RTRCPTR)aMappings[0].Address;
+ else
+ AssertLogRelMsgFailed(("iModule=%#x rc=%Rrc cMappings=%#x.\n", i, rc, cMappings));
+ }
+
+ /* Unlink them. */
+ for (uint32_t i = 0; i < cModules; i++)
+ {
+ int rc = RTDbgAsModuleUnlink(hAs, paEntries[i].hDbgMod);
+ AssertLogRelMsg(RT_SUCCESS(rc), ("iModule=%#x rc=%Rrc hDbgMod=%p\n", i, rc, paEntries[i].hDbgMod));
+ }
+
+ /* Link them at the new locations. */
+ for (uint32_t i = 0; i < cModules; i++)
+ {
+ RTRCPTR uNewAddr = paEntries[i].uOldAddr + offDelta;
+ int rc = RTDbgAsModuleLink(hAs, paEntries[i].hDbgMod, uNewAddr,
+ RTDBGASLINK_FLAGS_REPLACE);
+ AssertLogRelMsg(RT_SUCCESS(rc),
+ ("iModule=%#x rc=%Rrc hDbgMod=%p %RRv -> %RRv\n", i, rc, paEntries[i].hDbgMod,
+ paEntries[i].uOldAddr, uNewAddr));
+ RTDbgModRelease(paEntries[i].hDbgMod);
+ }
+
+ RTMemTmpFree(paEntries);
+ }
+ else
+ AssertLogRelMsgFailed(("No memory for %#x modules.\n", cModules));
+ }
+ else
+ AssertLogRelMsgFailed(("cModules=%#x\n", cModules));
+ RTDbgAsUnlockExcl(hAs);
+ }
+}
+
+
+/**
+ * Gets the IPRT debugging configuration handle (no refs retained).
+ *
+ * @returns Config handle or NIL_RTDBGCFG.
+ * @param pUVM The user mode VM handle.
*/
-void dbgfR3AsRelocate(PVM pVM, RTGCUINTPTR offDelta)
+VMMR3DECL(RTDBGCFG) DBGFR3AsGetConfig(PUVM pUVM)
{
- /** @todo */
- NOREF(pVM); NOREF(offDelta);
+ UVM_ASSERT_VALID_EXT_RETURN(pUVM, NIL_RTDBGCFG);
+ return pUVM->dbgf.s.hDbgCfg;
}
@@ -246,17 +400,17 @@ void dbgfR3AsRelocate(PVM pVM, RTGCUINTPTR offDelta)
* Adds the address space to the database.
*
* @returns VBox status code.
- * @param pVM Pointer to the VM.
- * @param hDbgAs The address space handle. The reference of the
- * caller will NOT be consumed.
- * @param ProcId The process id or NIL_RTPROCESS.
+ * @param pUVM The user mode VM handle.
+ * @param hDbgAs The address space handle. The reference of the caller
+ * will NOT be consumed.
+ * @param ProcId The process id or NIL_RTPROCESS.
*/
-VMMR3DECL(int) DBGFR3AsAdd(PVM pVM, RTDBGAS hDbgAs, RTPROCESS ProcId)
+VMMR3DECL(int) DBGFR3AsAdd(PUVM pUVM, RTDBGAS hDbgAs, RTPROCESS ProcId)
{
/*
* Input validation.
*/
- VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
+ UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
const char *pszName = RTDbgAsName(hDbgAs);
if (!pszName)
return VERR_INVALID_HANDLE;
@@ -268,26 +422,26 @@ VMMR3DECL(int) DBGFR3AsAdd(PVM pVM, RTDBGAS hDbgAs, RTPROCESS ProcId)
* Allocate a tracking node.
*/
int rc = VERR_NO_MEMORY;
- PDBGFASDBNODE pDbNode = (PDBGFASDBNODE)MMR3HeapAlloc(pVM, MM_TAG_DBGF_AS, sizeof(*pDbNode));
+ PDBGFASDBNODE pDbNode = (PDBGFASDBNODE)MMR3HeapAllocU(pUVM, MM_TAG_DBGF_AS, sizeof(*pDbNode));
if (pDbNode)
{
pDbNode->HandleCore.Key = hDbgAs;
pDbNode->PidCore.Key = ProcId;
pDbNode->NameCore.pszString = pszName;
pDbNode->NameCore.cchString = strlen(pszName);
- DBGF_AS_DB_LOCK_WRITE(pVM);
- if (RTStrSpaceInsert(&pVM->dbgf.s.AsNameSpace, &pDbNode->NameCore))
+ DBGF_AS_DB_LOCK_WRITE(pUVM);
+ if (RTStrSpaceInsert(&pUVM->dbgf.s.AsNameSpace, &pDbNode->NameCore))
{
- if (RTAvlPVInsert(&pVM->dbgf.s.AsHandleTree, &pDbNode->HandleCore))
+ if (RTAvlPVInsert(&pUVM->dbgf.s.AsHandleTree, &pDbNode->HandleCore))
{
- DBGF_AS_DB_UNLOCK_WRITE(pVM);
+ DBGF_AS_DB_UNLOCK_WRITE(pUVM);
return VINF_SUCCESS;
}
/* bail out */
- RTStrSpaceRemove(&pVM->dbgf.s.AsNameSpace, pszName);
+ RTStrSpaceRemove(&pUVM->dbgf.s.AsNameSpace, pszName);
}
- DBGF_AS_DB_UNLOCK_WRITE(pVM);
+ DBGF_AS_DB_UNLOCK_WRITE(pUVM);
MMR3HeapFree(pDbNode);
}
RTDbgAsRelease(hDbgAs);
@@ -304,16 +458,16 @@ VMMR3DECL(int) DBGFR3AsAdd(PVM pVM, RTDBGAS hDbgAs, RTPROCESS ProcId)
* @retval VERR_SHARING_VIOLATION if in use as an alias.
* @retval VERR_NOT_FOUND if not found in the address space database.
*
- * @param pVM Pointer to the VM.
- * @param hDbgAs The address space handle. Aliases are not allowed.
+ * @param pUVM The user mode VM handle.
+ * @param hDbgAs The address space handle. Aliases are not allowed.
*/
-VMMR3DECL(int) DBGFR3AsDelete(PVM pVM, RTDBGAS hDbgAs)
+VMMR3DECL(int) DBGFR3AsDelete(PUVM pUVM, RTDBGAS hDbgAs)
{
/*
* Input validation. Retain the address space so it can be released outside
* the lock as well as validated.
*/
- VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
+ UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
if (hDbgAs == NIL_RTDBGAS)
return VINF_SUCCESS;
uint32_t cRefs = RTDbgAsRetain(hDbgAs);
@@ -321,32 +475,32 @@ VMMR3DECL(int) DBGFR3AsDelete(PVM pVM, RTDBGAS hDbgAs)
return VERR_INVALID_HANDLE;
RTDbgAsRelease(hDbgAs);
- DBGF_AS_DB_LOCK_WRITE(pVM);
+ DBGF_AS_DB_LOCK_WRITE(pUVM);
/*
* You cannot delete any of the aliases.
*/
- for (size_t i = 0; i < RT_ELEMENTS(pVM->dbgf.s.ahAsAliases); i++)
- if (pVM->dbgf.s.ahAsAliases[i] == hDbgAs)
+ for (size_t i = 0; i < RT_ELEMENTS(pUVM->dbgf.s.ahAsAliases); i++)
+ if (pUVM->dbgf.s.ahAsAliases[i] == hDbgAs)
{
- DBGF_AS_DB_UNLOCK_WRITE(pVM);
+ DBGF_AS_DB_UNLOCK_WRITE(pUVM);
return VERR_SHARING_VIOLATION;
}
/*
* Ok, try remove it from the database.
*/
- PDBGFASDBNODE pDbNode = (PDBGFASDBNODE)RTAvlPVRemove(&pVM->dbgf.s.AsHandleTree, hDbgAs);
+ PDBGFASDBNODE pDbNode = (PDBGFASDBNODE)RTAvlPVRemove(&pUVM->dbgf.s.AsHandleTree, hDbgAs);
if (!pDbNode)
{
- DBGF_AS_DB_UNLOCK_WRITE(pVM);
+ DBGF_AS_DB_UNLOCK_WRITE(pUVM);
return VERR_NOT_FOUND;
}
- RTStrSpaceRemove(&pVM->dbgf.s.AsNameSpace, pDbNode->NameCore.pszString);
+ RTStrSpaceRemove(&pUVM->dbgf.s.AsNameSpace, pDbNode->NameCore.pszString);
if (pDbNode->PidCore.Key != NIL_RTPROCESS)
- RTAvlU32Remove(&pVM->dbgf.s.AsPidTree, pDbNode->PidCore.Key);
+ RTAvlU32Remove(&pUVM->dbgf.s.AsPidTree, pDbNode->PidCore.Key);
- DBGF_AS_DB_UNLOCK_WRITE(pVM);
+ DBGF_AS_DB_UNLOCK_WRITE(pUVM);
/*
* Free the resources.
@@ -365,21 +519,21 @@ VMMR3DECL(int) DBGFR3AsDelete(PVM pVM, RTDBGAS hDbgAs)
* and DBGF_AS_KERNEL.
*
* @returns VBox status code.
- * @param pVM Pointer to the VM.
- * @param hAlias The alias to change.
- * @param hAliasFor The address space hAlias should be an alias for.
- * This can be an alias. The caller's reference to
- * this address space will NOT be consumed.
+ * @param pUVM The user mode VM handle.
+ * @param hAlias The alias to change.
+ * @param hAliasFor The address space hAlias should be an alias for. This
+ * can be an alias. The caller's reference to this address
+ * space will NOT be consumed.
*/
-VMMR3DECL(int) DBGFR3AsSetAlias(PVM pVM, RTDBGAS hAlias, RTDBGAS hAliasFor)
+VMMR3DECL(int) DBGFR3AsSetAlias(PUVM pUVM, RTDBGAS hAlias, RTDBGAS hAliasFor)
{
/*
* Input validation.
*/
- VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
+ UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
AssertMsgReturn(DBGF_AS_IS_ALIAS(hAlias), ("%p\n", hAlias), VERR_INVALID_PARAMETER);
AssertMsgReturn(!DBGF_AS_IS_FIXED_ALIAS(hAlias), ("%p\n", hAlias), VERR_INVALID_PARAMETER);
- RTDBGAS hRealAliasFor = DBGFR3AsResolveAndRetain(pVM, hAliasFor);
+ RTDBGAS hRealAliasFor = DBGFR3AsResolveAndRetain(pUVM, hAliasFor);
if (hRealAliasFor == NIL_RTDBGAS)
return VERR_INVALID_HANDLE;
@@ -387,19 +541,19 @@ VMMR3DECL(int) DBGFR3AsSetAlias(PVM pVM, RTDBGAS hAlias, RTDBGAS hAliasFor)
* Make sure the handle has is already in the database.
*/
int rc = VERR_NOT_FOUND;
- DBGF_AS_DB_LOCK_WRITE(pVM);
- if (RTAvlPVGet(&pVM->dbgf.s.AsHandleTree, hRealAliasFor))
+ DBGF_AS_DB_LOCK_WRITE(pUVM);
+ if (RTAvlPVGet(&pUVM->dbgf.s.AsHandleTree, hRealAliasFor))
{
/*
* Update the alias table and release the current address space.
*/
RTDBGAS hAsOld;
- ASMAtomicXchgHandle(&pVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(hAlias)], hRealAliasFor, &hAsOld);
+ ASMAtomicXchgHandle(&pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(hAlias)], hRealAliasFor, &hAsOld);
uint32_t cRefs = RTDbgAsRelease(hAsOld);
Assert(cRefs > 0); Assert(cRefs != UINT32_MAX); NOREF(cRefs);
rc = VINF_SUCCESS;
}
- DBGF_AS_DB_UNLOCK_WRITE(pVM);
+ DBGF_AS_DB_UNLOCK_WRITE(pUVM);
return rc;
}
@@ -409,15 +563,15 @@ VMMR3DECL(int) DBGFR3AsSetAlias(PVM pVM, RTDBGAS hAlias, RTDBGAS hAliasFor)
* @callback_method_impl{FNPDMR3ENUM}
*/
static DECLCALLBACK(int) dbgfR3AsLazyPopulateR0Callback(PVM pVM, const char *pszFilename, const char *pszName,
- RTUINTPTR ImageBase, size_t cbImage, bool fRC, void *pvArg)
+ RTUINTPTR ImageBase, size_t cbImage, PDMLDRCTX enmCtx, void *pvArg)
{
NOREF(pVM); NOREF(cbImage);
/* Only ring-0 modules. */
- if (!fRC)
+ if (enmCtx == PDMLDRCTX_RING_0)
{
RTDBGMOD hDbgMod;
- int rc = RTDbgModCreateFromImage(&hDbgMod, pszFilename, pszName, 0 /*fFlags*/);
+ int rc = RTDbgModCreateFromImage(&hDbgMod, pszFilename, pszName, RTLDRARCH_HOST, pVM->pUVM->dbgf.s.hDbgCfg);
if (RT_SUCCESS(rc))
{
rc = RTDbgAsModuleLink((RTDBGAS)pvArg, hDbgMod, ImageBase, 0 /*fFlags*/);
@@ -434,25 +588,64 @@ static DECLCALLBACK(int) dbgfR3AsLazyPopulateR0Callback(PVM pVM, const char *psz
/**
+ * @callback_method_impl{FNPDMR3ENUM}
+ */
+static DECLCALLBACK(int) dbgfR3AsLazyPopulateRCCallback(PVM pVM, const char *pszFilename, const char *pszName,
+ RTUINTPTR ImageBase, size_t cbImage, PDMLDRCTX enmCtx, void *pvArg)
+{
+ NOREF(pVM); NOREF(cbImage);
+
+ /* Only raw-mode modules. */
+ if (enmCtx == PDMLDRCTX_RAW_MODE)
+ {
+ RTDBGMOD hDbgMod;
+ int rc = RTDbgModCreateFromImage(&hDbgMod, pszFilename, pszName, RTLDRARCH_X86_32, pVM->pUVM->dbgf.s.hDbgCfg);
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTDbgAsModuleLink((RTDBGAS)pvArg, hDbgMod, ImageBase, 0 /*fFlags*/);
+ if (RT_FAILURE(rc))
+ LogRel(("DBGF: Failed to link module \"%s\" into DBGF_AS_RC at %RTptr: %Rrc\n",
+ pszName, ImageBase, rc));
+ }
+ else
+ LogRel(("DBGF: RTDbgModCreateFromImage failed with rc=%Rrc for module \"%s\" (%s)\n",
+ rc, pszName, pszFilename));
+ }
+ return VINF_SUCCESS;
+}
+
+
+/**
* Lazily populates the specified address space.
*
- * @param pVM Pointer to the VM.
- * @param hAlias The alias.
+ * @param pUVM The user mode VM handle.
+ * @param hAlias The alias.
*/
-static void dbgfR3AsLazyPopulate(PVM pVM, RTDBGAS hAlias)
+static void dbgfR3AsLazyPopulate(PUVM pUVM, RTDBGAS hAlias)
{
- DBGF_AS_DB_LOCK_WRITE(pVM);
+ DBGF_AS_DB_LOCK_WRITE(pUVM);
uintptr_t iAlias = DBGF_AS_ALIAS_2_INDEX(hAlias);
- if (!pVM->dbgf.s.afAsAliasPopuplated[iAlias])
+ if (!pUVM->dbgf.s.afAsAliasPopuplated[iAlias])
{
- RTDBGAS hAs = pVM->dbgf.s.ahAsAliases[iAlias];
- if (hAlias == DBGF_AS_R0)
- PDMR3LdrEnumModules(pVM, dbgfR3AsLazyPopulateR0Callback, hAs);
- /** @todo what do we do about DBGF_AS_RC? */
+ RTDBGAS hDbgAs = pUVM->dbgf.s.ahAsAliases[iAlias];
+ if (hAlias == DBGF_AS_R0 && pUVM->pVM)
+ PDMR3LdrEnumModules(pUVM->pVM, dbgfR3AsLazyPopulateR0Callback, hDbgAs);
+ else if (hAlias == DBGF_AS_RC && pUVM->pVM && !HMIsEnabled(pUVM->pVM))
+ {
+ LogRel(("DBGF: Lazy init of RC address space\n"));
+ PDMR3LdrEnumModules(pUVM->pVM, dbgfR3AsLazyPopulateRCCallback, hDbgAs);
+#ifdef VBOX_WITH_RAW_MODE
+ PATMR3DbgPopulateAddrSpace(pUVM->pVM, hDbgAs);
+#endif
+ }
+ else if (hAlias == DBGF_AS_PHYS && pUVM->pVM)
+ {
+ /** @todo Lazy load pc and vga bios symbols or the EFI stuff. */
+ }
- pVM->dbgf.s.afAsAliasPopuplated[iAlias] = true;
+ pUVM->dbgf.s.afAsAliasPopuplated[iAlias] = true;
}
- DBGF_AS_DB_UNLOCK_WRITE(pVM);
+ DBGF_AS_DB_UNLOCK_WRITE(pUVM);
}
@@ -461,19 +654,19 @@ static void dbgfR3AsLazyPopulate(PVM pVM, RTDBGAS hAlias)
*
* @returns Real address space handle. NIL_RTDBGAS if invalid handle.
*
- * @param pVM Pointer to the VM.
- * @param hAlias The possibly address space alias.
+ * @param pUVM The user mode VM handle.
+ * @param hAlias The possibly address space alias.
*
* @remarks Doesn't take any locks.
*/
-VMMR3DECL(RTDBGAS) DBGFR3AsResolve(PVM pVM, RTDBGAS hAlias)
+VMMR3DECL(RTDBGAS) DBGFR3AsResolve(PUVM pUVM, RTDBGAS hAlias)
{
- VM_ASSERT_VALID_EXT_RETURN(pVM, NULL);
+ UVM_ASSERT_VALID_EXT_RETURN(pUVM, NULL);
AssertCompileNS(NIL_RTDBGAS == (RTDBGAS)0);
uintptr_t iAlias = DBGF_AS_ALIAS_2_INDEX(hAlias);
if (iAlias < DBGF_AS_COUNT)
- ASMAtomicReadHandle(&pVM->dbgf.s.ahAsAliases[iAlias], &hAlias);
+ ASMAtomicReadHandle(&pUVM->dbgf.s.ahAsAliases[iAlias], &hAlias);
return hAlias;
}
@@ -484,12 +677,12 @@ VMMR3DECL(RTDBGAS) DBGFR3AsResolve(PVM pVM, RTDBGAS hAlias)
*
* @returns Real address space handle. NIL_RTDBGAS if invalid handle.
*
- * @param pVM Pointer to the VM.
- * @param hAlias The possibly address space alias.
+ * @param pUVM The user mode VM handle.
+ * @param hAlias The possibly address space alias.
*/
-VMMR3DECL(RTDBGAS) DBGFR3AsResolveAndRetain(PVM pVM, RTDBGAS hAlias)
+VMMR3DECL(RTDBGAS) DBGFR3AsResolveAndRetain(PUVM pUVM, RTDBGAS hAlias)
{
- VM_ASSERT_VALID_EXT_RETURN(pVM, NULL);
+ UVM_ASSERT_VALID_EXT_RETURN(pUVM, NULL);
AssertCompileNS(NIL_RTDBGAS == (RTDBGAS)0);
uint32_t cRefs;
@@ -499,20 +692,20 @@ VMMR3DECL(RTDBGAS) DBGFR3AsResolveAndRetain(PVM pVM, RTDBGAS hAlias)
if (DBGF_AS_IS_FIXED_ALIAS(hAlias))
{
/* Perform lazy address space population. */
- if (!pVM->dbgf.s.afAsAliasPopuplated[iAlias])
- dbgfR3AsLazyPopulate(pVM, hAlias);
+ if (!pUVM->dbgf.s.afAsAliasPopuplated[iAlias])
+ dbgfR3AsLazyPopulate(pUVM, hAlias);
/* Won't ever change, no need to grab the lock. */
- hAlias = pVM->dbgf.s.ahAsAliases[iAlias];
+ hAlias = pUVM->dbgf.s.ahAsAliases[iAlias];
cRefs = RTDbgAsRetain(hAlias);
}
else
{
/* May change, grab the lock so we can read it safely. */
- DBGF_AS_DB_LOCK_READ(pVM);
- hAlias = pVM->dbgf.s.ahAsAliases[iAlias];
+ DBGF_AS_DB_LOCK_READ(pUVM);
+ hAlias = pUVM->dbgf.s.ahAsAliases[iAlias];
cRefs = RTDbgAsRetain(hAlias);
- DBGF_AS_DB_UNLOCK_READ(pVM);
+ DBGF_AS_DB_UNLOCK_READ(pUVM);
}
}
else
@@ -528,15 +721,15 @@ VMMR3DECL(RTDBGAS) DBGFR3AsResolveAndRetain(PVM pVM, RTDBGAS hAlias)
*
* @returns Retained address space handle if found, NIL_RTDBGAS if not.
*
- * @param pVM Pointer to the VM.
+ * @param pUVM The user mode VM handle.
* @param pszName The name.
*/
-VMMR3DECL(RTDBGAS) DBGFR3AsQueryByName(PVM pVM, const char *pszName)
+VMMR3DECL(RTDBGAS) DBGFR3AsQueryByName(PUVM pUVM, const char *pszName)
{
/*
* Validate the input.
*/
- VM_ASSERT_VALID_EXT_RETURN(pVM, NIL_RTDBGAS);
+ UVM_ASSERT_VALID_EXT_RETURN(pUVM, NIL_RTDBGAS);
AssertPtrReturn(pszName, NIL_RTDBGAS);
AssertReturn(*pszName, NIL_RTDBGAS);
@@ -544,9 +737,9 @@ VMMR3DECL(RTDBGAS) DBGFR3AsQueryByName(PVM pVM, const char *pszName)
* Look it up in the string space and retain the result.
*/
RTDBGAS hDbgAs = NIL_RTDBGAS;
- DBGF_AS_DB_LOCK_READ(pVM);
+ DBGF_AS_DB_LOCK_READ(pUVM);
- PRTSTRSPACECORE pNode = RTStrSpaceGet(&pVM->dbgf.s.AsNameSpace, pszName);
+ PRTSTRSPACECORE pNode = RTStrSpaceGet(&pUVM->dbgf.s.AsNameSpace, pszName);
if (pNode)
{
PDBGFASDBNODE pDbNode = RT_FROM_MEMBER(pNode, DBGFASDBNODE, NameCore);
@@ -555,8 +748,8 @@ VMMR3DECL(RTDBGAS) DBGFR3AsQueryByName(PVM pVM, const char *pszName)
if (RT_UNLIKELY(cRefs == UINT32_MAX))
hDbgAs = NIL_RTDBGAS;
}
- DBGF_AS_DB_UNLOCK_READ(pVM);
+ DBGF_AS_DB_UNLOCK_READ(pUVM);
return hDbgAs;
}
@@ -566,24 +759,24 @@ VMMR3DECL(RTDBGAS) DBGFR3AsQueryByName(PVM pVM, const char *pszName)
*
* @returns Retained address space handle if found, NIL_RTDBGAS if not.
*
- * @param pVM Pointer to the VM.
+ * @param pUVM The user mode VM handle.
* @param ProcId The process ID.
*/
-VMMR3DECL(RTDBGAS) DBGFR3AsQueryByPid(PVM pVM, RTPROCESS ProcId)
+VMMR3DECL(RTDBGAS) DBGFR3AsQueryByPid(PUVM pUVM, RTPROCESS ProcId)
{
/*
* Validate the input.
*/
- VM_ASSERT_VALID_EXT_RETURN(pVM, NIL_RTDBGAS);
+ UVM_ASSERT_VALID_EXT_RETURN(pUVM, NIL_RTDBGAS);
AssertReturn(ProcId != NIL_RTPROCESS, NIL_RTDBGAS);
/*
* Look it up in the PID tree and retain the result.
*/
RTDBGAS hDbgAs = NIL_RTDBGAS;
- DBGF_AS_DB_LOCK_READ(pVM);
+ DBGF_AS_DB_LOCK_READ(pUVM);
- PAVLU32NODECORE pNode = RTAvlU32Get(&pVM->dbgf.s.AsPidTree, ProcId);
+ PAVLU32NODECORE pNode = RTAvlU32Get(&pUVM->dbgf.s.AsPidTree, ProcId);
if (pNode)
{
PDBGFASDBNODE pDbNode = RT_FROM_MEMBER(pNode, DBGFASDBNODE, PidCore);
@@ -592,7 +785,7 @@ VMMR3DECL(RTDBGAS) DBGFR3AsQueryByPid(PVM pVM, RTPROCESS ProcId)
if (RT_UNLIKELY(cRefs == UINT32_MAX))
hDbgAs = NIL_RTDBGAS;
}
- DBGF_AS_DB_UNLOCK_READ(pVM);
+ DBGF_AS_DB_UNLOCK_READ(pUVM);
return hDbgAs;
}
@@ -716,15 +909,17 @@ static int dbgfR3AsSearchEnvPath(const char *pszFilename, const char *pszEnvVar,
* Nothing is done if the CFGM variable isn't set.
*
* @returns VBox status code.
+ * @param pUVM The user mode VM handle.
* @param pszFilename The filename.
* @param pszCfgValue The name of the config variable (under /DBGF/).
* @param pfnOpen The open callback function.
* @param pvUser User argument for the callback.
*/
-static int dbgfR3AsSearchCfgPath(PVM pVM, const char *pszFilename, const char *pszCfgValue, PFNDBGFR3ASSEARCHOPEN pfnOpen, void *pvUser)
+static int dbgfR3AsSearchCfgPath(PUVM pUVM, const char *pszFilename, const char *pszCfgValue,
+ PFNDBGFR3ASSEARCHOPEN pfnOpen, void *pvUser)
{
char *pszPath;
- int rc = CFGMR3QueryStringAllocDef(CFGMR3GetChild(CFGMR3GetRoot(pVM), "/DBGF"), pszCfgValue, &pszPath, NULL);
+ int rc = CFGMR3QueryStringAllocDef(CFGMR3GetChild(CFGMR3GetRootU(pUVM), "/DBGF"), pszCfgValue, &pszPath, NULL);
if (RT_FAILURE(rc))
return rc;
if (!pszPath)
@@ -736,20 +931,6 @@ static int dbgfR3AsSearchCfgPath(PVM pVM, const char *pszFilename, const char *p
/**
- * Callback function used by DBGFR3AsLoadImage.
- *
- * @returns VBox status code.
- * @param pszFilename The filename under evaluation.
- * @param pvUser Use arguments (DBGFR3ASLOADOPENDATA).
- */
-static DECLCALLBACK(int) dbgfR3AsLoadImageOpen(const char *pszFilename, void *pvUser)
-{
- DBGFR3ASLOADOPENDATA *pData = (DBGFR3ASLOADOPENDATA *)pvUser;
- return RTDbgModCreateFromImage(&pData->hMod, pszFilename, pData->pszModName, pData->fFlags);
-}
-
-
-/**
* Load symbols from an executable module into the specified address space.
*
* If an module exist at the specified address it will be replaced by this
@@ -757,49 +938,40 @@ static DECLCALLBACK(int) dbgfR3AsLoadImageOpen(const char *pszFilename, void *pv
*
* @returns VBox status code.
*
- * @param pVM Pointer to the VM.
+ * @param pUVM The user mode VM handle.
* @param hDbgAs The address space.
* @param pszFilename The filename of the executable module.
* @param pszModName The module name. If NULL, then then the file name
* base is used (no extension or nothing).
+ * @param enmArch The desired architecture, use RTLDRARCH_WHATEVER if
+ * it's not relevant or known.
* @param pModAddress The load address of the module.
* @param iModSeg The segment to load, pass NIL_RTDBGSEGIDX to load
* the whole image.
* @param fFlags Flags reserved for future extensions, must be 0.
*/
-VMMR3DECL(int) DBGFR3AsLoadImage(PVM pVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags)
+VMMR3DECL(int) DBGFR3AsLoadImage(PUVM pUVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, RTLDRARCH enmArch,
+ PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags)
{
/*
* Validate input
*/
+ UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
AssertReturn(*pszFilename, VERR_INVALID_PARAMETER);
- AssertReturn(DBGFR3AddrIsValid(pVM, pModAddress), VERR_INVALID_PARAMETER);
+ AssertReturn(DBGFR3AddrIsValid(pUVM, pModAddress), VERR_INVALID_PARAMETER);
AssertReturn(fFlags == 0, VERR_INVALID_PARAMETER);
- RTDBGAS hRealAS = DBGFR3AsResolveAndRetain(pVM, hDbgAs);
+ RTDBGAS hRealAS = DBGFR3AsResolveAndRetain(pUVM, hDbgAs);
if (hRealAS == NIL_RTDBGAS)
return VERR_INVALID_HANDLE;
- /*
- * Do the work.
- */
- DBGFR3ASLOADOPENDATA Data;
- Data.pszModName = pszModName;
- Data.uSubtrahend = 0;
- Data.fFlags = 0;
- Data.hMod = NIL_RTDBGMOD;
- int rc = dbgfR3AsSearchCfgPath(pVM, pszFilename, "ImagePath", dbgfR3AsLoadImageOpen, &Data);
- if (RT_FAILURE(rc))
- rc = dbgfR3AsSearchEnvPath(pszFilename, "VBOXDBG_IMAGE_PATH", dbgfR3AsLoadImageOpen, &Data);
- if (RT_FAILURE(rc))
- rc = dbgfR3AsSearchCfgPath(pVM, pszFilename, "Path", dbgfR3AsLoadImageOpen, &Data);
- if (RT_FAILURE(rc))
- rc = dbgfR3AsSearchEnvPath(pszFilename, "VBOXDBG_PATH", dbgfR3AsLoadImageOpen, &Data);
+ RTDBGMOD hDbgMod;
+ int rc = RTDbgModCreateFromImage(&hDbgMod, pszFilename, pszModName, enmArch, pUVM->dbgf.s.hDbgCfg);
if (RT_SUCCESS(rc))
{
- rc = DBGFR3AsLinkModule(pVM, hRealAS, Data.hMod, pModAddress, iModSeg, 0);
+ rc = DBGFR3AsLinkModule(pUVM, hRealAS, hDbgMod, pModAddress, iModSeg, 0);
if (RT_FAILURE(rc))
- RTDbgModRelease(Data.hMod);
+ RTDbgModRelease(hDbgMod);
}
RTDbgAsRelease(hRealAS);
@@ -808,20 +980,6 @@ VMMR3DECL(int) DBGFR3AsLoadImage(PVM pVM, RTDBGAS hDbgAs, const char *pszFilenam
/**
- * Callback function used by DBGFR3AsLoadMap.
- *
- * @returns VBox status code.
- * @param pszFilename The filename under evaluation.
- * @param pvUser Use arguments (DBGFR3ASLOADOPENDATA).
- */
-static DECLCALLBACK(int) dbgfR3AsLoadMapOpen(const char *pszFilename, void *pvUser)
-{
- DBGFR3ASLOADOPENDATA *pData = (DBGFR3ASLOADOPENDATA *)pvUser;
- return RTDbgModCreateFromMap(&pData->hMod, pszFilename, pData->pszModName, pData->uSubtrahend, pData->fFlags);
-}
-
-
-/**
* Load symbols from a map file into a module at the specified address space.
*
* If an module exist at the specified address it will be replaced by this
@@ -829,7 +987,7 @@ static DECLCALLBACK(int) dbgfR3AsLoadMapOpen(const char *pszFilename, void *pvUs
*
* @returns VBox status code.
*
- * @param pVM Pointer to the VM.
+ * @param pUVM The user mode VM handle.
* @param hDbgAs The address space.
* @param pszFilename The map file.
* @param pszModName The module name. If NULL, then then the file name
@@ -842,40 +1000,28 @@ static DECLCALLBACK(int) dbgfR3AsLoadMapOpen(const char *pszFilename, void *pvUs
* /proc/kallsyms.
* @param fFlags Flags reserved for future extensions, must be 0.
*/
-VMMR3DECL(int) DBGFR3AsLoadMap(PVM pVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName,
+VMMR3DECL(int) DBGFR3AsLoadMap(PUVM pUVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName,
PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, RTGCUINTPTR uSubtrahend, uint32_t fFlags)
{
/*
* Validate input
*/
+ UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
AssertReturn(*pszFilename, VERR_INVALID_PARAMETER);
- AssertReturn(DBGFR3AddrIsValid(pVM, pModAddress), VERR_INVALID_PARAMETER);
+ AssertReturn(DBGFR3AddrIsValid(pUVM, pModAddress), VERR_INVALID_PARAMETER);
AssertReturn(fFlags == 0, VERR_INVALID_PARAMETER);
- RTDBGAS hRealAS = DBGFR3AsResolveAndRetain(pVM, hDbgAs);
+ RTDBGAS hRealAS = DBGFR3AsResolveAndRetain(pUVM, hDbgAs);
if (hRealAS == NIL_RTDBGAS)
return VERR_INVALID_HANDLE;
- /*
- * Do the work.
- */
- DBGFR3ASLOADOPENDATA Data;
- Data.pszModName = pszModName;
- Data.uSubtrahend = uSubtrahend;
- Data.fFlags = 0;
- Data.hMod = NIL_RTDBGMOD;
- int rc = dbgfR3AsSearchCfgPath(pVM, pszFilename, "MapPath", dbgfR3AsLoadMapOpen, &Data);
- if (RT_FAILURE(rc))
- rc = dbgfR3AsSearchEnvPath(pszFilename, "VBOXDBG_MAP_PATH", dbgfR3AsLoadMapOpen, &Data);
- if (RT_FAILURE(rc))
- rc = dbgfR3AsSearchCfgPath(pVM, pszFilename, "Path", dbgfR3AsLoadMapOpen, &Data);
- if (RT_FAILURE(rc))
- rc = dbgfR3AsSearchEnvPath(pszFilename, "VBOXDBG_PATH", dbgfR3AsLoadMapOpen, &Data);
+ RTDBGMOD hDbgMod;
+ int rc = RTDbgModCreateFromMap(&hDbgMod, pszFilename, pszModName, uSubtrahend, pUVM->dbgf.s.hDbgCfg);
if (RT_SUCCESS(rc))
{
- rc = DBGFR3AsLinkModule(pVM, hRealAS, Data.hMod, pModAddress, iModSeg, 0);
+ rc = DBGFR3AsLinkModule(pUVM, hRealAS, hDbgMod, pModAddress, iModSeg, 0);
if (RT_FAILURE(rc))
- RTDbgModRelease(Data.hMod);
+ RTDbgModRelease(hDbgMod);
}
RTDbgAsRelease(hRealAS);
@@ -887,21 +1033,22 @@ VMMR3DECL(int) DBGFR3AsLoadMap(PVM pVM, RTDBGAS hDbgAs, const char *pszFilename,
* Wrapper around RTDbgAsModuleLink, RTDbgAsModuleLinkSeg and DBGFR3AsResolve.
*
* @returns VBox status code.
- * @param pVM Pointer to the VM.
+ * @param pUVM The user mode VM handle.
* @param hDbgAs The address space handle.
* @param hMod The module handle.
* @param pModAddress The link address.
* @param iModSeg The segment to link, NIL_RTDBGSEGIDX for the entire image.
* @param fFlags Flags to pass to the link functions, see RTDBGASLINK_FLAGS_*.
*/
-VMMR3DECL(int) DBGFR3AsLinkModule(PVM pVM, RTDBGAS hDbgAs, RTDBGMOD hMod, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags)
+VMMR3DECL(int) DBGFR3AsLinkModule(PUVM pUVM, RTDBGAS hDbgAs, RTDBGMOD hMod, PCDBGFADDRESS pModAddress,
+ RTDBGSEGIDX iModSeg, uint32_t fFlags)
{
/*
* Input validation.
*/
- VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
- AssertReturn(DBGFR3AddrIsValid(pVM, pModAddress), VERR_INVALID_PARAMETER);
- RTDBGAS hRealAS = DBGFR3AsResolveAndRetain(pVM, hDbgAs);
+ UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
+ AssertReturn(DBGFR3AddrIsValid(pUVM, pModAddress), VERR_INVALID_PARAMETER);
+ RTDBGAS hRealAS = DBGFR3AsResolveAndRetain(pUVM, hDbgAs);
if (hRealAS == NIL_RTDBGAS)
return VERR_INVALID_HANDLE;
@@ -920,6 +1067,54 @@ VMMR3DECL(int) DBGFR3AsLinkModule(PVM pVM, RTDBGAS hDbgAs, RTDBGMOD hMod, PCDBGF
/**
+ * Wrapper around RTDbgAsModuleByName and RTDbgAsModuleUnlink.
+ *
+ * Unlinks all mappings matching the given module name.
+ *
+ * @returns VBox status code.
+ * @param pUVM The user mode VM handle.
+ * @param hDbgAs The address space handle.
+ * @param pszModName The name of the module to unlink.
+ */
+VMMR3DECL(int) DBGFR3AsUnlinkModuleByName(PUVM pUVM, RTDBGAS hDbgAs, const char *pszModName)
+{
+ /*
+ * Input validation.
+ */
+ UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
+ RTDBGAS hRealAS = DBGFR3AsResolveAndRetain(pUVM, hDbgAs);
+ if (hRealAS == NIL_RTDBGAS)
+ return VERR_INVALID_HANDLE;
+
+ /*
+ * Do the job.
+ */
+ RTDBGMOD hMod;
+ int rc = RTDbgAsModuleByName(hRealAS, pszModName, 0, &hMod);
+ if (RT_SUCCESS(rc))
+ {
+ for (;;)
+ {
+ rc = RTDbgAsModuleUnlink(hRealAS, hMod);
+ RTDbgModRelease(hMod);
+ if (RT_FAILURE(rc))
+ break;
+ rc = RTDbgAsModuleByName(hRealAS, pszModName, 0, &hMod);
+ if (RT_FAILURE_NP(rc))
+ {
+ if (rc == VERR_NOT_FOUND)
+ rc = VINF_SUCCESS;
+ break;
+ }
+ }
+ }
+
+ RTDbgAsRelease(hRealAS);
+ return rc;
+}
+
+
+/**
* Adds the module name to the symbol name.
*
* @param pSymbol The symbol info (in/out).
@@ -966,17 +1161,18 @@ static void dbgfR3AsSymbolConvert(PRTDBGSYMBOL pSymbol, PCDBGFSYMBOL pDbgfSym)
*
* @returns VBox status code. See RTDbgAsSymbolByAddr.
*
- * @param pVM Pointer to the VM.
- * @param hDbgAs The address space handle.
- * @param pAddress The address to lookup.
- * @param poffDisp Where to return the distance between the
- * returned symbol and pAddress. Optional.
- * @param pSymbol Where to return the symbol information.
- * The returned symbol name will be prefixed by
- * the module name as far as space allows.
- * @param phMod Where to return the module handle. Optional.
+ * @param pUVM The user mode VM handle.
+ * @param hDbgAs The address space handle.
+ * @param pAddress The address to lookup.
+ * @param fFlags One of the RTDBGSYMADDR_FLAGS_XXX flags.
+ * @param poffDisp Where to return the distance between the returned
+ * symbol and pAddress. Optional.
+ * @param pSymbol Where to return the symbol information. The returned
+ * symbol name will be prefixed by the module name as
+ * far as space allows.
+ * @param phMod Where to return the module handle. Optional.
*/
-VMMR3DECL(int) DBGFR3AsSymbolByAddr(PVM pVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress,
+VMMR3DECL(int) DBGFR3AsSymbolByAddr(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, uint32_t fFlags,
PRTGCINTPTR poffDisp, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod)
{
/*
@@ -984,17 +1180,17 @@ VMMR3DECL(int) DBGFR3AsSymbolByAddr(PVM pVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddr
*/
if (hDbgAs == DBGF_AS_RC_AND_GC_GLOBAL)
{
- int rc = DBGFR3AsSymbolByAddr(pVM, DBGF_AS_RC, pAddress, poffDisp, pSymbol, phMod);
+ int rc = DBGFR3AsSymbolByAddr(pUVM, DBGF_AS_RC, pAddress, fFlags, poffDisp, pSymbol, phMod);
if (RT_FAILURE(rc))
- rc = DBGFR3AsSymbolByAddr(pVM, DBGF_AS_GLOBAL, pAddress, poffDisp, pSymbol, phMod);
+ rc = DBGFR3AsSymbolByAddr(pUVM, DBGF_AS_GLOBAL, pAddress, fFlags, poffDisp, pSymbol, phMod);
return rc;
}
/*
* Input validation.
*/
- VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
- AssertReturn(DBGFR3AddrIsValid(pVM, pAddress), VERR_INVALID_PARAMETER);
+ UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
+ AssertReturn(DBGFR3AddrIsValid(pUVM, pAddress), VERR_INVALID_PARAMETER);
AssertPtrNullReturn(poffDisp, VERR_INVALID_POINTER);
AssertPtrReturn(pSymbol, VERR_INVALID_POINTER);
AssertPtrNullReturn(phMod, VERR_INVALID_POINTER);
@@ -1002,7 +1198,7 @@ VMMR3DECL(int) DBGFR3AsSymbolByAddr(PVM pVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddr
*poffDisp = 0;
if (phMod)
*phMod = NIL_RTDBGMOD;
- RTDBGAS hRealAS = DBGFR3AsResolveAndRetain(pVM, hDbgAs);
+ RTDBGAS hRealAS = DBGFR3AsResolveAndRetain(pUVM, hDbgAs);
if (hRealAS == NIL_RTDBGAS)
return VERR_INVALID_HANDLE;
@@ -1010,49 +1206,13 @@ VMMR3DECL(int) DBGFR3AsSymbolByAddr(PVM pVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddr
* Do the lookup.
*/
RTDBGMOD hMod;
- int rc = RTDbgAsSymbolByAddr(hRealAS, pAddress->FlatPtr, RTDBGSYMADDR_FLAGS_LESS_OR_EQUAL, poffDisp, pSymbol, &hMod);
+ int rc = RTDbgAsSymbolByAddr(hRealAS, pAddress->FlatPtr, fFlags, poffDisp, pSymbol, &hMod);
if (RT_SUCCESS(rc))
{
dbgfR3AsSymbolJoinNames(pSymbol, hMod);
if (!phMod)
RTDbgModRelease(hMod);
}
- /* Temporary conversions. */
- else if (hDbgAs == DBGF_AS_GLOBAL)
- {
- DBGFSYMBOL DbgfSym;
- rc = DBGFR3SymbolByAddr(pVM, pAddress->FlatPtr, poffDisp, &DbgfSym);
- if (RT_SUCCESS(rc))
- dbgfR3AsSymbolConvert(pSymbol, &DbgfSym);
- }
- else if (hDbgAs == DBGF_AS_R0)
- {
- RTR0PTR R0PtrMod;
- char szNearSym[260];
- RTR0PTR R0PtrNearSym;
- RTR0PTR R0PtrNearSym2;
- rc = PDMR3LdrQueryR0ModFromPC(pVM, pAddress->FlatPtr,
- pSymbol->szName, sizeof(pSymbol->szName) / 2, &R0PtrMod,
- &szNearSym[0], sizeof(szNearSym), &R0PtrNearSym,
- NULL, 0, &R0PtrNearSym2);
- if (RT_SUCCESS(rc))
- {
- pSymbol->offSeg = pSymbol->Value = R0PtrNearSym;
- pSymbol->cb = R0PtrNearSym2 > R0PtrNearSym ? R0PtrNearSym2 - R0PtrNearSym : 0;
- pSymbol->iSeg = 0;
- pSymbol->fFlags = 0;
- pSymbol->iOrdinal = UINT32_MAX;
- size_t offName = strlen(pSymbol->szName);
- pSymbol->szName[offName++] = '!';
- size_t cchNearSym = strlen(szNearSym);
- if (cchNearSym + offName >= sizeof(pSymbol->szName))
- cchNearSym = sizeof(pSymbol->szName) - offName - 1;
- strncpy(&pSymbol->szName[offName], szNearSym, cchNearSym);
- pSymbol->szName[offName + cchNearSym] = '\0';
- if (poffDisp)
- *poffDisp = pAddress->FlatPtr - pSymbol->Value;
- }
- }
return rc;
}
@@ -1065,16 +1225,18 @@ VMMR3DECL(int) DBGFR3AsSymbolByAddr(PVM pVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddr
* RTDbgSymbolFree(). NULL is returned if not found or any error
* occurs.
*
- * @param pVM Pointer to the VM.
- * @param hDbgAs See DBGFR3AsSymbolByAddr.
- * @param pAddress See DBGFR3AsSymbolByAddr.
- * @param poffDisp See DBGFR3AsSymbolByAddr.
- * @param phMod See DBGFR3AsSymbolByAddr.
+ * @param pUVM The user mode VM handle.
+ * @param hDbgAs See DBGFR3AsSymbolByAddr.
+ * @param pAddress See DBGFR3AsSymbolByAddr.
+ * @param fFlags See DBGFR3AsSymbolByAddr.
+ * @param poffDisp See DBGFR3AsSymbolByAddr.
+ * @param phMod See DBGFR3AsSymbolByAddr.
*/
-VMMR3DECL(PRTDBGSYMBOL) DBGFR3AsSymbolByAddrA(PVM pVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, PRTGCINTPTR poffDisp, PRTDBGMOD phMod)
+VMMR3DECL(PRTDBGSYMBOL) DBGFR3AsSymbolByAddrA(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, uint32_t fFlags,
+ PRTGCINTPTR poffDisp, PRTDBGMOD phMod)
{
RTDBGSYMBOL SymInfo;
- int rc = DBGFR3AsSymbolByAddr(pVM, hDbgAs, pAddress, poffDisp, &SymInfo, phMod);
+ int rc = DBGFR3AsSymbolByAddr(pUVM, hDbgAs, pAddress, fFlags, poffDisp, &SymInfo, phMod);
if (RT_SUCCESS(rc))
return RTDbgSymbolDup(&SymInfo);
return NULL;
@@ -1090,16 +1252,16 @@ VMMR3DECL(PRTDBGSYMBOL) DBGFR3AsSymbolByAddrA(PVM pVM, RTDBGAS hDbgAs, PCDBGFADD
*
* @returns VBox status code. See RTDbgAsSymbolByAddr.
*
- * @param pVM Pointer to the VM.
- * @param hDbgAs The address space handle.
- * @param pszSymbol The symbol to search for, maybe prefixed by a
- * module pattern.
- * @param pSymbol Where to return the symbol information.
- * The returned symbol name will be prefixed by
- * the module name as far as space allows.
- * @param phMod Where to return the module handle. Optional.
+ * @param pUVM The user mode VM handle.
+ * @param hDbgAs The address space handle.
+ * @param pszSymbol The symbol to search for, maybe prefixed by a
+ * module pattern.
+ * @param pSymbol Where to return the symbol information.
+ * The returned symbol name will be prefixed by
+ * the module name as far as space allows.
+ * @param phMod Where to return the module handle. Optional.
*/
-VMMR3DECL(int) DBGFR3AsSymbolByName(PVM pVM, RTDBGAS hDbgAs, const char *pszSymbol,
+VMMR3DECL(int) DBGFR3AsSymbolByName(PUVM pUVM, RTDBGAS hDbgAs, const char *pszSymbol,
PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod)
{
/*
@@ -1107,21 +1269,21 @@ VMMR3DECL(int) DBGFR3AsSymbolByName(PVM pVM, RTDBGAS hDbgAs, const char *pszSymb
*/
if (hDbgAs == DBGF_AS_RC_AND_GC_GLOBAL)
{
- int rc = DBGFR3AsSymbolByName(pVM, DBGF_AS_RC, pszSymbol, pSymbol, phMod);
+ int rc = DBGFR3AsSymbolByName(pUVM, DBGF_AS_RC, pszSymbol, pSymbol, phMod);
if (RT_FAILURE(rc))
- rc = DBGFR3AsSymbolByName(pVM, DBGF_AS_GLOBAL, pszSymbol, pSymbol, phMod);
+ rc = DBGFR3AsSymbolByName(pUVM, DBGF_AS_GLOBAL, pszSymbol, pSymbol, phMod);
return rc;
}
/*
* Input validation.
*/
- VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
+ UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
AssertPtrReturn(pSymbol, VERR_INVALID_POINTER);
AssertPtrNullReturn(phMod, VERR_INVALID_POINTER);
if (phMod)
*phMod = NIL_RTDBGMOD;
- RTDBGAS hRealAS = DBGFR3AsResolveAndRetain(pVM, hDbgAs);
+ RTDBGAS hRealAS = DBGFR3AsResolveAndRetain(pUVM, hDbgAs);
if (hRealAS == NIL_RTDBGAS)
return VERR_INVALID_HANDLE;
@@ -1137,15 +1299,55 @@ VMMR3DECL(int) DBGFR3AsSymbolByName(PVM pVM, RTDBGAS hDbgAs, const char *pszSymb
if (!phMod)
RTDbgModRelease(hMod);
}
- /* Temporary conversion. */
- else if (hDbgAs == DBGF_AS_GLOBAL)
+
+ return rc;
+}
+
+
+VMMR3DECL(int) DBGFR3AsLineByAddr(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress,
+ PRTGCINTPTR poffDisp, PRTDBGLINE pLine, PRTDBGMOD phMod)
+{
+ /*
+ * Implement the special address space aliases the lazy way.
+ */
+ if (hDbgAs == DBGF_AS_RC_AND_GC_GLOBAL)
{
- DBGFSYMBOL DbgfSym;
- rc = DBGFR3SymbolByName(pVM, pszSymbol, &DbgfSym);
- if (RT_SUCCESS(rc))
- dbgfR3AsSymbolConvert(pSymbol, &DbgfSym);
+ int rc = DBGFR3AsLineByAddr(pUVM, DBGF_AS_RC, pAddress, poffDisp, pLine, phMod);
+ if (RT_FAILURE(rc))
+ rc = DBGFR3AsLineByAddr(pUVM, DBGF_AS_GLOBAL, pAddress, poffDisp, pLine, phMod);
+ return rc;
}
- return rc;
+ /*
+ * Input validation.
+ */
+ UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
+ AssertReturn(DBGFR3AddrIsValid(pUVM, pAddress), VERR_INVALID_PARAMETER);
+ AssertPtrNullReturn(poffDisp, VERR_INVALID_POINTER);
+ AssertPtrReturn(pLine, VERR_INVALID_POINTER);
+ AssertPtrNullReturn(phMod, VERR_INVALID_POINTER);
+ if (poffDisp)
+ *poffDisp = 0;
+ if (phMod)
+ *phMod = NIL_RTDBGMOD;
+ RTDBGAS hRealAS = DBGFR3AsResolveAndRetain(pUVM, hDbgAs);
+ if (hRealAS == NIL_RTDBGAS)
+ return VERR_INVALID_HANDLE;
+
+ /*
+ * Do the lookup.
+ */
+ return RTDbgAsLineByAddr(hRealAS, pAddress->FlatPtr, poffDisp, pLine, phMod);
+}
+
+
+VMMR3DECL(PRTDBGLINE) DBGFR3AsLineByAddrA(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress,
+ PRTGCINTPTR poffDisp, PRTDBGMOD phMod)
+{
+ RTDBGLINE Line;
+ int rc = DBGFR3AsLineByAddr(pUVM, hDbgAs, pAddress, poffDisp, &Line, phMod);
+ if (RT_SUCCESS(rc))
+ return RTDbgLineDup(&Line);
+ return NULL;
}