aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp')
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp83
1 files changed, 82 insertions, 1 deletions
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 8b3d775..75a8189 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -501,7 +501,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,
@@ -2662,6 +2666,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()) {