aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/SymbolFile/DWARF
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF')
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp37
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h9
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp8
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h5
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp35
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h1
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp7
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h8
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp29
9 files changed, 90 insertions, 49 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index c049829..d65aa40 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -623,6 +623,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
switch (tag) {
case DW_TAG_typedef:
+ case DW_TAG_template_alias:
case DW_TAG_base_type:
case DW_TAG_pointer_type:
case DW_TAG_reference_type:
@@ -748,7 +749,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
TypeSP type_sp;
CompilerType clang_type;
- if (tag == DW_TAG_typedef) {
+ if (tag == DW_TAG_typedef || tag == DW_TAG_template_alias) {
// DeclContext will be populated when the clang type is materialized in
// Type::ResolveCompilerType.
PrepareContextToReceiveMembers(
@@ -814,13 +815,18 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
// there...
[[fallthrough]];
- case DW_TAG_base_type:
+ case DW_TAG_base_type: {
resolve_state = Type::ResolveState::Full;
+ // If a builtin type's size isn't a multiple of a byte, DWARF producers may
+ // add a precise bit-size to the type. Use the most precise bit-size
+ // possible.
+ const uint64_t bit_size = attrs.data_bit_size
+ ? *attrs.data_bit_size
+ : attrs.byte_size.value_or(0) * 8;
clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(
- attrs.name.GetStringRef(), attrs.encoding,
- attrs.byte_size.value_or(0) * 8);
+ attrs.name.GetStringRef(), attrs.encoding, bit_size);
break;
-
+ }
case DW_TAG_pointer_type:
encoding_data_type = Type::eEncodingIsPointerUID;
break;
@@ -831,6 +837,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
encoding_data_type = Type::eEncodingIsRValueReferenceUID;
break;
case DW_TAG_typedef:
+ case DW_TAG_template_alias:
encoding_data_type = Type::eEncodingIsTypedefUID;
break;
case DW_TAG_const_type:
@@ -1700,8 +1707,11 @@ void DWARFASTParserClang::GetUniqueTypeNameAndDeclaration(
// For C++, we rely solely upon the one definition rule that says
// only one thing can exist at a given decl context. We ignore the
// file and line that things are declared on.
- if (!die.IsValid() || !Language::LanguageIsCPlusPlus(language) ||
- unique_typename.IsEmpty())
+ // FIXME: Rust pretends to be C++ for now, so use C++ name qualification rules
+ if (!Language::LanguageIsCPlusPlus(language) &&
+ language != lldb::eLanguageTypeRust)
+ return;
+ if (!die.IsValid() || unique_typename.IsEmpty())
return;
decl_declaration.Clear();
std::string qualified_name;
@@ -2047,11 +2057,10 @@ static std::optional<clang::APValue> MakeAPValue(const clang::ASTContext &ast,
if (is_integral)
return clang::APValue(apint);
- uint32_t count;
bool is_complex;
// FIXME: we currently support a limited set of floating point types.
// E.g., 16-bit floats are not supported.
- if (!clang_type.IsFloatingPointType(count, is_complex))
+ if (!clang_type.IsFloatingPointType(is_complex))
return std::nullopt;
return clang::APValue(llvm::APFloat(
@@ -3700,12 +3709,10 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
}
}
- DWARFASTParserClang *src_dwarf_ast_parser =
- static_cast<DWARFASTParserClang *>(
- SymbolFileDWARF::GetDWARFParser(*src_class_die.GetCU()));
- DWARFASTParserClang *dst_dwarf_ast_parser =
- static_cast<DWARFASTParserClang *>(
- SymbolFileDWARF::GetDWARFParser(*dst_class_die.GetCU()));
+ auto *src_dwarf_ast_parser = llvm::cast<DWARFASTParserClang>(
+ SymbolFileDWARF::GetDWARFParser(*src_class_die.GetCU()));
+ auto *dst_dwarf_ast_parser = llvm::cast<DWARFASTParserClang>(
+ SymbolFileDWARF::GetDWARFParser(*dst_class_die.GetCU()));
auto link = [&](DWARFDIE src, DWARFDIE dst) {
auto &die_to_type = dst_class_die.GetDWARF()->GetDIEToType();
clang::DeclContext *dst_decl_ctx =
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index f5f7071..6eb2b6b 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -47,6 +47,11 @@ public:
~DWARFASTParserClang() override;
+ // LLVM RTTI support
+ static bool classof(const DWARFASTParser *Parser) {
+ return Parser->GetKind() == Kind::DWARFASTParserClang;
+ }
+
// DWARFASTParser interface.
lldb::TypeSP
ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
@@ -264,10 +269,6 @@ protected:
lldb::ModuleSP
GetModuleForType(const lldb_private::plugin::dwarf::DWARFDIE &die);
- static bool classof(const DWARFASTParser *Parser) {
- return Parser->GetKind() == Kind::DWARFASTParserClang;
- }
-
private:
struct FieldInfo {
/// Size in bits that this field occupies. Can but
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
index 64a8005..c4efc06 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
@@ -173,6 +173,14 @@ void DWARFIndex::GetNamespacesWithParents(
});
}
+void DWARFIndex::GetFunctions(
+ const std::vector<Module::LookupInfo> &lookup_infos, SymbolFileDWARF &dwarf,
+ const CompilerDeclContext &parent_decl_ctx,
+ llvm::function_ref<IterationAction(DWARFDIE die)> callback) {
+ for (auto &lookup_info : lookup_infos)
+ GetFunctions(lookup_info, dwarf, parent_decl_ctx, callback);
+}
+
IterationAction DWARFIndex::ProcessNamespaceDieMatchParents(
const CompilerDeclContext &parent_decl_ctx, DWARFDIE die,
llvm::function_ref<IterationAction(DWARFDIE die)> callback) {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
index be73255..eaf1da1 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
@@ -86,6 +86,11 @@ public:
const CompilerDeclContext &parent_decl_ctx,
llvm::function_ref<IterationAction(DWARFDIE die)> callback) = 0;
virtual void
+ GetFunctions(const std::vector<Module::LookupInfo> &lookup_infos,
+ SymbolFileDWARF &dwarf,
+ const CompilerDeclContext &parent_decl_ctx,
+ llvm::function_ref<IterationAction(DWARFDIE die)> callback);
+ virtual void
GetFunctions(const RegularExpression &regex,
llvm::function_ref<IterationAction(DWARFDIE die)> callback) = 0;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index 94fc2e83..b78e6ce8 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -348,6 +348,10 @@ void DWARFUnit::ExtractDIEsRWLocked() {
void DWARFUnit::SetDwoStrOffsetsBase() {
lldb::offset_t baseOffset = 0;
+ // Size of offset for .debug_str_offsets is same as DWARF offset byte size
+ // of the DWARFUnit as a default. We might override this if below if needed.
+ m_str_offset_size = m_header.getDwarfOffsetByteSize();
+
if (const llvm::DWARFUnitIndex::Entry *entry = m_header.getIndexEntry()) {
if (const auto *contribution =
entry->getContribution(llvm::DW_SECT_STR_OFFSETS))
@@ -357,14 +361,17 @@ void DWARFUnit::SetDwoStrOffsetsBase() {
}
if (GetVersion() >= 5) {
- const DWARFDataExtractor &strOffsets =
- GetSymbolFileDWARF().GetDWARFContext().getOrLoadStrOffsetsData();
- uint64_t length = strOffsets.GetU32(&baseOffset);
- if (length == 0xffffffff)
- length = strOffsets.GetU64(&baseOffset);
-
+ const llvm::DWARFDataExtractor &strOffsets = GetSymbolFileDWARF()
+ .GetDWARFContext()
+ .getOrLoadStrOffsetsData()
+ .GetAsLLVMDWARF();
+
+ uint64_t length;
+ llvm::dwarf::DwarfFormat format;
+ std::tie(length, format) = strOffsets.getInitialLength(&baseOffset);
+ m_str_offset_size = format == llvm::dwarf::DwarfFormat::DWARF64 ? 8 : 4;
// Check version.
- if (strOffsets.GetU16(&baseOffset) < 5)
+ if (strOffsets.getU16(&baseOffset) < 5)
return;
// Skip padding.
@@ -409,7 +416,16 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
SetRangesBase(form_value.Unsigned());
break;
case DW_AT_str_offsets_base:
+ // When we have a DW_AT_str_offsets_base attribute, it points us to the
+ // first string offset for this DWARFUnit which is after the string
+ // offsets table header. In this case we use the DWARF32/DWARF64 of the
+ // DWARFUnit to determine the string offset byte size. DWO files do not
+ // use this attribute and they point to the start of the string offsets
+ // table header which can be used to determine the DWARF32/DWARF64 status
+ // of the string table. See SetDwoStrOffsetsBase() for now it figures out
+ // the m_str_offset_size value that should be used.
SetStrOffsetsBase(form_value.Unsigned());
+ m_str_offset_size = m_header.getDwarfOffsetByteSize();
break;
case DW_AT_low_pc:
SetBaseAddress(form_value.Address());
@@ -1079,10 +1095,9 @@ uint32_t DWARFUnit::GetHeaderByteSize() const { return m_header.getSize(); }
std::optional<uint64_t>
DWARFUnit::GetStringOffsetSectionItem(uint32_t index) const {
- lldb::offset_t offset =
- GetStrOffsetsBase() + index * m_header.getDwarfOffsetByteSize();
+ lldb::offset_t offset = GetStrOffsetsBase() + index * m_str_offset_size;
return m_dwarf.GetDWARFContext().getOrLoadStrOffsetsData().GetMaxU64(
- &offset, m_header.getDwarfOffsetByteSize());
+ &offset, m_str_offset_size);
}
llvm::Expected<llvm::DWARFAddressRangesVector>
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index 91a6938..b5199a8 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -364,6 +364,7 @@ protected:
dw_offset_t m_line_table_offset = DW_INVALID_OFFSET;
dw_offset_t m_str_offsets_base = 0; // Value of DW_AT_str_offsets_base.
+ dw_offset_t m_str_offset_size = 4; // Size in bytes of a string offset.
std::optional<llvm::DWARFDebugRnglistTable> m_rnglist_table;
bool m_rnglist_table_done = false;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
index d90108f..36dee14 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
@@ -22,7 +22,6 @@
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/Timer.h"
#include "lldb/lldb-private-enumerations.h"
-#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/ThreadPool.h"
#include <atomic>
#include <optional>
@@ -33,10 +32,10 @@ using namespace lldb_private::plugin::dwarf;
using namespace llvm::dwarf;
void ManualDWARFIndex::Index() {
- if (m_indexed)
- return;
- m_indexed = true;
+ std::call_once(m_indexed_flag, [this]() { IndexImpl(); });
+}
+void ManualDWARFIndex::IndexImpl() {
ElapsedTime elapsed(m_index_time);
LLDB_SCOPED_TIMERF("%p", static_cast<void *>(m_dwarf));
if (LoadFromCache()) {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
index 0b5b2f3..41e0e62 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
@@ -66,8 +66,14 @@ public:
void Dump(Stream &s) override;
private:
+ /// Reads the DWARF debug info to build the index once.
+ ///
+ /// Should be called before attempting to retrieve symbols.
void Index();
+ /// Call `ManualDWARFIndex::Index()` instead.
+ void IndexImpl();
+
/// Decode a serialized version of this object from data.
///
/// \param data
@@ -170,7 +176,7 @@ private:
llvm::DenseSet<uint64_t> m_type_sigs_to_avoid;
IndexSet<NameToDIE> m_set;
- bool m_indexed = false;
+ std::once_flag m_indexed_flag;
};
} // namespace dwarf
} // namespace lldb_private::plugin
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 881268b..b755f3a 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -794,12 +794,12 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
} else {
ModuleSP module_sp(m_objfile_sp->GetModule());
if (module_sp) {
- auto initialize_cu = [&](lldb::SupportFileSP support_file_sp,
+ auto initialize_cu = [&](SupportFileNSP support_file_nsp,
LanguageType cu_language,
SupportFileList &&support_files = {}) {
BuildCuTranslationTable();
cu_sp = std::make_shared<CompileUnit>(
- module_sp, &dwarf_cu, support_file_sp,
+ module_sp, &dwarf_cu, support_file_nsp,
*GetDWARFUnitIndex(dwarf_cu.GetID()), cu_language,
eLazyBoolCalculate, std::move(support_files));
@@ -1560,8 +1560,8 @@ bool SymbolFileDWARF::HasForwardDeclForCompilerType(
auto clang_type_system = compiler_type.GetTypeSystem<TypeSystemClang>();
if (!clang_type_system)
return false;
- DWARFASTParserClang *ast_parser =
- static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
+ auto *ast_parser =
+ llvm::cast<DWARFASTParserClang>(clang_type_system->GetDWARFParser());
return ast_parser->GetClangASTImporter().CanImport(compiler_type);
}
@@ -1569,8 +1569,8 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
auto clang_type_system = compiler_type.GetTypeSystem<TypeSystemClang>();
if (clang_type_system) {
- DWARFASTParserClang *ast_parser =
- static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
+ auto *ast_parser =
+ llvm::cast<DWARFASTParserClang>(clang_type_system->GetDWARFParser());
if (ast_parser &&
ast_parser->GetClangASTImporter().CanImport(compiler_type))
return ast_parser->GetClangASTImporter().CompleteType(compiler_type);
@@ -1614,8 +1614,7 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) {
if (decl_die != def_die) {
GetDIEToType()[def_die.GetDIE()] = type;
- DWARFASTParserClang *ast_parser =
- static_cast<DWARFASTParserClang *>(dwarf_ast);
+ auto *ast_parser = llvm::cast<DWARFASTParserClang>(dwarf_ast);
ast_parser->MapDeclDIEToDefDIE(decl_die, def_die);
}
@@ -2018,7 +2017,7 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
}
Status error = ModuleList::GetSharedModule(dwo_module_spec, module_sp,
- nullptr, nullptr, nullptr);
+ nullptr, nullptr);
if (!module_sp) {
// ReportWarning also rate-limits based on the warning string,
// but in a -gmodules build, each object file has a similar DAG
@@ -2341,7 +2340,7 @@ void SymbolFileDWARF::FindGlobalVariables(
bool name_is_mangled = Mangled::GetManglingScheme(name.GetStringRef()) !=
Mangled::eManglingSchemeNone;
- if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name.GetCString(),
+ if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name.GetStringRef(),
context, basename))
basename = name.GetStringRef();
@@ -2482,7 +2481,7 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die,
sc.block = function_block.FindBlockByID(inlined_die.GetOffset());
}
- sc_list.Append(sc);
+ sc_list.AppendIfUnique(sc, /*merge_symbol_into_function=*/true);
return true;
}
@@ -2550,11 +2549,11 @@ SymbolFileDWARF::FindFunctionDefinition(const FunctionCallLabel &label,
const DWARFDIE &declaration) {
auto do_lookup = [this](llvm::StringRef lookup_name) -> DWARFDIE {
DWARFDIE found;
- Module::LookupInfo info(ConstString(lookup_name),
- lldb::eFunctionNameTypeFull,
- lldb::eLanguageTypeUnknown);
+ auto lookup_infos = Module::LookupInfo::MakeLookupInfos(
+ ConstString(lookup_name), lldb::eFunctionNameTypeFull,
+ lldb::eLanguageTypeUnknown);
- m_index->GetFunctions(info, *this, {}, [&](DWARFDIE entry) {
+ m_index->GetFunctions(lookup_infos, *this, {}, [&](DWARFDIE entry) {
if (entry.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_declaration, 0))
return IterationAction::Continue;