diff options
Diffstat (limited to 'lldb/source')
-rw-r--r-- | lldb/source/API/SBDebugger.cpp | 11 | ||||
-rw-r--r-- | lldb/source/API/SBTarget.cpp | 8 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp | 6 | ||||
-rw-r--r-- | lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp | 19 | ||||
-rw-r--r-- | lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp | 83 | ||||
-rw-r--r-- | lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h | 20 | ||||
-rw-r--r-- | lldb/source/Target/Target.cpp | 3 | ||||
-rw-r--r-- | lldb/source/Target/TargetList.cpp | 12 |
8 files changed, 152 insertions, 10 deletions
diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp index 603e306..5c4c653 100644 --- a/lldb/source/API/SBDebugger.cpp +++ b/lldb/source/API/SBDebugger.cpp @@ -983,6 +983,17 @@ uint32_t SBDebugger::GetIndexOfTarget(lldb::SBTarget target) { return m_opaque_sp->GetTargetList().GetIndexOfTarget(target.GetSP()); } +SBTarget SBDebugger::FindTargetByGloballyUniqueID(lldb::user_id_t id) { + LLDB_INSTRUMENT_VA(this, id); + SBTarget sb_target; + if (m_opaque_sp) { + // No need to lock, the target list is thread safe + sb_target.SetSP( + m_opaque_sp->GetTargetList().FindTargetByGloballyUniqueID(id)); + } + return sb_target; +} + SBTarget SBDebugger::FindTargetWithProcessID(lldb::pid_t pid) { LLDB_INSTRUMENT_VA(this, pid); diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp index 0d03250..98d10aa 100644 --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -1633,6 +1633,14 @@ const char *SBTarget::GetLabel() const { return nullptr; } +lldb::user_id_t SBTarget::GetGloballyUniqueID() const { + LLDB_INSTRUMENT_VA(this); + + if (TargetSP target_sp = GetSP()) + return target_sp->GetGloballyUniqueID(); + return LLDB_INVALID_GLOBALLY_UNIQUE_TARGET_ID; +} + SBError SBTarget::SetLabel(const char *label) { LLDB_INSTRUMENT_VA(this, label); diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp index 9c798cb..7ef50da 100644 --- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -218,8 +218,8 @@ static Status EnsureFDFlags(int fd, int flags) { static llvm::Error AddPtraceScopeNote(llvm::Error original_error) { Expected<int> ptrace_scope = GetPtraceScope(); if (auto E = ptrace_scope.takeError()) { - Log *log = GetLog(POSIXLog::Process); - LLDB_LOG(log, "error reading value of ptrace_scope: {0}", E); + LLDB_LOG_ERROR(GetLog(POSIXLog::Process), std::move(E), + "error reading value of ptrace_scope: {0}"); // The original error is probably more interesting than not being able to // read or interpret ptrace_scope. @@ -230,6 +230,7 @@ static llvm::Error AddPtraceScopeNote(llvm::Error original_error) { switch (*ptrace_scope) { case 1: case 2: + llvm::consumeError(std::move(original_error)); return llvm::createStringError( std::error_code(errno, std::generic_category()), "The current value of ptrace_scope is %d, which can cause ptrace to " @@ -239,6 +240,7 @@ static llvm::Error AddPtraceScopeNote(llvm::Error original_error) { "https://www.kernel.org/doc/Documentation/security/Yama.txt.", *ptrace_scope); case 3: + llvm::consumeError(std::move(original_error)); return llvm::createStringError( std::error_code(errno, std::generic_category()), "The current value of ptrace_scope is 3, which will cause ptrace to " diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp index 51bdcc9..e7fddf0 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/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()) { diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h index 2405f8b..a5fef35 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; diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index fa98c24..e0286c4 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -139,6 +139,8 @@ private: }; } // namespace +static std::atomic<lldb::user_id_t> g_target_unique_id{1}; + template <typename Installer> static Status installExecutable(const Installer &installer) { if (!installer.m_local_file || !installer.m_remote_file) @@ -183,6 +185,7 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch, m_source_manager_up(), m_stop_hooks(), m_stop_hook_next_id(0), m_latest_stop_hook_id(0), m_valid(true), m_suppress_stop_hooks(false), m_is_dummy_target(is_dummy_target), + m_target_unique_id(g_target_unique_id++), m_frame_recognizer_manager_up( std::make_unique<StackFrameRecognizerManager>()) { SetEventName(eBroadcastBitBreakpointChanged, "breakpoint-changed"); diff --git a/lldb/source/Target/TargetList.cpp b/lldb/source/Target/TargetList.cpp index 7037dc2..188c250 100644 --- a/lldb/source/Target/TargetList.cpp +++ b/lldb/source/Target/TargetList.cpp @@ -428,6 +428,18 @@ TargetSP TargetList::FindTargetWithProcess(Process *process) const { return target_sp; } +TargetSP TargetList::FindTargetByGloballyUniqueID(lldb::user_id_t id) const { + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); + auto it = llvm::find_if(m_target_list, [id](const TargetSP &item) { + return item->GetGloballyUniqueID() == id; + }); + + if (it != m_target_list.end()) + return *it; + + return TargetSP(); +} + TargetSP TargetList::GetTargetSP(Target *target) const { TargetSP target_sp; if (!target) |