VirtualBox

Changeset 38617 in vbox


Ignore:
Timestamp:
Sep 2, 2011 8:22:26 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
73824
Message:

More DWARF parsing.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/dbg/dbgmoddwarf.cpp

    r38606 r38617  
    3636#include <iprt/ctype.h>
    3737#include <iprt/err.h>
     38#include <iprt/list.h>
    3839#include <iprt/log.h>
    3940#include <iprt/mem.h>
     
    268269/** @} */
    269270
     271/** @name Address classes.
     272 * @{ */
     273#define DW_ADDR_none            UINT8_C(0)
     274#define DW_ADDR_i386_near16     UINT8_C(1)
     275#define DW_ADDR_i386_far16      UINT8_C(2)
     276#define DW_ADDR_i386_huge16     UINT8_C(3)
     277#define DW_ADDR_i386_near32     UINT8_C(4)
     278#define DW_ADDR_i386_far32      UINT8_C(5)
     279/** @}  */
     280
    270281
    271282/*******************************************************************************
    272283*   Structures and Typedefs                                                    *
    273284*******************************************************************************/
     285/** Pointer to a DWARF section reader. */
     286typedef struct RTDWARFCURSOR *PRTDWARFCURSOR;
     287/** Pointer to an attribute descriptor. */
     288typedef struct RTDWARFATTRDESC const *PCRTDWARFATTRDESC;
     289/** Pointer to a DIE. */
     290typedef struct RTDWARFDIE *PRTDWARFDIE;
     291/** Pointer to a const DIE. */
     292typedef struct RTDWARFDIE const *PCRTDWARFDIE;
     293
    274294/**
    275295 * DWARF sections.
     
    344364    uint32_t                cCachedAbbrevs;
    345365    /** Array of cached abbreviations, indexed by code. */
    346     PRTDWARFABBREV           paCachedAbbrevs;
     366    PRTDWARFABBREV          paCachedAbbrevs;
    347367    /** Used by rtDwarfAbbrev_Lookup when the result is uncachable. */
    348     RTDWARFABBREV            LookupAbbrev;
     368    RTDWARFABBREV           LookupAbbrev;
     369
     370    /** The list of compilation units (RTDWARFDIE).   */
     371    RTLISTNODE              CompileUnitList;
    349372} RTDBGMODDWARF;
    350373/** Pointer to instance data of the DWARF reader. */
     
    354377 * DWARF cursor for reading byte data.
    355378 */
    356 typedef struct RTDWARFSECTRDR
     379typedef struct RTDWARFCURSOR
    357380{
    358381    /** The current position. */
     
    380403    krtDbgModDwarfSect      enmSect;
    381404} RTDWARFCURSOR;
    382 /** Pointer to a DWARF section reader. */
    383 typedef RTDWARFCURSOR *PRTDWARFCURSOR;
    384405
    385406
     
    438459/** Pointer to a DWARF line number program state. */
    439460typedef RTDWARFLINESTATE *PRTDWARFLINESTATE;
     461
     462
     463/**
     464 * Decodes an attribute and stores it in the specified DIE member field.
     465 *
     466 * @returns IPRT status code.
     467 * @param   pDie            Pointer to the DIE structure.
     468 * @param   pbMember        Pointer to the first byte in the member.
     469 * @param   pDesc           The attribute descriptor.
     470 * @param   uForm           The data form.
     471 * @param   pDataCursor     The cursor to read data from.
     472 */
     473typedef DECLCALLBACK(int) FNRTDWARFATTRDECODER(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc,
     474                                               uint32_t uForm, PRTDWARFCURSOR pCursor);
     475/** Pointer to an attribute decoder callback. */
     476typedef FNRTDWARFATTRDECODER *PFNRTDWARFATTRDECODER;
     477
     478/**
     479 * Attribute descriptor.
     480 */
     481typedef struct RTDWARFATTRDESC
     482{
     483    /** The attribute. */
     484    uint8_t                 uAttr;
     485    /** The data member size and initialization method. */
     486    uint8_t                 cbInit;
     487    /** The data member offset. */
     488    uint16_t                off;
     489    /** The decoder function. */
     490    PFNRTDWARFATTRDECODER   pfnDecoder;
     491} RTDWARFATTRDESC;
     492
     493/** Define a attribute entry. */
     494#define ATTR_ENTRY(a_uAttr, a_Struct, a_Member, a_Init, a_pfnDecoder) \
     495    { \
     496        a_uAttr, \
     497        a_Init | ((uint8_t)RT_SIZEOFMEMB(a_Struct, a_Member) & ATTR_SIZE_MASK), \
     498        (uint16_t)RT_OFFSETOF(a_Struct, a_Member), \
     499        a_pfnDecoder\
     500    }
     501
     502/** @name Attribute size and init methods.
     503 * @{ */
     504#define ATTR_INIT_ZERO      UINT8_C(0x00)
     505#define ATTR_INIT_FFFS      UINT8_C(0x40)
     506#define ATTR_INIT_ADDRINFO  UINT8_C(0x80)
     507#define ATTR_INIT_RESERVED  UINT8_C(0xc0)
     508#define ATTR_INIT_MASK      UINT8_C(0xc0)
     509#define ATTR_SIZE_MASK      UINT8_C(0x3f)
     510#define ATTR_GET_SIZE(a_pAttrDesc)   ((a_pAttrDesc)->cbInit & ATTR_SIZE_MASK)
     511/** @} */
     512
     513
     514/**
     515 * DIE descriptor.
     516 */
     517typedef struct RTDWARFDIEDESC
     518{
     519    /** The number of attributes. */
     520    size_t              cAttributes;
     521    /** The  */
     522    PCRTDWARFATTRDESC   paAttributes;
     523} RTDWARFDIEDESC;
     524typedef struct RTDWARFDIEDESC const *PCRTDWARFDIEDESC;
     525
     526
     527/**
     528 * DIE core structure, all inherits (starts with) this.
     529 */
     530typedef struct RTDWARFDIE
     531{
     532    /** Pointer to the parent node. NULL if root unit. */
     533    struct RTDWARFDIE  *pParent;
     534    /** Our node in the sibling list. */
     535    RTLISTNODE          SiblingNode;
     536    /** List of children. */
     537    RTLISTNODE          ChildList;
     538    /** The number of attributes successfully decoded. */
     539    uint8_t             cDecodedAttrs;
     540    /** The number of unknown or otherwise unhandled attributes. */
     541    uint8_t             cUnhandledAttrs;
     542    /** The date tag, indicating which union structure to use. */
     543    uint16_t            uTag;
     544    /** Offset of the abbreviation specification (within debug_abbrev). */
     545    uint32_t            offSpec;
     546} RTDWARFDIE;
     547
     548
     549/**
     550 * DWARF address structure.
     551 */
     552typedef struct RTDWARFADDR
     553{
     554    /** The address. */
     555    uint64_t            uAddress;
     556} RTDWARFADDR;
     557
     558
     559/**
     560 * DWARF address range.
     561 */
     562typedef struct RTDWARFADDRRANGE
     563{
     564    uint64_t            uLowAddress;
     565    uint64_t            uHighAddress;
     566    uint8_t const      *pbRanges; /* ?? */
     567    bool                fHaveLowAddress  : 1;
     568    bool                fHaveHighAddress : 1;
     569    bool                fHaveRanges      : 1;
     570} RTDWARFADDRRANGE;
     571typedef RTDWARFADDRRANGE *PRTDWARFADDRRANGE;
     572typedef RTDWARFADDRRANGE const *PCRTDWARFADDRRANGE;
     573
     574/** What a RTDWARFREF is relative to. */
     575typedef enum krtDwarfRef
     576{
     577    krtDwarfRef_NotSet,
     578    krtDwarfRef_LineSection,
     579    krtDwarfRef_LocSection,
     580    krtDwarfRef_RangesSection,
     581    krtDwarfRef_InfoSection,
     582    krtDwarfRef_SameUnit,
     583    krtDwarfRef_TypeId64
     584} krtDwarfRef;
     585
     586/**
     587 * DWARF reference.
     588 */
     589typedef struct RTDWARFREF
     590{
     591    /** The offset. */
     592    uint64_t        off;
     593    /** What the offset is relative to. */
     594    krtDwarfRef     enmWrt;
     595} RTDWARFREF;
     596typedef RTDWARFREF *PRTDWARFREF;
     597typedef RTDWARFREF const *PCRTDWARFREF;
     598
     599
     600
     601/*******************************************************************************
     602*   Internal Functions                                                         *
     603*******************************************************************************/
     604static FNRTDWARFATTRDECODER rtDwarfDecode_Bool;
     605static FNRTDWARFATTRDECODER rtDwarfDecode_LowHighPc;
     606static FNRTDWARFATTRDECODER rtDwarfDecode_Ranges;
     607static FNRTDWARFATTRDECODER rtDwarfDecode_Reference;
     608static FNRTDWARFATTRDECODER rtDwarfDecode_SectOff;
     609static FNRTDWARFATTRDECODER rtDwarfDecode_String;
     610static FNRTDWARFATTRDECODER rtDwarfDecode_UnsignedInt;
     611
     612
     613/*******************************************************************************
     614*   Global Variables                                                           *
     615*******************************************************************************/
     616/**
     617 * DW_TAG_compile_unit & DW_TAG_partial_unit.
     618 */
     619typedef struct RTDWARFDIECOMPILEUNIT
     620{
     621    /** The DIE core structure. */
     622    RTDWARFDIE          Core;
     623    /** The unit name. */
     624    const char         *pszName;
     625    /** The address range of the code belonging to this unit. */
     626    RTDWARFADDRRANGE    PcRange;
     627    /** The language name. */
     628    uint8_t             uLanguage;
     629    /** The identifier case. */
     630    uint8_t             uIdentifierCase;
     631    /** String are UTF-8 encoded.  If not set, the encoding is
     632     * unknown. */
     633    bool                fUseUtf8;
     634    /** The unit contains main() or equivalent. */
     635    bool                fMainFunction;
     636    /** The line numbers for this unit. */
     637    RTDWARFREF          StmtListRef;
     638    /** The macro information for this unit. */
     639    RTDWARFREF          MacroInfoRef;
     640    /** Reference to the base types. */
     641    RTDWARFREF          BaseTypesRef;
     642    /** Working directory for the unit. */
     643    const char         *pszCurDir;
     644    /** The name of the compiler or whatever that produced this unit. */
     645    const char         *pszProducer;
     646
     647    /** @name From the unit header.
     648     * @{ */
     649    /** The offset into debug_info of this unit (for references). */
     650    uint64_t            offUnit;
     651    /** The length of this unit. */
     652    uint64_t            cbUnit;
     653    /** The offset into debug_abbrev of the abbreviation for this unit. */
     654    uint64_t            offAbbrev;
     655    /** The native address size. */
     656    uint8_t             cbNativeAddr;
     657    /** The DWARF version. */
     658    uint8_t             uDwarfVer;
     659    /** @} */
     660} RTDWARFDIECOMPILEUNIT;
     661typedef RTDWARFDIECOMPILEUNIT *PRTDWARFDIECOMPILEUNIT;
     662
     663
     664/** RTDWARFDIECOMPILEUNIT attributes. */
     665static const RTDWARFATTRDESC g_aCompileUnitAttrs[] =
     666{
     667    ATTR_ENTRY(DW_AT_name,              RTDWARFDIECOMPILEUNIT, pszName,        ATTR_INIT_ZERO, rtDwarfDecode_String),
     668    ATTR_ENTRY(DW_AT_high_pc,           RTDWARFDIECOMPILEUNIT, PcRange,        ATTR_INIT_ZERO, rtDwarfDecode_LowHighPc),
     669    ATTR_ENTRY(DW_AT_ranges,            RTDWARFDIECOMPILEUNIT, PcRange,        ATTR_INIT_ZERO, rtDwarfDecode_Ranges),
     670    ATTR_ENTRY(DW_AT_language,          RTDWARFDIECOMPILEUNIT, uLanguage,      ATTR_INIT_ZERO, rtDwarfDecode_UnsignedInt),
     671    ATTR_ENTRY(DW_AT_macro_info,        RTDWARFDIECOMPILEUNIT, MacroInfoRef,   ATTR_INIT_FFFS, rtDwarfDecode_SectOff),
     672    ATTR_ENTRY(DW_AT_stmt_list,         RTDWARFDIECOMPILEUNIT, StmtListRef,    ATTR_INIT_FFFS, rtDwarfDecode_SectOff),
     673    ATTR_ENTRY(DW_AT_comp_dir,          RTDWARFDIECOMPILEUNIT, pszCurDir,      ATTR_INIT_ZERO, rtDwarfDecode_String),
     674    ATTR_ENTRY(DW_AT_producer,          RTDWARFDIECOMPILEUNIT, pszProducer,    ATTR_INIT_ZERO, rtDwarfDecode_String),
     675    ATTR_ENTRY(DW_AT_identifier_case,   RTDWARFDIECOMPILEUNIT, uIdentifierCase,ATTR_INIT_ZERO, rtDwarfDecode_UnsignedInt),
     676    ATTR_ENTRY(DW_AT_base_types,        RTDWARFDIECOMPILEUNIT, BaseTypesRef,   ATTR_INIT_ZERO, rtDwarfDecode_Reference),
     677    ATTR_ENTRY(DW_AT_use_UTF8,          RTDWARFDIECOMPILEUNIT, fUseUtf8,       ATTR_INIT_ZERO, rtDwarfDecode_Bool),
     678    ATTR_ENTRY(DW_AT_main_subprogram,   RTDWARFDIECOMPILEUNIT, fMainFunction,  ATTR_INIT_ZERO, rtDwarfDecode_Bool)
     679};
     680
     681/** RTDWARFDIECOMPILEUNIT description. */
     682static const RTDWARFDIEDESC  g_aCompileUnitDesc = { RT_ELEMENTS(g_aCompileUnitAttrs),  &g_aCompileUnitAttrs[0] };
     683
     684
     685#ifndef DEFINE_THESE_TAGS_TOO
     686#define DW_TAG_array_type                   UINT16_C(0x0001)
     687#define DW_TAG_class_type                   UINT16_C(0x0002)
     688#define DW_TAG_entry_point                  UINT16_C(0x0003)
     689#define DW_TAG_enumeration_type             UINT16_C(0x0004)
     690#define DW_TAG_formal_parameter             UINT16_C(0x0005)
     691#define DW_TAG_imported_declaration         UINT16_C(0x0008)
     692#define DW_TAG_label                        UINT16_C(0x000a)
     693#define DW_TAG_lexical_block                UINT16_C(0x000b)
     694#define DW_TAG_member                       UINT16_C(0x000d)
     695#define DW_TAG_pointer_type                 UINT16_C(0x000f)
     696#define DW_TAG_reference_type               UINT16_C(0x0010)
     697#define DW_TAG_compile_unit                 UINT16_C(0x0011)
     698#define DW_TAG_string_type                  UINT16_C(0x0012)
     699#define DW_TAG_structure_type               UINT16_C(0x0013)
     700#define DW_TAG_subroutine_type              UINT16_C(0x0015)
     701#define DW_TAG_typedef                      UINT16_C(0x0016)
     702#define DW_TAG_union_type                   UINT16_C(0x0017)
     703#define DW_TAG_unspecified_parameters       UINT16_C(0x0018)
     704#define DW_TAG_variant                      UINT16_C(0x0019)
     705#define DW_TAG_common_block                 UINT16_C(0x001a)
     706#define DW_TAG_common_inclusion             UINT16_C(0x001b)
     707#define DW_TAG_inheritance                  UINT16_C(0x001c)
     708#define DW_TAG_inlined_subroutine           UINT16_C(0x001d)
     709#define DW_TAG_module                       UINT16_C(0x001e)
     710#define DW_TAG_ptr_to_member_type           UINT16_C(0x001f)
     711#define DW_TAG_set_type                     UINT16_C(0x0020)
     712#define DW_TAG_subrange_type                UINT16_C(0x0021)
     713#define DW_TAG_with_stmt                    UINT16_C(0x0022)
     714#define DW_TAG_access_declaration           UINT16_C(0x0023)
     715#define DW_TAG_base_type                    UINT16_C(0x0024)
     716#define DW_TAG_catch_block                  UINT16_C(0x0025)
     717#define DW_TAG_const_type                   UINT16_C(0x0026)
     718#define DW_TAG_constant                     UINT16_C(0x0027)
     719#define DW_TAG_enumerator                   UINT16_C(0x0028)
     720#define DW_TAG_file_type                    UINT16_C(0x0029)
     721#define DW_TAG_friend                       UINT16_C(0x002a)
     722#define DW_TAG_namelist                     UINT16_C(0x002b)
     723#define DW_TAG_namelist_item                UINT16_C(0x002c)
     724#define DW_TAG_packed_type                  UINT16_C(0x002d)
     725#define DW_TAG_subprogram                   UINT16_C(0x002e)
     726#define DW_TAG_template_type_parameter      UINT16_C(0x002f)
     727#define DW_TAG_template_value_parameter     UINT16_C(0x0030)
     728#define DW_TAG_thrown_type                  UINT16_C(0x0031)
     729#define DW_TAG_try_block                    UINT16_C(0x0032)
     730#define DW_TAG_variant_part                 UINT16_C(0x0033)
     731#define DW_TAG_variable                     UINT16_C(0x0034)
     732#define DW_TAG_volatile_type                UINT16_C(0x0035)
     733#define DW_TAG_dwarf_procedure              UINT16_C(0x0036)
     734#define DW_TAG_restrict_type                UINT16_C(0x0037)
     735#define DW_TAG_interface_type               UINT16_C(0x0038)
     736#define DW_TAG_namespace                    UINT16_C(0x0039)
     737#define DW_TAG_imported_module              UINT16_C(0x003a)
     738#define DW_TAG_unspecified_type             UINT16_C(0x003b)
     739#define DW_TAG_partial_unit                 UINT16_C(0x003c)
     740#define DW_TAG_imported_unit                UINT16_C(0x003d)
     741#define DW_TAG_condition                    UINT16_C(0x003f)
     742#define DW_TAG_shared_type                  UINT16_C(0x0040)
     743#define DW_TAG_type_unit                    UINT16_C(0x0041)
     744#define DW_TAG_rvalue_reference_type        UINT16_C(0x0042)
     745#define DW_TAG_template_alias               UINT16_C(0x0043)
     746#define DW_TAG_lo_user                      UINT16_C(0x4080)
     747#define DW_TAG_hi_user                      UINT16_C(0xffff)
     748#endif
     749
     750
    440751
    441752
     
    19852296
    19862297
     2298
    19872299/*
    19882300 *
    1989  * DWARF DIE stack (used by the debug_info parser).
    1990  * DWARF DIE stack (used by the debug_info parser).
    1991  * DWARF DIE stack (used by the debug_info parser).
    1992  *
    1993  */
    1994 
    1995 /**
    1996  * DWARF DIE stack entry.
    1997  */
    1998 typedef struct RTDWARFDIESTACKENTRY
    1999 {
    2000     /** The abbreviation code. */
    2001     uint32_t        uAbbrCode;
    2002     /** The tag. */
    2003     uint16_t        uTag;
    2004     /** The offset into the debug_info section of the data. */
    2005     uint32_t        offData;
    2006     /** The associated name. (Points into some dwarf section.) */
    2007     const char     *pszName;
    2008 } RTDWARFDIESTACKENTRY;
    2009 /** Pointer to a DIE stack entry. */
    2010 typedef RTDWARFDIESTACKENTRY *PRTDWARFDIESTACKENTRY;
    2011 
    2012 /**
    2013  * DWARF DIE stack.
    2014  */
    2015 typedef struct RTDWARFDIESTACK
    2016 {
    2017     /** The number of items on the stack. */
    2018     uint32_t                cOnStack;
    2019     /** The number of stack entries we've allocated. */
    2020     uint32_t                cAlloced;
    2021     /** Pointer to the stack entries. */
    2022     PRTDWARFDIESTACKENTRY   paEntries;
    2023 } RTDWARFDIESTACK;
    2024 /** Pointer to a DIE stack. */
    2025 typedef RTDWARFDIESTACK *PRTDWARFDIESTACK;
    2026 /** Pointer to a const DIE stack. */
    2027 typedef RTDWARFDIESTACK const *PCRTDWARFDIESTACK;
    2028 
    2029 
    2030 static int rtDwarfDieStack_SetName(PRTDWARFDIESTACK pStack, const char *pszName)
    2031 {
    2032     uint32_t i = pStack->cOnStack;
    2033     if (i == 0)
    2034         return VERR_DWARF_BAD_INFO;
    2035     i--;
    2036     pStack->paEntries[i].pszName = pszName;
    2037     return VINF_SUCCESS;
    2038 }
    2039 
    2040 
    2041 static int rtDwarfDieStack_Push(PRTDWARFDIESTACK pStack, uint32_t uAbbrCode, uint16_t uTag, uint32_t offData)
    2042 {
    2043     uint32_t i = pStack->cOnStack;
    2044     if (i == pStack->cAlloced)
    2045     {
    2046         uint32_t cNewSize = pStack->cAlloced ? pStack->cAlloced * 2 : 1 /*16*/;
    2047         void *pv = RTMemRealloc(pStack->paEntries, sizeof(pStack->paEntries[0]) * cNewSize);
    2048         if (!pv)
    2049             return VERR_NO_MEMORY;
    2050         pStack->paEntries = (PRTDWARFDIESTACKENTRY)pv;
    2051         pStack->cAlloced  = cNewSize;
    2052     }
    2053     Assert(i < pStack->cAlloced);
    2054 
    2055     pStack->paEntries[i].uAbbrCode = uAbbrCode;
    2056     pStack->paEntries[i].uTag      = uTag;
    2057     pStack->paEntries[i].offData   = offData;
    2058     pStack->paEntries[i].pszName   = NULL;
    2059     pStack->cOnStack = i + 1;
    2060 
    2061     return VINF_SUCCESS;
    2062 }
    2063 
    2064 
    2065 static int rtDwarfDieStack_Pop(PRTDWARFDIESTACK pStack)
    2066 {
    2067     if (pStack->cOnStack == 0)
    2068         return VERR_DWARF_BAD_INFO;
    2069     pStack->cOnStack--;
    2070     return VINF_SUCCESS;
    2071 }
    2072 
    2073 
    2074 static void rtDwarfDieStack_Init(PRTDWARFDIESTACK pStack)
    2075 {
    2076     pStack->cOnStack  = 0;
    2077     pStack->cAlloced  = 0;
    2078     pStack->paEntries = NULL;
    2079 }
    2080 
    2081 
    2082 static void rtDwarfDieStack_Delete(PRTDWARFDIESTACK pStack)
    2083 {
    2084     RTMemFree(pStack->paEntries);
    2085     pStack->paEntries = NULL;
    2086 }
    2087 
    2088 
    2089 
    2090 /*
    2091  *
    2092  * DWARF debug_info parser
    2093  * DWARF debug_info parser
    2094  * DWARF debug_info parser
    2095  *
    2096  */
     2301 * DIE Attribute Parsers.
     2302 * DIE Attribute Parsers.
     2303 * DIE Attribute Parsers.
     2304 *
     2305 */
     2306
     2307/**
     2308 * Gets the compilation unit a DIE belongs to.
     2309 *
     2310 * @returns The compilation unit DIE.
     2311 * @param   pDie                Some DIE in the unit.
     2312 */
     2313static PRTDWARFDIECOMPILEUNIT rtDwarfDie_GetCompileUnit(PRTDWARFDIE pDie)
     2314{
     2315    while (pDie->pParent)
     2316        pDie = pDie->pParent;
     2317    AssertReturn(   pDie->uTag == DW_TAG_compile_unit
     2318                 || pDie->uTag == DW_TAG_partial_unit,
     2319                 NULL);
     2320    return (PRTDWARFDIECOMPILEUNIT)pDie;
     2321}
    20972322
    20982323
     
    21062331 *                              pCursor->rc is set).
    21072332 */
    2108 static const char *rtDwarfForm_GetStrp(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor, const char *pszErrValue)
     2333static const char *rtDwarfDecode_GetStrp(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor, const char *pszErrValue)
    21092334{
    21102335    uint64_t offDebugStr = rtDwarfCursor_GetUOff(pCursor, UINT64_MAX);
     
    21332358}
    21342359
     2360
     2361/** @callback_method_impl{FNRTDWARFATTRDECODER} */
     2362static DECLCALLBACK(int) rtDwarfDecode_Bool(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc,
     2363                                            uint32_t uForm, PRTDWARFCURSOR pCursor)
     2364{
     2365    AssertReturn(ATTR_GET_SIZE(pDesc) == sizeof(bool), VERR_INTERNAL_ERROR_3);
     2366
     2367    bool *pfMember = (bool *)pbMember;
     2368    switch (uForm)
     2369    {
     2370        case DW_FORM_flag:
     2371        {
     2372            uint8_t b = rtDwarfCursor_GetU8(pCursor, UINT8_MAX);
     2373            if (b > 1)
     2374                return RT_FAILURE(pCursor->rc) ? pCursor->rc : pCursor->rc = VERR_DWARF_BAD_INFO;
     2375            *pfMember = RT_BOOL(b);
     2376            break;
     2377        }
     2378
     2379        case DW_FORM_flag_present:
     2380            *pfMember = true;
     2381            break;
     2382
     2383        default:
     2384            AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM);
     2385    }
     2386
     2387    return VINF_SUCCESS;
     2388}
     2389
     2390
     2391/** @callback_method_impl{FNRTDWARFATTRDECODER} */
     2392static DECLCALLBACK(int) rtDwarfDecode_LowHighPc(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc,
     2393                                                 uint32_t uForm, PRTDWARFCURSOR pCursor)
     2394{
     2395    AssertReturn(ATTR_GET_SIZE(pDesc) == sizeof(RTDWARFADDRRANGE), VERR_INTERNAL_ERROR_3);
     2396    AssertReturn(pDesc->uAttr == DW_AT_low_pc || pDesc->uAttr == DW_AT_high_pc, VERR_INTERNAL_ERROR_3);
     2397
     2398    uint64_t uAddr;
     2399    switch (uForm)
     2400    {
     2401        case DW_FORM_addr:  uAddr = rtDwarfCursor_GetNativeUOff(pCursor, 0); break;
     2402        case DW_FORM_data1: uAddr = rtDwarfCursor_GetU8(pCursor, 0); break;
     2403        case DW_FORM_data2: uAddr = rtDwarfCursor_GetU16(pCursor, 0); break;
     2404        case DW_FORM_data4: uAddr = rtDwarfCursor_GetU32(pCursor, 0); break;
     2405        case DW_FORM_data8: uAddr = rtDwarfCursor_GetU64(pCursor, 0); break;
     2406        case DW_FORM_udata: uAddr = rtDwarfCursor_GetULeb128(pCursor, 0); break;
     2407        default:
     2408            AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM);
     2409    }
     2410    if (RT_FAILURE(pCursor->rc))
     2411        return pCursor->rc;
     2412
     2413    PRTDWARFADDRRANGE pRange = (PRTDWARFADDRRANGE)pbMember;
     2414    if (pDesc->uAttr == DW_AT_low_pc)
     2415    {
     2416        pRange->uLowAddress      = uAddr;
     2417        pRange->fHaveLowAddress  = true;
     2418    }
     2419    else
     2420    {
     2421        pRange->uHighAddress     = uAddr;
     2422        pRange->fHaveHighAddress = true;
     2423    }
     2424
     2425    return VINF_SUCCESS;
     2426}
     2427
     2428
     2429/** @callback_method_impl{FNRTDWARFATTRDECODER} */
     2430static DECLCALLBACK(int) rtDwarfDecode_Ranges(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc,
     2431                                              uint32_t uForm, PRTDWARFCURSOR pCursor)
     2432{
     2433    AssertReturn(ATTR_GET_SIZE(pDesc) == sizeof(RTDWARFADDRRANGE), VERR_INTERNAL_ERROR_3);
     2434    AssertReturn(pDesc->uAttr == DW_AT_low_pc || pDesc->uAttr == DW_AT_high_pc, VERR_INTERNAL_ERROR_3);
     2435
     2436    /* Decode it. */
     2437    uint64_t off;
     2438    switch (uForm)
     2439    {
     2440        case DW_FORM_addr:  off = rtDwarfCursor_GetNativeUOff(pCursor, 0); break;
     2441        case DW_FORM_data4: off = rtDwarfCursor_GetU32(pCursor, 0); break;
     2442        case DW_FORM_data8: off = rtDwarfCursor_GetU64(pCursor, 0); break;
     2443        default:
     2444            AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM);
     2445    }
     2446    if (RT_FAILURE(pCursor->rc))
     2447        return pCursor->rc;
     2448
     2449    /* Validate the offset and load the ranges. */
     2450    PRTDBGMODDWARF pThis = pCursor->pDwarfMod;
     2451    if (off >= pThis->aSections[krtDbgModDwarfSect_ranges].cb)
     2452        return pCursor->rc = VERR_DWARF_BAD_POS;
     2453
     2454    if (!pThis->aSections[krtDbgModDwarfSect_ranges].pv)
     2455    {
     2456        int rc = rtDbgModDwarfLoadSection(pThis, krtDbgModDwarfSect_ranges);
     2457        if (RT_FAILURE(rc))
     2458            return pCursor->rc = rc;
     2459    }
     2460
     2461    /* Store the result. */
     2462    PRTDWARFADDRRANGE pRange = (PRTDWARFADDRRANGE)pbMember;
     2463    pRange->pbRanges    = (uint8_t const *)pThis->aSections[krtDbgModDwarfSect_ranges].pv + (size_t)off;
     2464    pRange->fHaveRanges = true;
     2465
     2466    return VINF_SUCCESS;
     2467}
     2468
     2469
     2470/** @callback_method_impl{FNRTDWARFATTRDECODER} */
     2471static DECLCALLBACK(int) rtDwarfDecode_Reference(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc,
     2472                                                 uint32_t uForm, PRTDWARFCURSOR pCursor)
     2473{
     2474    AssertReturn(ATTR_GET_SIZE(pDesc) == sizeof(RTDWARFREF), VERR_INTERNAL_ERROR_3);
     2475
     2476    /* Decode it. */
     2477    uint64_t        off;
     2478    krtDwarfRef     enmWrt = krtDwarfRef_InfoSection;
     2479    switch (uForm)
     2480    {
     2481        case DW_FORM_ref1:          off = rtDwarfCursor_GetU8(pCursor, 0); break;
     2482        case DW_FORM_ref2:          off = rtDwarfCursor_GetU16(pCursor, 0); break;
     2483        case DW_FORM_ref4:          off = rtDwarfCursor_GetU32(pCursor, 0); break;
     2484        case DW_FORM_ref8:          off = rtDwarfCursor_GetU64(pCursor, 0); break;
     2485        case DW_FORM_ref_udata:     off = rtDwarfCursor_GetULeb128(pCursor, 0); break;
     2486
     2487        case DW_FORM_ref_addr:
     2488            enmWrt = krtDwarfRef_InfoSection;
     2489            off = rtDwarfCursor_GetUOff(pCursor, 0);
     2490            break;
     2491
     2492        case DW_FORM_ref_sig8:
     2493            enmWrt = krtDwarfRef_TypeId64;
     2494            off = rtDwarfCursor_GetU64(pCursor, 0);
     2495            break;
     2496
     2497        default:
     2498            AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM);
     2499    }
     2500    if (RT_FAILURE(pCursor->rc))
     2501        return pCursor->rc;
     2502
     2503    /* Validate the offset and convert to debug_info relative offsets. */
     2504    if (enmWrt == krtDwarfRef_InfoSection)
     2505    {
     2506        if (off >= pCursor->pDwarfMod->aSections[krtDbgModDwarfSect_info].cb)
     2507            return pCursor->rc = VERR_DWARF_BAD_POS;
     2508    }
     2509    else if (enmWrt == krtDwarfRef_SameUnit)
     2510    {
     2511        PRTDWARFDIECOMPILEUNIT pUnit = rtDwarfDie_GetCompileUnit(pDie);
     2512        if (off >= pUnit->cbUnit)
     2513            return pCursor->rc = VERR_DWARF_BAD_POS;
     2514        off += pUnit->offUnit;
     2515        enmWrt = krtDwarfRef_InfoSection;
     2516    }
     2517    /* else: not bother verifying/resolving the indirect type reference yet. */
     2518
     2519    /* Store it */
     2520    PRTDWARFREF pRef = (PRTDWARFREF)pbMember;
     2521    pRef->enmWrt = enmWrt;
     2522    pRef->off    = off;
     2523
     2524    return VINF_SUCCESS;
     2525}
     2526
     2527
     2528/** @callback_method_impl{FNRTDWARFATTRDECODER} */
     2529static DECLCALLBACK(int) rtDwarfDecode_SectOff(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc,
     2530                                               uint32_t uForm, PRTDWARFCURSOR pCursor)
     2531{
     2532    AssertReturn(ATTR_GET_SIZE(pDesc) == sizeof(RTDWARFREF), VERR_INTERNAL_ERROR_3);
     2533
     2534    uint64_t off;
     2535    switch (uForm)
     2536    {
     2537        case DW_FORM_data4:         off = rtDwarfCursor_GetU32(pCursor, 0); break;
     2538        case DW_FORM_data8:         off = rtDwarfCursor_GetU64(pCursor, 0); break;
     2539        case DW_FORM_sec_offset:    off = rtDwarfCursor_GetUOff(pCursor, 0); break;
     2540        default:
     2541            AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM);
     2542    }
     2543    if (RT_FAILURE(pCursor->rc))
     2544        return pCursor->rc;
     2545
     2546    krtDbgModDwarfSect  enmSect;
     2547    krtDwarfRef         enmWrt;
     2548    switch (pDesc->uAttr)
     2549    {
     2550        case DW_AT_stmt_list:   enmSect = krtDbgModDwarfSect_line;    enmWrt = krtDwarfRef_LineSection;     break;
     2551        case DW_AT_macro_info:  enmSect = krtDbgModDwarfSect_loc;     enmWrt = krtDwarfRef_LocSection;      break;
     2552        case DW_AT_ranges:      enmSect = krtDbgModDwarfSect_ranges;  enmWrt = krtDwarfRef_RangesSection;  break;
     2553        default:                AssertMsgFailedReturn(("%u\n", pDesc->uAttr), VERR_INTERNAL_ERROR_4);
     2554    }
     2555    if (off > pCursor->pDwarfMod->aSections[enmSect].cb)
     2556        return pCursor->rc = VERR_DWARF_BAD_POS;
     2557
     2558    PRTDWARFREF pRef = (PRTDWARFREF)pbMember;
     2559    pRef->enmWrt = enmWrt;
     2560    pRef->off    = off;
     2561
     2562    return VINF_SUCCESS;
     2563}
     2564
     2565
     2566/** @callback_method_impl{FNRTDWARFATTRDECODER} */
     2567static DECLCALLBACK(int) rtDwarfDecode_String(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc,
     2568                                              uint32_t uForm, PRTDWARFCURSOR pCursor)
     2569{
     2570    AssertReturn(ATTR_GET_SIZE(pDesc) == sizeof(const char *), VERR_INTERNAL_ERROR_3);
     2571
     2572    switch (uForm)
     2573    {
     2574        case DW_FORM_string:
     2575            *(const char **)pbMember = rtDwarfCursor_GetSZ(pCursor, NULL);
     2576            break;
     2577
     2578        case DW_FORM_strp:
     2579            *(const char **)pbMember = rtDwarfDecode_GetStrp(pCursor->pDwarfMod, pCursor, NULL);
     2580            break;
     2581
     2582        default:
     2583            AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM);
     2584    }
     2585
     2586    return pCursor->rc;
     2587}
     2588
     2589
     2590/** @callback_method_impl{FNRTDWARFATTRDECODER} */
     2591static DECLCALLBACK(int) rtDwarfDecode_UnsignedInt(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc,
     2592                                                   uint32_t uForm, PRTDWARFCURSOR pCursor)
     2593{
     2594    uint64_t u64Val;
     2595    switch (uForm)
     2596    {
     2597        case DW_FORM_udata: u64Val = rtDwarfCursor_GetULeb128(pCursor, 0); break;
     2598        case DW_FORM_data1: u64Val = rtDwarfCursor_GetU8(pCursor, 0); break;
     2599        case DW_FORM_data2: u64Val = rtDwarfCursor_GetU16(pCursor, 0); break;
     2600        case DW_FORM_data4: u64Val = rtDwarfCursor_GetU32(pCursor, 0); break;
     2601        case DW_FORM_data8: u64Val = rtDwarfCursor_GetU64(pCursor, 0); break;
     2602        default:
     2603            AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM);
     2604    }
     2605    if (RT_FAILURE(pCursor->rc))
     2606        return pCursor->rc;
     2607
     2608    switch (ATTR_GET_SIZE(pDesc))
     2609    {
     2610        case 1:
     2611            *pbMember = (uint8_t)u64Val;
     2612            if (*pbMember != u64Val)
     2613                return VERR_OUT_OF_RANGE;
     2614            break;
     2615
     2616        case 2:
     2617            *(uint16_t *)pbMember = (uint16_t)u64Val;
     2618            if (*(uint16_t *)pbMember != u64Val)
     2619                return VERR_OUT_OF_RANGE;
     2620            break;
     2621
     2622        case 4:
     2623            *(uint32_t *)pbMember = (uint32_t)u64Val;
     2624            if (*(uint32_t *)pbMember != u64Val)
     2625                return VERR_OUT_OF_RANGE;
     2626            break;
     2627
     2628        case 8:
     2629            *(uint64_t *)pbMember = (uint64_t)u64Val;
     2630            if (*(uint64_t *)pbMember != u64Val)
     2631                return VERR_OUT_OF_RANGE;
     2632            break;
     2633
     2634        default:
     2635            AssertMsgFailedReturn(("%#x\n", ATTR_GET_SIZE(pDesc)), VERR_INTERNAL_ERROR_2);
     2636    }
     2637    return VINF_SUCCESS;
     2638}
     2639
     2640
     2641
     2642/*
     2643 *
     2644 * DWARF debug_info parser
     2645 * DWARF debug_info parser
     2646 * DWARF debug_info parser
     2647 *
     2648 */
     2649
     2650
     2651
    21352652static const char *rtDwarfForm_GetString(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor, uint16_t uForm, const char *pszErrValue)
    21362653{
     
    21412658
    21422659        case DW_FORM_strp:
    2143             return rtDwarfForm_GetStrp(pThis, pCursor, pszErrValue);
     2660            return rtDwarfDecode_GetStrp(pThis, pCursor, pszErrValue);
    21442661
    21452662        default:
     
    21472664            return pszErrValue;
    21482665    }
     2666}
     2667
     2668
     2669/**
     2670 * Creates a new internal DIE structure and links it up.
     2671 *
     2672 * @returns Pointer to the new DIE structure.
     2673 * @param   pThis               The DWARF instance.
     2674 * @param   cbUnit              The size required for this unit.
     2675 * @param   pAbbrev             The abbreviation cache entry.
     2676 * @param   pParent             The parent DIE (NULL if unit).
     2677 */
     2678static PRTDWARFDIE rtDwarfInfo_NewDie(PRTDBGMODDWARF pThis, size_t cbUnit, PCRTDWARFABBREV pAbbrev, PRTDWARFDIE pParent)
     2679{
     2680    Assert(cbUnit >= sizeof(RTDWARFDIE));
     2681    PRTDWARFDIE pDie = (PRTDWARFDIE)RTMemAllocZ(cbUnit);
     2682    if (pDie)
     2683    {
     2684        pDie->uTag         = pAbbrev->uTag;
     2685        pDie->offSpec      = pAbbrev->offSpec;
     2686        pDie->pParent      = pParent;
     2687        if (pParent)
     2688            RTListAppend(&pParent->ChildList, &pDie->SiblingNode);
     2689        else
     2690            RTListInit(&pDie->SiblingNode);
     2691        RTListInit(&pDie->ChildList);
     2692    }
     2693    return pDie;
    21492694}
    21502695
     
    22452790
    22462791
     2792#if 0
    22472793/**
    22482794 * Parse a DIE.
     
    23272873    return rtDwarfInfo_SkipDie(pCursor, pAbbrevCursor);
    23282874}
     2875#endif
    23292876
    23302877
     
    23372884     * Read the compilation unit header.
    23382885     */
    2339     rtDwarfCursor_GetInitalLength(pCursor);
     2886    uint64_t offUnit = rtDwarfCursor_CalcSectOffsetU32(pCursor);
     2887    uint64_t cbUnit  = rtDwarfCursor_GetInitalLength(pCursor);
     2888    cbUnit += rtDwarfCursor_CalcSectOffsetU32(pCursor) - offUnit;
    23402889    uint16_t const uVer = rtDwarfCursor_GetUHalf(pCursor, 0);
    23412890    if (   uVer < 2
     
    23572906
    23582907    /*
    2359      * We want a DIE stack as well.
     2908     * The first DIE is a compile or partial unit, parse it here.
    23602909     */
    2361     RTDWARFDIESTACK Stack;
    2362     rtDwarfDieStack_Init(&Stack);
     2910    uint32_t uAbbrCode = rtDwarfCursor_GetULeb128AsU32(pCursor, UINT32_MAX);
     2911    if (!uAbbrCode)
     2912        return VERR_DWARF_BAD_INFO;
     2913    PCRTDWARFABBREV pAbbrev = rtDwarfAbbrev_Lookup(pThis, uAbbrCode);
     2914    if (!pAbbrev)
     2915        return VERR_DWARF_ABBREV_NOT_FOUND;
     2916    if (   pAbbrev->uTag != DW_TAG_compile_unit
     2917        && pAbbrev->uTag != DW_TAG_partial_unit)
     2918    {
     2919        Log(("Unexpected compile/partial unit tag %#x\n", pAbbrev->uTag));
     2920        return VERR_DWARF_BAD_INFO;
     2921    }
     2922
     2923    PRTDWARFDIECOMPILEUNIT pUnit = (PRTDWARFDIECOMPILEUNIT)rtDwarfInfo_NewDie(pThis, sizeof(*pUnit), pAbbrev, NULL /*pParent*/);
     2924    if (!pUnit)
     2925        return VERR_NO_MEMORY;
     2926    pUnit->offUnit      = offUnit;
     2927    pUnit->cbUnit       = cbUnit;
     2928    pUnit->offAbbrev    = offAbbrev;
     2929    pUnit->cbNativeAddr = cbNativeAddr;
     2930    pUnit->uDwarfVer    = uVer;
     2931    RTListAppend(&pThis->CompileUnitList, &pUnit->Core.SiblingNode);
     2932
     2933    /** @todo Parse the DIE data using the descriptor. */
     2934    RTDWARFCURSOR AbbrevCursor;
     2935    int rc = rtDwarfCursor_InitWithOffset(&AbbrevCursor, pThis, krtDbgModDwarfSect_abbrev, pAbbrev->offSpec);
     2936#if 0
     2937    if (RT_SUCCESS(rc))
     2938    {
     2939        rc = rtDwarfInfo_ParseDie(pThis, pCursor, pAbbrev, &AbbrevCursor, &Stack);
     2940        rc = rtDwarfCursor_Delete(&AbbrevCursor, rc);
     2941    }
     2942    if (RT_FAILURE(rc))
     2943        break;
    23632944
    23642945    /*
     
    24152996
    24162997    rtDwarfDieStack_Delete(&Stack);
     2998#endif
    24172999    return RT_SUCCESS(rc) ? pCursor->rc : rc;
    24183000}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette