/** * Links the segments of the module into the address space. * * @returns VBox status code on failure. * * @param hAs The address space. * @param hMod The module. * @param paSegs Array of segment indexes and load addresses. * @param cSegs The number of segments in the array. */ static int dbgDiggerCommonLinkElfSegs(RTDBGAS hAs, RTDBGMOD hMod, PDBGDIGGERELFSEG paSegs, uint32_t cSegs) { for (uint32_t i = 0; i < cSegs; i++) if (paSegs[i].iSeg != NIL_RTDBGSEGIDX) { int rc = RTDbgAsModuleLinkSeg(hAs, hMod, paSegs[i].iSeg, paSegs[i].uLoadAddr, RTDBGASLINK_FLAGS_REPLACE); if (RT_FAILURE(rc)) { RTDbgAsModuleUnlink(hAs, hMod); return rc; } } return VINF_SUCCESS; }
/** * 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; }
/** * Relocates the RC address space. * * @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); } }