VirtualBox

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


Ignore:
Timestamp:
Jul 9, 2013 4:02:56 PM (12 years ago)
Author:
vboxsync
Message:

RTLdrFlt,dwarf: Sequeeze more info out of the darwin kernel debug info.

File:
1 edited

Legend:

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

    r46916 r47057  
    241241#define DW_AT_linkage_name                  UINT16_C(0x006e)
    242242#define DW_AT_lo_user                       UINT16_C(0x2000)
     243/** Used by GCC and others, same as DW_AT_linkage_name. See http://wiki.dwarfstd.org/index.php?title=DW_AT_linkage_name*/
     244#define DW_AT_MIPS_linkage_name             UINT16_C(0x2007)
    243245#define DW_AT_hi_user                       UINT16_C(0x3fff)
    244246/** @} */
     
    598600{
    599601    /** The attribute. */
    600     uint8_t                 uAttr;
     602    uint16_t                uAttr;
     603    /** The data member offset. */
     604    uint16_t                off;
    601605    /** The data member size and initialization method. */
    602606    uint8_t                 cbInit;
    603     /** The data member offset. */
    604     uint16_t                off;
     607    uint8_t                 bPadding[3]; /**< Alignment padding. */
    605608    /** The decoder function. */
    606609    PFNRTDWARFATTRDECODER   pfnDecoder;
     
    611614    { \
    612615        a_uAttr, \
     616        (uint16_t)RT_OFFSETOF(a_Struct, a_Member), \
    613617        a_Init | ((uint8_t)RT_SIZEOFMEMB(a_Struct, a_Member) & ATTR_SIZE_MASK), \
    614         (uint16_t)RT_OFFSETOF(a_Struct, a_Member), \
     618        { 0, 0, 0 }, \
    615619        a_pfnDecoder\
    616620    }
     
    848852    /** Segment number (watcom). */
    849853    RTSEL               uSegment;
     854    /** Reference to the specification. */
     855    RTDWARFREF          SpecRef;
    850856} RTDWARFDIESUBPROGRAM;
    851857/** Pointer to a DW_TAG_subprogram DIE.  */
     
    860866    ATTR_ENTRY(DW_AT_name,              RTDWARFDIESUBPROGRAM, pszName,        ATTR_INIT_ZERO, rtDwarfDecode_String),
    861867    ATTR_ENTRY(DW_AT_linkage_name,      RTDWARFDIESUBPROGRAM, pszLinkageName, ATTR_INIT_ZERO, rtDwarfDecode_String),
     868    ATTR_ENTRY(DW_AT_MIPS_linkage_name, RTDWARFDIESUBPROGRAM, pszLinkageName, ATTR_INIT_ZERO, rtDwarfDecode_String),
    862869    ATTR_ENTRY(DW_AT_low_pc,            RTDWARFDIESUBPROGRAM, PcRange,        ATTR_INIT_ZERO, rtDwarfDecode_LowHighPc),
    863870    ATTR_ENTRY(DW_AT_high_pc,           RTDWARFDIESUBPROGRAM, PcRange,        ATTR_INIT_ZERO, rtDwarfDecode_LowHighPc),
    864871    ATTR_ENTRY(DW_AT_ranges,            RTDWARFDIESUBPROGRAM, PcRange,        ATTR_INIT_ZERO, rtDwarfDecode_Ranges),
    865872    ATTR_ENTRY(DW_AT_entry_pc,          RTDWARFDIESUBPROGRAM, EntryPc,        ATTR_INIT_ZERO, rtDwarfDecode_Address),
    866     ATTR_ENTRY(DW_AT_segment,           RTDWARFDIESUBPROGRAM, uSegment,       ATTR_INIT_ZERO, rtDwarfDecode_SegmentLoc)
     873    ATTR_ENTRY(DW_AT_segment,           RTDWARFDIESUBPROGRAM, uSegment,       ATTR_INIT_ZERO, rtDwarfDecode_SegmentLoc),
     874    ATTR_ENTRY(DW_AT_specification,     RTDWARFDIESUBPROGRAM, SpecRef,        ATTR_INIT_ZERO, rtDwarfDecode_Reference)
    867875};
    868876
    869877/** RTDWARFDIESUBPROGRAM description. */
    870878static const RTDWARFDIEDESC g_SubProgramDesc = DIE_DESC_INIT(RTDWARFDIESUBPROGRAM, g_aSubProgramAttrs);
     879
     880
     881/** RTDWARFDIESUBPROGRAM attributes for the specification hack. */
     882static const RTDWARFATTRDESC g_aSubProgramSpecHackAttrs[] =
     883{
     884    ATTR_ENTRY(DW_AT_name,              RTDWARFDIESUBPROGRAM, pszName,        ATTR_INIT_ZERO, rtDwarfDecode_String),
     885    ATTR_ENTRY(DW_AT_linkage_name,      RTDWARFDIESUBPROGRAM, pszLinkageName, ATTR_INIT_ZERO, rtDwarfDecode_String),
     886    ATTR_ENTRY(DW_AT_MIPS_linkage_name, RTDWARFDIESUBPROGRAM, pszLinkageName, ATTR_INIT_ZERO, rtDwarfDecode_String),
     887};
     888
     889/** RTDWARFDIESUBPROGRAM description for the specification hack. */
     890static const RTDWARFDIEDESC g_SubProgramSpecHackDesc = DIE_DESC_INIT(RTDWARFDIESUBPROGRAM, g_aSubProgramSpecHackAttrs);
    871891
    872892
     
    9941014#undef TAGDESC_CORE
    9951015};
     1016
     1017
     1018/*******************************************************************************
     1019*   Internal Functions                                                         *
     1020*******************************************************************************/
     1021static int rtDwarfInfo_ParseDie(PRTDBGMODDWARF pThis, PRTDWARFDIE pDie, PCRTDWARFDIEDESC pDieDesc,
     1022                                PRTDWARFCURSOR pCursor, PCRTDWARFABBREV pAbbrev, bool fInitDie);
     1023
    9961024
    9971025
     
    11211149        RT_CASE_RET_STR(DW_AT_enum_class);
    11221150        RT_CASE_RET_STR(DW_AT_linkage_name);
     1151        RT_CASE_RET_STR(DW_AT_MIPS_linkage_name);
    11231152    }
    11241153    static char s_szStatic[32];
     
    11921221{
    11931222    PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pvUser;
    1194     Log(("Segment %.*s: LinkAddress=%#llx RVA=%#llx cb=%#llx\n",
    1195          pSeg->cchName, pSeg->pszName, (uint64_t)pSeg->LinkAddress, (uint64_t)pSeg->RVA, pSeg->cb));
     1223    Log(("Segment %.*s: LinkAddress=%#llx RVA=%#llx cb=%#llx cbMapped=%#llx\n",
     1224         pSeg->cchName, pSeg->pszName, (uint64_t)pSeg->LinkAddress, (uint64_t)pSeg->RVA, pSeg->cb, pSeg->cbMapped));
    11961225    NOREF(hLdrMod);
    11971226    Assert(pSeg->cchName > 0);
     
    32193248    /* Decode it. */
    32203249    uint64_t        off;
    3221     krtDwarfRef     enmWrt = krtDwarfRef_InfoSection;
     3250    krtDwarfRef     enmWrt = krtDwarfRef_SameUnit;
    32223251    switch (uForm)
    32233252    {
     
    36773706
    36783707/**
     3708 * Special hack to get the name and/or linkage name for a subprogram via a
     3709 * specification reference.
     3710 *
     3711 * Since this is a hack, we ignore failure.
     3712 *
     3713 * If we want to really make use of DWARF info, we'll have to create some kind
     3714 * of lookup tree for handling this. But currently we don't, so a hack will
     3715 * suffice.
     3716 *
     3717 * @param   pThis               The DWARF instance.
     3718 * @param   pSubProgram         The subprogram which is short on names.
     3719 */
     3720static void rtDwarfInfo_TryGetSubProgramNameFromSpecRef(PRTDBGMODDWARF pThis, PRTDWARFDIESUBPROGRAM pSubProgram)
     3721{
     3722    /*
     3723     * Must have a spec ref, and it must be in the info section.
     3724     */
     3725    if (pSubProgram->SpecRef.enmWrt != krtDwarfRef_InfoSection)
     3726        return;
     3727
     3728    /*
     3729     * Create a cursor for reading the info and then the abbrivation code
     3730     * starting the off the DIE.
     3731     */
     3732    RTDWARFCURSOR InfoCursor;
     3733    int rc = rtDwarfCursor_InitWithOffset(&InfoCursor, pThis, krtDbgModDwarfSect_info, pSubProgram->SpecRef.off);
     3734    if (RT_FAILURE(rc))
     3735        return;
     3736
     3737    uint32_t uAbbrCode = rtDwarfCursor_GetULeb128AsU32(&InfoCursor, UINT32_MAX);
     3738    if (uAbbrCode)
     3739    {
     3740        /* Only references to subprogram tags are interesting here. */
     3741        PCRTDWARFABBREV pAbbrev = rtDwarfAbbrev_Lookup(pThis, uAbbrCode);
     3742        if (   pAbbrev
     3743            && pAbbrev->uTag == DW_TAG_subprogram)
     3744        {
     3745            /*
     3746             * Use rtDwarfInfo_ParseDie to do the parsing, but with a different
     3747             * attribute spec than usual.
     3748             */
     3749            rtDwarfInfo_ParseDie(pThis, &pSubProgram->Core, &g_SubProgramSpecHackDesc, &InfoCursor,
     3750                                 pAbbrev, false /*fInitDie*/);
     3751        }
     3752    }
     3753
     3754    rtDwarfCursor_Delete(&InfoCursor, VINF_SUCCESS);
     3755}
     3756
     3757
     3758/**
     3759 * Select which name to use.
     3760 *
     3761 * @returns One of the names.
     3762 * @param   pszName             The DWARF name, may exclude namespace and class.
     3763 *                              Can also be NULL.
     3764 * @param   pszLinkageName      The linkage name. Can be NULL.
     3765 */
     3766static const char *rtDwarfInfo_SelectName(const char *pszName,  const char *pszLinkageName)
     3767{
     3768    if (!pszName || !pszLinkageName)
     3769        return pszName ? pszName : pszLinkageName;
     3770
     3771    /*
     3772     * Some heuristics for selecting the link name if the normal name is missing
     3773     * namespace or class prefixes.
     3774     */
     3775    size_t cchName = strlen(pszName);
     3776    size_t cchLinkageName = strlen(pszLinkageName);
     3777    if (cchLinkageName <= cchName + 1)
     3778        return pszName;
     3779
     3780    const char *psz = strstr(pszLinkageName, pszName);
     3781    if (!psz || psz - pszLinkageName < 4)
     3782        return pszName;
     3783
     3784    return pszLinkageName;
     3785}
     3786
     3787
     3788/**
    36793789 * Parse the attributes of a DIE.
    36803790 *
     
    36903800        case DW_TAG_subprogram:
    36913801        {
    3692             PCRTDWARFDIESUBPROGRAM pSubProgram = (PCRTDWARFDIESUBPROGRAM)pDie;
     3802            PRTDWARFDIESUBPROGRAM pSubProgram = (PRTDWARFDIESUBPROGRAM)pDie;
     3803
     3804            /* Obtain referenced specification there is only partial info. */
     3805            if (   pSubProgram->PcRange.cAttrs
     3806                && !pSubProgram->pszName)
     3807                rtDwarfInfo_TryGetSubProgramNameFromSpecRef(pThis, pSubProgram);
     3808
    36933809            if (pSubProgram->PcRange.cAttrs)
    36943810            {
     
    37003816                          pSubProgram->PcRange.uLowAddress, pSubProgram->PcRange.uHighAddress,
    37013817                          pSubProgram->PcRange.cAttrs == 2 ? "" : " !bad!"));
    3702                     if (   pSubProgram->pszName
     3818                    if (   ( pSubProgram->pszName || pSubProgram->pszLinkageName)
    37033819                        && pSubProgram->PcRange.cAttrs == 2)
    37043820                    {
     
    37143830                            if (RT_SUCCESS(rc))
    37153831                            {
    3716                                 rc = RTDbgModSymbolAdd(pThis->hCnt, pSubProgram->pszName, iSeg, offSeg,
     3832                                rc = RTDbgModSymbolAdd(pThis->hCnt,
     3833                                                       rtDwarfInfo_SelectName(pSubProgram->pszName, pSubProgram->pszLinkageName),
     3834                                                       iSeg, offSeg,
    37173835                                                       pSubProgram->PcRange.uHighAddress - pSubProgram->PcRange.uLowAddress,
    37183836                                                       0 /*fFlags*/, NULL /*piOrdinal*/);
     
    40104128 * @param   pCursor             The debug_info cursor.
    40114129 * @param   pAbbrev             The abbreviation cache entry.
     4130 * @param   fInitDie            Whether to initialize the DIE first.  If not (@c
     4131 *                              false) it's safe to assume we're following a
     4132 *                              DW_AT_specification or DW_AT_abstract_origin,
     4133 *                              and that we shouldn't be snooping any symbols.
    40124134 */
    40134135static int rtDwarfInfo_ParseDie(PRTDBGMODDWARF pThis, PRTDWARFDIE pDie, PCRTDWARFDIEDESC pDieDesc,
    4014                                 PRTDWARFCURSOR pCursor, PCRTDWARFABBREV pAbbrev)
     4136                                PRTDWARFCURSOR pCursor, PCRTDWARFABBREV pAbbrev, bool fInitDie)
    40154137{
    40164138    RTDWARFCURSOR AbbrevCursor;
     
    40194141        return rc;
    40204142
    4021     rtDwarfInfo_InitDie(pDie, pDieDesc);
     4143    if (fInitDie)
     4144        rtDwarfInfo_InitDie(pDie, pDieDesc);
    40224145    for (;;)
    40234146    {
     
    40604183     * Snoop up symbols on the way out.
    40614184     */
    4062     if (RT_SUCCESS(rc))
     4185    if (RT_SUCCESS(rc) && fInitDie)
    40634186    {
    40644187        rc = rtDwarfInfo_SnoopSymbols(pThis, pDie);
     
    41434266    RTListAppend(&pThis->CompileUnitList, &pUnit->Core.SiblingNode);
    41444267
    4145     int rc = rtDwarfInfo_ParseDie(pThis, &pUnit->Core, &g_CompileUnitDesc, pCursor, pAbbrev);
     4268    int rc = rtDwarfInfo_ParseDie(pThis, &pUnit->Core, &g_CompileUnitDesc, pCursor, pAbbrev, true /*fInitDie*/);
    41464269    if (RT_FAILURE(rc))
    41474270        return rc;
     
    42204343            }
    42214344
    4222             rc = rtDwarfInfo_ParseDie(pThis, pNewDie, pDieDesc, pCursor, pAbbrev);
     4345            rc = rtDwarfInfo_ParseDie(pThis, pNewDie, pDieDesc, pCursor, pAbbrev, true /*fInitDie*/);
    42234346            if (RT_FAILURE(rc))
    42244347                return rc;
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