diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp')
| -rw-r--r-- | lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp | 156 |
1 files changed, 137 insertions, 19 deletions
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()) { |
