llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>>
DebugNamesDWARFIndex::Create(Module &module, DWARFDataExtractor debug_names,
DWARFDataExtractor debug_str,
- DWARFDebugInfo &debug_info) {
+ SymbolFileDWARF &dwarf) {
auto index_up = std::make_unique<DebugNames>(debug_names.GetAsLLVM(),
debug_str.GetAsLLVM());
if (llvm::Error E = index_up->extract())
return std::move(E);
return std::unique_ptr<DebugNamesDWARFIndex>(new DebugNamesDWARFIndex(
- module, std::move(index_up), debug_names, debug_str, debug_info));
+ module, std::move(index_up), debug_names, debug_str, dwarf));
}
llvm::DenseSet<dw_offset_t>
#include "Plugins/SymbolFile/DWARF/DWARFIndex.h"
#include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
#include "Plugins/SymbolFile/DWARF/ManualDWARFIndex.h"
+#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
#include "lldb/Utility/ConstString.h"
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
public:
static llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>>
Create(Module &module, DWARFDataExtractor debug_names,
- DWARFDataExtractor debug_str, DWARFDebugInfo &debug_info);
+ DWARFDataExtractor debug_str, SymbolFileDWARF &dwarf);
void Preload() override { m_fallback.Preload(); }
std::unique_ptr<llvm::DWARFDebugNames> debug_names_up,
DWARFDataExtractor debug_names_data,
DWARFDataExtractor debug_str_data,
- DWARFDebugInfo &debug_info)
- : DWARFIndex(module), m_debug_info(debug_info),
+ SymbolFileDWARF &dwarf)
+ : DWARFIndex(module), m_debug_info(dwarf.DebugInfo()),
m_debug_names_data(debug_names_data), m_debug_str_data(debug_str_data),
m_debug_names_up(std::move(debug_names_up)),
- m_fallback(module, debug_info, GetUnits(*m_debug_names_up)) {}
+ m_fallback(module, dwarf, GetUnits(*m_debug_names_up)) {}
DWARFDebugInfo &m_debug_info;
using namespace lldb;
void ManualDWARFIndex::Index() {
- if (!m_debug_info)
+ if (!m_dwarf)
return;
- DWARFDebugInfo &debug_info = *m_debug_info;
- m_debug_info = nullptr;
+ SymbolFileDWARF &main_dwarf = *m_dwarf;
+ m_dwarf = nullptr;
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "%p", static_cast<void *>(&debug_info));
+ Timer scoped_timer(func_cat, "%p", static_cast<void *>(&main_dwarf));
+
+ DWARFDebugInfo &main_info = main_dwarf.DebugInfo();
+ SymbolFileDWARFDwo *dwp_dwarf = main_dwarf.GetDwpSymbolFile().get();
+ DWARFDebugInfo *dwp_info = dwp_dwarf ? &dwp_dwarf->DebugInfo() : nullptr;
std::vector<DWARFUnit *> units_to_index;
- units_to_index.reserve(debug_info.GetNumUnits());
- for (size_t U = 0; U < debug_info.GetNumUnits(); ++U) {
- DWARFUnit *unit = debug_info.GetUnitAtIndex(U);
+ units_to_index.reserve(main_info.GetNumUnits() +
+ (dwp_info ? dwp_info->GetNumUnits() : 0));
+
+ // Process all units in the main file, as well as any type units in the dwp
+ // file. Type units in dwo files are handled when we reach the dwo file in
+ // IndexUnit.
+ for (size_t U = 0; U < main_info.GetNumUnits(); ++U) {
+ DWARFUnit *unit = main_info.GetUnitAtIndex(U);
if (unit && m_units_to_avoid.count(unit->GetOffset()) == 0)
units_to_index.push_back(unit);
}
+ if (dwp_info && dwp_info->ContainsTypeUnits()) {
+ for (size_t U = 0; U < dwp_info->GetNumUnits(); ++U) {
+ if (auto *tu = llvm::dyn_cast<DWARFTypeUnit>(dwp_info->GetUnitAtIndex(U)))
+ units_to_index.push_back(tu);
+ }
+ }
+
if (units_to_index.empty())
return;
std::vector<llvm::Optional<DWARFUnit::ScopedExtractDIEs>> clear_cu_dies(
units_to_index.size());
auto parser_fn = [&](size_t cu_idx) {
- IndexUnit(*units_to_index[cu_idx], sets[cu_idx]);
+ IndexUnit(*units_to_index[cu_idx], dwp_dwarf, sets[cu_idx]);
};
auto extract_fn = [&units_to_index, &clear_cu_dies](size_t cu_idx) {
[&]() { finalize_fn(&IndexSet::namespaces); });
}
-void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, IndexSet &set) {
- assert(
- !unit.IsDWOUnit() &&
- "DWARFUnit associated with .dwo or .dwp should not be indexed directly");
-
+void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp,
+ IndexSet &set) {
Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS);
if (log) {
IndexUnitImpl(unit, cu_language, set);
if (SymbolFileDWARFDwo *dwo_symbol_file = unit.GetDwoSymbolFile()) {
- DWARFDebugInfo &dwo_info = dwo_symbol_file->DebugInfo();
- for (size_t i = 0; i < dwo_info.GetNumUnits(); ++i)
- IndexUnitImpl(*dwo_info.GetUnitAtIndex(i), cu_language, set);
+ // Type units in a dwp file are indexed separately, so we just need to
+ // process the split unit here. However, if the split unit is in a dwo file,
+ // then we need to process type units here.
+ if (dwo_symbol_file == dwp) {
+ IndexUnitImpl(unit.GetNonSkeletonUnit(), cu_language, set);
+ } else {
+ DWARFDebugInfo &dwo_info = dwo_symbol_file->DebugInfo();
+ for (size_t i = 0; i < dwo_info.GetNumUnits(); ++i)
+ IndexUnitImpl(*dwo_info.GetUnitAtIndex(i), cu_language, set);
+ }
}
}
#include "llvm/ADT/DenseSet.h"
class DWARFDebugInfo;
+class SymbolFileDWARFDwo;
namespace lldb_private {
class ManualDWARFIndex : public DWARFIndex {
public:
- ManualDWARFIndex(Module &module, DWARFDebugInfo &debug_info,
+ ManualDWARFIndex(Module &module, SymbolFileDWARF &dwarf,
llvm::DenseSet<dw_offset_t> units_to_avoid = {})
- : DWARFIndex(module), m_debug_info(&debug_info),
+ : DWARFIndex(module), m_dwarf(&dwarf),
m_units_to_avoid(std::move(units_to_avoid)) {}
void Preload() override { Index(); }
NameToDIE namespaces;
};
void Index();
- void IndexUnit(DWARFUnit &unit, IndexSet &set);
+ void IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp, IndexSet &set);
static void IndexUnitImpl(DWARFUnit &unit,
const lldb::LanguageType cu_language,
IndexSet &set);
- /// Non-null value means we haven't built the index yet.
- DWARFDebugInfo *m_debug_info;
+ /// The DWARF file which we are indexing. Set to nullptr after the index is
+ /// built.
+ SymbolFileDWARF *m_dwarf;
/// Which dwarf units should we skip while building the index.
llvm::DenseSet<dw_offset_t> m_units_to_avoid;
LoadSectionData(eSectionTypeDWARFDebugNames, debug_names);
if (debug_names.GetByteSize() > 0) {
llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> index_or =
- DebugNamesDWARFIndex::Create(
- *GetObjectFile()->GetModule(), debug_names,
- m_context.getOrLoadStrData(), DebugInfo());
+ DebugNamesDWARFIndex::Create(*GetObjectFile()->GetModule(),
+ debug_names,
+ m_context.getOrLoadStrData(), *this);
if (index_or) {
m_index = std::move(*index_or);
return;
}
}
- m_index = std::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(),
- DebugInfo());
+ m_index =
+ std::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(), *this);
}
bool SymbolFileDWARF::SupportedVersion(uint16_t version) {
if (!dwo_name)
return nullptr;
- FindDwpSymbolFile();
- if (m_dwp_symfile)
- return m_dwp_symfile;
+ if (std::shared_ptr<SymbolFileDWARFDwo> dwp_sp = GetDwpSymbolFile())
+ return dwp_sp;
FileSpec dwo_file(dwo_name);
FileSystem::Instance().Resolve(dwo_file);
return m_debug_map_symfile;
}
-void SymbolFileDWARF::FindDwpSymbolFile() {
+const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() {
llvm::call_once(m_dwp_symfile_once_flag, [this]() {
ModuleSpec module_spec;
module_spec.GetFileSpec() = m_objfile_sp->GetFileSpec();
std::make_shared<SymbolFileDWARFDwo>(*this, dwp_obj_file, 0x3fffffff);
}
});
+ return m_dwp_symfile;
}
llvm::Expected<TypeSystem &> SymbolFileDWARF::GetTypeSystem(DWARFUnit &unit) {
lldb_private::DWARFContext &GetDWARFContext() { return m_context; }
+ const std::shared_ptr<SymbolFileDWARFDwo> &GetDwpSymbolFile();
+
lldb_private::FileSpec GetFile(DWARFUnit &unit, size_t file_idx);
static llvm::Expected<lldb_private::TypeSystem &>
# RUN: llvm-mc --filetype=obj --triple x86_64-pc-linux %s -o %t --defsym MAIN=0
# RUN: llvm-mc --filetype=obj --triple x86_64-pc-linux %s -o %t.dwp --defsym DWP=0
# RUN: %lldb %t -o "type lookup ENUM0" -o "target variable A" -b | FileCheck %s
+# RUN: lldb-test symbols %t | FileCheck %s --check-prefix=SYMBOLS
# CHECK-LABEL: type lookup ENUM0
# CHECK-NEXT: enum ENUM0 {
# CHECK: (ENUM0) A = case0
# CHECK: (ENUM1) A = case0
+# Make sure each entity is present in the index only once.
+# SYMBOLS: Globals and statics:
+# SYMBOLS-NEXT: 3fffffff/INFO/00000023 "A"
+# SYMBOLS-NEXT: 3fffffff/INFO/0000005a "A"
+# SYMBOLS-EMPTY:
+
+# SYMBOLS: Types:
+# SYMBOLS-NEXT: 3fffffff/TYPE/00000018 "ENUM0"
+# SYMBOLS-NEXT: 3fffffff/TYPE/0000002d "int"
+# SYMBOLS-NEXT: 3fffffff/TYPE/00000062 "int"
+# SYMBOLS-NEXT: 3fffffff/TYPE/0000004d "ENUM1"
+# SYMBOLS-EMPTY:
+
.ifdef MAIN
.section .debug_abbrev,"",@progbits
.byte 1 # Abbreviation Code