diff options
| author | Pavel Labath <pavel@labath.sk> | 2019-05-24 08:11:12 +0000 |
|---|---|---|
| committer | Pavel Labath <pavel@labath.sk> | 2019-05-24 08:11:12 +0000 |
| commit | f750842c8b35c56b58402c1842869a885bfcff56 (patch) | |
| tree | 29fa54e798c5f45c1b4cb364f5e766407c52c52e /lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp | |
| parent | 8ac0bc9832a251837681b3a1cd53085ed8d594dc (diff) | |
DWARF: Implement DW_AT_signature lookup for type unit support
Summary:
This patch implements the main feature of type units. When completing a
type, if we encounter a DW_AT_signature attribute, we use it's value to
lookup the complete definition of the type in the relevant type unit.
To enable this lookup, we build up a map of all type units in a symbol
file when parsing the units. Then we consult this map when resolving the
DW_AT_signature attribute.
I include add a couple of tests which exercise the type lookup feature,
including one that ensure we do something reasonable in case we fail to
lookup the type.
A lot of the ideas in this patch have been taken from D32167 and D61505.
Reviewers: clayborg, JDevlieghere, aprantl, alexshap
Subscribers: mgrang, lldb-commits
Differential Revision: https://reviews.llvm.org/D62246
llvm-svn: 361603
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp')
| -rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp index c81b6ce05f0f..0810afc8b1a1 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -15,6 +15,7 @@ #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Stream.h" +#include "llvm/Support/Casting.h" #include "DWARFCompileUnit.h" #include "DWARFContext.h" @@ -74,12 +75,14 @@ llvm::Expected<DWARFDebugAranges &> DWARFDebugInfo::GetCompileUnitAranges() { return *m_cu_aranges_up; } -void Parse(SymbolFileDWARF *dwarf, const DWARFDataExtractor &data, - DIERef::Section section, std::vector<DWARFUnitSP> &units) { +void DWARFDebugInfo::ParseUnitsFor(DIERef::Section section) { + DWARFDataExtractor data = section == DIERef::Section::DebugTypes + ? m_context.getOrLoadDebugTypesData() + : m_context.getOrLoadDebugInfoData(); lldb::offset_t offset = 0; while (data.ValidOffset(offset)) { - llvm::Expected<DWARFUnitSP> unit_sp = - DWARFUnit::extract(dwarf, units.size(), data, section, &offset); + llvm::Expected<DWARFUnitSP> unit_sp = DWARFUnit::extract( + m_dwarf2Data, m_units.size(), data, section, &offset); if (!unit_sp) { // FIXME: Propagate this error up. @@ -89,10 +92,13 @@ void Parse(SymbolFileDWARF *dwarf, const DWARFDataExtractor &data, // If it didn't return an error, then it should be returning a valid Unit. assert(*unit_sp); - - units.push_back(*unit_sp); - + m_units.push_back(*unit_sp); offset = (*unit_sp)->GetNextUnitOffset(); + + if (auto *type_unit = llvm::dyn_cast<DWARFTypeUnit>(unit_sp->get())) { + m_type_hash_to_unit_index.emplace_back(type_unit->GetTypeHash(), + unit_sp.get()->GetID()); + } } } @@ -102,10 +108,9 @@ void DWARFDebugInfo::ParseUnitHeadersIfNeeded() { if (!m_dwarf2Data) return; - Parse(m_dwarf2Data, m_context.getOrLoadDebugInfoData(), - DIERef::Section::DebugInfo, m_units); - Parse(m_dwarf2Data, m_context.getOrLoadDebugTypesData(), - DIERef::Section::DebugTypes, m_units); + ParseUnitsFor(DIERef::Section::DebugInfo); + ParseUnitsFor(DIERef::Section::DebugTypes); + llvm::sort(m_type_hash_to_unit_index, llvm::less_first()); } size_t DWARFDebugInfo::GetNumUnits() { @@ -169,6 +174,14 @@ DWARFDebugInfo::GetUnitContainingDIEOffset(DIERef::Section section, return result; } +DWARFTypeUnit *DWARFDebugInfo::GetTypeUnitForHash(uint64_t hash) { + auto pos = llvm::lower_bound(m_type_hash_to_unit_index, + std::make_pair(hash, 0u), llvm::less_first()); + if (pos == m_type_hash_to_unit_index.end() || pos->first != hash) + return nullptr; + return llvm::cast<DWARFTypeUnit>(GetUnitAtIndex(pos->second)); +} + DWARFDIE DWARFDebugInfo::GetDIEForDIEOffset(DIERef::Section section, dw_offset_t die_offset) { |
