Changeset 38619 in vbox
- Timestamp:
- Sep 3, 2011 7:51:02 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 73826
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/dbg/dbgmoddwarf.cpp
r38617 r38619 503 503 * @{ */ 504 504 #define ATTR_INIT_ZERO UINT8_C(0x00) 505 #define ATTR_INIT_FFFS UINT8_C(0x40) 506 #define ATTR_INIT_ADDRINFO UINT8_C(0x80) 507 #define ATTR_INIT_RESERVED UINT8_C(0xc0) 508 #define ATTR_INIT_MASK UINT8_C(0xc0) 505 #define ATTR_INIT_FFFS UINT8_C(0x80) 506 #define ATTR_INIT_MASK UINT8_C(0x80) 509 507 #define ATTR_SIZE_MASK UINT8_C(0x3f) 510 508 #define ATTR_GET_SIZE(a_pAttrDesc) ((a_pAttrDesc)->cbInit & ATTR_SIZE_MASK) … … 517 515 typedef struct RTDWARFDIEDESC 518 516 { 517 /** The size of the DIE. */ 518 size_t cbDie; 519 519 /** The number of attributes. */ 520 520 size_t cAttributes; … … 523 523 } RTDWARFDIEDESC; 524 524 typedef struct RTDWARFDIEDESC const *PCRTDWARFDIEDESC; 525 /** DIE descriptor initializer. */ 526 #define DIE_DESC_INIT(a_Type, a_aAttrs) { sizeof(a_Type), RT_ELEMENTS(a_aAttrs), &a_aAttrs[0] } 525 527 526 528 … … 555 557 uint64_t uAddress; 556 558 } RTDWARFADDR; 559 typedef RTDWARFADDR *PRTDWARFADDR; 560 typedef RTDWARFADDR const *PCRTDWARFADDR; 557 561 558 562 … … 565 569 uint64_t uHighAddress; 566 570 uint8_t const *pbRanges; /* ?? */ 567 bool fHaveLowAddress : 1; 568 bool fHaveHighAddress : 1; 569 bool fHaveRanges : 1; 571 uint8_t cAttrs : 2; 572 uint8_t fHaveLowAddress : 1; 573 uint8_t fHaveHighAddress : 1; 574 uint8_t fHaveRanges : 1; 570 575 } RTDWARFADDRRANGE; 571 576 typedef RTDWARFADDRRANGE *PRTDWARFADDRRANGE; … … 602 607 * Internal Functions * 603 608 *******************************************************************************/ 609 static FNRTDWARFATTRDECODER rtDwarfDecode_Address; 604 610 static FNRTDWARFATTRDECODER rtDwarfDecode_Bool; 605 611 static FNRTDWARFATTRDECODER rtDwarfDecode_LowHighPc; … … 614 620 * Global Variables * 615 621 *******************************************************************************/ 622 /** RTDWARFDIE description. */ 623 static const RTDWARFDIEDESC g_CoreDieDesc = { sizeof(RTDWARFDIE), 0, NULL }; 624 625 616 626 /** 617 627 * DW_TAG_compile_unit & DW_TAG_partial_unit. … … 666 676 { 667 677 ATTR_ENTRY(DW_AT_name, RTDWARFDIECOMPILEUNIT, pszName, ATTR_INIT_ZERO, rtDwarfDecode_String), 678 ATTR_ENTRY(DW_AT_low_pc, RTDWARFDIECOMPILEUNIT, PcRange, ATTR_INIT_ZERO, rtDwarfDecode_LowHighPc), 668 679 ATTR_ENTRY(DW_AT_high_pc, RTDWARFDIECOMPILEUNIT, PcRange, ATTR_INIT_ZERO, rtDwarfDecode_LowHighPc), 669 680 ATTR_ENTRY(DW_AT_ranges, RTDWARFDIECOMPILEUNIT, PcRange, ATTR_INIT_ZERO, rtDwarfDecode_Ranges), 670 681 ATTR_ENTRY(DW_AT_language, RTDWARFDIECOMPILEUNIT, uLanguage, ATTR_INIT_ZERO, rtDwarfDecode_UnsignedInt), 671 ATTR_ENTRY(DW_AT_macro_info, RTDWARFDIECOMPILEUNIT, MacroInfoRef, ATTR_INIT_ FFFS, rtDwarfDecode_SectOff),672 ATTR_ENTRY(DW_AT_stmt_list, RTDWARFDIECOMPILEUNIT, StmtListRef, ATTR_INIT_ FFFS, rtDwarfDecode_SectOff),682 ATTR_ENTRY(DW_AT_macro_info, RTDWARFDIECOMPILEUNIT, MacroInfoRef, ATTR_INIT_ZERO, rtDwarfDecode_SectOff), 683 ATTR_ENTRY(DW_AT_stmt_list, RTDWARFDIECOMPILEUNIT, StmtListRef, ATTR_INIT_ZERO, rtDwarfDecode_SectOff), 673 684 ATTR_ENTRY(DW_AT_comp_dir, RTDWARFDIECOMPILEUNIT, pszCurDir, ATTR_INIT_ZERO, rtDwarfDecode_String), 674 685 ATTR_ENTRY(DW_AT_producer, RTDWARFDIECOMPILEUNIT, pszProducer, ATTR_INIT_ZERO, rtDwarfDecode_String), … … 680 691 681 692 /** RTDWARFDIECOMPILEUNIT description. */ 682 static const RTDWARFDIEDESC g_aCompileUnitDesc = { RT_ELEMENTS(g_aCompileUnitAttrs), &g_aCompileUnitAttrs[0] }; 683 684 685 #ifndef DEFINE_THESE_TAGS_TOO 686 #define DW_TAG_array_type UINT16_C(0x0001) 687 #define DW_TAG_class_type UINT16_C(0x0002) 688 #define DW_TAG_entry_point UINT16_C(0x0003) 689 #define DW_TAG_enumeration_type UINT16_C(0x0004) 690 #define DW_TAG_formal_parameter UINT16_C(0x0005) 691 #define DW_TAG_imported_declaration UINT16_C(0x0008) 692 #define DW_TAG_label UINT16_C(0x000a) 693 #define DW_TAG_lexical_block UINT16_C(0x000b) 694 #define DW_TAG_member UINT16_C(0x000d) 695 #define DW_TAG_pointer_type UINT16_C(0x000f) 696 #define DW_TAG_reference_type UINT16_C(0x0010) 697 #define DW_TAG_compile_unit UINT16_C(0x0011) 698 #define DW_TAG_string_type UINT16_C(0x0012) 699 #define DW_TAG_structure_type UINT16_C(0x0013) 700 #define DW_TAG_subroutine_type UINT16_C(0x0015) 701 #define DW_TAG_typedef UINT16_C(0x0016) 702 #define DW_TAG_union_type UINT16_C(0x0017) 703 #define DW_TAG_unspecified_parameters UINT16_C(0x0018) 704 #define DW_TAG_variant UINT16_C(0x0019) 705 #define DW_TAG_common_block UINT16_C(0x001a) 706 #define DW_TAG_common_inclusion UINT16_C(0x001b) 707 #define DW_TAG_inheritance UINT16_C(0x001c) 708 #define DW_TAG_inlined_subroutine UINT16_C(0x001d) 709 #define DW_TAG_module UINT16_C(0x001e) 710 #define DW_TAG_ptr_to_member_type UINT16_C(0x001f) 711 #define DW_TAG_set_type UINT16_C(0x0020) 712 #define DW_TAG_subrange_type UINT16_C(0x0021) 713 #define DW_TAG_with_stmt UINT16_C(0x0022) 714 #define DW_TAG_access_declaration UINT16_C(0x0023) 715 #define DW_TAG_base_type UINT16_C(0x0024) 716 #define DW_TAG_catch_block UINT16_C(0x0025) 717 #define DW_TAG_const_type UINT16_C(0x0026) 718 #define DW_TAG_constant UINT16_C(0x0027) 719 #define DW_TAG_enumerator UINT16_C(0x0028) 720 #define DW_TAG_file_type UINT16_C(0x0029) 721 #define DW_TAG_friend UINT16_C(0x002a) 722 #define DW_TAG_namelist UINT16_C(0x002b) 723 #define DW_TAG_namelist_item UINT16_C(0x002c) 724 #define DW_TAG_packed_type UINT16_C(0x002d) 725 #define DW_TAG_subprogram UINT16_C(0x002e) 726 #define DW_TAG_template_type_parameter UINT16_C(0x002f) 727 #define DW_TAG_template_value_parameter UINT16_C(0x0030) 728 #define DW_TAG_thrown_type UINT16_C(0x0031) 729 #define DW_TAG_try_block UINT16_C(0x0032) 730 #define DW_TAG_variant_part UINT16_C(0x0033) 731 #define DW_TAG_variable UINT16_C(0x0034) 732 #define DW_TAG_volatile_type UINT16_C(0x0035) 733 #define DW_TAG_dwarf_procedure UINT16_C(0x0036) 734 #define DW_TAG_restrict_type UINT16_C(0x0037) 735 #define DW_TAG_interface_type UINT16_C(0x0038) 736 #define DW_TAG_namespace UINT16_C(0x0039) 737 #define DW_TAG_imported_module UINT16_C(0x003a) 738 #define DW_TAG_unspecified_type UINT16_C(0x003b) 739 #define DW_TAG_partial_unit UINT16_C(0x003c) 740 #define DW_TAG_imported_unit UINT16_C(0x003d) 741 #define DW_TAG_condition UINT16_C(0x003f) 742 #define DW_TAG_shared_type UINT16_C(0x0040) 743 #define DW_TAG_type_unit UINT16_C(0x0041) 744 #define DW_TAG_rvalue_reference_type UINT16_C(0x0042) 745 #define DW_TAG_template_alias UINT16_C(0x0043) 746 #define DW_TAG_lo_user UINT16_C(0x4080) 747 #define DW_TAG_hi_user UINT16_C(0xffff) 748 #endif 749 750 693 static const RTDWARFDIEDESC g_CompileUnitDesc = DIE_DESC_INIT(RTDWARFDIECOMPILEUNIT, g_aCompileUnitAttrs); 694 695 696 /** 697 * DW_TAG_subprogram. 698 */ 699 typedef struct RTDWARFDIESUBPROGRAM 700 { 701 /** The DIE core structure. */ 702 RTDWARFDIE Core; 703 /** The name. */ 704 const char *pszName; 705 /** The linkage name. */ 706 const char *pszLinkageName; 707 /** The address range of the code belonging to this unit. */ 708 RTDWARFADDRRANGE PcRange; 709 /** The first instruction in the function. */ 710 RTDWARFADDR EntryPc; 711 } RTDWARFDIESUBPROGRAM; 712 /** Pointer to a DW_TAG_subprogram DIE. */ 713 typedef RTDWARFDIESUBPROGRAM *PRTDWARFDIESUBPROGRAM; 714 /** Pointer to a const DW_TAG_subprogram DIE. */ 715 typedef RTDWARFDIESUBPROGRAM const *PCRTDWARFDIESUBPROGRAM; 716 717 718 /** RTDWARFDIESUBPROGRAM attributes. */ 719 static const RTDWARFATTRDESC g_aSubProgramAttrs[] = 720 { 721 ATTR_ENTRY(DW_AT_name, RTDWARFDIESUBPROGRAM, pszName, ATTR_INIT_ZERO, rtDwarfDecode_String), 722 ATTR_ENTRY(DW_AT_linkage_name, RTDWARFDIESUBPROGRAM, pszLinkageName, ATTR_INIT_ZERO, rtDwarfDecode_String), 723 ATTR_ENTRY(DW_AT_low_pc, RTDWARFDIESUBPROGRAM, PcRange, ATTR_INIT_ZERO, rtDwarfDecode_LowHighPc), 724 ATTR_ENTRY(DW_AT_high_pc, RTDWARFDIESUBPROGRAM, PcRange, ATTR_INIT_ZERO, rtDwarfDecode_LowHighPc), 725 ATTR_ENTRY(DW_AT_ranges, RTDWARFDIESUBPROGRAM, PcRange, ATTR_INIT_ZERO, rtDwarfDecode_Ranges), 726 ATTR_ENTRY(DW_AT_entry_pc, RTDWARFDIESUBPROGRAM, EntryPc, ATTR_INIT_ZERO, rtDwarfDecode_Address), 727 }; 728 729 /** RTDWARFDIESUBPROGRAM description. */ 730 static const RTDWARFDIEDESC g_SubProgramDesc = DIE_DESC_INIT(RTDWARFDIESUBPROGRAM, g_aSubProgramAttrs); 731 732 733 /** 734 * Tag names and descriptors. 735 */ 736 static const struct RTDWARFTAGDESC 737 { 738 /** The tag value. */ 739 uint16_t uTag; 740 /** The tag name as string. */ 741 const char *pszName; 742 /** The DIE descriptor to use. */ 743 PCRTDWARFDIEDESC pDesc; 744 } g_aTagDescs[] = 745 { 746 #define TAGDESC(a_Name, a_pDesc) { DW_ ## a_Name, #a_Name, a_pDesc } 747 #define TAGDESC_EMPTY() { 0, NULL, NULL } 748 #define TAGDESC_CORE(a_Name) TAGDESC(a_Name, &g_CoreDieDesc) 749 TAGDESC_EMPTY(), /* 0x00 */ 750 TAGDESC_CORE(TAG_array_type), 751 TAGDESC_CORE(TAG_class_type), 752 TAGDESC_CORE(TAG_entry_point), 753 TAGDESC_CORE(TAG_enumeration_type), /* 0x04 */ 754 TAGDESC_CORE(TAG_formal_parameter), 755 TAGDESC_EMPTY(), 756 TAGDESC_EMPTY(), 757 TAGDESC_CORE(TAG_imported_declaration), /* 0x08 */ 758 TAGDESC_EMPTY(), 759 TAGDESC_CORE(TAG_label), 760 TAGDESC_CORE(TAG_lexical_block), 761 TAGDESC_EMPTY(), /* 0x0c */ 762 TAGDESC_CORE(TAG_member), 763 TAGDESC_EMPTY(), 764 TAGDESC_CORE(TAG_pointer_type), 765 TAGDESC_CORE(TAG_reference_type), /* 0x10 */ 766 TAGDESC_CORE(TAG_compile_unit), 767 TAGDESC_CORE(TAG_string_type), 768 TAGDESC_CORE(TAG_structure_type), 769 TAGDESC_EMPTY(), /* 0x14 */ 770 TAGDESC_CORE(TAG_subroutine_type), 771 TAGDESC_CORE(TAG_typedef), 772 TAGDESC_CORE(TAG_union_type), 773 TAGDESC_CORE(TAG_unspecified_parameters), /* 0x18 */ 774 TAGDESC_CORE(TAG_variant), 775 TAGDESC_CORE(TAG_common_block), 776 TAGDESC_CORE(TAG_common_inclusion), 777 TAGDESC_CORE(TAG_inheritance), /* 0x1c */ 778 TAGDESC_CORE(TAG_inlined_subroutine), 779 TAGDESC_CORE(TAG_module), 780 TAGDESC_CORE(TAG_ptr_to_member_type), 781 TAGDESC_CORE(TAG_set_type), /* 0x20 */ 782 TAGDESC_CORE(TAG_subrange_type), 783 TAGDESC_CORE(TAG_with_stmt), 784 TAGDESC_CORE(TAG_access_declaration), 785 TAGDESC_CORE(TAG_base_type), /* 0x24 */ 786 TAGDESC_CORE(TAG_catch_block), 787 TAGDESC_CORE(TAG_const_type), 788 TAGDESC_CORE(TAG_constant), 789 TAGDESC_CORE(TAG_enumerator), /* 0x28 */ 790 TAGDESC_CORE(TAG_file_type), 791 TAGDESC_CORE(TAG_friend), 792 TAGDESC_CORE(TAG_namelist), 793 TAGDESC_CORE(TAG_namelist_item), /* 0x2c */ 794 TAGDESC_CORE(TAG_packed_type), 795 TAGDESC(TAG_subprogram, &g_SubProgramDesc), 796 TAGDESC_CORE(TAG_template_type_parameter), 797 TAGDESC_CORE(TAG_template_value_parameter), /* 0x30 */ 798 TAGDESC_CORE(TAG_thrown_type), 799 TAGDESC_CORE(TAG_try_block), 800 TAGDESC_CORE(TAG_variant_part), 801 TAGDESC_CORE(TAG_variable), /* 0x34 */ 802 TAGDESC_CORE(TAG_volatile_type), 803 TAGDESC_CORE(TAG_dwarf_procedure), 804 TAGDESC_CORE(TAG_restrict_type), 805 TAGDESC_CORE(TAG_interface_type), /* 0x38 */ 806 TAGDESC_CORE(TAG_namespace), 807 TAGDESC_CORE(TAG_imported_module), 808 TAGDESC_CORE(TAG_unspecified_type), 809 TAGDESC_CORE(TAG_partial_unit), /* 0x3c */ 810 TAGDESC_CORE(TAG_imported_unit), 811 TAGDESC_EMPTY(), 812 TAGDESC_CORE(TAG_condition), 813 TAGDESC_CORE(TAG_shared_type), /* 0x40 */ 814 TAGDESC_CORE(TAG_type_unit), 815 TAGDESC_CORE(TAG_rvalue_reference_type), 816 TAGDESC_CORE(TAG_template_alias) 817 #undef TAGDESC 818 #undef TAGDESC_EMPTY 819 #undef TAGDESC_CORE 820 }; 751 821 752 822 … … 2360 2430 2361 2431 /** @callback_method_impl{FNRTDWARFATTRDECODER} */ 2432 static DECLCALLBACK(int) rtDwarfDecode_Address(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc, 2433 uint32_t uForm, PRTDWARFCURSOR pCursor) 2434 { 2435 AssertReturn(ATTR_GET_SIZE(pDesc) == sizeof(RTDWARFADDR), VERR_INTERNAL_ERROR_3); 2436 2437 uint64_t uAddr; 2438 switch (uForm) 2439 { 2440 case DW_FORM_addr: uAddr = rtDwarfCursor_GetNativeUOff(pCursor, 0); break; 2441 case DW_FORM_data1: uAddr = rtDwarfCursor_GetU8(pCursor, 0); break; 2442 case DW_FORM_data2: uAddr = rtDwarfCursor_GetU16(pCursor, 0); break; 2443 case DW_FORM_data4: uAddr = rtDwarfCursor_GetU32(pCursor, 0); break; 2444 case DW_FORM_data8: uAddr = rtDwarfCursor_GetU64(pCursor, 0); break; 2445 case DW_FORM_udata: uAddr = rtDwarfCursor_GetULeb128(pCursor, 0); break; 2446 default: 2447 AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM); 2448 } 2449 if (RT_FAILURE(pCursor->rc)) 2450 return pCursor->rc; 2451 2452 PRTDWARFADDR pAddr = (PRTDWARFADDR)pbMember; 2453 pAddr->uAddress = uAddr; 2454 2455 return VINF_SUCCESS; 2456 } 2457 2458 2459 /** @callback_method_impl{FNRTDWARFATTRDECODER} */ 2362 2460 static DECLCALLBACK(int) rtDwarfDecode_Bool(PRTDWARFDIE pDie, uint8_t *pbMember, PCRTDWARFATTRDESC pDesc, 2363 2461 uint32_t uForm, PRTDWARFCURSOR pCursor) … … 2414 2512 if (pDesc->uAttr == DW_AT_low_pc) 2415 2513 { 2514 if (pRange->fHaveLowAddress) 2515 { 2516 Log(("rtDwarfDecode_LowHighPc: Duplicate DW_AT_low_pc\n")); 2517 return pCursor->rc = VERR_DWARF_BAD_INFO; 2518 } 2519 pRange->fHaveLowAddress = true; 2416 2520 pRange->uLowAddress = uAddr; 2417 pRange->fHaveLowAddress = true;2418 2521 } 2419 2522 else 2420 2523 { 2524 if (pRange->fHaveHighAddress) 2525 { 2526 Log(("rtDwarfDecode_LowHighPc: Duplicate DW_AT_high_pc\n")); 2527 return pCursor->rc = VERR_DWARF_BAD_INFO; 2528 } 2529 pRange->fHaveHighAddress = true; 2421 2530 pRange->uHighAddress = uAddr; 2422 pRange->fHaveHighAddress = true;2423 }2531 } 2532 pRange->cAttrs++; 2424 2533 2425 2534 return VINF_SUCCESS; … … 2450 2559 PRTDBGMODDWARF pThis = pCursor->pDwarfMod; 2451 2560 if (off >= pThis->aSections[krtDbgModDwarfSect_ranges].cb) 2561 { 2562 Log(("rtDwarfDecode_Ranges: bad ranges off=%#llx\n", off)); 2452 2563 return pCursor->rc = VERR_DWARF_BAD_POS; 2564 } 2453 2565 2454 2566 if (!pThis->aSections[krtDbgModDwarfSect_ranges].pv) … … 2461 2573 /* Store the result. */ 2462 2574 PRTDWARFADDRRANGE pRange = (PRTDWARFADDRRANGE)pbMember; 2575 if (pRange->fHaveRanges) 2576 { 2577 Log(("rtDwarfDecode_Ranges: Duplicate DW_AT_ranges\n")); 2578 return pCursor->rc = VERR_DWARF_BAD_INFO; 2579 } 2580 pRange->fHaveRanges = true; 2581 pRange->cAttrs++; 2463 2582 pRange->pbRanges = (uint8_t const *)pThis->aSections[krtDbgModDwarfSect_ranges].pv + (size_t)off; 2464 pRange->fHaveRanges = true;2465 2583 2466 2584 return VINF_SUCCESS; … … 2505 2623 { 2506 2624 if (off >= pCursor->pDwarfMod->aSections[krtDbgModDwarfSect_info].cb) 2625 { 2626 Log(("rtDwarfDecode_Reference: bad info off=%#llx\n", off)); 2507 2627 return pCursor->rc = VERR_DWARF_BAD_POS; 2628 } 2508 2629 } 2509 2630 else if (enmWrt == krtDwarfRef_SameUnit) … … 2511 2632 PRTDWARFDIECOMPILEUNIT pUnit = rtDwarfDie_GetCompileUnit(pDie); 2512 2633 if (off >= pUnit->cbUnit) 2634 { 2635 Log(("rtDwarfDecode_Reference: bad unit off=%#llx\n", off)); 2513 2636 return pCursor->rc = VERR_DWARF_BAD_POS; 2637 } 2514 2638 off += pUnit->offUnit; 2515 2639 enmWrt = krtDwarfRef_InfoSection; … … 2535 2659 switch (uForm) 2536 2660 { 2537 case DW_FORM_data4: off = rtDwarfCursor_GetU32(pCursor, 0);break;2538 case DW_FORM_data8: off = rtDwarfCursor_GetU64(pCursor, 0);break;2539 case DW_FORM_sec_offset: 2661 case DW_FORM_data4: off = rtDwarfCursor_GetU32(pCursor, 0); break; 2662 case DW_FORM_data8: off = rtDwarfCursor_GetU64(pCursor, 0); break; 2663 case DW_FORM_sec_offset: off = rtDwarfCursor_GetUOff(pCursor, 0); break; 2540 2664 default: 2541 2665 AssertMsgFailedReturn(("%#x\n", uForm), VERR_DWARF_UNEXPECTED_FORM); … … 2548 2672 switch (pDesc->uAttr) 2549 2673 { 2550 case DW_AT_stmt_list: enmSect = krtDbgModDwarfSect_line; enmWrt = krtDwarfRef_LineSection; 2551 case DW_AT_macro_info: enmSect = krtDbgModDwarfSect_loc; enmWrt = krtDwarfRef_LocSection; 2674 case DW_AT_stmt_list: enmSect = krtDbgModDwarfSect_line; enmWrt = krtDwarfRef_LineSection; break; 2675 case DW_AT_macro_info: enmSect = krtDbgModDwarfSect_loc; enmWrt = krtDwarfRef_LocSection; break; 2552 2676 case DW_AT_ranges: enmSect = krtDbgModDwarfSect_ranges; enmWrt = krtDwarfRef_RangesSection; break; 2553 2677 default: AssertMsgFailedReturn(("%u\n", pDesc->uAttr), VERR_INTERNAL_ERROR_4); 2554 2678 } 2555 if (off > pCursor->pDwarfMod->aSections[enmSect].cb) 2679 if (off >= pCursor->pDwarfMod->aSections[enmSect].cb) 2680 { 2681 Log(("rtDwarfDecode_SectOff: bad off=%#llx, attr %#x\n", off, pDesc->uAttr)); 2556 2682 return pCursor->rc = VERR_DWARF_BAD_POS; 2683 } 2557 2684 2558 2685 PRTDWARFREF pRef = (PRTDWARFREF)pbMember; … … 2649 2776 2650 2777 2651 2652 static const char *rtDwarfForm_GetString(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor, uint16_t uForm, const char *pszErrValue) 2653 { 2654 switch (uForm) 2655 { 2656 case DW_FORM_string: 2657 return rtDwarfCursor_GetSZ(pCursor, pszErrValue); 2658 2659 case DW_FORM_strp: 2660 return rtDwarfDecode_GetStrp(pThis, pCursor, pszErrValue); 2661 2662 default: 2663 pCursor->rc = VERR_DWARF_UNEXPECTED_FORM; 2664 return pszErrValue; 2778 /** 2779 * Parse the attributes of a DIE. 2780 * 2781 * @returns IPRT status code. 2782 * @param pThis The DWARF instance. 2783 * @param pDie The internal DIE structure to fill. 2784 */ 2785 static int rtDwarfInfo_SnoopSymbols(PRTDBGMODDWARF pThis, PRTDWARFDIE pDie) 2786 { 2787 int rc = VINF_SUCCESS; 2788 switch (pDie->uTag) 2789 { 2790 case DW_TAG_subprogram: 2791 { 2792 PCRTDWARFDIESUBPROGRAM pSubProgram = (PCRTDWARFDIESUBPROGRAM)pDie; 2793 if (pSubProgram->PcRange.cAttrs) 2794 { 2795 if (pSubProgram->PcRange.fHaveRanges) 2796 Log5(("subprogram %s (%s) <implement ranges>\n", pSubProgram->pszName, pSubProgram->pszLinkageName)); 2797 else 2798 { 2799 Log5(("subprogram %s (%s) %#llx-%#llx%s\n", pSubProgram->pszName, pSubProgram->pszLinkageName, 2800 pSubProgram->PcRange.uLowAddress, pSubProgram->PcRange.uHighAddress, 2801 pSubProgram->PcRange.cAttrs == 2 ? "" : " !bad!")); 2802 if ( pSubProgram->pszName 2803 && pSubProgram->PcRange.cAttrs == 2) 2804 { 2805 RTDBGSEGIDX iSeg; 2806 RTUINTPTR offSeg; 2807 rc = rtDbgModDwarfLinkAddressToSegOffset(pThis, pSubProgram->PcRange.uLowAddress, 2808 &iSeg, &offSeg); 2809 if (RT_SUCCESS(rc)) 2810 rc = RTDbgModSymbolAdd(pThis->hCnt, pSubProgram->pszName, iSeg, offSeg, 2811 pSubProgram->PcRange.uHighAddress - pSubProgram->PcRange.uLowAddress, 2812 0 /*fFlags*/, NULL /*piOrdinal*/); 2813 else 2814 Log5(("rtDbgModDwarfLinkAddressToSegOffset failed: %Rrc\n", rc)); 2815 } 2816 } 2817 } 2818 else 2819 Log5(("subprogram %s (%s) external\n", pSubProgram->pszName, pSubProgram->pszLinkageName)); 2820 break; 2821 } 2822 2823 } 2824 return rc; 2825 } 2826 2827 2828 /** 2829 * Initializes the non-core fields of an internal DIE structure. 2830 * 2831 * @param pDie The DIE structure. 2832 * @param pDieDesc The DIE descriptor. 2833 */ 2834 static void rtDwarfInfo_InitDie(PRTDWARFDIE pDie, PCRTDWARFDIEDESC pDieDesc) 2835 { 2836 uint32_t i = pDieDesc->cAttributes; 2837 while (i-- > 0) 2838 { 2839 switch (pDieDesc->paAttributes[i].cbInit & ATTR_INIT_MASK) 2840 { 2841 case ATTR_INIT_ZERO: 2842 /* Nothing to do (RTMemAllocZ). */ 2843 break; 2844 2845 case ATTR_INIT_FFFS: 2846 switch (pDieDesc->paAttributes[i].cbInit & ATTR_SIZE_MASK) 2847 { 2848 case 1: 2849 *(uint8_t *)((uintptr_t)pDie + pDieDesc->paAttributes[i].off) = UINT8_MAX; 2850 break; 2851 case 2: 2852 *(uint16_t *)((uintptr_t)pDie + pDieDesc->paAttributes[i].off) = UINT16_MAX; 2853 break; 2854 case 4: 2855 *(uint32_t *)((uintptr_t)pDie + pDieDesc->paAttributes[i].off) = UINT32_MAX; 2856 break; 2857 case 8: 2858 *(uint64_t *)((uintptr_t)pDie + pDieDesc->paAttributes[i].off) = UINT64_MAX; 2859 break; 2860 default: 2861 AssertFailed(); 2862 memset((uint8_t *)pDie + pDieDesc->paAttributes[i].off, 0xff, 2863 pDieDesc->paAttributes[i].cbInit & ATTR_SIZE_MASK); 2864 break; 2865 } 2866 break; 2867 2868 default: 2869 AssertFailed(); 2870 } 2665 2871 } 2666 2872 } … … 2672 2878 * @returns Pointer to the new DIE structure. 2673 2879 * @param pThis The DWARF instance. 2674 * @param cbUnit The size required for this unit.2880 * @param pDieDesc The DIE descriptor (for size and init). 2675 2881 * @param pAbbrev The abbreviation cache entry. 2676 2882 * @param pParent The parent DIE (NULL if unit). 2677 2883 */ 2678 static PRTDWARFDIE rtDwarfInfo_NewDie(PRTDBGMODDWARF pThis, size_t cbUnit, PCRTDWARFABBREV pAbbrev, PRTDWARFDIE pParent) 2679 { 2680 Assert(cbUnit >= sizeof(RTDWARFDIE)); 2681 PRTDWARFDIE pDie = (PRTDWARFDIE)RTMemAllocZ(cbUnit); 2884 static PRTDWARFDIE rtDwarfInfo_NewDie(PRTDBGMODDWARF pThis, PCRTDWARFDIEDESC pDieDesc, 2885 PCRTDWARFABBREV pAbbrev, PRTDWARFDIE pParent) 2886 { 2887 Assert(pDieDesc->cbDie >= sizeof(RTDWARFDIE)); 2888 PRTDWARFDIE pDie = (PRTDWARFDIE)RTMemAllocZ(pDieDesc->cbDie); 2682 2889 if (pDie) 2683 2890 { 2891 rtDwarfInfo_InitDie(pDie, pDieDesc); 2892 2684 2893 pDie->uTag = pAbbrev->uTag; 2685 2894 pDie->offSpec = pAbbrev->offSpec; … … 2690 2899 RTListInit(&pDie->SiblingNode); 2691 2900 RTListInit(&pDie->ChildList); 2901 2692 2902 } 2693 2903 return pDie; … … 2790 3000 2791 3001 2792 #if 0 2793 /** 2794 * Parse a DIE. 3002 /** 3003 * Parse the attributes of a DIE. 3004 * 3005 * @returns IPRT status code. 3006 * @param pThis The DWARF instance. 3007 * @param pDie The internal DIE structure to fill. 3008 * @param pDieDesc The DIE descriptor. 3009 * @param pCursor The debug_info cursor. 3010 * @param pAbbrev The abbreviation cache entry. 3011 */ 3012 static int rtDwarfInfo_ParseDie(PRTDBGMODDWARF pThis, PRTDWARFDIE pDie, PCRTDWARFDIEDESC pDieDesc, 3013 PRTDWARFCURSOR pCursor, PCRTDWARFABBREV pAbbrev) 3014 { 3015 RTDWARFCURSOR AbbrevCursor; 3016 int rc = rtDwarfCursor_InitWithOffset(&AbbrevCursor, pThis, krtDbgModDwarfSect_abbrev, pAbbrev->offSpec); 3017 if (RT_FAILURE(rc)) 3018 return rc; 3019 3020 rtDwarfInfo_InitDie(pDie, pDieDesc); 3021 for (;;) 3022 { 3023 uint32_t uAttr = rtDwarfCursor_GetULeb128AsU32(&AbbrevCursor, 0); 3024 uint32_t uForm = rtDwarfCursor_GetULeb128AsU32(&AbbrevCursor, 0); 3025 if (uAttr == 0) 3026 break; 3027 if (uForm == DW_FORM_indirect) 3028 uForm = rtDwarfCursor_GetULeb128AsU32(pCursor, 0); 3029 3030 /* Look up the attribute in the descriptor and invoke the decoder. */ 3031 PCRTDWARFATTRDESC pAttr = NULL; 3032 uint32_t i = pDieDesc->cAttributes; 3033 while (i-- > 0) 3034 if (pDieDesc->paAttributes[i].uAttr == uAttr) 3035 { 3036 pAttr = &pDieDesc->paAttributes[i]; 3037 rc = pAttr->pfnDecoder(pDie, (uint8_t *)pDie + pAttr->off, pAttr, uForm, pCursor); 3038 break; 3039 } 3040 3041 /* Some house keeping. */ 3042 if (pAttr) 3043 pDie->cDecodedAttrs++; 3044 else 3045 { 3046 pDie->cUnhandledAttrs++; 3047 rc = rtDwarfInfo_SkipForm(pCursor, uForm); 3048 } 3049 if (RT_FAILURE(rc)) 3050 break; 3051 } 3052 3053 rc = rtDwarfCursor_Delete(&AbbrevCursor, rc); 3054 if (RT_SUCCESS(rc)) 3055 rc = pCursor->rc; 3056 3057 /* 3058 * Snoope up symbols on the way out. 3059 */ 3060 if (RT_SUCCESS(rc)) 3061 rc = rtDwarfInfo_SnoopSymbols(pThis, pDie); 3062 3063 return rc; 3064 } 3065 3066 3067 /** 3068 * Load the debug information of a unit. 2795 3069 * 2796 3070 * @returns IPRT status code. 2797 3071 * @param pThis The DWARF instance. 2798 3072 * @param pCursor The debug_info cursor. 2799 * @param pAbbrev The abbreviation entry. 2800 * @param pAbbrevCursor The abbreviation cursor. 2801 * @param pStack The DIE stack. 2802 */ 2803 static int rtDwarfInfo_ParseDie(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor, 2804 PCRTDWARFABBREV pAbbrev, PRTDWARFCURSOR pAbbrevCursor, 2805 PRTDWARFDIESTACK pStack) 2806 { 2807 /* 2808 * Pick out DIEs which tag we find interesting. 2809 */ 2810 switch (pAbbrev->uTag) 2811 { 2812 case DW_TAG_compile_unit: 2813 case DW_TAG_partial_unit: 2814 Log((" - DW_TAG_%s_unit:\n", pAbbrev->uTag == DW_TAG_compile_unit ? "compile" : "partial")); 2815 for (;;) 2816 { 2817 uint32_t uAttr = rtDwarfCursor_GetULeb128AsU32(pAbbrevCursor, 0); 2818 uint32_t uForm = rtDwarfCursor_GetULeb128AsU32(pAbbrevCursor, 0); 2819 switch (uAttr) 2820 { 2821 case 0: 2822 return VINF_SUCCESS; 2823 2824 case DW_AT_name: 2825 { 2826 const char *pszName = rtDwarfForm_GetString(pThis, pCursor, uForm, "<error>"); 2827 rtDwarfDieStack_SetName(pStack, pszName); 2828 Log4(("%*s - name=%s\n", pStack->cOnStack*2, "", pszName)); 2829 break; 2830 } 2831 2832 case DW_AT_stmt_list: 2833 /** @todo */ 2834 default: 2835 Log4(("%*s - attr=%#x form=%#x\n", pStack->cOnStack*2, "", uAttr, uForm)); 2836 rtDwarfInfo_SkipForm(pCursor, uForm); 2837 } 2838 if (RT_FAILURE(pCursor->rc)) 2839 return pCursor->rc; 2840 } 2841 break; /* not reached. */ 2842 2843 case DW_TAG_subprogram: 2844 Log((" - DW_TAG_subprogram:\n")); 2845 for (;;) 2846 { 2847 uint32_t uAttr = rtDwarfCursor_GetULeb128AsU32(pAbbrevCursor, 0); 2848 uint32_t uForm = rtDwarfCursor_GetULeb128AsU32(pAbbrevCursor, 0); 2849 switch (uAttr) 2850 { 2851 case 0: 2852 return VINF_SUCCESS; 2853 2854 case DW_AT_name: 2855 { 2856 const char *pszName = rtDwarfForm_GetString(pThis, pCursor, uForm, "<error>"); 2857 rtDwarfDieStack_SetName(pStack, pszName); 2858 Log4(("%*s - name=%s\n", pStack->cOnStack*2, "", pszName)); 2859 break; 2860 } 2861 2862 default: 2863 Log4(("%*s - attr=%#x form=%#x\n", pStack->cOnStack*2, "", uAttr, uForm)); 2864 rtDwarfInfo_SkipForm(pCursor, uForm); 2865 } 2866 if (RT_FAILURE(pCursor->rc)) 2867 return pCursor->rc; 2868 } 2869 break; /* not reached. */ 2870 2871 } 2872 2873 return rtDwarfInfo_SkipDie(pCursor, pAbbrevCursor); 2874 } 2875 #endif 2876 2877 2878 2879 static int rtDwarfInfo_LoadUnit(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor) 3073 * @param fKeepDies Whether to keep the DIEs or discard them as soon 3074 * as possible. 3075 */ 3076 static int rtDwarfInfo_LoadUnit(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor, bool fKeepDies) 2880 3077 { 2881 3078 Log(("rtDwarfInfo_LoadUnit: %#x\n", rtDwarfCursor_CalcSectOffsetU32(pCursor))); … … 2921 3118 } 2922 3119 2923 PRTDWARFDIECOMPILEUNIT pUnit = (PRTDWARFDIECOMPILEUNIT)rtDwarfInfo_NewDie(pThis, sizeof(*pUnit), pAbbrev, NULL /*pParent*/); 3120 PRTDWARFDIECOMPILEUNIT pUnit; 3121 pUnit = (PRTDWARFDIECOMPILEUNIT)rtDwarfInfo_NewDie(pThis, &g_CompileUnitDesc, pAbbrev, NULL /*pParent*/); 2924 3122 if (!pUnit) 2925 3123 return VERR_NO_MEMORY; … … 2931 3129 RTListAppend(&pThis->CompileUnitList, &pUnit->Core.SiblingNode); 2932 3130 2933 /** @todo Parse the DIE data using the descriptor. */ 2934 RTDWARFCURSOR AbbrevCursor; 2935 int rc = rtDwarfCursor_InitWithOffset(&AbbrevCursor, pThis, krtDbgModDwarfSect_abbrev, pAbbrev->offSpec); 2936 #if 0 2937 if (RT_SUCCESS(rc)) 2938 { 2939 rc = rtDwarfInfo_ParseDie(pThis, pCursor, pAbbrev, &AbbrevCursor, &Stack); 2940 rc = rtDwarfCursor_Delete(&AbbrevCursor, rc); 2941 } 3131 int rc = rtDwarfInfo_ParseDie(pThis, &pUnit->Core, &g_CompileUnitDesc, pCursor, pAbbrev); 2942 3132 if (RT_FAILURE(rc)) 2943 break;3133 return rc; 2944 3134 2945 3135 /* 2946 3136 * Parse DIEs. 2947 3137 */ 2948 int rc = VINF_SUCCESS; 3138 uint32_t cDepth = 0; 3139 PRTDWARFDIE pParentDie = &pUnit->Core; 2949 3140 while (!rtDwarfCursor_IsAtEndOfUnit(pCursor)) 2950 3141 { 2951 u int32_t uAbbrCode = rtDwarfCursor_GetULeb128AsU32(pCursor, UINT32_MAX);3142 uAbbrCode = rtDwarfCursor_GetULeb128AsU32(pCursor, UINT32_MAX); 2952 3143 if (!uAbbrCode) 2953 3144 { 2954 /* End of siblings, pop the stack. */ 2955 rc = rtDwarfDieStack_Pop(&Stack); 2956 if (RT_FAILURE(rc)) 3145 /* End of siblings, up one level. */ 3146 pParentDie = pParentDie->pParent; 3147 if (!pParentDie) 3148 { 3149 if (!rtDwarfCursor_IsAtEndOfUnit(pCursor)) 3150 return VERR_DWARF_BAD_INFO; 2957 3151 break; 3152 } 3153 cDepth--; 3154 3155 /* Unlink and free child DIEs if told to do so. */ 3156 if (!fKeepDies && pParentDie->pParent) 3157 { 3158 PRTDWARFDIE pChild, pNextChild; 3159 RTListForEachSafe(&pParentDie->ChildList, pChild, pNextChild, RTDWARFDIE, SiblingNode) 3160 { 3161 RTListNodeRemove(&pChild->SiblingNode); 3162 RTMemFree(pChild); 3163 } 3164 } 2958 3165 } 2959 3166 else 2960 3167 { 2961 3168 /* 2962 * Look up the abbreviation .3169 * Look up the abbreviation and match the tag up with a descriptor. 2963 3170 */ 2964 PCRTDWARFABBREVpAbbrev = rtDwarfAbbrev_Lookup(pThis, uAbbrCode);3171 pAbbrev = rtDwarfAbbrev_Lookup(pThis, uAbbrCode); 2965 3172 if (!pAbbrev) 3173 return VERR_DWARF_ABBREV_NOT_FOUND; 3174 3175 PCRTDWARFDIEDESC pDieDesc; 3176 const char *pszName; 3177 if (pAbbrev->uTag < RT_ELEMENTS(g_aTagDescs)) 2966 3178 { 2967 rc = VERR_DWARF_ABBREV_NOT_FOUND; 2968 break; 3179 Assert(g_aTagDescs[pAbbrev->uTag].uTag == pAbbrev->uTag || g_aTagDescs[pAbbrev->uTag].uTag == 0); 3180 pszName = g_aTagDescs[pAbbrev->uTag].pszName; 3181 pDieDesc = g_aTagDescs[pAbbrev->uTag].pDesc; 2969 3182 } 2970 Log4((" %*stag=%#x%s\n", Stack.cOnStack * 2, "", pAbbrev->uTag, pAbbrev->fChildren ? " has children" : "")); 3183 else 3184 { 3185 pszName = "<unknown>"; 3186 pDieDesc = g_aTagDescs[0].pDesc; 3187 } 3188 Log4((" %*stag=%s (%#x)%s\n", cDepth * 2, "", pszName, 3189 pAbbrev->uTag, pAbbrev->fChildren ? " has children" : "")); 2971 3190 2972 3191 /* 2973 * If this DIE has children, push it onto the stack. 3192 * Create a new internal DIE structure and parse the 3193 * attributes. 2974 3194 */ 3195 PRTDWARFDIE pNewDie = rtDwarfInfo_NewDie(pThis, pDieDesc, pAbbrev, pParentDie); 3196 if (!pNewDie) 3197 return VERR_NO_MEMORY; 3198 2975 3199 if (pAbbrev->fChildren) 2976 3200 { 2977 rc = rtDwarfDieStack_Push(&Stack, uAbbrCode, pAbbrev->uTag, rtDwarfCursor_CalcSectOffsetU32(pCursor)); 2978 if (RT_FAILURE(rc)) 2979 break; 3201 pParentDie = pNewDie; 3202 cDepth++; 2980 3203 } 2981 3204 2982 /* 2983 * Parse it. 2984 */ 2985 RTDWARFCURSOR AbbrevCursor; 2986 rc = rtDwarfCursor_InitWithOffset(&AbbrevCursor, pThis, krtDbgModDwarfSect_abbrev, pAbbrev->offSpec); 2987 if (RT_SUCCESS(rc)) 2988 { 2989 rc = rtDwarfInfo_ParseDie(pThis, pCursor, pAbbrev, &AbbrevCursor, &Stack); 2990 rc = rtDwarfCursor_Delete(&AbbrevCursor, rc); 2991 } 3205 rc = rtDwarfInfo_ParseDie(pThis, pNewDie, pDieDesc, pCursor, pAbbrev); 2992 3206 if (RT_FAILURE(rc)) 2993 break;3207 return rc; 2994 3208 } 2995 } 2996 2997 rtDwarfDieStack_Delete(&Stack); 2998 #endif 3209 } /* while more DIEs */ 3210 2999 3211 return RT_SUCCESS(rc) ? pCursor->rc : rc; 3000 3212 } … … 3018 3230 while ( !rtDwarfCursor_IsAtEnd(&Cursor) 3019 3231 && RT_SUCCESS(rc)) 3020 rc = rtDwarfInfo_LoadUnit(pThis, &Cursor );3232 rc = rtDwarfInfo_LoadUnit(pThis, &Cursor, false /* fKeepDies */); 3021 3233 3022 3234 return rtDwarfCursor_Delete(&Cursor, rc); … … 3258 3470 return VERR_NO_MEMORY; 3259 3471 pThis->pMod = pMod; 3472 RTListInit(&pThis->CompileUnitList); 3260 3473 3261 3474 int rc = pMod->pImgVt->pfnEnumDbgInfo(pMod, rtDbgModDwarfEnumCallback, pThis); -
trunk/src/VBox/Runtime/tools/RTLdrFlt.cpp
r38573 r38619 140 140 }; 141 141 142 PRTSTREAM pInput = g_pStdIn;143 PRTSTREAM pOutput = g_pStdOut;144 bool fVerbose = false;142 PRTSTREAM pInput = g_pStdIn; 143 PRTSTREAM pOutput = g_pStdOut; 144 unsigned cVerbosityLevel = 0; 145 145 146 146 RTGETOPTUNION ValueUnion; … … 158 158 159 159 case 'v': 160 fVerbose = true;160 cVerbosityLevel++; 161 161 break; 162 162 … … 209 209 * Display the address space. 210 210 */ 211 if ( fVerbose)211 if (cVerbosityLevel) 212 212 { 213 213 RTPrintf("*** Address Space Dump ***\n"); … … 243 243 RTPrintf(" mapping #%u: %RTptr-???????? (segment #%u)", iMapping, aMappings[iMapping].Address); 244 244 } 245 246 if (cVerbosityLevel > 1) 247 { 248 uint32_t cSymbols = RTDbgModSymbolCount(hDbgMod); 249 RTPrintf(" %u symbols\n", cSymbols); 250 for (uint32_t iSymbol = 0; iSymbol < cSymbols; iSymbol++) 251 { 252 RTDBGSYMBOL SymInfo; 253 rc = RTDbgModSymbolByOrdinal(hDbgMod, iSymbol, &SymInfo); 254 if (RT_SUCCESS(rc)) 255 RTPrintf(" #%04u at %08x:%RTptr %05llx %s\n", 256 SymInfo.iOrdinal, SymInfo.iSeg, SymInfo.offSeg, 257 (uint64_t)SymInfo.cb, SymInfo.szName); 258 } 259 } 245 260 } 246 261 }
Note:
See TracChangeset
for help on using the changeset viewer.