summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
diff options
context:
space:
mode:
authorPavel Labath <pavel@labath.sk>2019-05-24 08:11:12 +0000
committerPavel Labath <pavel@labath.sk>2019-05-24 08:11:12 +0000
commitf750842c8b35c56b58402c1842869a885bfcff56 (patch)
tree29fa54e798c5f45c1b4cb364f5e766407c52c52e /lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
parent8ac0bc9832a251837681b3a1cd53085ed8d594dc (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.cpp35
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) {