VirtualBox

Changeset 45968 in vbox


Ignore:
Timestamp:
May 9, 2013 5:12:13 PM (12 years ago)
Author:
vboxsync
Message:

Ldr,Dbg: DWARF and ELF hacking in progress.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/cdefs.h

    r44528 r45968  
    10921092 */
    10931093#define RT_STR_TUPLE(a_szConst)  a_szConst, (sizeof(a_szConst) - 1)
     1094
     1095
     1096/**
     1097 * Macro for using in switch statements that turns constants into strings.
     1098 *
     1099 * @param   a_Const     The constant (not string).
     1100 */
     1101#define RT_CASE_RET_STR(a_Const)     case a_Const: return #a_Const
    10941102
    10951103
  • trunk/include/iprt/err.h

    r45454 r45968  
    14801480/** Encountered an unexpected attribute form. */
    14811481#define VERR_DWARF_UNEXPECTED_FORM              (-678)
     1482/** Unfinished code. */
     1483#define VERR_DWARF_TODO                         (-679)
     1484/** Unknown location opcode. */
     1485#define VERR_DWARF_UNKNOWN_LOC_OPCODE           (-680)
     1486/** Expression stack overflow. */
     1487#define VERR_DWARF_STACK_OVERFLOW               (-681)
     1488/** Expression stack underflow. */
     1489#define VERR_DWARF_STACK_UNDERFLOW              (-682)
     1490/** Internal processing error in the DWARF code. */
     1491#define VERR_DWARF_IPE                          (-683)
    14821492/** @} */
    14831493
  • trunk/src/VBox/Runtime/common/dbg/dbgmoddwarf.cpp

    r45936 r45968  
    280280
    281281
     282/** @name Location Expression Opcodes
     283 * @{ */
     284#define DW_OP_addr              UINT8_C(0x03) /**< 1 operand, a constant address (size target specific). */
     285#define DW_OP_deref             UINT8_C(0x06) /**< 0 operands. */
     286#define DW_OP_const1u           UINT8_C(0x08) /**< 1 operand, a 1-byte constant. */
     287#define DW_OP_const1s           UINT8_C(0x09) /**< 1 operand, a 1-byte constant. */
     288#define DW_OP_const2u           UINT8_C(0x0a) /**< 1 operand, a 2-byte constant. */
     289#define DW_OP_const2s           UINT8_C(0x0b) /**< 1 operand, a 2-byte constant. */
     290#define DW_OP_const4u           UINT8_C(0x0c) /**< 1 operand, a 4-byte constant. */
     291#define DW_OP_const4s           UINT8_C(0x0d) /**< 1 operand, a 4-byte constant. */
     292#define DW_OP_const8u           UINT8_C(0x0e) /**< 1 operand, a 8-byte constant. */
     293#define DW_OP_const8s           UINT8_C(0x0f) /**< 1 operand, a 8-byte constant. */
     294#define DW_OP_constu            UINT8_C(0x10) /**< 1 operand, a ULEB128 constant. */
     295#define DW_OP_consts            UINT8_C(0x11) /**< 1 operand, a SLEB128 constant. */
     296#define DW_OP_dup               UINT8_C(0x12) /**< 0 operands. */
     297#define DW_OP_drop              UINT8_C(0x13) /**< 0 operands. */
     298#define DW_OP_over              UINT8_C(0x14) /**< 0 operands. */
     299#define DW_OP_pick              UINT8_C(0x15) /**< 1 operands, a 1-byte stack index. */
     300#define DW_OP_swap              UINT8_C(0x16) /**< 0 operands. */
     301#define DW_OP_rot               UINT8_C(0x17) /**< 0 operands. */
     302#define DW_OP_xderef            UINT8_C(0x18) /**< 0 operands. */
     303#define DW_OP_abs               UINT8_C(0x19) /**< 0 operands. */
     304#define DW_OP_and               UINT8_C(0x1a) /**< 0 operands. */
     305#define DW_OP_div               UINT8_C(0x1b) /**< 0 operands. */
     306#define DW_OP_minus             UINT8_C(0x1c) /**< 0 operands. */
     307#define DW_OP_mod               UINT8_C(0x1d) /**< 0 operands. */
     308#define DW_OP_mul               UINT8_C(0x1e) /**< 0 operands. */
     309#define DW_OP_neg               UINT8_C(0x1f) /**< 0 operands. */
     310#define DW_OP_not               UINT8_C(0x20) /**< 0 operands. */
     311#define DW_OP_or                UINT8_C(0x21) /**< 0 operands. */
     312#define DW_OP_plus              UINT8_C(0x22) /**< 0 operands. */
     313#define DW_OP_plus_uconst       UINT8_C(0x23) /**< 1 operands, a ULEB128 addend. */
     314#define DW_OP_shl               UINT8_C(0x24) /**< 0 operands. */
     315#define DW_OP_shr               UINT8_C(0x25) /**< 0 operands. */
     316#define DW_OP_shra              UINT8_C(0x26) /**< 0 operands. */
     317#define DW_OP_xor               UINT8_C(0x27) /**< 0 operands. */
     318#define DW_OP_skip              UINT8_C(0x2f) /**< 1 signed 2-byte constant. */
     319#define DW_OP_bra               UINT8_C(0x28) /**< 1 signed 2-byte constant. */
     320#define DW_OP_eq                UINT8_C(0x29) /**< 0 operands. */
     321#define DW_OP_ge                UINT8_C(0x2a) /**< 0 operands. */
     322#define DW_OP_gt                UINT8_C(0x2b) /**< 0 operands. */
     323#define DW_OP_le                UINT8_C(0x2c) /**< 0 operands. */
     324#define DW_OP_lt                UINT8_C(0x2d) /**< 0 operands. */
     325#define DW_OP_ne                UINT8_C(0x2e) /**< 0 operands. */
     326#define DW_OP_lit0              UINT8_C(0x30) /**< 0 operands - literals 0..31 */
     327#define DW_OP_lit31             UINT8_C(0x4f) /**< last litteral. */
     328#define DW_OP_reg0              UINT8_C(0x50) /**< 0 operands - reg 0..31. */
     329#define DW_OP_reg31             UINT8_C(0x6f) /**< last register. */
     330#define DW_OP_breg0             UINT8_C(0x70) /**< 1 operand, a SLEB128 offset. */
     331#define DW_OP_breg31            UINT8_C(0x8f) /**< last branch register. */
     332#define DW_OP_regx              UINT8_C(0x90) /**< 1 operand, a ULEB128 register. */
     333#define DW_OP_fbreg             UINT8_C(0x91) /**< 1 operand, a SLEB128 offset. */
     334#define DW_OP_bregx             UINT8_C(0x92) /**< 2 operands, a ULEB128 register followed by a SLEB128 offset. */
     335#define DW_OP_piece             UINT8_C(0x93) /**< 1 operand, a ULEB128 size of piece addressed. */
     336#define DW_OP_deref_size        UINT8_C(0x94) /**< 1 operand, a 1-byte size of data retrieved. */
     337#define DW_OP_xderef_size       UINT8_C(0x95) /**< 1 operand, a 1-byte size of data retrieved. */
     338#define DW_OP_nop               UINT8_C(0x96) /**< 0 operands. */
     339#define DW_OP_lo_user           UINT8_C(0xe0) /**< First user opcode */
     340#define DW_OP_hi_user           UINT8_C(0xff) /**< Last user opcode. */
     341/** @} */
     342
     343
    282344/*******************************************************************************
    283345*   Structures and Typedefs                                                    *
     
    603665
    604666
     667/**
     668 * DWARF Location state.
     669 */
     670typedef struct RTDWARFLOCST
     671{
     672    /** The input cursor. */
     673    RTDWARFCURSOR   Cursor;
     674    /** Points to the current top of the stack. Initial value -1. */
     675    int32_t         iTop;
     676    /** The value stack.  */
     677    uint64_t        auStack[64];
     678} RTDWARFLOCST;
     679/** Pointer to location state. */
     680typedef RTDWARFLOCST *PRTDWARFLOCST;
     681
     682
    605683
    606684/*******************************************************************************
     
    615693static FNRTDWARFATTRDECODER rtDwarfDecode_String;
    616694static FNRTDWARFATTRDECODER rtDwarfDecode_UnsignedInt;
     695static FNRTDWARFATTRDECODER rtDwarfDecode_SegmentLoc;
    617696
    618697
     
    709788    /** The first instruction in the function. */
    710789    RTDWARFADDR         EntryPc;
     790    /** Segment number (watcom). */
     791    RTSEL               uSegment;
    711792} RTDWARFDIESUBPROGRAM;
    712793/** Pointer to a DW_TAG_subprogram DIE.  */
     
    725806    ATTR_ENTRY(DW_AT_ranges,            RTDWARFDIESUBPROGRAM, PcRange,        ATTR_INIT_ZERO, rtDwarfDecode_Ranges),
    726807    ATTR_ENTRY(DW_AT_entry_pc,          RTDWARFDIESUBPROGRAM, EntryPc,        ATTR_INIT_ZERO, rtDwarfDecode_Address),
     808    ATTR_ENTRY(DW_AT_segment,           RTDWARFDIESUBPROGRAM, uSegment,       ATTR_INIT_ZERO, rtDwarfDecode_SegmentLoc)
    727809};
    728810
     
    821903
    822904
     905#if defined(LOG_ENABLED) || defined(RT_STRICT)
     906
     907/**
     908 * Turns a tag value into a string for logging purposes.
     909 *
     910 * @returns String name.
     911 * @param   uTag            The tag.
     912 */
     913static const char *rtDwarfLog_GetTagName(uint32_t uTag)
     914{
     915    if (uTag < RT_ELEMENTS(g_aTagDescs))
     916    {
     917        const char *pszTag = g_aTagDescs[uTag].pszName;
     918        if (pszTag)
     919            return pszTag;
     920    }
     921
     922    static char s_szStatic[32];
     923    RTStrPrintf(s_szStatic, sizeof(s_szStatic),"DW_TAG_%#x", uTag);
     924    return s_szStatic;
     925}
     926
     927
     928/**
     929 * Turns an attributevalue into a string for logging purposes.
     930 *
     931 * @returns String name.
     932 * @param   uAttr               The attribute.
     933 */
     934static const char *rtDwarfLog_AttrName(uint32_t uAttr)
     935{
     936    switch (uAttr)
     937    {
     938        RT_CASE_RET_STR(DW_AT_sibling);
     939        RT_CASE_RET_STR(DW_AT_location);
     940        RT_CASE_RET_STR(DW_AT_name);
     941        RT_CASE_RET_STR(DW_AT_ordering);
     942        RT_CASE_RET_STR(DW_AT_byte_size);
     943        RT_CASE_RET_STR(DW_AT_bit_offset);
     944        RT_CASE_RET_STR(DW_AT_bit_size);
     945        RT_CASE_RET_STR(DW_AT_stmt_list);
     946        RT_CASE_RET_STR(DW_AT_low_pc);
     947        RT_CASE_RET_STR(DW_AT_high_pc);
     948        RT_CASE_RET_STR(DW_AT_language);
     949        RT_CASE_RET_STR(DW_AT_discr);
     950        RT_CASE_RET_STR(DW_AT_discr_value);
     951        RT_CASE_RET_STR(DW_AT_visibility);
     952        RT_CASE_RET_STR(DW_AT_import);
     953        RT_CASE_RET_STR(DW_AT_string_length);
     954        RT_CASE_RET_STR(DW_AT_common_reference);
     955        RT_CASE_RET_STR(DW_AT_comp_dir);
     956        RT_CASE_RET_STR(DW_AT_const_value);
     957        RT_CASE_RET_STR(DW_AT_containing_type);
     958        RT_CASE_RET_STR(DW_AT_default_value);
     959        RT_CASE_RET_STR(DW_AT_inline);
     960        RT_CASE_RET_STR(DW_AT_is_optional);
     961        RT_CASE_RET_STR(DW_AT_lower_bound);
     962        RT_CASE_RET_STR(DW_AT_producer);
     963        RT_CASE_RET_STR(DW_AT_prototyped);
     964        RT_CASE_RET_STR(DW_AT_return_addr);
     965        RT_CASE_RET_STR(DW_AT_start_scope);
     966        RT_CASE_RET_STR(DW_AT_bit_stride);
     967        RT_CASE_RET_STR(DW_AT_upper_bound);
     968        RT_CASE_RET_STR(DW_AT_abstract_origin);
     969        RT_CASE_RET_STR(DW_AT_accessibility);
     970        RT_CASE_RET_STR(DW_AT_address_class);
     971        RT_CASE_RET_STR(DW_AT_artificial);
     972        RT_CASE_RET_STR(DW_AT_base_types);
     973        RT_CASE_RET_STR(DW_AT_calling_convention);
     974        RT_CASE_RET_STR(DW_AT_count);
     975        RT_CASE_RET_STR(DW_AT_data_member_location);
     976        RT_CASE_RET_STR(DW_AT_decl_column);
     977        RT_CASE_RET_STR(DW_AT_decl_file);
     978        RT_CASE_RET_STR(DW_AT_decl_line);
     979        RT_CASE_RET_STR(DW_AT_declaration);
     980        RT_CASE_RET_STR(DW_AT_discr_list);
     981        RT_CASE_RET_STR(DW_AT_encoding);
     982        RT_CASE_RET_STR(DW_AT_external);
     983        RT_CASE_RET_STR(DW_AT_frame_base);
     984        RT_CASE_RET_STR(DW_AT_friend);
     985        RT_CASE_RET_STR(DW_AT_identifier_case);
     986        RT_CASE_RET_STR(DW_AT_macro_info);
     987        RT_CASE_RET_STR(DW_AT_namelist_item);
     988        RT_CASE_RET_STR(DW_AT_priority);
     989        RT_CASE_RET_STR(DW_AT_segment);
     990        RT_CASE_RET_STR(DW_AT_specification);
     991        RT_CASE_RET_STR(DW_AT_static_link);
     992        RT_CASE_RET_STR(DW_AT_type);
     993        RT_CASE_RET_STR(DW_AT_use_location);
     994        RT_CASE_RET_STR(DW_AT_variable_parameter);
     995        RT_CASE_RET_STR(DW_AT_virtuality);
     996        RT_CASE_RET_STR(DW_AT_vtable_elem_location);
     997        RT_CASE_RET_STR(DW_AT_allocated);
     998        RT_CASE_RET_STR(DW_AT_associated);
     999        RT_CASE_RET_STR(DW_AT_data_location);
     1000        RT_CASE_RET_STR(DW_AT_byte_stride);
     1001        RT_CASE_RET_STR(DW_AT_entry_pc);
     1002        RT_CASE_RET_STR(DW_AT_use_UTF8);
     1003        RT_CASE_RET_STR(DW_AT_extension);
     1004        RT_CASE_RET_STR(DW_AT_ranges);
     1005        RT_CASE_RET_STR(DW_AT_trampoline);
     1006        RT_CASE_RET_STR(DW_AT_call_column);
     1007        RT_CASE_RET_STR(DW_AT_call_file);
     1008        RT_CASE_RET_STR(DW_AT_call_line);
     1009        RT_CASE_RET_STR(DW_AT_description);
     1010        RT_CASE_RET_STR(DW_AT_binary_scale);
     1011        RT_CASE_RET_STR(DW_AT_decimal_scale);
     1012        RT_CASE_RET_STR(DW_AT_small);
     1013        RT_CASE_RET_STR(DW_AT_decimal_sign);
     1014        RT_CASE_RET_STR(DW_AT_digit_count);
     1015        RT_CASE_RET_STR(DW_AT_picture_string);
     1016        RT_CASE_RET_STR(DW_AT_mutable);
     1017        RT_CASE_RET_STR(DW_AT_threads_scaled);
     1018        RT_CASE_RET_STR(DW_AT_explicit);
     1019        RT_CASE_RET_STR(DW_AT_object_pointer);
     1020        RT_CASE_RET_STR(DW_AT_endianity);
     1021        RT_CASE_RET_STR(DW_AT_elemental);
     1022        RT_CASE_RET_STR(DW_AT_pure);
     1023        RT_CASE_RET_STR(DW_AT_recursive);
     1024        RT_CASE_RET_STR(DW_AT_signature);
     1025        RT_CASE_RET_STR(DW_AT_main_subprogram);
     1026        RT_CASE_RET_STR(DW_AT_data_bit_offset);
     1027        RT_CASE_RET_STR(DW_AT_const_expr);
     1028        RT_CASE_RET_STR(DW_AT_enum_class);
     1029        RT_CASE_RET_STR(DW_AT_linkage_name);
     1030    }
     1031    static char s_szStatic[32];
     1032    RTStrPrintf(s_szStatic, sizeof(s_szStatic),"DW_AT_%#x", uAttr);
     1033    return s_szStatic;
     1034}
     1035
     1036
     1037/**
     1038 * Turns a form value into a string for logging purposes.
     1039 *
     1040 * @returns String name.
     1041 * @param   uForm               The form.
     1042 */
     1043static const char *rtDwarfLog_FormName(uint32_t uForm)
     1044{
     1045    switch (uForm)
     1046    {
     1047        RT_CASE_RET_STR(DW_FORM_addr);
     1048        RT_CASE_RET_STR(DW_FORM_block2);
     1049        RT_CASE_RET_STR(DW_FORM_block4);
     1050        RT_CASE_RET_STR(DW_FORM_data2);
     1051        RT_CASE_RET_STR(DW_FORM_data4);
     1052        RT_CASE_RET_STR(DW_FORM_data8);
     1053        RT_CASE_RET_STR(DW_FORM_string);
     1054        RT_CASE_RET_STR(DW_FORM_block);
     1055        RT_CASE_RET_STR(DW_FORM_block1);
     1056        RT_CASE_RET_STR(DW_FORM_data1);
     1057        RT_CASE_RET_STR(DW_FORM_flag);
     1058        RT_CASE_RET_STR(DW_FORM_sdata);
     1059        RT_CASE_RET_STR(DW_FORM_strp);
     1060        RT_CASE_RET_STR(DW_FORM_udata);
     1061        RT_CASE_RET_STR(DW_FORM_ref_addr);
     1062        RT_CASE_RET_STR(DW_FORM_ref1);
     1063        RT_CASE_RET_STR(DW_FORM_ref2);
     1064        RT_CASE_RET_STR(DW_FORM_ref4);
     1065        RT_CASE_RET_STR(DW_FORM_ref8);
     1066        RT_CASE_RET_STR(DW_FORM_ref_udata);
     1067        RT_CASE_RET_STR(DW_FORM_indirect);
     1068        RT_CASE_RET_STR(DW_FORM_sec_offset);
     1069        RT_CASE_RET_STR(DW_FORM_exprloc);
     1070        RT_CASE_RET_STR(DW_FORM_flag_present);
     1071        RT_CASE_RET_STR(DW_FORM_ref_sig8);
     1072    }
     1073    static char s_szStatic[32];
     1074    RTStrPrintf(s_szStatic, sizeof(s_szStatic),"DW_FORM_%#x", uForm);
     1075    return s_szStatic;
     1076}
     1077
     1078#endif /* LOG_ENABLED || RT_STRICT */
     1079
     1080
    8231081/** @callback_method_impl{FNRTLDRENUMSEGS} */
    8241082static DECLCALLBACK(int) rtDbgModHlpAddSegmentCallback(RTLDRMOD hLdrMod, PCRTLDRSEG pSeg, void *pvUser)
     
    8281086         pSeg->cchName, pSeg->pchName, (uint64_t)pSeg->LinkAddress, (uint64_t)pSeg->RVA, pSeg->cb));
    8291087    NOREF(hLdrMod);
     1088
     1089    /* If the segment doesn't have a mapping, just add a dummy so the indexing
     1090       works out correctly (same as for the image). */
     1091    if (pSeg->RVA == NIL_RTLDRADDR)
     1092        return pMod->pDbgVt->pfnSegmentAdd(pMod, 0, 0, pSeg->pchName, pSeg->cchName, 0 /*fFlags*/, NULL);
     1093
    8301094    RTLDRADDR cb = RT_MAX(pSeg->cb, pSeg->cbMapped);
    8311095#if 1
     
    13471611    return u64Ret;
    13481612}
     1613
     1614
     1615#if 0 /* unused */
     1616/**
     1617 * Gets the pointer to a variable size block and advances the cursor.
     1618 *
     1619 * @returns Pointer to the block at the current cursor location. On error
     1620 *          RTDWARFCURSOR::rc is set and NULL returned.
     1621 * @param   pCursor             The cursor.
     1622 * @param   cbBlock             The block size.
     1623 */
     1624static const uint8_t *rtDwarfCursor_GetBlock(PRTDWARFCURSOR pCursor, uint32_t cbBlock)
     1625{
     1626    if (cbBlock > pCursor->cbUnitLeft)
     1627    {
     1628        pCursor->rc = VERR_DWARF_UNEXPECTED_END;
     1629        return NULL;
     1630    }
     1631
     1632    uint8_t const *pb = &pCursor->pb[0];
     1633    pCursor->pb         += cbBlock;
     1634    pCursor->cbUnitLeft -= cbBlock;
     1635    pCursor->cbLeft     -= cbBlock;
     1636    return pb;
     1637}
     1638#endif
    13491639
    13501640
     
    16411931
    16421932    return rc;
     1933}
     1934
     1935
     1936/**
     1937 * Initialize a cursor for a block (subsection) retrieved from the given cursor.
     1938 *
     1939 * The parent cursor will be advanced past the block.
     1940 *
     1941 * @returns IPRT status code.
     1942 * @param   pCursor             The cursor.
     1943 * @param   pParent             The parent cursor. Will be moved by @a cbBlock.
     1944 * @param   cbBlock             The size of the block the new cursor should
     1945 *                              cover.
     1946 */
     1947static int rtDwarfCursor_InitForBlock(PRTDWARFCURSOR pCursor, PRTDWARFCURSOR pParent, uint32_t cbBlock)
     1948{
     1949    if (RT_FAILURE(pParent->rc))
     1950        return pParent->rc;
     1951    if (pParent->cbUnitLeft < cbBlock)
     1952    {
     1953        Log(("rtDwarfCursor_InitForBlock: cbUnitLeft=%#x < cbBlock=%#x \n", pParent->cbUnitLeft, cbBlock));
     1954        return VERR_DWARF_BAD_POS;
     1955    }
     1956
     1957    *pCursor = *pParent;
     1958    pCursor->cbLeft     = cbBlock;
     1959    pCursor->cbUnitLeft = cbBlock;
     1960
     1961    pParent->pb         += cbBlock;
     1962    pParent->cbLeft     -= cbBlock;
     1963    pParent->cbUnitLeft -= cbBlock;
     1964
     1965    return VINF_SUCCESS;
    16431966}
    16441967
     
    19552278                            if (RT_SUCCESS(rc))
    19562279                                rc = rtDwarfLine_DefineFileName(pLnState, pszFilename, idxInc);
     2280                            break;
    19572281                        }
    19582282
     
    19722296                            {
    19732297                                uint64_t uSeg = rtDwarfCursor_GetVarSizedU(pCursor, cbInstr - 1, UINT64_MAX);
    1974                                 Log2(("%08x: DW_LNE_set_segment: %ll#x - Watcom Extension\n", offOpCode, uSeg));
     2298                                Log2(("%08x: DW_LNE_set_segment: %#llx, cbInstr=%#x - Watcom Extension\n", offOpCode, uSeg, cbInstr));
    19752299                                NOREF(uSeg);
    19762300                                /** @todo make use of this? */
     
    24092733 *                              pCursor->rc is set).
    24102734 */
    2411 static const char *rtDwarfDecode_GetStrp(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor, const char *pszErrValue)
     2735static const char *rtDwarfDecodeHlp_GetStrp(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor, const char *pszErrValue)
    24122736{
    24132737    uint64_t offDebugStr = rtDwarfCursor_GetUOff(pCursor, UINT64_MAX);
     
    24422766{
    24432767    AssertReturn(ATTR_GET_SIZE(pDesc) == sizeof(RTDWARFADDR), VERR_INTERNAL_ERROR_3);
     2768    NOREF(pDie);
     2769
     2770    uint64_t uAddr;
     2771    switch (uForm)
     2772    {
     2773        case DW_FORM_addr:  uAddr = rtDwarfCursor_GetNativeUOff(pCursor, 0); break;
     2774        case DW_FORM_data1: uAddr = rtDwarfCursor_GetU8(pCursor, 0); break;
     2775        case DW_FORM_data2: uAddr = rtDwarfCursor_GetU16(pCursor, 0); break;
     2776        case DW_FORM_data4: uAddr = rtDwarfCursor_GetU32(pCursor, 0); break;
     2777        case DW_FORM_data8: uAddr = rtDwarfCursor_GetU64(pCursor, 0); break;
     2778        case DW_FORM_udata: uAddr = rtDwarfCursor_GetULeb128(pCursor, 0); break;
     2779        default:
     2780            AssertMsgFailedReturn(("%#x (%s)\n", uForm, rtDwarfLog_FormName(uForm)), VERR_DWARF_UNEXPECTED_FORM);
     2781    }
     2782    if (RT_FAILURE(pCursor->rc))
     2783        return pCursor->rc;
     2784
     2785    PRTDWARFADDR pAddr = (PRTDWARFADDR)pbMember;
     2786    pAddr->uAddress = uAddr;
     2787
     2788    Log4(("          %-20s  %#010llx  [%s]\n", rtDwarfLog_AttrName(pDesc->uAttr), uAddr, rtDwarfLog_FormName(uForm)));
     2789    return VINF_SUCCESS;
     2790}
     2791
     2792
     2793/** @callback_method_impl{FNRTDWARFATTRDECODER} */
     2794static DECLCALLBACK(int) rtDwarfDecode_Bool(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc,
     2795                                            uint32_t uForm, PRTDWARFCURSOR pCursor)
     2796{
     2797    AssertReturn(ATTR_GET_SIZE(pDesc) == sizeof(bool), VERR_INTERNAL_ERROR_3);
     2798    NOREF(pDie);
     2799
     2800    bool *pfMember = (bool *)pbMember;
     2801    switch (uForm)
     2802    {
     2803        case DW_FORM_flag:
     2804        {
     2805            uint8_t b = rtDwarfCursor_GetU8(pCursor, UINT8_MAX);
     2806            if (b > 1)
     2807            {
     2808                Log(("Unexpected boolean value %#x\n", b));
     2809                return RT_FAILURE(pCursor->rc) ? pCursor->rc : pCursor->rc = VERR_DWARF_BAD_INFO;
     2810            }
     2811            *pfMember = RT_BOOL(b);
     2812            break;
     2813        }
     2814
     2815        case DW_FORM_flag_present:
     2816            *pfMember = true;
     2817            break;
     2818
     2819        default:
     2820            AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM);
     2821    }
     2822
     2823    Log4(("          %-20s  %RTbool  [%s]\n", rtDwarfLog_AttrName(pDesc->uAttr), *pfMember, rtDwarfLog_FormName(uForm)));
     2824    return VINF_SUCCESS;
     2825}
     2826
     2827
     2828/** @callback_method_impl{FNRTDWARFATTRDECODER} */
     2829static DECLCALLBACK(int) rtDwarfDecode_LowHighPc(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc,
     2830                                                 uint32_t uForm, PRTDWARFCURSOR pCursor)
     2831{
     2832    AssertReturn(ATTR_GET_SIZE(pDesc) == sizeof(RTDWARFADDRRANGE), VERR_INTERNAL_ERROR_3);
     2833    AssertReturn(pDesc->uAttr == DW_AT_low_pc || pDesc->uAttr == DW_AT_high_pc, VERR_INTERNAL_ERROR_3);
    24442834    NOREF(pDie);
    24452835
     
    24592849        return pCursor->rc;
    24602850
    2461     PRTDWARFADDR pAddr = (PRTDWARFADDR)pbMember;
    2462     pAddr->uAddress = uAddr;
    2463 
    2464     return VINF_SUCCESS;
    2465 }
    2466 
    2467 
    2468 /** @callback_method_impl{FNRTDWARFATTRDECODER} */
    2469 static DECLCALLBACK(int) rtDwarfDecode_Bool(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc,
    2470                                             uint32_t uForm, PRTDWARFCURSOR pCursor)
    2471 {
    2472     AssertReturn(ATTR_GET_SIZE(pDesc) == sizeof(bool), VERR_INTERNAL_ERROR_3);
    2473     NOREF(pDie);
    2474 
    2475     bool *pfMember = (bool *)pbMember;
    2476     switch (uForm)
    2477     {
    2478         case DW_FORM_flag:
    2479         {
    2480             uint8_t b = rtDwarfCursor_GetU8(pCursor, UINT8_MAX);
    2481             if (b > 1)
    2482                 return RT_FAILURE(pCursor->rc) ? pCursor->rc : pCursor->rc = VERR_DWARF_BAD_INFO;
    2483             *pfMember = RT_BOOL(b);
    2484             break;
    2485         }
    2486 
    2487         case DW_FORM_flag_present:
    2488             *pfMember = true;
    2489             break;
    2490 
    2491         default:
    2492             AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM);
    2493     }
    2494 
    2495     return VINF_SUCCESS;
    2496 }
    2497 
    2498 
    2499 /** @callback_method_impl{FNRTDWARFATTRDECODER} */
    2500 static DECLCALLBACK(int) rtDwarfDecode_LowHighPc(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc,
    2501                                                  uint32_t uForm, PRTDWARFCURSOR pCursor)
    2502 {
    2503     AssertReturn(ATTR_GET_SIZE(pDesc) == sizeof(RTDWARFADDRRANGE), VERR_INTERNAL_ERROR_3);
    2504     AssertReturn(pDesc->uAttr == DW_AT_low_pc || pDesc->uAttr == DW_AT_high_pc, VERR_INTERNAL_ERROR_3);
    2505     NOREF(pDie);
    2506 
    2507     uint64_t uAddr;
    2508     switch (uForm)
    2509     {
    2510         case DW_FORM_addr:  uAddr = rtDwarfCursor_GetNativeUOff(pCursor, 0); break;
    2511         case DW_FORM_data1: uAddr = rtDwarfCursor_GetU8(pCursor, 0); break;
    2512         case DW_FORM_data2: uAddr = rtDwarfCursor_GetU16(pCursor, 0); break;
    2513         case DW_FORM_data4: uAddr = rtDwarfCursor_GetU32(pCursor, 0); break;
    2514         case DW_FORM_data8: uAddr = rtDwarfCursor_GetU64(pCursor, 0); break;
    2515         case DW_FORM_udata: uAddr = rtDwarfCursor_GetULeb128(pCursor, 0); break;
    2516         default:
    2517             AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM);
    2518     }
    2519     if (RT_FAILURE(pCursor->rc))
    2520         return pCursor->rc;
    2521 
    25222851    PRTDWARFADDRRANGE pRange = (PRTDWARFADDRRANGE)pbMember;
    25232852    if (pDesc->uAttr == DW_AT_low_pc)
     
    25432872    pRange->cAttrs++;
    25442873
     2874    Log4(("          %-20s  %#010llx  [%s]\n", rtDwarfLog_AttrName(pDesc->uAttr), uAddr, rtDwarfLog_FormName(uForm)));
    25452875    return VINF_SUCCESS;
    25462876}
     
    25942924    pRange->pbRanges    = (uint8_t const *)pThis->aSections[krtDbgModDwarfSect_ranges].pv + (size_t)off;
    25952925
     2926    Log4(("          %-20s  TODO  [%s]\n", rtDwarfLog_AttrName(pDesc->uAttr), rtDwarfLog_FormName(uForm)));
    25962927    return VINF_SUCCESS;
    25972928}
     
    26582989    pRef->off    = off;
    26592990
     2991    Log4(("          %-20s  %d:%#010llx  [%s]\n", rtDwarfLog_AttrName(pDesc->uAttr), enmWrt, off, rtDwarfLog_FormName(uForm)));
    26602992    return VINF_SUCCESS;
    26612993}
     
    26763008        case DW_FORM_sec_offset: off = rtDwarfCursor_GetUOff(pCursor, 0); break;
    26773009        default:
    2678             AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM);
     3010            AssertMsgFailedReturn(("%#x (%s)\n", uForm, rtDwarfLog_FormName(uForm)), VERR_DWARF_UNEXPECTED_FORM);
    26793011    }
    26803012    if (RT_FAILURE(pCursor->rc))
     
    26883020        case DW_AT_macro_info:  enmSect = krtDbgModDwarfSect_loc;     enmWrt = krtDwarfRef_LocSection;     break;
    26893021        case DW_AT_ranges:      enmSect = krtDbgModDwarfSect_ranges;  enmWrt = krtDwarfRef_RangesSection;  break;
    2690         default:                AssertMsgFailedReturn(("%u\n", pDesc->uAttr), VERR_INTERNAL_ERROR_4);
    2691     }
    2692     if (off >= pCursor->pDwarfMod->aSections[enmSect].cb)
    2693     {
    2694         Log(("rtDwarfDecode_SectOff: bad off=%#llx, attr %#x\n", off, pDesc->uAttr));
    2695         return pCursor->rc = VERR_DWARF_BAD_POS;
     3022        default:
     3023            AssertMsgFailedReturn(("%u (%s)\n", pDesc->uAttr, rtDwarfLog_AttrName(pDesc->uAttr)), VERR_INTERNAL_ERROR_4);
     3024    }
     3025    size_t cbSect = pCursor->pDwarfMod->aSections[enmSect].cb;
     3026    if (off >= cbSect)
     3027    {
     3028        /* Watcom generates offset past the end of the section, increasing the
     3029           offset by one for each compile unit. So, just fudge it. */
     3030        Log(("rtDwarfDecode_SectOff: bad off=%#llx, attr %#x (%s), enmSect=%d cb=%#llx; Assuming watcom.\n", off,
     3031             pDesc->uAttr, rtDwarfLog_AttrName(pDesc->uAttr), enmSect, cbSect));
     3032        off = cbSect;
    26963033    }
    26973034
     
    27003037    pRef->off    = off;
    27013038
     3039    Log4(("          %-20s  %d:%#010llx  [%s]\n", rtDwarfLog_AttrName(pDesc->uAttr), enmWrt, off, rtDwarfLog_FormName(uForm)));
    27023040    return VINF_SUCCESS;
    27033041}
     
    27113049    NOREF(pDie);
    27123050
     3051    const char *psz;
    27133052    switch (uForm)
    27143053    {
    27153054        case DW_FORM_string:
    2716             *(const char **)pbMember = rtDwarfCursor_GetSZ(pCursor, NULL);
     3055            psz = rtDwarfCursor_GetSZ(pCursor, NULL);
    27173056            break;
    27183057
    27193058        case DW_FORM_strp:
    2720             *(const char **)pbMember = rtDwarfDecode_GetStrp(pCursor->pDwarfMod, pCursor, NULL);
     3059            psz = rtDwarfDecodeHlp_GetStrp(pCursor->pDwarfMod, pCursor, NULL);
    27213060            break;
    27223061
     
    27253064    }
    27263065
     3066    *(const char **)pbMember = psz;
     3067    Log4(("          %-20s  '%s'  [%s]\n", rtDwarfLog_AttrName(pDesc->uAttr), psz, rtDwarfLog_FormName(uForm)));
    27273068    return pCursor->rc;
    27283069}
     
    27813122
    27823123
     3124/**
     3125 * Initialize location interpreter state from cursor & form.
     3126 *
     3127 * @returns IPRT status code.
     3128 * @retval  VERR_NOT_FOUND if no location information (i.e. there is source but
     3129 *          it resulted in no byte code).
     3130 * @param   pLoc                The location state structure to initialize.
     3131 * @param   pCursor             The cursor to read from.
     3132 * @param   uForm               The attribute form.
     3133 */
     3134static int rtDwarfLoc_Init(PRTDWARFLOCST pLoc, PRTDWARFCURSOR pCursor, uint32_t uForm)
     3135{
     3136    uint32_t cbBlock;
     3137    switch (uForm)
     3138    {
     3139        case DW_FORM_block1:
     3140            cbBlock = rtDwarfCursor_GetU8(pCursor, 0);
     3141            break;
     3142
     3143        case DW_FORM_block2:
     3144            cbBlock = rtDwarfCursor_GetU16(pCursor, 0);
     3145            break;
     3146
     3147        case DW_FORM_block4:
     3148            cbBlock = rtDwarfCursor_GetU32(pCursor, 0);
     3149            break;
     3150
     3151        case DW_FORM_block:
     3152            cbBlock = rtDwarfCursor_GetULeb128(pCursor, 0);
     3153            break;
     3154
     3155        default:
     3156            AssertMsgFailedReturn(("uForm=%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM);
     3157    }
     3158    if (!cbBlock)
     3159        return VERR_NOT_FOUND;
     3160
     3161    int rc = rtDwarfCursor_InitForBlock(&pLoc->Cursor, pCursor, cbBlock);
     3162    if (RT_FAILURE(rc))
     3163        return rc;
     3164    pLoc->iTop = -1;
     3165    return VINF_SUCCESS;
     3166}
     3167
     3168
     3169/**
     3170 * Pushes a value onto the stack.
     3171 *
     3172 * @returns VINF_SUCCESS or VERR_DWARF_STACK_OVERFLOW.
     3173 * @param   pLoc                The state.
     3174 * @param   uValue              The value to push.
     3175 */
     3176static int rtDwarfLoc_Push(PRTDWARFLOCST pLoc, uint64_t uValue)
     3177{
     3178    int iTop = pLoc->iTop + 1;
     3179    AssertReturn((unsigned)iTop < RT_ELEMENTS(pLoc->auStack), VERR_DWARF_STACK_OVERFLOW);
     3180    pLoc->auStack[iTop] = uValue;
     3181    pLoc->iTop = iTop;
     3182    return VINF_SUCCESS;
     3183}
     3184
     3185
     3186static int rtDwarfLoc_Evaluate(PRTDWARFLOCST pLoc, void *pvLater, void *pvUser)
     3187{
     3188    while (!rtDwarfCursor_IsAtEndOfUnit(&pLoc->Cursor))
     3189    {
     3190        /* Read the next opcode.*/
     3191        uint8_t const bOpcode = rtDwarfCursor_GetU8(&pLoc->Cursor, 0);
     3192
     3193        /* Get its operands. */
     3194        uint64_t uOperand1 = 0;
     3195        uint64_t uOperand2 = 0;
     3196        switch (bOpcode)
     3197        {
     3198            case DW_OP_addr:
     3199                uOperand1 = rtDwarfCursor_GetNativeUOff(&pLoc->Cursor, 0);
     3200                break;
     3201            case DW_OP_pick:
     3202            case DW_OP_const1u:
     3203            case DW_OP_deref_size:
     3204            case DW_OP_xderef_size:
     3205                uOperand1 = rtDwarfCursor_GetU8(&pLoc->Cursor, 0);
     3206                break;
     3207            case DW_OP_const1s:
     3208                uOperand1 = (int8_t)rtDwarfCursor_GetU8(&pLoc->Cursor, 0);
     3209                break;
     3210            case DW_OP_const2u:
     3211                uOperand1 = rtDwarfCursor_GetU16(&pLoc->Cursor, 0);
     3212                break;
     3213            case DW_OP_skip:
     3214            case DW_OP_bra:
     3215            case DW_OP_const2s:
     3216                uOperand1 = (int16_t)rtDwarfCursor_GetU16(&pLoc->Cursor, 0);
     3217                break;
     3218            case DW_OP_const4u:
     3219                uOperand1 = rtDwarfCursor_GetU32(&pLoc->Cursor, 0);
     3220                break;
     3221            case DW_OP_const4s:
     3222                uOperand1 = (int32_t)rtDwarfCursor_GetU32(&pLoc->Cursor, 0);
     3223                break;
     3224            case DW_OP_const8u:
     3225                uOperand1 = rtDwarfCursor_GetU64(&pLoc->Cursor, 0);
     3226                break;
     3227            case DW_OP_const8s:
     3228                uOperand1 = rtDwarfCursor_GetU64(&pLoc->Cursor, 0);
     3229                break;
     3230            case DW_OP_regx:
     3231            case DW_OP_piece:
     3232            case DW_OP_plus_uconst:
     3233            case DW_OP_constu:
     3234                uOperand1 = rtDwarfCursor_GetULeb128(&pLoc->Cursor, 0);
     3235                break;
     3236            case DW_OP_consts:
     3237            case DW_OP_fbreg:
     3238            case DW_OP_breg0+0: case DW_OP_breg0+1: case DW_OP_breg0+2: case DW_OP_breg0+3:
     3239            case DW_OP_breg0+4: case DW_OP_breg0+5: case DW_OP_breg0+6: case DW_OP_breg0+7:
     3240            case DW_OP_breg0+8: case DW_OP_breg0+9: case DW_OP_breg0+10: case DW_OP_breg0+11:
     3241            case DW_OP_breg0+12: case DW_OP_breg0+13: case DW_OP_breg0+14: case DW_OP_breg0+15:
     3242            case DW_OP_breg0+16: case DW_OP_breg0+17: case DW_OP_breg0+18: case DW_OP_breg0+19:
     3243            case DW_OP_breg0+20: case DW_OP_breg0+21: case DW_OP_breg0+22: case DW_OP_breg0+23:
     3244            case DW_OP_breg0+24: case DW_OP_breg0+25: case DW_OP_breg0+26: case DW_OP_breg0+27:
     3245            case DW_OP_breg0+28: case DW_OP_breg0+29: case DW_OP_breg0+30: case DW_OP_breg0+31:
     3246                uOperand1 = rtDwarfCursor_GetSLeb128(&pLoc->Cursor, 0);
     3247                break;
     3248            case DW_OP_bregx:
     3249                uOperand1 = rtDwarfCursor_GetULeb128(&pLoc->Cursor, 0);
     3250                uOperand2 = rtDwarfCursor_GetSLeb128(&pLoc->Cursor, 0);
     3251                break;
     3252        }
     3253        if (RT_FAILURE(pLoc->Cursor.rc))
     3254            break;
     3255
     3256        /* Interpret the opcode. */
     3257        int rc;
     3258        switch (bOpcode)
     3259        {
     3260            case DW_OP_const1u:
     3261            case DW_OP_const1s:
     3262            case DW_OP_const2u:
     3263            case DW_OP_const2s:
     3264            case DW_OP_const4u:
     3265            case DW_OP_const4s:
     3266            case DW_OP_const8u:
     3267            case DW_OP_const8s:
     3268            case DW_OP_constu:
     3269            case DW_OP_consts:
     3270            case DW_OP_addr:
     3271                rc = rtDwarfLoc_Push(pLoc, uOperand1);
     3272                break;
     3273            case DW_OP_lit0 +  0: case DW_OP_lit0 +  1: case DW_OP_lit0 +  2: case DW_OP_lit0 +  3:
     3274            case DW_OP_lit0 +  4: case DW_OP_lit0 +  5: case DW_OP_lit0 +  6: case DW_OP_lit0 +  7:
     3275            case DW_OP_lit0 +  8: case DW_OP_lit0 +  9: case DW_OP_lit0 + 10: case DW_OP_lit0 + 11:
     3276            case DW_OP_lit0 + 12: case DW_OP_lit0 + 13: case DW_OP_lit0 + 14: case DW_OP_lit0 + 15:
     3277            case DW_OP_lit0 + 16: case DW_OP_lit0 + 17: case DW_OP_lit0 + 18: case DW_OP_lit0 + 19:
     3278            case DW_OP_lit0 + 20: case DW_OP_lit0 + 21: case DW_OP_lit0 + 22: case DW_OP_lit0 + 23:
     3279            case DW_OP_lit0 + 24: case DW_OP_lit0 + 25: case DW_OP_lit0 + 26: case DW_OP_lit0 + 27:
     3280            case DW_OP_lit0 + 28: case DW_OP_lit0 + 29: case DW_OP_lit0 + 30: case DW_OP_lit0 + 31:
     3281                rc = rtDwarfLoc_Push(pLoc, bOpcode - DW_OP_lit0);
     3282                break;
     3283            case DW_OP_nop:
     3284                break;
     3285            case DW_OP_dup:               /** @todo 0 operands. */
     3286            case DW_OP_drop:              /** @todo 0 operands. */
     3287            case DW_OP_over:              /** @todo 0 operands. */
     3288            case DW_OP_pick:              /** @todo 1 operands, a 1-byte stack index. */
     3289            case DW_OP_swap:              /** @todo 0 operands. */
     3290            case DW_OP_rot:               /** @todo 0 operands. */
     3291            case DW_OP_abs:               /** @todo 0 operands. */
     3292            case DW_OP_and:               /** @todo 0 operands. */
     3293            case DW_OP_div:               /** @todo 0 operands. */
     3294            case DW_OP_minus:             /** @todo 0 operands. */
     3295            case DW_OP_mod:               /** @todo 0 operands. */
     3296            case DW_OP_mul:               /** @todo 0 operands. */
     3297            case DW_OP_neg:               /** @todo 0 operands. */
     3298            case DW_OP_not:               /** @todo 0 operands. */
     3299            case DW_OP_or:                /** @todo 0 operands. */
     3300            case DW_OP_plus:              /** @todo 0 operands. */
     3301            case DW_OP_plus_uconst:       /** @todo 1 operands, a ULEB128 addend. */
     3302            case DW_OP_shl:               /** @todo 0 operands. */
     3303            case DW_OP_shr:               /** @todo 0 operands. */
     3304            case DW_OP_shra:              /** @todo 0 operands. */
     3305            case DW_OP_xor:               /** @todo 0 operands. */
     3306            case DW_OP_skip:              /** @todo 1 signed 2-byte constant. */
     3307            case DW_OP_bra:               /** @todo 1 signed 2-byte constant. */
     3308            case DW_OP_eq:                /** @todo 0 operands. */
     3309            case DW_OP_ge:                /** @todo 0 operands. */
     3310            case DW_OP_gt:                /** @todo 0 operands. */
     3311            case DW_OP_le:                /** @todo 0 operands. */
     3312            case DW_OP_lt:                /** @todo 0 operands. */
     3313            case DW_OP_ne:                /** @todo 0 operands. */
     3314            case DW_OP_reg0 +  0: case DW_OP_reg0 +  1: case DW_OP_reg0 +  2: case DW_OP_reg0 +  3: /** @todo 0 operands - reg 0..31. */
     3315            case DW_OP_reg0 +  4: case DW_OP_reg0 +  5: case DW_OP_reg0 +  6: case DW_OP_reg0 +  7:
     3316            case DW_OP_reg0 +  8: case DW_OP_reg0 +  9: case DW_OP_reg0 + 10: case DW_OP_reg0 + 11:
     3317            case DW_OP_reg0 + 12: case DW_OP_reg0 + 13: case DW_OP_reg0 + 14: case DW_OP_reg0 + 15:
     3318            case DW_OP_reg0 + 16: case DW_OP_reg0 + 17: case DW_OP_reg0 + 18: case DW_OP_reg0 + 19:
     3319            case DW_OP_reg0 + 20: case DW_OP_reg0 + 21: case DW_OP_reg0 + 22: case DW_OP_reg0 + 23:
     3320            case DW_OP_reg0 + 24: case DW_OP_reg0 + 25: case DW_OP_reg0 + 26: case DW_OP_reg0 + 27:
     3321            case DW_OP_reg0 + 28: case DW_OP_reg0 + 29: case DW_OP_reg0 + 30: case DW_OP_reg0 + 31:
     3322            case DW_OP_breg0+  0: case DW_OP_breg0+  1: case DW_OP_breg0+  2: case DW_OP_breg0+  3: /** @todo 1 operand, a SLEB128 offset. */
     3323            case DW_OP_breg0+  4: case DW_OP_breg0+  5: case DW_OP_breg0+  6: case DW_OP_breg0+  7:
     3324            case DW_OP_breg0+  8: case DW_OP_breg0+  9: case DW_OP_breg0+ 10: case DW_OP_breg0+ 11:
     3325            case DW_OP_breg0+ 12: case DW_OP_breg0+ 13: case DW_OP_breg0+ 14: case DW_OP_breg0+ 15:
     3326            case DW_OP_breg0+ 16: case DW_OP_breg0+ 17: case DW_OP_breg0+ 18: case DW_OP_breg0+ 19:
     3327            case DW_OP_breg0+ 20: case DW_OP_breg0+ 21: case DW_OP_breg0+ 22: case DW_OP_breg0+ 23:
     3328            case DW_OP_breg0+ 24: case DW_OP_breg0+ 25: case DW_OP_breg0+ 26: case DW_OP_breg0+ 27:
     3329            case DW_OP_breg0+ 28: case DW_OP_breg0+ 29: case DW_OP_breg0+ 30: case DW_OP_breg0+ 31:
     3330            case DW_OP_piece:             /** @todo 1 operand, a ULEB128 size of piece addressed. */
     3331            case DW_OP_regx:              /** @todo 1 operand, a ULEB128 register. */
     3332            case DW_OP_fbreg:             /** @todo 1 operand, a SLEB128 offset. */
     3333            case DW_OP_bregx:             /** @todo 2 operands, a ULEB128 register followed by a SLEB128 offset. */
     3334            case DW_OP_deref:             /** @todo 0 operands. */
     3335            case DW_OP_deref_size:        /** @todo 1 operand, a 1-byte size of data retrieved. */
     3336            case DW_OP_xderef:            /** @todo 0 operands. */
     3337            case DW_OP_xderef_size:        /** @todo 1 operand, a 1-byte size of data retrieved. */
     3338                AssertMsgFailedReturn(("bOpcode=%#x\n", bOpcode), VERR_DWARF_TODO);
     3339            default:
     3340                AssertMsgFailedReturn(("bOpcode=%#x\n", bOpcode), VERR_DWARF_UNKNOWN_LOC_OPCODE);
     3341        }
     3342    }
     3343
     3344    return pLoc->Cursor.rc;
     3345}
     3346
     3347
     3348/** @callback_method_impl{FNRTDWARFATTRDECODER} */
     3349static DECLCALLBACK(int) rtDwarfDecode_SegmentLoc(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc,
     3350                                                  uint32_t uForm, PRTDWARFCURSOR pCursor)
     3351{
     3352    NOREF(pDie);
     3353    AssertReturn(ATTR_GET_SIZE(pDesc) == 2, VERR_DWARF_IPE);
     3354
     3355    RTDWARFLOCST LocSt;
     3356    int rc = rtDwarfLoc_Init(&LocSt, pCursor, uForm);
     3357    if (RT_SUCCESS(rc))
     3358    {
     3359        rc = rtDwarfLoc_Evaluate(&LocSt, NULL, NULL);
     3360        if (RT_SUCCESS(rc))
     3361        {
     3362            if (LocSt.iTop >= 0)
     3363                *(uint16_t *)pbMember = LocSt.auStack[LocSt.iTop];
     3364            else
     3365                rc = VERR_DWARF_STACK_UNDERFLOW;
     3366        }
     3367    }
     3368    return rc;
     3369}
    27833370
    27843371/*
     
    30643651            pDie->cUnhandledAttrs++;
    30653652            rc = rtDwarfInfo_SkipForm(pCursor, uForm);
     3653            Log4(("          %-20s    [%s]\n", rtDwarfLog_AttrName(uAttr), rtDwarfLog_FormName(uForm)));
    30663654        }
    30673655        if (RT_FAILURE(rc))
     
    31223710     */
    31233711    if (offAbbrev > UINT32_MAX)
     3712    {
     3713        Log(("Unexpected abbrviation code offset of %#llx\n", offAbbrev));
    31243714        return VERR_DWARF_BAD_INFO;
     3715    }
    31253716    rtDwarfAbbrev_SetUnitOffset(pThis, (uint32_t)offAbbrev);
    31263717    pCursor->cbNativeAddr = cbNativeAddr;
     
    31313722    uint32_t uAbbrCode = rtDwarfCursor_GetULeb128AsU32(pCursor, UINT32_MAX);
    31323723    if (!uAbbrCode)
     3724    {
     3725        Log(("Unexpected abbrviation code of zero\n"));
    31333726        return VERR_DWARF_BAD_INFO;
     3727    }
    31343728    PCRTDWARFABBREV pAbbrev = rtDwarfAbbrev_Lookup(pThis, uAbbrCode);
    31353729    if (!pAbbrev)
     
    31643758    while (!rtDwarfCursor_IsAtEndOfUnit(pCursor))
    31653759    {
     3760#ifdef LOG_ENABLED
     3761        uint32_t offLog = rtDwarfCursor_CalcSectOffsetU32(pCursor);
     3762#endif
    31663763        uAbbrCode = rtDwarfCursor_GetULeb128AsU32(pCursor, UINT32_MAX);
    31673764        if (!uAbbrCode)
    31683765        {
    3169             /* End of siblings, up one level. */
     3766            /* End of siblings, up one level. (Is this correct?) */
    31703767            pParentDie = pParentDie->pParent;
    31713768            if (!pParentDie)
    31723769            {
    3173                 if (!rtDwarfCursor_IsAtEndOfUnit(pCursor))
    3174                     return VERR_DWARF_BAD_INFO;
     3770                /* Padding. */
     3771                while (!rtDwarfCursor_IsAtEndOfUnit(pCursor))
     3772                {
     3773                    uAbbrCode = rtDwarfCursor_GetULeb128AsU32(pCursor, UINT32_MAX);
     3774                    if (uAbbrCode)
     3775                    {
     3776                        Log(("%08x: End of DIE stack, but still more info to parse: uAbbrCode=%#x (+%u bytes).\n",
     3777                             offLog, uAbbrCode, pCursor->cbUnitLeft));
     3778                        return VERR_DWARF_BAD_INFO;
     3779                    }
     3780                }
    31753781                break;
    31763782            }
     
    32103816                pDieDesc = g_aTagDescs[0].pDesc;
    32113817            }
    3212             Log4((" %*stag=%s (%#x)%s\n", cDepth * 2, "", pszName,
     3818            Log4(("%08x: %*stag=%s (%#x)%s\n", offLog, cDepth * 2, "", pszName,
    32133819                  pAbbrev->uTag, pAbbrev->fChildren ? " has children" : ""));
    32143820
     
    34334039     * or underscores.
    34344040     */
    3435     if (!strncmp(pszPartNm, ".debug_", sizeof(".debug_") - 1))        /* ELF */
     4041    if (!strncmp(pszPartNm, RT_STR_TUPLE(".debug_")))       /* ELF */
    34364042        pszPartNm += sizeof(".debug_") - 1;
    3437     else if (!strncmp(pszPartNm, "__debug_", sizeof("__debug_") - 1)) /* Mach-O */
     4043    else if (!strncmp(pszPartNm, RT_STR_TUPLE("__debug_"))) /* Mach-O */
    34384044        pszPartNm += sizeof("__debug_") - 1;
     4045    else if (!strcmp(pszPartNm, ".WATCOM_references"))
     4046        return VINF_SUCCESS; /* Ignore special watcom section for now.*/
    34394047    else
    34404048        AssertMsgFailedReturn(("%s\n", pszPartNm), VINF_SUCCESS /*ignore*/);
  • trunk/src/VBox/Runtime/common/ldr/ldrELFRelocatable.cpp.h

    r44528 r45968  
    105105     * Not valid if the image is DONE. */
    106106    Elf_Shdr               *paShdrs;
     107    /** Unmodified section headers (allocated after paShdrs, so no need to free).
     108     * Not valid if the image is DONE. */
     109    Elf_Shdr const         *paOrgShdrs;
    107110    /** The size of the loaded image. */
    108111    size_t                  cbImage;
     
    731734{
    732735    PRTLDRMODELF pModElf = (PRTLDRMODELF)pMod;
    733     NOREF(pvBits);
    734 
    735     return VERR_NOT_IMPLEMENTED; NOREF(pModElf); NOREF(pfnCallback); NOREF(pvUser);
    736 }
    737 
     736
     737    /*
     738     * Map the image bits if not already done and setup pointer into it.
     739     */
     740    int rc = RTLDRELF_NAME(MapBits)(pModElf, true);
     741    if (RT_FAILURE(rc))
     742        return rc;
     743
     744    /*
     745     * Do the enumeration.
     746     */
     747    const Elf_Shdr *paShdrs = pModElf->paOrgShdrs;
     748    for (unsigned iShdr = 0; iShdr < pModElf->Ehdr.e_shnum; iShdr++)
     749    {
     750        /* Debug sections are expected to be PROGBITS and not allocated. */
     751        if (paShdrs[iShdr].sh_type != SHT_PROGBITS)
     752            continue;
     753        if (paShdrs[iShdr].sh_flags & SHF_ALLOC)
     754            continue;
     755
     756        const char *pszSectName = ELF_STR(pModElf, paShdrs[iShdr].sh_name);
     757        if (   !strncmp(pszSectName, RT_STR_TUPLE(".debug_"))
     758            || !strcmp(pszSectName, ".WATCOM_references") )
     759        {
     760            int rc = pfnCallback(pMod, iShdr - 1, RTLDRDBGINFOTYPE_DWARF, 0, 0, pszSectName,
     761                                 paShdrs[iShdr].sh_offset,
     762                                 paShdrs[iShdr].sh_addr,
     763                                 paShdrs[iShdr].sh_size,
     764                                 NULL, pvUser);
     765            if (rc != VINF_SUCCESS)
     766                return rc;
     767        }
     768        else if (!strcmp(pszSectName, ".gnu_debuglink"))
     769        {
     770            if ((paShdrs[iShdr].sh_size & 3) || paShdrs[iShdr].sh_size < 8)
     771                return VERR_BAD_EXE_FORMAT;
     772            const char     *pszExtFile = (const char *)((uintptr_t)pModElf->pvBits + paShdrs[iShdr].sh_offset);
     773            if (!RTStrEnd(pszExtFile, paShdrs[iShdr].sh_size))
     774                return VERR_BAD_EXE_FORMAT;
     775
     776            uint32_t uCrc32  = *(uint32_t *)((uintptr_t)pszExtFile + paShdrs[iShdr].sh_size - sizeof(uint32_t));
     777            char    szCrc32[16];
     778            RTStrPrintf(szCrc32, sizeof(szCrc32), "%#010x", uCrc32);
     779
     780            int rc = pfnCallback(pMod, iShdr - 1, RTLDRDBGINFOTYPE_DWARF, 0, 0, szCrc32,
     781                                 paShdrs[iShdr].sh_offset,
     782                                 paShdrs[iShdr].sh_addr,
     783                                 paShdrs[iShdr].sh_size,
     784                                 pszExtFile, pvUser);
     785            if (rc != VINF_SUCCESS)
     786                return rc;
     787        }
     788    }
     789
     790    return VINF_SUCCESS;
     791}
     792
     793
     794/**
     795 * Helper that locates the first allocated section.
     796 *
     797 * @returns Pointer to the section header if found, NULL if none.
     798 * @param   pShdr   The section header to start searching at.
     799 * @param   cLeft   The number of section headers left to search. Can be 0.
     800 */
     801static const Elf_Shdr *RTLDRELF_NAME(GetFirstAllocatedSection)(const Elf_Shdr *pShdr, unsigned cLeft)
     802{
     803    while (cLeft-- > 0)
     804    {
     805        if (pShdr->sh_flags & SHF_ALLOC)
     806            return pShdr;
     807        pShdr++;
     808    }
     809    return NULL;
     810}
    738811
    739812/** @copydoc RTLDROPS::pfnEnumSegments. */
     
    742815    PRTLDRMODELF pModElf = (PRTLDRMODELF)pMod;
    743816
    744     return VERR_NOT_IMPLEMENTED; NOREF(pModElf); NOREF(pfnCallback); NOREF(pvUser);
     817    /*
     818     * Map the image bits if not already done and setup pointer into it.
     819     */
     820    int rc = RTLDRELF_NAME(MapBits)(pModElf, true);
     821    if (RT_FAILURE(rc))
     822        return rc;
     823
     824    /*
     825     * Do the enumeration.
     826     */
     827    const Elf_Shdr *paShdrs    = pModElf->paShdrs;
     828    const Elf_Shdr *paOrgShdrs = pModElf->paOrgShdrs;
     829    for (unsigned iShdr = 1; iShdr < pModElf->Ehdr.e_shnum; iShdr++)
     830    {
     831        RTLDRSEG Seg;
     832        Seg.pchName     = ELF_STR(pModElf, paShdrs[iShdr].sh_name);
     833        Seg.cchName     = (uint32_t)strlen(Seg.pchName);
     834        Seg.SelFlat     = 0;
     835        Seg.Sel16bit    = 0;
     836        Seg.fFlags      = 0;
     837        Seg.fProt       = RTMEM_PROT_READ;
     838        if (paShdrs[iShdr].sh_flags & SHF_WRITE)
     839            Seg.fProt  |= RTMEM_PROT_WRITE;
     840        if (paShdrs[iShdr].sh_flags & SHF_EXECINSTR)
     841            Seg.fProt  |= RTMEM_PROT_EXEC;
     842        Seg.cb          = paShdrs[iShdr].sh_size;
     843        Seg.Alignment   = paShdrs[iShdr].sh_addralign;
     844        if (paShdrs[iShdr].sh_flags & SHF_ALLOC)
     845        {
     846            Seg.LinkAddress = paOrgShdrs[iShdr].sh_addr;
     847            Seg.RVA         = paShdrs[iShdr].sh_addr;
     848            const Elf_Shdr *pShdr2 = RTLDRELF_NAME(GetFirstAllocatedSection)(&paShdrs[iShdr + 1],
     849                                                                             pModElf->Ehdr.e_shnum - iShdr - 1);
     850            Seg.cbMapped    = pShdr2 ? pShdr2->sh_addr - paShdrs[iShdr].sh_addr : paShdrs[iShdr].sh_size;
     851        }
     852        else
     853        {
     854            Seg.LinkAddress = NIL_RTLDRADDR;
     855            Seg.RVA         = NIL_RTLDRADDR;
     856            Seg.cbMapped    = NIL_RTLDRADDR;
     857        }
     858        if (paShdrs[iShdr].sh_type != SHT_NOBITS)
     859        {
     860            Seg.offFile     = paShdrs[iShdr].sh_offset;
     861            Seg.cbFile      = paShdrs[iShdr].sh_size;
     862        }
     863        else
     864        {
     865            Seg.offFile     = -1;
     866            Seg.cbFile      = 0;
     867        }
     868
     869        int rc = pfnCallback(pMod, &Seg, pvUser);
     870        if (rc != VINF_SUCCESS)
     871            return rc;
     872    }
     873
     874    return VINF_SUCCESS;
    745875}
    746876
     
    752882    PRTLDRMODELF pModElf = (PRTLDRMODELF)pMod;
    753883
    754     return VERR_NOT_IMPLEMENTED; NOREF(pModElf); NOREF(LinkAddress); NOREF(piSeg); NOREF(poffSeg);
     884    const Elf_Shdr *pShdrEnd = NULL;
     885    unsigned        cLeft    = pModElf->Ehdr.e_shnum - 1;
     886    const Elf_Shdr *pShdr    = &pModElf->paOrgShdrs[cLeft];
     887    while (cLeft-- > 0)
     888    {
     889        pShdr--;
     890        if (pShdr->sh_flags & SHF_ALLOC)
     891        {
     892            RTLDRADDR offSeg = LinkAddress - pShdr->sh_addr;
     893            if (offSeg < pShdr->sh_size)
     894            {
     895                *poffSeg = offSeg;
     896                *piSeg   = cLeft;
     897                return VINF_SUCCESS;
     898            }
     899            if (offSeg == pShdr->sh_size)
     900                pShdrEnd = pShdr;
     901        }
     902    }
     903
     904    if (pShdrEnd)
     905    {
     906        *poffSeg = pShdrEnd->sh_size;
     907        *piSeg   = pShdrEnd - pModElf->paOrgShdrs - 1;
     908        return VINF_SUCCESS;
     909    }
     910
     911    return VERR_LDR_INVALID_LINK_ADDRESS;
    755912}
    756913
     
    760917{
    761918    PRTLDRMODELF pModElf = (PRTLDRMODELF)pMod;
    762 
    763     return VERR_NOT_IMPLEMENTED; NOREF(pModElf); NOREF(LinkAddress); NOREF(pRva);
     919    uint32_t     iSeg;
     920    RTLDRADDR    offSeg;
     921    int rc = RTLDRELF_NAME(LinkAddressToSegOffset)(pMod, LinkAddress, &iSeg, &offSeg);
     922    if (RT_SUCCESS(rc))
     923        *pRva = pModElf->paShdrs[iSeg].sh_addr + offSeg;
     924    return rc;
    764925}
    765926
     
    770931{
    771932    PRTLDRMODELF pModElf = (PRTLDRMODELF)pMod;
    772 
    773     return VERR_NOT_IMPLEMENTED; NOREF(pModElf); NOREF(iSeg); NOREF(offSeg); NOREF(pRva);
     933    if (iSeg >= pModElf->Ehdr.e_shnum - 1U)
     934        return VERR_LDR_INVALID_SEG_OFFSET;
     935
     936    iSeg++; /* skip section 0 */
     937    if (offSeg > pModElf->paShdrs[iSeg].sh_size)
     938    {
     939        const Elf_Shdr *pShdr2 = RTLDRELF_NAME(GetFirstAllocatedSection)(&pModElf->paShdrs[iSeg + 1],
     940                                                                         pModElf->Ehdr.e_shnum - iSeg - 1);
     941        if (   !pShdr2
     942            || offSeg > (pShdr2->sh_addr - pModElf->paShdrs[iSeg].sh_addr))
     943            return VERR_LDR_INVALID_SEG_OFFSET;
     944    }
     945
     946    if (!(pModElf->paShdrs[iSeg].sh_flags & SHF_ALLOC))
     947        return VERR_LDR_INVALID_SEG_OFFSET;
     948
     949    *pRva = pModElf->paShdrs[iSeg].sh_addr;
     950    return VINF_SUCCESS;
    774951}
    775952
     
    781958    PRTLDRMODELF pModElf = (PRTLDRMODELF)pMod;
    782959
    783     return VERR_NOT_IMPLEMENTED; NOREF(pModElf); NOREF(Rva); NOREF(piSeg); NOREF(poffSeg);
     960    Elf_Addr        PrevAddr = 0;
     961    unsigned        cLeft    = pModElf->Ehdr.e_shnum - 1;
     962    const Elf_Shdr *pShdr    = &pModElf->paShdrs[cLeft];
     963    while (cLeft-- > 0)
     964    {
     965        pShdr--;
     966        if (pShdr->sh_flags & SHF_ALLOC)
     967        {
     968            Elf_Addr    cbSeg  = PrevAddr ? PrevAddr - pShdr->sh_addr : pShdr->sh_size;
     969            RTLDRADDR   offSeg = Rva - pShdr->sh_addr;
     970            if (offSeg <= cbSeg)
     971            {
     972                *poffSeg = offSeg;
     973                *piSeg   = cLeft;
     974                return VINF_SUCCESS;
     975            }
     976            PrevAddr = pShdr->sh_addr;
     977        }
     978    }
     979
     980    return VERR_LDR_INVALID_RVA;
    784981}
    785982
     
    10171214          pShdr->sh_entsize));
    10181215
     1216    if (iShdr == 0)
     1217    {
     1218        if (   pShdr->sh_name       != 0
     1219            || pShdr->sh_type       != SHT_NULL
     1220            || pShdr->sh_flags      != 0
     1221            || pShdr->sh_addr       != 0
     1222            || pShdr->sh_size       != 0
     1223            || pShdr->sh_offset     != 0
     1224            || pShdr->sh_link       != SHN_UNDEF
     1225            || pShdr->sh_addralign  != 0
     1226            || pShdr->sh_entsize    != 0 )
     1227        {
     1228            Log(("RTLdrELF: %s: Bad #0 section: %.*Rhxs\n", pszLogName, sizeof(*pShdr), pShdr ));
     1229            return VERR_BAD_EXE_FORMAT;
     1230        }
     1231        return VINF_SUCCESS;
     1232    }
     1233
    10191234    if (pShdr->sh_link >= pModElf->Ehdr.e_shnum)
    10201235    {
     
    10371252
    10381253        case SHT_NULL:
     1254            break;
    10391255        case SHT_PROGBITS:
    10401256        case SHT_SYMTAB:
     
    11381354    {
    11391355        /*
    1140          * Read the section headers.
     1356         * Read the section headers, keeping a prestine copy for the module
     1357         * introspection methods.
    11411358         */
    1142         Elf_Shdr *paShdrs = (Elf_Shdr *)RTMemAlloc(pModElf->Ehdr.e_shnum * sizeof(Elf_Shdr));
     1359        size_t const cbShdrs = pModElf->Ehdr.e_shnum * sizeof(Elf_Shdr);
     1360        Elf_Shdr *paShdrs = (Elf_Shdr *)RTMemAlloc(cbShdrs * 2);
    11431361        if (paShdrs)
    11441362        {
    11451363            pModElf->paShdrs = paShdrs;
    1146             rc = pReader->pfnRead(pReader, paShdrs, pModElf->Ehdr.e_shnum * sizeof(Elf_Shdr),
    1147                                   pModElf->Ehdr.e_shoff);
     1364            rc = pReader->pfnRead(pReader, paShdrs, cbShdrs, pModElf->Ehdr.e_shoff);
    11481365            if (RT_SUCCESS(rc))
    11491366            {
     1367                memcpy(&paShdrs[pModElf->Ehdr.e_shnum], paShdrs, cbShdrs);
     1368                pModElf->paOrgShdrs = &paShdrs[pModElf->Ehdr.e_shnum];
     1369
    11501370                /*
    11511371                 * Validate the section headers, allocate memory for the sections (determine the image size),
     
    11871407                        AssertReturn(pModElf->cbStr == paShdrs[pModElf->iStrSh].sh_size, VERR_IMAGE_TOO_BIG);
    11881408                    }
     1409                    else if (paShdrs[i].sh_type == SHT_STRTAB)
     1410                    {
     1411                        pModElf->iStrSh = i;
     1412                        pModElf->cbStr  = (unsigned)paShdrs[i].sh_size;
     1413                        AssertReturn(pModElf->cbStr == paShdrs[i].sh_size, VERR_IMAGE_TOO_BIG);
     1414                    }
     1415
    11891416                } /* for each section header */
    11901417
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