VirtualBox

Changeset 38619 in vbox


Ignore:
Timestamp:
Sep 3, 2011 7:51:02 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
73826
Message:

IPRT: More dwarf reading.

Location:
trunk/src/VBox/Runtime
Files:
2 edited

Legend:

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

    r38617 r38619  
    503503 * @{ */
    504504#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)
     505#define ATTR_INIT_FFFS      UINT8_C(0x80)
     506#define ATTR_INIT_MASK      UINT8_C(0x80)
    509507#define ATTR_SIZE_MASK      UINT8_C(0x3f)
    510508#define ATTR_GET_SIZE(a_pAttrDesc)   ((a_pAttrDesc)->cbInit & ATTR_SIZE_MASK)
     
    517515typedef struct RTDWARFDIEDESC
    518516{
     517    /** The size of the DIE. */
     518    size_t              cbDie;
    519519    /** The number of attributes. */
    520520    size_t              cAttributes;
     
    523523} RTDWARFDIEDESC;
    524524typedef struct RTDWARFDIEDESC const *PCRTDWARFDIEDESC;
     525/** DIE descriptor initializer.  */
     526#define DIE_DESC_INIT(a_Type, a_aAttrs)  { sizeof(a_Type), RT_ELEMENTS(a_aAttrs), &a_aAttrs[0] }
    525527
    526528
     
    555557    uint64_t            uAddress;
    556558} RTDWARFADDR;
     559typedef RTDWARFADDR *PRTDWARFADDR;
     560typedef RTDWARFADDR const *PCRTDWARFADDR;
    557561
    558562
     
    565569    uint64_t            uHighAddress;
    566570    uint8_t const      *pbRanges; /* ?? */
    567     bool                fHaveLowAddress  : 1;
    568     bool                fHaveHighAddress : 1;
    569     bool                fHaveRanges      : 1;
     571    uint8_t             cAttrs           : 2;
     572    uint8_t             fHaveLowAddress  : 1;
     573    uint8_t             fHaveHighAddress : 1;
     574    uint8_t             fHaveRanges      : 1;
    570575} RTDWARFADDRRANGE;
    571576typedef RTDWARFADDRRANGE *PRTDWARFADDRRANGE;
     
    602607*   Internal Functions                                                         *
    603608*******************************************************************************/
     609static FNRTDWARFATTRDECODER rtDwarfDecode_Address;
    604610static FNRTDWARFATTRDECODER rtDwarfDecode_Bool;
    605611static FNRTDWARFATTRDECODER rtDwarfDecode_LowHighPc;
     
    614620*   Global Variables                                                           *
    615621*******************************************************************************/
     622/** RTDWARFDIE description. */
     623static const RTDWARFDIEDESC g_CoreDieDesc = { sizeof(RTDWARFDIE), 0, NULL };
     624
     625
    616626/**
    617627 * DW_TAG_compile_unit & DW_TAG_partial_unit.
     
    666676{
    667677    ATTR_ENTRY(DW_AT_name,              RTDWARFDIECOMPILEUNIT, pszName,        ATTR_INIT_ZERO, rtDwarfDecode_String),
     678    ATTR_ENTRY(DW_AT_low_pc,            RTDWARFDIECOMPILEUNIT, PcRange,        ATTR_INIT_ZERO, rtDwarfDecode_LowHighPc),
    668679    ATTR_ENTRY(DW_AT_high_pc,           RTDWARFDIECOMPILEUNIT, PcRange,        ATTR_INIT_ZERO, rtDwarfDecode_LowHighPc),
    669680    ATTR_ENTRY(DW_AT_ranges,            RTDWARFDIECOMPILEUNIT, PcRange,        ATTR_INIT_ZERO, rtDwarfDecode_Ranges),
    670681    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),
     682    ATTR_ENTRY(DW_AT_macro_info,        RTDWARFDIECOMPILEUNIT, MacroInfoRef,   ATTR_INIT_ZERO, rtDwarfDecode_SectOff),
     683    ATTR_ENTRY(DW_AT_stmt_list,         RTDWARFDIECOMPILEUNIT, StmtListRef,    ATTR_INIT_ZERO, rtDwarfDecode_SectOff),
    673684    ATTR_ENTRY(DW_AT_comp_dir,          RTDWARFDIECOMPILEUNIT, pszCurDir,      ATTR_INIT_ZERO, rtDwarfDecode_String),
    674685    ATTR_ENTRY(DW_AT_producer,          RTDWARFDIECOMPILEUNIT, pszProducer,    ATTR_INIT_ZERO, rtDwarfDecode_String),
     
    680691
    681692/** RTDWARFDIECOMPILEUNIT description. */
    682 static 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 
     693static const RTDWARFDIEDESC g_CompileUnitDesc = DIE_DESC_INIT(RTDWARFDIECOMPILEUNIT, g_aCompileUnitAttrs);
     694
     695
     696/**
     697 * DW_TAG_subprogram.
     698 */
     699typedef struct RTDWARFDIESUBPROGRAM
     700{
     701    /** The DIE core structure. */
     702    RTDWARFDIE          Core;
     703    /** The name. */
     704    const char         *pszName;
     705    /** The linkage name. */
     706    const char         *pszLinkageName;
     707    /** The address range of the code belonging to this unit. */
     708    RTDWARFADDRRANGE    PcRange;
     709    /** The first instruction in the function. */
     710    RTDWARFADDR         EntryPc;
     711} RTDWARFDIESUBPROGRAM;
     712/** Pointer to a DW_TAG_subprogram DIE.  */
     713typedef RTDWARFDIESUBPROGRAM *PRTDWARFDIESUBPROGRAM;
     714/** Pointer to a const DW_TAG_subprogram DIE.  */
     715typedef RTDWARFDIESUBPROGRAM const *PCRTDWARFDIESUBPROGRAM;
     716
     717
     718/** RTDWARFDIESUBPROGRAM attributes. */
     719static const RTDWARFATTRDESC g_aSubProgramAttrs[] =
     720{
     721    ATTR_ENTRY(DW_AT_name,              RTDWARFDIESUBPROGRAM, pszName,        ATTR_INIT_ZERO, rtDwarfDecode_String),
     722    ATTR_ENTRY(DW_AT_linkage_name,      RTDWARFDIESUBPROGRAM, pszLinkageName, ATTR_INIT_ZERO, rtDwarfDecode_String),
     723    ATTR_ENTRY(DW_AT_low_pc,            RTDWARFDIESUBPROGRAM, PcRange,        ATTR_INIT_ZERO, rtDwarfDecode_LowHighPc),
     724    ATTR_ENTRY(DW_AT_high_pc,           RTDWARFDIESUBPROGRAM, PcRange,        ATTR_INIT_ZERO, rtDwarfDecode_LowHighPc),
     725    ATTR_ENTRY(DW_AT_ranges,            RTDWARFDIESUBPROGRAM, PcRange,        ATTR_INIT_ZERO, rtDwarfDecode_Ranges),
     726    ATTR_ENTRY(DW_AT_entry_pc,          RTDWARFDIESUBPROGRAM, EntryPc,        ATTR_INIT_ZERO, rtDwarfDecode_Address),
     727};
     728
     729/** RTDWARFDIESUBPROGRAM description. */
     730static const RTDWARFDIEDESC g_SubProgramDesc = DIE_DESC_INIT(RTDWARFDIESUBPROGRAM, g_aSubProgramAttrs);
     731
     732
     733/**
     734 * Tag names and descriptors.
     735 */
     736static const struct RTDWARFTAGDESC
     737{
     738    /** The tag value.  */
     739    uint16_t            uTag;
     740    /** The tag name as string. */
     741    const char         *pszName;
     742    /** The DIE descriptor to use. */
     743    PCRTDWARFDIEDESC    pDesc;
     744}   g_aTagDescs[] =
     745{
     746#define TAGDESC(a_Name, a_pDesc)        { DW_ ## a_Name, #a_Name, a_pDesc }
     747#define TAGDESC_EMPTY()                 { 0, NULL, NULL }
     748#define TAGDESC_CORE(a_Name)            TAGDESC(a_Name, &g_CoreDieDesc)
     749    TAGDESC_EMPTY(),                            /* 0x00 */
     750    TAGDESC_CORE(TAG_array_type),
     751    TAGDESC_CORE(TAG_class_type),
     752    TAGDESC_CORE(TAG_entry_point),
     753    TAGDESC_CORE(TAG_enumeration_type),         /* 0x04 */
     754    TAGDESC_CORE(TAG_formal_parameter),
     755    TAGDESC_EMPTY(),
     756    TAGDESC_EMPTY(),
     757    TAGDESC_CORE(TAG_imported_declaration),     /* 0x08 */
     758    TAGDESC_EMPTY(),
     759    TAGDESC_CORE(TAG_label),
     760    TAGDESC_CORE(TAG_lexical_block),
     761    TAGDESC_EMPTY(),                            /* 0x0c */
     762    TAGDESC_CORE(TAG_member),
     763    TAGDESC_EMPTY(),
     764    TAGDESC_CORE(TAG_pointer_type),
     765    TAGDESC_CORE(TAG_reference_type),           /* 0x10 */
     766    TAGDESC_CORE(TAG_compile_unit),
     767    TAGDESC_CORE(TAG_string_type),
     768    TAGDESC_CORE(TAG_structure_type),
     769    TAGDESC_EMPTY(),                            /* 0x14 */
     770    TAGDESC_CORE(TAG_subroutine_type),
     771    TAGDESC_CORE(TAG_typedef),
     772    TAGDESC_CORE(TAG_union_type),
     773    TAGDESC_CORE(TAG_unspecified_parameters),   /* 0x18 */
     774    TAGDESC_CORE(TAG_variant),
     775    TAGDESC_CORE(TAG_common_block),
     776    TAGDESC_CORE(TAG_common_inclusion),
     777    TAGDESC_CORE(TAG_inheritance),              /* 0x1c */
     778    TAGDESC_CORE(TAG_inlined_subroutine),
     779    TAGDESC_CORE(TAG_module),
     780    TAGDESC_CORE(TAG_ptr_to_member_type),
     781    TAGDESC_CORE(TAG_set_type),                 /* 0x20 */
     782    TAGDESC_CORE(TAG_subrange_type),
     783    TAGDESC_CORE(TAG_with_stmt),
     784    TAGDESC_CORE(TAG_access_declaration),
     785    TAGDESC_CORE(TAG_base_type),                /* 0x24 */
     786    TAGDESC_CORE(TAG_catch_block),
     787    TAGDESC_CORE(TAG_const_type),
     788    TAGDESC_CORE(TAG_constant),
     789    TAGDESC_CORE(TAG_enumerator),               /* 0x28 */
     790    TAGDESC_CORE(TAG_file_type),
     791    TAGDESC_CORE(TAG_friend),
     792    TAGDESC_CORE(TAG_namelist),
     793    TAGDESC_CORE(TAG_namelist_item),            /* 0x2c */
     794    TAGDESC_CORE(TAG_packed_type),
     795    TAGDESC(TAG_subprogram, &g_SubProgramDesc),
     796    TAGDESC_CORE(TAG_template_type_parameter),
     797    TAGDESC_CORE(TAG_template_value_parameter), /* 0x30 */
     798    TAGDESC_CORE(TAG_thrown_type),
     799    TAGDESC_CORE(TAG_try_block),
     800    TAGDESC_CORE(TAG_variant_part),
     801    TAGDESC_CORE(TAG_variable),                 /* 0x34 */
     802    TAGDESC_CORE(TAG_volatile_type),
     803    TAGDESC_CORE(TAG_dwarf_procedure),
     804    TAGDESC_CORE(TAG_restrict_type),
     805    TAGDESC_CORE(TAG_interface_type),           /* 0x38 */
     806    TAGDESC_CORE(TAG_namespace),
     807    TAGDESC_CORE(TAG_imported_module),
     808    TAGDESC_CORE(TAG_unspecified_type),
     809    TAGDESC_CORE(TAG_partial_unit),             /* 0x3c */
     810    TAGDESC_CORE(TAG_imported_unit),
     811    TAGDESC_EMPTY(),
     812    TAGDESC_CORE(TAG_condition),
     813    TAGDESC_CORE(TAG_shared_type),              /* 0x40 */
     814    TAGDESC_CORE(TAG_type_unit),
     815    TAGDESC_CORE(TAG_rvalue_reference_type),
     816    TAGDESC_CORE(TAG_template_alias)
     817#undef TAGDESC
     818#undef TAGDESC_EMPTY
     819#undef TAGDESC_CORE
     820};
    751821
    752822
     
    23602430
    23612431/** @callback_method_impl{FNRTDWARFATTRDECODER} */
     2432static DECLCALLBACK(int) rtDwarfDecode_Address(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc,
     2433                                               uint32_t uForm, PRTDWARFCURSOR pCursor)
     2434{
     2435    AssertReturn(ATTR_GET_SIZE(pDesc) == sizeof(RTDWARFADDR), VERR_INTERNAL_ERROR_3);
     2436
     2437    uint64_t uAddr;
     2438    switch (uForm)
     2439    {
     2440        case DW_FORM_addr:  uAddr = rtDwarfCursor_GetNativeUOff(pCursor, 0); break;
     2441        case DW_FORM_data1: uAddr = rtDwarfCursor_GetU8(pCursor, 0); break;
     2442        case DW_FORM_data2: uAddr = rtDwarfCursor_GetU16(pCursor, 0); break;
     2443        case DW_FORM_data4: uAddr = rtDwarfCursor_GetU32(pCursor, 0); break;
     2444        case DW_FORM_data8: uAddr = rtDwarfCursor_GetU64(pCursor, 0); break;
     2445        case DW_FORM_udata: uAddr = rtDwarfCursor_GetULeb128(pCursor, 0); break;
     2446        default:
     2447            AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM);
     2448    }
     2449    if (RT_FAILURE(pCursor->rc))
     2450        return pCursor->rc;
     2451
     2452    PRTDWARFADDR pAddr = (PRTDWARFADDR)pbMember;
     2453    pAddr->uAddress = uAddr;
     2454
     2455    return VINF_SUCCESS;
     2456}
     2457
     2458
     2459/** @callback_method_impl{FNRTDWARFATTRDECODER} */
    23622460static DECLCALLBACK(int) rtDwarfDecode_Bool(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc,
    23632461                                            uint32_t uForm, PRTDWARFCURSOR pCursor)
     
    24142512    if (pDesc->uAttr == DW_AT_low_pc)
    24152513    {
     2514        if (pRange->fHaveLowAddress)
     2515        {
     2516            Log(("rtDwarfDecode_LowHighPc: Duplicate DW_AT_low_pc\n"));
     2517            return pCursor->rc = VERR_DWARF_BAD_INFO;
     2518        }
     2519        pRange->fHaveLowAddress  = true;
    24162520        pRange->uLowAddress      = uAddr;
    2417         pRange->fHaveLowAddress  = true;
    24182521    }
    24192522    else
    24202523    {
     2524        if (pRange->fHaveHighAddress)
     2525        {
     2526            Log(("rtDwarfDecode_LowHighPc: Duplicate DW_AT_high_pc\n"));
     2527            return pCursor->rc = VERR_DWARF_BAD_INFO;
     2528        }
     2529        pRange->fHaveHighAddress = true;
    24212530        pRange->uHighAddress     = uAddr;
    2422         pRange->fHaveHighAddress = true;
    2423     }
     2531    }
     2532    pRange->cAttrs++;
    24242533
    24252534    return VINF_SUCCESS;
     
    24502559    PRTDBGMODDWARF pThis = pCursor->pDwarfMod;
    24512560    if (off >= pThis->aSections[krtDbgModDwarfSect_ranges].cb)
     2561    {
     2562        Log(("rtDwarfDecode_Ranges: bad ranges off=%#llx\n", off));
    24522563        return pCursor->rc = VERR_DWARF_BAD_POS;
     2564    }
    24532565
    24542566    if (!pThis->aSections[krtDbgModDwarfSect_ranges].pv)
     
    24612573    /* Store the result. */
    24622574    PRTDWARFADDRRANGE pRange = (PRTDWARFADDRRANGE)pbMember;
     2575    if (pRange->fHaveRanges)
     2576    {
     2577        Log(("rtDwarfDecode_Ranges: Duplicate DW_AT_ranges\n"));
     2578        return pCursor->rc = VERR_DWARF_BAD_INFO;
     2579    }
     2580    pRange->fHaveRanges = true;
     2581    pRange->cAttrs++;
    24632582    pRange->pbRanges    = (uint8_t const *)pThis->aSections[krtDbgModDwarfSect_ranges].pv + (size_t)off;
    2464     pRange->fHaveRanges = true;
    24652583
    24662584    return VINF_SUCCESS;
     
    25052623    {
    25062624        if (off >= pCursor->pDwarfMod->aSections[krtDbgModDwarfSect_info].cb)
     2625        {
     2626            Log(("rtDwarfDecode_Reference: bad info off=%#llx\n", off));
    25072627            return pCursor->rc = VERR_DWARF_BAD_POS;
     2628        }
    25082629    }
    25092630    else if (enmWrt == krtDwarfRef_SameUnit)
     
    25112632        PRTDWARFDIECOMPILEUNIT pUnit = rtDwarfDie_GetCompileUnit(pDie);
    25122633        if (off >= pUnit->cbUnit)
     2634        {
     2635            Log(("rtDwarfDecode_Reference: bad unit off=%#llx\n", off));
    25132636            return pCursor->rc = VERR_DWARF_BAD_POS;
     2637        }
    25142638        off += pUnit->offUnit;
    25152639        enmWrt = krtDwarfRef_InfoSection;
     
    25352659    switch (uForm)
    25362660    {
    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;
     2661        case DW_FORM_data4:      off = rtDwarfCursor_GetU32(pCursor, 0); break;
     2662        case DW_FORM_data8:      off = rtDwarfCursor_GetU64(pCursor, 0); break;
     2663        case DW_FORM_sec_offset: off = rtDwarfCursor_GetUOff(pCursor, 0); break;
    25402664        default:
    25412665            AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM);
     
    25482672    switch (pDesc->uAttr)
    25492673    {
    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;
     2674        case DW_AT_stmt_list:   enmSect = krtDbgModDwarfSect_line;    enmWrt = krtDwarfRef_LineSection;    break;
     2675        case DW_AT_macro_info:  enmSect = krtDbgModDwarfSect_loc;     enmWrt = krtDwarfRef_LocSection;     break;
    25522676        case DW_AT_ranges:      enmSect = krtDbgModDwarfSect_ranges;  enmWrt = krtDwarfRef_RangesSection;  break;
    25532677        default:                AssertMsgFailedReturn(("%u\n", pDesc->uAttr), VERR_INTERNAL_ERROR_4);
    25542678    }
    2555     if (off > pCursor->pDwarfMod->aSections[enmSect].cb)
     2679    if (off >= pCursor->pDwarfMod->aSections[enmSect].cb)
     2680    {
     2681        Log(("rtDwarfDecode_SectOff: bad off=%#llx, attr %#x\n", off, pDesc->uAttr));
    25562682        return pCursor->rc = VERR_DWARF_BAD_POS;
     2683    }
    25572684
    25582685    PRTDWARFREF pRef = (PRTDWARFREF)pbMember;
     
    26492776
    26502777
    2651 
    2652 static const char *rtDwarfForm_GetString(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor, uint16_t uForm, const char *pszErrValue)
    2653 {
    2654     switch (uForm)
    2655     {
    2656         case DW_FORM_string:
    2657             return rtDwarfCursor_GetSZ(pCursor, pszErrValue);
    2658 
    2659         case DW_FORM_strp:
    2660             return rtDwarfDecode_GetStrp(pThis, pCursor, pszErrValue);
    2661 
    2662         default:
    2663             pCursor->rc = VERR_DWARF_UNEXPECTED_FORM;
    2664             return pszErrValue;
     2778/**
     2779 * Parse the attributes of a DIE.
     2780 *
     2781 * @returns IPRT status code.
     2782 * @param   pThis               The DWARF instance.
     2783 * @param   pDie                The internal DIE structure to fill.
     2784 */
     2785static int rtDwarfInfo_SnoopSymbols(PRTDBGMODDWARF pThis, PRTDWARFDIE pDie)
     2786{
     2787    int rc = VINF_SUCCESS;
     2788    switch (pDie->uTag)
     2789    {
     2790        case DW_TAG_subprogram:
     2791        {
     2792            PCRTDWARFDIESUBPROGRAM pSubProgram = (PCRTDWARFDIESUBPROGRAM)pDie;
     2793            if (pSubProgram->PcRange.cAttrs)
     2794            {
     2795                if (pSubProgram->PcRange.fHaveRanges)
     2796                    Log5(("subprogram %s (%s) <implement ranges>\n", pSubProgram->pszName, pSubProgram->pszLinkageName));
     2797                else
     2798                {
     2799                    Log5(("subprogram %s (%s) %#llx-%#llx%s\n", pSubProgram->pszName, pSubProgram->pszLinkageName,
     2800                          pSubProgram->PcRange.uLowAddress, pSubProgram->PcRange.uHighAddress,
     2801                          pSubProgram->PcRange.cAttrs == 2 ? "" : " !bad!"));
     2802                    if (   pSubProgram->pszName
     2803                        && pSubProgram->PcRange.cAttrs == 2)
     2804                    {
     2805                        RTDBGSEGIDX iSeg;
     2806                        RTUINTPTR   offSeg;
     2807                        rc = rtDbgModDwarfLinkAddressToSegOffset(pThis, pSubProgram->PcRange.uLowAddress,
     2808                                                                 &iSeg, &offSeg);
     2809                        if (RT_SUCCESS(rc))
     2810                            rc = RTDbgModSymbolAdd(pThis->hCnt, pSubProgram->pszName, iSeg, offSeg,
     2811                                                   pSubProgram->PcRange.uHighAddress - pSubProgram->PcRange.uLowAddress,
     2812                                                   0 /*fFlags*/, NULL /*piOrdinal*/);
     2813                        else
     2814                            Log5(("rtDbgModDwarfLinkAddressToSegOffset failed: %Rrc\n", rc));
     2815                    }
     2816                }
     2817            }
     2818            else
     2819                Log5(("subprogram %s (%s) external\n", pSubProgram->pszName, pSubProgram->pszLinkageName));
     2820            break;
     2821        }
     2822
     2823    }
     2824    return rc;
     2825}
     2826
     2827
     2828/**
     2829 * Initializes the non-core fields of an internal  DIE structure.
     2830 *
     2831 * @param   pDie                The DIE structure.
     2832 * @param   pDieDesc            The DIE descriptor.
     2833 */
     2834static void rtDwarfInfo_InitDie(PRTDWARFDIE pDie, PCRTDWARFDIEDESC pDieDesc)
     2835{
     2836    uint32_t i = pDieDesc->cAttributes;
     2837    while (i-- > 0)
     2838    {
     2839        switch (pDieDesc->paAttributes[i].cbInit & ATTR_INIT_MASK)
     2840        {
     2841            case ATTR_INIT_ZERO:
     2842                /* Nothing to do (RTMemAllocZ). */
     2843                break;
     2844
     2845            case ATTR_INIT_FFFS:
     2846                switch (pDieDesc->paAttributes[i].cbInit & ATTR_SIZE_MASK)
     2847                {
     2848                    case 1:
     2849                        *(uint8_t *)((uintptr_t)pDie + pDieDesc->paAttributes[i].off)  = UINT8_MAX;
     2850                        break;
     2851                    case 2:
     2852                        *(uint16_t *)((uintptr_t)pDie + pDieDesc->paAttributes[i].off) = UINT16_MAX;
     2853                        break;
     2854                    case 4:
     2855                        *(uint32_t *)((uintptr_t)pDie + pDieDesc->paAttributes[i].off) = UINT32_MAX;
     2856                        break;
     2857                    case 8:
     2858                        *(uint64_t *)((uintptr_t)pDie + pDieDesc->paAttributes[i].off) = UINT64_MAX;
     2859                        break;
     2860                    default:
     2861                        AssertFailed();
     2862                        memset((uint8_t *)pDie + pDieDesc->paAttributes[i].off, 0xff,
     2863                               pDieDesc->paAttributes[i].cbInit & ATTR_SIZE_MASK);
     2864                        break;
     2865                }
     2866                break;
     2867
     2868            default:
     2869                AssertFailed();
     2870        }
    26652871    }
    26662872}
     
    26722878 * @returns Pointer to the new DIE structure.
    26732879 * @param   pThis               The DWARF instance.
    2674  * @param   cbUnit              The size required for this unit.
     2880 * @param   pDieDesc            The DIE descriptor (for size and init).
    26752881 * @param   pAbbrev             The abbreviation cache entry.
    26762882 * @param   pParent             The parent DIE (NULL if unit).
    26772883 */
    2678 static PRTDWARFDIE rtDwarfInfo_NewDie(PRTDBGMODDWARF pThis, size_t cbUnit, PCRTDWARFABBREV pAbbrev, PRTDWARFDIE pParent)
    2679 {
    2680     Assert(cbUnit >= sizeof(RTDWARFDIE));
    2681     PRTDWARFDIE pDie = (PRTDWARFDIE)RTMemAllocZ(cbUnit);
     2884static PRTDWARFDIE rtDwarfInfo_NewDie(PRTDBGMODDWARF pThis, PCRTDWARFDIEDESC pDieDesc,
     2885                                      PCRTDWARFABBREV pAbbrev, PRTDWARFDIE pParent)
     2886{
     2887    Assert(pDieDesc->cbDie >= sizeof(RTDWARFDIE));
     2888    PRTDWARFDIE pDie = (PRTDWARFDIE)RTMemAllocZ(pDieDesc->cbDie);
    26822889    if (pDie)
    26832890    {
     2891        rtDwarfInfo_InitDie(pDie, pDieDesc);
     2892
    26842893        pDie->uTag         = pAbbrev->uTag;
    26852894        pDie->offSpec      = pAbbrev->offSpec;
     
    26902899            RTListInit(&pDie->SiblingNode);
    26912900        RTListInit(&pDie->ChildList);
     2901
    26922902    }
    26932903    return pDie;
     
    27903000
    27913001
    2792 #if 0
    2793 /**
    2794  * Parse a DIE.
     3002/**
     3003 * Parse the attributes of a DIE.
     3004 *
     3005 * @returns IPRT status code.
     3006 * @param   pThis               The DWARF instance.
     3007 * @param   pDie                The internal DIE structure to fill.
     3008 * @param   pDieDesc            The DIE descriptor.
     3009 * @param   pCursor             The debug_info cursor.
     3010 * @param   pAbbrev             The abbreviation cache entry.
     3011 */
     3012static int rtDwarfInfo_ParseDie(PRTDBGMODDWARF pThis, PRTDWARFDIE pDie, PCRTDWARFDIEDESC pDieDesc,
     3013                                PRTDWARFCURSOR pCursor, PCRTDWARFABBREV pAbbrev)
     3014{
     3015    RTDWARFCURSOR AbbrevCursor;
     3016    int rc = rtDwarfCursor_InitWithOffset(&AbbrevCursor, pThis, krtDbgModDwarfSect_abbrev, pAbbrev->offSpec);
     3017    if (RT_FAILURE(rc))
     3018        return rc;
     3019
     3020    rtDwarfInfo_InitDie(pDie, pDieDesc);
     3021    for (;;)
     3022    {
     3023        uint32_t uAttr = rtDwarfCursor_GetULeb128AsU32(&AbbrevCursor, 0);
     3024        uint32_t uForm = rtDwarfCursor_GetULeb128AsU32(&AbbrevCursor, 0);
     3025        if (uAttr == 0)
     3026            break;
     3027        if (uForm == DW_FORM_indirect)
     3028            uForm = rtDwarfCursor_GetULeb128AsU32(pCursor, 0);
     3029
     3030        /* Look up the attribute in the descriptor and invoke the decoder. */
     3031        PCRTDWARFATTRDESC pAttr = NULL;
     3032        uint32_t i = pDieDesc->cAttributes;
     3033        while (i-- > 0)
     3034            if (pDieDesc->paAttributes[i].uAttr == uAttr)
     3035            {
     3036                pAttr = &pDieDesc->paAttributes[i];
     3037                rc = pAttr->pfnDecoder(pDie, (uint8_t *)pDie + pAttr->off, pAttr, uForm, pCursor);
     3038                break;
     3039            }
     3040
     3041        /* Some house keeping. */
     3042        if (pAttr)
     3043            pDie->cDecodedAttrs++;
     3044        else
     3045        {
     3046            pDie->cUnhandledAttrs++;
     3047            rc = rtDwarfInfo_SkipForm(pCursor, uForm);
     3048        }
     3049        if (RT_FAILURE(rc))
     3050            break;
     3051    }
     3052
     3053    rc = rtDwarfCursor_Delete(&AbbrevCursor, rc);
     3054    if (RT_SUCCESS(rc))
     3055        rc = pCursor->rc;
     3056
     3057    /*
     3058     * Snoope up symbols on the way out.
     3059     */
     3060    if (RT_SUCCESS(rc))
     3061        rc = rtDwarfInfo_SnoopSymbols(pThis, pDie);
     3062
     3063    return rc;
     3064}
     3065
     3066
     3067/**
     3068 * Load the debug information of a unit.
    27953069 *
    27963070 * @returns IPRT status code.
    27973071 * @param   pThis               The DWARF instance.
    27983072 * @param   pCursor             The debug_info cursor.
    2799  * @param   pAbbrev             The abbreviation entry.
    2800  * @param   pAbbrevCursor       The abbreviation cursor.
    2801  * @param   pStack              The DIE stack.
    2802  */
    2803 static int rtDwarfInfo_ParseDie(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor,
    2804                                 PCRTDWARFABBREV pAbbrev, PRTDWARFCURSOR pAbbrevCursor,
    2805                                 PRTDWARFDIESTACK pStack)
    2806 {
    2807     /*
    2808      * Pick out DIEs which tag we find interesting.
    2809      */
    2810     switch (pAbbrev->uTag)
    2811     {
    2812         case DW_TAG_compile_unit:
    2813         case DW_TAG_partial_unit:
    2814             Log((" - DW_TAG_%s_unit:\n", pAbbrev->uTag == DW_TAG_compile_unit ? "compile" : "partial"));
    2815             for (;;)
    2816             {
    2817                 uint32_t uAttr = rtDwarfCursor_GetULeb128AsU32(pAbbrevCursor, 0);
    2818                 uint32_t uForm = rtDwarfCursor_GetULeb128AsU32(pAbbrevCursor, 0);
    2819                 switch (uAttr)
    2820                 {
    2821                     case 0:
    2822                         return VINF_SUCCESS;
    2823 
    2824                     case DW_AT_name:
    2825                     {
    2826                         const char *pszName = rtDwarfForm_GetString(pThis, pCursor, uForm, "<error>");
    2827                         rtDwarfDieStack_SetName(pStack, pszName);
    2828                         Log4(("%*s   - name=%s\n", pStack->cOnStack*2, "", pszName));
    2829                         break;
    2830                     }
    2831 
    2832                     case DW_AT_stmt_list:
    2833                         /** @todo  */
    2834                     default:
    2835                         Log4(("%*s   - attr=%#x form=%#x\n", pStack->cOnStack*2, "", uAttr, uForm));
    2836                         rtDwarfInfo_SkipForm(pCursor, uForm);
    2837                 }
    2838                 if (RT_FAILURE(pCursor->rc))
    2839                     return pCursor->rc;
    2840             }
    2841             break; /* not reached. */
    2842 
    2843         case DW_TAG_subprogram:
    2844             Log((" - DW_TAG_subprogram:\n"));
    2845             for (;;)
    2846             {
    2847                 uint32_t uAttr = rtDwarfCursor_GetULeb128AsU32(pAbbrevCursor, 0);
    2848                 uint32_t uForm = rtDwarfCursor_GetULeb128AsU32(pAbbrevCursor, 0);
    2849                 switch (uAttr)
    2850                 {
    2851                     case 0:
    2852                         return VINF_SUCCESS;
    2853 
    2854                     case DW_AT_name:
    2855                     {
    2856                         const char *pszName = rtDwarfForm_GetString(pThis, pCursor, uForm, "<error>");
    2857                         rtDwarfDieStack_SetName(pStack, pszName);
    2858                         Log4(("%*s   - name=%s\n", pStack->cOnStack*2, "", pszName));
    2859                         break;
    2860                     }
    2861 
    2862                     default:
    2863                         Log4(("%*s   - attr=%#x form=%#x\n", pStack->cOnStack*2, "", uAttr, uForm));
    2864                         rtDwarfInfo_SkipForm(pCursor, uForm);
    2865                 }
    2866                 if (RT_FAILURE(pCursor->rc))
    2867                     return pCursor->rc;
    2868             }
    2869             break; /* not reached. */
    2870 
    2871     }
    2872 
    2873     return rtDwarfInfo_SkipDie(pCursor, pAbbrevCursor);
    2874 }
    2875 #endif
    2876 
    2877 
    2878 
    2879 static int rtDwarfInfo_LoadUnit(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor)
     3073 * @param   fKeepDies           Whether to keep the DIEs or discard them as soon
     3074 *                              as possible.
     3075 */
     3076static int rtDwarfInfo_LoadUnit(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor, bool fKeepDies)
    28803077{
    28813078    Log(("rtDwarfInfo_LoadUnit: %#x\n", rtDwarfCursor_CalcSectOffsetU32(pCursor)));
     
    29213118    }
    29223119
    2923     PRTDWARFDIECOMPILEUNIT pUnit = (PRTDWARFDIECOMPILEUNIT)rtDwarfInfo_NewDie(pThis, sizeof(*pUnit), pAbbrev, NULL /*pParent*/);
     3120    PRTDWARFDIECOMPILEUNIT pUnit;
     3121    pUnit = (PRTDWARFDIECOMPILEUNIT)rtDwarfInfo_NewDie(pThis, &g_CompileUnitDesc, pAbbrev, NULL /*pParent*/);
    29243122    if (!pUnit)
    29253123        return VERR_NO_MEMORY;
     
    29313129    RTListAppend(&pThis->CompileUnitList, &pUnit->Core.SiblingNode);
    29323130
    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     }
     3131    int rc = rtDwarfInfo_ParseDie(pThis, &pUnit->Core, &g_CompileUnitDesc, pCursor, pAbbrev);
    29423132    if (RT_FAILURE(rc))
    2943         break;
     3133        return rc;
    29443134
    29453135    /*
    29463136     * Parse DIEs.
    29473137     */
    2948     int rc = VINF_SUCCESS;
     3138    uint32_t    cDepth     = 0;
     3139    PRTDWARFDIE pParentDie = &pUnit->Core;
    29493140    while (!rtDwarfCursor_IsAtEndOfUnit(pCursor))
    29503141    {
    2951         uint32_t uAbbrCode = rtDwarfCursor_GetULeb128AsU32(pCursor, UINT32_MAX);
     3142        uAbbrCode = rtDwarfCursor_GetULeb128AsU32(pCursor, UINT32_MAX);
    29523143        if (!uAbbrCode)
    29533144        {
    2954             /* End of siblings, pop the stack. */
    2955             rc = rtDwarfDieStack_Pop(&Stack);
    2956             if (RT_FAILURE(rc))
     3145            /* End of siblings, up one level. */
     3146            pParentDie = pParentDie->pParent;
     3147            if (!pParentDie)
     3148            {
     3149                if (!rtDwarfCursor_IsAtEndOfUnit(pCursor))
     3150                    return VERR_DWARF_BAD_INFO;
    29573151                break;
     3152            }
     3153            cDepth--;
     3154
     3155            /* Unlink and free child DIEs if told to do so. */
     3156            if (!fKeepDies && pParentDie->pParent)
     3157            {
     3158                PRTDWARFDIE pChild, pNextChild;
     3159                RTListForEachSafe(&pParentDie->ChildList, pChild, pNextChild, RTDWARFDIE, SiblingNode)
     3160                {
     3161                    RTListNodeRemove(&pChild->SiblingNode);
     3162                    RTMemFree(pChild);
     3163                }
     3164            }
    29583165        }
    29593166        else
    29603167        {
    29613168            /*
    2962              * Look up the abbreviation.
     3169             * Look up the abbreviation and match the tag up with a descriptor.
    29633170             */
    2964             PCRTDWARFABBREV pAbbrev = rtDwarfAbbrev_Lookup(pThis, uAbbrCode);
     3171            pAbbrev = rtDwarfAbbrev_Lookup(pThis, uAbbrCode);
    29653172            if (!pAbbrev)
     3173                return VERR_DWARF_ABBREV_NOT_FOUND;
     3174
     3175            PCRTDWARFDIEDESC pDieDesc;
     3176            const char      *pszName;
     3177            if (pAbbrev->uTag < RT_ELEMENTS(g_aTagDescs))
    29663178            {
    2967                 rc = VERR_DWARF_ABBREV_NOT_FOUND;
    2968                 break;
     3179                Assert(g_aTagDescs[pAbbrev->uTag].uTag == pAbbrev->uTag || g_aTagDescs[pAbbrev->uTag].uTag == 0);
     3180                pszName  = g_aTagDescs[pAbbrev->uTag].pszName;
     3181                pDieDesc = g_aTagDescs[pAbbrev->uTag].pDesc;
    29693182            }
    2970             Log4((" %*stag=%#x%s\n", Stack.cOnStack * 2, "", pAbbrev->uTag, pAbbrev->fChildren ? " has children" : ""));
     3183            else
     3184            {
     3185                pszName  = "<unknown>";
     3186                pDieDesc = g_aTagDescs[0].pDesc;
     3187            }
     3188            Log4((" %*stag=%s (%#x)%s\n", cDepth * 2, "", pszName,
     3189                  pAbbrev->uTag, pAbbrev->fChildren ? " has children" : ""));
    29713190
    29723191            /*
    2973              * If this DIE has children, push it onto the stack.
     3192             * Create a new internal DIE structure and parse the
     3193             * attributes.
    29743194             */
     3195            PRTDWARFDIE pNewDie = rtDwarfInfo_NewDie(pThis, pDieDesc, pAbbrev, pParentDie);
     3196            if (!pNewDie)
     3197                return VERR_NO_MEMORY;
     3198
    29753199            if (pAbbrev->fChildren)
    29763200            {
    2977                 rc = rtDwarfDieStack_Push(&Stack, uAbbrCode, pAbbrev->uTag, rtDwarfCursor_CalcSectOffsetU32(pCursor));
    2978                 if (RT_FAILURE(rc))
    2979                     break;
     3201                pParentDie = pNewDie;
     3202                cDepth++;
    29803203            }
    29813204
    2982             /*
    2983              * Parse it.
    2984              */
    2985             RTDWARFCURSOR AbbrevCursor;
    2986             rc = rtDwarfCursor_InitWithOffset(&AbbrevCursor, pThis, krtDbgModDwarfSect_abbrev, pAbbrev->offSpec);
    2987             if (RT_SUCCESS(rc))
    2988             {
    2989                 rc = rtDwarfInfo_ParseDie(pThis, pCursor, pAbbrev, &AbbrevCursor, &Stack);
    2990                 rc = rtDwarfCursor_Delete(&AbbrevCursor, rc);
    2991             }
     3205            rc = rtDwarfInfo_ParseDie(pThis, pNewDie, pDieDesc, pCursor, pAbbrev);
    29923206            if (RT_FAILURE(rc))
    2993                 break;
     3207                return rc;
    29943208        }
    2995     }
    2996 
    2997     rtDwarfDieStack_Delete(&Stack);
    2998 #endif
     3209    } /* while more DIEs */
     3210
    29993211    return RT_SUCCESS(rc) ? pCursor->rc : rc;
    30003212}
     
    30183230    while (   !rtDwarfCursor_IsAtEnd(&Cursor)
    30193231           && RT_SUCCESS(rc))
    3020         rc = rtDwarfInfo_LoadUnit(pThis, &Cursor);
     3232        rc = rtDwarfInfo_LoadUnit(pThis, &Cursor, false /* fKeepDies */);
    30213233
    30223234    return rtDwarfCursor_Delete(&Cursor, rc);
     
    32583470        return VERR_NO_MEMORY;
    32593471    pThis->pMod = pMod;
     3472    RTListInit(&pThis->CompileUnitList);
    32603473
    32613474    int rc = pMod->pImgVt->pfnEnumDbgInfo(pMod, rtDbgModDwarfEnumCallback, pThis);
  • trunk/src/VBox/Runtime/tools/RTLdrFlt.cpp

    r38573 r38619  
    140140    };
    141141
    142     PRTSTREAM       pInput   = g_pStdIn;
    143     PRTSTREAM       pOutput  = g_pStdOut;
    144     bool            fVerbose = false;
     142    PRTSTREAM       pInput          = g_pStdIn;
     143    PRTSTREAM       pOutput         = g_pStdOut;
     144    unsigned        cVerbosityLevel = 0;
    145145
    146146    RTGETOPTUNION   ValueUnion;
     
    158158
    159159            case 'v':
    160                 fVerbose = true;
     160                cVerbosityLevel++;
    161161                break;
    162162
     
    209209     * Display the address space.
    210210     */
    211     if (fVerbose)
     211    if (cVerbosityLevel)
    212212    {
    213213        RTPrintf("*** Address Space Dump ***\n");
     
    243243                            RTPrintf("  mapping #%u: %RTptr-???????? (segment #%u)", iMapping, aMappings[iMapping].Address);
    244244                    }
     245
     246                    if (cVerbosityLevel > 1)
     247                    {
     248                        uint32_t cSymbols = RTDbgModSymbolCount(hDbgMod);
     249                        RTPrintf("    %u symbols\n", cSymbols);
     250                        for (uint32_t iSymbol = 0; iSymbol < cSymbols; iSymbol++)
     251                        {
     252                            RTDBGSYMBOL SymInfo;
     253                            rc = RTDbgModSymbolByOrdinal(hDbgMod, iSymbol, &SymInfo);
     254                            if (RT_SUCCESS(rc))
     255                                RTPrintf("    #%04u at %08x:%RTptr %05llx %s\n",
     256                                         SymInfo.iOrdinal, SymInfo.iSeg, SymInfo.offSeg,
     257                                         (uint64_t)SymInfo.cb, SymInfo.szName);
     258                        }
     259                    }
    245260                }
    246261            }
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