diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp')
| -rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp | 127 |
1 files changed, 71 insertions, 56 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index 749ffcb094ec..6f771c66a725 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -13,6 +13,7 @@ #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h" #include "llvm/Object/Error.h" @@ -27,12 +28,13 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::dwarf; +using namespace lldb_private::plugin::dwarf; extern int g_verbose; DWARFUnit::DWARFUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid, const DWARFUnitHeader &header, - const DWARFAbbreviationDeclarationSet &abbrevs, + const llvm::DWARFAbbreviationDeclarationSet &abbrevs, DIERef::Section section, bool is_dwo) : UserID(uid), m_dwarf(dwarf), m_header(header), m_abbrevs(&abbrevs), m_cancel_scopes(false), m_section(section), m_is_dwo(is_dwo), @@ -200,8 +202,8 @@ DWARFUnit::ScopedExtractDIEs::ScopedExtractDIEs(ScopedExtractDIEs &&rhs) rhs.m_cu = nullptr; } -DWARFUnit::ScopedExtractDIEs &DWARFUnit::ScopedExtractDIEs::operator=( - DWARFUnit::ScopedExtractDIEs &&rhs) { +DWARFUnit::ScopedExtractDIEs & +DWARFUnit::ScopedExtractDIEs::operator=(DWARFUnit::ScopedExtractDIEs &&rhs) { m_cu = rhs.m_cu; rhs.m_cu = nullptr; m_clear_dies = rhs.m_clear_dies; @@ -310,9 +312,9 @@ void DWARFUnit::ExtractDIEsRWLocked() { } if (!m_die_array.empty()) { - // The last die cannot have children (if it did, it wouldn't be the last one). - // This only makes a difference for malformed dwarf that does not have a - // terminating null die. + // The last die cannot have children (if it did, it wouldn't be the last + // one). This only makes a difference for malformed dwarf that does not have + // a terminating null die. m_die_array.back().SetHasChildren(false); if (m_first_die) { @@ -435,7 +437,8 @@ size_t DWARFUnit::GetDebugInfoSize() const { return GetLengthByteSize() + GetLength() - GetHeaderByteSize(); } -const DWARFAbbreviationDeclarationSet *DWARFUnit::GetAbbreviations() const { +const llvm::DWARFAbbreviationDeclarationSet * +DWARFUnit::GetAbbreviations() const { return m_abbrevs; } @@ -718,7 +721,7 @@ void DWARFUnit::ParseProducerInfo() { llvm::SmallVector<llvm::StringRef, 3> matches; if (g_swiftlang_version_regex.Execute(producer, &matches)) { - m_producer_version.tryParse(matches[1]); + m_producer_version.tryParse(matches[1]); m_producer = eProducerSwift; } else if (producer.contains("clang")) { if (g_clang_version_regex.Execute(producer, &matches)) @@ -875,10 +878,37 @@ const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() { return *m_func_aranges_up; } +llvm::Error DWARFUnitHeader::ApplyIndexEntry( + const llvm::DWARFUnitIndex::Entry *index_entry) { + // We should only be calling this function when the index entry is not set and + // we have a valid one to set it to. + assert(index_entry); + assert(!m_index_entry); + + if (m_abbr_offset) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Package unit with a non-zero abbreviation offset"); + + auto *unit_contrib = index_entry->getContribution(); + if (!unit_contrib || unit_contrib->getLength32() != m_length + 4) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Inconsistent DWARF package unit index"); + + auto *abbr_entry = index_entry->getContribution(llvm::DW_SECT_ABBREV); + if (!abbr_entry) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "DWARF package index missing abbreviation column"); + + m_abbr_offset = abbr_entry->getOffset(); + m_index_entry = index_entry; + return llvm::Error::success(); +} + llvm::Expected<DWARFUnitHeader> DWARFUnitHeader::extract(const DWARFDataExtractor &data, - DIERef::Section section, - lldb_private::DWARFContext &context, + DIERef::Section section, DWARFContext &context, lldb::offset_t *offset_ptr) { DWARFUnitHeader header; header.m_offset = *offset_ptr; @@ -903,42 +933,6 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data, header.m_type_offset = data.GetDWARFOffset(offset_ptr); } - if (context.isDwo()) { - const llvm::DWARFUnitIndex *Index; - if (header.IsTypeUnit()) { - Index = &context.GetAsLLVM().getTUIndex(); - if (*Index) - header.m_index_entry = Index->getFromHash(header.m_type_hash); - } else { - Index = &context.GetAsLLVM().getCUIndex(); - if (*Index && header.m_version >= 5 && header.m_dwo_id) - header.m_index_entry = Index->getFromHash(*header.m_dwo_id); - } - if (!header.m_index_entry) - header.m_index_entry = Index->getFromOffset(header.m_offset); - } - - if (header.m_index_entry) { - if (header.m_abbr_offset) { - return llvm::createStringError( - llvm::inconvertibleErrorCode(), - "Package unit with a non-zero abbreviation offset"); - } - auto *unit_contrib = header.m_index_entry->getContribution(); - if (!unit_contrib || unit_contrib->getLength32() != header.m_length + 4) { - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "Inconsistent DWARF package unit index"); - } - auto *abbr_entry = - header.m_index_entry->getContribution(llvm::DW_SECT_ABBREV); - if (!abbr_entry) { - return llvm::createStringError( - llvm::inconvertibleErrorCode(), - "DWARF package index missing abbreviation column"); - } - header.m_abbr_offset = abbr_entry->getOffset(); - } - bool length_OK = data.ValidOffset(header.GetNextUnitOffset() - 1); bool version_OK = SymbolFileDWARF::SupportedVersion(header.m_version); bool addr_size_OK = (header.m_addr_size == 2) || (header.m_addr_size == 4) || @@ -968,12 +962,31 @@ DWARFUnit::extract(SymbolFileDWARF &dwarf, user_id_t uid, DIERef::Section section, lldb::offset_t *offset_ptr) { assert(debug_info.ValidOffset(*offset_ptr)); - auto expected_header = DWARFUnitHeader::extract( - debug_info, section, dwarf.GetDWARFContext(), offset_ptr); + DWARFContext &context = dwarf.GetDWARFContext(); + auto expected_header = + DWARFUnitHeader::extract(debug_info, section, context, offset_ptr); if (!expected_header) return expected_header.takeError(); - const DWARFDebugAbbrev *abbr = dwarf.DebugAbbrev(); + if (context.isDwo()) { + const llvm::DWARFUnitIndex::Entry *entry = nullptr; + const llvm::DWARFUnitIndex &index = expected_header->IsTypeUnit() + ? context.GetAsLLVM().getTUIndex() + : context.GetAsLLVM().getCUIndex(); + if (index) { + if (expected_header->IsTypeUnit()) + entry = index.getFromHash(expected_header->GetTypeHash()); + else if (auto dwo_id = expected_header->GetDWOId()) + entry = index.getFromHash(*dwo_id); + } + if (!entry) + entry = index.getFromOffset(expected_header->GetOffset()); + if (entry) + if (llvm::Error err = expected_header->ApplyIndexEntry(entry)) + return std::move(err); + } + + const llvm::DWARFDebugAbbrev *abbr = dwarf.DebugAbbrev(); if (!abbr) return llvm::make_error<llvm::object::GenericBinaryError>( "No debug_abbrev data"); @@ -985,8 +998,12 @@ DWARFUnit::extract(SymbolFileDWARF &dwarf, user_id_t uid, return llvm::make_error<llvm::object::GenericBinaryError>( "Abbreviation offset for unit is not valid"); - const DWARFAbbreviationDeclarationSet *abbrevs = - abbr->GetAbbreviationDeclarationSet(expected_header->GetAbbrOffset()); + llvm::Expected<const llvm::DWARFAbbreviationDeclarationSet *> abbrevs_or_err = + abbr->getAbbreviationDeclarationSet(expected_header->GetAbbrOffset()); + if (!abbrevs_or_err) + return abbrevs_or_err.takeError(); + + const llvm::DWARFAbbreviationDeclarationSet *abbrevs = *abbrevs_or_err; if (!abbrevs) return llvm::make_error<llvm::object::GenericBinaryError>( "No abbrev exists at the specified offset."); @@ -1071,22 +1088,20 @@ DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) { return ranges; } -llvm::Expected<DWARFRangeList> -DWARFUnit::FindRnglistFromIndex(uint32_t index) { +llvm::Expected<DWARFRangeList> DWARFUnit::FindRnglistFromIndex(uint32_t index) { llvm::Expected<uint64_t> maybe_offset = GetRnglistOffset(index); if (!maybe_offset) return maybe_offset.takeError(); return FindRnglistFromOffset(*maybe_offset); } - bool DWARFUnit::HasAny(llvm::ArrayRef<dw_tag_t> tags) { ExtractUnitDIEIfNeeded(); if (m_dwo) return m_dwo->HasAny(tags); - for (const auto &die: m_die_array) { - for (const auto tag: tags) { + for (const auto &die : m_die_array) { + for (const auto tag : tags) { if (tag == die.Tag()) return true; } |
