summaryrefslogtreecommitdiff
path: root/src/VBox/Runtime/common/ldr/ldrkStuff.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Runtime/common/ldr/ldrkStuff.cpp')
-rw-r--r--src/VBox/Runtime/common/ldr/ldrkStuff.cpp151
1 files changed, 131 insertions, 20 deletions
diff --git a/src/VBox/Runtime/common/ldr/ldrkStuff.cpp b/src/VBox/Runtime/common/ldr/ldrkStuff.cpp
index 61b36663..da53c29f 100644
--- a/src/VBox/Runtime/common/ldr/ldrkStuff.cpp
+++ b/src/VBox/Runtime/common/ldr/ldrkStuff.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -240,9 +240,10 @@ static int rtkldrRdr_Create( PPKRDR ppRdr, const char *pszFilename)
/** @copydoc KLDRRDROPS::pfnDestroy */
static int rtkldrRdr_Destroy( PKRDR pRdr)
{
- PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader;
- int rc = pReader->pfnDestroy(pReader);
- return rtkldrConvertErrorFromIPRT(rc);
+ PRTKLDRRDR pThis = (PRTKLDRRDR)pRdr;
+ pThis->pReader = NULL;
+ RTMemFree(pThis);
+ return 0;
}
@@ -598,23 +599,49 @@ static int rtkldrEnumDbgInfoWrapper(PKLDRMOD pMod, KU32 iDbgInfo, KLDRDBGINFOTYP
PRTLDRMODKLDRARGS pArgs = (PRTLDRMODKLDRARGS)pvUser;
NOREF(pMod);
- RTLDRDBGINFOTYPE enmMyType;
+ RTLDRDBGINFO DbgInfo;
+ RT_ZERO(DbgInfo.u);
+ DbgInfo.iDbgInfo = iDbgInfo;
+ DbgInfo.offFile = offFile;
+ DbgInfo.LinkAddress = LinkAddress;
+ DbgInfo.cb = cb;
+ DbgInfo.pszExtFile = pszExtFile;
+
switch (enmType)
{
- case KLDRDBGINFOTYPE_UNKNOWN: enmMyType = RTLDRDBGINFOTYPE_UNKNOWN; break;
- case KLDRDBGINFOTYPE_STABS: enmMyType = RTLDRDBGINFOTYPE_STABS; break;
- case KLDRDBGINFOTYPE_DWARF: enmMyType = RTLDRDBGINFOTYPE_DWARF; break;
- case KLDRDBGINFOTYPE_CODEVIEW: enmMyType = RTLDRDBGINFOTYPE_CODEVIEW; break;
- case KLDRDBGINFOTYPE_WATCOM: enmMyType = RTLDRDBGINFOTYPE_WATCOM; break;
- case KLDRDBGINFOTYPE_HLL: enmMyType = RTLDRDBGINFOTYPE_HLL; break;
+ case KLDRDBGINFOTYPE_UNKNOWN:
+ DbgInfo.enmType = RTLDRDBGINFOTYPE_UNKNOWN;
+ break;
+ case KLDRDBGINFOTYPE_STABS:
+ DbgInfo.enmType = RTLDRDBGINFOTYPE_STABS;
+ break;
+ case KLDRDBGINFOTYPE_DWARF:
+ DbgInfo.enmType = RTLDRDBGINFOTYPE_DWARF;
+ if (!pszExtFile)
+ DbgInfo.u.Dwarf.pszSection = pszPartNm;
+ else
+ {
+ DbgInfo.enmType = RTLDRDBGINFOTYPE_DWARF_DWO;
+ DbgInfo.u.Dwo.uCrc32 = 0;
+ }
+ break;
+ case KLDRDBGINFOTYPE_CODEVIEW:
+ DbgInfo.enmType = RTLDRDBGINFOTYPE_CODEVIEW;
+ /* Should make some more effort here... Assume the IPRT loader will kick in before we get here! */
+ break;
+ case KLDRDBGINFOTYPE_WATCOM:
+ DbgInfo.enmType = RTLDRDBGINFOTYPE_WATCOM;
+ break;
+ case KLDRDBGINFOTYPE_HLL:
+ DbgInfo.enmType = RTLDRDBGINFOTYPE_HLL;
+ break;
default:
AssertFailed();
- enmMyType = RTLDRDBGINFOTYPE_UNKNOWN;
+ DbgInfo.enmType = RTLDRDBGINFOTYPE_UNKNOWN;
break;
}
- int rc = pArgs->u.pfnEnumDbgInfo(&pArgs->pMod->Core, iDbgInfo, enmMyType, iMajorVer, iMinorVer, pszPartNm,
- offFile, LinkAddress, cb, pszExtFile, pArgs->pvUser);
+ int rc = pArgs->u.pfnEnumDbgInfo(&pArgs->pMod->Core, &DbgInfo, pArgs->pvUser);
if (RT_FAILURE(rc))
return rc; /* don't bother converting. */
return 0;
@@ -645,13 +672,29 @@ static DECLCALLBACK(int) rtkldr_EnumSegments(PRTLDRMODINTERNAL pMod, PFNRTLDRENU
PRTLDRMODKLDR pThis = (PRTLDRMODKLDR)pMod;
uint32_t const cSegments = pThis->pMod->cSegments;
PCKLDRSEG paSegments = &pThis->pMod->aSegments[0];
+ char szName[128];
for (uint32_t iSeg = 0; iSeg < cSegments; iSeg++)
{
RTLDRSEG Seg;
- Seg.pchName = paSegments[iSeg].pchName;
- Seg.cchName = paSegments[iSeg].cchName;
+ if (!paSegments[iSeg].cchName)
+ {
+ Seg.pszName = szName;
+ Seg.cchName = (uint32_t)RTStrPrintf(szName, sizeof(szName), "Seg%02u", iSeg);
+ }
+ else if (paSegments[iSeg].pchName[paSegments[iSeg].cchName])
+ {
+ AssertReturn(paSegments[iSeg].cchName < sizeof(szName), VERR_INTERNAL_ERROR_3);
+ RTStrCopyEx(szName, sizeof(szName), paSegments[iSeg].pchName, paSegments[iSeg].cchName);
+ Seg.pszName = szName;
+ Seg.cchName = paSegments[iSeg].cchName;
+ }
+ else
+ {
+ Seg.pszName = paSegments[iSeg].pchName;
+ Seg.cchName = paSegments[iSeg].cchName;
+ }
Seg.SelFlat = paSegments[iSeg].SelFlat;
Seg.Sel16bit = paSegments[iSeg].Sel16bit;
Seg.fFlags = paSegments[iSeg].fFlags;
@@ -784,6 +827,15 @@ static DECLCALLBACK(int) rtkldr_RvaToSegOffset(PRTLDRMODINTERNAL pMod, RTLDRADDR
}
+/** @copydoc RTLDROPS::pfnReadDbgInfo. */
+static DECLCALLBACK(int) rtkldr_ReadDbgInfo(PRTLDRMODINTERNAL pMod, uint32_t iDbgInfo, RTFOFF off, size_t cb, void *pvBuf)
+{
+ PRTLDRMODKLDR pThis = (PRTLDRMODKLDR)pMod;
+ /** @todo May have to apply fixups here. */
+ return pThis->Core.pReader->pfnRead(pThis->Core.pReader, pvBuf, cb, off);
+}
+
+
/**
* Operations for a kLdr module.
*/
@@ -805,6 +857,7 @@ static const RTLDROPS g_rtkldrOps =
rtkldr_LinkAddressToRva,
rtkldr_SegOffsetToRva,
rtkldr_RvaToSegOffset,
+ rtkldr_ReadDbgInfo,
42
};
@@ -836,6 +889,9 @@ int rtldrkLdrOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, PRTL
default:
return VERR_INVALID_PARAMETER;
}
+ KU32 fKFlags = 0;
+ if (fFlags & RTLDR_O_FOR_DEBUG)
+ fKFlags |= KLDRMOD_OPEN_FLAGS_FOR_INFO;
/* Create a rtkldrRdr_ instance. */
PRTKLDRRDR pRdr = (PRTKLDRRDR)RTMemAllocZ(sizeof(*pRdr));
@@ -847,7 +903,7 @@ int rtldrkLdrOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, PRTL
/* Try open it. */
PKLDRMOD pMod;
- int krc = kLdrModOpenFromRdr(&pRdr->Core, fFlags, enmCpuArch, &pMod);
+ int krc = kLdrModOpenFromRdr(&pRdr->Core, fKFlags, enmCpuArch, &pMod);
if (!krc)
{
/* Create a module wrapper for it. */
@@ -855,9 +911,59 @@ int rtldrkLdrOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, PRTL
if (pNewMod)
{
pNewMod->Core.u32Magic = RTLDRMOD_MAGIC;
- pNewMod->Core.eState = LDR_STATE_OPENED;
- pNewMod->Core.pOps = &g_rtkldrOps;
- pNewMod->pMod = pMod;
+ pNewMod->Core.eState = LDR_STATE_OPENED;
+ pNewMod->Core.pOps = &g_rtkldrOps;
+ pNewMod->Core.pReader = pReader;
+ switch (pMod->enmFmt)
+ {
+ case KLDRFMT_NATIVE: pNewMod->Core.enmFormat = RTLDRFMT_NATIVE; break;
+ case KLDRFMT_AOUT: pNewMod->Core.enmFormat = RTLDRFMT_AOUT; break;
+ case KLDRFMT_ELF: pNewMod->Core.enmFormat = RTLDRFMT_ELF; break;
+ case KLDRFMT_LX: pNewMod->Core.enmFormat = RTLDRFMT_LX; break;
+ case KLDRFMT_MACHO: pNewMod->Core.enmFormat = RTLDRFMT_MACHO; break;
+ case KLDRFMT_PE: pNewMod->Core.enmFormat = RTLDRFMT_PE; break;
+ default:
+ AssertMsgFailed(("%d\n", pMod->enmFmt));
+ pNewMod->Core.enmFormat = RTLDRFMT_NATIVE;
+ break;
+ }
+ switch (pMod->enmType)
+ {
+ case KLDRTYPE_OBJECT: pNewMod->Core.enmType = RTLDRTYPE_OBJECT; break;
+ case KLDRTYPE_EXECUTABLE_FIXED: pNewMod->Core.enmType = RTLDRTYPE_EXECUTABLE_FIXED; break;
+ case KLDRTYPE_EXECUTABLE_RELOCATABLE: pNewMod->Core.enmType = RTLDRTYPE_EXECUTABLE_RELOCATABLE; break;
+ case KLDRTYPE_EXECUTABLE_PIC: pNewMod->Core.enmType = RTLDRTYPE_EXECUTABLE_PIC; break;
+ case KLDRTYPE_SHARED_LIBRARY_FIXED: pNewMod->Core.enmType = RTLDRTYPE_SHARED_LIBRARY_FIXED; break;
+ case KLDRTYPE_SHARED_LIBRARY_RELOCATABLE: pNewMod->Core.enmType = RTLDRTYPE_SHARED_LIBRARY_RELOCATABLE; break;
+ case KLDRTYPE_SHARED_LIBRARY_PIC: pNewMod->Core.enmType = RTLDRTYPE_SHARED_LIBRARY_PIC; break;
+ case KLDRTYPE_FORWARDER_DLL: pNewMod->Core.enmType = RTLDRTYPE_FORWARDER_DLL; break;
+ case KLDRTYPE_CORE: pNewMod->Core.enmType = RTLDRTYPE_CORE; break;
+ case KLDRTYPE_DEBUG_INFO: pNewMod->Core.enmType = RTLDRTYPE_DEBUG_INFO; break;
+ default:
+ AssertMsgFailed(("%d\n", pMod->enmType));
+ pNewMod->Core.enmType = RTLDRTYPE_OBJECT;
+ break;
+ }
+ switch (pMod->enmEndian)
+ {
+ case KLDRENDIAN_LITTLE: pNewMod->Core.enmEndian = RTLDRENDIAN_LITTLE; break;
+ case KLDRENDIAN_BIG: pNewMod->Core.enmEndian = RTLDRENDIAN_BIG; break;
+ case KLDRENDIAN_NA: pNewMod->Core.enmEndian = RTLDRENDIAN_NA; break;
+ default:
+ AssertMsgFailed(("%d\n", pMod->enmEndian));
+ pNewMod->Core.enmEndian = RTLDRENDIAN_NA;
+ break;
+ }
+ switch (pMod->enmArch)
+ {
+ case KCPUARCH_X86_32: pNewMod->Core.enmArch = RTLDRARCH_X86_32; break;
+ case KCPUARCH_AMD64: pNewMod->Core.enmArch = RTLDRARCH_AMD64; break;
+ default:
+ AssertMsgFailed(("%d\n", pMod->enmArch));
+ pNewMod->Core.enmArch = RTLDRARCH_WHATEVER;
+ break;
+ }
+ pNewMod->pMod = pMod;
*phLdrMod = &pNewMod->Core;
#ifdef LOG_ENABLED
@@ -874,9 +980,14 @@ int rtldrkLdrOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, PRTL
#endif
return VINF_SUCCESS;
}
+
+ /* bail out */
kLdrModClose(pMod);
krc = KERR_NO_MEMORY;
}
+ else
+ RTMemFree(pRdr);
+
return rtkldrConvertError(krc);
}