VirtualBox

Changeset 38601 in vbox for trunk/src/VBox/Runtime/common


Ignore:
Timestamp:
Sep 1, 2011 2:44:54 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
73804
Message:

IPRT: Some more dwarf bits.

File:
1 edited

Legend:

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

    r38585 r38601  
    6666/** @name Extended DWARF Line Number Opcodes
    6767 * @{ */
    68 #define DW_LNE_end_sequence         UINT8_C(1)
    69 #define DW_LNE_set_address          UINT8_C(2)
    70 #define DW_LNE_define_file          UINT8_C(3)
    71 #define DW_LNE_set_descriminator    UINT8_C(4)
     68#define DW_LNE_end_sequence                 UINT8_C(1)
     69#define DW_LNE_set_address                  UINT8_C(2)
     70#define DW_LNE_define_file                  UINT8_C(3)
     71#define DW_LNE_set_descriminator            UINT8_C(4)
    7272/** @} */
    7373
     74/** @name DIE Tags.
     75 * @{ */
     76#define DW_TAG_array_type                   UINT16_C(0x0001)
     77#define DW_TAG_class_type                   UINT16_C(0x0002)
     78#define DW_TAG_entry_point                  UINT16_C(0x0003)
     79#define DW_TAG_enumeration_type             UINT16_C(0x0004)
     80#define DW_TAG_formal_parameter             UINT16_C(0x0005)
     81#define DW_TAG_imported_declaration         UINT16_C(0x0008)
     82#define DW_TAG_label                        UINT16_C(0x000a)
     83#define DW_TAG_lexical_block                UINT16_C(0x000b)
     84#define DW_TAG_member                       UINT16_C(0x000d)
     85#define DW_TAG_pointer_type                 UINT16_C(0x000f)
     86#define DW_TAG_reference_type               UINT16_C(0x0010)
     87#define DW_TAG_compile_unit                 UINT16_C(0x0011)
     88#define DW_TAG_string_type                  UINT16_C(0x0012)
     89#define DW_TAG_structure_type               UINT16_C(0x0013)
     90#define DW_TAG_subroutine_type              UINT16_C(0x0015)
     91#define DW_TAG_typedef                      UINT16_C(0x0016)
     92#define DW_TAG_union_type                   UINT16_C(0x0017)
     93#define DW_TAG_unspecified_parameters       UINT16_C(0x0018)
     94#define DW_TAG_variant                      UINT16_C(0x0019)
     95#define DW_TAG_common_block                 UINT16_C(0x001a)
     96#define DW_TAG_common_inclusion             UINT16_C(0x001b)
     97#define DW_TAG_inheritance                  UINT16_C(0x001c)
     98#define DW_TAG_inlined_subroutine           UINT16_C(0x001d)
     99#define DW_TAG_module                       UINT16_C(0x001e)
     100#define DW_TAG_ptr_to_member_type           UINT16_C(0x001f)
     101#define DW_TAG_set_type                     UINT16_C(0x0020)
     102#define DW_TAG_subrange_type                UINT16_C(0x0021)
     103#define DW_TAG_with_stmt                    UINT16_C(0x0022)
     104#define DW_TAG_access_declaration           UINT16_C(0x0023)
     105#define DW_TAG_base_type                    UINT16_C(0x0024)
     106#define DW_TAG_catch_block                  UINT16_C(0x0025)
     107#define DW_TAG_const_type                   UINT16_C(0x0026)
     108#define DW_TAG_constant                     UINT16_C(0x0027)
     109#define DW_TAG_enumerator                   UINT16_C(0x0028)
     110#define DW_TAG_file_type                    UINT16_C(0x0029)
     111#define DW_TAG_friend                       UINT16_C(0x002a)
     112#define DW_TAG_namelist                     UINT16_C(0x002b)
     113#define DW_TAG_namelist_item                UINT16_C(0x002c)
     114#define DW_TAG_packed_type                  UINT16_C(0x002d)
     115#define DW_TAG_subprogram                   UINT16_C(0x002e)
     116#define DW_TAG_template_type_parameter      UINT16_C(0x002f)
     117#define DW_TAG_template_value_parameter     UINT16_C(0x0030)
     118#define DW_TAG_thrown_type                  UINT16_C(0x0031)
     119#define DW_TAG_try_block                    UINT16_C(0x0032)
     120#define DW_TAG_variant_part                 UINT16_C(0x0033)
     121#define DW_TAG_variable                     UINT16_C(0x0034)
     122#define DW_TAG_volatile_type                UINT16_C(0x0035)
     123#define DW_TAG_dwarf_procedure              UINT16_C(0x0036)
     124#define DW_TAG_restrict_type                UINT16_C(0x0037)
     125#define DW_TAG_interface_type               UINT16_C(0x0038)
     126#define DW_TAG_namespace                    UINT16_C(0x0039)
     127#define DW_TAG_imported_module              UINT16_C(0x003a)
     128#define DW_TAG_unspecified_type             UINT16_C(0x003b)
     129#define DW_TAG_partial_unit                 UINT16_C(0x003c)
     130#define DW_TAG_imported_unit                UINT16_C(0x003d)
     131#define DW_TAG_condition                    UINT16_C(0x003f)
     132#define DW_TAG_shared_type                  UINT16_C(0x0040)
     133#define DW_TAG_type_unit                    UINT16_C(0x0041)
     134#define DW_TAG_rvalue_reference_type        UINT16_C(0x0042)
     135#define DW_TAG_template_alias               UINT16_C(0x0043)
     136#define DW_TAG_lo_user                      UINT16_C(0x4080)
     137#define DW_TAG_hi_user                      UINT16_C(0xffff)
     138/** @} */
    74139
    75140/*******************************************************************************
     
    101166 * Abbreviation cache entry.
    102167 */
    103 typedef struct RTDBGMODDWARFABBREV
     168typedef struct RTDWARFABBREV
    104169{
    105170    /** Whether this entry is filled in or not. */
     
    111176    /** Offset into the abbrev section of the specification pairs. */
    112177    uint32_t            offSpec;
    113 } RTDBGMODDWARFABBREV;
     178} RTDWARFABBREV;
    114179/** Pointer to an abbreviation cache entry. */
    115 typedef RTDBGMODDWARFABBREV *PRTDBGMODDWARFABBREV;
     180typedef RTDWARFABBREV *PRTDWARFABBREV;
    116181/** Pointer to a const abbreviation cache entry. */
    117 typedef RTDBGMODDWARFABBREV const *PCRTDBGMODDWARFABBREV;
     182typedef RTDWARFABBREV const *PCRTDWARFABBREV;
    118183
    119184
     
    148213    uint32_t                cCachedAbbrevs;
    149214    /** Array of cached abbreviations, indexed by code. */
    150     PRTDBGMODDWARFABBREV    paCachedAbbrevs;
     215    PRTDWARFABBREV           paCachedAbbrevs;
    151216    /** Used by rtDwarfAbbrev_Lookup when the result is uncachable. */
    152     RTDBGMODDWARFABBREV     LookupAbbrev;
     217    RTDWARFABBREV            LookupAbbrev;
    153218} RTDBGMODDWARF;
    154219/** Pointer to instance data of the DWARF reader. */
     
    904969 * Check if the cursor is at the end of the current DWARF unit.
    905970 *
    906  * @returns @c true if at the end, @c false if not.
     971 * @retval  @c true if at the end or a cursor error is pending.
     972 * @retval  @c false if not.
    907973 * @param   pCursor             The cursor.
    908974 */
    909975static bool rtDwarfCursor_IsAtEndOfUnit(PRTDWARFCURSOR pCursor)
    910976{
    911     return !pCursor->cbUnitLeft;
     977    return !pCursor->cbUnitLeft || RT_FAILURE(pCursor->rc);
    912978}
    913979
     
    932998 * processing).
    933999 *
    934  * @returns @c true if at the end, @c false if not.
     1000 * @retval  @c true if at the end or a cursor error is pending.
     1001 * @retval  @c false if not.
    9351002 * @param   pCursor             The cursor.
    9361003 */
    9371004static bool rtDwarfCursor_IsAtEnd(PRTDWARFCURSOR pCursor)
    9381005{
    939     return !pCursor->cbLeft;
     1006    return !pCursor->cbLeft || RT_FAILURE(pCursor->rc);
    9401007}
    9411008
     
    10031070 * Deletes a section reader initialized by rtDwarfCursor_Init.
    10041071 *
    1005  * @param   pCursor            The section reader.
    1006  */
    1007 static void rtDwarfCursor_Delete(PRTDWARFCURSOR pCursor)
     1072 * @returns @a rcOther or RTDWARCURSOR::rc.
     1073 * @param   pCursor             The section reader.
     1074 * @param   rcOther             Other error code to be returned if it indicates
     1075 *                              error or if the cursor status is OK.
     1076 */
     1077static int rtDwarfCursor_Delete(PRTDWARFCURSOR pCursor, int rcOther)
    10081078{
    10091079    /* ... and a drop of poison. */
     
    10121082    pCursor->cbUnitLeft = ~(size_t)0;
    10131083    pCursor->pDwarfMod  = NULL;
     1084    if (RT_FAILURE(pCursor->rc) && RT_SUCCESS(rcOther))
     1085        rcOther = pCursor->rc;
    10141086    pCursor->rc         = VERR_INTERNAL_ERROR_4;
     1087    return rcOther;
    10151088}
    10161089
     
    15061579        rc = rtDwarfLine_ExplodeUnit(pThis, &Cursor);
    15071580
    1508     rtDwarfCursor_Delete(&Cursor);
    1509     return rc;
     1581    return rtDwarfCursor_Delete(&Cursor, rc);
    15101582}
    15111583
     
    15271599 * @param   uCode               The abbreviation code to lookup.
    15281600 */
    1529 static PCRTDBGMODDWARFABBREV rtDwarfAbbrev_LookupMiss(PRTDBGMODDWARF pThis, uint32_t uCode)
     1601static PCRTDWARFABBREV rtDwarfAbbrev_LookupMiss(PRTDBGMODDWARF pThis, uint32_t uCode)
    15301602{
    15311603    /*
     
    15521624            {
    15531625                pThis->cCachedAbbrevsAlloced = cNew;
    1554                 pThis->paCachedAbbrevs       = (PRTDBGMODDWARFABBREV)pv;
     1626                pThis->paCachedAbbrevs       = (PRTDWARFABBREV)pv;
    15551627            }
    15561628        }
     
    15651637        return NULL;
    15661638
    1567     PRTDBGMODDWARFABBREV pRet = NULL;
     1639    PRTDWARFABBREV pRet = NULL;
    15681640    if (fFillCache)
    15691641    {
     
    15891661            if (uCurCode >= pThis->cCachedAbbrevsAlloced)
    15901662            {
    1591                 PRTDBGMODDWARFABBREV pEntry = &pThis->paCachedAbbrevs[uCurCode - 1];
     1663                PRTDWARFABBREV pEntry = &pThis->paCachedAbbrevs[uCurCode - 1];
    15921664                while (pThis->cCachedAbbrevs < uCurCode)
    15931665                {
     
    16681740    }
    16691741
    1670     rtDwarfCursor_Delete(&Cursor);
     1742    rtDwarfCursor_Delete(&Cursor, VINF_SUCCESS);
    16711743    return pRet;
    16721744}
     
    16811753 * @param   uCode               The abbreviation code to lookup.
    16821754 */
    1683 static PCRTDBGMODDWARFABBREV rtDwarfAbbrev_Lookup(PRTDBGMODDWARF pThis, uint32_t uCode)
     1755static PCRTDWARFABBREV rtDwarfAbbrev_Lookup(PRTDBGMODDWARF pThis, uint32_t uCode)
    16841756{
    16851757    if (   uCode - 1 >= pThis->cCachedAbbrevs
     
    17111783/*
    17121784 *
     1785 * DWARF DIE stack (used by the debug_info parser).
     1786 * DWARF DIE stack (used by the debug_info parser).
     1787 * DWARF DIE stack (used by the debug_info parser).
     1788 *
     1789 */
     1790
     1791/**
     1792 * DWARF DIE stack entry.
     1793 */
     1794typedef struct RTDWARFDIESTACKENTRY
     1795{
     1796    /** The abbreviation code. */
     1797    uint32_t        uAbbrCode;
     1798    /** The tag. */
     1799    uint16_t        uTag;
     1800    /** The offset into the debug_info section of the data. */
     1801    uint32_t        offData;
     1802    /** The associated name. (Points into some dwarf section.) */
     1803    const char     *pszName;
     1804} RTDWARFDIESTACKENTRY;
     1805/** Pointer to a DIE stack entry. */
     1806typedef RTDWARFDIESTACKENTRY *PRTDWARFDIESTACKENTRY;
     1807
     1808/**
     1809 * DWARF DIE stack.
     1810 */
     1811typedef struct RTDWARFDIESTACK
     1812{
     1813    /** The number of items on the stack. */
     1814    uint32_t                cOnStack;
     1815    /** The number of stack entries we've allocated. */
     1816    uint32_t                cAlloced;
     1817    /** Pointer to the stack entries. */
     1818    PRTDWARFDIESTACKENTRY   paEntries;
     1819} RTDWARFDIESTACK;
     1820/** Pointer to a DIE stack. */
     1821typedef RTDWARFDIESTACK *PRTDWARFDIESTACK;
     1822/** Pointer to a const DIE stack. */
     1823typedef RTDWARFDIESTACK const *PCRTDWARFDIESTACK;
     1824
     1825
     1826static int rtDwarfDieStack_SetName(PRTDWARFDIESTACK pStack, const char *pszName)
     1827{
     1828    uint32_t i = pStack->cOnStack;
     1829    if (i == 0)
     1830        return VERR_DWARF_BAD_INFO;
     1831    i--;
     1832    pStack->paEntries[i].pszName = pszName;
     1833    return VINF_SUCCESS;
     1834}
     1835
     1836
     1837static int rtDwarfDieStack_Push(PRTDWARFDIESTACK pStack, uint32_t uAbbrCode, uint16_t uTag, uint32_t offData)
     1838{
     1839    uint32_t i = pStack->cOnStack;
     1840    if (i == pStack->cAlloced)
     1841    {
     1842        size_t cNewSize = pStack->cAlloced ? pStack->cAlloced * 2 : 1 /*16*/;
     1843        void *pv = RTMemRealloc(pStack->paEntries, sizeof(pStack->paEntries[0]) * cNewSize);
     1844        if (!pv)
     1845            return VERR_NO_MEMORY;
     1846        pStack->paEntries = (PRTDWARFDIESTACKENTRY)pv;
     1847        pStack->cAlloced  = cNewSize;
     1848    }
     1849    Assert(i < pStack->cAlloced);
     1850
     1851    pStack->paEntries[i].uAbbrCode = uAbbrCode;
     1852    pStack->paEntries[i].uTag      = uTag;
     1853    pStack->paEntries[i].offData   = offData;
     1854    pStack->paEntries[i].pszName   = NULL;
     1855    pStack->cOnStack = i + 1;
     1856
     1857    return VINF_SUCCESS;
     1858}
     1859
     1860
     1861static int rtDwarfDieStack_Pop(PRTDWARFDIESTACK pStack)
     1862{
     1863    if (pStack->cOnStack == 0)
     1864        return VERR_DWARF_BAD_INFO;
     1865    pStack->cOnStack--;
     1866    return VINF_SUCCESS;
     1867}
     1868
     1869
     1870static void rtDwarfDieStack_Init(PRTDWARFDIESTACK pStack)
     1871{
     1872    pStack->cOnStack  = 0;
     1873    pStack->cAlloced  = 0;
     1874    pStack->paEntries = NULL;
     1875}
     1876
     1877
     1878static void rtDwarfDieStack_Delete(PRTDWARFDIESTACK pStack)
     1879{
     1880    RTMemFree(pStack->paEntries);
     1881    pStack->paEntries = NULL;
     1882}
     1883
     1884
     1885
     1886/*
     1887 *
    17131888 * DWARF debug_info parser
    17141889 * DWARF debug_info parser
     
    17161891 *
    17171892 */
     1893
     1894
     1895/**
     1896 * Parse a DIE.
     1897 *
     1898 * @returns IPRT status code.
     1899 * @param   pThis               The DWARF instance.
     1900 * @param   pCursor             The debug_info cursor.
     1901 * @param   pAbbrev             The abbreviation entry.
     1902 * @param   pAbbrevCursor       The abbreviation cursor.
     1903 * @param   pStack              The DIE stack.
     1904 */
     1905static int rtDwarfInfo_ParseDie(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor,
     1906                                PCRTDWARFABBREV pAbbrev, PRTDWARFCURSOR pAbbrevCursor,
     1907                                PRTDWARFDIESTACK pStack)
     1908{
     1909    return VERR_NOT_IMPLEMENTED;
     1910}
     1911
    17181912
    17191913
     
    17421936
    17431937    /*
     1938     * We want a DIE stack as well.
     1939     */
     1940    RTDWARFDIESTACK Stack;
     1941    rtDwarfDieStack_Init(&Stack);
     1942
     1943    /*
    17441944     * Parse DIEs.
    17451945     */
     
    17471947    while (!rtDwarfCursor_IsAtEndOfUnit(pCursor))
    17481948    {
    1749         /** @todo The fun starts again here.  */
    1750         rtDwarfCursor_SkipUnit(pCursor);
    1751 
    1752         /*
    1753          * Check status codes before continuing.
    1754          */
    1755         if (RT_FAILURE(rc))
    1756             return rc;
    1757         if (RT_FAILURE(pCursor->rc))
    1758             return pCursor->rc;
    1759     }
    1760 
    1761     return rc;
     1949        uint32_t uAbbrCode = rtDwarfCursor_GetULeb128AsU32(pCursor, UINT32_MAX);
     1950
     1951        if (!uAbbrCode)
     1952        {
     1953            /* End of siblings, pop the stack. */
     1954            rc = rtDwarfDieStack_Pop(&Stack);
     1955            if (RT_FAILURE(rc))
     1956                break;
     1957        }
     1958        else
     1959        {
     1960            /*
     1961             * Look up the abbreviation.
     1962             */
     1963            PCRTDWARFABBREV pAbbrev = rtDwarfAbbrev_Lookup(pThis, uAbbrCode);
     1964            if (!pAbbrev)
     1965            {
     1966                rc = VERR_DWARF_ABBREV_NOT_FOUND;
     1967                break;
     1968            }
     1969
     1970            /*
     1971             * If this DIE has children, push it onto the stack.
     1972             */
     1973            if (pAbbrev->fChildren)
     1974            {
     1975                rc = rtDwarfDieStack_Push(&Stack, uAbbrCode, pAbbrev->uTag, rtDwarfCursor_CalcSectOffsetU32(pCursor));
     1976                if (RT_FAILURE(rc))
     1977                    break;
     1978            }
     1979
     1980            /*
     1981             * Parse it.
     1982             */
     1983            RTDWARFCURSOR AbbrevCursor;
     1984            rc = rtDwarfCursor_InitWithOffset(&AbbrevCursor, pThis, krtDbgModDwarfSect_abbrev, pAbbrev->offSpec);
     1985            if (RT_SUCCESS(rc))
     1986            {
     1987                rc = rtDwarfInfo_ParseDie(pThis, pCursor, pAbbrev, &AbbrevCursor, &Stack);
     1988                rc = rtDwarfCursor_Delete(&AbbrevCursor, rc);
     1989            }
     1990            if (RT_FAILURE(rc))
     1991                break;
     1992        }
     1993    }
     1994
     1995    rtDwarfDieStack_Delete(&Stack);
     1996    return RT_SUCCESS(rc) ? pCursor->rc : rc;
    17621997}
    17631998
     
    17822017        rc = rtDwarfInfo_LoadUnit(pThis, &Cursor);
    17832018
    1784     rtDwarfCursor_Delete(&Cursor);
    1785     return rc;
     2019    return rtDwarfCursor_Delete(&Cursor, rc);
    17862020}
    17872021
Note: See TracChangeset for help on using the changeset viewer.

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