aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/SymbolFile
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/SymbolFile')
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp31
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.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/NativePDB/SymbolFileNativePDB.cpp67
-rw-r--r--lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp18
6 files changed, 93 insertions, 39 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 82e9d86..63b2dc4 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -450,6 +450,10 @@ ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const DWARFDIE &die) {
byte_size = form_value.Unsigned();
break;
+ case DW_AT_bit_size:
+ data_bit_size = form_value.Unsigned();
+ break;
+
case DW_AT_alignment:
alignment = form_value.Unsigned();
break;
@@ -810,13 +814,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;
@@ -1901,6 +1910,17 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
m_ast.CreateClassTemplateSpecializationDecl(
containing_decl_ctx, GetOwningClangModule(die), class_template_decl,
tag_decl_kind, template_param_infos);
+ if (!class_specialization_decl) {
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF({0:p}) - Failed to create specialization for "
+ "clang::ClassTemplateDecl({1}, {2:p}).",
+ this, llvm::StringRef(attrs.name), class_template_decl);
+ }
+ return TypeSP();
+ }
+
clang_type =
m_ast.CreateClassTemplateSpecializationType(class_specialization_decl);
@@ -2032,11 +2052,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(
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index da58f4c..f5f7071 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -574,6 +574,7 @@ struct ParsedDWARFTypeAttributes {
lldb_private::plugin::dwarf::DWARFFormValue type;
lldb::LanguageType class_language = lldb::eLanguageTypeUnknown;
std::optional<uint64_t> byte_size;
+ std::optional<uint64_t> data_bit_size;
std::optional<uint64_t> alignment;
size_t calling_convention = llvm::dwarf::DW_CC_normal;
uint32_t bit_stride = 0;
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/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index e76b7a3..aaec160 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -1130,7 +1130,35 @@ void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {
if (!section_list)
return;
- for (auto pid : m_index->publics().getPublicsTable()) {
+ PublicSym32 last_sym;
+ size_t last_sym_idx = 0;
+ lldb::SectionSP section_sp;
+
+ // To estimate the size of a symbol, we use the difference to the next symbol.
+ // If there's no next symbol or the section/segment changed, the symbol will
+ // take the remaining space. The estimate can be too high in case there's
+ // padding between symbols. This similar to the algorithm used by the DIA
+ // SDK.
+ auto finish_last_symbol = [&](const PublicSym32 *next) {
+ if (!section_sp)
+ return;
+ Symbol *last = symtab.SymbolAtIndex(last_sym_idx);
+ if (!last)
+ return;
+
+ if (next && last_sym.Segment == next->Segment) {
+ assert(last_sym.Offset <= next->Offset);
+ last->SetByteSize(next->Offset - last_sym.Offset);
+ } else {
+ // the last symbol was the last in its section
+ assert(section_sp->GetByteSize() >= last_sym.Offset);
+ assert(!next || next->Segment > last_sym.Segment);
+ last->SetByteSize(section_sp->GetByteSize() - last_sym.Offset);
+ }
+ };
+
+ // The address map is sorted by the address of a symbol.
+ for (auto pid : m_index->publics().getAddressMap()) {
PdbGlobalSymId global{pid, true};
CVSymbol sym = m_index->ReadSymbolRecord(global);
auto kind = sym.kind();
@@ -1138,8 +1166,11 @@ void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {
continue;
PublicSym32 pub =
llvm::cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(sym));
+ finish_last_symbol(&pub);
+
+ if (!section_sp || last_sym.Segment != pub.Segment)
+ section_sp = section_list->FindSectionByID(pub.Segment);
- auto section_sp = section_list->FindSectionByID(pub.Segment);
if (!section_sp)
continue;
@@ -1148,20 +1179,24 @@ void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {
(pub.Flags & PublicSymFlags::Code) != PublicSymFlags::None)
type = eSymbolTypeCode;
- symtab.AddSymbol(Symbol(/*symID=*/pid,
- /*name=*/pub.Name,
- /*type=*/type,
- /*external=*/true,
- /*is_debug=*/true,
- /*is_trampoline=*/false,
- /*is_artificial=*/false,
- /*section_sp=*/section_sp,
- /*value=*/pub.Offset,
- /*size=*/0,
- /*size_is_valid=*/false,
- /*contains_linker_annotations=*/false,
- /*flags=*/0));
- }
+ last_sym_idx =
+ symtab.AddSymbol(Symbol(/*symID=*/pid,
+ /*name=*/pub.Name,
+ /*type=*/type,
+ /*external=*/true,
+ /*is_debug=*/true,
+ /*is_trampoline=*/false,
+ /*is_artificial=*/false,
+ /*section_sp=*/section_sp,
+ /*value=*/pub.Offset,
+ /*size=*/0,
+ /*size_is_valid=*/false,
+ /*contains_linker_annotations=*/false,
+ /*flags=*/0));
+ last_sym = pub;
+ }
+
+ finish_last_symbol(nullptr);
}
size_t SymbolFileNativePDB::ParseFunctions(CompileUnit &comp_unit) {
diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index 3b936c0..0ccb1804 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -83,8 +83,8 @@ constexpr OptionEnumValueElement g_pdb_reader_enums[] = {
{
ePDBReaderDefault,
"default",
- "Use DIA PDB reader unless LLDB_USE_NATIVE_PDB_READER environment "
- "variable is set",
+ "Use native PDB reader unless LLDB_USE_NATIVE_PDB_READER environment "
+ "is set to 0",
},
{
ePDBReaderDIA,
@@ -109,16 +109,10 @@ enum {
static const bool g_should_use_native_reader_by_default = [] {
llvm::StringRef env_value = ::getenv("LLDB_USE_NATIVE_PDB_READER");
-#if !LLVM_ENABLE_DIA_SDK || !defined(_WIN32)
- // if the environment value is unset, the native reader is requested
- if (env_value.empty())
- return true;
-#endif
-
- return env_value.equals_insensitive("on") ||
- env_value.equals_insensitive("yes") ||
- env_value.equals_insensitive("1") ||
- env_value.equals_insensitive("true");
+ return !env_value.equals_insensitive("off") &&
+ !env_value.equals_insensitive("no") &&
+ !env_value.equals_insensitive("0") &&
+ !env_value.equals_insensitive("false");
}();
class PluginProperties : public Properties {