From eb0c5c8776498f8644bf55cf35e1d86d2b44e428 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Tue, 29 Mar 2016 13:42:02 +0000 Subject: [PATCH] Fix infinite recursion in DWO file parsing Summary: Since r264316, clang started adding DW_AT_GNU_dwo_name attribute to dwo files (previously, this attribute was only present in main object files), breaking pretty much every dwo test. The problem was that we were treating the presence of said attribute as a signal that we should look for information in an external object file, and caused us to enter an infinite loop. I fix this by making sure we do not go looking for an external dwo file if we already *are* parsing a dwo file. Reviewers: tberghammer, clayborg Subscribers: lldb-commits Differential Revision: http://reviews.llvm.org/D18547 llvm-svn: 264729 --- .../Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp | 40 ++-------------------- .../Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 32 +++++++++++++++++ .../Plugins/SymbolFile/DWARF/SymbolFileDWARF.h | 4 +++ .../Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h | 6 ++++ 4 files changed, 45 insertions(+), 37 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp index f8a1043..51dcb7c 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -311,46 +311,12 @@ 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) + const DWARFDebugInfoEntry &cu_die = m_die_array.front(); + std::unique_ptr dwo_symbol_file = m_dwarf2Data->GetDwoSymbolFileForCompileUnit(*this, cu_die); + if (!dwo_symbol_file) return; - FileSpec dwo_file(dwo_name, true); - if (dwo_file.IsRelative()) - { - const char* comp_dir = cu_die.GetAttributeValueAsString(m_dwarf2Data, - this, - DW_AT_comp_dir, - nullptr); - if (!comp_dir) - return; - - dwo_file.SetFile(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, this)); - DWARFCompileUnit* dwo_cu = dwo_symbol_file->GetCompileUnit(); if (!dwo_cu) return; // Can't fetch the compile unit from the dwo file. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 66e3e72..e161c08 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1763,6 +1763,38 @@ SymbolFileDWARF::GetDWOModule (ConstString name) return lldb::ModuleSP(); } +std::unique_ptr +SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die) +{ + const char *dwo_name = cu_die.GetAttributeValueAsString(this, &dwarf_cu, DW_AT_GNU_dwo_name, nullptr); + if (!dwo_name) + return nullptr; + + FileSpec dwo_file(dwo_name, true); + if (dwo_file.IsRelative()) + { + const char *comp_dir = cu_die.GetAttributeValueAsString(this, &dwarf_cu, DW_AT_comp_dir, nullptr); + if (!comp_dir) + return nullptr; + + dwo_file.SetFile(comp_dir, true); + dwo_file.AppendPathComponent(dwo_name); + } + + if (!dwo_file.Exists()) + return nullptr; + + const lldb::offset_t file_offset = 0; + DataBufferSP dwo_file_data_sp; + lldb::offset_t dwo_file_data_offset = 0; + ObjectFileSP dwo_obj_file = ObjectFile::FindPlugin(GetObjectFile()->GetModule(), &dwo_file, file_offset, + dwo_file.GetByteSize(), dwo_file_data_sp, dwo_file_data_offset); + if (dwo_obj_file == nullptr) + return nullptr; + + return llvm::make_unique(dwo_obj_file, &dwarf_cu); +} + void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 2742d45..fa7f12d 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -58,6 +58,7 @@ class DWARFDeclContext; class DWARFDIECollection; class DWARFFormValue; class SymbolFileDWARFDebugMap; +class SymbolFileDWARFDwo; #define DIE_IS_BEING_PARSED ((lldb_private::Type*)1) @@ -329,6 +330,9 @@ public: lldb::ModuleSP GetDWOModule (lldb_private::ConstString name); + virtual std::unique_ptr + GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die); + protected: typedef llvm::DenseMap DIEToTypePtr; typedef llvm::DenseMap DIEToVariableSP; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h index 39ed650..81cbd58 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h @@ -38,6 +38,12 @@ public: lldb_private::TypeSystem* GetTypeSystemForLanguage(lldb::LanguageType language) override; + std::unique_ptr + GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die) override + { + return nullptr; + } + protected: void LoadSectionData (lldb::SectionType sect_type, lldb_private::DWARFDataExtractor& data) override; -- 2.7.4