8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * IPRT - Debug Module Interpreter.
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2009-2012 Oracle Corporation
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * available from http://www.virtualbox.org. This file is free software;
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * you can redistribute it and/or modify it under the terms of the GNU
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * General Public License (GPL) as published by the Free Software
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * The contents of this file may alternatively be used under the terms
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * of the Common Development and Distribution License Version 1.0
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * VirtualBox OSE distribution, in which case the provisions of the
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * CDDL are applicable instead of those of the GPL.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * You may elect to license modified versions of this file under the
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync * terms and conditions of either the GPL or the CDDL or both.
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync/*******************************************************************************
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync* Header Files *
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsync*******************************************************************************/
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync/*******************************************************************************
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync* Structures and Typedefs *
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync*******************************************************************************/
1c822ec4298d5d20b0fb1cc20346c5d4e4e596bfvboxsync/** Debug info interpreter registration record. */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /** Pointer to the next record. */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /** Pointer to the virtual function table for the interpreter. */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /** Usage counter. */
1c822ec4298d5d20b0fb1cc20346c5d4e4e596bfvboxsync/** Image interpreter registration record. */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /** Pointer to the next record. */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /** Pointer to the virtual function table for the interpreter. */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /** Usage counter. */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync/*******************************************************************************
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync* Defined Constants And Macros *
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync*******************************************************************************/
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync/** Validates a debug module handle and returns rc if not valid. */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync AssertReturn((pDbgMod)->u32Magic == RTDBGMOD_MAGIC, (rc)); \
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync } while (0)
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync/** Locks the debug module. */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync int rcLock = RTCritSectEnter(&(pDbgMod)->CritSect); \
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync } while (0)
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync/** Unlocks the debug module. */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync int rcLock = RTCritSectLeave(&(pDbgMod)->CritSect); \
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync } while (0)
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync/*******************************************************************************
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync* Global Variables *
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync*******************************************************************************/
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync/** Init once object for lazy registration of the built-in image and debug
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync * info interpreters. */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync/** Read/Write semaphore protecting the list of registered interpreters. */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync/** List of registered image interpreters. */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync/** List of registered debug infor interpreters. */
7af218a7441de38fc9e814919db04bae3e917664vboxsync/** String cache for the debug info interpreters.
7af218a7441de38fc9e814919db04bae3e917664vboxsync * RTSTRCACHE is thread safe. */
7af218a7441de38fc9e814919db04bae3e917664vboxsyncDECLHIDDEN(RTSTRCACHE) g_hDbgModStrCache = NIL_RTSTRCACHE;
7af218a7441de38fc9e814919db04bae3e917664vboxsync * Cleanup debug info interpreter globals.
7af218a7441de38fc9e814919db04bae3e917664vboxsync * @param enmReason The cause of the termination.
7af218a7441de38fc9e814919db04bae3e917664vboxsync * @param iStatus The meaning of this depends on enmReason.
7af218a7441de38fc9e814919db04bae3e917664vboxsync * @param pvUser User argument, unused.
7af218a7441de38fc9e814919db04bae3e917664vboxsyncstatic DECLCALLBACK(void) rtDbgModTermCallback(RTTERMREASON enmReason, int32_t iStatus, void *pvUser)
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync AssertMsg(pDbg->cUsers == 0, ("%#x %s\n", pDbg->cUsers, pDbg->pVt->pszName));
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync AssertMsg(pImg->cUsers == 0, ("%#x %s\n", pImg->cUsers, pImg->pVt->pszName));
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync * Internal worker for register a debug interpreter.
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync * Called while owning the write lock or when locking isn't required.
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync * @returns IPRT status code.
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync * @retval VERR_NO_MEMORY
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync * @retval VERR_ALREADY_EXISTS
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync * @param pVt The virtual function table of the debug
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync * module interpreter.
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsyncstatic int rtDbgModDebugInterpreterRegister(PCRTDBGMODVTDBG pVt)
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync * Search or duplicate registration.
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync for (PRTDBGMODREGDBG pCur = g_pDbgHead; pCur; pCur = pCur->pNext)
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync * Create a new record and add it to the end of the list.
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync PRTDBGMODREGDBG pReg = (PRTDBGMODREGDBG)RTMemAlloc(sizeof(*pReg));
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * Internal worker for register a image interpreter.
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * Called while owning the write lock or when locking isn't required.
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * @returns IPRT status code.
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * @retval VERR_NO_MEMORY
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * @retval VERR_ALREADY_EXISTS
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * @param pVt The virtual function table of the image
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * interpreter.
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsyncstatic int rtDbgModImageInterpreterRegister(PCRTDBGMODVTIMG pVt)
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * Search or duplicate registration.
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync for (PRTDBGMODREGIMG pCur = g_pImgHead; pCur; pCur = pCur->pNext)
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync * Create a new record and add it to the end of the list.
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync PRTDBGMODREGIMG pReg = (PRTDBGMODREGIMG)RTMemAlloc(sizeof(*pReg));
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync * Do-once callback that initializes the read/write semaphore and registers
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync * the built-in interpreters.
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync * @returns IPRT status code.
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * @param pvUser NULL.
a438caaf732f7839dc66b4f8dad672527845a003vboxsyncstatic DECLCALLBACK(int) rtDbgModInitOnce(void *pvUser)
7af218a7441de38fc9e814919db04bae3e917664vboxsync * Create the semaphore and string cache.
7af218a7441de38fc9e814919db04bae3e917664vboxsync rc = RTStrCacheCreate(&g_hDbgModStrCache, "RTDBGMOD");
7af218a7441de38fc9e814919db04bae3e917664vboxsync * Register the interpreters.
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync rc = rtDbgModDebugInterpreterRegister(&g_rtDbgModVtDbgNm);
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync rc = rtDbgModDebugInterpreterRegister(&g_rtDbgModVtDbgDwarf);
541212b8e2b7f2f1d237d16a6658cbd195b1b936vboxsync rc = rtDbgModDebugInterpreterRegister(&g_rtDbgModVtDbgCodeView);
e36f03470adaee73199dcdddd8eb9cf39bbdf7advboxsync rc = rtDbgModDebugInterpreterRegister(&g_rtDbgModVtDbgDbgHelp);
c58c758d3642ac45d3f12356c406c631fcd8f538vboxsync rc = rtDbgModImageInterpreterRegister(&g_rtDbgModVtImgLdr);
7af218a7441de38fc9e814919db04bae3e917664vboxsync * Finally, register the IPRT cleanup callback.
7af218a7441de38fc9e814919db04bae3e917664vboxsync rc = RTTermRegisterCallback(rtDbgModTermCallback, NULL);
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync /* bail out: use the termination callback. */
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync rtDbgModTermCallback(RTTERMREASON_UNLOAD, 0, NULL);
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync * Performs lazy init of our global variables.
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync * @returns IPRT status code.
a438caaf732f7839dc66b4f8dad672527845a003vboxsync return RTOnce(&g_rtDbgModOnce, rtDbgModInitOnce, NULL);
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsyncRTDECL(int) RTDbgModCreate(PRTDBGMOD phDbgMod, const char *pszName, RTUINTPTR cbSeg, uint32_t fFlags)
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync * Input validation and lazy initialization.
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync AssertReturn(fFlags == 0 || fFlags == RTDBGMOD_F_NOT_DEFERRED, VERR_INVALID_PARAMETER);
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync * Allocate a new module instance.
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync PRTDBGMODINT pDbgMod = (PRTDBGMODINT)RTMemAllocZ(sizeof(*pDbgMod));
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pDbgMod->pszImgFileSpecified = RTStrCacheEnter(g_hDbgModStrCache, pszName);
fd66a4782980b7567eb181f809b629e74e4fd697vboxsync pDbgMod->pszName = RTStrCacheEnterLower(g_hDbgModStrCache, RTPathFilenameEx(pszName, RTPATH_STR_F_STYLE_DOS));
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile);
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName);
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsyncRTDECL(int) RTDbgModCreateFromMap(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName,
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync * Input validation and lazy initialization.
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync AssertReturn(*pszFilename, VERR_INVALID_PARAMETER);
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync AssertPtrNullReturn(pszName, VERR_INVALID_POINTER);
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync AssertReturn(uSubtrahend == 0, VERR_NOT_IMPLEMENTED); /** @todo implement uSubtrahend. */
fd66a4782980b7567eb181f809b629e74e4fd697vboxsync pszName = RTPathFilenameEx(pszFilename, RTPATH_STR_F_STYLE_DOS);
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync * Allocate a new module instance.
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync PRTDBGMODINT pDbgMod = (PRTDBGMODINT)RTMemAllocZ(sizeof(*pDbgMod));
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pDbgMod->pszName = RTStrCacheEnterLower(g_hDbgModStrCache, pszName);
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync pDbgMod->pszDbgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename);
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync * Try the map file readers.
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT);
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync for (PRTDBGMODREGDBG pCur = g_pDbgHead; pCur; pCur = pCur->pNext)
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync rc = pCur->pVt->pfnTryOpen(pDbgMod, RTLDRARCH_WHATEVER);
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync /* bail out */
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName);
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszDbgFile);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * E x e c u t a b l e I m a g e F i l e s
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * E x e c u t a b l e I m a g e F i l e s
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * E x e c u t a b l e I m a g e F i l e s
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync * Opens debug information for an image.
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync * @returns IPRT status code
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync * @param pDbgMod The debug module structure.
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync * @note This will generally not look for debug info stored in external
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync * files. rtDbgModFromPeImageExtDbgInfoCallback can help with that.
daa94352f51be2329ac8660f70396e03a7cb983bvboxsyncstatic int rtDbgModOpenDebugInfoInsideImage(PRTDBGMODINT pDbgMod)
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync int rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync for (PRTDBGMODREGDBG pDbg = g_pDbgHead; pDbg; pDbg = pDbg->pNext)
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync rc = pDbg->pVt->pfnTryOpen(pDbgMod, pDbgMod->pImgVt->pfnGetArch(pDbgMod));
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync * That's it!
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync/** @callback_method_impl{FNRTDBGCFGOPEN} */
daa94352f51be2329ac8660f70396e03a7cb983bvboxsyncstatic DECLCALLBACK(int) rtDbgModExtDbgInfoOpenCallback(RTDBGCFG hDbgCfg, const char *pszFilename, void *pvUser1, void *pvUser2)
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync NOREF(pDbgInfo); /** @todo consider a more direct search for a interpreter. */
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync * Set the debug file name and try possible interpreters.
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync pDbgMod->pszDbgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync int rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync for (PRTDBGMODREGDBG pDbg = g_pDbgHead; pDbg; pDbg = pDbg->pNext)
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync rc = pDbg->pVt->pfnTryOpen(pDbgMod, pDbgMod->pImgVt->pfnGetArch(pDbgMod));
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync /* No joy. */
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszDbgFile);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync * Argument package used by rtDbgModOpenDebugInfoExternalToImage.
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync/** @callback_method_impl{FNRTLDRENUMDBG} */
daa94352f51be2329ac8660f70396e03a7cb983bvboxsyncrtDbgModOpenDebugInfoExternalToImageCallback(RTLDRMOD hLdrMod, PCRTLDRDBGINFO pDbgInfo, void *pvUser)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync RTDBGMODOPENDIETI *pArgs = (RTDBGMODOPENDIETI *)pvUser;
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync Assert(pDbgInfo->enmType > RTLDRDBGINFOTYPE_INVALID && pDbgInfo->enmType < RTLDRDBGINFOTYPE_END);
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync * If a external debug type comes without a file name, calculate a
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync * likely debug filename for it. (Hack for NT4 drivers.)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync if (pDbgInfo->enmType == RTLDRDBGINFOTYPE_CODEVIEW_DBG)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync else if ( pDbgInfo->enmType == RTLDRDBGINFOTYPE_CODEVIEW_PDB20
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync || pDbgInfo->enmType == RTLDRDBGINFOTYPE_CODEVIEW_PDB70)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync char *psz = (char *)alloca(cchName + strlen(pszExt) + 1);
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync Log2(("rtDbgModOpenDebugInfoExternalToImageCallback: enmType=%d\n", pDbgInfo->enmType));
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync * Switch on type and call the appropriate search function.
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync rtDbgModExtDbgInfoOpenCallback, pArgs->pDbgMod, (void *)pDbgInfo);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync rtDbgModExtDbgInfoOpenCallback, pArgs->pDbgMod, (void *)pDbgInfo);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync rtDbgModExtDbgInfoOpenCallback, pArgs->pDbgMod, (void *)pDbgInfo);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync rtDbgModExtDbgInfoOpenCallback, pArgs->pDbgMod, (void *)pDbgInfo);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync Log(("rtDbgModOpenDebugInfoExternalToImageCallback: Don't know how to handle enmType=%d and pszFileExt=%s\n",
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync LogFlow(("RTDbgMod: Successfully opened external debug info '%s' for '%s'\n",
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync pArgs->pDbgMod->pszDbgFile, pArgs->pDbgMod->pszImgFile));
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync Log(("rtDbgModOpenDebugInfoExternalToImageCallback: '%s' (enmType=%d) for '%s' -> %Rrc\n",
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pszExtFile, pDbgInfo->enmType, pArgs->pDbgMod->pszImgFile, rc));
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync * Opens debug info listed in the image that is stored in a separate file.
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync * @returns IPRT status code
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync * @param pDbgMod The debug module.
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync * @param hDbgCfg The debug config. Can be NIL.
daa94352f51be2329ac8660f70396e03a7cb983bvboxsyncstatic int rtDbgModOpenDebugInfoExternalToImage(PRTDBGMODINT pDbgMod, RTDBGCFG hDbgCfg)
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync int rc = pDbgMod->pImgVt->pfnEnumDbgInfo(pDbgMod, rtDbgModOpenDebugInfoExternalToImageCallback, &Args);
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync LogFlow(("rtDbgModOpenDebugInfoExternalToImage: rc=%Rrc\n", rc));
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync/** @callback_method_impl{FNRTDBGCFGOPEN} */
6ba706e9f431401d425d16817fdcd6316f83b584vboxsyncstatic DECLCALLBACK(int) rtDbgModExtDbgInfoOpenCallback2(RTDBGCFG hDbgCfg, const char *pszFilename, void *pvUser1, void *pvUser2)
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync NOREF(pvUser2); /** @todo image matching string or smth. */
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Set the debug file name and try possible interpreters.
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync pDbgMod->pszDbgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync int rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync for (PRTDBGMODREGDBG pDbg = g_pDbgHead; pDbg; pDbg = pDbg->pNext)
d1e9999d55e7ac80a28692c161710be98071fc00vboxsync rc = pDbg->pVt->pfnTryOpen(pDbgMod, pDbgMod->pImgVt->pfnGetArch(pDbgMod));
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync /* No joy. */
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszDbgFile);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Opens external debug info that is not listed in the image.
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * @returns IPRT status code
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * @param pDbgMod The debug module.
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * @param hDbgCfg The debug config. Can be NIL.
6ba706e9f431401d425d16817fdcd6316f83b584vboxsyncstatic int rtDbgModOpenDebugInfoExternalToImage2(PRTDBGMODINT pDbgMod, RTDBGCFG hDbgCfg)
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Figure out what to search for based on the image format.
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync RTLDRFMT enmFmt = pDbgMod->pImgVt->pfnGetFormat(pDbgMod);
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync rc = pDbgMod->pImgVt->pfnQueryProp(pDbgMod, RTLDRPROP_UUID, &Uuid, sizeof(Uuid));
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync rc = RTDbgCfgOpenDsymBundle(hDbgCfg, pDbgMod->pszImgFile, pUuid,
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync rtDbgModExtDbgInfoOpenCallback2, pDbgMod, NULL /*pvUser2*/);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync#if 0 /* Will be links in the image if these apply. .map readers for PE or ELF we don't have. */
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync#if 0 /* Haven't implemented .sym or .map file readers for OS/2 yet. */
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync#if 0 /* Later */
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync LogFlow(("rtDbgModOpenDebugInfoExternalToImage2: rc=%Rrc\n", rc));
6ba706e9f431401d425d16817fdcd6316f83b584vboxsyncRTDECL(int) RTDbgModCreateFromImage(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName,
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Input validation and lazy initialization.
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync AssertReturn(*pszFilename, VERR_INVALID_PARAMETER);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync AssertPtrNullReturn(pszName, VERR_INVALID_POINTER);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync AssertReturn(enmArch > RTLDRARCH_INVALID && enmArch < RTLDRARCH_END, VERR_INVALID_PARAMETER);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync pszName = RTPathFilenameEx(pszFilename, RTPATH_STR_F_STYLE_DOS);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Allocate a new module instance.
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync PRTDBGMODINT pDbgMod = (PRTDBGMODINT)RTMemAllocZ(sizeof(*pDbgMod));
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync pDbgMod->pszName = RTStrCacheEnterLower(g_hDbgModStrCache, pszName);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync pDbgMod->pszImgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync pDbgMod->pszImgFileSpecified = pDbgMod->pszImgFile;
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Find an image reader which groks the file.
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync /** @todo need to specify some arch stuff here. */
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Image detected, but found no debug info we were
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * able to understand.
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync /** @todo some generic way of matching image and debug info, flexible signature
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * of some kind. Apple uses UUIDs, microsoft uses a UUID+age or a
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * size+timestamp, and GNU a CRC32 (last time I checked). */
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync rc = rtDbgModOpenDebugInfoExternalToImage(pDbgMod, hDbgCfg);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync rc = rtDbgModOpenDebugInfoExternalToImage2(pDbgMod, hDbgCfg);
682342827b0e80c493c820603508e79e76c42658vboxsync * We're done!
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync /* Failed, close up the shop. */
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Could it be a file containing raw debug info?
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync for (PRTDBGMODREGDBG pDbg = g_pDbgHead; pDbg; pDbg = pDbg->pNext)
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * That's it!
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync /* bail out */
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFileSpecified);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * P E I M A G E
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * P E I M A G E
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * P E I M A G E
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync/** @callback_method_impl{FNRTDBGCFGOPEN} */
daa94352f51be2329ac8660f70396e03a7cb983bvboxsyncstatic DECLCALLBACK(int) rtDbgModFromPeImageOpenCallback(RTDBGCFG hDbgCfg, const char *pszFilename, void *pvUser1, void *pvUser2)
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync PRTDBGMODDEFERRED pDeferred = (PRTDBGMODDEFERRED)pvUser2;
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync LogFlow(("rtDbgModFromPeImageOpenCallback: %s\n", pszFilename));
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * Replace the image file name while probing it.
fa6dbd9c9e9645298cca864aa561382469907905vboxsync const char *pszNewImgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync * Find an image reader which groks the file.
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync int rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync rc = pImg->pVt->pfnTryOpen(pDbgMod, RTLDRARCH_WHATEVER);
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * Check the deferred info.
fa6dbd9c9e9645298cca864aa561382469907905vboxsync RTUINTPTR cbImage = pDbgMod->pImgVt->pfnImageSize(pDbgMod);
fa6dbd9c9e9645298cca864aa561382469907905vboxsync uint32_t uTimestamp = pDeferred->u.PeImage.uTimestamp; /** @todo add method for getting the timestamp. */
fa6dbd9c9e9645298cca864aa561382469907905vboxsync Log(("RTDbgMod: Found matching PE image '%s'\n", pszFilename));
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * We found the executable image we need, now go find any
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * debug info associated with it. For PE images, this is
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * generally found in an external file, so we do a sweep
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * for that first.
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * Then try open debug inside the module, and finally
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * falling back on exports.
fa6dbd9c9e9645298cca864aa561382469907905vboxsync rc = rtDbgModOpenDebugInfoExternalToImage(pDbgMod, pDeferred->hDbgCfg);
fa6dbd9c9e9645298cca864aa561382469907905vboxsync RTStrCacheRelease(g_hDbgModStrCache, pszOldImgFile);
fa6dbd9c9e9645298cca864aa561382469907905vboxsync /* Something bad happened, just give up. */
fa6dbd9c9e9645298cca864aa561382469907905vboxsync Log(("rtDbgModFromPeImageOpenCallback: rtDbgModCreateForExports failed: %Rrc\n", rc));
fa6dbd9c9e9645298cca864aa561382469907905vboxsync LogFlow(("rtDbgModFromPeImageOpenCallback: uTimestamp mismatch (found %#x, expected %#x) - %s\n",
fa6dbd9c9e9645298cca864aa561382469907905vboxsync uTimestamp, pDeferred->u.PeImage.uTimestamp, pszFilename));
fa6dbd9c9e9645298cca864aa561382469907905vboxsync LogFlow(("rtDbgModFromPeImageOpenCallback: cbImage mismatch (found %#x, expected %#x) - %s\n",
fa6dbd9c9e9645298cca864aa561382469907905vboxsync LogFlow(("rtDbgModFromPeImageOpenCallback: Failed %Rrc - %s\n", rc, pszFilename));
fa6dbd9c9e9645298cca864aa561382469907905vboxsync /* Restore image name. */
fa6dbd9c9e9645298cca864aa561382469907905vboxsync RTStrCacheRelease(g_hDbgModStrCache, pszNewImgFile);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync/** @callback_method_impl{FNRTDBGMODDEFERRED} */
daa94352f51be2329ac8660f70396e03a7cb983bvboxsyncstatic DECLCALLBACK(int) rtDbgModFromPeImageDeferredCallback(PRTDBGMODINT pDbgMod, PRTDBGMODDEFERRED pDeferred)
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync rc = RTDbgCfgOpenPeImage(pDeferred->hDbgCfg, pDbgMod->pszImgFile,
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync pDeferred->cbImage, pDeferred->u.PeImage.uTimestamp,
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync rtDbgModFromPeImageOpenCallback, pDbgMod, pDeferred);
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync rc = rtDbgModOpenDebugInfoExternalToImage(pDbgMod, pDeferred->hDbgCfg);
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsyncRTDECL(int) RTDbgModCreateFromPeImage(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, RTLDRMOD hLdrMod,
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync uint32_t cbImage, uint32_t uTimestamp, RTDBGCFG hDbgCfg)
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync * Input validation and lazy initialization.
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync AssertReturn(*pszFilename, VERR_INVALID_PARAMETER);
fd66a4782980b7567eb181f809b629e74e4fd697vboxsync pszName = RTPathFilenameEx(pszFilename, RTPATH_STR_F_STYLE_DOS);
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync AssertReturn(hLdrMod == NIL_RTLDRMOD || RTLdrSize(hLdrMod) != ~(size_t)0, VERR_INVALID_HANDLE);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync rc = RTDbgCfgQueryUInt(hDbgCfg, RTDBGCFGPROP_FLAGS, &fDbgCfg);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync * Allocate a new module instance.
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync PRTDBGMODINT pDbgMod = (PRTDBGMODINT)RTMemAllocZ(sizeof(*pDbgMod));
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync pDbgMod->pszName = RTStrCacheEnterLower(g_hDbgModStrCache, pszName);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync pDbgMod->pszImgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename);
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync pDbgMod->pszImgFileSpecified = pDbgMod->pszImgFile;
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync * If we have a loader module, we must instantiate the loader
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync * side of things regardless of the deferred setting.
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync * Do it now or procrastinate?
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync if (!(fDbgCfg & RTDBGCFG_FLAGS_DEFERRED) || !cbImage)
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync rc = rtDbgModFromPeImageDeferredCallback(pDbgMod, &Deferred);
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync rc = rtDbgModDeferredCreate(pDbgMod, rtDbgModFromPeImageDeferredCallback, cbImage, hDbgCfg, 0,
830a019ad79a45e6bf7a5419efd5a729a36e599evboxsync /* Failed, bail out. */
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName);
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFileSpecified);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile);
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync * M a c h - O I M A G E
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync * M a c h - O I M A G E
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync * M a c h - O I M A G E
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync * Argument package used when opening Mach-O images and .dSYMs files.
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync /** For use more internal use in file locator callbacks. */
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync /** For use more internal use in file locator callbacks. */
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync /** For use more internal use in file locator callbacks. */
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync/** Pointer to a const segment package. */
e0d6f087507011df5f570f6800a2c332f8970e58vboxsynctypedef RTDBGMODMACHOARGS const *PCRTDBGMODMACHOARGS;
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync/** @callback_method_impl{FNRTDBGCFGOPEN} */
e0d6f087507011df5f570f6800a2c332f8970e58vboxsyncrtDbgModFromMachOImageOpenDsymMachOCallback(RTDBGCFG hDbgCfg, const char *pszFilename, void *pvUser1, void *pvUser2)
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync PCRTDBGMODMACHOARGS pArgs = (PCRTDBGMODMACHOARGS)pvUser2;
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync pDbgMod->pszImgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename);
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync * Try image interpreters as the dwarf file inside the dSYM bundle is a
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync * Mach-O file with dwarf debug sections insides it and no code or data.
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync int rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT);
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync rc = pImg->pVt->pfnTryOpen(pDbgMod, pArgs->enmArch);
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync * Check the UUID if one was given.
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync rc = pDbgMod->pImgVt->pfnQueryProp(pDbgMod, RTLDRPROP_UUID, &UuidOpened, sizeof(UuidOpened));
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync else if (rc == VERR_NOT_FOUND || rc == VERR_NOT_IMPLEMENTED)
5d9793f386d0e741d409c7991c6c4f4a5a08c068vboxsync * Pass it to the DWARF reader(s). Careful to restrict this or
5d9793f386d0e741d409c7991c6c4f4a5a08c068vboxsync * the dbghelp wrapper may end up being overly helpful.
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync for (PRTDBGMODREGDBG pDbg = g_pDbgHead; pDbg; pDbg = pDbg->pNext)
5d9793f386d0e741d409c7991c6c4f4a5a08c068vboxsync if (pDbg->pVt->fSupports & (RT_DBGTYPE_DWARF | RT_DBGTYPE_STABS | RT_DBGTYPE_WATCOM))
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync rc = pDbg->pVt->pfnTryOpen(pDbgMod, pDbgMod->pImgVt->pfnGetArch(pDbgMod));
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync RTStrCacheRelease(g_hDbgModStrCache, pszImgFileOrg);
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync * Likely fallback for when opening image.
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync RTStrCacheRelease(g_hDbgModStrCache, pszImgFileOrg);
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync /* No joy. */
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile);
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszDbgFile);
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsyncstatic int rtDbgModFromMachOImageWorker(PRTDBGMODINT pDbgMod, RTLDRARCH enmArch, uint32_t cbImage,
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync uint32_t cSegs, PCRTDBGSEGMENT paSegs, PCRTUUID pUuid, RTDBGCFG hDbgCfg)
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync Args.pUuid = pUuid && RTUuidIsNull(pUuid) ? pUuid : NULL;
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync * Search for the .dSYM bundle first, since that's generally all we need.
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync int rc = RTDbgCfgOpenDsymBundle(hDbgCfg, pDbgMod->pszImgFile, pUuid,
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync rtDbgModFromMachOImageOpenDsymMachOCallback, pDbgMod, &Args);
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync * If we cannot get at the .dSYM, try the executable image.
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync rc = RTDbgCfgOpenMachOImage(hDbgCfg, pDbgMod->pszImgFile, pUuid,
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync rtDbgModFromMachOImageOpenDsymMachOCallback, pDbgMod, &Args);
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync/** @callback_method_impl{FNRTDBGMODDEFERRED} */
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsyncstatic DECLCALLBACK(int) rtDbgModFromMachOImageDeferredCallback(PRTDBGMODINT pDbgMod, PRTDBGMODDEFERRED pDeferred)
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync return rtDbgModFromMachOImageWorker(pDbgMod, pDeferred->u.MachO.enmArch, pDeferred->cbImage,
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync pDeferred->u.MachO.cSegs, pDeferred->u.MachO.aSegs,
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsyncRTDECL(int) RTDbgModCreateFromMachOImage(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName,
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync RTLDRARCH enmArch, uint32_t cbImage, uint32_t cSegs, PCRTDBGSEGMENT paSegs,
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync * Input validation and lazy initialization.
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync AssertReturn(*pszFilename, VERR_INVALID_PARAMETER);
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync pszName = RTPathFilenameEx(pszFilename, RTPATH_STR_F_STYLE_HOST);
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync AssertReturn(cSegs < 1024, VERR_INVALID_PARAMETER);
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync AssertReturn(cbImage || cSegs, VERR_INVALID_PARAMETER);
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync AssertReturn(!(fFlags & ~(RTDBGMOD_F_NOT_DEFERRED)), VERR_INVALID_PARAMETER);
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync rc = RTDbgCfgQueryUInt(hDbgCfg, RTDBGCFGPROP_FLAGS, &fDbgCfg);
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync * Allocate a new module instance.
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync PRTDBGMODINT pDbgMod = (PRTDBGMODINT)RTMemAllocZ(sizeof(*pDbgMod));
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync pDbgMod->pszName = RTStrCacheEnterLower(g_hDbgModStrCache, pszName);
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync pDbgMod->pszImgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename);
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync pDbgMod->pszImgFileSpecified = pDbgMod->pszImgFile;
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync * Load it immediately?
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync rc = rtDbgModFromMachOImageWorker(pDbgMod, enmArch, cbImage, cSegs, paSegs, pUuid, hDbgCfg);
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync * Procrastinate. Need image size atm.
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync rc = rtDbgModDeferredCreate(pDbgMod, rtDbgModFromMachOImageDeferredCallback, cbImage, hDbgCfg,
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync RT_OFFSETOF(RTDBGMODDEFERRED, u.MachO.aSegs[cSegs]),
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync memcpy(&pDeferred->u.MachO.aSegs, paSegs, cSegs * sizeof(paSegs[0]));
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync /* Failed, bail out. */
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName);
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFileSpecified);
2a2b173b54c259e34320ce0acf26f18e9382ce2avboxsync RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile);
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync * Destroys an module after the reference count has reached zero.
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync * @param pDbgMod The module instance.
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync * Close the debug info interpreter first, then the image interpret.
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync RTCritSectEnter(&pDbgMod->CritSect); /* paranoia */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync * Free the resources.
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync ASMAtomicWriteU32(&pDbgMod->u32Magic, ~RTDBGMOD_MAGIC);
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName);
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile);
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFileSpecified);
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszDbgFile);
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync RTCritSectLeave(&pDbgMod->CritSect); /* paranoia */
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsyncRTDECL(const char *) RTDbgModDebugFile(RTDBGMOD hDbgMod)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsyncRTDECL(const char *) RTDbgModImageFile(RTDBGMOD hDbgMod)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsyncRTDECL(const char *) RTDbgModImageFileUsed(RTDBGMOD hDbgMod)
e9525bea57dc13d82fd3392913aebb33d2cb79e3vboxsync return pDbgMod->pszImgFile == pDbgMod->pszImgFileSpecified ? NULL : pDbgMod->pszImgFile;
31771163041e3661403a806eb3382d2a165c003bvboxsyncRTDECL(int) RTDbgModRemoveAll(RTDBGMOD hDbgMod, bool fLeaveSegments)
31771163041e3661403a806eb3382d2a165c003bvboxsync RTDBGMOD_VALID_RETURN_RC(pDbgMod, VERR_INVALID_HANDLE);
31771163041e3661403a806eb3382d2a165c003bvboxsync /* Only possible on container modules. */
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsyncRTDECL(RTDBGSEGIDX) RTDbgModRvaToSegOff(RTDBGMOD hDbgMod, RTUINTPTR uRva, PRTUINTPTR poffSeg)
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync RTDBGMOD_VALID_RETURN_RC(pDbgMod, NIL_RTDBGSEGIDX);
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync RTDBGSEGIDX iSeg = pDbgMod->pDbgVt->pfnRvaToSegOff(pDbgMod, uRva, poffSeg);
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsyncRTDECL(RTUINTPTR) RTDbgModImageSize(RTDBGMOD hDbgMod)
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync RTUINTPTR cbImage = pDbgMod->pDbgVt->pfnImageSize(pDbgMod);
bbb4c0bfd5ea55e99591d8811771257a437053eevboxsyncRTDECL(int) RTDbgModSetTag(RTDBGMOD hDbgMod, uint64_t uTag)
bbb4c0bfd5ea55e99591d8811771257a437053eevboxsync RTDBGMOD_VALID_RETURN_RC(pDbgMod, VERR_INVALID_HANDLE);
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsyncRTDECL(int) RTDbgModSegmentAdd(RTDBGMOD hDbgMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName,
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync * Validate input.
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync RTDBGMOD_VALID_RETURN_RC(pDbgMod, VERR_INVALID_HANDLE);
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync AssertMsgReturn(uRva + cb >= uRva, ("uRva=%RTptr cb=%RTptr\n", uRva, cb), VERR_DBG_ADDRESS_WRAP);
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync AssertReturn(cchName > 0, VERR_DBG_SEGMENT_NAME_OUT_OF_RANGE);
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync AssertReturn(cchName < RTDBG_SEGMENT_NAME_LENGTH, VERR_DBG_SEGMENT_NAME_OUT_OF_RANGE);
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync AssertMsgReturn(!fFlags, ("%#x\n", fFlags), VERR_INVALID_PARAMETER);
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync AssertMsgReturn(!piSeg || *piSeg == NIL_RTDBGSEGIDX || *piSeg <= RTDBGSEGIDX_LAST, ("%#x\n", *piSeg), VERR_DBG_SPECIAL_SEGMENT);
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync * Do the deed.
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync int rc = pDbgMod->pDbgVt->pfnSegmentAdd(pDbgMod, uRva, cb, pszName, cchName, fFlags, piSeg);
8b4a8db7768e94d025f1216ecfcd50d727fa2b7cvboxsyncRTDECL(RTDBGSEGIDX) RTDbgModSegmentCount(RTDBGMOD hDbgMod)
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync RTDBGMOD_VALID_RETURN_RC(pDbgMod, NIL_RTDBGSEGIDX);
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync RTDBGSEGIDX cSegs = pDbgMod->pDbgVt->pfnSegmentCount(pDbgMod);
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsyncRTDECL(int) RTDbgModSegmentByIndex(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, PRTDBGSEGMENT pSegInfo)
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync AssertMsgReturn(iSeg <= RTDBGSEGIDX_LAST, ("%#x\n", iSeg), VERR_DBG_SPECIAL_SEGMENT);
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync RTDBGMOD_VALID_RETURN_RC(pDbgMod, VERR_INVALID_HANDLE);
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync int rc = pDbgMod->pDbgVt->pfnSegmentByIndex(pDbgMod, iSeg, pSegInfo);
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsyncRTDECL(RTUINTPTR) RTDbgModSegmentSize(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg)
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync int rc = RTDbgModSegmentByIndex(hDbgMod, iSeg, &SegInfo);
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync return RT_SUCCESS(rc) ? SegInfo.cb : RTUINTPTR_MAX;
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsyncRTDECL(RTUINTPTR) RTDbgModSegmentRva(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg)
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync int rc = RTDbgModSegmentByIndex(hDbgMod, iSeg, &SegInfo);
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync return RT_SUCCESS(rc) ? SegInfo.uRva : RTUINTPTR_MAX;
a1df400bbe9d64aad400442e56eb637019300a5evboxsyncRTDECL(int) RTDbgModSymbolAdd(RTDBGMOD hDbgMod, const char *pszSymbol, RTDBGSEGIDX iSeg, RTUINTPTR off,
a1df400bbe9d64aad400442e56eb637019300a5evboxsync RTUINTPTR cb, uint32_t fFlags, uint32_t *piOrdinal)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Validate input.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTDBGMOD_VALID_RETURN_RC(pDbgMod, VERR_INVALID_HANDLE);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync AssertReturn(cchSymbol, VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync AssertReturn(cchSymbol < RTDBG_SYMBOL_NAME_LENGTH, VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE);
a1df400bbe9d64aad400442e56eb637019300a5evboxsync AssertMsgReturn(off + cb >= off, ("off=%RTptr cb=%RTptr\n", off, cb), VERR_DBG_ADDRESS_WRAP);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync AssertReturn(!fFlags, VERR_INVALID_PARAMETER); /* currently reserved. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Convert RVAs.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync iSeg = pDbgMod->pDbgVt->pfnRvaToSegOff(pDbgMod, off, &off);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Get down to business.
044af0d1e6474076366759db86f101778c5f20ccvboxsync int rc = pDbgMod->pDbgVt->pfnSymbolAdd(pDbgMod, pszSymbol, cchSymbol, iSeg, off, cb, fFlags, piOrdinal);
a1df400bbe9d64aad400442e56eb637019300a5evboxsyncRTDECL(uint32_t) RTDbgModSymbolCount(RTDBGMOD hDbgMod)
a1df400bbe9d64aad400442e56eb637019300a5evboxsync uint32_t cSymbols = pDbgMod->pDbgVt->pfnSymbolCount(pDbgMod);
a1df400bbe9d64aad400442e56eb637019300a5evboxsyncRTDECL(int) RTDbgModSymbolByOrdinal(RTDBGMOD hDbgMod, uint32_t iOrdinal, PRTDBGSYMBOL pSymInfo)
a1df400bbe9d64aad400442e56eb637019300a5evboxsync RTDBGMOD_VALID_RETURN_RC(pDbgMod, VERR_INVALID_HANDLE);
a1df400bbe9d64aad400442e56eb637019300a5evboxsync int rc = pDbgMod->pDbgVt->pfnSymbolByOrdinal(pDbgMod, iOrdinal, pSymInfo);
a1df400bbe9d64aad400442e56eb637019300a5evboxsyncRTDECL(int) RTDbgModSymbolByOrdinalA(RTDBGMOD hDbgMod, uint32_t iOrdinal, PRTDBGSYMBOL *ppSymInfo)
a1df400bbe9d64aad400442e56eb637019300a5evboxsync int rc = RTDbgModSymbolByOrdinal(hDbgMod, iOrdinal, pSymInfo);
2d8870843ff566fee9bd3a6a5942414254106479vboxsyncRTDECL(int) RTDbgModSymbolByAddr(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t fFlags,
a1df400bbe9d64aad400442e56eb637019300a5evboxsync * Validate input.
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync RTDBGMOD_VALID_RETURN_RC(pDbgMod, VERR_INVALID_HANDLE);
2d8870843ff566fee9bd3a6a5942414254106479vboxsync AssertReturn(!(fFlags & ~RTDBGSYMADDR_FLAGS_VALID_MASK), VERR_INVALID_PARAMETER);
a1df400bbe9d64aad400442e56eb637019300a5evboxsync * Convert RVAs.
a1df400bbe9d64aad400442e56eb637019300a5evboxsync iSeg = pDbgMod->pDbgVt->pfnRvaToSegOff(pDbgMod, off, &off);
a1df400bbe9d64aad400442e56eb637019300a5evboxsync * Get down to business.
2d8870843ff566fee9bd3a6a5942414254106479vboxsync int rc = pDbgMod->pDbgVt->pfnSymbolByAddr(pDbgMod, iSeg, off, fFlags, poffDisp, pSymInfo);
2d8870843ff566fee9bd3a6a5942414254106479vboxsyncRTDECL(int) RTDbgModSymbolByAddrA(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t fFlags,
2d8870843ff566fee9bd3a6a5942414254106479vboxsync int rc = RTDbgModSymbolByAddr(hDbgMod, iSeg, off, fFlags, poffDisp, pSymInfo);
a1df400bbe9d64aad400442e56eb637019300a5evboxsyncRTDECL(int) RTDbgModSymbolByName(RTDBGMOD hDbgMod, const char *pszSymbol, PRTDBGSYMBOL pSymInfo)
a1df400bbe9d64aad400442e56eb637019300a5evboxsync * Validate input.
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync RTDBGMOD_VALID_RETURN_RC(pDbgMod, VERR_INVALID_HANDLE);
a1df400bbe9d64aad400442e56eb637019300a5evboxsync AssertReturn(cchSymbol, VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE);
a1df400bbe9d64aad400442e56eb637019300a5evboxsync AssertReturn(cchSymbol < RTDBG_SYMBOL_NAME_LENGTH, VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE);
a1df400bbe9d64aad400442e56eb637019300a5evboxsync * Make the query.
a1df400bbe9d64aad400442e56eb637019300a5evboxsync int rc = pDbgMod->pDbgVt->pfnSymbolByName(pDbgMod, pszSymbol, cchSymbol, pSymInfo);
a1df400bbe9d64aad400442e56eb637019300a5evboxsyncRTDECL(int) RTDbgModSymbolByNameA(RTDBGMOD hDbgMod, const char *pszSymbol, PRTDBGSYMBOL *ppSymInfo)
a1df400bbe9d64aad400442e56eb637019300a5evboxsync int rc = RTDbgModSymbolByName(hDbgMod, pszSymbol, pSymInfo);
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsyncRTDECL(int) RTDbgModLineAdd(RTDBGMOD hDbgMod, const char *pszFile, uint32_t uLineNo,
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t *piOrdinal)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Validate input.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync RTDBGMOD_VALID_RETURN_RC(pDbgMod, VERR_INVALID_HANDLE);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync AssertReturn(cchFile, VERR_DBG_FILE_NAME_OUT_OF_RANGE);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync AssertReturn(cchFile < RTDBG_FILE_NAME_LENGTH, VERR_DBG_FILE_NAME_OUT_OF_RANGE);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync AssertReturn(uLineNo > 0 && uLineNo < UINT32_MAX, VERR_INVALID_PARAMETER);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Convert RVAs.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync iSeg = pDbgMod->pDbgVt->pfnRvaToSegOff(pDbgMod, off, &off);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Get down to business.
044af0d1e6474076366759db86f101778c5f20ccvboxsync int rc = pDbgMod->pDbgVt->pfnLineAdd(pDbgMod, pszFile, cchFile, uLineNo, iSeg, off, piOrdinal);
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsyncRTDECL(uint32_t) RTDbgModLineCount(RTDBGMOD hDbgMod)
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync uint32_t cLineNumbers = pDbgMod->pDbgVt->pfnLineCount(pDbgMod);
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsyncRTDECL(int) RTDbgModLineByOrdinal(RTDBGMOD hDbgMod, uint32_t iOrdinal, PRTDBGLINE pLineInfo)
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync RTDBGMOD_VALID_RETURN_RC(pDbgMod, VERR_INVALID_HANDLE);
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync int rc = pDbgMod->pDbgVt->pfnLineByOrdinal(pDbgMod, iOrdinal, pLineInfo);
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsyncRTDECL(int) RTDbgModLineByOrdinalA(RTDBGMOD hDbgMod, uint32_t iOrdinal, PRTDBGLINE *ppLineInfo)
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync int rc = RTDbgModLineByOrdinal(hDbgMod, iOrdinal, pLineInfo);
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsyncRTDECL(int) RTDbgModLineByAddr(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR off, PRTINTPTR poffDisp, PRTDBGLINE pLineInfo)
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync * Validate input.
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync RTDBGMOD_VALID_RETURN_RC(pDbgMod, VERR_INVALID_HANDLE);
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync * Convert RVAs.
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync iSeg = pDbgMod->pDbgVt->pfnRvaToSegOff(pDbgMod, off, &off);
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync int rc = pDbgMod->pDbgVt->pfnLineByAddr(pDbgMod, iSeg, off, poffDisp, pLineInfo);
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsyncRTDECL(int) RTDbgModLineByAddrA(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR off, PRTINTPTR poffDisp, PRTDBGLINE *ppLineInfo)