Index: include/lldb/Symbol/ObjectFile.h =================================================================== --- include/lldb/Symbol/ObjectFile.h +++ include/lldb/Symbol/ObjectFile.h @@ -369,7 +369,7 @@ /// The list of sections contained in this object file. //------------------------------------------------------------------ virtual SectionList * - GetSectionList (); + GetSectionList (bool update_module_section_list = true); virtual void CreateSections (SectionList &unified_section_list) = 0; Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp =================================================================== --- source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -1684,6 +1684,12 @@ static ConstString g_sect_name_dwarf_debug_ranges (".debug_ranges"); static ConstString g_sect_name_dwarf_debug_str (".debug_str"); static ConstString g_sect_name_dwarf_debug_str_offsets (".debug_str_offsets"); + static ConstString g_sect_name_dwarf_debug_abbrev_dwo (".debug_abbrev.dwo"); + static ConstString g_sect_name_dwarf_debug_info_dwo (".debug_info.dwo"); + static ConstString g_sect_name_dwarf_debug_line_dwo (".debug_line.dwo"); + static ConstString g_sect_name_dwarf_debug_loc_dwo (".debug_loc.dwo"); + static ConstString g_sect_name_dwarf_debug_str_dwo (".debug_str.dwo"); + static ConstString g_sect_name_dwarf_debug_str_offsets_dwo (".debug_str_offsets.dwo"); static ConstString g_sect_name_eh_frame (".eh_frame"); SectionType sect_type = eSectionTypeOther; @@ -1717,20 +1723,26 @@ // MISSING? .gnu_debugdata - "mini debuginfo / MiniDebugInfo" section, http://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html // MISSING? .debug-index - http://src.chromium.org/viewvc/chrome/trunk/src/build/gdb-add-index?pathrev=144644 // MISSING? .debug_types - Type descriptions from DWARF 4? See http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo - else if (name == g_sect_name_dwarf_debug_abbrev) sect_type = eSectionTypeDWARFDebugAbbrev; - else if (name == g_sect_name_dwarf_debug_addr) sect_type = eSectionTypeDWARFDebugAddr; - else if (name == g_sect_name_dwarf_debug_aranges) sect_type = eSectionTypeDWARFDebugAranges; - else if (name == g_sect_name_dwarf_debug_frame) sect_type = eSectionTypeDWARFDebugFrame; - else if (name == g_sect_name_dwarf_debug_info) sect_type = eSectionTypeDWARFDebugInfo; - else if (name == g_sect_name_dwarf_debug_line) sect_type = eSectionTypeDWARFDebugLine; - else if (name == g_sect_name_dwarf_debug_loc) sect_type = eSectionTypeDWARFDebugLoc; - else if (name == g_sect_name_dwarf_debug_macinfo) sect_type = eSectionTypeDWARFDebugMacInfo; - else if (name == g_sect_name_dwarf_debug_pubnames) sect_type = eSectionTypeDWARFDebugPubNames; - else if (name == g_sect_name_dwarf_debug_pubtypes) sect_type = eSectionTypeDWARFDebugPubTypes; - else if (name == g_sect_name_dwarf_debug_ranges) sect_type = eSectionTypeDWARFDebugRanges; - else if (name == g_sect_name_dwarf_debug_str) sect_type = eSectionTypeDWARFDebugStr; - else if (name == g_sect_name_dwarf_debug_str_offsets) sect_type = eSectionTypeDWARFDebugStrOffsets; - else if (name == g_sect_name_eh_frame) sect_type = eSectionTypeEHFrame; + else if (name == g_sect_name_dwarf_debug_abbrev) sect_type = eSectionTypeDWARFDebugAbbrev; + else if (name == g_sect_name_dwarf_debug_addr) sect_type = eSectionTypeDWARFDebugAddr; + else if (name == g_sect_name_dwarf_debug_aranges) sect_type = eSectionTypeDWARFDebugAranges; + else if (name == g_sect_name_dwarf_debug_frame) sect_type = eSectionTypeDWARFDebugFrame; + else if (name == g_sect_name_dwarf_debug_info) sect_type = eSectionTypeDWARFDebugInfo; + else if (name == g_sect_name_dwarf_debug_line) sect_type = eSectionTypeDWARFDebugLine; + else if (name == g_sect_name_dwarf_debug_loc) sect_type = eSectionTypeDWARFDebugLoc; + else if (name == g_sect_name_dwarf_debug_macinfo) sect_type = eSectionTypeDWARFDebugMacInfo; + else if (name == g_sect_name_dwarf_debug_pubnames) sect_type = eSectionTypeDWARFDebugPubNames; + else if (name == g_sect_name_dwarf_debug_pubtypes) sect_type = eSectionTypeDWARFDebugPubTypes; + else if (name == g_sect_name_dwarf_debug_ranges) sect_type = eSectionTypeDWARFDebugRanges; + else if (name == g_sect_name_dwarf_debug_str) sect_type = eSectionTypeDWARFDebugStr; + else if (name == g_sect_name_dwarf_debug_str_offsets) sect_type = eSectionTypeDWARFDebugStrOffsets; + else if (name == g_sect_name_dwarf_debug_abbrev_dwo) sect_type = eSectionTypeDWARFDebugAbbrev; + else if (name == g_sect_name_dwarf_debug_info_dwo) sect_type = eSectionTypeDWARFDebugInfo; + else if (name == g_sect_name_dwarf_debug_line_dwo) sect_type = eSectionTypeDWARFDebugLine; + else if (name == g_sect_name_dwarf_debug_loc_dwo) sect_type = eSectionTypeDWARFDebugLoc; + else if (name == g_sect_name_dwarf_debug_str_dwo) sect_type = eSectionTypeDWARFDebugStr; + else if (name == g_sect_name_dwarf_debug_str_offsets_dwo) sect_type = eSectionTypeDWARFDebugStrOffsets; + else if (name == g_sect_name_eh_frame) sect_type = eSectionTypeEHFrame; switch (header.sh_type) { Index: source/Plugins/SymbolFile/DWARF/CMakeLists.txt =================================================================== --- source/Plugins/SymbolFile/DWARF/CMakeLists.txt +++ source/Plugins/SymbolFile/DWARF/CMakeLists.txt @@ -24,6 +24,7 @@ LogChannelDWARF.cpp NameToDIE.cpp SymbolFileDWARF.cpp + SymbolFileDWARFDwo.cpp SymbolFileDWARFDebugMap.cpp UniqueDWARFASTType.cpp ) Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -15,6 +15,7 @@ #include "SymbolFileDWARF.h" class NameToDIE; +class SymbolFileDWARFDwo; class DWARFCompileUnit { @@ -29,6 +30,7 @@ }; DWARFCompileUnit(SymbolFileDWARF* dwarf2Data); + ~DWARFCompileUnit(); bool Extract(const lldb_private::DWARFDataExtractor &debug_info, lldb::offset_t *offset_ptr); size_t ExtractDIEsIfNeeded (bool cu_die_only); @@ -53,7 +55,8 @@ dw_offset_t GetAbbrevOffset() const; uint8_t GetAddressByteSize() const { return m_addr_size; } dw_addr_t GetBaseAddress() const { return m_base_addr; } - dw_addr_t GetAddrBase() const { return 0; } // TODO: Read out DW_AT_addr_base from the parent compile unit + dw_addr_t GetAddrBase() const { return m_addr_base; } + void SetAddrBase(dw_addr_t addr_base) { m_addr_base = addr_base; } void ClearDIEs(bool keep_compile_unit_die); void BuildAddressRangeTable (SymbolFileDWARF* dwarf2Data, DWARFDebugAranges* debug_aranges); @@ -98,6 +101,9 @@ m_die_array.reserve(GetDebugInfoSize() / 24); m_die_array.push_back(die); } + + void + AddCompileUnitDIE (DWARFDebugInfoEntry& die); bool HasDIEsParsed () const @@ -199,9 +205,19 @@ bool GetIsOptimized (); + + SymbolFileDWARFDwo* + GetDwoSymbolFile() + { + // Extract the compile unit DIE as that one contains the dwo symbol file information + ExtractDIEsIfNeeded(true); + return m_dwo_symbol_file.get(); + } protected: SymbolFileDWARF* m_dwarf2Data; + lldb::ObjectFileSP m_dwo_obj_file; + std::unique_ptr m_dwo_symbol_file; const DWARFAbbreviationDeclarationSet *m_abbrevs; void * m_user_data; DWARFDebugInfoEntry::collection m_die_array; // The compile unit debug information entry item @@ -218,6 +234,7 @@ lldb::LanguageType m_language_type; bool m_is_dwarf64; lldb_private::LazyBool m_is_optimized; + dw_addr_t m_addr_base; // Value of DW_AT_addr_base void ParseProducerInfo (); Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -28,6 +28,7 @@ #include "NameToDIE.h" #include "SymbolFileDWARF.h" #include "SymbolFileDWARFDebugMap.h" +#include "SymbolFileDWARFDwo.h" using namespace lldb; using namespace lldb_private; @@ -57,6 +58,9 @@ { } +DWARFCompileUnit::~DWARFCompileUnit() +{} + void DWARFCompileUnit::Clear() { @@ -191,12 +195,12 @@ const bool null_die = die.IsNULL(); if (depth == 0) { - uint64_t base_addr = die.GetAttributeValueAsUnsigned(m_dwarf2Data, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS); + if (initial_die_array_size == 0) + AddCompileUnitDIE(die); + uint64_t base_addr = die.GetAttributeValueAsAddress(m_dwarf2Data, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS); if (base_addr == LLDB_INVALID_ADDRESS) - base_addr = die.GetAttributeValueAsUnsigned(m_dwarf2Data, this, DW_AT_entry_pc, 0); + base_addr = die.GetAttributeValueAsAddress(m_dwarf2Data, this, DW_AT_entry_pc, 0); SetBaseAddress (base_addr); - if (initial_die_array_size == 0) - AddDIE (die); if (cu_die_only) return 1; } @@ -289,6 +293,74 @@ return m_die_array.size(); } +void +DWARFCompileUnit::AddCompileUnitDIE(DWARFDebugInfoEntry& die) +{ + assert (m_die_array.empty() && "Compile unit DIE already added"); + AddDIE(die); + + DWARFDebugInfoEntry& cu_die = m_die_array.front(); + + const char* dwo_name = cu_die.GetAttributeValueAsString(m_dwarf2Data, + this, + DW_AT_GNU_dwo_name, + nullptr); + if (!dwo_name) + return; + + const char* comp_dir = cu_die.GetAttributeValueAsString(m_dwarf2Data, + this, + DW_AT_comp_dir, + nullptr); + if (!comp_dir) + return; + + FileSpec dwo_file(comp_dir, true); + dwo_file.AppendPathComponent(dwo_name); + if (!dwo_file.Exists()) + return; + + DataBufferSP dwo_file_data_sp; + lldb::offset_t dwo_file_data_offset = 0; + ObjectFileSP dwo_obj_file = ObjectFile::FindPlugin(m_dwarf2Data->GetObjectFile()->GetModule(), + &dwo_file, + 0 /* file_offset */, + dwo_file.GetByteSize(), + dwo_file_data_sp, + dwo_file_data_offset); + if (dwo_obj_file == nullptr) + return; + + std::unique_ptr dwo_symbol_file(new SymbolFileDWARFDwo(dwo_obj_file.get(), + this)); + + DWARFCompileUnit* dwo_cu = dwo_symbol_file->GetCompileUnit(); + if (!dwo_cu) + return; // Can't fetch the compile unit from the dwo file. + + const DWARFDebugInfoEntry* dwo_cu_die = dwo_cu->GetCompileUnitDIEOnly(); + if (!dwo_cu_die) + return; // Can't fetch the compile unit DIE from the dwo file. + + uint64_t main_dwo_id = cu_die.GetAttributeValueAsUnsigned(m_dwarf2Data, + this, + DW_AT_GNU_dwo_id, + 0); + uint64_t sub_dwo_id = dwo_cu_die->GetAttributeValueAsUnsigned(dwo_symbol_file.get(), + dwo_cu, + DW_AT_GNU_dwo_id, + 0); + if (main_dwo_id != sub_dwo_id) + return; // The 2 dwo ID isn't match. Don't use the dwo file as it belongs to a differectn compilation. + + m_dwo_symbol_file = std::move(dwo_symbol_file); + m_dwo_obj_file = std::move(dwo_obj_file); + m_dwarf2Data->AddDwoSymbolFile(m_dwo_symbol_file.get()); + dwo_cu->SetAddrBase(cu_die.GetAttributeValueAsUnsigned(m_dwarf2Data, + this, + DW_AT_GNU_addr_base, + 0)); +} dw_offset_t DWARFCompileUnit::GetAbbrevOffset() const @@ -442,7 +514,6 @@ { const LineTable::FileAddressRanges::Entry &range = file_ranges.GetEntryRef(idx); debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), range.GetRangeEnd()); - printf ("0x%8.8x: [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", GetOffset(), range.GetRangeBase(), range.GetRangeEnd()); } } } Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -477,8 +477,7 @@ ) { DumpInfo* dumpInfo = (DumpInfo*)userData; - - const DWARFCompileUnit* cu = cu_sp.get(); + DWARFCompileUnit* cu = cu_sp.get(); Stream *s = dumpInfo->strm; bool show_parents = s->GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowAncestors); @@ -734,7 +733,7 @@ ) { FindCallbackStringInfo* info = (FindCallbackStringInfo*)userData; - const DWARFCompileUnit* cu = cu_sp.get(); + DWARFCompileUnit* cu = cu_sp.get(); if (die) { Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h +++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h @@ -132,118 +132,117 @@ void BuildAddressRangeTable( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, DWARFDebugAranges* debug_aranges) const; void BuildFunctionAddressRangeTable( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, DWARFDebugAranges* debug_aranges) const; bool FastExtract( const lldb_private::DWARFDataExtractor& debug_info_data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const DWARFFormValue::FixedFormSizes& fixed_form_sizes, lldb::offset_t* offset_ptr); bool Extract( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, lldb::offset_t* offset_ptr); bool LookupAddress( const dw_addr_t address, SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, DWARFDebugInfoEntry** function_die, DWARFDebugInfoEntry** block_die); size_t GetAttributes( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, DWARFFormValue::FixedFormSizes fixed_form_sizes, DWARFDebugInfoEntry::Attributes& attrs, uint32_t curr_depth = 0) const; // "curr_depth" for internal use only, don't set this yourself!!! - dw_offset_t GetAttributeValue( - SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, - const dw_attr_t attr, - DWARFFormValue& formValue, - dw_offset_t* end_attr_offset_ptr = NULL) const; - const char* GetAttributeValueAsString( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const dw_attr_t attr, const char* fail_value) const; uint64_t GetAttributeValueAsUnsigned( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const dw_attr_t attr, uint64_t fail_value) const; uint64_t GetAttributeValueAsReference( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const dw_attr_t attr, uint64_t fail_value) const; int64_t GetAttributeValueAsSigned( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const dw_attr_t attr, int64_t fail_value) const; + uint64_t GetAttributeValueAsAddress( + SymbolFileDWARF* dwarf2Data, + DWARFCompileUnit* cu, + const dw_attr_t attr, + uint64_t fail_value) const; + dw_addr_t GetAttributeHighPC( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, dw_addr_t lo_pc, uint64_t fail_value) const; bool GetAttributeAddressRange( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, dw_addr_t& lo_pc, dw_addr_t& hi_pc, uint64_t fail_value) const; size_t GetAttributeAddressRanges ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, DWARFDebugRanges::RangeList &ranges, bool check_hi_lo_pc) const; dw_offset_t GetAttributeValueAsLocation( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const dw_attr_t attr, lldb_private::DWARFDataExtractor& data, uint32_t &block_size) const; const char* GetName( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu) const; + DWARFCompileUnit* cu) const; const char* GetMangledName( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, bool substitute_name_allowed = true) const; const char* GetPubname( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu) const; + DWARFCompileUnit* cu) const; static bool GetName( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const dw_offset_t die_offset, lldb_private::Stream &s); static bool AppendTypeName( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const dw_offset_t die_offset, lldb_private::Stream &s); @@ -280,20 +279,20 @@ void Dump( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, lldb_private::Stream &s, uint32_t recurse_depth) const; void DumpAncestry( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const DWARFDebugInfoEntry* oldest, lldb_private::Stream &s, uint32_t recurse_depth) const; static void DumpAttribute( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const lldb_private::DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr, lldb_private::Stream &s, @@ -307,7 +306,7 @@ bool GetDIENamesAndRanges( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const char * &name, const char * &mangled, DWARFDebugRanges::RangeList& rangeList, @@ -449,6 +448,13 @@ DWARFDebugInfoEntry::collection &die_collection); protected: + dw_offset_t GetAttributeValue(SymbolFileDWARF* dwarf2Data, + DWARFCompileUnit* cu, + const dw_attr_t attr, + DWARFFormValue& formValue, + dw_offset_t* end_attr_offset_ptr = nullptr, + SymbolFileDWARF** attribute_symbol_file_ptr = nullptr) const; + dw_offset_t m_offset; // Offset within the .debug_info of the start of this entry uint32_t m_parent_idx; // How many to subtract from "this" to get the parent. If zero this die has no parent uint32_t m_sibling_idx:31, // How many to add to "this" to get the sibling. Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -19,7 +19,6 @@ #include "lldb/Symbol/ObjectFile.h" #include "DWARFCompileUnit.h" -#include "SymbolFileDWARF.h" #include "DWARFDebugAbbrev.h" #include "DWARFDebugAranges.h" #include "DWARFDebugInfo.h" @@ -29,6 +28,8 @@ #include "DWARFLocationDescription.h" #include "DWARFLocationList.h" #include "DWARFDebugRanges.h" +#include "SymbolFileDWARF.h" +#include "SymbolFileDWARFDwo.h" using namespace lldb_private; using namespace std; @@ -118,7 +119,7 @@ DWARFDebugInfoEntry::FastExtract ( const DWARFDataExtractor& debug_info_data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const DWARFFormValue::FixedFormSizes& fixed_form_sizes, lldb::offset_t *offset_ptr ) @@ -280,7 +281,7 @@ DWARFDebugInfoEntry::Extract ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, lldb::offset_t *offset_ptr ) { @@ -325,7 +326,10 @@ if (form_value.ExtractValue(debug_info_data, &offset)) { if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc) - ((DWARFCompileUnit*)cu)->SetBaseAddress(form_value.Unsigned()); + { + dw_addr_t base_address = form_value.Address(dwarf2Data); + cu->SetBaseAddress(base_address); + } } } else @@ -447,7 +451,7 @@ DWARFDebugInfoEntry::DumpAncestry ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const DWARFDebugInfoEntry* oldest, Stream &s, uint32_t recurse_depth @@ -740,7 +744,7 @@ DWARFDebugInfoEntry::GetDIENamesAndRanges ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const char * &name, const char * &mangled, DWARFDebugRanges::RangeList& ranges, @@ -788,7 +792,7 @@ switch (attr) { case DW_AT_low_pc: - lo_pc = form_value.Unsigned(); + lo_pc = form_value.Address(dwarf2Data); if (do_offset) hi_pc += lo_pc; @@ -796,13 +800,18 @@ break; case DW_AT_entry_pc: - lo_pc = form_value.Unsigned(); + lo_pc = form_value.Address(dwarf2Data); break; case DW_AT_high_pc: - hi_pc = form_value.Unsigned(); - if (form_value.Form() != DW_FORM_addr) + if (form_value.Form() == DW_FORM_addr || + form_value.Form() == DW_FORM_GNU_addr_index) { + hi_pc = form_value.Address(dwarf2Data); + } + else + { + hi_pc = form_value.Unsigned(); if (lo_pc == LLDB_INVALID_ADDRESS) do_offset = hi_pc != LLDB_INVALID_ADDRESS; else @@ -957,7 +966,7 @@ DWARFDebugInfoEntry::Dump ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, Stream &s, uint32_t recurse_depth ) const @@ -1055,7 +1064,7 @@ DWARFDebugInfoEntry::DumpAttribute ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr, Stream &s, @@ -1212,7 +1221,7 @@ DWARFDebugInfoEntry::GetAttributes ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, DWARFFormValue::FixedFormSizes fixed_form_sizes, DWARFDebugInfoEntry::Attributes& attributes, uint32_t curr_depth @@ -1309,10 +1318,11 @@ DWARFDebugInfoEntry::GetAttributeValue ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const dw_attr_t attr, DWARFFormValue& form_value, - dw_offset_t* end_attr_offset_ptr + dw_offset_t* end_attr_offset_ptr, + SymbolFileDWARF** attribute_symbol_file_ptr ) const { lldb::offset_t offset; @@ -1337,12 +1347,35 @@ { if (end_attr_offset_ptr) *end_attr_offset_ptr = offset; + if (attribute_symbol_file_ptr) + *attribute_symbol_file_ptr = dwarf2Data; return attr_offset; } } } - - return 0; + + // Try to get the attribute value from the dwo compile unit for compile unit DIEs + if (m_tag != DW_TAG_compile_unit) + return 0; + + SymbolFileDWARFDwo* dwo_sym_file = cu->GetDwoSymbolFile(); + if (!dwo_sym_file) + return 0; + + DWARFCompileUnit* dwo_cu = dwo_sym_file->GetCompileUnit(); + if (!dwo_cu) + return 0; + + const DWARFDebugInfoEntry* dwo_cu_die = dwo_cu->GetCompileUnitDIEOnly(); + if (!dwo_cu_die) + return 0; + + return dwo_cu_die->GetAttributeValue(dwo_sym_file, + dwo_cu, + attr, + form_value, + end_attr_offset_ptr, + attribute_symbol_file_ptr); } //---------------------------------------------------------------------- @@ -1357,13 +1390,14 @@ DWARFDebugInfoEntry::GetAttributeValueAsString ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const dw_attr_t attr, const char* fail_value) const { DWARFFormValue form_value; - if (GetAttributeValue(dwarf2Data, cu, attr, form_value)) - return form_value.AsCString(dwarf2Data); + SymbolFileDWARF* attribute_symbol_file = nullptr; + if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, &attribute_symbol_file)) + return form_value.AsCString(attribute_symbol_file); return fail_value; } @@ -1376,7 +1410,7 @@ DWARFDebugInfoEntry::GetAttributeValueAsUnsigned ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const dw_attr_t attr, uint64_t fail_value ) const @@ -1396,7 +1430,7 @@ DWARFDebugInfoEntry::GetAttributeValueAsSigned ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const dw_attr_t attr, int64_t fail_value ) const @@ -1417,7 +1451,7 @@ DWARFDebugInfoEntry::GetAttributeValueAsReference ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const dw_attr_t attr, uint64_t fail_value ) const @@ -1428,6 +1462,22 @@ return fail_value; } +uint64_t +DWARFDebugInfoEntry::GetAttributeValueAsAddress +( + SymbolFileDWARF* dwarf2Data, + DWARFCompileUnit* cu, + const dw_attr_t attr, + uint64_t fail_value +) const +{ + DWARFFormValue form_value; + SymbolFileDWARF* attribute_symbol_file = nullptr; + if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, &attribute_symbol_file)) + return form_value.Address(attribute_symbol_file); + return fail_value; +} + //---------------------------------------------------------------------- // GetAttributeHighPC // @@ -1440,7 +1490,7 @@ DWARFDebugInfoEntry::GetAttributeHighPC ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, dw_addr_t lo_pc, uint64_t fail_value ) const @@ -1470,13 +1520,13 @@ DWARFDebugInfoEntry::GetAttributeAddressRange ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, dw_addr_t& lo_pc, dw_addr_t& hi_pc, uint64_t fail_value ) const { - lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, fail_value); + lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc, fail_value); if (lo_pc != fail_value) { hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, fail_value); @@ -1490,7 +1540,7 @@ size_t DWARFDebugInfoEntry::GetAttributeAddressRanges(SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, DWARFDebugRanges::RangeList &ranges, bool check_hi_lo_pc) const { @@ -1531,7 +1581,7 @@ DWARFDebugInfoEntry::GetAttributeValueAsLocation ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const dw_attr_t attr, DWARFDataExtractor& location_data, uint32_t &block_size @@ -1543,14 +1593,20 @@ // Empty out data in case we don't find anything location_data.Clear(); dw_offset_t end_addr_offset = DW_INVALID_OFFSET; - const dw_offset_t attr_offset = GetAttributeValue(dwarf2Data, cu, attr, form_value, &end_addr_offset); + SymbolFileDWARF* attribute_symbol_file = nullptr; + const dw_offset_t attr_offset = GetAttributeValue(dwarf2Data, + cu, + attr, + form_value, + &end_addr_offset, + &attribute_symbol_file); if (attr_offset) { const uint8_t* blockData = form_value.BlockData(); if (blockData) { // We have an inlined location list in the .debug_info section - const DWARFDataExtractor& debug_info = dwarf2Data->get_debug_info_data(); + const DWARFDataExtractor& debug_info = attribute_symbol_file->get_debug_info_data(); dw_offset_t block_offset = blockData - debug_info.GetDataStart(); block_size = (end_addr_offset - attr_offset) - form_value.Unsigned(); location_data.SetData(debug_info, block_offset, block_size); @@ -1561,10 +1617,12 @@ // the offset into the .debug_loc section that describes // the value over it's lifetime lldb::offset_t debug_loc_offset = form_value.Unsigned(); - if (dwarf2Data) + if (attribute_symbol_file) { - assert(dwarf2Data->get_debug_loc_data().GetAddressByteSize() == cu->GetAddressByteSize()); - return DWARFLocationList::Extract(dwarf2Data->get_debug_loc_data(), &debug_loc_offset, location_data); + assert(attribute_symbol_file->get_debug_loc_data().GetAddressByteSize() == cu->GetAddressByteSize()); + return DWARFLocationList::Extract(attribute_symbol_file->get_debug_loc_data(), + &debug_loc_offset, + location_data); } } } @@ -1581,23 +1639,25 @@ DWARFDebugInfoEntry::GetName ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu + DWARFCompileUnit* cu ) const { + const char* dw_at_name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr); + if (dw_at_name) + return dw_at_name; + DWARFFormValue form_value; - if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value)) - return form_value.AsCString(dwarf2Data); - else if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) + if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) { DWARFCompileUnitSP cu_sp_ptr; - const DWARFDebugInfoEntry* die = const_cast(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(), &cu_sp_ptr); + const DWARFDebugInfoEntry* die = dwarf2Data->DebugInfo()->GetDIEPtr(form_value.Reference(), &cu_sp_ptr); if (die) return die->GetName(dwarf2Data, cu_sp_ptr.get()); } else if (GetAttributeValue(dwarf2Data, cu, DW_AT_abstract_origin, form_value)) { DWARFCompileUnitSP cu_sp_ptr; - const DWARFDebugInfoEntry* die = const_cast(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(), &cu_sp_ptr); + const DWARFDebugInfoEntry* die = dwarf2Data->DebugInfo()->GetDIEPtr(form_value.Reference(), &cu_sp_ptr); if (die) return die->GetName(dwarf2Data, cu_sp_ptr.get()); } @@ -1615,24 +1675,24 @@ DWARFDebugInfoEntry::GetMangledName ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, bool substitute_name_allowed ) const { const char* name = nullptr; - DWARFFormValue form_value; - if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value)) - name = form_value.AsCString(dwarf2Data); + name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name, nullptr); + if (name) + return name; - if (GetAttributeValue(dwarf2Data, cu, DW_AT_linkage_name, form_value)) - name = form_value.AsCString(dwarf2Data); + name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr); + if (name) + return name; - if (substitute_name_allowed && name == nullptr) - { - if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value)) - name = form_value.AsCString(dwarf2Data); - } + if (!substitute_name_allowed) + return nullptr; + + name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr); return name; } @@ -1647,27 +1707,32 @@ DWARFDebugInfoEntry::GetPubname ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu + DWARFCompileUnit* cu ) const { - const char* name = NULL; + const char* name = nullptr; if (!dwarf2Data) return name; - DWARFFormValue form_value; + name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name, nullptr); + if (name) + return name; - if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value)) - name = form_value.AsCString(dwarf2Data); - else if (GetAttributeValue(dwarf2Data, cu, DW_AT_linkage_name, form_value)) - name = form_value.AsCString(dwarf2Data); - else if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value)) - name = form_value.AsCString(dwarf2Data); - else if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) + name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr); + if (name) + return name; + + name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr); + if (name) + return name; + + DWARFFormValue form_value; + if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) { // The specification DIE may be in another compile unit so we need // to get a die and its compile unit. DWARFCompileUnitSP cu_sp_ptr; - const DWARFDebugInfoEntry* die = const_cast(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(), &cu_sp_ptr); + const DWARFDebugInfoEntry* die = dwarf2Data->DebugInfo()->GetDIEPtr(form_value.Reference(), &cu_sp_ptr); if (die) return die->GetPubname(dwarf2Data, cu_sp_ptr.get()); } @@ -1688,7 +1753,7 @@ DWARFDebugInfoEntry::GetName ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const dw_offset_t die_offset, Stream &s ) @@ -1710,15 +1775,11 @@ } else { - DWARFFormValue form_value; - if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value)) + const char* name = die.GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr); + if (name) { - const char* name = form_value.AsCString(dwarf2Data); - if (name) - { - s.PutCString(name); - return true; - } + s.PutCString(name); + return true; } } } @@ -1737,7 +1798,7 @@ DWARFDebugInfoEntry::AppendTypeName ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, const dw_offset_t die_offset, Stream &s ) @@ -1760,8 +1821,6 @@ else { const char* name = die.GetPubname(dwarf2Data, cu); - // if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value)) - // name = form_value.AsCString(&dwarf2Data->get_debug_str_data()); if (name) s.PutCString(name); else @@ -1848,7 +1907,7 @@ DWARFDebugInfoEntry::BuildAddressRangeTable ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, DWARFDebugAranges* debug_aranges ) const { @@ -1887,7 +1946,7 @@ DWARFDebugInfoEntry::BuildFunctionAddressRangeTable ( SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, DWARFDebugAranges* debug_aranges ) const { @@ -2110,7 +2169,7 @@ ( const dw_addr_t address, SymbolFileDWARF* dwarf2Data, - const DWARFCompileUnit* cu, + DWARFCompileUnit* cu, DWARFDebugInfoEntry** function_die, DWARFDebugInfoEntry** block_die ) @@ -2184,7 +2243,7 @@ if (match_addr_range) { - dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS); + dw_addr_t lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS); if (lo_pc != LLDB_INVALID_ADDRESS) { dw_addr_t hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, LLDB_INVALID_ADDRESS); Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -63,6 +63,8 @@ #define DIE_IS_BEING_PARSED ((lldb_private::Type*)1) +class SymbolFileDWARFDwo; + class SymbolFileDWARF : public lldb_private::SymbolFile, public lldb_private::UserID { public: @@ -108,10 +110,12 @@ //------------------------------------------------------------------ // Compile Unit function calls //------------------------------------------------------------------ - uint32_t GetNumCompileUnits() override; + virtual lldb::CompUnitSP + ParseCompileUnit(DWARFCompileUnit* dwarf_cu, uint32_t cu_idx); + lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; @@ -273,7 +277,7 @@ const DWARFDebugRanges* DebugRanges() const; - const lldb_private::DWARFDataExtractor& + virtual const lldb_private::DWARFDataExtractor& GetCachedSectionData (uint32_t got_flag, lldb::SectionType sect_type, lldb_private::DWARFDataExtractor &data); @@ -282,8 +286,7 @@ SupportedVersion(uint16_t version); const DWARFDebugInfoEntry * - GetDeclContextDIEContainingDIE (const DWARFCompileUnit *cu, - const DWARFDebugInfoEntry *die); + GetDeclContextDIEContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die); lldb_private::Flags& GetFlags () @@ -352,12 +355,8 @@ const DWARFDebugInfoEntry *die); DISALLOW_COPY_AND_ASSIGN (SymbolFileDWARF); - - lldb::CompUnitSP - ParseCompileUnit (DWARFCompileUnit* dwarf_cu, - uint32_t cu_idx); - - DWARFCompileUnit* + + virtual DWARFCompileUnit* GetDWARFCompileUnit (lldb_private::CompileUnit *comp_unit); DWARFCompileUnit* @@ -433,7 +432,7 @@ bool FunctionDieMatchesPartialName (const DWARFDebugInfoEntry* die, - const DWARFCompileUnit *dwarf_cu, + DWARFCompileUnit *dwarf_cu, uint32_t name_type_mask, const char *partial_name, const char *base_name_start, @@ -481,11 +480,6 @@ GetTypeForDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry* die); - uint32_t - FindTypes (std::vector die_offsets, - uint32_t max_matches, - lldb_private::TypeList& types); - void Index(); @@ -560,6 +554,12 @@ void UpdateExternalModuleListIfNeeded(); + + void + AddDwoSymbolFile(SymbolFileDWARFDwo* dwo_symbol_file) + { + m_dwo_symbol_files.push_back(dwo_symbol_file); + } lldb::ModuleWP m_debug_map_module_wp; SymbolFileDWARFDebugMap * m_debug_map_symfile; @@ -614,6 +614,7 @@ DIEToVariableSP m_die_to_variable_sp; DIEToClangType m_forward_decl_die_to_clang_type; ClangTypeToDIE m_forward_decl_clang_type_to_die; + std::vector m_dwo_symbol_files; }; #endif // SymbolFileDWARF_SymbolFileDWARF_h_ Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -71,6 +71,7 @@ #include "DWARFLocationList.h" #include "LogChannelDWARF.h" #include "SymbolFileDWARFDebugMap.h" +#include "SymbolFileDWARFDwo.h" #include @@ -295,6 +296,7 @@ { if (cu) { + assert (cu->GetSymbolFileDWARF() == this); if (die) { const dw_offset_t die_offset = die->GetOffset(); @@ -367,12 +369,27 @@ dwarf_cu = GetDWARFCompileUnit(comp_unit); if (dwarf_cu == 0) return 0; - GetTypes (dwarf_cu, - dwarf_cu->DIE(), - dwarf_cu->GetOffset(), - dwarf_cu->GetNextCompileUnitOffset(), - type_mask, - type_set); + + SymbolFileDWARFDwo* dwo_symbol_file = dwarf_cu->GetDwoSymbolFile(); + if (dwo_symbol_file) + { + dwarf_cu = dwo_symbol_file->GetCompileUnit(); + dwo_symbol_file->GetTypes (dwarf_cu, + dwarf_cu->DIE(), + 0, + UINT32_MAX, + type_mask, + type_set); + } + else + { + GetTypes (dwarf_cu, + dwarf_cu->DIE(), + dwarf_cu->GetOffset(), + dwarf_cu->GetNextCompileUnitOffset(), + type_mask, + type_set); + } } else { @@ -385,12 +402,26 @@ dwarf_cu = info->GetCompileUnitAtIndex(cu_idx); if (dwarf_cu) { - GetTypes (dwarf_cu, - dwarf_cu->DIE(), - 0, - UINT32_MAX, - type_mask, - type_set); + SymbolFileDWARFDwo* dwo_symbol_file = dwarf_cu->GetDwoSymbolFile(); + if (dwo_symbol_file) + { + dwarf_cu = dwo_symbol_file->GetCompileUnit(); + dwo_symbol_file->GetTypes (dwarf_cu, + dwarf_cu->DIE(), + 0, + UINT32_MAX, + type_mask, + type_set); + } + else + { + GetTypes (dwarf_cu, + dwarf_cu->DIE(), + 0, + UINT32_MAX, + type_mask, + type_set); + } } } } @@ -990,7 +1021,7 @@ ModuleSP module_sp (m_obj_file->GetModule()); if (module_sp) { - const DWARFDebugInfoEntry * cu_die = dwarf_cu->GetCompileUnitDIEOnly (); + const DWARFDebugInfoEntry* cu_die = dwarf_cu->GetCompileUnitDIEOnly (); if (cu_die) { FileSpec cu_file_spec{cu_die->GetName(this, dwarf_cu), false}; @@ -1036,6 +1067,13 @@ dwarf_cu->SetUserData(cu_sp.get()); + SymbolFileDWARFDwo* dwo_symbol_file = dwarf_cu->GetDwoSymbolFile(); + if (dwo_symbol_file) + { + DWARFCompileUnit* dwo_dwarf_cu = dwo_symbol_file->GetCompileUnit(); + dwo_dwarf_cu->SetUserData(cu_sp.get()); + } + // Figure out the compile unit index if we weren't given one if (cu_idx == UINT32_MAX) DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx); @@ -1117,6 +1155,10 @@ DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); if (dwarf_cu) { + SymbolFileDWARFDwo* dwo_symbol_file = dwarf_cu->GetDwoSymbolFile(); + if (dwo_symbol_file) + return dwo_symbol_file->ParseFunctionBlocks(sc); + DWARFDIECollection function_dies; const size_t num_functions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies); size_t func_idx; @@ -1581,8 +1623,15 @@ // We have a struct/union/class/enum that needs to be fully resolved. CompilerType clang_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(clang_type); const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers.GetOpaqueQualType()); - if (die == NULL) + if (die == nullptr) { + // Ask the child dwo files if any of them know about this type + for (SymbolFileDWARFDwo* dwo_symbol_file : m_dwo_symbol_files) + { + if (dwo_symbol_file && dwo_symbol_file->HasForwardDeclForClangType(clang_type)) + return dwo_symbol_file->CompleteType(clang_type); + } + // We have already resolved this type... return true; } @@ -1723,8 +1772,7 @@ m_fetched_external_modules = true; DWARFDebugInfo * debug_info = DebugInfo(); - debug_info->GetNumCompileUnits(); - + const uint32_t num_compile_units = GetNumCompileUnits(); for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { @@ -1873,6 +1921,10 @@ sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx); if (sc.comp_unit) { + SymbolFileDWARFDwo* dwo_symbol_file = dwarf_cu->GetDwoSymbolFile(); + if (dwo_symbol_file) + return dwo_symbol_file->ResolveSymbolContext(so_addr, resolve_scope, sc); + resolved |= eSymbolContextCompUnit; bool force_check_line_table = false; @@ -2170,7 +2222,11 @@ } uint32_t -SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, VariableList& variables) +SymbolFileDWARF::FindGlobalVariables (const ConstString &name, + const CompilerDeclContext *parent_decl_ctx, + bool append, + uint32_t max_matches, + VariableList& variables) { Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); @@ -2218,6 +2274,13 @@ if (!m_indexed) Index (); + for (SymbolFileDWARFDwo* dwo_symbol_file : m_dwo_symbol_files) + dwo_symbol_file->FindGlobalVariables(name, + parent_decl_ctx, + true /* append */, + max_matches, + variables); + m_global_index.Find (name, die_offsets); } @@ -2338,7 +2401,13 @@ // Index the DWARF if we haven't already if (!m_indexed) Index (); - + + for (SymbolFileDWARFDwo* dwo_symbol_file : m_dwo_symbol_files) + dwo_symbol_file->FindGlobalVariables(regex, + true /* append */, + max_matches, + variables); + m_global_index.Find (regex, die_offsets); } @@ -2511,7 +2580,7 @@ bool SymbolFileDWARF::FunctionDieMatchesPartialName (const DWARFDebugInfoEntry* die, - const DWARFCompileUnit *dwarf_cu, + DWARFCompileUnit *dwarf_cu, uint32_t name_type_mask, const char *partial_name, const char *base_name_start, @@ -2955,7 +3024,14 @@ { FindFunctions (name, m_function_selector_index, include_inlines, sc_list); } - + + for (SymbolFileDWARFDwo* dwo_symbol_file : m_dwo_symbol_files) + dwo_symbol_file->FindFunctions(name, + parent_decl_ctx, + name_type_mask, + include_inlines, + true /* append */, + sc_list); } // Return the number of variable that were appended to the list @@ -2990,7 +3066,6 @@ regex.GetText(), append); } - // If we aren't appending the results to this list, then clear the list if (!append) @@ -3014,6 +3089,9 @@ FindFunctions (regex, m_function_basename_index, include_inlines, sc_list); FindFunctions (regex, m_function_fullname_index, include_inlines, sc_list); + + for (SymbolFileDWARFDwo* dwo_symbol_file : m_dwo_symbol_files) + dwo_symbol_file->FindFunctions(regex, include_inlines, true, sc_list); } // Return the number of variable that were appended to the list @@ -3053,6 +3131,7 @@ // If we aren't appending the results to this list, then clear the list if (!append) types.Clear(); + const uint32_t initial_types_size = types.GetSize(); if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) return 0; @@ -3073,13 +3152,20 @@ Index (); m_type_index.Find (name, die_offsets); + + for (SymbolFileDWARFDwo* dwo_symbol_file : m_dwo_symbol_files) + dwo_symbol_file->FindTypes(sc, + name, + parent_decl_ctx, + true /* append */, + max_matches, + types); } const size_t num_die_matches = die_offsets.size(); if (num_die_matches) { - const uint32_t initial_types_size = types.GetSize(); DWARFCompileUnit* dwarf_cu = NULL; const DWARFDebugInfoEntry* die = NULL; DWARFDebugInfo* debug_info = DebugInfo(); @@ -3112,31 +3198,31 @@ } } - const uint32_t num_matches = types.GetSize() - initial_types_size; - if (log && num_matches) + } + + const uint32_t num_matches = types.GetSize() - initial_types_size; + if (log && num_matches) + { + if (parent_decl_ctx) { - if (parent_decl_ctx) - { - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = %p (\"%s\"), append=%u, max_matches=%u, type_list) => %u", - name.GetCString(), - static_cast(parent_decl_ctx), - parent_decl_ctx->GetName().AsCString(""), - append, max_matches, - num_matches); - } - else - { - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list) => %u", - name.GetCString(), - append, max_matches, - num_matches); - } + GetObjectFile()->GetModule()->LogMessage (log, + "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = %p (\"%s\"), append=%u, max_matches=%u, type_list) => %u", + name.GetCString(), + static_cast(parent_decl_ctx), + parent_decl_ctx->GetName().AsCString(""), + append, max_matches, + num_matches); + } + else + { + GetObjectFile()->GetModule()->LogMessage (log, + "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list) => %u", + name.GetCString(), + append, max_matches, + num_matches); } - return num_matches; } - return 0; + return num_matches; } @@ -3180,6 +3266,13 @@ if (!m_indexed) Index (); + for (SymbolFileDWARFDwo* dwo_symbol_file : m_dwo_symbol_files) + { + namespace_decl_ctx = dwo_symbol_file->FindNamespace(sc, name, parent_decl_ctx); + if (namespace_decl_ctx) + return namespace_decl_ctx; + } + m_namespace_index.Find (name, die_offsets); } @@ -3233,35 +3326,6 @@ return namespace_decl_ctx; } -uint32_t -SymbolFileDWARF::FindTypes(std::vector die_offsets, uint32_t max_matches, TypeList& types) -{ - // Remember how many sc_list are in the list before we search in case - // we are appending the results to a variable list. - uint32_t original_size = types.GetSize(); - - const uint32_t num_die_offsets = die_offsets.size(); - // Parse all of the types we found from the pubtypes matches - uint32_t i; - uint32_t num_matches = 0; - for (i = 0; i < num_die_offsets; ++i) - { - Type *matching_type = ResolveTypeUID (die_offsets[i]); - if (matching_type) - { - // We found a type pointer, now find the shared pointer form our type list - types.InsertUnique (matching_type->shared_from_this()); - ++num_matches; - if (num_matches >= max_matches) - break; - } - } - - // Return the number of variable that were appended to the list - return types.GetSize() - original_size; -} - - TypeSP SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *dwarf_cu, const DWARFDebugInfoEntry* die) { @@ -3289,7 +3353,7 @@ const DWARFDebugInfoEntry * -SymbolFileDWARF::GetDeclContextDIEContainingDIE (const DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die) +SymbolFileDWARF::GetDeclContextDIEContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die) { if (cu && die) { @@ -3653,6 +3717,13 @@ { if (!m_indexed) Index (); + + for (SymbolFileDWARFDwo* dwo_symbol_file : m_dwo_symbol_files) + { + type_sp = dwo_symbol_file->FindDefinitionTypeForDWARFDeclContext(dwarf_decl_ctx); + if (type_sp) + return type_sp; + } m_type_index.Find (type_name, die_offsets); } @@ -3833,6 +3904,10 @@ DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); if (dwarf_cu) { + SymbolFileDWARFDwo* dwo_symbol_file = dwarf_cu->GetDwoSymbolFile(); + if (dwo_symbol_file) + return dwo_symbol_file->ParseFunctionBlocks(sc); + dw_offset_t function_die_offset = sc.function->GetID(); const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset); if (function_die) @@ -3854,6 +3929,10 @@ DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); if (dwarf_cu) { + SymbolFileDWARFDwo* dwo_symbol_file = dwarf_cu->GetDwoSymbolFile(); + if (dwo_symbol_file) + return dwo_symbol_file->ParseTypes(sc); + if (sc.function) { dw_offset_t function_die_offset = sc.function->GetID(); @@ -3887,14 +3966,16 @@ if (sc.function) { - DWARFCompileUnit* dwarf_cu = info->GetCompileUnitContainingDIE(sc.function->GetID()).get(); - - if (dwarf_cu == NULL) + DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.function->GetCompileUnit()); + if (dwarf_cu == nullptr) return 0; - + + SymbolFileDWARFDwo* dwo_symbol_file = dwarf_cu->GetDwoSymbolFile(); + if (dwo_symbol_file) + return dwo_symbol_file->ParseVariablesForContext (sc); + const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID()); - - dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS); + dw_addr_t func_lo_pc = function_die->GetAttributeValueAsAddress (this, dwarf_cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS); if (func_lo_pc != LLDB_INVALID_ADDRESS) { const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true); @@ -3908,8 +3989,12 @@ { DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID()).get(); - if (dwarf_cu == NULL) + if (dwarf_cu == nullptr) return 0; + + SymbolFileDWARFDwo* dwo_symbol_file = dwarf_cu->GetDwoSymbolFile(); + if (dwo_symbol_file) + return dwo_symbol_file->ParseVariablesForContext (sc); uint32_t vars_added = 0; VariableListSP variables (sc.comp_unit->GetVariableList(false)); Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h =================================================================== --- /dev/null +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h @@ -0,0 +1,45 @@ +//===-- SymbolFileDWARFDwo.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_ +#define SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "SymbolFileDWARF.h" + +class SymbolFileDWARFDwo : public SymbolFileDWARF +{ +public: + SymbolFileDWARFDwo(lldb_private::ObjectFile* objfile, DWARFCompileUnit* dwarf_cu); + + virtual + ~SymbolFileDWARFDwo() = default; + + const lldb_private::DWARFDataExtractor& + GetCachedSectionData(uint32_t got_flag, + lldb::SectionType sect_type, + lldb_private::DWARFDataExtractor &data) override; + + lldb::CompUnitSP + ParseCompileUnit(DWARFCompileUnit* dwarf_cu, uint32_t cu_idx) override; + + DWARFCompileUnit* + GetCompileUnit(); + + DWARFCompileUnit* + GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) override; + +protected: + DWARFCompileUnit* m_base_dwarf_cu; +}; + +#endif // SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_ Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp =================================================================== --- /dev/null +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp @@ -0,0 +1,79 @@ +//===-- SymbolFileDWARFDwo.cpp ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "SymbolFileDWARFDwo.h" + +#include "lldb/Core/Section.h" +#include "lldb/Symbol/ObjectFile.h" + +#include "DWARFCompileUnit.h" +#include "DWARFDebugInfo.h" + +using namespace lldb; +using namespace lldb_private; + +SymbolFileDWARFDwo::SymbolFileDWARFDwo(ObjectFile* objfile, DWARFCompileUnit* dwarf_cu) : + SymbolFileDWARF(objfile), + m_base_dwarf_cu(dwarf_cu) +{ +} + +const lldb_private::DWARFDataExtractor& +SymbolFileDWARFDwo::GetCachedSectionData(uint32_t got_flag, + lldb::SectionType sect_type, + lldb_private::DWARFDataExtractor &data) +{ + if (!m_flags.IsClear (got_flag)) + return data; + + const SectionList* section_list = m_obj_file->GetSectionList(false /* update_module_section_list */); + if (section_list) + { + SectionSP section_sp (section_list->FindSectionByType(sect_type, true)); + if (section_sp) + { + // See if we memory mapped the DWARF segment? + if (m_dwarf_data.GetByteSize()) + { + data.SetData(m_dwarf_data, section_sp->GetOffset(), section_sp->GetFileSize()); + m_flags.Set (got_flag); + return data; + } + + if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0) + { + m_flags.Set (got_flag); + return data; + } + + data.Clear(); + } + } + return SymbolFileDWARF::GetCachedSectionData(got_flag, sect_type, data); +} + +lldb::CompUnitSP +SymbolFileDWARFDwo::ParseCompileUnit(DWARFCompileUnit* dwarf_cu, uint32_t cu_idx) +{ + assert(GetCompileUnit() == dwarf_cu && "SymbolFileDWARFDwo::ParseCompileUnit called with incompatible compile unit"); + return m_base_dwarf_cu->GetSymbolFileDWARF()->ParseCompileUnit(m_base_dwarf_cu, UINT32_MAX); +} + +DWARFCompileUnit* +SymbolFileDWARFDwo::GetCompileUnit() +{ + assert(GetNumCompileUnits() == 1 && "Only dwo files with 1 compile unit is supported"); + return DebugInfo()->GetCompileUnitAtIndex(0); +} + +DWARFCompileUnit* +SymbolFileDWARFDwo::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) +{ + return GetCompileUnit(); +} Index: source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h =================================================================== --- source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h +++ source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h @@ -86,7 +86,7 @@ lldb::TypeSP m_type_sp; SymbolFileDWARF *m_symfile; - const DWARFCompileUnit *m_cu; + DWARFCompileUnit *m_cu; const DWARFDebugInfoEntry *m_die; lldb_private::Declaration m_declaration; int32_t m_byte_size; @@ -118,7 +118,7 @@ bool Find (SymbolFileDWARF *symfile, - const DWARFCompileUnit *cu, + DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die, const lldb_private::Declaration &decl, const int32_t byte_size, @@ -151,7 +151,7 @@ bool Find (const lldb_private::ConstString &name, SymbolFileDWARF *symfile, - const DWARFCompileUnit *cu, + DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die, const lldb_private::Declaration &decl, const int32_t byte_size, Index: source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp +++ source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp @@ -21,7 +21,7 @@ UniqueDWARFASTTypeList::Find ( SymbolFileDWARF *symfile, - const DWARFCompileUnit *cu, + DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die, const lldb_private::Declaration &decl, const int32_t byte_size, Index: source/Symbol/ObjectFile.cpp =================================================================== --- source/Symbol/ObjectFile.cpp +++ source/Symbol/ObjectFile.cpp @@ -602,15 +602,23 @@ } SectionList * -ObjectFile::GetSectionList() +ObjectFile::GetSectionList(bool update_module_section_list) { if (m_sections_ap.get() == nullptr) { - ModuleSP module_sp(GetModule()); - if (module_sp) + if (update_module_section_list) { - lldb_private::Mutex::Locker locker(module_sp->GetMutex()); - CreateSections(*module_sp->GetUnifiedSectionList()); + ModuleSP module_sp(GetModule()); + if (module_sp) + { + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + CreateSections(*module_sp->GetUnifiedSectionList()); + } + } + else + { + SectionList unified_section_list; + CreateSections(unified_section_list); } } return m_sections_ap.get();