Changeset 47057 in vbox for trunk/src/VBox/Runtime/common
- Timestamp:
- Jul 9, 2013 4:02:56 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/dbg/dbgmoddwarf.cpp
r46916 r47057 241 241 #define DW_AT_linkage_name UINT16_C(0x006e) 242 242 #define DW_AT_lo_user UINT16_C(0x2000) 243 /** Used by GCC and others, same as DW_AT_linkage_name. See http://wiki.dwarfstd.org/index.php?title=DW_AT_linkage_name*/ 244 #define DW_AT_MIPS_linkage_name UINT16_C(0x2007) 243 245 #define DW_AT_hi_user UINT16_C(0x3fff) 244 246 /** @} */ … … 598 600 { 599 601 /** The attribute. */ 600 uint8_t uAttr; 602 uint16_t uAttr; 603 /** The data member offset. */ 604 uint16_t off; 601 605 /** The data member size and initialization method. */ 602 606 uint8_t cbInit; 603 /** The data member offset. */ 604 uint16_t off; 607 uint8_t bPadding[3]; /**< Alignment padding. */ 605 608 /** The decoder function. */ 606 609 PFNRTDWARFATTRDECODER pfnDecoder; … … 611 614 { \ 612 615 a_uAttr, \ 616 (uint16_t)RT_OFFSETOF(a_Struct, a_Member), \ 613 617 a_Init | ((uint8_t)RT_SIZEOFMEMB(a_Struct, a_Member) & ATTR_SIZE_MASK), \ 614 (uint16_t)RT_OFFSETOF(a_Struct, a_Member), \618 { 0, 0, 0 }, \ 615 619 a_pfnDecoder\ 616 620 } … … 848 852 /** Segment number (watcom). */ 849 853 RTSEL uSegment; 854 /** Reference to the specification. */ 855 RTDWARFREF SpecRef; 850 856 } RTDWARFDIESUBPROGRAM; 851 857 /** Pointer to a DW_TAG_subprogram DIE. */ … … 860 866 ATTR_ENTRY(DW_AT_name, RTDWARFDIESUBPROGRAM, pszName, ATTR_INIT_ZERO, rtDwarfDecode_String), 861 867 ATTR_ENTRY(DW_AT_linkage_name, RTDWARFDIESUBPROGRAM, pszLinkageName, ATTR_INIT_ZERO, rtDwarfDecode_String), 868 ATTR_ENTRY(DW_AT_MIPS_linkage_name, RTDWARFDIESUBPROGRAM, pszLinkageName, ATTR_INIT_ZERO, rtDwarfDecode_String), 862 869 ATTR_ENTRY(DW_AT_low_pc, RTDWARFDIESUBPROGRAM, PcRange, ATTR_INIT_ZERO, rtDwarfDecode_LowHighPc), 863 870 ATTR_ENTRY(DW_AT_high_pc, RTDWARFDIESUBPROGRAM, PcRange, ATTR_INIT_ZERO, rtDwarfDecode_LowHighPc), 864 871 ATTR_ENTRY(DW_AT_ranges, RTDWARFDIESUBPROGRAM, PcRange, ATTR_INIT_ZERO, rtDwarfDecode_Ranges), 865 872 ATTR_ENTRY(DW_AT_entry_pc, RTDWARFDIESUBPROGRAM, EntryPc, ATTR_INIT_ZERO, rtDwarfDecode_Address), 866 ATTR_ENTRY(DW_AT_segment, RTDWARFDIESUBPROGRAM, uSegment, ATTR_INIT_ZERO, rtDwarfDecode_SegmentLoc) 873 ATTR_ENTRY(DW_AT_segment, RTDWARFDIESUBPROGRAM, uSegment, ATTR_INIT_ZERO, rtDwarfDecode_SegmentLoc), 874 ATTR_ENTRY(DW_AT_specification, RTDWARFDIESUBPROGRAM, SpecRef, ATTR_INIT_ZERO, rtDwarfDecode_Reference) 867 875 }; 868 876 869 877 /** RTDWARFDIESUBPROGRAM description. */ 870 878 static const RTDWARFDIEDESC g_SubProgramDesc = DIE_DESC_INIT(RTDWARFDIESUBPROGRAM, g_aSubProgramAttrs); 879 880 881 /** RTDWARFDIESUBPROGRAM attributes for the specification hack. */ 882 static const RTDWARFATTRDESC g_aSubProgramSpecHackAttrs[] = 883 { 884 ATTR_ENTRY(DW_AT_name, RTDWARFDIESUBPROGRAM, pszName, ATTR_INIT_ZERO, rtDwarfDecode_String), 885 ATTR_ENTRY(DW_AT_linkage_name, RTDWARFDIESUBPROGRAM, pszLinkageName, ATTR_INIT_ZERO, rtDwarfDecode_String), 886 ATTR_ENTRY(DW_AT_MIPS_linkage_name, RTDWARFDIESUBPROGRAM, pszLinkageName, ATTR_INIT_ZERO, rtDwarfDecode_String), 887 }; 888 889 /** RTDWARFDIESUBPROGRAM description for the specification hack. */ 890 static const RTDWARFDIEDESC g_SubProgramSpecHackDesc = DIE_DESC_INIT(RTDWARFDIESUBPROGRAM, g_aSubProgramSpecHackAttrs); 871 891 872 892 … … 994 1014 #undef TAGDESC_CORE 995 1015 }; 1016 1017 1018 /******************************************************************************* 1019 * Internal Functions * 1020 *******************************************************************************/ 1021 static int rtDwarfInfo_ParseDie(PRTDBGMODDWARF pThis, PRTDWARFDIE pDie, PCRTDWARFDIEDESC pDieDesc, 1022 PRTDWARFCURSOR pCursor, PCRTDWARFABBREV pAbbrev, bool fInitDie); 1023 996 1024 997 1025 … … 1121 1149 RT_CASE_RET_STR(DW_AT_enum_class); 1122 1150 RT_CASE_RET_STR(DW_AT_linkage_name); 1151 RT_CASE_RET_STR(DW_AT_MIPS_linkage_name); 1123 1152 } 1124 1153 static char s_szStatic[32]; … … 1192 1221 { 1193 1222 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pvUser; 1194 Log(("Segment %.*s: LinkAddress=%#llx RVA=%#llx cb=%#llx \n",1195 pSeg->cchName, pSeg->pszName, (uint64_t)pSeg->LinkAddress, (uint64_t)pSeg->RVA, pSeg->cb ));1223 Log(("Segment %.*s: LinkAddress=%#llx RVA=%#llx cb=%#llx cbMapped=%#llx\n", 1224 pSeg->cchName, pSeg->pszName, (uint64_t)pSeg->LinkAddress, (uint64_t)pSeg->RVA, pSeg->cb, pSeg->cbMapped)); 1196 1225 NOREF(hLdrMod); 1197 1226 Assert(pSeg->cchName > 0); … … 3219 3248 /* Decode it. */ 3220 3249 uint64_t off; 3221 krtDwarfRef enmWrt = krtDwarfRef_ InfoSection;3250 krtDwarfRef enmWrt = krtDwarfRef_SameUnit; 3222 3251 switch (uForm) 3223 3252 { … … 3677 3706 3678 3707 /** 3708 * Special hack to get the name and/or linkage name for a subprogram via a 3709 * specification reference. 3710 * 3711 * Since this is a hack, we ignore failure. 3712 * 3713 * If we want to really make use of DWARF info, we'll have to create some kind 3714 * of lookup tree for handling this. But currently we don't, so a hack will 3715 * suffice. 3716 * 3717 * @param pThis The DWARF instance. 3718 * @param pSubProgram The subprogram which is short on names. 3719 */ 3720 static void rtDwarfInfo_TryGetSubProgramNameFromSpecRef(PRTDBGMODDWARF pThis, PRTDWARFDIESUBPROGRAM pSubProgram) 3721 { 3722 /* 3723 * Must have a spec ref, and it must be in the info section. 3724 */ 3725 if (pSubProgram->SpecRef.enmWrt != krtDwarfRef_InfoSection) 3726 return; 3727 3728 /* 3729 * Create a cursor for reading the info and then the abbrivation code 3730 * starting the off the DIE. 3731 */ 3732 RTDWARFCURSOR InfoCursor; 3733 int rc = rtDwarfCursor_InitWithOffset(&InfoCursor, pThis, krtDbgModDwarfSect_info, pSubProgram->SpecRef.off); 3734 if (RT_FAILURE(rc)) 3735 return; 3736 3737 uint32_t uAbbrCode = rtDwarfCursor_GetULeb128AsU32(&InfoCursor, UINT32_MAX); 3738 if (uAbbrCode) 3739 { 3740 /* Only references to subprogram tags are interesting here. */ 3741 PCRTDWARFABBREV pAbbrev = rtDwarfAbbrev_Lookup(pThis, uAbbrCode); 3742 if ( pAbbrev 3743 && pAbbrev->uTag == DW_TAG_subprogram) 3744 { 3745 /* 3746 * Use rtDwarfInfo_ParseDie to do the parsing, but with a different 3747 * attribute spec than usual. 3748 */ 3749 rtDwarfInfo_ParseDie(pThis, &pSubProgram->Core, &g_SubProgramSpecHackDesc, &InfoCursor, 3750 pAbbrev, false /*fInitDie*/); 3751 } 3752 } 3753 3754 rtDwarfCursor_Delete(&InfoCursor, VINF_SUCCESS); 3755 } 3756 3757 3758 /** 3759 * Select which name to use. 3760 * 3761 * @returns One of the names. 3762 * @param pszName The DWARF name, may exclude namespace and class. 3763 * Can also be NULL. 3764 * @param pszLinkageName The linkage name. Can be NULL. 3765 */ 3766 static const char *rtDwarfInfo_SelectName(const char *pszName, const char *pszLinkageName) 3767 { 3768 if (!pszName || !pszLinkageName) 3769 return pszName ? pszName : pszLinkageName; 3770 3771 /* 3772 * Some heuristics for selecting the link name if the normal name is missing 3773 * namespace or class prefixes. 3774 */ 3775 size_t cchName = strlen(pszName); 3776 size_t cchLinkageName = strlen(pszLinkageName); 3777 if (cchLinkageName <= cchName + 1) 3778 return pszName; 3779 3780 const char *psz = strstr(pszLinkageName, pszName); 3781 if (!psz || psz - pszLinkageName < 4) 3782 return pszName; 3783 3784 return pszLinkageName; 3785 } 3786 3787 3788 /** 3679 3789 * Parse the attributes of a DIE. 3680 3790 * … … 3690 3800 case DW_TAG_subprogram: 3691 3801 { 3692 PCRTDWARFDIESUBPROGRAM pSubProgram = (PCRTDWARFDIESUBPROGRAM)pDie; 3802 PRTDWARFDIESUBPROGRAM pSubProgram = (PRTDWARFDIESUBPROGRAM)pDie; 3803 3804 /* Obtain referenced specification there is only partial info. */ 3805 if ( pSubProgram->PcRange.cAttrs 3806 && !pSubProgram->pszName) 3807 rtDwarfInfo_TryGetSubProgramNameFromSpecRef(pThis, pSubProgram); 3808 3693 3809 if (pSubProgram->PcRange.cAttrs) 3694 3810 { … … 3700 3816 pSubProgram->PcRange.uLowAddress, pSubProgram->PcRange.uHighAddress, 3701 3817 pSubProgram->PcRange.cAttrs == 2 ? "" : " !bad!")); 3702 if ( pSubProgram->pszName3818 if ( ( pSubProgram->pszName || pSubProgram->pszLinkageName) 3703 3819 && pSubProgram->PcRange.cAttrs == 2) 3704 3820 { … … 3714 3830 if (RT_SUCCESS(rc)) 3715 3831 { 3716 rc = RTDbgModSymbolAdd(pThis->hCnt, pSubProgram->pszName, iSeg, offSeg, 3832 rc = RTDbgModSymbolAdd(pThis->hCnt, 3833 rtDwarfInfo_SelectName(pSubProgram->pszName, pSubProgram->pszLinkageName), 3834 iSeg, offSeg, 3717 3835 pSubProgram->PcRange.uHighAddress - pSubProgram->PcRange.uLowAddress, 3718 3836 0 /*fFlags*/, NULL /*piOrdinal*/); … … 4010 4128 * @param pCursor The debug_info cursor. 4011 4129 * @param pAbbrev The abbreviation cache entry. 4130 * @param fInitDie Whether to initialize the DIE first. If not (@c 4131 * false) it's safe to assume we're following a 4132 * DW_AT_specification or DW_AT_abstract_origin, 4133 * and that we shouldn't be snooping any symbols. 4012 4134 */ 4013 4135 static int rtDwarfInfo_ParseDie(PRTDBGMODDWARF pThis, PRTDWARFDIE pDie, PCRTDWARFDIEDESC pDieDesc, 4014 PRTDWARFCURSOR pCursor, PCRTDWARFABBREV pAbbrev )4136 PRTDWARFCURSOR pCursor, PCRTDWARFABBREV pAbbrev, bool fInitDie) 4015 4137 { 4016 4138 RTDWARFCURSOR AbbrevCursor; … … 4019 4141 return rc; 4020 4142 4021 rtDwarfInfo_InitDie(pDie, pDieDesc); 4143 if (fInitDie) 4144 rtDwarfInfo_InitDie(pDie, pDieDesc); 4022 4145 for (;;) 4023 4146 { … … 4060 4183 * Snoop up symbols on the way out. 4061 4184 */ 4062 if (RT_SUCCESS(rc) )4185 if (RT_SUCCESS(rc) && fInitDie) 4063 4186 { 4064 4187 rc = rtDwarfInfo_SnoopSymbols(pThis, pDie); … … 4143 4266 RTListAppend(&pThis->CompileUnitList, &pUnit->Core.SiblingNode); 4144 4267 4145 int rc = rtDwarfInfo_ParseDie(pThis, &pUnit->Core, &g_CompileUnitDesc, pCursor, pAbbrev );4268 int rc = rtDwarfInfo_ParseDie(pThis, &pUnit->Core, &g_CompileUnitDesc, pCursor, pAbbrev, true /*fInitDie*/); 4146 4269 if (RT_FAILURE(rc)) 4147 4270 return rc; … … 4220 4343 } 4221 4344 4222 rc = rtDwarfInfo_ParseDie(pThis, pNewDie, pDieDesc, pCursor, pAbbrev );4345 rc = rtDwarfInfo_ParseDie(pThis, pNewDie, pDieDesc, pCursor, pAbbrev, true /*fInitDie*/); 4223 4346 if (RT_FAILURE(rc)) 4224 4347 return rc;
Note:
See TracChangeset
for help on using the changeset viewer.