dbgmoddwarf.cpp revision d3dea25ec07f6546715fe3af943ea863294b392e
/* $Id$ */
/** @file
* IPRT - Debug Info Reader For DWARF.
*/
/*
* Copyright (C) 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;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
/*******************************************************************************
* Structures and Typedefs *
*******************************************************************************/
/**
* DWARF sections.
*/
typedef enum krtDbgModDwarfSect
{
/** End of valid parts (exclusive). */
/**
* The instance data of the DWARF reader.
*/
typedef struct RTDBGMODDWARF
{
/** The debug container containing doing the real work. */
/** Pointer to back to the debug info module (no reference ofc). */
/** DWARF debug info sections. */
struct
{
/** The file offset of the part. */
/** The size of the part. */
/** The memory mapping of the part. */
void const *pv;
/** Set if present. */
bool fPresent;
/** Pointer to instance data of the DWARF reader. */
typedef RTDBGMODDWARF *PRTDBGMODDWARF;
/**
* Loads a DWARF section from the image file.
*
* @returns IPRT status code.
* @param pThis The DWARF instance.
* @param enmSect The section to load.
*/
{
/*
* Don't load stuff twice.
*/
return VINF_SUCCESS;
/*
* Sections that are not present cannot be loaded, treat them like they
* are empty
*/
{
return VINF_SUCCESS;
}
return VINF_SUCCESS;
/*
* Sections must be readable with the current image interface.
*/
return VERR_OUT_OF_RANGE;
/*
* Do the job.
*/
return pThis->pMod->pImgVt->pfnMapPart(pThis->pMod, pThis->aSections[enmSect].offFile, pThis->aSections[enmSect].cb,
}
/**
* Unloads a DWARF section previously mapped by rtDbgModDwarfLoadSection.
*
* @returns IPRT status code.
* @param pThis The DWARF instance.
* @param enmSect The section to unload.
*/
{
return VINF_SUCCESS;
int rc = pThis->pMod->pImgVt->pfnUnmapPart(pThis->pMod, pThis->aSections[enmSect].cb, &pThis->aSections[enmSect].pv);
return rc;
}
/** @interface_method_impl{RTDBGMODVTDBG,pfnLineByAddr} */
static DECLCALLBACK(int) rtDbgModDwarf_LineByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off,
{
}
/** @interface_method_impl{RTDBGMODVTDBG,pfnLineByOrdinal} */
static DECLCALLBACK(int) rtDbgModDwarf_LineByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGLINE pLineInfo)
{
}
/** @interface_method_impl{RTDBGMODVTDBG,pfnLineCount} */
{
}
/** @interface_method_impl{RTDBGMODVTDBG,pfnLineAdd} */
static DECLCALLBACK(int) rtDbgModDwarf_LineAdd(PRTDBGMODINT pMod, const char *pszFile, size_t cchFile, uint32_t uLineNo,
{
}
/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByAddr} */
static DECLCALLBACK(int) rtDbgModDwarf_SymbolByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off,
{
}
/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByName} */
static DECLCALLBACK(int) rtDbgModDwarf_SymbolByName(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
{
}
/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByOrdinal} */
static DECLCALLBACK(int) rtDbgModDwarf_SymbolByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGSYMBOL pSymInfo)
{
}
/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolCount} */
{
}
/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolAdd} */
static DECLCALLBACK(int) rtDbgModDwarf_SymbolAdd(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
{
}
/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentByIndex} */
static DECLCALLBACK(int) rtDbgModDwarf_SegmentByIndex(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, PRTDBGSEGMENT pSegInfo)
{
}
/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentCount} */
{
}
/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentAdd} */
static DECLCALLBACK(int) rtDbgModDwarf_SegmentAdd(PRTDBGMODINT pMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName, size_t cchName,
{
}
/** @interface_method_impl{RTDBGMODVTDBG,pfnImageSize} */
{
}
/** @interface_method_impl{RTDBGMODVTDBG,pfnRvaToSegOff} */
static DECLCALLBACK(RTDBGSEGIDX) rtDbgModDwarf_RvaToSegOff(PRTDBGMODINT pMod, RTUINTPTR uRva, PRTUINTPTR poffSeg)
{
}
/** @interface_method_impl{RTDBGMODVTDBG,pfnClose} */
{
pThis->pMod->pImgVt->pfnUnmapPart(pThis->pMod, pThis->aSections[iSect].cb, &pThis->aSections[iSect].pv);
return VINF_SUCCESS;
}
/**
* Explodes the line number table.
*
* The line numbers are insered into the debug info container.
*
* @returns IPRT status code
* @param pThis The DWARF instance.
*/
{
if (RT_FAILURE(rc))
return rc;
#if 0 /** @todo */
while (cbLeft > 0)
{
}
#endif
return rc;
}
/**
* Extracts the symbols.
*
* The symbols are insered into the debug info container.
*
* @returns IPRT status code
* @param pThis The DWARF instance.
*/
{
if (RT_FAILURE(rc))
return rc;
/** @todo */
return rc;
}
/**
* Loads the abbreviations used to parse the info section.
*
* @returns IPRT status code
* @param pThis The DWARF instance.
*/
{
if (RT_FAILURE(rc))
return rc;
#if 0 /** @todo */
while (cbLeft > 0)
{
}
#endif
return rc;
}
/** @callback_method_impl{FNRTLDRENUMSEGS} */
static DECLCALLBACK(int) rtDbgModHlpAddSegmentCallback(RTLDRMOD hLdrMod, PCRTLDRSEG pSeg, void *pvUser)
{
return pMod->pDbgVt->pfnSegmentAdd(pMod, pSeg->RVA, pSeg->cb, pSeg->pchName, pSeg->cchName, 0 /*fFlags*/, NULL);
}
/**
* Calls pfnSegmentAdd for each segment in the executable image.
*
* @returns IPRT status code.
* @param pMod The debug module.
*/
{
}
/** @callback_method_impl{FNRTLDRENUMDBG} */
static DECLCALLBACK(int) rtDbgModDwarfEnumCallback(RTLDRMOD hLdrMod, uint32_t iDbgInfo, RTLDRDBGINFOTYPE enmType,
const char *pszExtFile, void *pvUser)
{
/*
* Skip stuff we can't handle.
*/
if ( enmType != RTLDRDBGINFOTYPE_DWARF
|| !pszPartNm
|| pszExtFile)
return VINF_SUCCESS;
/*
* Must have a part name starting with debug_ and possibly prefixed by dots
* or underscores.
*/
else
/*
* Figure out which part we're talking about.
*/
if (0) { /* dummy */ }
#define ELSE_IF_STRCMP_SET(a_Name) else if (!strcmp(pszPartNm, #a_Name)) enmSect = krtDbgModDwarfSect_ ## a_Name
else
{
return VINF_SUCCESS;
}
/*
* Record the section.
*/
AssertMsgReturn(!pThis->aSections[enmSect].fPresent, ("duplicate %s\n", pszPartNm), VINF_SUCCESS /*ignore*/);
return VINF_SUCCESS;
}
/** @interface_method_impl{RTDBGMODVTDBG,pfnTryOpen} */
{
/*
* DWARF is only supported when part of an image.
*/
return VERR_DBG_NO_MATCHING_INTERPRETER;
/*
* Enumerate the debug info in the module, looking for DWARF bits.
*/
if (!pThis)
return VERR_NO_MEMORY;
if (RT_SUCCESS(rc))
{
{
/*
* Extract / explode the data we want (symbols and line numbers)
* storing them in a container module.
*/
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
if (RT_SUCCESS(rc))
if (RT_SUCCESS(rc))
if (RT_SUCCESS(rc))
{
return VINF_SUCCESS;
}
/* bail out. */
}
}
else
}
return rc;
}
/** Virtual function table for the DWARF debug info reader. */
{
/*.u32Magic = */ RTDBGMODVTDBG_MAGIC,
/*.fSupports = */ RT_DBGTYPE_DWARF,
/*.pszName = */ "dwarf",
/*.pfnTryOpen = */ rtDbgModDwarf_TryOpen,
/*.pfnClose = */ rtDbgModDwarf_Close,
/*.pfnRvaToSegOff = */ rtDbgModDwarf_RvaToSegOff,
/*.pfnImageSize = */ rtDbgModDwarf_ImageSize,
/*.pfnSegmentAdd = */ rtDbgModDwarf_SegmentAdd,
/*.pfnSegmentCount = */ rtDbgModDwarf_SegmentCount,
/*.pfnSegmentByIndex = */ rtDbgModDwarf_SegmentByIndex,
/*.pfnSymbolAdd = */ rtDbgModDwarf_SymbolAdd,
/*.pfnSymbolCount = */ rtDbgModDwarf_SymbolCount,
/*.pfnSymbolByOrdinal = */ rtDbgModDwarf_SymbolByOrdinal,
/*.pfnSymbolByName = */ rtDbgModDwarf_SymbolByName,
/*.pfnSymbolByAddr = */ rtDbgModDwarf_SymbolByAddr,
/*.pfnLineAdd = */ rtDbgModDwarf_LineAdd,
/*.pfnLineCount = */ rtDbgModDwarf_LineCount,
/*.pfnLineByOrdinal = */ rtDbgModDwarf_LineByOrdinal,
/*.pfnLineByAddr = */ rtDbgModDwarf_LineByAddr,
/*.u32EndMagic = */ RTDBGMODVTDBG_MAGIC
};