summaryrefslogtreecommitdiff
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.cpp37
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp19
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp31
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp156
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h20
5 files changed, 197 insertions, 66 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index f1e73d73a733..82e9d867c3ac 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -3126,43 +3126,6 @@ void DWARFASTParserClang::ParseSingleMember(
if (!member_clang_type.IsCompleteType())
member_clang_type.GetCompleteType();
- {
- // Older versions of clang emit the same DWARF for array[0] and array[1]. If
- // the current field is at the end of the structure, then there is
- // definitely no room for extra elements and we override the type to
- // array[0]. This was fixed by f454dfb6b5af.
- CompilerType member_array_element_type;
- uint64_t member_array_size;
- bool member_array_is_incomplete;
-
- if (member_clang_type.IsArrayType(&member_array_element_type,
- &member_array_size,
- &member_array_is_incomplete) &&
- !member_array_is_incomplete) {
- uint64_t parent_byte_size =
- parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX);
-
- // If the attrs.member_byte_offset is still set to UINT32_MAX this means
- // that the DW_TAG_member didn't have a DW_AT_data_member_location, so
- // don't emit an error if this is the case.
- if (attrs.member_byte_offset != UINT32_MAX &&
- attrs.member_byte_offset >= parent_byte_size) {
- if (member_array_size != 1 &&
- (member_array_size != 0 ||
- attrs.member_byte_offset > parent_byte_size)) {
- module_sp->ReportError(
- "{0:x8}: DW_TAG_member '{1}' refers to type {2:x16}"
- " which extends beyond the bounds of {3:x8}",
- die.GetID(), attrs.name,
- attrs.encoding_form.Reference().GetOffset(), parent_die.GetID());
- }
-
- member_clang_type =
- m_ast.CreateArrayType(member_array_element_type, 0, false);
- }
- }
- }
-
TypeSystemClang::RequireCompleteType(member_clang_type);
clang::FieldDecl *field_decl = TypeSystemClang::AddFieldToRecordType(
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index 51bdcc92b05a..e7fddf08967f 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -38,16 +38,18 @@ struct CreateMethodDecl : public TypeVisitorCallbacks {
TypeIndex func_type_index,
clang::FunctionDecl *&function_decl,
lldb::opaque_compiler_type_t parent_ty,
- llvm::StringRef proc_name, CompilerType func_ct)
+ llvm::StringRef proc_name, ConstString mangled_name,
+ CompilerType func_ct)
: m_index(m_index), m_clang(m_clang), func_type_index(func_type_index),
function_decl(function_decl), parent_ty(parent_ty),
- proc_name(proc_name), func_ct(func_ct) {}
+ proc_name(proc_name), mangled_name(mangled_name), func_ct(func_ct) {}
PdbIndex &m_index;
TypeSystemClang &m_clang;
TypeIndex func_type_index;
clang::FunctionDecl *&function_decl;
lldb::opaque_compiler_type_t parent_ty;
llvm::StringRef proc_name;
+ ConstString mangled_name;
CompilerType func_ct;
llvm::Error visitKnownMember(CVMemberRecord &cvr,
@@ -87,8 +89,7 @@ struct CreateMethodDecl : public TypeVisitorCallbacks {
bool is_artificial = (options & MethodOptions::CompilerGenerated) ==
MethodOptions::CompilerGenerated;
function_decl = m_clang.AddMethodToCXXRecordType(
- parent_ty, proc_name,
- /*asm_label=*/{}, func_ct, /*access=*/access_type,
+ parent_ty, proc_name, mangled_name, func_ct, /*access=*/access_type,
/*is_virtual=*/is_virtual, /*is_static=*/is_static,
/*is_inline=*/false, /*is_explicit=*/false,
/*is_attr_used=*/false, /*is_artificial=*/is_artificial);
@@ -892,6 +893,10 @@ PdbAstBuilder::CreateFunctionDecl(PdbCompilandSymId func_id,
tag_record = CVTagRecord::create(index.tpi().getType(*eti)).asTag();
}
}
+
+ ConstString mangled_name(
+ pdb->FindMangledFunctionName(func_id).value_or(llvm::StringRef()));
+
if (!tag_record.FieldList.isSimple()) {
CVType field_list_cvt = index.tpi().getType(tag_record.FieldList);
FieldListRecord field_list;
@@ -899,15 +904,15 @@ PdbAstBuilder::CreateFunctionDecl(PdbCompilandSymId func_id,
field_list_cvt, field_list))
llvm::consumeError(std::move(error));
CreateMethodDecl process(index, m_clang, func_ti, function_decl,
- parent_opaque_ty, func_name, func_ct);
+ parent_opaque_ty, func_name, mangled_name,
+ func_ct);
if (llvm::Error err = visitMemberRecordStream(field_list.Data, process))
llvm::consumeError(std::move(err));
}
if (!function_decl) {
function_decl = m_clang.AddMethodToCXXRecordType(
- parent_opaque_ty, func_name,
- /*asm_label=*/{}, func_ct,
+ parent_opaque_ty, func_name, mangled_name, func_ct,
/*access=*/lldb::AccessType::eAccessPublic,
/*is_virtual=*/false, /*is_static=*/false,
/*is_inline=*/false, /*is_explicit=*/false,
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
index 888bd89a7262..6c66d86d3e64 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
@@ -946,17 +946,21 @@ lldb_private::npdb::GetCompilerTypeForSimpleKind(SimpleTypeKind kind) {
case SimpleTypeKind::Complex64:
return lldb::eBasicTypeDoubleComplex;
case SimpleTypeKind::Complex32:
+ case SimpleTypeKind::Complex32PartialPrecision:
return lldb::eBasicTypeFloatComplex;
- case SimpleTypeKind::Float128:
case SimpleTypeKind::Float80:
return lldb::eBasicTypeLongDouble;
+ case SimpleTypeKind::Float128:
+ return lldb::eBasicTypeFloat128;
case SimpleTypeKind::Float64:
return lldb::eBasicTypeDouble;
case SimpleTypeKind::Float32:
+ case SimpleTypeKind::Float32PartialPrecision:
return lldb::eBasicTypeFloat;
case SimpleTypeKind::Float16:
return lldb::eBasicTypeHalf;
case SimpleTypeKind::Int128:
+ case SimpleTypeKind::Int128Oct:
return lldb::eBasicTypeInt128;
case SimpleTypeKind::Int64:
case SimpleTypeKind::Int64Quad:
@@ -967,6 +971,7 @@ lldb_private::npdb::GetCompilerTypeForSimpleKind(SimpleTypeKind kind) {
case SimpleTypeKind::Int16Short:
return lldb::eBasicTypeShort;
case SimpleTypeKind::UInt128:
+ case SimpleTypeKind::UInt128Oct:
return lldb::eBasicTypeUnsignedInt128;
case SimpleTypeKind::UInt64:
case SimpleTypeKind::UInt64Quad:
@@ -985,16 +990,27 @@ lldb_private::npdb::GetCompilerTypeForSimpleKind(SimpleTypeKind kind) {
return lldb::eBasicTypeVoid;
case SimpleTypeKind::WideCharacter:
return lldb::eBasicTypeWChar;
- default:
+
+ // Not supported.
+ case SimpleTypeKind::Float48:
+ case SimpleTypeKind::Complex16:
+ case SimpleTypeKind::Complex48:
+ case SimpleTypeKind::Complex128:
+ case SimpleTypeKind::NotTranslated:
+ case SimpleTypeKind::None:
return lldb::eBasicTypeInvalid;
}
+ return lldb::eBasicTypeInvalid;
}
size_t lldb_private::npdb::GetTypeSizeForSimpleKind(SimpleTypeKind kind) {
switch (kind) {
case SimpleTypeKind::Boolean128:
+ case SimpleTypeKind::Complex128:
case SimpleTypeKind::Int128:
+ case SimpleTypeKind::Int128Oct:
case SimpleTypeKind::UInt128:
+ case SimpleTypeKind::UInt128Oct:
case SimpleTypeKind::Float128:
return 16;
case SimpleTypeKind::Complex80:
@@ -1008,10 +1024,15 @@ size_t lldb_private::npdb::GetTypeSizeForSimpleKind(SimpleTypeKind kind) {
case SimpleTypeKind::Int64:
case SimpleTypeKind::Int64Quad:
return 8;
+ case SimpleTypeKind::Complex48:
+ case SimpleTypeKind::Float48:
+ return 6;
case SimpleTypeKind::Boolean32:
case SimpleTypeKind::Character32:
case SimpleTypeKind::Complex32:
+ case SimpleTypeKind::Complex32PartialPrecision:
case SimpleTypeKind::Float32:
+ case SimpleTypeKind::Float32PartialPrecision:
case SimpleTypeKind::Int32:
case SimpleTypeKind::Int32Long:
case SimpleTypeKind::UInt32Long:
@@ -1020,6 +1041,7 @@ size_t lldb_private::npdb::GetTypeSizeForSimpleKind(SimpleTypeKind kind) {
return 4;
case SimpleTypeKind::Boolean16:
case SimpleTypeKind::Character16:
+ case SimpleTypeKind::Complex16:
case SimpleTypeKind::Float16:
case SimpleTypeKind::Int16:
case SimpleTypeKind::Int16Short:
@@ -1035,10 +1057,13 @@ size_t lldb_private::npdb::GetTypeSizeForSimpleKind(SimpleTypeKind kind) {
case SimpleTypeKind::SByte:
case SimpleTypeKind::Character8:
return 1;
+
case SimpleTypeKind::Void:
- default:
+ case SimpleTypeKind::None:
+ case SimpleTypeKind::NotTranslated:
return 0;
}
+ return 0;
}
PdbTypeSymId lldb_private::npdb::GetBestPossibleDecl(PdbTypeSymId id,
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 8b3d775afc16..ecd3188b3d56 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -152,14 +152,24 @@ static bool IsFunctionEpilogue(const CompilandIndexItem &cci,
return false;
}
+// See llvm::codeview::TypeIndex::simpleTypeName as well as strForPrimitiveTi
+// from the original pdbdump:
+// https://github.com/microsoft/microsoft-pdb/blob/805655a28bd8198004be2ac27e6e0290121a5e89/pdbdump/pdbdump.cpp#L1896-L1974
+//
+// For 64bit integers we use "long long" like DIA instead of "__int64".
static llvm::StringRef GetSimpleTypeName(SimpleTypeKind kind) {
switch (kind) {
case SimpleTypeKind::Boolean128:
- case SimpleTypeKind::Boolean16:
- case SimpleTypeKind::Boolean32:
+ return "__bool128";
case SimpleTypeKind::Boolean64:
+ return "__bool64";
+ case SimpleTypeKind::Boolean32:
+ return "__bool32";
+ case SimpleTypeKind::Boolean16:
+ return "__bool16";
case SimpleTypeKind::Boolean8:
return "bool";
+
case SimpleTypeKind::Byte:
case SimpleTypeKind::UnsignedCharacter:
return "unsigned char";
@@ -168,57 +178,81 @@ static llvm::StringRef GetSimpleTypeName(SimpleTypeKind kind) {
case SimpleTypeKind::SignedCharacter:
case SimpleTypeKind::SByte:
return "signed char";
- case SimpleTypeKind::Character16:
- return "char16_t";
case SimpleTypeKind::Character32:
return "char32_t";
+ case SimpleTypeKind::Character16:
+ return "char16_t";
case SimpleTypeKind::Character8:
return "char8_t";
+
+ case SimpleTypeKind::Complex128:
+ return "_Complex __float128";
case SimpleTypeKind::Complex80:
+ return "_Complex long double";
case SimpleTypeKind::Complex64:
+ return "_Complex double";
+ case SimpleTypeKind::Complex48:
+ return "_Complex __float48";
case SimpleTypeKind::Complex32:
- return "complex";
+ case SimpleTypeKind::Complex32PartialPrecision:
+ return "_Complex float";
+ case SimpleTypeKind::Complex16:
+ return "_Complex _Float16";
+
case SimpleTypeKind::Float128:
+ return "__float128";
case SimpleTypeKind::Float80:
return "long double";
case SimpleTypeKind::Float64:
return "double";
+ case SimpleTypeKind::Float48:
+ return "__float48";
case SimpleTypeKind::Float32:
+ case SimpleTypeKind::Float32PartialPrecision:
return "float";
case SimpleTypeKind::Float16:
- return "single";
+ return "_Float16";
+
+ case SimpleTypeKind::Int128Oct:
case SimpleTypeKind::Int128:
return "__int128";
case SimpleTypeKind::Int64:
case SimpleTypeKind::Int64Quad:
- return "int64_t";
+ return "long long";
+ case SimpleTypeKind::Int32Long:
+ return "long";
case SimpleTypeKind::Int32:
return "int";
case SimpleTypeKind::Int16:
+ case SimpleTypeKind::Int16Short:
return "short";
+
+ case SimpleTypeKind::UInt128Oct:
case SimpleTypeKind::UInt128:
return "unsigned __int128";
case SimpleTypeKind::UInt64:
case SimpleTypeKind::UInt64Quad:
- return "uint64_t";
- case SimpleTypeKind::HResult:
- return "HRESULT";
+ return "unsigned long long";
case SimpleTypeKind::UInt32:
return "unsigned";
case SimpleTypeKind::UInt16:
case SimpleTypeKind::UInt16Short:
return "unsigned short";
- case SimpleTypeKind::Int32Long:
- return "long";
case SimpleTypeKind::UInt32Long:
return "unsigned long";
+
+ case SimpleTypeKind::HResult:
+ return "HRESULT";
case SimpleTypeKind::Void:
return "void";
case SimpleTypeKind::WideCharacter:
return "wchar_t";
- default:
+
+ case SimpleTypeKind::None:
+ case SimpleTypeKind::NotTranslated:
return "";
}
+ return "";
}
static bool IsClassRecord(TypeLeafKind kind) {
@@ -501,7 +535,11 @@ lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbCompilandSymId func_id,
return nullptr;
PdbTypeSymId sig_id(proc.FunctionType, false);
- Mangled mangled(proc.Name);
+
+ std::optional<llvm::StringRef> mangled_opt = FindMangledSymbol(
+ SegmentOffset(proc.Segment, proc.CodeOffset), proc.FunctionType);
+ Mangled mangled(mangled_opt.value_or(proc.Name));
+
FunctionSP func_sp = std::make_shared<Function>(
&comp_unit, toOpaqueUid(func_id), toOpaqueUid(sig_id), mangled,
func_type.get(), func_addr,
@@ -594,8 +632,8 @@ lldb::TypeSP SymbolFileNativePDB::CreateSimpleType(TypeIndex ti,
uint64_t uid = toOpaqueUid(PdbTypeSymId(ti, false));
if (ti == TypeIndex::NullptrT()) {
Declaration decl;
- return MakeType(uid, ConstString("std::nullptr_t"), 0, nullptr,
- LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct,
+ return MakeType(uid, ConstString("decltype(nullptr)"), std::nullopt,
+ nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct,
Type::ResolveState::Full);
}
@@ -2137,14 +2175,17 @@ TypeSP SymbolFileNativePDB::CreateTypedef(PdbGlobalSymId id) {
if (!ts)
return nullptr;
- ts->GetNativePDBParser()->GetOrCreateTypedefDecl(id);
+ auto *typedef_decl = ts->GetNativePDBParser()->GetOrCreateTypedefDecl(id);
+
+ CompilerType ct = target_type->GetForwardCompilerType();
+ if (auto *clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get()))
+ ct = clang->GetType(clang->getASTContext().getTypeDeclType(typedef_decl));
Declaration decl;
return MakeType(toOpaqueUid(id), ConstString(udt.Name),
llvm::expectedToOptional(target_type->GetByteSize(nullptr)),
nullptr, target_type->GetID(),
- lldb_private::Type::eEncodingIsTypedefUID, decl,
- target_type->GetForwardCompilerType(),
+ lldb_private::Type::eEncodingIsTypedefUID, decl, ct,
lldb_private::Type::ResolveState::Forward);
}
@@ -2662,6 +2703,83 @@ SymbolFileNativePDB::GetContextForType(TypeIndex ti) {
return ctx;
}
+std::optional<llvm::StringRef>
+SymbolFileNativePDB::FindMangledFunctionName(PdbCompilandSymId func_id) {
+ const CompilandIndexItem *cci =
+ m_index->compilands().GetCompiland(func_id.modi);
+ if (!cci)
+ return std::nullopt;
+
+ CVSymbol sym_record = cci->m_debug_stream.readSymbolAtOffset(func_id.offset);
+ if (sym_record.kind() != S_LPROC32 && sym_record.kind() != S_GPROC32)
+ return std::nullopt;
+
+ ProcSym proc(static_cast<SymbolRecordKind>(sym_record.kind()));
+ cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc));
+
+ return FindMangledSymbol(SegmentOffset(proc.Segment, proc.CodeOffset),
+ proc.FunctionType);
+}
+
+std::optional<llvm::StringRef>
+SymbolFileNativePDB::FindMangledSymbol(SegmentOffset so,
+ TypeIndex function_type) {
+ auto symbol = m_index->publics().findByAddress(m_index->symrecords(),
+ so.segment, so.offset);
+ if (!symbol)
+ return std::nullopt;
+
+ llvm::StringRef name = symbol->first.Name;
+ // For functions, we might need to strip the mangled name. See
+ // StripMangledFunctionName for more info.
+ if (!function_type.isNoneType() &&
+ (symbol->first.Flags & PublicSymFlags::Function) != PublicSymFlags::None)
+ name = StripMangledFunctionName(name, function_type);
+
+ return name;
+}
+
+llvm::StringRef
+SymbolFileNativePDB::StripMangledFunctionName(const llvm::StringRef mangled,
+ PdbTypeSymId func_ty) {
+ // "In non-64 bit environments" (on x86 in pactice), __cdecl functions get
+ // prefixed with an underscore. For compilers using LLVM, this happens in LLVM
+ // (as opposed to the compiler frontend). Because of this, DWARF doesn't
+ // contain the "full" mangled name in DW_AT_linkage_name for these functions.
+ // We strip the mangling here for compatibility with DWARF. See
+ // llvm.org/pr161676 and
+ // https://learn.microsoft.com/en-us/cpp/build/reference/decorated-names#FormatC
+
+ if (!mangled.starts_with('_') ||
+ m_index->dbi().getMachineType() != PDB_Machine::x86)
+ return mangled;
+
+ CVType cvt = m_index->tpi().getType(func_ty.index);
+ PDB_CallingConv cc = PDB_CallingConv::NearC;
+ if (cvt.kind() == LF_PROCEDURE) {
+ ProcedureRecord proc;
+ if (llvm::Error error =
+ TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, proc))
+ llvm::consumeError(std::move(error));
+ cc = proc.CallConv;
+ } else if (cvt.kind() == LF_MFUNCTION) {
+ MemberFunctionRecord mfunc;
+ if (llvm::Error error =
+ TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfunc))
+ llvm::consumeError(std::move(error));
+ cc = mfunc.CallConv;
+ } else {
+ LLDB_LOG(GetLog(LLDBLog::Symbols), "Unexpected function type, got {0}",
+ cvt.kind());
+ return mangled;
+ }
+
+ if (cc == PDB_CallingConv::NearC || cc == PDB_CallingConv::FarC)
+ return mangled.drop_front();
+
+ return mangled;
+}
+
void SymbolFileNativePDB::CacheUdtDeclarations() {
for (CVType cvt : m_index->ipi().typeArray()) {
switch (cvt.kind()) {
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index 2405f8b29933..a5fef354af65 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -140,6 +140,12 @@ public:
std::optional<PdbCompilandSymId> FindSymbolScope(PdbCompilandSymId id);
+ /// Find the mangled name for a function
+ ///
+ /// \param id A symbol ID of a S_LPROC32/S_GPROC32 record
+ /// \returns The mangled name of the function (if available)
+ std::optional<llvm::StringRef> FindMangledFunctionName(PdbCompilandSymId id);
+
void FindTypes(const lldb_private::TypeQuery &match,
lldb_private::TypeResults &results) override;
@@ -269,6 +275,20 @@ private:
void CacheUdtDeclarations();
llvm::Expected<Declaration> ResolveUdtDeclaration(PdbTypeSymId type_id);
+ /// Find a symbol name at a specific address (`so`).
+ ///
+ /// \param[in] so The segment and offset where the symbol is located.
+ /// \param[in] function_type If the symbol is expected to be a function, this
+ /// has to be the type of the function. It's used to strip the name of
+ /// __cdecl functions on x86.
+ /// \returns The mangled symbol name if found, otherwise `std::nullopt`.
+ std::optional<llvm::StringRef> FindMangledSymbol(
+ SegmentOffset so,
+ llvm::codeview::TypeIndex function_type = llvm::codeview::TypeIndex());
+
+ llvm::StringRef StripMangledFunctionName(llvm::StringRef mangled,
+ PdbTypeSymId func_ty);
+
llvm::BumpPtrAllocator m_allocator;
lldb::addr_t m_obj_load_address = 0;