diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2014-03-26 19:21:20 +0000 |
---|---|---|
committer | <> | 2014-05-08 15:03:54 +0000 |
commit | fb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch) | |
tree | c2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/Runtime/common/dbg/dbgas.cpp | |
parent | 58ed4748338f9466599adfc8a9171280ed99e23f (diff) | |
download | VirtualBox-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/Runtime/common/dbg/dbgas.cpp')
-rw-r--r-- | src/VBox/Runtime/common/dbg/dbgas.cpp | 180 |
1 files changed, 113 insertions, 67 deletions
diff --git a/src/VBox/Runtime/common/dbg/dbgas.cpp b/src/VBox/Runtime/common/dbg/dbgas.cpp index 947fffaa..445cc492 100644 --- a/src/VBox/Runtime/common/dbg/dbgas.cpp +++ b/src/VBox/Runtime/common/dbg/dbgas.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009 Oracle Corporation + * Copyright (C) 2009-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -396,6 +396,26 @@ RTDECL(uint32_t) RTDbgAsRelease(RTDBGAS hDbgAs) RT_EXPORT_SYMBOL(RTDbgAsRelease); +RTDECL(int) RTDbgAsLockExcl(RTDBGAS hDbgAs) +{ + PRTDBGASINT pDbgAs = hDbgAs; + RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE); + RTDBGAS_LOCK_WRITE(pDbgAs); + return VINF_SUCCESS; +} +RT_EXPORT_SYMBOL(RTDbgAsLockExcl); + + +RTDECL(int) RTDbgAsUnlockExcl(RTDBGAS hDbgAs) +{ + PRTDBGASINT pDbgAs = hDbgAs; + RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE); + RTDBGAS_UNLOCK_WRITE(pDbgAs); + return VINF_SUCCESS; +} +RT_EXPORT_SYMBOL(RTDbgAsUnlockExcl); + + /** * Gets the name of an address space. * @@ -900,7 +920,7 @@ RTDECL(int) RTDbgAsModuleUnlinkByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr) RTDBGAS_LOCK_WRITE(pDbgAs); PRTDBGASMAP pMap = (PRTDBGASMAP)RTAvlrUIntPtrRangeGet(&pDbgAs->MapTree, Addr); - if (pMap) + if (!pMap) { RTDBGAS_UNLOCK_WRITE(pDbgAs); return VERR_NOT_FOUND; @@ -1283,6 +1303,37 @@ RT_EXPORT_SYMBOL(RTDbgAsSymbolAdd); /** + * Creates a snapshot of the module table on the temporary heap. + * + * The caller must release all the module handles before freeing the table + * using RTMemTmpFree. + * + * @returns Module table snaphot. + * @param pDbgAs The address space instance data. + * @param pcModules Where to return the number of modules. + */ +static PRTDBGMOD rtDbgAsSnapshotModuleTable(PRTDBGASINT pDbgAs, uint32_t *pcModules) +{ + RTDBGAS_LOCK_READ(pDbgAs); + + uint32_t iMod = *pcModules = pDbgAs->cModules; + PRTDBGMOD pahModules = (PRTDBGMOD)RTMemTmpAlloc(sizeof(pahModules[0]) * RT_MAX(iMod, 1)); + if (pahModules) + { + while (iMod-- > 0) + { + RTDBGMOD hMod = (RTDBGMOD)pDbgAs->papModules[iMod]->Core.Key; + pahModules[iMod] = hMod; + RTDbgModRetain(hMod); + } + } + + RTDBGAS_UNLOCK_READ(pDbgAs); + return pahModules; +} + + +/** * Query a symbol by address. * * @returns IPRT status code. See RTDbgModSymbolAddr for more specific ones. @@ -1306,6 +1357,8 @@ RTDECL(int) RTDbgAsSymbolByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr, uint32_t fFlags, */ PRTDBGASINT pDbgAs = hDbgAs; RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE); + if (phMod) + *phMod = NIL_RTDBGMOD; RTDBGSEGIDX iSeg = NIL_RTDBGSEGIDX; /* shut up gcc */ RTUINTPTR offSeg = 0; @@ -1313,9 +1366,46 @@ RTDECL(int) RTDbgAsSymbolByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr, uint32_t fFlags, RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg, &MapAddr); if (hMod == NIL_RTDBGMOD) { - if (phMod) - *phMod = NIL_RTDBGMOD; - return VERR_NOT_FOUND; + /* + * Check for absolute symbols. Requires iterating all modules. + */ + uint32_t cModules; + PRTDBGMOD pahModules = rtDbgAsSnapshotModuleTable(pDbgAs, &cModules); + if (!pahModules) + return VERR_NO_TMP_MEMORY; + + int rc; + RTINTPTR offBestDisp = RTINTPTR_MAX; + uint32_t iBest = UINT32_MAX; + for (uint32_t i = 0; i < cModules; i++) + { + RTINTPTR offDisp; + rc = RTDbgModSymbolByAddr(pahModules[i], RTDBGSEGIDX_ABS, Addr, fFlags, &offDisp, pSymbol); + if (RT_SUCCESS(rc) && RT_ABS(offDisp) < offBestDisp) + { + offBestDisp = RT_ABS(offDisp); + iBest = i; + } + } + + if (iBest == UINT32_MAX) + rc = VERR_NOT_FOUND; + else + { + hMod = pahModules[iBest]; + rc = RTDbgModSymbolByAddr(hMod, RTDBGSEGIDX_ABS, Addr, fFlags, poffDisp, pSymbol); + if (RT_SUCCESS(rc)) + { + rtDbgAsAdjustSymbolValue(pSymbol, hMod, MapAddr, iSeg); + if (phMod) + RTDbgModRetain(*phMod = hMod); + } + } + + for (uint32_t i = 0; i < cModules; i++) + RTDbgModRelease(pahModules[i]); + RTMemTmpFree(pahModules); + return rc; } /* @@ -1386,37 +1476,6 @@ RT_EXPORT_SYMBOL(RTDbgAsSymbolByAddrA); /** - * Creates a snapshot of the module table on the temporary heap. - * - * The caller must release all the module handles before freeing the table - * using RTMemTmpFree. - * - * @returns Module table snaphot. - * @param pDbgAs The address space instance data. - * @param pcModules Where to return the number of modules. - */ -DECLINLINE(PRTDBGMOD) rtDbgAsSnapshotModuleTable(PRTDBGASINT pDbgAs, uint32_t *pcModules) -{ - RTDBGAS_LOCK_READ(pDbgAs); - - uint32_t iMod = *pcModules = pDbgAs->cModules; - PRTDBGMOD pahModules = (PRTDBGMOD)RTMemTmpAlloc(sizeof(pahModules[0]) * RT_MAX(iMod, 1)); - if (pahModules) - { - while (iMod-- > 0) - { - RTDBGMOD hMod = (RTDBGMOD)pDbgAs->papModules[iMod]->Core.Key; - pahModules[iMod] = hMod; - RTDbgModRetain(hMod); - } - } - - RTDBGAS_UNLOCK_READ(pDbgAs); - return pahModules; -} - - -/** * Attempts to find a mapping of the specified symbol/module and * adjust it's Value field accordingly. * @@ -1675,20 +1734,7 @@ RTDECL(int) RTDbgAsLineAdd(RTDBGAS hDbgAs, const char *pszFile, uint32_t uLineNo RT_EXPORT_SYMBOL(RTDbgAsLineAdd); -/** - * Query a line number by address. - * - * @returns IPRT status code. See RTDbgModSymbolAddrA for more specific ones. - * @retval VERR_INVALID_HANDLE if hDbgAs is invalid. - * @retval VERR_NOT_FOUND if the address couldn't be mapped to a module. - * - * @param hDbgAs The address space handle. - * @param Addr The address which closest symbol is requested. - * @param poffDisp Where to return the distance between the line - * number and address. - * @param pLine Where to return the line number information. - */ -RTDECL(int) RTDbgAsLineByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGLINE pLine) +RTDECL(int) RTDbgAsLineByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGLINE pLine, PRTDBGMOD phMod) { /* * Validate input and resolve the address. @@ -1708,28 +1754,21 @@ RTDECL(int) RTDbgAsLineByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp */ int rc = RTDbgModLineByAddr(hMod, iSeg, offSeg, poffDisp, pLine); if (RT_SUCCESS(rc)) + { rtDbgAsAdjustLineAddress(pLine, hMod, MapAddr, iSeg); - RTDbgModRelease(hMod); + if (phMod) + *phMod = hMod; + else + RTDbgModRelease(hMod); + } + else + RTDbgModRelease(hMod); return rc; } RT_EXPORT_SYMBOL(RTDbgAsLineByAddr); -/** - * Query a line number by address. - * - * @returns IPRT status code. See RTDbgModSymbolAddrA for more specific ones. - * @retval VERR_INVALID_HANDLE if hDbgAs is invalid. - * @retval VERR_NOT_FOUND if the address couldn't be mapped to a module. - * - * @param hDbgAs The address space handle. - * @param Addr The address which closest symbol is requested. - * @param poffDisp Where to return the distance between the line - * number and address. - * @param ppLine Where to return the pointer to the allocated line - * number info. Always set. Free with RTDbgLineFree. - */ -RTDECL(int) RTDbgAsLineByAddrA(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGLINE *ppLine) +RTDECL(int) RTDbgAsLineByAddrA(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGLINE *ppLine, PRTDBGMOD phMod) { /* * Validate input and resolve the address. @@ -1749,8 +1788,15 @@ RTDECL(int) RTDbgAsLineByAddrA(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDis */ int rc = RTDbgModLineByAddrA(hMod, iSeg, offSeg, poffDisp, ppLine); if (RT_SUCCESS(rc)) + { rtDbgAsAdjustLineAddress(*ppLine, hMod, MapAddr, iSeg); - RTDbgModRelease(hMod); + if (phMod) + *phMod = hMod; + else + RTDbgModRelease(hMod); + } + else + RTDbgModRelease(hMod); return rc; } RT_EXPORT_SYMBOL(RTDbgAsLineByAddrA); |