Changeset 45968 in vbox
- Timestamp:
- May 9, 2013 5:12:13 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/cdefs.h
r44528 r45968 1092 1092 */ 1093 1093 #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 1094 1102 1095 1103 -
trunk/include/iprt/err.h
r45454 r45968 1480 1480 /** Encountered an unexpected attribute form. */ 1481 1481 #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) 1482 1492 /** @} */ 1483 1493 -
trunk/src/VBox/Runtime/common/dbg/dbgmoddwarf.cpp
r45936 r45968 280 280 281 281 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 282 344 /******************************************************************************* 283 345 * Structures and Typedefs * … … 603 665 604 666 667 /** 668 * DWARF Location state. 669 */ 670 typedef 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. */ 680 typedef RTDWARFLOCST *PRTDWARFLOCST; 681 682 605 683 606 684 /******************************************************************************* … … 615 693 static FNRTDWARFATTRDECODER rtDwarfDecode_String; 616 694 static FNRTDWARFATTRDECODER rtDwarfDecode_UnsignedInt; 695 static FNRTDWARFATTRDECODER rtDwarfDecode_SegmentLoc; 617 696 618 697 … … 709 788 /** The first instruction in the function. */ 710 789 RTDWARFADDR EntryPc; 790 /** Segment number (watcom). */ 791 RTSEL uSegment; 711 792 } RTDWARFDIESUBPROGRAM; 712 793 /** Pointer to a DW_TAG_subprogram DIE. */ … … 725 806 ATTR_ENTRY(DW_AT_ranges, RTDWARFDIESUBPROGRAM, PcRange, ATTR_INIT_ZERO, rtDwarfDecode_Ranges), 726 807 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) 727 809 }; 728 810 … … 821 903 822 904 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 */ 913 static 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 */ 934 static 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 */ 1043 static 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 823 1081 /** @callback_method_impl{FNRTLDRENUMSEGS} */ 824 1082 static DECLCALLBACK(int) rtDbgModHlpAddSegmentCallback(RTLDRMOD hLdrMod, PCRTLDRSEG pSeg, void *pvUser) … … 828 1086 pSeg->cchName, pSeg->pchName, (uint64_t)pSeg->LinkAddress, (uint64_t)pSeg->RVA, pSeg->cb)); 829 1087 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 830 1094 RTLDRADDR cb = RT_MAX(pSeg->cb, pSeg->cbMapped); 831 1095 #if 1 … … 1347 1611 return u64Ret; 1348 1612 } 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 */ 1624 static 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 1349 1639 1350 1640 … … 1641 1931 1642 1932 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 */ 1947 static 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; 1643 1966 } 1644 1967 … … 1955 2278 if (RT_SUCCESS(rc)) 1956 2279 rc = rtDwarfLine_DefineFileName(pLnState, pszFilename, idxInc); 2280 break; 1957 2281 } 1958 2282 … … 1972 2296 { 1973 2297 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)); 1975 2299 NOREF(uSeg); 1976 2300 /** @todo make use of this? */ … … 2409 2733 * pCursor->rc is set). 2410 2734 */ 2411 static const char *rtDwarfDecode _GetStrp(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor, const char *pszErrValue)2735 static const char *rtDwarfDecodeHlp_GetStrp(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor, const char *pszErrValue) 2412 2736 { 2413 2737 uint64_t offDebugStr = rtDwarfCursor_GetUOff(pCursor, UINT64_MAX); … … 2442 2766 { 2443 2767 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} */ 2794 static 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} */ 2829 static 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); 2444 2834 NOREF(pDie); 2445 2835 … … 2459 2849 return pCursor->rc; 2460 2850 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 2522 2851 PRTDWARFADDRRANGE pRange = (PRTDWARFADDRRANGE)pbMember; 2523 2852 if (pDesc->uAttr == DW_AT_low_pc) … … 2543 2872 pRange->cAttrs++; 2544 2873 2874 Log4((" %-20s %#010llx [%s]\n", rtDwarfLog_AttrName(pDesc->uAttr), uAddr, rtDwarfLog_FormName(uForm))); 2545 2875 return VINF_SUCCESS; 2546 2876 } … … 2594 2924 pRange->pbRanges = (uint8_t const *)pThis->aSections[krtDbgModDwarfSect_ranges].pv + (size_t)off; 2595 2925 2926 Log4((" %-20s TODO [%s]\n", rtDwarfLog_AttrName(pDesc->uAttr), rtDwarfLog_FormName(uForm))); 2596 2927 return VINF_SUCCESS; 2597 2928 } … … 2658 2989 pRef->off = off; 2659 2990 2991 Log4((" %-20s %d:%#010llx [%s]\n", rtDwarfLog_AttrName(pDesc->uAttr), enmWrt, off, rtDwarfLog_FormName(uForm))); 2660 2992 return VINF_SUCCESS; 2661 2993 } … … 2676 3008 case DW_FORM_sec_offset: off = rtDwarfCursor_GetUOff(pCursor, 0); break; 2677 3009 default: 2678 AssertMsgFailedReturn(("%#x \n", uForm), VERR_DWARF_UNEXPECTED_FORM);3010 AssertMsgFailedReturn(("%#x (%s)\n", uForm, rtDwarfLog_FormName(uForm)), VERR_DWARF_UNEXPECTED_FORM); 2679 3011 } 2680 3012 if (RT_FAILURE(pCursor->rc)) … … 2688 3020 case DW_AT_macro_info: enmSect = krtDbgModDwarfSect_loc; enmWrt = krtDwarfRef_LocSection; break; 2689 3021 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; 2696 3033 } 2697 3034 … … 2700 3037 pRef->off = off; 2701 3038 3039 Log4((" %-20s %d:%#010llx [%s]\n", rtDwarfLog_AttrName(pDesc->uAttr), enmWrt, off, rtDwarfLog_FormName(uForm))); 2702 3040 return VINF_SUCCESS; 2703 3041 } … … 2711 3049 NOREF(pDie); 2712 3050 3051 const char *psz; 2713 3052 switch (uForm) 2714 3053 { 2715 3054 case DW_FORM_string: 2716 *(const char **)pbMember= rtDwarfCursor_GetSZ(pCursor, NULL);3055 psz = rtDwarfCursor_GetSZ(pCursor, NULL); 2717 3056 break; 2718 3057 2719 3058 case DW_FORM_strp: 2720 *(const char **)pbMember = rtDwarfDecode_GetStrp(pCursor->pDwarfMod, pCursor, NULL);3059 psz = rtDwarfDecodeHlp_GetStrp(pCursor->pDwarfMod, pCursor, NULL); 2721 3060 break; 2722 3061 … … 2725 3064 } 2726 3065 3066 *(const char **)pbMember = psz; 3067 Log4((" %-20s '%s' [%s]\n", rtDwarfLog_AttrName(pDesc->uAttr), psz, rtDwarfLog_FormName(uForm))); 2727 3068 return pCursor->rc; 2728 3069 } … … 2781 3122 2782 3123 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 */ 3134 static 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 */ 3176 static 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 3186 static 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} */ 3349 static 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 } 2783 3370 2784 3371 /* … … 3064 3651 pDie->cUnhandledAttrs++; 3065 3652 rc = rtDwarfInfo_SkipForm(pCursor, uForm); 3653 Log4((" %-20s [%s]\n", rtDwarfLog_AttrName(uAttr), rtDwarfLog_FormName(uForm))); 3066 3654 } 3067 3655 if (RT_FAILURE(rc)) … … 3122 3710 */ 3123 3711 if (offAbbrev > UINT32_MAX) 3712 { 3713 Log(("Unexpected abbrviation code offset of %#llx\n", offAbbrev)); 3124 3714 return VERR_DWARF_BAD_INFO; 3715 } 3125 3716 rtDwarfAbbrev_SetUnitOffset(pThis, (uint32_t)offAbbrev); 3126 3717 pCursor->cbNativeAddr = cbNativeAddr; … … 3131 3722 uint32_t uAbbrCode = rtDwarfCursor_GetULeb128AsU32(pCursor, UINT32_MAX); 3132 3723 if (!uAbbrCode) 3724 { 3725 Log(("Unexpected abbrviation code of zero\n")); 3133 3726 return VERR_DWARF_BAD_INFO; 3727 } 3134 3728 PCRTDWARFABBREV pAbbrev = rtDwarfAbbrev_Lookup(pThis, uAbbrCode); 3135 3729 if (!pAbbrev) … … 3164 3758 while (!rtDwarfCursor_IsAtEndOfUnit(pCursor)) 3165 3759 { 3760 #ifdef LOG_ENABLED 3761 uint32_t offLog = rtDwarfCursor_CalcSectOffsetU32(pCursor); 3762 #endif 3166 3763 uAbbrCode = rtDwarfCursor_GetULeb128AsU32(pCursor, UINT32_MAX); 3167 3764 if (!uAbbrCode) 3168 3765 { 3169 /* End of siblings, up one level. */3766 /* End of siblings, up one level. (Is this correct?) */ 3170 3767 pParentDie = pParentDie->pParent; 3171 3768 if (!pParentDie) 3172 3769 { 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 } 3175 3781 break; 3176 3782 } … … 3210 3816 pDieDesc = g_aTagDescs[0].pDesc; 3211 3817 } 3212 Log4((" %*stag=%s (%#x)%s\n", cDepth * 2, "", pszName,3818 Log4(("%08x: %*stag=%s (%#x)%s\n", offLog, cDepth * 2, "", pszName, 3213 3819 pAbbrev->uTag, pAbbrev->fChildren ? " has children" : "")); 3214 3820 … … 3433 4039 * or underscores. 3434 4040 */ 3435 if (!strncmp(pszPartNm, ".debug_", sizeof(".debug_") - 1))/* ELF */4041 if (!strncmp(pszPartNm, RT_STR_TUPLE(".debug_"))) /* ELF */ 3436 4042 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 */ 3438 4044 pszPartNm += sizeof("__debug_") - 1; 4045 else if (!strcmp(pszPartNm, ".WATCOM_references")) 4046 return VINF_SUCCESS; /* Ignore special watcom section for now.*/ 3439 4047 else 3440 4048 AssertMsgFailedReturn(("%s\n", pszPartNm), VINF_SUCCESS /*ignore*/); -
trunk/src/VBox/Runtime/common/ldr/ldrELFRelocatable.cpp.h
r44528 r45968 105 105 * Not valid if the image is DONE. */ 106 106 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; 107 110 /** The size of the loaded image. */ 108 111 size_t cbImage; … … 731 734 { 732 735 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 */ 801 static 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 } 738 811 739 812 /** @copydoc RTLDROPS::pfnEnumSegments. */ … … 742 815 PRTLDRMODELF pModElf = (PRTLDRMODELF)pMod; 743 816 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; 745 875 } 746 876 … … 752 882 PRTLDRMODELF pModElf = (PRTLDRMODELF)pMod; 753 883 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; 755 912 } 756 913 … … 760 917 { 761 918 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; 764 925 } 765 926 … … 770 931 { 771 932 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; 774 951 } 775 952 … … 781 958 PRTLDRMODELF pModElf = (PRTLDRMODELF)pMod; 782 959 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; 784 981 } 785 982 … … 1017 1214 pShdr->sh_entsize)); 1018 1215 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 1019 1234 if (pShdr->sh_link >= pModElf->Ehdr.e_shnum) 1020 1235 { … … 1037 1252 1038 1253 case SHT_NULL: 1254 break; 1039 1255 case SHT_PROGBITS: 1040 1256 case SHT_SYMTAB: … … 1138 1354 { 1139 1355 /* 1140 * Read the section headers. 1356 * Read the section headers, keeping a prestine copy for the module 1357 * introspection methods. 1141 1358 */ 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); 1143 1361 if (paShdrs) 1144 1362 { 1145 1363 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); 1148 1365 if (RT_SUCCESS(rc)) 1149 1366 { 1367 memcpy(&paShdrs[pModElf->Ehdr.e_shnum], paShdrs, cbShdrs); 1368 pModElf->paOrgShdrs = &paShdrs[pModElf->Ehdr.e_shnum]; 1369 1150 1370 /* 1151 1371 * Validate the section headers, allocate memory for the sections (determine the image size), … … 1187 1407 AssertReturn(pModElf->cbStr == paShdrs[pModElf->iStrSh].sh_size, VERR_IMAGE_TOO_BIG); 1188 1408 } 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 1189 1416 } /* for each section header */ 1190 1417
Note:
See TracChangeset
for help on using the changeset viewer.