aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Plugins
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-01-27 22:17:16 +0000
committerDimitry Andric <dim@FreeBSD.org>2022-06-04 11:59:19 +0000
commit390adc38fc112be360bd15499e5241bf4e675b6f (patch)
tree712d68d3aa03f7aa4902ba03dcac2a56f49ae0e5 /contrib/llvm-project/lldb/source/Plugins
parent8a84287b0edc66fc6dede3db770d10ff41da5464 (diff)
downloadsrc-390adc38fc112be360bd15499e5241bf4e675b6f.tar.gz
src-390adc38fc112be360bd15499e5241bf4e675b6f.zip
Merge llvm-project main llvmorg-14-init-17616-g024a1fab5c35
This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp to llvmorg-14-init-17616-g024a1fab5c35. PR: 261742 MFC after: 2 weeks (cherry picked from commit 04eeddc0aa8e0a417a16eaf9d7d095207f4a8623)
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins')
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp45
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp132
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h16
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSString.cpp37
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp28
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp94
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp141
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp13
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h8
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp173
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp45
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp30
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp121
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.cpp11
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.h16
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp30
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp20
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h32
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.cpp111
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp11
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp314
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h88
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp16
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.cpp86
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.h26
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp63
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp28
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h55
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp28
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp70
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp91
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.h12
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp30
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h54
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h53
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp206
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp28
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp19
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/lldb-python.h7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp37
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h31
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp11
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp18
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h33
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp232
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h98
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp52
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h38
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp19
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h13
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp525
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h33
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp71
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h11
92 files changed, 2688 insertions, 1071 deletions
diff --git a/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp b/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
index 2cf32bdd3800..8c54219f0a14 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
@@ -1111,7 +1111,7 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch,
triple.getSubArch() == llvm::Triple::NoSubArch)
triple.setArchName("armv8.7a");
- std::string features_str = "";
+ std::string features_str;
const char *triple_str = triple.getTriple().c_str();
// ARM Cortex M0-M7 devices only execute thumb instructions
diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index d9cbcce22c52..188b6da7a712 100644
--- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -338,7 +338,7 @@ bool DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() {
dyld_break = target.CreateBreakpoint(
&containingModules, /*containingSourceFiles=*/nullptr,
DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC,
- /*offset=*/0,
+ /*m_offset=*/0,
/*skip_prologue=*/eLazyBoolNo,
/*internal=*/true,
/*request_hardware=*/false);
@@ -348,7 +348,7 @@ bool DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() {
dyld_break = target.CreateBreakpoint(
&containingModules, /*containingSourceFiles=*/nullptr,
DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC,
- /*offset=*/0,
+ /*m_offset=*/0,
/*skip_prologue=*/eLazyBoolNo,
/*internal=*/true,
/*request_hardware=*/false);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index a0cff3cc9bf8..51f34369c383 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -995,7 +995,8 @@ public:
void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
OverloadCandidate *Candidates,
unsigned NumCandidates,
- SourceLocation OpenParLoc) override {
+ SourceLocation OpenParLoc,
+ bool Braced) override {
// At the moment we don't filter out any overloaded candidates.
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp
index 74dd04600b4b..fecffd1183f8 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp
@@ -138,7 +138,7 @@ getEqualLocalDeclContext(Sema &sema, DeclContext *foreign_ctxt) {
// We currently only support building namespaces.
if (foreign_ctxt->isNamespace()) {
- NamedDecl *ns = llvm::dyn_cast<NamedDecl>(foreign_ctxt);
+ NamedDecl *ns = llvm::cast<NamedDecl>(foreign_ctxt);
llvm::StringRef ns_name = ns->getName();
auto lookup_result = emulateLookupInCtxt(sema, ns_name, *parent);
diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
index ea9c95c55cbb..4ef0a034b6dd 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
@@ -137,7 +137,7 @@ EmulateInstructionMIPS::EmulateInstructionMIPS(
break;
}
- std::string features = "";
+ std::string features;
uint32_t arch_flags = arch.GetFlags();
if (arch_flags & ArchSpec::eMIPSAse_msa)
features += "+msa,";
diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
index e5732a50f3f2..26736f4c58ba 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
@@ -137,7 +137,7 @@ EmulateInstructionMIPS64::EmulateInstructionMIPS64(
break;
}
- std::string features = "";
+ std::string features;
uint32_t arch_flags = arch.GetFlags();
if (arch_flags & ArchSpec::eMIPSAse_msa)
features += "+msa,";
diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp
index dc8c7c96aa11..a5c23615309d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp
@@ -100,14 +100,14 @@ InstrumentationRuntimeMainThreadChecker::RetrieveReportData(
if (!apiname_ptr)
return StructuredData::ObjectSP();
- std::string apiName = "";
+ std::string apiName;
Status read_error;
target.ReadCStringFromMemory(apiname_ptr, apiName, read_error);
if (read_error.Fail())
return StructuredData::ObjectSP();
- std::string className = "";
- std::string selector = "";
+ std::string className;
+ std::string selector;
if (apiName.substr(0, 2) == "-[") {
size_t spacePos = apiName.find(' ');
if (spacePos != std::string::npos) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp
index aef10bb2a778..977d8e4dbe07 100644
--- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp
@@ -711,7 +711,7 @@ addr_t InstrumentationRuntimeTSan::GetMainRacyAddress(
std::string InstrumentationRuntimeTSan::GetLocationDescription(
StructuredData::ObjectSP report, addr_t &global_addr,
std::string &global_name, std::string &filename, uint32_t &line) {
- std::string result = "";
+ std::string result;
ProcessSP process_sp = GetProcessSP();
@@ -820,8 +820,8 @@ bool InstrumentationRuntimeTSan::NotifyBreakpointHit(
report->GetAsDictionary()->AddIntegerItem("memory_address", main_address);
addr_t global_addr = 0;
- std::string global_name = "";
- std::string location_filename = "";
+ std::string global_name;
+ std::string location_filename;
uint32_t location_line = 0;
std::string location_description = instance->GetLocationDescription(
report, global_addr, global_name, location_filename, location_line);
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index df61cc3853eb..0fb65f5a317d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -579,6 +579,51 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"std::__[[:alnum:]]+::allocator<wchar_t> >$"),
stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxStringViewSummaryProviderASCII,
+ "std::string_view summary provider",
+ ConstString("^std::__[[:alnum:]]+::string_view$"),
+ stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxStringViewSummaryProviderASCII,
+ "std::string_view summary provider",
+ ConstString("^std::__[[:alnum:]]+::basic_string_view<char, "
+ "std::__[[:alnum:]]+::char_traits<char> >$"),
+ stl_summary_flags, true);
+ AddCXXSummary(
+ cpp_category_sp,
+ lldb_private::formatters::LibcxxStringViewSummaryProviderASCII,
+ "std::string_view summary provider",
+ ConstString("^std::__[[:alnum:]]+::basic_string_view<unsigned char, "
+ "std::__[[:alnum:]]+::char_traits<unsigned char> >$"),
+ stl_summary_flags, true);
+
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxStringViewSummaryProviderUTF16,
+ "std::u16string_view summary provider",
+ ConstString("^std::__[[:alnum:]]+::basic_string_view<char16_t, "
+ "std::__[[:alnum:]]+::char_traits<char16_t> >$"),
+ stl_summary_flags, true);
+
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxStringViewSummaryProviderUTF32,
+ "std::u32string_view summary provider",
+ ConstString("^std::__[[:alnum:]]+::basic_string_view<char32_t, "
+ "std::__[[:alnum:]]+::char_traits<char32_t> >$"),
+ stl_summary_flags, true);
+
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxWStringViewSummaryProvider,
+ "std::wstring_view summary provider",
+ ConstString("^std::__[[:alnum:]]+::wstring_view$"),
+ stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxWStringViewSummaryProvider,
+ "std::wstring_view summary provider",
+ ConstString("^std::__[[:alnum:]]+::basic_string_view<wchar_t, "
+ "std::__[[:alnum:]]+::char_traits<wchar_t> >$"),
+ stl_summary_flags, true);
+
SyntheticChildren::Flags stl_synth_flags;
stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
false);
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
index c8063915b178..d1d844bb4ca4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
@@ -72,6 +72,7 @@ ConstString GenericBitsetFrontEnd::GetDataContainerMemberName() {
case StdLib::LibStdcpp:
return ConstString("_M_w");
}
+ llvm_unreachable("Unknown StdLib enum");
}
bool GenericBitsetFrontEnd::Update() {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index b9aef0ae7d9e..21196393371e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -19,6 +19,7 @@
#include "lldb/Target/ProcessStructReader.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/Status.h"
@@ -26,6 +27,7 @@
#include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+#include <tuple>
using namespace lldb;
using namespace lldb_private;
@@ -560,7 +562,7 @@ ExtractLibcxxStringInfo(ValueObject &valobj) {
return {};
ValueObjectSP layout_decider(
- D->GetChildAtIndexPath(llvm::ArrayRef<size_t>({0, 0})));
+ D->GetChildAtIndexPath(llvm::ArrayRef<size_t>({0, 0})));
// this child should exist
if (!layout_decider)
@@ -643,16 +645,10 @@ ExtractLibcxxStringInfo(ValueObject &valobj) {
return std::make_pair(size, location_sp);
}
-bool lldb_private::formatters::LibcxxWStringSummaryProvider(
- ValueObject &valobj, Stream &stream,
- const TypeSummaryOptions &summary_options) {
- auto string_info = ExtractLibcxxStringInfo(valobj);
- if (!string_info)
- return false;
- uint64_t size;
- ValueObjectSP location_sp;
- std::tie(size, location_sp) = *string_info;
-
+static bool
+LibcxxWStringSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options,
+ ValueObjectSP location_sp, size_t size) {
if (size == 0) {
stream.Printf("L\"\"");
return true;
@@ -660,7 +656,6 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider(
if (!location_sp)
return false;
-
StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) {
const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary();
@@ -714,10 +709,9 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider(
return false;
}
-template <StringPrinter::StringElementType element_type>
-bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream,
- const TypeSummaryOptions &summary_options,
- std::string prefix_token) {
+bool lldb_private::formatters::LibcxxWStringSummaryProvider(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options) {
auto string_info = ExtractLibcxxStringInfo(valobj);
if (!string_info)
return false;
@@ -725,6 +719,17 @@ bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream,
ValueObjectSP location_sp;
std::tie(size, location_sp) = *string_info;
+ return ::LibcxxWStringSummaryProvider(valobj, stream, summary_options,
+ location_sp, size);
+}
+
+template <StringPrinter::StringElementType element_type>
+static bool
+LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options,
+ std::string prefix_token, ValueObjectSP location_sp,
+ uint64_t size) {
+
if (size == 0) {
stream.Printf("\"\"");
return true;
@@ -763,6 +768,21 @@ bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream,
}
template <StringPrinter::StringElementType element_type>
+static bool
+LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options,
+ std::string prefix_token) {
+ auto string_info = ExtractLibcxxStringInfo(valobj);
+ if (!string_info)
+ return false;
+ uint64_t size;
+ ValueObjectSP location_sp;
+ std::tie(size, location_sp) = *string_info;
+
+ return LibcxxStringSummaryProvider<element_type>(
+ valobj, stream, summary_options, prefix_token, location_sp, size);
+}
+template <StringPrinter::StringElementType element_type>
static bool formatStringImpl(ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &summary_options,
std::string prefix_token) {
@@ -796,3 +816,83 @@ bool lldb_private::formatters::LibcxxStringSummaryProviderUTF32(
return formatStringImpl<StringPrinter::StringElementType::UTF32>(
valobj, stream, summary_options, "U");
}
+
+static std::tuple<bool, ValueObjectSP, size_t>
+LibcxxExtractStringViewData(ValueObject& valobj) {
+ ConstString g_data_name("__data");
+ ConstString g_size_name("__size");
+ auto dataobj = valobj.GetChildMemberWithName(g_data_name, true);
+ auto sizeobj = valobj.GetChildMemberWithName(g_size_name, true);
+
+ if (!dataobj || !sizeobj)
+ return std::make_tuple<bool,ValueObjectSP,size_t>(false, {}, {});
+
+ if (!dataobj->GetError().Success() || !sizeobj->GetError().Success())
+ return std::make_tuple<bool,ValueObjectSP,size_t>(false, {}, {});
+
+ bool success{false};
+ uint64_t size = sizeobj->GetValueAsUnsigned(0, &success);
+ if (!success)
+ return std::make_tuple<bool,ValueObjectSP,size_t>(false, {}, {});
+
+ return std::make_tuple(true,dataobj,size);
+}
+
+template <StringPrinter::StringElementType element_type>
+static bool formatStringViewImpl(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options,
+ std::string prefix_token) {
+
+ bool success;
+ ValueObjectSP dataobj;
+ size_t size;
+ std::tie(success, dataobj, size) = LibcxxExtractStringViewData(valobj);
+
+ if (!success) {
+ stream << "Summary Unavailable";
+ return true;
+ }
+
+ return LibcxxStringSummaryProvider<element_type>(
+ valobj, stream, summary_options, prefix_token, dataobj, size);
+}
+
+bool lldb_private::formatters::LibcxxStringViewSummaryProviderASCII(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options) {
+ return formatStringViewImpl<StringPrinter::StringElementType::ASCII>(
+ valobj, stream, summary_options, "");
+}
+
+bool lldb_private::formatters::LibcxxStringViewSummaryProviderUTF16(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options) {
+ return formatStringViewImpl<StringPrinter::StringElementType::UTF16>(
+ valobj, stream, summary_options, "u");
+}
+
+bool lldb_private::formatters::LibcxxStringViewSummaryProviderUTF32(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options) {
+ return formatStringViewImpl<StringPrinter::StringElementType::UTF32>(
+ valobj, stream, summary_options, "U");
+}
+
+bool lldb_private::formatters::LibcxxWStringViewSummaryProvider(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options) {
+
+ bool success;
+ ValueObjectSP dataobj;
+ size_t size;
+ std::tie( success, dataobj, size ) = LibcxxExtractStringViewData(valobj);
+
+ if (!success) {
+ stream << "Summary Unavailable";
+ return true;
+ }
+
+
+ return ::LibcxxWStringSummaryProvider(valobj, stream, summary_options,
+ dataobj, size);
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
index 80dc71787ceb..0f166ae24912 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -34,6 +34,22 @@ bool LibcxxWStringSummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // libc++ std::wstring
+bool LibcxxStringViewSummaryProviderASCII(
+ ValueObject &valueObj, Stream &stream,
+ const TypeSummaryOptions &summary_options); // libc++ std::string_view
+
+bool LibcxxStringViewSummaryProviderUTF16(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options); // libc++ std::u16string_view
+
+bool LibcxxStringViewSummaryProviderUTF32(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options); // libc++ std::u32string_view
+
+bool LibcxxWStringViewSummaryProvider(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options); // libc++ std::wstring_view
+
bool LibcxxOptionalSummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // libc++ std::optional<>
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSString.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSString.cpp
index 2b5161e781f2..61705c866778 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSString.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSString.cpp
@@ -8,14 +8,13 @@
#include "NSString.h"
-#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/DataFormatters/StringPrinter.h"
#include "lldb/Target/Language.h"
-#include "lldb/Target/ProcessStructReader.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/Status.h"
@@ -31,24 +30,6 @@ NSString_Additionals::GetAdditionalSummaries() {
return g_map;
}
-static CompilerType GetNSPathStore2Type(Target &target) {
- static ConstString g_type_name("__lldb_autogen_nspathstore2");
-
- TypeSystemClang *ast_ctx = ScratchTypeSystemClang::GetForTarget(target);
-
- if (!ast_ctx)
- return CompilerType();
-
- CompilerType voidstar =
- ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType();
- CompilerType uint32 =
- ast_ctx->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
-
- return ast_ctx->GetOrCreateStructForIdentifier(
- g_type_name,
- {{"isa", voidstar}, {"lengthAndRef", uint32}, {"buffer", voidstar}});
-}
-
bool lldb_private::formatters::NSStringSummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &summary_options) {
@@ -229,11 +210,17 @@ bool lldb_private::formatters::NSStringSummaryProvider(
return StringPrinter::ReadStringAndDumpToStream<
StringPrinter::StringElementType::UTF16>(options);
} else if (is_path_store) {
- ProcessStructReader reader(valobj.GetProcessSP().get(),
- valobj.GetValueAsUnsigned(0),
- GetNSPathStore2Type(*valobj.GetTargetSP()));
- explicit_length =
- reader.GetField<uint32_t>(ConstString("lengthAndRef")) >> 20;
+ // _lengthAndRefCount is the first ivar of NSPathStore2 (after the isa).
+ uint64_t length_ivar_offset = 1 * ptr_size;
+ CompilerType length_type = valobj.GetCompilerType().GetBasicTypeFromAST(
+ lldb::eBasicTypeUnsignedInt);
+ ValueObjectSP length_valobj_sp =
+ valobj.GetSyntheticChildAtOffset(length_ivar_offset, length_type, true,
+ ConstString("_lengthAndRefCount"));
+ if (!length_valobj_sp)
+ return false;
+ // Get the length out of _lengthAndRefCount.
+ explicit_length = length_valobj_sp->GetValueAsUnsigned(0) >> 20;
lldb::addr_t location = valobj.GetValueAsUnsigned(0) + ptr_size + 4;
options.SetLocation(location);
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index bd6b6335ca8c..f2cf25f93eb2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -671,7 +671,7 @@ AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process,
static const ConstString g_objc_copyRealizedClassList(
"_ZL33objc_copyRealizedClassList_nolockPj");
m_has_objc_copyRealizedClassList = HasSymbol(g_objc_copyRealizedClassList);
-
+ WarnIfNoExpandedSharedCache();
RegisterObjCExceptionRecognizer(process);
}
@@ -2355,6 +2355,32 @@ void AppleObjCRuntimeV2::WarnIfNoClassesCached(
}
}
+void AppleObjCRuntimeV2::WarnIfNoExpandedSharedCache() {
+ if (!m_objc_module_sp)
+ return;
+
+ ObjectFile *object_file = m_objc_module_sp->GetObjectFile();
+ if (!object_file)
+ return;
+
+ if (!object_file->IsInMemory())
+ return;
+
+ Target &target = GetProcess()->GetTarget();
+ Debugger &debugger = target.GetDebugger();
+ if (auto stream = debugger.GetAsyncOutputStream()) {
+ const char *msg = "read from the shared cache";
+ if (PlatformSP platform_sp = target.GetPlatform())
+ msg = platform_sp->IsHost()
+ ? "read from the host's in-memory shared cache"
+ : "find the on-disk shared cache for this device";
+ stream->Printf("warning: libobjc.A.dylib is being read from process "
+ "memory. This indicates that LLDB could not %s. This will "
+ "likely reduce debugging performance.\n",
+ msg);
+ }
+}
+
DeclVendor *AppleObjCRuntimeV2::GetDeclVendor() {
if (!m_decl_vendor_up)
m_decl_vendor_up = std::make_unique<AppleObjCDeclVendor>(*this);
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
index 6266634e64c5..e1a6b7cde48a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
@@ -399,6 +399,7 @@ private:
};
void WarnIfNoClassesCached(SharedCacheWarningReason reason);
+ void WarnIfNoExpandedSharedCache();
lldb::addr_t GetSharedCacheReadOnlyAddress();
lldb::addr_t GetSharedCacheBaseAddress();
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
index aa6306bef8b9..ff41f187ba9d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
@@ -889,8 +889,8 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
ThreadPlanSP ret_plan_sp;
lldb::addr_t curr_pc = thread.GetRegisterContext()->GetPC();
- DispatchFunction vtable_dispatch
- = {"vtable", 0, false, false, DispatchFunction::eFixUpFixed};
+ DispatchFunction vtable_dispatch = {"vtable", false, false, false,
+ DispatchFunction::eFixUpFixed};
// First step is to look and see if we are in one of the known ObjC
// dispatch functions. We've already compiled a table of same, so
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
index c6cb2be981a7..40a0ea3e97a4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
@@ -59,7 +59,7 @@ uint32_t AppleObjCTypeEncodingParser::ReadNumber(StringLexer &type) {
// "{CGRect=\"origin\"{CGPoint=\"x\"d\"y\"d}\"size\"{CGSize=\"width\"d\"height\"d}}"
AppleObjCTypeEncodingParser::StructElement::StructElement()
- : name(""), type(clang::QualType()) {}
+ : type(clang::QualType()) {}
AppleObjCTypeEncodingParser::StructElement
AppleObjCTypeEncodingParser::ReadStructElement(TypeSystemClang &ast_ctx,
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
index a70e6a079f76..516bcb21b019 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
@@ -115,7 +115,7 @@ Status MinidumpFileBuilder::AddSystemInfo(const llvm::Triple &target_triple) {
sys_info.PlatformId = platform_id;
m_data.AppendData(&sys_info, sizeof(llvm::minidump::SystemInfo));
- std::string csd_string = "";
+ std::string csd_string;
error = WriteString(csd_string, &m_data);
if (error.Fail()) {
@@ -272,7 +272,8 @@ Status MinidumpFileBuilder::AddModuleList(Target &target) {
mod->GetObjectFile()->GetBaseAddress().GetLoadAddress(&target));
m.SizeOfImage = static_cast<llvm::support::ulittle32_t>(mod_size);
m.Checksum = static_cast<llvm::support::ulittle32_t>(0);
- m.TimeDateStamp = static_cast<llvm::support::ulittle32_t>(std::time(0));
+ m.TimeDateStamp =
+ static_cast<llvm::support::ulittle32_t>(std::time(nullptr));
m.ModuleNameRVA = static_cast<llvm::support::ulittle32_t>(
size_before + module_stream_size + helper_data.GetByteSize());
m.VersionInfo = info;
@@ -719,7 +720,7 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP &core_file) const {
header.Checksum = static_cast<llvm::support::ulittle32_t>(
0u), // not used in most of the writers
header.TimeDateStamp =
- static_cast<llvm::support::ulittle32_t>(std::time(0));
+ static_cast<llvm::support::ulittle32_t>(std::time(nullptr));
header.Flags =
static_cast<llvm::support::ulittle64_t>(0u); // minidump normal flag
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h
index da999d2b55a7..a1a3eeb656dd 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h
@@ -102,4 +102,4 @@ private:
};
} // namespace lldb_private
-#endif // LLDB_PLUGINS_OBJECTFILE_PDB_OBJECTFILEPDB_H
+#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_PDB_OBJECTFILEPDB_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
index 754d06de7cb9..2bf0a44e4a3e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
@@ -183,3 +183,97 @@ MmapArgList PlatformFreeBSD::GetMmapArgumentList(const ArchSpec &arch,
args.push_back(0);
return args;
}
+
+CompilerType PlatformFreeBSD::GetSiginfoType(const llvm::Triple &triple) {
+ if (!m_type_system_up)
+ m_type_system_up.reset(new TypeSystemClang("siginfo", triple));
+ TypeSystemClang *ast = m_type_system_up.get();
+
+ // generic types
+ CompilerType int_type = ast->GetBasicType(eBasicTypeInt);
+ CompilerType uint_type = ast->GetBasicType(eBasicTypeUnsignedInt);
+ CompilerType long_type = ast->GetBasicType(eBasicTypeLong);
+ CompilerType voidp_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType();
+
+ // platform-specific types
+ CompilerType &pid_type = int_type;
+ CompilerType &uid_type = uint_type;
+
+ CompilerType sigval_type = ast->CreateRecordType(
+ nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_sigval_t",
+ clang::TTK_Union, lldb::eLanguageTypeC);
+ ast->StartTagDeclarationDefinition(sigval_type);
+ ast->AddFieldToRecordType(sigval_type, "sival_int", int_type,
+ lldb::eAccessPublic, 0);
+ ast->AddFieldToRecordType(sigval_type, "sival_ptr", voidp_type,
+ lldb::eAccessPublic, 0);
+ ast->CompleteTagDeclarationDefinition(sigval_type);
+
+ // siginfo_t
+ CompilerType siginfo_type = ast->CreateRecordType(
+ nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_siginfo_t",
+ clang::TTK_Struct, lldb::eLanguageTypeC);
+ ast->StartTagDeclarationDefinition(siginfo_type);
+ ast->AddFieldToRecordType(siginfo_type, "si_signo", int_type,
+ lldb::eAccessPublic, 0);
+ ast->AddFieldToRecordType(siginfo_type, "si_errno", int_type,
+ lldb::eAccessPublic, 0);
+ ast->AddFieldToRecordType(siginfo_type, "si_code", int_type,
+ lldb::eAccessPublic, 0);
+ ast->AddFieldToRecordType(siginfo_type, "si_pid", pid_type,
+ lldb::eAccessPublic, 0);
+ ast->AddFieldToRecordType(siginfo_type, "si_uid", uid_type,
+ lldb::eAccessPublic, 0);
+ ast->AddFieldToRecordType(siginfo_type, "si_status", int_type,
+ lldb::eAccessPublic, 0);
+ ast->AddFieldToRecordType(siginfo_type, "si_addr", voidp_type,
+ lldb::eAccessPublic, 0);
+ ast->AddFieldToRecordType(siginfo_type, "si_value", sigval_type,
+ lldb::eAccessPublic, 0);
+
+ // union used to hold the signal data
+ CompilerType union_type = ast->CreateRecordType(
+ nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "",
+ clang::TTK_Union, lldb::eLanguageTypeC);
+ ast->StartTagDeclarationDefinition(union_type);
+
+ ast->AddFieldToRecordType(
+ union_type, "_fault",
+ ast->CreateStructForIdentifier(ConstString(),
+ {
+ {"_trapno", int_type},
+ }),
+ lldb::eAccessPublic, 0);
+
+ ast->AddFieldToRecordType(
+ union_type, "_timer",
+ ast->CreateStructForIdentifier(ConstString(),
+ {
+ {"_timerid", int_type},
+ {"_overrun", int_type},
+ }),
+ lldb::eAccessPublic, 0);
+
+ ast->AddFieldToRecordType(
+ union_type, "_mesgq",
+ ast->CreateStructForIdentifier(ConstString(),
+ {
+ {"_mqd", int_type},
+ }),
+ lldb::eAccessPublic, 0);
+
+ ast->AddFieldToRecordType(
+ union_type, "_poll",
+ ast->CreateStructForIdentifier(ConstString(),
+ {
+ {"_band", long_type},
+ }),
+ lldb::eAccessPublic, 0);
+
+ ast->CompleteTagDeclarationDefinition(union_type);
+ ast->AddFieldToRecordType(siginfo_type, "_reason", union_type,
+ lldb::eAccessPublic, 0);
+
+ ast->CompleteTagDeclarationDefinition(siginfo_type);
+ return siginfo_type;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h b/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
index fd37b13de017..7f9dfd87a59a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
@@ -10,6 +10,7 @@
#define LLDB_SOURCE_PLUGINS_PLATFORM_FREEBSD_PLATFORMFREEBSD_H
#include "Plugins/Platform/POSIX/PlatformPOSIX.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
namespace lldb_private {
namespace platform_freebsd {
@@ -53,7 +54,12 @@ public:
unsigned flags, lldb::addr_t fd,
lldb::addr_t offset) override;
+ CompilerType GetSiginfoType(const llvm::Triple &triple) override;
+
std::vector<ArchSpec> m_supported_architectures;
+
+private:
+ std::unique_ptr<TypeSystemClang> m_type_system_up;
};
} // namespace platform_freebsd
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
index 552b3890615c..ddba64bc5d11 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
@@ -202,3 +202,144 @@ MmapArgList PlatformNetBSD::GetMmapArgumentList(const ArchSpec &arch,
MmapArgList args({addr, length, prot, flags_platform, fd, offset});
return args;
}
+
+CompilerType PlatformNetBSD::GetSiginfoType(const llvm::Triple &triple) {
+ if (!m_type_system_up)
+ m_type_system_up.reset(new TypeSystemClang("siginfo", triple));
+ TypeSystemClang *ast = m_type_system_up.get();
+
+ // generic types
+ CompilerType int_type = ast->GetBasicType(eBasicTypeInt);
+ CompilerType uint_type = ast->GetBasicType(eBasicTypeUnsignedInt);
+ CompilerType long_type = ast->GetBasicType(eBasicTypeLong);
+ CompilerType long_long_type = ast->GetBasicType(eBasicTypeLongLong);
+ CompilerType voidp_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType();
+
+ // platform-specific types
+ CompilerType &pid_type = int_type;
+ CompilerType &uid_type = uint_type;
+ CompilerType &clock_type = uint_type;
+ CompilerType &lwpid_type = int_type;
+
+ CompilerType sigval_type = ast->CreateRecordType(
+ nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_sigval_t",
+ clang::TTK_Union, lldb::eLanguageTypeC);
+ ast->StartTagDeclarationDefinition(sigval_type);
+ ast->AddFieldToRecordType(sigval_type, "sival_int", int_type,
+ lldb::eAccessPublic, 0);
+ ast->AddFieldToRecordType(sigval_type, "sival_ptr", voidp_type,
+ lldb::eAccessPublic, 0);
+ ast->CompleteTagDeclarationDefinition(sigval_type);
+
+ CompilerType ptrace_option_type = ast->CreateRecordType(
+ nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "",
+ clang::TTK_Union, lldb::eLanguageTypeC);
+ ast->StartTagDeclarationDefinition(ptrace_option_type);
+ ast->AddFieldToRecordType(ptrace_option_type, "_pe_other_pid", pid_type,
+ lldb::eAccessPublic, 0);
+ ast->AddFieldToRecordType(ptrace_option_type, "_pe_lwp", lwpid_type,
+ lldb::eAccessPublic, 0);
+ ast->CompleteTagDeclarationDefinition(ptrace_option_type);
+
+ // siginfo_t
+ CompilerType siginfo_type = ast->CreateRecordType(
+ nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_siginfo_t",
+ clang::TTK_Union, lldb::eLanguageTypeC);
+ ast->StartTagDeclarationDefinition(siginfo_type);
+
+ // struct _ksiginfo
+ CompilerType ksiginfo_type = ast->CreateRecordType(
+ nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "",
+ clang::TTK_Struct, lldb::eLanguageTypeC);
+ ast->StartTagDeclarationDefinition(ksiginfo_type);
+ ast->AddFieldToRecordType(ksiginfo_type, "_signo", int_type,
+ lldb::eAccessPublic, 0);
+ ast->AddFieldToRecordType(ksiginfo_type, "_code", int_type,
+ lldb::eAccessPublic, 0);
+ ast->AddFieldToRecordType(ksiginfo_type, "_errno", int_type,
+ lldb::eAccessPublic, 0);
+
+ // the structure is padded on 64-bit arches to fix alignment
+ if (triple.isArch64Bit())
+ ast->AddFieldToRecordType(ksiginfo_type, "__pad0", int_type,
+ lldb::eAccessPublic, 0);
+
+ // union used to hold the signal data
+ CompilerType union_type = ast->CreateRecordType(
+ nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "",
+ clang::TTK_Union, lldb::eLanguageTypeC);
+ ast->StartTagDeclarationDefinition(union_type);
+
+ ast->AddFieldToRecordType(
+ union_type, "_rt",
+ ast->CreateStructForIdentifier(ConstString(),
+ {
+ {"_pid", pid_type},
+ {"_uid", uid_type},
+ {"_value", sigval_type},
+ }),
+ lldb::eAccessPublic, 0);
+
+ ast->AddFieldToRecordType(
+ union_type, "_child",
+ ast->CreateStructForIdentifier(ConstString(),
+ {
+ {"_pid", pid_type},
+ {"_uid", uid_type},
+ {"_status", int_type},
+ {"_utime", clock_type},
+ {"_stime", clock_type},
+ }),
+ lldb::eAccessPublic, 0);
+
+ ast->AddFieldToRecordType(
+ union_type, "_fault",
+ ast->CreateStructForIdentifier(ConstString(),
+ {
+ {"_addr", voidp_type},
+ {"_trap", int_type},
+ {"_trap2", int_type},
+ {"_trap3", int_type},
+ }),
+ lldb::eAccessPublic, 0);
+
+ ast->AddFieldToRecordType(
+ union_type, "_poll",
+ ast->CreateStructForIdentifier(ConstString(),
+ {
+ {"_band", long_type},
+ {"_fd", int_type},
+ }),
+ lldb::eAccessPublic, 0);
+
+ ast->AddFieldToRecordType(union_type, "_syscall",
+ ast->CreateStructForIdentifier(
+ ConstString(),
+ {
+ {"_sysnum", int_type},
+ {"_retval", int_type.GetArrayType(2)},
+ {"_error", int_type},
+ {"_args", long_long_type.GetArrayType(8)},
+ }),
+ lldb::eAccessPublic, 0);
+
+ ast->AddFieldToRecordType(
+ union_type, "_ptrace_state",
+ ast->CreateStructForIdentifier(ConstString(),
+ {
+ {"_pe_report_event", int_type},
+ {"_option", ptrace_option_type},
+ }),
+ lldb::eAccessPublic, 0);
+
+ ast->CompleteTagDeclarationDefinition(union_type);
+ ast->AddFieldToRecordType(ksiginfo_type, "_reason", union_type,
+ lldb::eAccessPublic, 0);
+
+ ast->CompleteTagDeclarationDefinition(ksiginfo_type);
+ ast->AddFieldToRecordType(siginfo_type, "_info", ksiginfo_type,
+ lldb::eAccessPublic, 0);
+
+ ast->CompleteTagDeclarationDefinition(siginfo_type);
+ return siginfo_type;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h b/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
index 7158fbd26efb..433cf6653126 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
@@ -10,6 +10,7 @@
#define LLDB_SOURCE_PLUGINS_PLATFORM_NETBSD_PLATFORMNETBSD_H
#include "Plugins/Platform/POSIX/PlatformPOSIX.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
namespace lldb_private {
namespace platform_netbsd {
@@ -55,7 +56,12 @@ public:
unsigned flags, lldb::addr_t fd,
lldb::addr_t offset) override;
+ CompilerType GetSiginfoType(const llvm::Triple &triple) override;
+
std::vector<ArchSpec> m_supported_architectures;
+
+private:
+ std::unique_ptr<TypeSystemClang> m_type_system_up;
};
} // namespace platform_netbsd
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp
index 67c9484680a4..dd7546d8fa15 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp
@@ -162,7 +162,10 @@ lldb::ProcessSP PlatformQemuUser::DebugProcess(ProcessLaunchInfo &launch_info,
Target &target, Status &error) {
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- std::string qemu = GetGlobalProperties().GetEmulatorPath().GetPath();
+ FileSpec qemu = GetGlobalProperties().GetEmulatorPath();
+ if (!qemu)
+ qemu.SetPath(("qemu-" + GetGlobalProperties().GetArchitecture()).str());
+ FileSystem::Instance().ResolveExecutableLocation(qemu);
llvm::SmallString<0> socket_model, socket_path;
HostInfo::GetProcessTempDir().GetPath(socket_model);
@@ -171,7 +174,11 @@ lldb::ProcessSP PlatformQemuUser::DebugProcess(ProcessLaunchInfo &launch_info,
llvm::sys::fs::createUniquePath(socket_model, socket_path, false);
} while (FileSystem::Instance().Exists(socket_path));
- Args args({qemu, "-g", socket_path});
+ Args args({qemu.GetPath(), "-g", socket_path});
+ if (!launch_info.GetArg0().empty()) {
+ args.AppendArgument("-0");
+ args.AppendArgument(launch_info.GetArg0());
+ }
args.AppendArguments(GetGlobalProperties().GetEmulatorArgs());
args.AppendArgument("--");
args.AppendArgument(launch_info.GetExecutableFile().GetPath());
@@ -184,6 +191,8 @@ lldb::ProcessSP PlatformQemuUser::DebugProcess(ProcessLaunchInfo &launch_info,
launch_info.SetArguments(args, true);
Environment emulator_env = Host::GetEnvironment();
+ if (ConstString sysroot = GetSDKRootDirectory())
+ emulator_env["QEMU_LD_PREFIX"] = sysroot.GetStringRef().str();
for (const auto &KV : GetGlobalProperties().GetEmulatorEnvVars())
emulator_env[KV.first()] = KV.second;
launch_info.GetEnvironment() = ComputeLaunchEnvironment(
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h b/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h
index 71df1b7b7811..c5439e126db1 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h
@@ -47,6 +47,14 @@ public:
Environment GetEnvironment() override;
+ MmapArgList GetMmapArgumentList(const ArchSpec &arch, lldb::addr_t addr,
+ lldb::addr_t length, unsigned prot,
+ unsigned flags, lldb::addr_t fd,
+ lldb::addr_t offset) override {
+ return Platform::GetHostPlatform()->GetMmapArgumentList(
+ arch, addr, length, prot, flags, fd, offset);
+ }
+
private:
static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
static void DebuggerInitialize(Debugger &debugger);
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td b/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td
index 4e8fbcfd6760..c7ec4bbc6e78 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td
@@ -8,7 +8,7 @@ let Definition = "platformqemuuser" in {
def EmulatorPath: Property<"emulator-path", "FileSpec">,
Global,
DefaultStringValue<"">,
- Desc<"Path to the emulator binary.">;
+ Desc<"Path to the emulator binary. If the path does not contain a directory separator, the filename is looked up in the PATH environment variable. If empty, the filename is derived from the architecture setting.">;
def EmulatorArgs: Property<"emulator-args", "Args">,
Global,
DefaultStringValue<"">,
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 3535a5ad739d..0929a060d0b8 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -96,7 +96,8 @@ bool PlatformRemoteGDBServer::GetModuleSpec(const FileSpec &module_file_spec,
const auto module_path = module_file_spec.GetPath(false);
- if (!m_gdb_client.GetModuleInfo(module_file_spec, arch, module_spec)) {
+ if (!m_gdb_client_up ||
+ !m_gdb_client_up->GetModuleInfo(module_file_spec, arch, module_spec)) {
LLDB_LOGF(
log,
"PlatformRemoteGDBServer::%s - failed to get module info for %s:%s",
@@ -127,11 +128,7 @@ Status PlatformRemoteGDBServer::GetFileWithUUID(const FileSpec &platform_file,
/// Default Constructor
PlatformRemoteGDBServer::PlatformRemoteGDBServer()
- : Platform(false), // This is a remote platform
- m_gdb_client() {
- m_gdb_client.SetPacketTimeout(
- process_gdb_remote::ProcessGDBRemote::GetPacketTimeout());
-}
+ : Platform(/*is_host=*/false) {}
/// Destructor.
///
@@ -147,29 +144,36 @@ size_t PlatformRemoteGDBServer::GetSoftwareBreakpointTrapOpcode(
}
bool PlatformRemoteGDBServer::GetRemoteOSVersion() {
- m_os_version = m_gdb_client.GetOSVersion();
+ if (m_gdb_client_up)
+ m_os_version = m_gdb_client_up->GetOSVersion();
return !m_os_version.empty();
}
llvm::Optional<std::string> PlatformRemoteGDBServer::GetRemoteOSBuildString() {
- return m_gdb_client.GetOSBuildString();
+ if (!m_gdb_client_up)
+ return llvm::None;
+ return m_gdb_client_up->GetOSBuildString();
}
llvm::Optional<std::string>
PlatformRemoteGDBServer::GetRemoteOSKernelDescription() {
- return m_gdb_client.GetOSKernelDescription();
+ if (!m_gdb_client_up)
+ return llvm::None;
+ return m_gdb_client_up->GetOSKernelDescription();
}
// Remote Platform subclasses need to override this function
ArchSpec PlatformRemoteGDBServer::GetRemoteSystemArchitecture() {
- return m_gdb_client.GetSystemArchitecture();
+ if (!m_gdb_client_up)
+ return ArchSpec();
+ return m_gdb_client_up->GetSystemArchitecture();
}
FileSpec PlatformRemoteGDBServer::GetRemoteWorkingDirectory() {
if (IsConnected()) {
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
FileSpec working_dir;
- if (m_gdb_client.GetWorkingDir(working_dir) && log)
+ if (m_gdb_client_up->GetWorkingDir(working_dir) && log)
LLDB_LOGF(log,
"PlatformRemoteGDBServer::GetRemoteWorkingDirectory() -> '%s'",
working_dir.GetCString());
@@ -187,13 +191,17 @@ bool PlatformRemoteGDBServer::SetRemoteWorkingDirectory(
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
LLDB_LOGF(log, "PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')",
working_dir.GetCString());
- return m_gdb_client.SetWorkingDir(working_dir) == 0;
+ return m_gdb_client_up->SetWorkingDir(working_dir) == 0;
} else
return Platform::SetRemoteWorkingDirectory(working_dir);
}
bool PlatformRemoteGDBServer::IsConnected() const {
- return m_gdb_client.IsConnected();
+ if (m_gdb_client_up) {
+ assert(m_gdb_client_up->IsConnected());
+ return true;
+ }
+ return false;
}
Status PlatformRemoteGDBServer::ConnectRemote(Args &args) {
@@ -224,26 +232,31 @@ Status PlatformRemoteGDBServer::ConnectRemote(Args &args) {
m_platform_scheme = parsed_url->scheme.str();
m_platform_hostname = parsed_url->hostname.str();
- m_gdb_client.SetConnection(std::make_unique<ConnectionFileDescriptor>());
+ auto client_up =
+ std::make_unique<process_gdb_remote::GDBRemoteCommunicationClient>();
+ client_up->SetPacketTimeout(
+ process_gdb_remote::ProcessGDBRemote::GetPacketTimeout());
+ client_up->SetConnection(std::make_unique<ConnectionFileDescriptor>());
if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
repro::GDBRemoteProvider &provider =
g->GetOrCreate<repro::GDBRemoteProvider>();
- m_gdb_client.SetPacketRecorder(provider.GetNewPacketRecorder());
+ client_up->SetPacketRecorder(provider.GetNewPacketRecorder());
}
- m_gdb_client.Connect(url, &error);
+ client_up->Connect(url, &error);
if (error.Fail())
return error;
- if (m_gdb_client.HandshakeWithServer(&error)) {
- m_gdb_client.GetHostInfo();
+ if (client_up->HandshakeWithServer(&error)) {
+ m_gdb_client_up = std::move(client_up);
+ m_gdb_client_up->GetHostInfo();
// If a working directory was set prior to connecting, send it down
// now.
if (m_working_dir)
- m_gdb_client.SetWorkingDir(m_working_dir);
+ m_gdb_client_up->SetWorkingDir(m_working_dir);
m_supported_architectures.clear();
- ArchSpec remote_arch = m_gdb_client.GetSystemArchitecture();
+ ArchSpec remote_arch = m_gdb_client_up->GetSystemArchitecture();
if (remote_arch) {
m_supported_architectures.push_back(remote_arch);
if (remote_arch.GetTriple().isArch64Bit())
@@ -251,7 +264,7 @@ Status PlatformRemoteGDBServer::ConnectRemote(Args &args) {
ArchSpec(remote_arch.GetTriple().get32BitArchVariant()));
}
} else {
- m_gdb_client.Disconnect();
+ client_up->Disconnect();
if (error.Success())
error.SetErrorString("handshake failed");
}
@@ -260,13 +273,14 @@ Status PlatformRemoteGDBServer::ConnectRemote(Args &args) {
Status PlatformRemoteGDBServer::DisconnectRemote() {
Status error;
- m_gdb_client.Disconnect(&error);
+ m_gdb_client_up.reset();
m_remote_signals_sp.reset();
return error;
}
const char *PlatformRemoteGDBServer::GetHostname() {
- m_gdb_client.GetHostname(m_name);
+ if (m_gdb_client_up)
+ m_gdb_client_up->GetHostname(m_name);
if (m_name.empty())
return nullptr;
return m_name.c_str();
@@ -275,7 +289,7 @@ const char *PlatformRemoteGDBServer::GetHostname() {
llvm::Optional<std::string>
PlatformRemoteGDBServer::DoGetUserName(UserIDResolver::id_t uid) {
std::string name;
- if (m_gdb_client.GetUserName(uid, name))
+ if (m_gdb_client_up && m_gdb_client_up->GetUserName(uid, name))
return std::move(name);
return llvm::None;
}
@@ -283,7 +297,7 @@ PlatformRemoteGDBServer::DoGetUserName(UserIDResolver::id_t uid) {
llvm::Optional<std::string>
PlatformRemoteGDBServer::DoGetGroupName(UserIDResolver::id_t gid) {
std::string name;
- if (m_gdb_client.GetGroupName(gid, name))
+ if (m_gdb_client_up && m_gdb_client_up->GetGroupName(gid, name))
return std::move(name);
return llvm::None;
}
@@ -291,12 +305,16 @@ PlatformRemoteGDBServer::DoGetGroupName(UserIDResolver::id_t gid) {
uint32_t PlatformRemoteGDBServer::FindProcesses(
const ProcessInstanceInfoMatch &match_info,
ProcessInstanceInfoList &process_infos) {
- return m_gdb_client.FindProcesses(match_info, process_infos);
+ if (m_gdb_client_up)
+ return m_gdb_client_up->FindProcesses(match_info, process_infos);
+ return 0;
}
bool PlatformRemoteGDBServer::GetProcessInfo(
lldb::pid_t pid, ProcessInstanceInfo &process_info) {
- return m_gdb_client.GetProcessInfo(pid, process_info);
+ if (m_gdb_client_up)
+ return m_gdb_client_up->GetProcessInfo(pid, process_info);
+ return false;
}
Status PlatformRemoteGDBServer::LaunchProcess(ProcessLaunchInfo &launch_info) {
@@ -305,6 +323,8 @@ Status PlatformRemoteGDBServer::LaunchProcess(ProcessLaunchInfo &launch_info) {
LLDB_LOGF(log, "PlatformRemoteGDBServer::%s() called", __FUNCTION__);
+ if (!IsConnected())
+ return Status("Not connected.");
auto num_file_actions = launch_info.GetNumFileActions();
for (decltype(num_file_actions) i = 0; i < num_file_actions; ++i) {
const auto file_action = launch_info.GetFileActionAtIndex(i);
@@ -312,34 +332,34 @@ Status PlatformRemoteGDBServer::LaunchProcess(ProcessLaunchInfo &launch_info) {
continue;
switch (file_action->GetFD()) {
case STDIN_FILENO:
- m_gdb_client.SetSTDIN(file_action->GetFileSpec());
+ m_gdb_client_up->SetSTDIN(file_action->GetFileSpec());
break;
case STDOUT_FILENO:
- m_gdb_client.SetSTDOUT(file_action->GetFileSpec());
+ m_gdb_client_up->SetSTDOUT(file_action->GetFileSpec());
break;
case STDERR_FILENO:
- m_gdb_client.SetSTDERR(file_action->GetFileSpec());
+ m_gdb_client_up->SetSTDERR(file_action->GetFileSpec());
break;
}
}
- m_gdb_client.SetDisableASLR(
+ m_gdb_client_up->SetDisableASLR(
launch_info.GetFlags().Test(eLaunchFlagDisableASLR));
- m_gdb_client.SetDetachOnError(
+ m_gdb_client_up->SetDetachOnError(
launch_info.GetFlags().Test(eLaunchFlagDetachOnError));
FileSpec working_dir = launch_info.GetWorkingDirectory();
if (working_dir) {
- m_gdb_client.SetWorkingDir(working_dir);
+ m_gdb_client_up->SetWorkingDir(working_dir);
}
// Send the environment and the program + arguments after we connect
- m_gdb_client.SendEnvironment(launch_info.GetEnvironment());
+ m_gdb_client_up->SendEnvironment(launch_info.GetEnvironment());
ArchSpec arch_spec = launch_info.GetArchitecture();
const char *arch_triple = arch_spec.GetTriple().str().c_str();
- m_gdb_client.SendLaunchArchPacket(arch_triple);
+ m_gdb_client_up->SendLaunchArchPacket(arch_triple);
LLDB_LOGF(
log,
"PlatformRemoteGDBServer::%s() set launch architecture triple to '%s'",
@@ -349,14 +369,14 @@ Status PlatformRemoteGDBServer::LaunchProcess(ProcessLaunchInfo &launch_info) {
{
// Scope for the scoped timeout object
process_gdb_remote::GDBRemoteCommunication::ScopedTimeout timeout(
- m_gdb_client, std::chrono::seconds(5));
- arg_packet_err = m_gdb_client.SendArgumentsPacket(launch_info);
+ *m_gdb_client_up, std::chrono::seconds(5));
+ arg_packet_err = m_gdb_client_up->SendArgumentsPacket(launch_info);
}
if (arg_packet_err == 0) {
std::string error_str;
- if (m_gdb_client.GetLaunchSuccess(error_str)) {
- const auto pid = m_gdb_client.GetCurrentProcessID(false);
+ if (m_gdb_client_up->GetLaunchSuccess(error_str)) {
+ const auto pid = m_gdb_client_up->GetCurrentProcessID(false);
if (pid != LLDB_INVALID_PROCESS_ID) {
launch_info.SetProcessID(pid);
LLDB_LOGF(log,
@@ -428,6 +448,8 @@ PlatformRemoteGDBServer::DebugProcess(ProcessLaunchInfo &launch_info,
bool PlatformRemoteGDBServer::LaunchGDBServer(lldb::pid_t &pid,
std::string &connect_url) {
+ assert(IsConnected());
+
ArchSpec remote_arch = GetRemoteSystemArchitecture();
llvm::Triple &remote_triple = remote_arch.GetTriple();
@@ -440,11 +462,11 @@ bool PlatformRemoteGDBServer::LaunchGDBServer(lldb::pid_t &pid,
// localhost, so we will need the remote debugserver to accept connections
// only from localhost, no matter what our current hostname is
launch_result =
- m_gdb_client.LaunchGDBServer("127.0.0.1", pid, port, socket_name);
+ m_gdb_client_up->LaunchGDBServer("127.0.0.1", pid, port, socket_name);
} else {
// All other hosts should use their actual hostname
launch_result =
- m_gdb_client.LaunchGDBServer(nullptr, pid, port, socket_name);
+ m_gdb_client_up->LaunchGDBServer(nullptr, pid, port, socket_name);
}
if (!launch_result)
@@ -457,7 +479,8 @@ bool PlatformRemoteGDBServer::LaunchGDBServer(lldb::pid_t &pid,
}
bool PlatformRemoteGDBServer::KillSpawnedProcess(lldb::pid_t pid) {
- return m_gdb_client.KillSpawnedProcess(pid);
+ assert(IsConnected());
+ return m_gdb_client_up->KillSpawnedProcess(pid);
}
lldb::ProcessSP PlatformRemoteGDBServer::Attach(
@@ -513,7 +536,9 @@ lldb::ProcessSP PlatformRemoteGDBServer::Attach(
Status PlatformRemoteGDBServer::MakeDirectory(const FileSpec &file_spec,
uint32_t mode) {
- Status error = m_gdb_client.MakeDirectory(file_spec, mode);
+ if (!IsConnected())
+ return Status("Not connected.");
+ Status error = m_gdb_client_up->MakeDirectory(file_spec, mode);
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
LLDB_LOGF(log,
"PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) "
@@ -524,7 +549,10 @@ Status PlatformRemoteGDBServer::MakeDirectory(const FileSpec &file_spec,
Status PlatformRemoteGDBServer::GetFilePermissions(const FileSpec &file_spec,
uint32_t &file_permissions) {
- Status error = m_gdb_client.GetFilePermissions(file_spec, file_permissions);
+ if (!IsConnected())
+ return Status("Not connected.");
+ Status error =
+ m_gdb_client_up->GetFilePermissions(file_spec, file_permissions);
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
LLDB_LOGF(log,
"PlatformRemoteGDBServer::GetFilePermissions(path='%s', "
@@ -536,7 +564,10 @@ Status PlatformRemoteGDBServer::GetFilePermissions(const FileSpec &file_spec,
Status PlatformRemoteGDBServer::SetFilePermissions(const FileSpec &file_spec,
uint32_t file_permissions) {
- Status error = m_gdb_client.SetFilePermissions(file_spec, file_permissions);
+ if (!IsConnected())
+ return Status("Not connected.");
+ Status error =
+ m_gdb_client_up->SetFilePermissions(file_spec, file_permissions);
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
LLDB_LOGF(log,
"PlatformRemoteGDBServer::SetFilePermissions(path='%s', "
@@ -550,33 +581,47 @@ lldb::user_id_t PlatformRemoteGDBServer::OpenFile(const FileSpec &file_spec,
File::OpenOptions flags,
uint32_t mode,
Status &error) {
- return m_gdb_client.OpenFile(file_spec, flags, mode, error);
+ if (IsConnected())
+ return m_gdb_client_up->OpenFile(file_spec, flags, mode, error);
+ return LLDB_INVALID_UID;
}
bool PlatformRemoteGDBServer::CloseFile(lldb::user_id_t fd, Status &error) {
- return m_gdb_client.CloseFile(fd, error);
+ if (IsConnected())
+ return m_gdb_client_up->CloseFile(fd, error);
+ error = Status("Not connected.");
+ return false;
}
lldb::user_id_t
PlatformRemoteGDBServer::GetFileSize(const FileSpec &file_spec) {
- return m_gdb_client.GetFileSize(file_spec);
+ if (IsConnected())
+ return m_gdb_client_up->GetFileSize(file_spec);
+ return LLDB_INVALID_UID;
}
void PlatformRemoteGDBServer::AutoCompleteDiskFileOrDirectory(
CompletionRequest &request, bool only_dir) {
- m_gdb_client.AutoCompleteDiskFileOrDirectory(request, only_dir);
+ if (IsConnected())
+ m_gdb_client_up->AutoCompleteDiskFileOrDirectory(request, only_dir);
}
uint64_t PlatformRemoteGDBServer::ReadFile(lldb::user_id_t fd, uint64_t offset,
void *dst, uint64_t dst_len,
Status &error) {
- return m_gdb_client.ReadFile(fd, offset, dst, dst_len, error);
+ if (IsConnected())
+ return m_gdb_client_up->ReadFile(fd, offset, dst, dst_len, error);
+ error = Status("Not connected.");
+ return 0;
}
uint64_t PlatformRemoteGDBServer::WriteFile(lldb::user_id_t fd, uint64_t offset,
const void *src, uint64_t src_len,
Status &error) {
- return m_gdb_client.WriteFile(fd, offset, src, src_len, error);
+ if (IsConnected())
+ return m_gdb_client_up->WriteFile(fd, offset, src, src_len, error);
+ error = Status("Not connected.");
+ return 0;
}
Status PlatformRemoteGDBServer::PutFile(const FileSpec &source,
@@ -589,7 +634,9 @@ Status PlatformRemoteGDBServer::CreateSymlink(
const FileSpec &src, // The name of the link is in src
const FileSpec &dst) // The symlink points to dst
{
- Status error = m_gdb_client.CreateSymlink(src, dst);
+ if (!IsConnected())
+ return Status("Not connected.");
+ Status error = m_gdb_client_up->CreateSymlink(src, dst);
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
LLDB_LOGF(log,
"PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') "
@@ -600,7 +647,9 @@ Status PlatformRemoteGDBServer::CreateSymlink(
}
Status PlatformRemoteGDBServer::Unlink(const FileSpec &file_spec) {
- Status error = m_gdb_client.Unlink(file_spec);
+ if (!IsConnected())
+ return Status("Not connected.");
+ Status error = m_gdb_client_up->Unlink(file_spec);
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
LLDB_LOGF(log, "PlatformRemoteGDBServer::Unlink(path='%s') error = %u (%s)",
file_spec.GetCString(), error.GetError(), error.AsCString());
@@ -608,7 +657,9 @@ Status PlatformRemoteGDBServer::Unlink(const FileSpec &file_spec) {
}
bool PlatformRemoteGDBServer::GetFileExists(const FileSpec &file_spec) {
- return m_gdb_client.GetFileExists(file_spec);
+ if (IsConnected())
+ return m_gdb_client_up->GetFileExists(file_spec);
+ return false;
}
Status PlatformRemoteGDBServer::RunShellCommand(
@@ -621,8 +672,10 @@ Status PlatformRemoteGDBServer::RunShellCommand(
std::string
*command_output, // Pass NULL if you don't want the command output
const Timeout<std::micro> &timeout) {
- return m_gdb_client.RunShellCommand(command, working_dir, status_ptr,
- signo_ptr, command_output, timeout);
+ if (!IsConnected())
+ return Status("Not connected.");
+ return m_gdb_client_up->RunShellCommand(command, working_dir, status_ptr,
+ signo_ptr, command_output, timeout);
}
void PlatformRemoteGDBServer::CalculateTrapHandlerSymbolNames() {
@@ -642,7 +695,7 @@ const UnixSignalsSP &PlatformRemoteGDBServer::GetRemoteUnixSignals() {
StringExtractorGDBRemote response;
auto result =
- m_gdb_client.SendPacketAndWaitForResponse("jSignalsInfo", response);
+ m_gdb_client_up->SendPacketAndWaitForResponse("jSignalsInfo", response);
if (result != decltype(result)::Success ||
response.GetResponseType() != response.eResponse)
@@ -693,7 +746,7 @@ const UnixSignalsSP &PlatformRemoteGDBServer::GetRemoteUnixSignals() {
if (object_sp && object_sp->IsValid())
notify = object_sp->GetBooleanValue();
- std::string description{""};
+ std::string description;
object_sp = dict->GetValueForKey("description");
if (object_sp && object_sp->IsValid())
description = std::string(object_sp->GetStringValue());
@@ -754,7 +807,9 @@ size_t PlatformRemoteGDBServer::ConnectToWaitingProcesses(Debugger &debugger,
size_t PlatformRemoteGDBServer::GetPendingGdbServerList(
std::vector<std::string> &connection_urls) {
std::vector<std::pair<uint16_t, std::string>> remote_servers;
- m_gdb_client.QueryGDBServer(remote_servers);
+ if (!IsConnected())
+ return 0;
+ m_gdb_client_up->QueryGDBServer(remote_servers);
for (const auto &gdbserver : remote_servers) {
const char *socket_name_cstr =
gdbserver.second.empty() ? nullptr : gdbserver.second.c_str();
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
index f594f43b3f13..263516f520d5 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -14,7 +14,6 @@
#include "Plugins/Process/Utility/GDBRemoteSignals.h"
#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h"
-#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h"
#include "lldb/Target/Platform.h"
namespace lldb_private {
@@ -154,8 +153,8 @@ public:
GetPendingGdbServerList(std::vector<std::string> &connection_urls);
protected:
- process_gdb_remote::GDBRemoteCommunicationClient m_gdb_client;
- process_gdb_remote::GDBRemoteCommunicationReplayServer m_gdb_replay_server;
+ std::unique_ptr<process_gdb_remote::GDBRemoteCommunicationClient>
+ m_gdb_client_up;
std::string m_platform_description; // After we connect we can get a more
// complete description of what we are
// connected to
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
index a62d3c1ba052..21c9ead0eca4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
@@ -54,7 +54,7 @@ llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
NativeProcessFreeBSD::Factory::Launch(ProcessLaunchInfo &launch_info,
NativeDelegate &native_delegate,
MainLoop &mainloop) const {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ Log *log = GetLog(POSIXLog::Process);
Status status;
::pid_t pid = ProcessLauncherPosixFork()
@@ -108,7 +108,7 @@ llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
NativeProcessFreeBSD::Factory::Attach(
lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
MainLoop &mainloop) const {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ Log *log = GetLog(POSIXLog::Process);
LLDB_LOG(log, "pid = {0:x}", pid);
// Retrieve the architecture for the running process.
@@ -135,7 +135,8 @@ NativeProcessFreeBSD::Factory::GetSupportedExtensions() const {
Extension::savecore |
#endif
Extension::multiprocess | Extension::fork | Extension::vfork |
- Extension::pass_signals | Extension::auxv | Extension::libraries_svr4;
+ Extension::pass_signals | Extension::auxv | Extension::libraries_svr4 |
+ Extension::siginfo_read;
}
// Public Instance Methods
@@ -170,7 +171,7 @@ void NativeProcessFreeBSD::MonitorCallback(lldb::pid_t pid, int signal) {
}
void NativeProcessFreeBSD::MonitorExited(lldb::pid_t pid, WaitStatus status) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ Log *log = GetLog(POSIXLog::Process);
LLDB_LOG(log, "got exit signal({0}) , pid = {1}", status, pid);
@@ -193,7 +194,7 @@ void NativeProcessFreeBSD::MonitorSIGSTOP(lldb::pid_t pid) {
}
void NativeProcessFreeBSD::MonitorSIGTRAP(lldb::pid_t pid) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ Log *log = GetLog(POSIXLog::Process);
struct ptrace_lwpinfo info;
const auto siginfo_err = PtraceWrapper(PT_LWPINFO, pid, &info, sizeof(info));
@@ -254,6 +255,7 @@ void NativeProcessFreeBSD::MonitorSIGTRAP(lldb::pid_t pid) {
for (const auto &thread : m_threads)
static_cast<NativeThreadFreeBSD &>(*thread).SetStoppedByExec();
+ SetCurrentThreadID(m_threads.front()->GetID());
SetState(StateType::eStateStopped, true);
return;
}
@@ -312,6 +314,7 @@ void NativeProcessFreeBSD::MonitorSIGTRAP(lldb::pid_t pid) {
} else
thread->SetStoppedByBreakpoint();
FixupBreakpointPCAsNeeded(*thread);
+ SetCurrentThreadID(thread->GetID());
}
SetState(StateType::eStateStopped, true);
return;
@@ -333,11 +336,13 @@ void NativeProcessFreeBSD::MonitorSIGTRAP(lldb::pid_t pid) {
if (wp_index != LLDB_INVALID_INDEX32) {
regctx.ClearWatchpointHit(wp_index);
thread->SetStoppedByWatchpoint(wp_index);
+ SetCurrentThreadID(thread->GetID());
SetState(StateType::eStateStopped, true);
break;
}
thread->SetStoppedByTrace();
+ SetCurrentThreadID(thread->GetID());
}
SetState(StateType::eStateStopped, true);
@@ -352,7 +357,7 @@ void NativeProcessFreeBSD::MonitorSIGTRAP(lldb::pid_t pid) {
}
void NativeProcessFreeBSD::MonitorSignal(lldb::pid_t pid, int signal) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ Log *log = GetLog(POSIXLog::Process);
struct ptrace_lwpinfo info;
const auto siginfo_err = PtraceWrapper(PT_LWPINFO, pid, &info, sizeof(info));
@@ -370,9 +375,10 @@ void NativeProcessFreeBSD::MonitorSignal(lldb::pid_t pid, int signal) {
static_cast<NativeThreadFreeBSD &>(*abs_thread);
assert(info.pl_lwpid >= 0);
if (info.pl_lwpid == 0 ||
- static_cast<lldb::tid_t>(info.pl_lwpid) == thread.GetID())
+ static_cast<lldb::tid_t>(info.pl_lwpid) == thread.GetID()) {
thread.SetStoppedBySignal(info.pl_siginfo.si_signo, &info.pl_siginfo);
- else
+ SetCurrentThreadID(thread.GetID());
+ } else
thread.SetStoppedWithNoReason();
}
SetState(StateType::eStateStopped, true);
@@ -380,7 +386,7 @@ void NativeProcessFreeBSD::MonitorSignal(lldb::pid_t pid, int signal) {
Status NativeProcessFreeBSD::PtraceWrapper(int req, lldb::pid_t pid, void *addr,
int data, int *result) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
+ Log *log = GetLog(POSIXLog::Ptrace);
Status error;
int ret;
@@ -424,7 +430,7 @@ NativeProcessFreeBSD::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
}
Status NativeProcessFreeBSD::Resume(const ResumeActionList &resume_actions) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ Log *log = GetLog(POSIXLog::Process);
LLDB_LOG(log, "pid {0}", GetID());
Status ret;
@@ -521,7 +527,7 @@ Status NativeProcessFreeBSD::Signal(int signo) {
Status NativeProcessFreeBSD::Interrupt() { return Halt(); }
Status NativeProcessFreeBSD::Kill() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ Log *log = GetLog(POSIXLog::Process);
LLDB_LOG(log, "pid {0}", GetID());
Status error;
@@ -608,7 +614,7 @@ Status NativeProcessFreeBSD::GetMemoryRegionInfo(lldb::addr_t load_addr,
}
Status NativeProcessFreeBSD::PopulateMemoryRegionCache() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ Log *log = GetLog(POSIXLog::Process);
// If our cache is empty, pull the latest. There should always be at least
// one memory region if memory region handling is supported.
if (!m_mem_region_cache.empty()) {
@@ -735,7 +741,7 @@ NativeProcessFreeBSD::GetFileLoadAddress(const llvm::StringRef &file_name,
}
void NativeProcessFreeBSD::SigchldHandler() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ Log *log = GetLog(POSIXLog::Process);
int status;
::pid_t wait_pid =
llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status, WNOHANG);
@@ -780,7 +786,7 @@ bool NativeProcessFreeBSD::HasThreadNoLock(lldb::tid_t thread_id) {
}
NativeThreadFreeBSD &NativeProcessFreeBSD::AddThread(lldb::tid_t thread_id) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ Log *log = GetLog(POSIXLog::Thread);
LLDB_LOG(log, "pid {0} adding thread with tid {1}", GetID(), thread_id);
assert(thread_id > 0);
@@ -796,7 +802,7 @@ NativeThreadFreeBSD &NativeProcessFreeBSD::AddThread(lldb::tid_t thread_id) {
}
void NativeProcessFreeBSD::RemoveThread(lldb::tid_t thread_id) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ Log *log = GetLog(POSIXLog::Thread);
LLDB_LOG(log, "pid {0} removing thread with tid {1}", GetID(), thread_id);
assert(thread_id > 0);
@@ -809,6 +815,9 @@ void NativeProcessFreeBSD::RemoveThread(lldb::tid_t thread_id) {
break;
}
}
+
+ if (GetCurrentThreadID() == thread_id)
+ SetCurrentThreadID(m_threads.front()->GetID());
}
Status NativeProcessFreeBSD::Attach() {
@@ -845,7 +854,7 @@ Status NativeProcessFreeBSD::ReadMemory(lldb::addr_t addr, void *buf,
unsigned char *dst = static_cast<unsigned char *>(buf);
struct ptrace_io_desc io;
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY));
+ Log *log = GetLog(POSIXLog::Memory);
LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
bytes_read = 0;
@@ -873,7 +882,7 @@ Status NativeProcessFreeBSD::WriteMemory(lldb::addr_t addr, const void *buf,
Status error;
struct ptrace_io_desc io;
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY));
+ Log *log = GetLog(POSIXLog::Memory);
LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
bytes_written = 0;
@@ -953,7 +962,7 @@ bool NativeProcessFreeBSD::SupportHardwareSingleStepping() const {
void NativeProcessFreeBSD::MonitorClone(::pid_t child_pid, bool is_vfork,
NativeThreadFreeBSD &parent_thread) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ Log *log = GetLog(POSIXLog::Process);
LLDB_LOG(log, "fork, child_pid={0}", child_pid);
int status;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
index 4578138a89b3..143d94069bc6 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
@@ -227,7 +227,7 @@ llvm::Error NativeRegisterContextFreeBSD_arm64::CopyHardwareWatchpointsFrom(
llvm::Error NativeRegisterContextFreeBSD_arm64::ReadHardwareDebugInfo() {
#ifdef LLDB_HAS_FREEBSD_WATCHPOINT
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_REGISTERS));
+ Log *log = GetLog(POSIXLog::Registers);
// we're fully stateful, so no need to reread control registers ever
if (m_read_dbreg)
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
index 80b3527aebce..a75668f3b5c7 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
@@ -75,7 +75,7 @@ Status NativeThreadFreeBSD::Suspend() {
void NativeThreadFreeBSD::SetStoppedBySignal(uint32_t signo,
const siginfo_t *info) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ Log *log = GetLog(POSIXLog::Thread);
LLDB_LOG(log, "tid = {0} in called with signal {1}", GetID(), signo);
SetStopped();
@@ -178,7 +178,7 @@ void NativeThreadFreeBSD::SetStepping() {
}
std::string NativeThreadFreeBSD::GetName() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ Log *log = GetLog(POSIXLog::Thread);
std::vector<struct kinfo_proc> kp;
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID | KERN_PROC_INC_THREAD,
@@ -213,7 +213,7 @@ lldb::StateType NativeThreadFreeBSD::GetState() { return m_state; }
bool NativeThreadFreeBSD::GetStopReason(ThreadStopInfo &stop_info,
std::string &description) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ Log *log = GetLog(POSIXLog::Thread);
description.clear();
switch (m_state) {
@@ -313,3 +313,27 @@ NativeThreadFreeBSD::CopyWatchpointsFrom(NativeThreadFreeBSD &source) {
}
return s;
}
+
+llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
+NativeThreadFreeBSD::GetSiginfo() const {
+ Log *log = GetLog(POSIXLog::Process);
+
+ struct ptrace_lwpinfo info;
+ const auto siginfo_err = NativeProcessFreeBSD::PtraceWrapper(
+ PT_LWPINFO, GetID(), &info, sizeof(info));
+ if (siginfo_err.Fail()) {
+ LLDB_LOG(log, "PT_LWPINFO failed {0}", siginfo_err);
+ return siginfo_err.ToError();
+ }
+
+ if (info.pl_event != PL_EVENT_SIGNAL)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Thread not signaled");
+ if (!(info.pl_flags & PL_FLAG_SI))
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "No siginfo for thread");
+
+ return llvm::MemoryBuffer::getMemBufferCopy(
+ llvm::StringRef(reinterpret_cast<const char *>(&info.pl_siginfo),
+ sizeof(info.pl_siginfo)));
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h
index 3ec6daa409e4..6294a7a70963 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h
@@ -47,6 +47,9 @@ public:
Status RemoveHardwareBreakpoint(lldb::addr_t addr) override;
+ llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
+ GetSiginfo() const override;
+
private:
// Interface for friend classes
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
index 339d33d25110..e3707365a9c3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
@@ -137,12 +137,115 @@ bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list,
return false;
}
- const Symbol *pcb_sym =
- GetTarget().GetExecutableModule()->FindFirstSymbolWithNameAndType(
- ConstString("dumppcb"));
- ThreadSP thread_sp(new ThreadFreeBSDKernel(
- *this, 1, pcb_sym ? pcb_sym->GetFileAddress() : LLDB_INVALID_ADDRESS));
- new_thread_list.AddThread(thread_sp);
+ Status error;
+
+ // struct field offsets are written as symbols so that we don't have
+ // to figure them out ourselves
+ int32_t offset_p_list = ReadSignedIntegerFromMemory(
+ FindSymbol("proc_off_p_list"), 4, -1, error);
+ int32_t offset_p_pid =
+ ReadSignedIntegerFromMemory(FindSymbol("proc_off_p_pid"), 4, -1, error);
+ int32_t offset_p_threads = ReadSignedIntegerFromMemory(
+ FindSymbol("proc_off_p_threads"), 4, -1, error);
+ int32_t offset_p_comm = ReadSignedIntegerFromMemory(
+ FindSymbol("proc_off_p_comm"), 4, -1, error);
+
+ int32_t offset_td_tid = ReadSignedIntegerFromMemory(
+ FindSymbol("thread_off_td_tid"), 4, -1, error);
+ int32_t offset_td_plist = ReadSignedIntegerFromMemory(
+ FindSymbol("thread_off_td_plist"), 4, -1, error);
+ int32_t offset_td_pcb = ReadSignedIntegerFromMemory(
+ FindSymbol("thread_off_td_pcb"), 4, -1, error);
+ int32_t offset_td_oncpu = ReadSignedIntegerFromMemory(
+ FindSymbol("thread_off_td_oncpu"), 4, -1, error);
+ int32_t offset_td_name = ReadSignedIntegerFromMemory(
+ FindSymbol("thread_off_td_name"), 4, -1, error);
+
+ // fail if we were not able to read any of the offsets
+ if (offset_p_list == -1 || offset_p_pid == -1 || offset_p_threads == -1 ||
+ offset_p_comm == -1 || offset_td_tid == -1 || offset_td_plist == -1 ||
+ offset_td_pcb == -1 || offset_td_oncpu == -1 || offset_td_name == -1)
+ return false;
+
+ // dumptid contains the thread-id of the crashing thread
+ // dumppcb contains its PCB
+ int32_t dumptid =
+ ReadSignedIntegerFromMemory(FindSymbol("dumptid"), 4, -1, error);
+ lldb::addr_t dumppcb = FindSymbol("dumppcb");
+
+ // stoppcbs is an array of PCBs on all CPUs
+ // each element is of size pcb_size
+ int32_t pcbsize =
+ ReadSignedIntegerFromMemory(FindSymbol("pcb_size"), 4, -1, error);
+ lldb::addr_t stoppcbs = FindSymbol("stoppcbs");
+
+ // from FreeBSD sys/param.h
+ constexpr size_t fbsd_maxcomlen = 19;
+
+ // iterate through a linked list of all processes
+ // allproc is a pointer to the first list element, p_list field
+ // (found at offset_p_list) specifies the next element
+ for (lldb::addr_t proc =
+ ReadPointerFromMemory(FindSymbol("allproc"), error);
+ proc != 0 && proc != LLDB_INVALID_ADDRESS;
+ proc = ReadPointerFromMemory(proc + offset_p_list, error)) {
+ int32_t pid =
+ ReadSignedIntegerFromMemory(proc + offset_p_pid, 4, -1, error);
+ // process' command-line string
+ char comm[fbsd_maxcomlen + 1];
+ ReadCStringFromMemory(proc + offset_p_comm, comm, sizeof(comm), error);
+
+ // iterate through a linked list of all process' threads
+ // the initial thread is found in process' p_threads, subsequent
+ // elements are linked via td_plist field
+ for (lldb::addr_t td =
+ ReadPointerFromMemory(proc + offset_p_threads, error);
+ td != 0; td = ReadPointerFromMemory(td + offset_td_plist, error)) {
+ int32_t tid =
+ ReadSignedIntegerFromMemory(td + offset_td_tid, 4, -1, error);
+ lldb::addr_t pcb_addr =
+ ReadPointerFromMemory(td + offset_td_pcb, error);
+ // whether process was on CPU (-1 if not, otherwise CPU number)
+ int32_t oncpu =
+ ReadSignedIntegerFromMemory(td + offset_td_oncpu, 4, -2, error);
+ // thread name
+ char thread_name[fbsd_maxcomlen + 1];
+ ReadCStringFromMemory(td + offset_td_name, thread_name,
+ sizeof(thread_name), error);
+
+ // if we failed to read TID, ignore this thread
+ if (tid == -1)
+ continue;
+
+ std::string thread_desc = llvm::formatv("(pid {0}) {1}", pid, comm);
+ if (*thread_name && strcmp(thread_name, comm)) {
+ thread_desc += '/';
+ thread_desc += thread_name;
+ }
+
+ // roughly:
+ // 1. if the thread crashed, its PCB is going to be at "dumppcb"
+ // 2. if the thread was on CPU, its PCB is going to be on the CPU
+ // 3. otherwise, its PCB is in the thread struct
+ if (tid == dumptid) {
+ // NB: dumppcb can be LLDB_INVALID_ADDRESS if reading it failed
+ pcb_addr = dumppcb;
+ thread_desc += " (crashed)";
+ } else if (oncpu != -1) {
+ // if we managed to read stoppcbs and pcb_size, use them to find
+ // the correct PCB
+ if (stoppcbs != LLDB_INVALID_ADDRESS && pcbsize > 0)
+ pcb_addr = stoppcbs + oncpu * pcbsize;
+ else
+ pcb_addr = LLDB_INVALID_ADDRESS;
+ thread_desc += llvm::formatv(" (on CPU {0})", oncpu);
+ }
+
+ ThreadSP thread_sp{
+ new ThreadFreeBSDKernel(*this, tid, pcb_addr, thread_desc)};
+ new_thread_list.AddThread(thread_sp);
+ }
+ }
} else {
const uint32_t num_threads = old_thread_list.GetSize(false);
for (uint32_t i = 0; i < num_threads; ++i)
@@ -163,6 +266,12 @@ DynamicLoader *ProcessFreeBSDKernel::GetDynamicLoader() {
return m_dyld_up.get();
}
+lldb::addr_t ProcessFreeBSDKernel::FindSymbol(const char *name) {
+ ModuleSP mod_sp = GetTarget().GetExecutableModule();
+ const Symbol *sym = mod_sp->FindFirstSymbolWithNameAndType(ConstString(name));
+ return sym ? sym->GetLoadAddress(&GetTarget()) : LLDB_INVALID_ADDRESS;
+}
+
#if LLDB_ENABLE_FBSDVMCORE
ProcessFreeBSDKernelFVC::ProcessFreeBSDKernelFVC(lldb::TargetSP target_sp,
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
index 558eec5403db..5bd463126307 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
@@ -46,6 +46,8 @@ public:
protected:
bool DoUpdateThreadList(lldb_private::ThreadList &old_thread_list,
lldb_private::ThreadList &new_thread_list) override;
+
+ lldb::addr_t FindSymbol(const char* name);
};
#endif // LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_PROCESSFREEBSDKERNEL_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.cpp
index 124c65d587ff..8d304086a163 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.cpp
@@ -24,8 +24,10 @@ using namespace lldb;
using namespace lldb_private;
ThreadFreeBSDKernel::ThreadFreeBSDKernel(Process &process, lldb::tid_t tid,
- lldb::addr_t pcb_addr)
- : Thread(process, tid), m_pcb_addr(pcb_addr) {}
+ lldb::addr_t pcb_addr,
+ std::string thread_name)
+ : Thread(process, tid), m_thread_name(std::move(thread_name)),
+ m_pcb_addr(pcb_addr) {}
ThreadFreeBSDKernel::~ThreadFreeBSDKernel() {}
@@ -61,9 +63,8 @@ ThreadFreeBSDKernel::CreateRegisterContextForFrame(StackFrame *frame) {
m_pcb_addr);
break;
case llvm::Triple::x86:
- m_thread_reg_ctx_sp =
- std::make_shared<RegisterContextFreeBSDKernel_i386>(
- *this, new RegisterContextFreeBSD_i386(arch), m_pcb_addr);
+ m_thread_reg_ctx_sp = std::make_shared<RegisterContextFreeBSDKernel_i386>(
+ *this, new RegisterContextFreeBSD_i386(arch), m_pcb_addr);
break;
case llvm::Triple::x86_64:
m_thread_reg_ctx_sp =
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.h
index 2842eba64e56..3bc019b63e68 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.h
@@ -14,7 +14,7 @@
class ThreadFreeBSDKernel : public lldb_private::Thread {
public:
ThreadFreeBSDKernel(lldb_private::Process &process, lldb::tid_t tid,
- lldb::addr_t pcb_addr);
+ lldb::addr_t pcb_addr, std::string thread_name);
~ThreadFreeBSDKernel() override;
@@ -25,10 +25,24 @@ public:
lldb::RegisterContextSP
CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
+ const char *GetName() override {
+ if (m_thread_name.empty())
+ return nullptr;
+ return m_thread_name.c_str();
+ }
+
+ void SetName(const char *name) override {
+ if (name && name[0])
+ m_thread_name.assign(name);
+ else
+ m_thread_name.clear();
+ }
+
protected:
bool CalculateStopInfo() override;
private:
+ std::string m_thread_name;
lldb::RegisterContextSP m_thread_reg_ctx_sp;
lldb::addr_t m_pcb_addr;
};
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
index 0420d00e39d6..182eefb7bee7 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -59,7 +59,7 @@ llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
NativeProcessNetBSD::Factory::Launch(ProcessLaunchInfo &launch_info,
NativeDelegate &native_delegate,
MainLoop &mainloop) const {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ Log *log = GetLog(POSIXLog::Process);
Status status;
::pid_t pid = ProcessLauncherPosixFork()
@@ -113,7 +113,7 @@ llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
NativeProcessNetBSD::Factory::Attach(
lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
MainLoop &mainloop) const {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ Log *log = GetLog(POSIXLog::Process);
LLDB_LOG(log, "pid = {0:x}", pid);
// Retrieve the architecture for the running process.
@@ -172,7 +172,7 @@ void NativeProcessNetBSD::MonitorCallback(lldb::pid_t pid, int signal) {
}
void NativeProcessNetBSD::MonitorExited(lldb::pid_t pid, WaitStatus status) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ Log *log = GetLog(POSIXLog::Process);
LLDB_LOG(log, "got exit signal({0}) , pid = {1}", status, pid);
@@ -207,7 +207,7 @@ void NativeProcessNetBSD::MonitorSIGSTOP(lldb::pid_t pid) {
}
void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ Log *log = GetLog(POSIXLog::Process);
ptrace_siginfo_t info;
const auto siginfo_err =
@@ -359,7 +359,7 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
}
void NativeProcessNetBSD::MonitorSignal(lldb::pid_t pid, int signal) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ Log *log = GetLog(POSIXLog::Process);
ptrace_siginfo_t info;
const auto siginfo_err =
@@ -383,7 +383,7 @@ void NativeProcessNetBSD::MonitorSignal(lldb::pid_t pid, int signal) {
Status NativeProcessNetBSD::PtraceWrapper(int req, lldb::pid_t pid, void *addr,
int data, int *result) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
+ Log *log = GetLog(POSIXLog::Ptrace);
Status error;
int ret;
@@ -459,7 +459,7 @@ static llvm::Expected<ptrace_siginfo_t> ComputeSignalInfo(
}
Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ Log *log = GetLog(POSIXLog::Process);
LLDB_LOG(log, "pid {0}", GetID());
Status ret;
@@ -562,7 +562,7 @@ Status NativeProcessNetBSD::Interrupt() {
}
Status NativeProcessNetBSD::Kill() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ Log *log = GetLog(POSIXLog::Process);
LLDB_LOG(log, "pid {0}", GetID());
Status error;
@@ -654,7 +654,7 @@ Status NativeProcessNetBSD::GetMemoryRegionInfo(lldb::addr_t load_addr,
}
Status NativeProcessNetBSD::PopulateMemoryRegionCache() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ Log *log = GetLog(POSIXLog::Process);
// If our cache is empty, pull the latest. There should always be at least
// one memory region if memory region handling is supported.
if (!m_mem_region_cache.empty()) {
@@ -772,7 +772,7 @@ Status NativeProcessNetBSD::GetFileLoadAddress(const llvm::StringRef &file_name,
}
void NativeProcessNetBSD::SigchldHandler() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ Log *log = GetLog(POSIXLog::Process);
int status;
::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status,
WALLSIG | WNOHANG);
@@ -817,7 +817,7 @@ bool NativeProcessNetBSD::HasThreadNoLock(lldb::tid_t thread_id) {
}
NativeThreadNetBSD &NativeProcessNetBSD::AddThread(lldb::tid_t thread_id) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ Log *log = GetLog(POSIXLog::Thread);
LLDB_LOG(log, "pid {0} adding thread with tid {1}", GetID(), thread_id);
assert(thread_id > 0);
@@ -833,7 +833,7 @@ NativeThreadNetBSD &NativeProcessNetBSD::AddThread(lldb::tid_t thread_id) {
}
void NativeProcessNetBSD::RemoveThread(lldb::tid_t thread_id) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ Log *log = GetLog(POSIXLog::Thread);
LLDB_LOG(log, "pid {0} removing thread with tid {1}", GetID(), thread_id);
assert(thread_id > 0);
@@ -882,7 +882,7 @@ Status NativeProcessNetBSD::ReadMemory(lldb::addr_t addr, void *buf,
unsigned char *dst = static_cast<unsigned char *>(buf);
struct ptrace_io_desc io;
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY));
+ Log *log = GetLog(POSIXLog::Memory);
LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
bytes_read = 0;
@@ -910,7 +910,7 @@ Status NativeProcessNetBSD::WriteMemory(lldb::addr_t addr, const void *buf,
Status error;
struct ptrace_io_desc io;
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY));
+ Log *log = GetLog(POSIXLog::Memory);
LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
bytes_written = 0;
@@ -1013,7 +1013,7 @@ Status NativeProcessNetBSD::ReinitializeThreads() {
void NativeProcessNetBSD::MonitorClone(::pid_t child_pid, bool is_vfork,
NativeThreadNetBSD &parent_thread) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ Log *log = GetLog(POSIXLog::Process);
LLDB_LOG(log, "clone, child_pid={0}", child_pid);
int status;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
index 400b89a5fddf..3e8cf9fd9f23 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
@@ -75,7 +75,7 @@ Status NativeThreadNetBSD::Suspend() {
void NativeThreadNetBSD::SetStoppedBySignal(uint32_t signo,
const siginfo_t *info) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ Log *log = GetLog(POSIXLog::Thread);
LLDB_LOG(log, "tid = {0} in called with signal {1}", GetID(), signo);
SetStopped();
@@ -178,7 +178,7 @@ void NativeThreadNetBSD::SetStepping() {
}
std::string NativeThreadNetBSD::GetName() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ Log *log = GetLog(POSIXLog::Thread);
#ifdef PT_LWPSTATUS
struct ptrace_lwpstatus info = {};
@@ -225,7 +225,7 @@ lldb::StateType NativeThreadNetBSD::GetState() { return m_state; }
bool NativeThreadNetBSD::GetStopReason(ThreadStopInfo &stop_info,
std::string &description) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ Log *log = GetLog(POSIXLog::Thread);
description.clear();
switch (m_state) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
index f4d0803b264a..7ad88aabc2c0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
@@ -13,16 +13,20 @@
using namespace lldb_private;
static constexpr Log::Category g_categories[] = {
- {{"break"}, {"log breakpoints"}, POSIX_LOG_BREAKPOINTS},
- {{"memory"}, {"log memory reads and writes"}, POSIX_LOG_MEMORY},
- {{"process"}, {"log process events and activities"}, POSIX_LOG_PROCESS},
- {{"ptrace"}, {"log all calls to ptrace"}, POSIX_LOG_PTRACE},
- {{"registers"}, {"log register read/writes"}, POSIX_LOG_REGISTERS},
- {{"thread"}, {"log thread events and activities"}, POSIX_LOG_THREAD},
- {{"watch"}, {"log watchpoint related activities"}, POSIX_LOG_WATCHPOINTS},
+ {{"break"}, {"log breakpoints"}, POSIXLog::Breakpoints},
+ {{"memory"}, {"log memory reads and writes"}, POSIXLog::Memory},
+ {{"process"}, {"log process events and activities"}, POSIXLog::Process},
+ {{"ptrace"}, {"log all calls to ptrace"}, POSIXLog::Ptrace},
+ {{"registers"}, {"log register read/writes"}, POSIXLog::Registers},
+ {{"thread"}, {"log thread events and activities"}, POSIXLog::Thread},
+ {{"watch"}, {"log watchpoint related activities"}, POSIXLog::Watchpoints},
};
-Log::Channel ProcessPOSIXLog::g_channel(g_categories, POSIX_LOG_DEFAULT);
+static Log::Channel g_channel(g_categories, POSIXLog::Process);
+
+template <> Log::Channel &lldb_private::LogChannelFor<POSIXLog>() {
+ return g_channel;
+}
void ProcessPOSIXLog::Initialize() {
static llvm::once_flag g_once_flag;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h
index c0147c43410f..7b8b6cdbf255 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h
@@ -13,27 +13,25 @@
#include "lldb/Utility/Log.h"
-#define POSIX_LOG_PROCESS (1u << 1)
-#define POSIX_LOG_THREAD (1u << 2)
-#define POSIX_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
-#define POSIX_LOG_PTRACE (1u << 5)
-#define POSIX_LOG_REGISTERS (1u << 6)
-#define POSIX_LOG_BREAKPOINTS (1u << 7)
-#define POSIX_LOG_WATCHPOINTS (1u << 8)
-#define POSIX_LOG_ALL (UINT32_MAX)
-#define POSIX_LOG_DEFAULT POSIX_LOG_PROCESS
-
namespace lldb_private {
-class ProcessPOSIXLog {
- static Log::Channel g_channel;
+enum class POSIXLog : Log::MaskType {
+ Breakpoints = Log::ChannelFlag<0>,
+ Memory = Log::ChannelFlag<1>,
+ Process = Log::ChannelFlag<2>,
+ Ptrace = Log::ChannelFlag<3>,
+ Registers = Log::ChannelFlag<4>,
+ Thread = Log::ChannelFlag<5>,
+ Watchpoints = Log::ChannelFlag<6>,
+ LLVM_MARK_AS_BITMASK_ENUM(Watchpoints)
+};
+
+class ProcessPOSIXLog {
public:
static void Initialize();
-
- static Log *GetLogIfAllCategoriesSet(uint32_t mask) {
- return g_channel.GetLogIfAll(mask);
- }
};
-}
+
+template <> Log::Channel &LogChannelFor<POSIXLog>();
+} // namespace lldb_private
#endif // liblldb_ProcessPOSIXLog_h_
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.cpp
index d74b66b58afc..b71de4cadb18 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.cpp
@@ -7,6 +7,8 @@
//===----------------------------------------------------------------------===//
#include "MemoryTagManagerAArch64MTE.h"
+#include "llvm/Support/Error.h"
+#include <assert.h>
using namespace lldb_private;
@@ -20,7 +22,7 @@ MemoryTagManagerAArch64MTE::GetLogicalTag(lldb::addr_t addr) const {
}
lldb::addr_t
-MemoryTagManagerAArch64MTE::RemoveNonAddressBits(lldb::addr_t addr) const {
+MemoryTagManagerAArch64MTE::RemoveTagBits(lldb::addr_t addr) const {
// Here we're ignoring the whole top byte. If you've got MTE
// you must also have TBI (top byte ignore).
// The other 4 bits could contain other extension bits or
@@ -30,7 +32,7 @@ MemoryTagManagerAArch64MTE::RemoveNonAddressBits(lldb::addr_t addr) const {
ptrdiff_t MemoryTagManagerAArch64MTE::AddressDiff(lldb::addr_t addr1,
lldb::addr_t addr2) const {
- return RemoveNonAddressBits(addr1) - RemoveNonAddressBits(addr2);
+ return RemoveTagBits(addr1) - RemoveTagBits(addr2);
}
lldb::addr_t MemoryTagManagerAArch64MTE::GetGranuleSize() const {
@@ -66,6 +68,15 @@ MemoryTagManagerAArch64MTE::ExpandToGranule(TagRange range) const {
return TagRange(new_start, new_len);
}
+static llvm::Error MakeInvalidRangeErr(lldb::addr_t addr,
+ lldb::addr_t end_addr) {
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "End address (0x%" PRIx64
+ ") must be greater than the start address (0x%" PRIx64 ")",
+ end_addr, addr);
+}
+
llvm::Expected<MemoryTagManager::TagRange>
MemoryTagManagerAArch64MTE::MakeTaggedRange(
lldb::addr_t addr, lldb::addr_t end_addr,
@@ -74,17 +85,12 @@ MemoryTagManagerAArch64MTE::MakeTaggedRange(
// We must remove tags here otherwise an address with a higher
// tag value will always be > the other.
ptrdiff_t len = AddressDiff(end_addr, addr);
- if (len <= 0) {
- return llvm::createStringError(
- llvm::inconvertibleErrorCode(),
- "End address (0x%" PRIx64
- ") must be greater than the start address (0x%" PRIx64 ")",
- end_addr, addr);
- }
+ if (len <= 0)
+ return MakeInvalidRangeErr(addr, end_addr);
// Region addresses will not have memory tags. So when searching
// we must use an untagged address.
- MemoryRegionInfo::RangeType tag_range(RemoveNonAddressBits(addr), len);
+ MemoryRegionInfo::RangeType tag_range(RemoveTagBits(addr), len);
tag_range = ExpandToGranule(tag_range);
// Make a copy so we can use the original for errors and the final return.
@@ -123,6 +129,91 @@ MemoryTagManagerAArch64MTE::MakeTaggedRange(
return tag_range;
}
+llvm::Expected<std::vector<MemoryTagManager::TagRange>>
+MemoryTagManagerAArch64MTE::MakeTaggedRanges(
+ lldb::addr_t addr, lldb::addr_t end_addr,
+ const lldb_private::MemoryRegionInfos &memory_regions) const {
+ // First check that the range is not inverted.
+ // We must remove tags here otherwise an address with a higher
+ // tag value will always be > the other.
+ ptrdiff_t len = AddressDiff(end_addr, addr);
+ if (len <= 0)
+ return MakeInvalidRangeErr(addr, end_addr);
+
+ std::vector<MemoryTagManager::TagRange> tagged_ranges;
+ // No memory regions means no tagged memory at all
+ if (memory_regions.empty())
+ return tagged_ranges;
+
+ // For the logic to work regions must be in ascending order
+ // which is what you'd have if you used GetMemoryRegions.
+ assert(std::is_sorted(
+ memory_regions.begin(), memory_regions.end(),
+ [](const MemoryRegionInfo &lhs, const MemoryRegionInfo &rhs) {
+ return lhs.GetRange().GetRangeBase() < rhs.GetRange().GetRangeBase();
+ }));
+
+ // If we're debugging userspace in an OS like Linux that uses an MMU,
+ // the only reason we'd get overlapping regions is incorrect data.
+ // It is possible that won't hold for embedded with memory protection
+ // units (MPUs) that allow overlaps.
+ //
+ // For now we're going to assume the former, as there is no good way
+ // to handle overlaps. For example:
+ // < requested range >
+ // [-- region 1 --]
+ // [-- region 2--]
+ // Where the first region will reduce the requested range to nothing
+ // and exit early before it sees the overlap.
+ MemoryRegionInfos::const_iterator overlap = std::adjacent_find(
+ memory_regions.begin(), memory_regions.end(),
+ [](const MemoryRegionInfo &lhs, const MemoryRegionInfo &rhs) {
+ return rhs.GetRange().DoesIntersect(lhs.GetRange());
+ });
+ UNUSED_IF_ASSERT_DISABLED(overlap);
+ assert(overlap == memory_regions.end());
+
+ // Region addresses will not have memory tags so when searching
+ // we must use an untagged address.
+ MemoryRegionInfo::RangeType range(RemoveTagBits(addr), len);
+ range = ExpandToGranule(range);
+
+ // While there are regions to check and the range has non zero length
+ for (const MemoryRegionInfo &region : memory_regions) {
+ // If range we're checking has been reduced to zero length, exit early
+ if (!range.IsValid())
+ break;
+
+ // If the region doesn't overlap the range at all, ignore it.
+ if (!region.GetRange().DoesIntersect(range))
+ continue;
+
+ // If it's tagged record this sub-range.
+ // (assuming that it's already granule aligned)
+ if (region.GetMemoryTagged()) {
+ // The region found may extend outside the requested range.
+ // For example the first region might start before the range.
+ // We must only add what covers the requested range.
+ lldb::addr_t start =
+ std::max(range.GetRangeBase(), region.GetRange().GetRangeBase());
+ lldb::addr_t end =
+ std::min(range.GetRangeEnd(), region.GetRange().GetRangeEnd());
+ tagged_ranges.push_back(MemoryTagManager::TagRange(start, end - start));
+ }
+
+ // Move the range up to start at the end of the region.
+ lldb::addr_t old_end = range.GetRangeEnd();
+ // This "slides" the range so it moves the end as well.
+ range.SetRangeBase(region.GetRange().GetRangeEnd());
+ // So we set the end back to the original end address after sliding it up.
+ range.SetRangeEnd(old_end);
+ // (if the above were to try to set end < begin the range will just be set
+ // to 0 size)
+ }
+
+ return tagged_ranges;
+}
+
llvm::Expected<std::vector<lldb::addr_t>>
MemoryTagManagerAArch64MTE::UnpackTagsData(const std::vector<uint8_t> &tags,
size_t granules /*=0*/) const {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h
index d4e8249da93f..7cda728b140f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h
@@ -27,7 +27,7 @@ public:
size_t GetTagSizeInBytes() const override;
lldb::addr_t GetLogicalTag(lldb::addr_t addr) const override;
- lldb::addr_t RemoveNonAddressBits(lldb::addr_t addr) const override;
+ lldb::addr_t RemoveTagBits(lldb::addr_t addr) const override;
ptrdiff_t AddressDiff(lldb::addr_t addr1, lldb::addr_t addr2) const override;
TagRange ExpandToGranule(TagRange range) const override;
@@ -36,6 +36,10 @@ public:
lldb::addr_t addr, lldb::addr_t end_addr,
const lldb_private::MemoryRegionInfos &memory_regions) const override;
+ llvm::Expected<std::vector<TagRange>> MakeTaggedRanges(
+ lldb::addr_t addr, lldb::addr_t end_addr,
+ const lldb_private::MemoryRegionInfos &memory_regions) const override;
+
llvm::Expected<std::vector<lldb::addr_t>>
UnpackTagsData(const std::vector<uint8_t> &tags,
size_t granules = 0) const override;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
index 6c130be7b741..d6c4a8687ec5 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
@@ -178,10 +178,10 @@ static const lldb_private::RegisterSet g_reg_sets_arm64[k_num_register_sets] = {
g_sve_regnums_arm64}};
static const lldb_private::RegisterSet g_reg_set_pauth_arm64 = {
- "Pointer Authentication Registers", "pauth", k_num_pauth_register, NULL};
+ "Pointer Authentication Registers", "pauth", k_num_pauth_register, nullptr};
static const lldb_private::RegisterSet g_reg_set_mte_arm64 = {
- "MTE Control Register", "mte", k_num_mte_register, NULL};
+ "MTE Control Register", "mte", k_num_mte_register, nullptr};
RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64(
const lldb_private::ArchSpec &target_arch, lldb_private::Flags opt_regsets)
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index b5b105351de5..f6526d03863b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -173,6 +173,13 @@ bool GDBRemoteCommunicationClient::GetQXferMemoryMapReadSupported() {
return m_supports_qXfer_memory_map_read == eLazyBoolYes;
}
+bool GDBRemoteCommunicationClient::GetQXferSigInfoReadSupported() {
+ if (m_supports_qXfer_siginfo_read == eLazyBoolCalculate) {
+ GetRemoteQSupported();
+ }
+ return m_supports_qXfer_siginfo_read == eLazyBoolYes;
+}
+
uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {
if (m_max_packet_size == 0) {
GetRemoteQSupported();
@@ -273,6 +280,7 @@ void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
m_supports_qXfer_features_read = eLazyBoolCalculate;
m_supports_qXfer_memory_map_read = eLazyBoolCalculate;
+ m_supports_qXfer_siginfo_read = eLazyBoolCalculate;
m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
m_uses_native_signals = eLazyBoolCalculate;
m_supports_qProcessInfoPID = true;
@@ -320,6 +328,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
m_supports_qXfer_features_read = eLazyBoolNo;
m_supports_qXfer_memory_map_read = eLazyBoolNo;
+ m_supports_qXfer_siginfo_read = eLazyBoolNo;
m_supports_multiprocess = eLazyBoolNo;
m_supports_qEcho = eLazyBoolNo;
m_supports_QPassSignals = eLazyBoolNo;
@@ -362,6 +371,8 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
m_supports_qXfer_features_read = eLazyBoolYes;
else if (x == "qXfer:memory-map:read+")
m_supports_qXfer_memory_map_read = eLazyBoolYes;
+ else if (x == "qXfer:siginfo:read+")
+ m_supports_qXfer_siginfo_read = eLazyBoolYes;
else if (x == "qEcho")
m_supports_qEcho = eLazyBoolYes;
else if (x == "QPassSignals+")
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index c69c33bb1c15..58ed22187747 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -337,6 +337,8 @@ public:
bool GetQXferMemoryMapReadSupported();
+ bool GetQXferSigInfoReadSupported();
+
LazyBool SupportsAllocDeallocMemory() // const
{
// Uncomment this to have lldb pretend the debug server doesn't respond to
@@ -551,6 +553,7 @@ protected:
LazyBool m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
LazyBool m_supports_qXfer_features_read = eLazyBoolCalculate;
LazyBool m_supports_qXfer_memory_map_read = eLazyBoolCalculate;
+ LazyBool m_supports_qXfer_siginfo_read = eLazyBoolCalculate;
LazyBool m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
LazyBool m_supports_jThreadExtendedInfo = eLazyBoolCalculate;
LazyBool m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolCalculate;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
deleted file mode 100644
index c91d7cb5ac30..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
+++ /dev/null
@@ -1,314 +0,0 @@
-//===-- GDBRemoteCommunicationReplayServer.cpp ----------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include <cerrno>
-
-#include "lldb/Host/Config.h"
-#include "llvm/ADT/ScopeExit.h"
-
-#include "GDBRemoteCommunicationReplayServer.h"
-#include "ProcessGDBRemoteLog.h"
-
-// C Includes
-// C++ Includes
-#include <cstring>
-
-// Project includes
-#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/Event.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/StreamString.h"
-#include "lldb/Utility/StringExtractorGDBRemote.h"
-
-using namespace llvm;
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::process_gdb_remote;
-
-/// Check if the given expected packet matches the actual packet.
-static bool unexpected(llvm::StringRef expected, llvm::StringRef actual) {
- // The 'expected' string contains the raw data, including the leading $ and
- // trailing checksum. The 'actual' string contains only the packet's content.
- if (expected.contains(actual))
- return false;
- // Contains a PID which might be different.
- if (expected.contains("vAttach"))
- return false;
- // Contains a ascii-hex-path.
- if (expected.contains("QSetSTD"))
- return false;
- // Contains environment values.
- if (expected.contains("QEnvironment"))
- return false;
-
- return true;
-}
-
-/// Check if we should reply to the given packet.
-static bool skip(llvm::StringRef data) {
- assert(!data.empty() && "Empty packet?");
-
- // We've already acknowledge the '+' packet so we're done here.
- if (data == "+")
- return true;
-
- /// Don't 't reply to ^C. We need this because of stop reply packets, which
- /// are only returned when the target halts. Reproducers synchronize these
- /// 'asynchronous' replies, by recording them as a regular replies to the
- /// previous packet (e.g. vCont). As a result, we should ignore real
- /// asynchronous requests.
- if (data.data()[0] == 0x03)
- return true;
-
- return false;
-}
-
-GDBRemoteCommunicationReplayServer::GDBRemoteCommunicationReplayServer()
- : GDBRemoteCommunication("gdb-replay", "gdb-replay.rx_packet"),
- m_async_broadcaster(nullptr, "lldb.gdb-replay.async-broadcaster"),
- m_async_listener_sp(
- Listener::MakeListener("lldb.gdb-replay.async-listener")),
- m_async_thread_state_mutex() {
- m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
- "async thread continue");
- m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
- "async thread should exit");
-
- const uint32_t async_event_mask =
- eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;
- m_async_listener_sp->StartListeningForEvents(&m_async_broadcaster,
- async_event_mask);
-}
-
-GDBRemoteCommunicationReplayServer::~GDBRemoteCommunicationReplayServer() {
- StopAsyncThread();
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse(
- Timeout<std::micro> timeout, Status &error, bool &interrupt, bool &quit) {
- std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
-
- StringExtractorGDBRemote packet;
- PacketResult packet_result = WaitForPacketNoLock(packet, timeout, false);
-
- if (packet_result != PacketResult::Success) {
- if (!IsConnected()) {
- error.SetErrorString("lost connection");
- quit = true;
- } else {
- error.SetErrorString("timeout");
- }
- return packet_result;
- }
-
- m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue);
-
- // Check if we should reply to this packet.
- if (skip(packet.GetStringRef()))
- return PacketResult::Success;
-
- // This completes the handshake. Since m_send_acks was true, we can unset it
- // already.
- if (packet.GetStringRef() == "QStartNoAckMode")
- m_send_acks = false;
-
- // A QEnvironment packet is sent for every environment variable. If the
- // number of environment variables is different during replay, the replies
- // become out of sync.
- if (packet.GetStringRef().find("QEnvironment") == 0)
- return SendRawPacketNoLock("$OK#9a");
-
- Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- while (!m_packet_history.empty()) {
- // Pop last packet from the history.
- GDBRemotePacket entry = m_packet_history.back();
- m_packet_history.pop_back();
-
- // Decode run-length encoding.
- const std::string expanded_data =
- GDBRemoteCommunication::ExpandRLE(entry.packet.data);
-
- // We've handled the handshake implicitly before. Skip the packet and move
- // on.
- if (entry.packet.data == "+")
- continue;
-
- if (entry.type == GDBRemotePacket::ePacketTypeSend) {
- if (unexpected(expanded_data, packet.GetStringRef())) {
- LLDB_LOG(log,
- "GDBRemoteCommunicationReplayServer expected packet: '{0}'",
- expanded_data);
- LLDB_LOG(log, "GDBRemoteCommunicationReplayServer actual packet: '{0}'",
- packet.GetStringRef());
-#ifndef NDEBUG
- // This behaves like a regular assert, but prints the expected and
- // received packet before aborting.
- printf("Reproducer expected packet: '%s'\n", expanded_data.c_str());
- printf("Reproducer received packet: '%s'\n",
- packet.GetStringRef().data());
- llvm::report_fatal_error("Encountered unexpected packet during replay");
-#endif
- return PacketResult::ErrorSendFailed;
- }
-
- // Ignore QEnvironment packets as they're handled earlier.
- if (expanded_data.find("QEnvironment") == 1) {
- assert(m_packet_history.back().type ==
- GDBRemotePacket::ePacketTypeRecv);
- m_packet_history.pop_back();
- }
-
- continue;
- }
-
- if (entry.type == GDBRemotePacket::ePacketTypeInvalid) {
- LLDB_LOG(
- log,
- "GDBRemoteCommunicationReplayServer skipped invalid packet: '{0}'",
- packet.GetStringRef());
- continue;
- }
-
- LLDB_LOG(log,
- "GDBRemoteCommunicationReplayServer replied to '{0}' with '{1}'",
- packet.GetStringRef(), entry.packet.data);
- return SendRawPacketNoLock(entry.packet.data);
- }
-
- quit = true;
-
- return packet_result;
-}
-
-llvm::Error
-GDBRemoteCommunicationReplayServer::LoadReplayHistory(const FileSpec &path) {
- auto error_or_file = MemoryBuffer::getFile(path.GetPath());
- if (auto err = error_or_file.getError())
- return errorCodeToError(err);
-
- yaml::Input yin((*error_or_file)->getBuffer());
- yin >> m_packet_history;
-
- if (auto err = yin.error())
- return errorCodeToError(err);
-
- // We want to manipulate the vector like a stack so we need to reverse the
- // order of the packets to have the oldest on at the back.
- std::reverse(m_packet_history.begin(), m_packet_history.end());
-
- return Error::success();
-}
-
-bool GDBRemoteCommunicationReplayServer::StartAsyncThread() {
- std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
- if (!m_async_thread.IsJoinable()) {
- // Create a thread that watches our internal state and controls which
- // events make it to clients (into the DCProcess event queue).
- llvm::Expected<HostThread> async_thread = ThreadLauncher::LaunchThread(
- "<lldb.gdb-replay.async>",
- GDBRemoteCommunicationReplayServer::AsyncThread, this);
- if (!async_thread) {
- LLDB_LOG_ERROR(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST),
- async_thread.takeError(),
- "failed to launch host thread: {}");
- return false;
- }
- m_async_thread = *async_thread;
- }
-
- // Wait for handshake.
- m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue);
-
- return m_async_thread.IsJoinable();
-}
-
-void GDBRemoteCommunicationReplayServer::StopAsyncThread() {
- std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
-
- if (!m_async_thread.IsJoinable())
- return;
-
- // Request thread to stop.
- m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncThreadShouldExit);
-
- // Disconnect client.
- Disconnect();
-
- // Stop the thread.
- m_async_thread.Join(nullptr);
- m_async_thread.Reset();
-}
-
-void GDBRemoteCommunicationReplayServer::ReceivePacket(
- GDBRemoteCommunicationReplayServer &server, bool &done) {
- Status error;
- bool interrupt;
- auto packet_result = server.GetPacketAndSendResponse(std::chrono::seconds(1),
- error, interrupt, done);
- if (packet_result != GDBRemoteCommunication::PacketResult::Success &&
- packet_result !=
- GDBRemoteCommunication::PacketResult::ErrorReplyTimeout) {
- done = true;
- } else {
- server.m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue);
- }
-}
-
-thread_result_t GDBRemoteCommunicationReplayServer::AsyncThread(void *arg) {
- GDBRemoteCommunicationReplayServer *server =
- (GDBRemoteCommunicationReplayServer *)arg;
- auto D = make_scope_exit([&]() { server->Disconnect(); });
- EventSP event_sp;
- bool done = false;
- while (!done) {
- if (server->m_async_listener_sp->GetEvent(event_sp, llvm::None)) {
- const uint32_t event_type = event_sp->GetType();
- if (event_sp->BroadcasterIs(&server->m_async_broadcaster)) {
- switch (event_type) {
- case eBroadcastBitAsyncContinue:
- ReceivePacket(*server, done);
- if (done)
- return {};
- break;
- case eBroadcastBitAsyncThreadShouldExit:
- default:
- return {};
- }
- }
- }
- }
-
- return {};
-}
-
-Status GDBRemoteCommunicationReplayServer::Connect(
- process_gdb_remote::GDBRemoteCommunicationClient &client) {
- repro::Loader *loader = repro::Reproducer::Instance().GetLoader();
- if (!loader)
- return Status("No loader provided.");
-
- static std::unique_ptr<repro::MultiLoader<repro::GDBRemoteProvider>>
- multi_loader = repro::MultiLoader<repro::GDBRemoteProvider>::Create(
- repro::Reproducer::Instance().GetLoader());
- if (!multi_loader)
- return Status("No gdb remote provider found.");
-
- llvm::Optional<std::string> history_file = multi_loader->GetNextFile();
- if (!history_file)
- return Status("No gdb remote packet log found.");
-
- if (auto error = LoadReplayHistory(FileSpec(*history_file)))
- return Status("Unable to load replay history");
-
- if (auto error = GDBRemoteCommunication::ConnectLocally(client, *this))
- return Status("Unable to connect to replay server");
-
- return {};
-}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
deleted file mode 100644
index 2f8770d0accf..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
+++ /dev/null
@@ -1,88 +0,0 @@
-//===-- GDBRemoteCommunicationReplayServer.h --------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONREPLAYSERVER_H
-#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONREPLAYSERVER_H
-
-// Other libraries and framework includes
-#include "GDBRemoteCommunication.h"
-#include "GDBRemoteCommunicationClient.h"
-#include "GDBRemoteCommunicationHistory.h"
-
-// Project includes
-#include "lldb/Host/HostThread.h"
-#include "lldb/Utility/Broadcaster.h"
-#include "lldb/lldb-private-forward.h"
-#include "llvm/Support/Error.h"
-
-// C Includes
-// C++ Includes
-#include <functional>
-#include <map>
-#include <thread>
-
-class StringExtractorGDBRemote;
-
-namespace lldb_private {
-namespace process_gdb_remote {
-
-class ProcessGDBRemote;
-
-/// Dummy GDB server that replays packets from the GDB Remote Communication
-/// history. This is used to replay GDB packets.
-class GDBRemoteCommunicationReplayServer : public GDBRemoteCommunication {
-public:
- GDBRemoteCommunicationReplayServer();
-
- ~GDBRemoteCommunicationReplayServer() override;
-
- PacketResult GetPacketAndSendResponse(Timeout<std::micro> timeout,
- Status &error, bool &interrupt,
- bool &quit);
-
- bool HandshakeWithClient() { return GetAck() == PacketResult::Success; }
-
- llvm::Error LoadReplayHistory(const FileSpec &path);
-
- bool StartAsyncThread();
- void StopAsyncThread();
-
- Status Connect(process_gdb_remote::GDBRemoteCommunicationClient &client);
-
-protected:
- enum {
- eBroadcastBitAsyncContinue = (1 << 0),
- eBroadcastBitAsyncThreadShouldExit = (1 << 1),
- };
-
- static void ReceivePacket(GDBRemoteCommunicationReplayServer &server,
- bool &done);
- static lldb::thread_result_t AsyncThread(void *arg);
-
- /// Replay history with the oldest packet at the end.
- std::vector<GDBRemotePacket> m_packet_history;
-
- /// Server thread.
- Broadcaster m_async_broadcaster;
- lldb::ListenerSP m_async_listener_sp;
- HostThread m_async_thread;
- std::recursive_mutex m_async_thread_state_mutex;
-
- bool m_skip_acks = false;
-
-private:
- GDBRemoteCommunicationReplayServer(
- const GDBRemoteCommunicationReplayServer &) = delete;
- const GDBRemoteCommunicationReplayServer &
- operator=(const GDBRemoteCommunicationReplayServer &) = delete;
-};
-
-} // namespace process_gdb_remote
-} // namespace lldb_private
-
-#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONREPLAYSERVER_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 30f14a52dfb5..123a8198a89b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -1086,7 +1086,7 @@ void GDBRemoteCommunicationServerLLGS::NewSubprocess(
}
void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() {
- Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_COMM));
+ Log *log = GetLog(GDBRLog::Comm);
bool interrupt = false;
bool done = false;
@@ -2920,6 +2920,18 @@ GDBRemoteCommunicationServerLLGS::ReadXferObject(llvm::StringRef object,
return std::move(*buffer_or_error);
}
+ if (object == "siginfo") {
+ NativeThreadProtocol *thread = m_current_process->GetCurrentThread();
+ if (!thread)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "no current thread");
+
+ auto buffer_or_error = thread->GetSiginfo();
+ if (!buffer_or_error)
+ return buffer_or_error.takeError();
+ return std::move(*buffer_or_error);
+ }
+
if (object == "libraries-svr4") {
auto library_list = m_current_process->GetLoadedSVR4Libraries();
if (!library_list)
@@ -3838,6 +3850,8 @@ std::vector<std::string> GDBRemoteCommunicationServerLLGS::HandleFeatures(
ret.push_back("qXfer:auxv:read+");
if (bool(plugin_features & Extension::libraries_svr4))
ret.push_back("qXfer:libraries-svr4:read+");
+ if (bool(plugin_features & Extension::siginfo_read))
+ ret.push_back("qXfer:siginfo:read+");
if (bool(plugin_features & Extension::memory_tagging))
ret.push_back("memory-tagging+");
if (bool(plugin_features & Extension::savecore))
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.cpp
new file mode 100644
index 000000000000..b391edced695
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.cpp
@@ -0,0 +1,86 @@
+//===-- GDBRemoteRegisterFallback.cpp -------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "GDBRemoteRegisterFallback.h"
+
+namespace lldb_private {
+namespace process_gdb_remote {
+
+#define REG(name, size) \
+ DynamicRegisterInfo::Register { \
+ ConstString(#name), empty_alt_name, reg_set, size, LLDB_INVALID_INDEX32, \
+ lldb::eEncodingUint, lldb::eFormatHex, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, {}, {} \
+ }
+#define R64(name) REG(name, 8)
+#define R32(name) REG(name, 4)
+
+static std::vector<DynamicRegisterInfo::Register> GetRegisters_aarch64() {
+ ConstString empty_alt_name;
+ ConstString reg_set{"general purpose registers"};
+
+ std::vector<DynamicRegisterInfo::Register> registers{
+ R64(x0), R64(x1), R64(x2), R64(x3), R64(x4), R64(x5), R64(x6),
+ R64(x7), R64(x8), R64(x9), R64(x10), R64(x11), R64(x12), R64(x13),
+ R64(x14), R64(x15), R64(x16), R64(x17), R64(x18), R64(x19), R64(x20),
+ R64(x21), R64(x22), R64(x23), R64(x24), R64(x25), R64(x26), R64(x27),
+ R64(x28), R64(x29), R64(x30), R64(sp), R64(pc), R32(cpsr),
+ };
+
+ return registers;
+}
+
+static std::vector<DynamicRegisterInfo::Register> GetRegisters_x86() {
+ ConstString empty_alt_name;
+ ConstString reg_set{"general purpose registers"};
+
+ std::vector<DynamicRegisterInfo::Register> registers{
+ R32(eax), R32(ecx), R32(edx), R32(ebx), R32(esp), R32(ebp),
+ R32(esi), R32(edi), R32(eip), R32(eflags), R32(cs), R32(ss),
+ R32(ds), R32(es), R32(fs), R32(gs),
+ };
+
+ return registers;
+}
+
+static std::vector<DynamicRegisterInfo::Register> GetRegisters_x86_64() {
+ ConstString empty_alt_name;
+ ConstString reg_set{"general purpose registers"};
+
+ std::vector<DynamicRegisterInfo::Register> registers{
+ R64(rax), R64(rbx), R64(rcx), R64(rdx), R64(rsi), R64(rdi),
+ R64(rbp), R64(rsp), R64(r8), R64(r9), R64(r10), R64(r11),
+ R64(r12), R64(r13), R64(r14), R64(r15), R64(rip), R32(eflags),
+ R32(cs), R32(ss), R32(ds), R32(es), R32(fs), R32(gs),
+ };
+
+ return registers;
+}
+
+#undef R32
+#undef R64
+#undef REG
+
+std::vector<DynamicRegisterInfo::Register>
+GetFallbackRegisters(const ArchSpec &arch_to_use) {
+ switch (arch_to_use.GetMachine()) {
+ case llvm::Triple::aarch64:
+ return GetRegisters_aarch64();
+ case llvm::Triple::x86:
+ return GetRegisters_x86();
+ case llvm::Triple::x86_64:
+ return GetRegisters_x86_64();
+ default:
+ break;
+ }
+
+ return {};
+}
+
+} // namespace process_gdb_remote
+} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.h
new file mode 100644
index 000000000000..82e03c6b9b1c
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.h
@@ -0,0 +1,26 @@
+//===-- GDBRemoteRegisterFallback.h -----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTEREGISTERFALLBACK_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTEREGISTERFALLBACK_H
+
+#include <vector>
+
+#include "lldb/Target/DynamicRegisterInfo.h"
+#include "lldb/Utility/ArchSpec.h"
+
+namespace lldb_private {
+namespace process_gdb_remote {
+
+std::vector<DynamicRegisterInfo::Register>
+GetFallbackRegisters(const ArchSpec &arch_to_use);
+
+} // namespace process_gdb_remote
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTEREGISTERFALLBACK_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index af95ef0718a5..5f3c1ad9c1e1 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -23,13 +23,6 @@
#include <ctime>
#include <sys/types.h>
-#include <algorithm>
-#include <csignal>
-#include <map>
-#include <memory>
-#include <mutex>
-#include <sstream>
-
#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
@@ -70,8 +63,16 @@
#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
+#include <algorithm>
+#include <csignal>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <sstream>
+#include <thread>
#include "GDBRemoteRegisterContext.h"
+#include "GDBRemoteRegisterFallback.h"
#ifdef LLDB_ENABLE_ALL
#include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
#endif // LLDB_ENABLE_ALL
@@ -255,9 +256,8 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
m_addr_to_mmap_size(), m_thread_create_bp_sp(),
m_waiting_for_attach(false), m_destroy_tried_resuming(false),
m_command_sp(), m_breakpoint_pc_offset(0),
- m_initial_tid(LLDB_INVALID_THREAD_ID), m_replay_mode(false),
- m_allow_flash_writes(false), m_erased_flash_ranges(),
- m_vfork_in_progress(false) {
+ m_initial_tid(LLDB_INVALID_THREAD_ID), m_allow_flash_writes(false),
+ m_erased_flash_ranges(), m_vfork_in_progress(false) {
m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
"async thread should exit");
m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
@@ -397,6 +397,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
// 2 - If the target definition doesn't have any of the info from the
// target.xml (registers) then proceed to read the target.xml.
// 3 - Fall back on the qRegisterInfo packets.
+ // 4 - Use hardcoded defaults if available.
FileSpec target_definition_fspec =
GetGlobalPluginProperties().GetTargetDefinitionFile();
@@ -510,6 +511,9 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
}
}
+ if (registers.empty())
+ registers = GetFallbackRegisters(arch_to_use);
+
AddRemoteRegisters(registers, arch_to_use);
}
@@ -527,7 +531,7 @@ Status ProcessGDBRemote::WillAttachToProcessWithName(const char *process_name,
}
Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) {
- Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ Log *log = GetLog(GDBRLog::Process);
Status error(WillLaunchOrAttach());
if (error.Fail())
@@ -604,8 +608,7 @@ Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) {
ReadModuleFromMemory(FileSpec(namebuf), standalone_value);
}
- Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(
- LIBLLDB_LOG_DYNAMIC_LOADER));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
if (module_sp.get()) {
target.GetImages().AppendIfNeeded(module_sp, false);
@@ -3320,24 +3323,6 @@ Status ProcessGDBRemote::DoSignal(int signo) {
return error;
}
-Status ProcessGDBRemote::ConnectToReplayServer() {
- Status status = m_gdb_replay_server.Connect(m_gdb_comm);
- if (status.Fail())
- return status;
-
- // Enable replay mode.
- m_replay_mode = true;
-
- // Start server thread.
- m_gdb_replay_server.StartAsyncThread();
-
- // Start client thread.
- StartAsyncThread();
-
- // Do the usual setup.
- return ConnectToDebugserver("");
-}
-
Status
ProcessGDBRemote::EstablishConnectionIfNeeded(const ProcessInfo &process_info) {
// Make sure we aren't already connected?
@@ -4374,9 +4359,9 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess(
} else if (name == "osabi") {
node.GetElementText(target_info.osabi);
} else if (name == "xi:include" || name == "include") {
- llvm::StringRef href = node.GetAttributeValue("href");
+ std::string href = node.GetAttributeValue("href");
if (!href.empty())
- target_info.includes.push_back(href.str());
+ target_info.includes.push_back(href);
} else if (name == "feature") {
feature_nodes.push_back(node);
} else if (name == "groups") {
@@ -4415,9 +4400,9 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess(
const XMLNode &node) -> bool {
llvm::StringRef name = node.GetName();
if (name == "xi:include" || name == "include") {
- llvm::StringRef href = node.GetAttributeValue("href");
+ std::string href = node.GetAttributeValue("href");
if (!href.empty())
- target_info.includes.push_back(href.str());
+ target_info.includes.push_back(href);
}
return true;
});
@@ -4553,7 +4538,7 @@ llvm::Expected<LoadedModuleInfoList> ProcessGDBRemote::GetLoadedModuleList() {
"Error finding library-list-svr4 xml element");
// main link map structure
- llvm::StringRef main_lm = root_element.GetAttributeValue("main-lm");
+ std::string main_lm = root_element.GetAttributeValue("main-lm");
// FIXME: we're silently ignoring invalid data here
if (!main_lm.empty())
llvm::to_integer(main_lm, list.m_link_map);
@@ -4641,15 +4626,15 @@ llvm::Expected<LoadedModuleInfoList> ProcessGDBRemote::GetLoadedModuleList() {
"library", [log, &list](const XMLNode &library) -> bool {
LoadedModuleInfoList::LoadedModuleInfo module;
- llvm::StringRef name = library.GetAttributeValue("name");
- module.set_name(name.str());
+ std::string name = library.GetAttributeValue("name");
+ module.set_name(name);
// The base address of a given library will be the address of its
// first section. Most remotes send only one section for Windows
// targets for example.
const XMLNode &section =
library.FindFirstChildElementWithName("section");
- llvm::StringRef address = section.GetAttributeValue("address");
+ std::string address = section.GetAttributeValue("address");
uint64_t address_value = LLDB_INVALID_ADDRESS;
llvm::to_integer(address, address_value);
module.set_base(address_value);
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 488336b8c1b8..bdf130e3ec11 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -34,7 +34,6 @@
#include "lldb/lldb-private-forward.h"
#include "GDBRemoteCommunicationClient.h"
-#include "GDBRemoteCommunicationReplayServer.h"
#include "GDBRemoteRegisterContext.h"
#include "llvm/ADT/DenseMap.h"
@@ -251,7 +250,6 @@ protected:
};
GDBRemoteCommunicationClient m_gdb_comm;
- GDBRemoteCommunicationReplayServer m_gdb_replay_server;
std::atomic<lldb::pid_t> m_debugserver_pid;
llvm::Optional<StringExtractorGDBRemote> m_last_stop_packet;
@@ -292,7 +290,6 @@ protected:
lldb::tid_t m_initial_tid; // The initial thread ID, given by stub on attach
bool m_use_g_packet_for_reading;
- bool m_replay_mode;
bool m_allow_flash_writes;
using FlashRangeVector = lldb_private::RangeVector<lldb::addr_t, size_t>;
using FlashRange = FlashRangeVector::Entry;
@@ -320,8 +317,6 @@ protected:
bool DoUpdateThreadList(ThreadList &old_thread_list,
ThreadList &new_thread_list) override;
- Status ConnectToReplayServer();
-
Status EstablishConnectionIfNeeded(const ProcessInfo &process_info);
Status LaunchAndConnectToDebugserver(const ProcessInfo &process_info);
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
index 40990ef66494..3322f6b8048a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
@@ -15,25 +15,29 @@ using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
static constexpr Log::Category g_categories[] = {
- {{"async"}, {"log asynchronous activity"}, GDBR_LOG_ASYNC},
- {{"break"}, {"log breakpoints"}, GDBR_LOG_BREAKPOINTS},
- {{"comm"}, {"log communication activity"}, GDBR_LOG_COMM},
- {{"packets"}, {"log gdb remote packets"}, GDBR_LOG_PACKETS},
- {{"memory"}, {"log memory reads and writes"}, GDBR_LOG_MEMORY},
+ {{"async"}, {"log asynchronous activity"}, GDBRLog::Async},
+ {{"break"}, {"log breakpoints"}, GDBRLog::Breakpoints},
+ {{"comm"}, {"log communication activity"}, GDBRLog::Comm},
+ {{"packets"}, {"log gdb remote packets"}, GDBRLog::Packets},
+ {{"memory"}, {"log memory reads and writes"}, GDBRLog::Memory},
{{"data-short"},
{"log memory bytes for memory reads and writes for short transactions "
"only"},
- GDBR_LOG_MEMORY_DATA_SHORT},
+ GDBRLog::MemoryDataShort},
{{"data-long"},
{"log memory bytes for memory reads and writes for all transactions"},
- GDBR_LOG_MEMORY_DATA_LONG},
- {{"process"}, {"log process events and activities"}, GDBR_LOG_PROCESS},
- {{"step"}, {"log step related activities"}, GDBR_LOG_STEP},
- {{"thread"}, {"log thread events and activities"}, GDBR_LOG_THREAD},
- {{"watch"}, {"log watchpoint related activities"}, GDBR_LOG_WATCHPOINTS},
+ GDBRLog::MemoryDataLong},
+ {{"process"}, {"log process events and activities"}, GDBRLog::Process},
+ {{"step"}, {"log step related activities"}, GDBRLog::Step},
+ {{"thread"}, {"log thread events and activities"}, GDBRLog::Thread},
+ {{"watch"}, {"log watchpoint related activities"}, GDBRLog::Watchpoints},
};
-Log::Channel ProcessGDBRemoteLog::g_channel(g_categories, GDBR_LOG_DEFAULT);
+static Log::Channel g_channel(g_categories, GDBRLog::Packets);
+
+template <> Log::Channel &lldb_private::LogChannelFor<GDBRLog>() {
+ return g_channel;
+}
void ProcessGDBRemoteLog::Initialize() {
static llvm::once_flag g_once_flag;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
index bd3e993cf72a..44e390ec8cad 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
@@ -11,35 +11,52 @@
#include "lldb/Utility/Log.h"
-#define GDBR_LOG_PROCESS (1u << 1)
-#define GDBR_LOG_THREAD (1u << 2)
-#define GDBR_LOG_PACKETS (1u << 3)
-#define GDBR_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
-#define GDBR_LOG_MEMORY_DATA_SHORT \
- (1u << 5) // Log short memory reads/writes bytes
-#define GDBR_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes
-#define GDBR_LOG_BREAKPOINTS (1u << 7)
-#define GDBR_LOG_WATCHPOINTS (1u << 8)
-#define GDBR_LOG_STEP (1u << 9)
-#define GDBR_LOG_COMM (1u << 10)
-#define GDBR_LOG_ASYNC (1u << 11)
-#define GDBR_LOG_ALL (UINT32_MAX)
-#define GDBR_LOG_DEFAULT GDBR_LOG_PACKETS
-
namespace lldb_private {
namespace process_gdb_remote {
-class ProcessGDBRemoteLog {
- static Log::Channel g_channel;
+enum class GDBRLog : Log::MaskType {
+ Async = Log::ChannelFlag<0>,
+ Breakpoints = Log::ChannelFlag<1>,
+ Comm = Log::ChannelFlag<2>,
+ Memory = Log::ChannelFlag<3>, // Log memory reads/writes calls
+ MemoryDataLong = Log::ChannelFlag<4>, // Log all memory reads/writes bytes
+ MemoryDataShort = Log::ChannelFlag<5>, // Log short memory reads/writes bytes
+ Packets = Log::ChannelFlag<6>,
+ Process = Log::ChannelFlag<7>,
+ Step = Log::ChannelFlag<8>,
+ Thread = Log::ChannelFlag<9>,
+ Watchpoints = Log::ChannelFlag<10>,
+ LLVM_MARK_AS_BITMASK_ENUM(Watchpoints)
+};
+#define GDBR_LOG_PROCESS ::lldb_private::process_gdb_remote::GDBRLog::Process
+#define GDBR_LOG_THREAD ::lldb_private::process_gdb_remote::GDBRLog::Thread
+#define GDBR_LOG_PACKETS ::lldb_private::process_gdb_remote::GDBRLog::Packets
+#define GDBR_LOG_MEMORY ::lldb_private::process_gdb_remote::GDBRLog::Memory
+#define GDBR_LOG_MEMORY_DATA_SHORT \
+ ::lldb_private::process_gdb_remote::GDBRLog::MemoryDataShort
+#define GDBR_LOG_MEMORY_DATA_LONG \
+ ::lldb_private::process_gdb_remote::GDBRLog::MemoryDataLong
+#define GDBR_LOG_BREAKPOINTS \
+ ::lldb_private::process_gdb_remote::GDBRLog::Breakpoints
+#define GDBR_LOG_WATCHPOINTS \
+ ::lldb_private::process_gdb_remote::GDBRLog::Watchpoints
+#define GDBR_LOG_STEP ::lldb_private::process_gdb_remote::GDBRLog::Step
+#define GDBR_LOG_COMM ::lldb_private::process_gdb_remote::GDBRLog::Comm
+#define GDBR_LOG_ASYNC ::lldb_private::process_gdb_remote::GDBRLog::Async
+
+class ProcessGDBRemoteLog {
public:
static void Initialize();
- static Log *GetLogIfAllCategoriesSet(uint32_t mask) { return g_channel.GetLogIfAll(mask); }
- static Log *GetLogIfAnyCategoryIsSet(uint32_t mask) { return g_channel.GetLogIfAny(mask); }
+ static Log *GetLogIfAllCategoriesSet(GDBRLog mask) { return GetLog(mask); }
+ static Log *GetLogIfAnyCategoryIsSet(GDBRLog mask) { return GetLog(mask); }
};
} // namespace process_gdb_remote
+
+template <> Log::Channel &LogChannelFor<process_gdb_remote::GDBRLog>();
+
} // namespace lldb_private
#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTELOG_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index 2a9896e41085..3d23c074c1be 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -39,7 +39,7 @@ ThreadGDBRemote::ThreadGDBRemote(Process &process, lldb::tid_t tid)
m_dispatch_queue_t(LLDB_INVALID_ADDRESS), m_queue_kind(eQueueKindUnknown),
m_queue_serial_number(LLDB_INVALID_QUEUE_ID),
m_associated_with_libdispatch_queue(eLazyBoolCalculate) {
- Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
+ Log *log = GetLog(GDBRLog::Thread);
LLDB_LOG(log, "this = {0}, pid = {1}, tid = {2}", this, process.GetID(),
GetID());
// At this point we can clone reg_info for architectures supporting
@@ -54,7 +54,7 @@ ThreadGDBRemote::ThreadGDBRemote(Process &process, lldb::tid_t tid)
ThreadGDBRemote::~ThreadGDBRemote() {
ProcessSP process_sp(GetProcess());
- Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
+ Log *log = GetLog(GDBRLog::Thread);
LLDB_LOG(log, "this = {0}, pid = {1}, tid = {2}", this,
process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID, GetID());
DestroyThread();
@@ -222,7 +222,7 @@ void ThreadGDBRemote::SetAssociatedWithLibdispatchQueue(
StructuredData::ObjectSP ThreadGDBRemote::FetchThreadExtendedInfo() {
StructuredData::ObjectSP object_sp;
const lldb::user_id_t tid = GetProtocolID();
- Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
+ Log *log = GetLog(GDBRLog::Thread);
LLDB_LOGF(log, "Fetching extended information for thread %4.4" PRIx64, tid);
ProcessSP process_sp(GetProcess());
if (process_sp) {
@@ -236,7 +236,7 @@ StructuredData::ObjectSP ThreadGDBRemote::FetchThreadExtendedInfo() {
void ThreadGDBRemote::WillResume(StateType resume_state) {
int signo = GetResumeSignal();
const lldb::user_id_t tid = GetProtocolID();
- Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
+ Log *log = GetLog(GDBRLog::Thread);
LLDB_LOGF(log, "Resuming thread: %4.4" PRIx64 " with state: %s.", tid,
StateAsCString(resume_state));
@@ -346,3 +346,23 @@ bool ThreadGDBRemote::CalculateStopInfo() {
->CalculateThreadStopInfo(this);
return false;
}
+
+llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
+ThreadGDBRemote::GetSiginfo(size_t max_size) const {
+ ProcessSP process_sp(GetProcess());
+ if (!process_sp)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "no process");
+ ProcessGDBRemote *gdb_process =
+ static_cast<ProcessGDBRemote *>(process_sp.get());
+ if (!gdb_process->m_gdb_comm.GetQXferSigInfoReadSupported())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "qXfer:siginfo:read not supported");
+
+ llvm::Expected<std::string> response =
+ gdb_process->m_gdb_comm.ReadExtFeature("siginfo", "");
+ if (!response)
+ return response.takeError();
+
+ return llvm::MemoryBuffer::getMemBufferCopy(response.get());
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
index b7d75021c062..fb83c74fd2c5 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
@@ -90,6 +90,9 @@ public:
StructuredData::ObjectSP FetchThreadExtendedInfo() override;
+ llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
+ GetSiginfo(size_t max_size) const override;
+
protected:
friend class ProcessGDBRemote;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
index cb21a3e7e65f..5eb7cb0e6a5c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
@@ -164,9 +164,6 @@ Status ScriptedProcess::DoLaunch(Module *exe_module,
SetPrivateState(eStateStopped);
- UpdateThreadListIfNeeded();
- GetThreadList();
-
return {};
}
@@ -225,8 +222,8 @@ bool ScriptedProcess::IsAlive() {
size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
Status &error) {
if (!m_interpreter)
- return GetInterface().ErrorWithMessage<size_t>(LLVM_PRETTY_FUNCTION,
- "No interpreter.", error);
+ return ScriptedInterface::ErrorWithMessage<size_t>(
+ LLVM_PRETTY_FUNCTION, "No interpreter.", error);
lldb::DataExtractorSP data_extractor_sp =
GetInterface().ReadMemoryAtAddress(addr, size, error);
@@ -238,7 +235,7 @@ size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
0, data_extractor_sp->GetByteSize(), buf, size, GetByteOrder());
if (!bytes_copied || bytes_copied == LLDB_INVALID_OFFSET)
- return GetInterface().ErrorWithMessage<size_t>(
+ return ScriptedInterface::ErrorWithMessage<size_t>(
LLVM_PRETTY_FUNCTION, "Failed to copy read memory to buffer.", error);
return size;
@@ -296,7 +293,7 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list,
ScriptLanguage language = m_interpreter->GetLanguage();
if (language != eScriptLanguagePython)
- return GetInterface().ErrorWithMessage<bool>(
+ return ScriptedInterface::ErrorWithMessage<bool>(
LLVM_PRETTY_FUNCTION,
llvm::Twine("ScriptInterpreter language (" +
llvm::Twine(m_interpreter->LanguageToString(language)) +
@@ -304,19 +301,57 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list,
.str(),
error);
- lldb::ThreadSP thread_sp;
- thread_sp = std::make_shared<ScriptedThread>(*this, error);
+ StructuredData::DictionarySP thread_info_sp = GetInterface().GetThreadsInfo();
+
+ if (!thread_info_sp)
+ return ScriptedInterface::ErrorWithMessage<bool>(
+ LLVM_PRETTY_FUNCTION,
+ "Couldn't fetch thread list from Scripted Process.", error);
+
+ auto create_scripted_thread =
+ [this, &old_thread_list, &error,
+ &new_thread_list](ConstString key, StructuredData::Object *val) -> bool {
+ if (!val)
+ return ScriptedInterface::ErrorWithMessage<bool>(
+ LLVM_PRETTY_FUNCTION, "Invalid thread info object", error);
+
+ lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
+ if (!llvm::to_integer(key.AsCString(), tid))
+ return ScriptedInterface::ErrorWithMessage<bool>(
+ LLVM_PRETTY_FUNCTION, "Invalid thread id", error);
+
+ if (ThreadSP thread_sp =
+ old_thread_list.FindThreadByID(tid, false /*=can_update*/)) {
+ // If the thread was already in the old_thread_list,
+ // just add it back to the new_thread_list.
+ new_thread_list.AddThread(thread_sp);
+ return true;
+ }
+
+ auto thread_or_error = ScriptedThread::Create(*this, val->GetAsGeneric());
+
+ if (!thread_or_error)
+ return ScriptedInterface::ErrorWithMessage<bool>(
+ LLVM_PRETTY_FUNCTION, toString(thread_or_error.takeError()), error);
+
+ ThreadSP thread_sp = thread_or_error.get();
+ lldbassert(thread_sp && "Couldn't initialize scripted thread.");
+
+ RegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext();
+ if (!reg_ctx_sp)
+ return ScriptedInterface::ErrorWithMessage<bool>(
+ LLVM_PRETTY_FUNCTION,
+ llvm::Twine("Invalid Register Context for thread " +
+ llvm::Twine(key.AsCString()))
+ .str(),
+ error);
- if (!thread_sp || error.Fail())
- return GetInterface().ErrorWithMessage<bool>(LLVM_PRETTY_FUNCTION,
- error.AsCString(), error);
+ new_thread_list.AddThread(thread_sp);
- RegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext();
- if (!reg_ctx_sp)
- return GetInterface().ErrorWithMessage<bool>(
- LLVM_PRETTY_FUNCTION, "Invalid Register Context", error);
+ return true;
+ };
- new_thread_list.AddThread(thread_sp);
+ thread_info_sp->ForEach(create_scripted_thread);
return new_thread_list.GetSize(false) > 0;
}
@@ -324,7 +359,6 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list,
void ScriptedProcess::RefreshStateAfterStop() {
// Let all threads recover from stopping and do any clean up based on the
// previous thread state (if any).
- m_thread_list.RefreshStateAfterStop();
}
bool ScriptedProcess::GetProcessInfo(ProcessInstanceInfo &info) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
index 959b8c581885..b6cbb62fd6e6 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
@@ -28,44 +28,60 @@ void ScriptedThread::CheckInterpreterAndScriptObject() const {
lldbassert(GetInterface() && "Invalid Scripted Thread Interface.");
}
-ScriptedThread::ScriptedThread(ScriptedProcess &process, Status &error)
- : Thread(process, LLDB_INVALID_THREAD_ID), m_scripted_process(process) {
- if (!process.IsValid()) {
- error.SetErrorString("Invalid scripted process");
- return;
- }
+llvm::Expected<std::shared_ptr<ScriptedThread>>
+ScriptedThread::Create(ScriptedProcess &process,
+ StructuredData::Generic *script_object) {
+ if (!process.IsValid())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Invalid scripted process.");
process.CheckInterpreterAndScriptObject();
- auto scripted_thread_interface = GetInterface();
- if (!scripted_thread_interface) {
- error.SetErrorString("Failed to get scripted thread interface.");
- return;
- }
-
- llvm::Optional<std::string> class_name =
- process.GetInterface().GetScriptedThreadPluginName();
- if (!class_name || class_name->empty()) {
- error.SetErrorString("Failed to get scripted thread class name.");
- return;
+ auto scripted_thread_interface =
+ process.GetInterface().CreateScriptedThreadInterface();
+ if (!scripted_thread_interface)
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "Failed to create scripted thread interface.");
+
+ llvm::StringRef thread_class_name;
+ if (!script_object) {
+ llvm::Optional<std::string> class_name =
+ process.GetInterface().GetScriptedThreadPluginName();
+ if (!class_name || class_name->empty())
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "Failed to get scripted thread class name.");
+ thread_class_name = *class_name;
}
ExecutionContext exe_ctx(process);
-
- StructuredData::GenericSP object_sp =
+ StructuredData::GenericSP owned_script_object_sp =
scripted_thread_interface->CreatePluginObject(
- class_name->c_str(), exe_ctx,
- process.m_scripted_process_info.GetArgsSP());
- if (!object_sp || !object_sp->IsValid()) {
- error.SetErrorString("Failed to create valid script object");
- return;
- }
+ thread_class_name, exe_ctx,
+ process.m_scripted_process_info.GetArgsSP(), script_object);
- m_script_object_sp = object_sp;
+ if (!owned_script_object_sp)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Failed to create script object.");
+ if (!owned_script_object_sp->IsValid())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Created script object is invalid.");
- SetID(scripted_thread_interface->GetThreadID());
+ lldb::tid_t tid = scripted_thread_interface->GetThreadID();
+
+ return std::make_shared<ScriptedThread>(process, scripted_thread_interface,
+ tid, owned_script_object_sp);
}
+ScriptedThread::ScriptedThread(ScriptedProcess &process,
+ ScriptedThreadInterfaceSP interface_sp,
+ lldb::tid_t tid,
+ StructuredData::GenericSP script_object_sp)
+ : Thread(process, tid), m_scripted_process(process),
+ m_scripted_thread_interface_sp(interface_sp),
+ m_script_object_sp(script_object_sp) {}
+
ScriptedThread::~ScriptedThread() { DestroyThread(); }
const char *ScriptedThread::GetName() {
@@ -137,6 +153,11 @@ bool ScriptedThread::CalculateStopInfo() {
StructuredData::DictionarySP dict_sp = GetInterface()->GetStopReason();
Status error;
+ if (!dict_sp)
+ return GetInterface()->ErrorWithMessage<bool>(
+ LLVM_PRETTY_FUNCTION, "Failed to get scripted thread stop info.", error,
+ LIBLLDB_LOG_THREAD);
+
lldb::StopInfoSP stop_info_sp;
lldb::StopReason stop_reason_type;
@@ -150,12 +171,12 @@ bool ScriptedThread::CalculateStopInfo() {
if (!dict_sp->GetValueForKeyAsDictionary("data", data_dict))
return GetInterface()->ErrorWithMessage<bool>(
LLVM_PRETTY_FUNCTION,
- "Couldn't find value for key 'type' in stop reason dictionary.", error,
+ "Couldn't find value for key 'data' in stop reason dictionary.", error,
LIBLLDB_LOG_THREAD);
switch (stop_reason_type) {
case lldb::eStopReasonNone:
- break;
+ return true;
case lldb::eStopReasonBreakpoint: {
lldb::break_id_t break_id;
data_dict->GetValueForKeyAsInteger("break_id", break_id,
@@ -172,6 +193,13 @@ bool ScriptedThread::CalculateStopInfo() {
stop_info_sp =
StopInfo::CreateStopReasonWithSignal(*this, signal, description.data());
} break;
+ case lldb::eStopReasonException: {
+ llvm::StringRef description;
+ data_dict->GetValueForKeyAsString("desc", description);
+
+ stop_info_sp =
+ StopInfo::CreateStopReasonWithException(*this, description.data());
+ } break;
default:
return GetInterface()->ErrorWithMessage<bool>(
LLVM_PRETTY_FUNCTION,
@@ -181,6 +209,9 @@ bool ScriptedThread::CalculateStopInfo() {
error, LIBLLDB_LOG_THREAD);
}
+ if (!stop_info_sp)
+ return false;
+
SetStopInfo(stop_info_sp);
return true;
}
@@ -190,7 +221,7 @@ void ScriptedThread::RefreshStateAfterStop() {
}
lldb::ScriptedThreadInterfaceSP ScriptedThread::GetInterface() const {
- return m_scripted_process.GetInterface().GetScriptedThreadInterface();
+ return m_scripted_thread_interface_sp;
}
std::shared_ptr<DynamicRegisterInfo> ScriptedThread::GetDynamicRegisterInfo() {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.h b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.h
index cdcd543702a4..8d8a7c2a3df9 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.h
@@ -25,11 +25,18 @@ class ScriptedProcess;
namespace lldb_private {
class ScriptedThread : public lldb_private::Thread {
+
public:
- ScriptedThread(ScriptedProcess &process, Status &error);
+ ScriptedThread(ScriptedProcess &process,
+ lldb::ScriptedThreadInterfaceSP interface_sp, lldb::tid_t tid,
+ StructuredData::GenericSP script_object_sp = nullptr);
~ScriptedThread() override;
+ static llvm::Expected<std::shared_ptr<ScriptedThread>>
+ Create(ScriptedProcess &process,
+ StructuredData::Generic *script_object = nullptr);
+
lldb::RegisterContextSP GetRegisterContext() override;
lldb::RegisterContextSP
@@ -59,8 +66,9 @@ private:
std::shared_ptr<DynamicRegisterInfo> GetDynamicRegisterInfo();
const ScriptedProcess &m_scripted_process;
+ lldb::ScriptedThreadInterfaceSP m_scripted_thread_interface_sp = nullptr;
+ lldb_private::StructuredData::GenericSP m_script_object_sp = nullptr;
std::shared_ptr<DynamicRegisterInfo> m_register_info_sp = nullptr;
- lldb_private::StructuredData::ObjectSP m_script_object_sp = nullptr;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index 7c71c9329e57..68f4e90d70f6 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -69,6 +69,30 @@ Expected<std::string> python::As<std::string>(Expected<PythonObject> &&obj) {
return std::string(utf8.get());
}
+static bool python_is_finalizing() {
+#if PY_MAJOR_VERSION == 2
+ return false;
+#elif PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 7
+ return _Py_Finalizing != nullptr;
+#else
+ return _Py_IsFinalizing();
+#endif
+}
+
+void PythonObject::Reset() {
+ if (m_py_obj && Py_IsInitialized()) {
+ if (python_is_finalizing()) {
+ // Leak m_py_obj rather than crashing the process.
+ // https://docs.python.org/3/c-api/init.html#c.PyGILState_Ensure
+ } else {
+ PyGILState_STATE state = PyGILState_Ensure();
+ Py_DECREF(m_py_obj);
+ PyGILState_Release(state);
+ }
+ }
+ m_py_obj = nullptr;
+}
+
Expected<long long> PythonObject::AsLongLong() const {
if (!m_py_obj)
return nullDeref();
@@ -257,6 +281,9 @@ PythonObject PythonObject::GetAttributeValue(llvm::StringRef attr) const {
}
StructuredData::ObjectSP PythonObject::CreateStructuredObject() const {
+#if PY_MAJOR_VERSION >= 3
+ assert(PyGILState_Check());
+#endif
switch (GetObjectType()) {
case PyObjectType::Dictionary:
return PythonDictionary(PyRefType::Borrowed, m_py_obj)
@@ -279,7 +306,8 @@ StructuredData::ObjectSP PythonObject::CreateStructuredObject() const {
case PyObjectType::None:
return StructuredData::ObjectSP();
default:
- return StructuredData::ObjectSP(new StructuredPythonObject(m_py_obj));
+ return StructuredData::ObjectSP(new StructuredPythonObject(
+ PythonObject(PyRefType::Borrowed, m_py_obj)));
}
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
index 56bc55d239d1..2094f0b3afd2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
@@ -83,30 +83,6 @@ protected:
PyGILState_STATE m_state;
};
-class StructuredPythonObject : public StructuredData::Generic {
-public:
- StructuredPythonObject() : StructuredData::Generic() {}
-
- StructuredPythonObject(void *obj) : StructuredData::Generic(obj) {
- Py_XINCREF(GetValue());
- }
-
- ~StructuredPythonObject() override {
- if (Py_IsInitialized())
- Py_XDECREF(GetValue());
- SetValue(nullptr);
- }
-
- bool IsValid() const override { return GetValue() && GetValue() != Py_None; }
-
- void Serialize(llvm::json::OStream &s) const override;
-
-private:
- StructuredPythonObject(const StructuredPythonObject &) = delete;
- const StructuredPythonObject &
- operator=(const StructuredPythonObject &) = delete;
-};
-
enum class PyObjectType {
Unknown,
None,
@@ -263,11 +239,7 @@ public:
~PythonObject() { Reset(); }
- void Reset() {
- if (m_py_obj && Py_IsInitialized())
- Py_DECREF(m_py_obj);
- m_py_obj = nullptr;
- }
+ void Reset();
void Dump() const {
if (m_py_obj)
@@ -767,6 +739,30 @@ public:
}
};
+class StructuredPythonObject : public StructuredData::Generic {
+public:
+ StructuredPythonObject() : StructuredData::Generic() {}
+
+ // Take ownership of the object we received.
+ StructuredPythonObject(PythonObject obj)
+ : StructuredData::Generic(obj.release()) {}
+
+ ~StructuredPythonObject() override {
+ // Hand ownership back to a (temporary) PythonObject instance and let it
+ // take care of releasing it.
+ PythonObject(PyRefType::Owned, static_cast<PyObject *>(GetValue()));
+ }
+
+ bool IsValid() const override { return GetValue() && GetValue() != Py_None; }
+
+ void Serialize(llvm::json::OStream &s) const override;
+
+private:
+ StructuredPythonObject(const StructuredPythonObject &) = delete;
+ const StructuredPythonObject &
+ operator=(const StructuredPythonObject &) = delete;
+};
+
} // namespace python
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
index 2bb69dc47731..4df235356737 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
@@ -18,6 +18,7 @@
// LLDB Python header must be included first
#include "lldb-python.h"
+#include "Plugins/ScriptInterpreter/Python/PythonDataObjects.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-types.h"
#include "llvm/Support/Error.h"
@@ -54,17 +55,15 @@ void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data);
// Although these are scripting-language specific, their definition depends on
// the public API.
-void *LLDBSwigPythonCreateScriptedProcess(const char *python_class_name,
- const char *session_dictionary_name,
- const lldb::TargetSP &target_sp,
- const StructuredDataImpl &args_impl,
- std::string &error_string);
+python::PythonObject LLDBSwigPythonCreateScriptedProcess(
+ const char *python_class_name, const char *session_dictionary_name,
+ const lldb::TargetSP &target_sp, const StructuredDataImpl &args_impl,
+ std::string &error_string);
-void *LLDBSwigPythonCreateScriptedThread(const char *python_class_name,
- const char *session_dictionary_name,
- const lldb::ProcessSP &process_sp,
- const StructuredDataImpl &args_impl,
- std::string &error_string);
+python::PythonObject LLDBSwigPythonCreateScriptedThread(
+ const char *python_class_name, const char *session_dictionary_name,
+ const lldb::ProcessSP &process_sp, const StructuredDataImpl &args_impl,
+ std::string &error_string);
llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction(
const char *python_function_name, const char *session_dictionary_name,
@@ -83,16 +82,17 @@ bool LLDBSwigPythonCallTypeScript(const char *python_function_name,
const lldb::TypeSummaryOptionsSP &options_sp,
std::string &retval);
-void *
+python::PythonObject
LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name,
const char *session_dictionary_name,
const lldb::ValueObjectSP &valobj_sp);
-void *LLDBSwigPythonCreateCommandObject(const char *python_class_name,
- const char *session_dictionary_name,
- lldb::DebuggerSP debugger_sp);
+python::PythonObject
+LLDBSwigPythonCreateCommandObject(const char *python_class_name,
+ const char *session_dictionary_name,
+ lldb::DebuggerSP debugger_sp);
-void *LLDBSwigPythonCreateScriptedThreadPlan(
+python::PythonObject LLDBSwigPythonCreateScriptedThreadPlan(
const char *python_class_name, const char *session_dictionary_name,
const StructuredDataImpl &args_data, std::string &error_string,
const lldb::ThreadPlanSP &thread_plan_sp);
@@ -101,7 +101,7 @@ bool LLDBSWIGPythonCallThreadPlan(void *implementor, const char *method_name,
lldb_private::Event *event_sp,
bool &got_error);
-void *LLDBSwigPythonCreateScriptedBreakpointResolver(
+python::PythonObject LLDBSwigPythonCreateScriptedBreakpointResolver(
const char *python_class_name, const char *session_dictionary_name,
const StructuredDataImpl &args, const lldb::BreakpointSP &bkpt_sp);
@@ -109,11 +109,10 @@ unsigned int
LLDBSwigPythonCallBreakpointResolver(void *implementor, const char *method_name,
lldb_private::SymbolContext *sym_ctx);
-void *LLDBSwigPythonCreateScriptedStopHook(lldb::TargetSP target_sp,
- const char *python_class_name,
- const char *session_dictionary_name,
- const StructuredDataImpl &args,
- lldb_private::Status &error);
+python::PythonObject LLDBSwigPythonCreateScriptedStopHook(
+ lldb::TargetSP target_sp, const char *python_class_name,
+ const char *session_dictionary_name, const StructuredDataImpl &args,
+ lldb_private::Status &error);
bool LLDBSwigPythonStopHookCallHandleStop(void *implementor,
lldb::ExecutionContextRefSP exc_ctx,
@@ -150,12 +149,14 @@ bool LLDBSwigPythonCallModuleInit(const char *python_module_name,
const char *session_dictionary_name,
lldb::DebuggerSP debugger);
-void *LLDBSWIGPythonCreateOSPlugin(const char *python_class_name,
- const char *session_dictionary_name,
- const lldb::ProcessSP &process_sp);
+python::PythonObject
+LLDBSWIGPythonCreateOSPlugin(const char *python_class_name,
+ const char *session_dictionary_name,
+ const lldb::ProcessSP &process_sp);
-void *LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name,
- const char *session_dictionary_name);
+python::PythonObject
+LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name,
+ const char *session_dictionary_name);
PyObject *
LLDBSwigPython_GetRecognizedArguments(PyObject *implementor,
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 6afa4742698b..1bf647e4acfc 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -37,7 +37,7 @@
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
-#include "lldb/Utility/ReproducerInstrumentation.h"
+#include "lldb/Utility/Instrumentation.h"
#include "lldb/Utility/Timer.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
@@ -70,6 +70,14 @@ extern "C" void init_lldb(void);
#define LLDBSwigPyInit init_lldb
#endif
+#if defined(_WIN32)
+// Don't mess with the signal handlers on Windows.
+#define LLDB_USE_PYTHON_SET_INTERRUPT 0
+#else
+// PyErr_SetInterrupt was introduced in 3.2.
+#define LLDB_USE_PYTHON_SET_INTERRUPT \
+ (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 2) || (PY_MAJOR_VERSION > 3)
+#endif
static ScriptInterpreterPythonImpl *GetPythonInterpreter(Debugger &debugger) {
ScriptInterpreter *script_interpreter =
@@ -77,8 +85,6 @@ static ScriptInterpreterPythonImpl *GetPythonInterpreter(Debugger &debugger) {
return static_cast<ScriptInterpreterPythonImpl *>(script_interpreter);
}
-static bool g_initialized = false;
-
namespace {
// Initializing Python is not a straightforward process. We cannot control
@@ -211,6 +217,28 @@ private:
PyGILState_STATE m_gil_state = PyGILState_UNLOCKED;
bool m_was_already_initialized = false;
};
+
+#if LLDB_USE_PYTHON_SET_INTERRUPT
+/// Saves the current signal handler for the specified signal and restores
+/// it at the end of the current scope.
+struct RestoreSignalHandlerScope {
+ /// The signal handler.
+ struct sigaction m_prev_handler;
+ int m_signal_code;
+ RestoreSignalHandlerScope(int signal_code) : m_signal_code(signal_code) {
+ // Initialize sigaction to their default state.
+ std::memset(&m_prev_handler, 0, sizeof(m_prev_handler));
+ // Don't install a new handler, just read back the old one.
+ struct sigaction *new_handler = nullptr;
+ int signal_err = ::sigaction(m_signal_code, new_handler, &m_prev_handler);
+ lldbassert(signal_err == 0 && "sigaction failed to read handler");
+ }
+ ~RestoreSignalHandlerScope() {
+ int signal_err = ::sigaction(m_signal_code, &m_prev_handler, nullptr);
+ lldbassert(signal_err == 0 && "sigaction failed to restore old handler");
+ }
+};
+#endif
} // namespace
void ScriptInterpreterPython::ComputePythonDirForApple(
@@ -325,12 +353,12 @@ llvm::StringRef ScriptInterpreterPython::GetPluginDescriptionStatic() {
void ScriptInterpreterPython::Initialize() {
static llvm::once_flag g_once_flag;
-
llvm::call_once(g_once_flag, []() {
PluginManager::RegisterPlugin(GetPluginNameStatic(),
GetPluginDescriptionStatic(),
lldb::eScriptLanguagePython,
ScriptInterpreterPythonImpl::CreateInstance);
+ ScriptInterpreterPythonImpl::Initialize();
});
}
@@ -342,7 +370,6 @@ ScriptInterpreterPythonImpl::Locker::Locker(
: ScriptInterpreterLocker(),
m_teardown_session((on_leave & TearDownSession) == TearDownSession),
m_python_interpreter(py_interpreter) {
- repro::Recorder::PrivateThread();
DoAcquireLock();
if ((on_entry & InitSession) == InitSession) {
if (!DoInitSession(on_entry, in, out, err)) {
@@ -408,8 +435,6 @@ ScriptInterpreterPythonImpl::ScriptInterpreterPythonImpl(Debugger &debugger)
m_active_io_handler(eIOHandlerNone), m_session_is_active(false),
m_pty_secondary_is_open(false), m_valid_session(true), m_lock_count(0),
m_command_thread_state(nullptr) {
- InitializePrivate();
-
m_scripted_process_interface_up =
std::make_unique<ScriptedProcessPythonInterface>(*this);
@@ -921,6 +946,22 @@ void ScriptInterpreterPythonImpl::ExecuteInterpreterLoop() {
}
bool ScriptInterpreterPythonImpl::Interrupt() {
+#if LLDB_USE_PYTHON_SET_INTERRUPT
+ // If the interpreter isn't evaluating any Python at the moment then return
+ // false to signal that this function didn't handle the interrupt and the
+ // next component should try handling it.
+ if (!IsExecutingPython())
+ return false;
+
+ // Tell Python that it should pretend to have received a SIGINT.
+ PyErr_SetInterrupt();
+ // PyErr_SetInterrupt has no way to return an error so we can only pretend the
+ // signal got successfully handled and return true.
+ // Python 3.10 introduces PyErr_SetInterruptEx that could return an error, but
+ // the error handling is limited to checking the arguments which would be
+ // just our (hardcoded) input signal code SIGINT, so that's not useful at all.
+ return true;
+#else
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT));
if (IsExecutingPython()) {
@@ -942,6 +983,7 @@ bool ScriptInterpreterPythonImpl::Interrupt() {
"ScriptInterpreterPythonImpl::Interrupt() python code not running, "
"can't interrupt");
return false;
+#endif
}
bool ScriptInterpreterPythonImpl::ExecuteOneLineWithReturn(
@@ -1414,16 +1456,12 @@ ScriptInterpreterPythonImpl::CreateFrameRecognizer(const char *class_name) {
if (class_name == nullptr || class_name[0] == '\0')
return StructuredData::GenericSP();
- void *ret_val;
-
- {
- Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN,
- Locker::FreeLock);
- ret_val = LLDBSWIGPython_CreateFrameRecognizer(class_name,
- m_dictionary_name.c_str());
- }
+ Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
+ PythonObject ret_val = LLDBSWIGPython_CreateFrameRecognizer(
+ class_name, m_dictionary_name.c_str());
- return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
+ return StructuredData::GenericSP(
+ new StructuredPythonObject(std::move(ret_val)));
}
lldb::ValueObjectListSP ScriptInterpreterPythonImpl::GetRecognizedArguments(
@@ -1478,16 +1516,12 @@ ScriptInterpreterPythonImpl::OSPlugin_CreatePluginObject(
if (!process_sp)
return StructuredData::GenericSP();
- void *ret_val;
-
- {
- Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN,
- Locker::FreeLock);
- ret_val = LLDBSWIGPythonCreateOSPlugin(
- class_name, m_dictionary_name.c_str(), process_sp);
- }
+ Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
+ PythonObject ret_val = LLDBSWIGPythonCreateOSPlugin(
+ class_name, m_dictionary_name.c_str(), process_sp);
- return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
+ return StructuredData::GenericSP(
+ new StructuredPythonObject(std::move(ret_val)));
}
StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_RegisterInfo(
@@ -1733,19 +1767,16 @@ StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan(
if (!python_interpreter)
return {};
- void *ret_val;
-
- {
- Locker py_lock(this,
- Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = LLDBSwigPythonCreateScriptedThreadPlan(
- class_name, python_interpreter->m_dictionary_name.c_str(),
- args_data, error_str, thread_plan_sp);
- if (!ret_val)
- return {};
- }
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ PythonObject ret_val = LLDBSwigPythonCreateScriptedThreadPlan(
+ class_name, python_interpreter->m_dictionary_name.c_str(), args_data,
+ error_str, thread_plan_sp);
+ if (!ret_val)
+ return {};
- return StructuredData::ObjectSP(new StructuredPythonObject(ret_val));
+ return StructuredData::ObjectSP(
+ new StructuredPythonObject(std::move(ret_val)));
}
bool ScriptInterpreterPythonImpl::ScriptedThreadPlanExplainsStop(
@@ -1836,18 +1867,15 @@ ScriptInterpreterPythonImpl::CreateScriptedBreakpointResolver(
if (!python_interpreter)
return StructuredData::GenericSP();
- void *ret_val;
-
- {
- Locker py_lock(this,
- Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = LLDBSwigPythonCreateScriptedBreakpointResolver(
- class_name, python_interpreter->m_dictionary_name.c_str(), args_data,
- bkpt_sp);
- }
+ PythonObject ret_val = LLDBSwigPythonCreateScriptedBreakpointResolver(
+ class_name, python_interpreter->m_dictionary_name.c_str(), args_data,
+ bkpt_sp);
- return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
+ return StructuredData::GenericSP(
+ new StructuredPythonObject(std::move(ret_val)));
}
bool ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchCallback(
@@ -1911,18 +1939,15 @@ StructuredData::GenericSP ScriptInterpreterPythonImpl::CreateScriptedStopHook(
return StructuredData::GenericSP();
}
- void *ret_val;
-
- {
- Locker py_lock(this,
- Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = LLDBSwigPythonCreateScriptedStopHook(
- target_sp, class_name, python_interpreter->m_dictionary_name.c_str(),
- args_data, error);
- }
+ PythonObject ret_val = LLDBSwigPythonCreateScriptedStopHook(
+ target_sp, class_name, python_interpreter->m_dictionary_name.c_str(),
+ args_data, error);
- return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
+ return StructuredData::GenericSP(
+ new StructuredPythonObject(std::move(ret_val)));
}
bool ScriptInterpreterPythonImpl::ScriptedStopHookHandleStop(
@@ -2011,16 +2036,13 @@ ScriptInterpreterPythonImpl::CreateSyntheticScriptedProvider(
if (!python_interpreter)
return StructuredData::ObjectSP();
- void *ret_val = nullptr;
-
- {
- Locker py_lock(this,
- Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = LLDBSwigPythonCreateSyntheticProvider(
- class_name, python_interpreter->m_dictionary_name.c_str(), valobj);
- }
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ PythonObject ret_val = LLDBSwigPythonCreateSyntheticProvider(
+ class_name, python_interpreter->m_dictionary_name.c_str(), valobj);
- return StructuredData::ObjectSP(new StructuredPythonObject(ret_val));
+ return StructuredData::ObjectSP(
+ new StructuredPythonObject(std::move(ret_val)));
}
StructuredData::GenericSP
@@ -2033,16 +2055,13 @@ ScriptInterpreterPythonImpl::CreateScriptCommandObject(const char *class_name) {
if (!debugger_sp.get())
return StructuredData::GenericSP();
- void *ret_val;
-
- {
- Locker py_lock(this,
- Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = LLDBSwigPythonCreateCommandObject(
- class_name, m_dictionary_name.c_str(), debugger_sp);
- }
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ PythonObject ret_val = LLDBSwigPythonCreateCommandObject(
+ class_name, m_dictionary_name.c_str(), debugger_sp);
- return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
+ return StructuredData::GenericSP(
+ new StructuredPythonObject(std::move(ret_val)));
}
bool ScriptInterpreterPythonImpl::GenerateTypeScriptFunction(
@@ -2152,8 +2171,12 @@ bool ScriptInterpreterPythonImpl::GetScriptedSummary(
return false;
}
- if (new_callee && old_callee != new_callee)
- callee_wrapper_sp = std::make_shared<StructuredPythonObject>(new_callee);
+ if (new_callee && old_callee != new_callee) {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ callee_wrapper_sp = std::make_shared<StructuredPythonObject>(
+ PythonObject(PyRefType::Borrowed, static_cast<PyObject *>(new_callee)));
+ }
return ret_val;
}
@@ -2805,7 +2828,8 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule(
ScriptInterpreter::eScriptReturnTypeOpaqueObject, &module_pyobj,
exc_options) &&
module_pyobj)
- *module_sp = std::make_shared<StructuredPythonObject>(module_pyobj);
+ *module_sp = std::make_shared<StructuredPythonObject>(PythonObject(
+ PyRefType::Owned, static_cast<PyObject *>(module_pyobj)));
}
return true;
@@ -3145,12 +3169,7 @@ ScriptInterpreterPythonImpl::AcquireInterpreterLock() {
return py_lock;
}
-void ScriptInterpreterPythonImpl::InitializePrivate() {
- if (g_initialized)
- return;
-
- g_initialized = true;
-
+void ScriptInterpreterPythonImpl::Initialize() {
LLDB_SCOPED_TIMER();
// RAII-based initialization which correctly handles multiple-initialization,
@@ -3180,6 +3199,25 @@ void ScriptInterpreterPythonImpl::InitializePrivate() {
"lldb.embedded_interpreter; from "
"lldb.embedded_interpreter import run_python_interpreter; "
"from lldb.embedded_interpreter import run_one_line");
+
+#if LLDB_USE_PYTHON_SET_INTERRUPT
+ // Python will not just overwrite its internal SIGINT handler but also the
+ // one from the process. Backup the current SIGINT handler to prevent that
+ // Python deletes it.
+ RestoreSignalHandlerScope save_sigint(SIGINT);
+
+ // Setup a default SIGINT signal handler that works the same way as the
+ // normal Python REPL signal handler which raises a KeyboardInterrupt.
+ // Also make sure to not pollute the user's REPL with the signal module nor
+ // our utility function.
+ PyRun_SimpleString("def lldb_setup_sigint_handler():\n"
+ " import signal;\n"
+ " def signal_handler(sig, frame):\n"
+ " raise KeyboardInterrupt()\n"
+ " signal.signal(signal.SIGINT, signal_handler);\n"
+ "lldb_setup_sigint_handler();\n"
+ "del lldb_setup_sigint_handler\n");
+#endif
}
void ScriptInterpreterPythonImpl::AddToSysPath(AddLocation location,
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
index defc2acffcfa..3b80c67d201a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -341,7 +341,7 @@ public:
static bool WatchpointCallbackFunction(void *baton,
StoppointCallbackContext *context,
lldb::user_id_t watch_id);
- static void InitializePrivate();
+ static void Initialize();
class SynchronicityHandler {
private:
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
index e3c1931a565a..e39f8be73e49 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
@@ -32,7 +32,7 @@ ScriptedProcessPythonInterface::ScriptedProcessPythonInterface(
StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject(
llvm::StringRef class_name, ExecutionContext &exe_ctx,
- StructuredData::DictionarySP args_sp) {
+ StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
if (class_name.empty())
return {};
@@ -43,15 +43,12 @@ StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject(
Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
Locker::FreeLock);
- void *ret_val = LLDBSwigPythonCreateScriptedProcess(
+ PythonObject ret_val = LLDBSwigPythonCreateScriptedProcess(
class_name.str().c_str(), m_interpreter.GetDictionaryName(), target_sp,
args_impl, error_string);
- if (!ret_val)
- return {};
-
m_object_instance_sp =
- StructuredData::GenericSP(new StructuredPythonObject(ret_val));
+ StructuredData::GenericSP(new StructuredPythonObject(std::move(ret_val)));
return m_object_instance_sp;
}
@@ -92,6 +89,17 @@ ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress(
return mem_region;
}
+StructuredData::DictionarySP ScriptedProcessPythonInterface::GetThreadsInfo() {
+ Status error;
+ StructuredData::DictionarySP dict =
+ Dispatch<StructuredData::DictionarySP>("get_threads_info", error);
+
+ if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
+ return {};
+
+ return dict;
+}
+
StructuredData::DictionarySP
ScriptedProcessPythonInterface::GetThreadWithID(lldb::tid_t tid) {
Status error;
@@ -154,12 +162,8 @@ ScriptedProcessPythonInterface::GetScriptedThreadPluginName() {
}
lldb::ScriptedThreadInterfaceSP
-ScriptedProcessPythonInterface::GetScriptedThreadInterface() {
- if (!m_scripted_thread_interface_sp)
- m_scripted_thread_interface_sp =
- std::make_shared<ScriptedThreadPythonInterface>(m_interpreter);
-
- return m_scripted_thread_interface_sp;
+ScriptedProcessPythonInterface::CreateScriptedThreadInterface() {
+ return std::make_shared<ScriptedThreadPythonInterface>(m_interpreter);
}
#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
index 421bdd59887c..e34a181849eb 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
@@ -25,7 +25,8 @@ public:
StructuredData::GenericSP
CreatePluginObject(const llvm::StringRef class_name,
ExecutionContext &exe_ctx,
- StructuredData::DictionarySP args_sp) override;
+ StructuredData::DictionarySP args_sp,
+ StructuredData::Generic *script_obj = nullptr) override;
Status Launch() override;
@@ -39,6 +40,8 @@ public:
GetMemoryRegionContainingAddress(lldb::addr_t address,
Status &error) override;
+ StructuredData::DictionarySP GetThreadsInfo() override;
+
StructuredData::DictionarySP GetThreadWithID(lldb::tid_t tid) override;
StructuredData::DictionarySP GetRegistersForThread(lldb::tid_t tid) override;
@@ -55,7 +58,7 @@ public:
llvm::Optional<std::string> GetScriptedThreadPluginName() override;
private:
- lldb::ScriptedThreadInterfaceSP GetScriptedThreadInterface() override;
+ lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
index 6a881bfe625c..d471b2c5f7e3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
@@ -31,9 +31,8 @@ ScriptedThreadPythonInterface::ScriptedThreadPythonInterface(
StructuredData::GenericSP ScriptedThreadPythonInterface::CreatePluginObject(
const llvm::StringRef class_name, ExecutionContext &exe_ctx,
- StructuredData::DictionarySP args_sp) {
-
- if (class_name.empty())
+ StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
+ if (class_name.empty() && !script_obj)
return {};
ProcessSP process_sp = exe_ctx.GetProcessSP();
@@ -43,15 +42,21 @@ StructuredData::GenericSP ScriptedThreadPythonInterface::CreatePluginObject(
Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
Locker::FreeLock);
- void *ret_val = LLDBSwigPythonCreateScriptedThread(
- class_name.str().c_str(), m_interpreter.GetDictionaryName(), process_sp,
- args_impl, error_string);
+ PythonObject ret_val;
+
+ if (!script_obj)
+ ret_val = LLDBSwigPythonCreateScriptedThread(
+ class_name.str().c_str(), m_interpreter.GetDictionaryName(), process_sp,
+ args_impl, error_string);
+ else
+ ret_val = PythonObject(PyRefType::Borrowed,
+ static_cast<PyObject *>(script_obj->GetValue()));
if (!ret_val)
return {};
m_object_instance_sp =
- StructuredData::GenericSP(new StructuredPythonObject(ret_val));
+ StructuredData::GenericSP(new StructuredPythonObject(std::move(ret_val)));
return m_object_instance_sp;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h
index 996b8d43136b..59bb182ae3f3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h
@@ -24,7 +24,8 @@ public:
StructuredData::GenericSP
CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx,
- StructuredData::DictionarySP args_sp) override;
+ StructuredData::DictionarySP args_sp,
+ StructuredData::Generic *script_obj = nullptr) override;
lldb::tid_t GetThreadID() override;
@@ -45,4 +46,4 @@ public:
} // namespace lldb_private
#endif // LLDB_ENABLE_PYTHON
-#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSTHREADINTERFACE_H
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDTHREADPYTHONINTERFACE_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/lldb-python.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/lldb-python.h
index 48f27b09b95c..c99372fa110c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/lldb-python.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/lldb-python.h
@@ -9,6 +9,13 @@
#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_LLDB_PYTHON_H
#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_LLDB_PYTHON_H
+// BEGIN FIXME
+// This declaration works around a clang module build failure.
+// It should be deleted ASAP.
+#include "llvm/Support/Error.h"
+static llvm::Expected<bool> *g_fcxx_modules_workaround;
+// END
+
#include "lldb/Host/Config.h"
// Python.h needs to be included before any system headers in order to avoid
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp
index 7a8ab9c9bcfd..25cb368763c1 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp
@@ -7,8 +7,13 @@
//===----------------------------------------------------------------------===//
#include "DIERef.h"
+#include "lldb/Utility/DataEncoder.h"
+#include "lldb/Utility/DataExtractor.h"
#include "llvm/Support/Format.h"
+using namespace lldb;
+using namespace lldb_private;
+
void llvm::format_provider<DIERef>::format(const DIERef &ref, raw_ostream &OS,
StringRef Style) {
if (ref.dwo_num())
@@ -16,3 +21,35 @@ void llvm::format_provider<DIERef>::format(const DIERef &ref, raw_ostream &OS,
OS << (ref.section() == DIERef::DebugInfo ? "INFO" : "TYPE");
OS << "/" << format_hex_no_prefix(ref.die_offset(), 8);
}
+
+constexpr uint32_t k_dwo_num_mask = 0x3FFFFFFF;
+constexpr uint32_t k_dwo_num_valid_bitmask = (1u << 30);
+constexpr uint32_t k_section_bitmask = (1u << 31);
+
+llvm::Optional<DIERef> DIERef::Decode(const DataExtractor &data,
+ lldb::offset_t *offset_ptr) {
+ const uint32_t bitfield_storage = data.GetU32(offset_ptr);
+ uint32_t dwo_num = bitfield_storage & k_dwo_num_mask;
+ bool dwo_num_valid = (bitfield_storage & (k_dwo_num_valid_bitmask)) != 0;
+ Section section = (Section)((bitfield_storage & (k_section_bitmask)) != 0);
+ // DIE offsets can't be zero and if we fail to decode something from data,
+ // it will return 0
+ dw_offset_t die_offset = data.GetU32(offset_ptr);
+ if (die_offset == 0)
+ return llvm::None;
+ if (dwo_num_valid)
+ return DIERef(dwo_num, section, die_offset);
+ else
+ return DIERef(llvm::None, section, die_offset);
+}
+
+void DIERef::Encode(DataEncoder &encoder) const {
+ uint32_t bitfield_storage = m_dwo_num;
+ if (m_dwo_num_valid)
+ bitfield_storage |= k_dwo_num_valid_bitmask;
+ if (m_section)
+ bitfield_storage |= k_section_bitmask;
+ encoder.AppendU32(bitfield_storage);
+ static_assert(sizeof(m_die_offset) == 4, "m_die_offset must be 4 bytes");
+ encoder.AppendU32(m_die_offset);
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
index f7e09ee17283..23e1eec26ec3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
@@ -54,6 +54,37 @@ public:
return m_die_offset < other.m_die_offset;
}
+ bool operator==(const DIERef &rhs) const {
+ return dwo_num() == rhs.dwo_num() && m_section == rhs.m_section &&
+ m_die_offset == rhs.m_die_offset;
+ }
+
+ bool operator!=(const DIERef &rhs) const { return !(*this == rhs); }
+
+ /// Decode a serialized version of this object from data.
+ ///
+ /// \param data
+ /// The decoder object that references the serialized data.
+ ///
+ /// \param offset_ptr
+ /// A pointer that contains the offset from which the data will be decoded
+ /// from that gets updated as data gets decoded.
+ ///
+ /// \return
+ /// Returns a valid DIERef if decoding succeeded, llvm::None if there was
+ /// unsufficient or invalid values that were decoded.
+ static llvm::Optional<DIERef> Decode(const lldb_private::DataExtractor &data,
+ lldb::offset_t *offset_ptr);
+
+ /// Encode this object into a data encoder object.
+ ///
+ /// This allows this object to be serialized to disk.
+ ///
+ /// \param encoder
+ /// A data encoder object that serialized bytes will be encoded into.
+ ///
+ void Encode(lldb_private::DataEncoder &encoder) const;
+
private:
uint32_t m_dwo_num : 30;
uint32_t m_dwo_num_valid : 1;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index b90f104c4d21..be555c130bfe 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -933,7 +933,7 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
DW_TAG_value_to_name(tag), type_name_cstr);
CompilerType return_clang_type;
- Type *func_type = NULL;
+ Type *func_type = nullptr;
if (attrs.type.IsValid())
func_type = dwarf->ResolveTypeUID(attrs.type.Reference(), true);
@@ -1027,7 +1027,7 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
class_opaque_type, attrs.name.GetCString(), clang_type,
attrs.accessibility, attrs.is_artificial, is_variadic,
attrs.is_objc_direct_call);
- type_handled = objc_method_decl != NULL;
+ type_handled = objc_method_decl != nullptr;
if (type_handled) {
LinkDeclContextToDIE(objc_method_decl, die);
m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID());
@@ -1178,7 +1178,7 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
is_static, attrs.is_inline, attrs.is_explicit,
is_attr_used, attrs.is_artificial);
- type_handled = cxx_method_decl != NULL;
+ type_handled = cxx_method_decl != nullptr;
// Artificial methods are always handled even when we
// don't create a new declaration for them.
type_handled |= attrs.is_artificial;
@@ -2036,7 +2036,7 @@ bool DWARFASTParserClang::ParseTemplateDIE(
if (name && name[0])
template_param_infos.names.push_back(name);
else
- template_param_infos.names.push_back(NULL);
+ template_param_infos.names.push_back(nullptr);
// Get the signed value for any integer or enumeration if available
clang_type.IsIntegerOrEnumerationType(is_signed);
@@ -3336,7 +3336,8 @@ DWARFASTParserClang::GetOwningClangModule(const DWARFDIE &die) {
auto it = m_die_to_module.find(module_die.GetDIE());
if (it != m_die_to_module.end())
return it->second;
- const char *name = module_die.GetAttributeValueAsString(DW_AT_name, 0);
+ const char *name =
+ module_die.GetAttributeValueAsString(DW_AT_name, nullptr);
if (!name)
return {};
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
index 1d3d70dfef01..c4995e721554 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
@@ -64,11 +64,11 @@ public:
virtual void Dump(Stream &s) = 0;
- StatsDuration GetIndexTime() { return m_index_time; }
+ StatsDuration::Duration GetIndexTime() { return m_index_time; }
protected:
Module &m_module;
- StatsDuration m_index_time{0.0};
+ StatsDuration m_index_time;
/// Helper function implementing common logic for processing function dies. If
/// the function given by "ref" matches search criteria given by
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index 71d4c1e6c52f..2457e8276e20 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -269,7 +269,7 @@ protected:
ExtractUnitDIENoDwoIfNeeded();
// m_first_die_mutex is not required as m_first_die is never cleared.
if (!m_first_die)
- return NULL;
+ return nullptr;
return &m_first_die;
}
@@ -277,7 +277,7 @@ protected:
const DWARFDebugInfoEntry *DIEPtr() {
ExtractDIEsIfNeeded();
if (m_die_array.empty())
- return NULL;
+ return nullptr;
return &m_die_array[0];
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
index 3f1d6677bacf..d2b8fe19db53 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
@@ -13,18 +13,20 @@ using namespace lldb_private;
static constexpr Log::Category g_categories[] = {
{{"comp"},
{"log insertions of object files into DWARF debug maps"},
- DWARF_LOG_TYPE_COMPLETION},
- {{"info"}, {"log the parsing of .debug_info"}, DWARF_LOG_DEBUG_INFO},
- {{"line"}, {"log the parsing of .debug_line"}, DWARF_LOG_DEBUG_LINE},
+ DWARFLog::TypeCompletion},
+ {{"info"}, {"log the parsing of .debug_info"}, DWARFLog::DebugInfo},
+ {{"line"}, {"log the parsing of .debug_line"}, DWARFLog::DebugLine},
{{"lookups"},
{"log any lookups that happen by name, regex, or address"},
- DWARF_LOG_LOOKUPS},
- {{"map"},
- {"log struct/unions/class type completions"},
- DWARF_LOG_DEBUG_MAP},
+ DWARFLog::Lookups},
+ {{"map"}, {"log struct/unions/class type completions"}, DWARFLog::DebugMap},
};
-Log::Channel LogChannelDWARF::g_channel(g_categories, DWARF_LOG_DEFAULT);
+static Log::Channel g_channel(g_categories, DWARFLog::DebugInfo);
+
+template <> Log::Channel &lldb_private::LogChannelFor<DWARFLog>() {
+ return g_channel;
+}
void LogChannelDWARF::Initialize() {
Log::Register("dwarf", g_channel);
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
index 2fc23563ef93..8076c719e9c4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
@@ -11,25 +11,32 @@
#include "lldb/Utility/Log.h"
-#define DWARF_LOG_DEBUG_INFO (1u << 1)
-#define DWARF_LOG_DEBUG_LINE (1u << 2)
-#define DWARF_LOG_LOOKUPS (1u << 3)
-#define DWARF_LOG_TYPE_COMPLETION (1u << 4)
-#define DWARF_LOG_DEBUG_MAP (1u << 5)
-#define DWARF_LOG_ALL (UINT32_MAX)
-#define DWARF_LOG_DEFAULT (DWARF_LOG_DEBUG_INFO)
-
namespace lldb_private {
-class LogChannelDWARF {
- static Log::Channel g_channel;
+enum class DWARFLog : Log::MaskType {
+ DebugInfo = Log::ChannelFlag<0>,
+ DebugLine = Log::ChannelFlag<1>,
+ DebugMap = Log::ChannelFlag<2>,
+ Lookups = Log::ChannelFlag<3>,
+ TypeCompletion = Log::ChannelFlag<4>,
+ LLVM_MARK_AS_BITMASK_ENUM(TypeCompletion)
+};
+#define DWARF_LOG_DEBUG_INFO ::lldb_private::DWARFLog::DebugInfo
+#define DWARF_LOG_DEBUG_LINE ::lldb_private::DWARFLog::DebugLine
+#define DWARF_LOG_LOOKUPS ::lldb_private::DWARFLog::Lookups
+#define DWARF_LOG_TYPE_COMPLETION ::lldb_private::DWARFLog::TypeCompletion
+#define DWARF_LOG_DEBUG_MAP ::lldb_private::DWARFLog::DebugMap
+
+class LogChannelDWARF {
public:
static void Initialize();
static void Terminate();
- static Log *GetLogIfAll(uint32_t mask) { return g_channel.GetLogIfAll(mask); }
- static Log *GetLogIfAny(uint32_t mask) { return g_channel.GetLogIfAny(mask); }
+ static Log *GetLogIfAll(DWARFLog mask) { return GetLog(mask); }
+ static Log *GetLogIfAny(DWARFLog mask) { return GetLog(mask); }
};
-}
+
+template <> Log::Channel &LogChannelFor<DWARFLog>();
+} // namespace lldb_private
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_LOGCHANNELDWARF_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
index ab10e9ca98f9..e15a22affcb2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
@@ -12,9 +12,12 @@
#include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h"
#include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h"
+#include "lldb/Core/DataFileCache.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Progress.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/DataEncoder.h"
+#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/Timer.h"
#include "llvm/Support/FormatVariadic.h"
@@ -24,17 +27,19 @@ using namespace lldb_private;
using namespace lldb;
void ManualDWARFIndex::Index() {
- if (!m_dwarf)
+ if (m_indexed)
return;
-
- SymbolFileDWARF &main_dwarf = *m_dwarf;
- m_dwarf = nullptr;
+ m_indexed = true;
ElapsedTime elapsed(m_index_time);
- LLDB_SCOPED_TIMERF("%p", static_cast<void *>(&main_dwarf));
+ LLDB_SCOPED_TIMERF("%p", static_cast<void *>(m_dwarf));
+ if (LoadFromCache()) {
+ m_dwarf->SetDebugInfoIndexWasLoadedFromCache();
+ return;
+ }
- DWARFDebugInfo &main_info = main_dwarf.DebugInfo();
- SymbolFileDWARFDwo *dwp_dwarf = main_dwarf.GetDwpSymbolFile().get();
+ DWARFDebugInfo &main_info = m_dwarf->DebugInfo();
+ SymbolFileDWARFDwo *dwp_dwarf = m_dwarf->GetDwpSymbolFile().get();
DWARFDebugInfo *dwp_info = dwp_dwarf ? &dwp_dwarf->DebugInfo() : nullptr;
std::vector<DWARFUnit *> units_to_index;
@@ -125,6 +130,8 @@ void ManualDWARFIndex::Index() {
pool.async(finalize_fn, &IndexSet::types);
pool.async(finalize_fn, &IndexSet::namespaces);
pool.wait();
+
+ SaveToCache();
}
void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp,
@@ -480,3 +487,214 @@ void ManualDWARFIndex::Dump(Stream &s) {
s.Printf("\nNamespaces:\n");
m_set.namespaces.Dump(&s);
}
+
+constexpr llvm::StringLiteral kIdentifierManualDWARFIndex("DIDX");
+// Define IDs for the different tables when encoding and decoding the
+// ManualDWARFIndex NameToDIE objects so we can avoid saving any empty maps.
+enum DataID {
+ kDataIDFunctionBasenames = 1u,
+ kDataIDFunctionFullnames,
+ kDataIDFunctionMethods,
+ kDataIDFunctionSelectors,
+ kDataIDFunctionObjcClassSelectors,
+ kDataIDGlobals,
+ kDataIDTypes,
+ kDataIDNamespaces,
+ kDataIDEnd = 255u,
+
+};
+constexpr uint32_t CURRENT_CACHE_VERSION = 1;
+
+bool ManualDWARFIndex::IndexSet::Decode(const DataExtractor &data,
+ lldb::offset_t *offset_ptr) {
+ StringTableReader strtab;
+ // We now decode the string table for all strings in the data cache file.
+ if (!strtab.Decode(data, offset_ptr))
+ return false;
+
+ llvm::StringRef identifier((const char *)data.GetData(offset_ptr, 4), 4);
+ if (identifier != kIdentifierManualDWARFIndex)
+ return false;
+ const uint32_t version = data.GetU32(offset_ptr);
+ if (version != CURRENT_CACHE_VERSION)
+ return false;
+
+ bool done = false;
+ while (!done) {
+ switch (data.GetU8(offset_ptr)) {
+ default:
+ // If we got here, this is not expected, we expect the data IDs to match
+ // one of the values from the DataID enumeration.
+ return false;
+ case kDataIDFunctionBasenames:
+ if (!function_basenames.Decode(data, offset_ptr, strtab))
+ return false;
+ break;
+ case kDataIDFunctionFullnames:
+ if (!function_fullnames.Decode(data, offset_ptr, strtab))
+ return false;
+ break;
+ case kDataIDFunctionMethods:
+ if (!function_methods.Decode(data, offset_ptr, strtab))
+ return false;
+ break;
+ case kDataIDFunctionSelectors:
+ if (!function_selectors.Decode(data, offset_ptr, strtab))
+ return false;
+ break;
+ case kDataIDFunctionObjcClassSelectors:
+ if (!objc_class_selectors.Decode(data, offset_ptr, strtab))
+ return false;
+ break;
+ case kDataIDGlobals:
+ if (!globals.Decode(data, offset_ptr, strtab))
+ return false;
+ break;
+ case kDataIDTypes:
+ if (!types.Decode(data, offset_ptr, strtab))
+ return false;
+ break;
+ case kDataIDNamespaces:
+ if (!namespaces.Decode(data, offset_ptr, strtab))
+ return false;
+ break;
+ case kDataIDEnd:
+ // We got to the end of our NameToDIE encodings.
+ done = true;
+ break;
+ }
+ }
+ // Success!
+ return true;
+}
+
+void ManualDWARFIndex::IndexSet::Encode(DataEncoder &encoder) const {
+ ConstStringTable strtab;
+
+ // Encoder the DWARF index into a separate encoder first. This allows us
+ // gather all of the strings we willl need in "strtab" as we will need to
+ // write the string table out before the symbol table.
+ DataEncoder index_encoder(encoder.GetByteOrder(),
+ encoder.GetAddressByteSize());
+
+ index_encoder.AppendData(kIdentifierManualDWARFIndex);
+ // Encode the data version.
+ index_encoder.AppendU32(CURRENT_CACHE_VERSION);
+
+ if (!function_basenames.IsEmpty()) {
+ index_encoder.AppendU8(kDataIDFunctionBasenames);
+ function_basenames.Encode(index_encoder, strtab);
+ }
+ if (!function_fullnames.IsEmpty()) {
+ index_encoder.AppendU8(kDataIDFunctionFullnames);
+ function_fullnames.Encode(index_encoder, strtab);
+ }
+ if (!function_methods.IsEmpty()) {
+ index_encoder.AppendU8(kDataIDFunctionMethods);
+ function_methods.Encode(index_encoder, strtab);
+ }
+ if (!function_selectors.IsEmpty()) {
+ index_encoder.AppendU8(kDataIDFunctionSelectors);
+ function_selectors.Encode(index_encoder, strtab);
+ }
+ if (!objc_class_selectors.IsEmpty()) {
+ index_encoder.AppendU8(kDataIDFunctionObjcClassSelectors);
+ objc_class_selectors.Encode(index_encoder, strtab);
+ }
+ if (!globals.IsEmpty()) {
+ index_encoder.AppendU8(kDataIDGlobals);
+ globals.Encode(index_encoder, strtab);
+ }
+ if (!types.IsEmpty()) {
+ index_encoder.AppendU8(kDataIDTypes);
+ types.Encode(index_encoder, strtab);
+ }
+ if (!namespaces.IsEmpty()) {
+ index_encoder.AppendU8(kDataIDNamespaces);
+ namespaces.Encode(index_encoder, strtab);
+ }
+ index_encoder.AppendU8(kDataIDEnd);
+
+ // Now that all strings have been gathered, we will emit the string table.
+ strtab.Encode(encoder);
+ // Followed the the symbol table data.
+ encoder.AppendData(index_encoder.GetData());
+}
+
+bool ManualDWARFIndex::Decode(const DataExtractor &data,
+ lldb::offset_t *offset_ptr,
+ bool &signature_mismatch) {
+ signature_mismatch = false;
+ CacheSignature signature;
+ if (!signature.Decode(data, offset_ptr))
+ return false;
+ if (CacheSignature(m_dwarf->GetObjectFile()) != signature) {
+ signature_mismatch = true;
+ return false;
+ }
+ IndexSet set;
+ if (!set.Decode(data, offset_ptr))
+ return false;
+ m_set = std::move(set);
+ return true;
+}
+
+bool ManualDWARFIndex::Encode(DataEncoder &encoder) const {
+ CacheSignature signature(m_dwarf->GetObjectFile());
+ if (!signature.Encode(encoder))
+ return false;
+ m_set.Encode(encoder);
+ return true;
+}
+
+std::string ManualDWARFIndex::GetCacheKey() {
+ std::string key;
+ llvm::raw_string_ostream strm(key);
+ // DWARF Index can come from different object files for the same module. A
+ // module can have one object file as the main executable and might have
+ // another object file in a separate symbol file, or we might have a .dwo file
+ // that claims its module is the main executable.
+ ObjectFile *objfile = m_dwarf->GetObjectFile();
+ strm << objfile->GetModule()->GetCacheKey() << "-dwarf-index-"
+ << llvm::format_hex(objfile->GetCacheHash(), 10);
+ return strm.str();
+}
+
+bool ManualDWARFIndex::LoadFromCache() {
+ DataFileCache *cache = Module::GetIndexCache();
+ if (!cache)
+ return false;
+ ObjectFile *objfile = m_dwarf->GetObjectFile();
+ if (!objfile)
+ return false;
+ std::unique_ptr<llvm::MemoryBuffer> mem_buffer_up =
+ cache->GetCachedData(GetCacheKey());
+ if (!mem_buffer_up)
+ return false;
+ DataExtractor data(mem_buffer_up->getBufferStart(),
+ mem_buffer_up->getBufferSize(),
+ endian::InlHostByteOrder(),
+ objfile->GetAddressByteSize());
+ bool signature_mismatch = false;
+ lldb::offset_t offset = 0;
+ const bool result = Decode(data, &offset, signature_mismatch);
+ if (signature_mismatch)
+ cache->RemoveCacheFile(GetCacheKey());
+ return result;
+}
+
+void ManualDWARFIndex::SaveToCache() {
+ DataFileCache *cache = Module::GetIndexCache();
+ if (!cache)
+ return; // Caching is not enabled.
+ ObjectFile *objfile = m_dwarf->GetObjectFile();
+ if (!objfile)
+ return;
+ DataEncoder file(endian::InlHostByteOrder(), objfile->GetAddressByteSize());
+ // Encode will return false if the object file doesn't have anything to make
+ // a signature from.
+ if (Encode(file)) {
+ if (cache->SetCachedData(GetCacheKey(), file.GetData()))
+ m_dwarf->SetDebugInfoIndexWasSavedToCache();
+ }
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
index 36f371402b90..5c5e43de9ca6 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
@@ -55,7 +55,7 @@ public:
void Dump(Stream &s) override;
-private:
+ // Make IndexSet public so we can unit test the encoding and decoding logic.
struct IndexSet {
NameToDIE function_basenames;
NameToDIE function_fullnames;
@@ -65,21 +65,113 @@ private:
NameToDIE globals;
NameToDIE types;
NameToDIE namespaces;
+ bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr);
+ void Encode(DataEncoder &encoder) const;
+ bool operator==(const IndexSet &rhs) const {
+ return function_basenames == rhs.function_basenames &&
+ function_fullnames == rhs.function_fullnames &&
+ function_methods == rhs.function_methods &&
+ function_selectors == rhs.function_selectors &&
+ objc_class_selectors == rhs.objc_class_selectors &&
+ globals == rhs.globals && types == rhs.types &&
+ namespaces == rhs.namespaces;
+ }
};
+
+private:
void Index();
+
+ /// Decode a serialized version of this object from data.
+ ///
+ /// \param data
+ /// The decoder object that references the serialized data.
+ ///
+ /// \param offset_ptr
+ /// A pointer that contains the offset from which the data will be decoded
+ /// from that gets updated as data gets decoded.
+ ///
+ /// \param strtab
+ /// All strings in cache files are put into string tables for efficiency
+ /// and cache file size reduction. Strings are stored as uint32_t string
+ /// table offsets in the cache data.
+ bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
+ bool &signature_mismatch);
+
+ /// Encode this object into a data encoder object.
+ ///
+ /// This allows this object to be serialized to disk.
+ ///
+ /// \param encoder
+ /// A data encoder object that serialized bytes will be encoded into.
+ ///
+ /// \param strtab
+ /// All strings in cache files are put into string tables for efficiency
+ /// and cache file size reduction. Strings are stored as uint32_t string
+ /// table offsets in the cache data.
+ ///
+ /// \return
+ /// True if the symbol table's object file can generate a valid signature
+ /// and all data for the symbol table was encoded, false otherwise.
+ bool Encode(DataEncoder &encoder) const;
+
+ /// Get the cache key string for this symbol table.
+ ///
+ /// The cache key must start with the module's cache key and is followed
+ /// by information that indicates this key is for caching the symbol table
+ /// contents and should also include the has of the object file. A module can
+ /// be represented by an ObjectFile object for the main executable, but can
+ /// also have a symbol file that is from the same or a different object file.
+ /// This means we might have two symbol tables cached in the index cache, one
+ /// for the main executable and one for the symbol file.
+ ///
+ /// \return
+ /// The unique cache key used to save and retrieve data from the index
+ /// cache.
+ std::string GetCacheKey();
+
+ /// Save the symbol table data out into a cache.
+ ///
+ /// The symbol table will only be saved to a cache file if caching is enabled.
+ ///
+ /// We cache the contents of the symbol table since symbol tables in LLDB take
+ /// some time to initialize. This is due to the many sources for data that are
+ /// used to create a symbol table:
+ /// - standard symbol table
+ /// - dynamic symbol table (ELF)
+ /// - compressed debug info sections
+ /// - unwind information
+ /// - function pointers found in runtimes for global constructor/destructors
+ /// - other sources.
+ /// All of the above sources are combined and one symbol table results after
+ /// all sources have been considered.
+ void SaveToCache();
+
+ /// Load the symbol table from the index cache.
+ ///
+ /// Quickly load the finalized symbol table from the index cache. This saves
+ /// time when the debugger starts up. The index cache file for the symbol
+ /// table has the modification time set to the same time as the main module.
+ /// If the cache file exists and the modification times match, we will load
+ /// the symbol table from the serlized cache file.
+ ///
+ /// \return
+ /// True if the symbol table was successfully loaded from the index cache,
+ /// false if the symbol table wasn't cached or was out of date.
+ bool LoadFromCache();
+
void IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp, IndexSet &set);
static void IndexUnitImpl(DWARFUnit &unit,
const lldb::LanguageType cu_language,
IndexSet &set);
- /// The DWARF file which we are indexing. Set to nullptr after the index is
- /// built.
+ /// The DWARF file which we are indexing.
SymbolFileDWARF *m_dwarf;
/// Which dwarf units should we skip while building the index.
llvm::DenseSet<dw_offset_t> m_units_to_avoid;
IndexSet m_set;
+ bool m_indexed = false;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
index 493d1b4a2702..413920f33619 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
@@ -8,8 +8,11 @@
#include "NameToDIE.h"
#include "DWARFUnit.h"
+#include "lldb/Core/DataFileCache.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/DataEncoder.h"
+#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StreamString.h"
@@ -18,7 +21,7 @@ using namespace lldb;
using namespace lldb_private;
void NameToDIE::Finalize() {
- m_map.Sort();
+ m_map.Sort(std::less<DIERef>());
m_map.SizeToFit();
}
@@ -87,3 +90,50 @@ void NameToDIE::Append(const NameToDIE &other) {
other.m_map.GetValueAtIndexUnchecked(i));
}
}
+
+constexpr llvm::StringLiteral kIdentifierNameToDIE("N2DI");
+
+bool NameToDIE::Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
+ const StringTableReader &strtab) {
+ m_map.Clear();
+ llvm::StringRef identifier((const char *)data.GetData(offset_ptr, 4), 4);
+ if (identifier != kIdentifierNameToDIE)
+ return false;
+ const uint32_t count = data.GetU32(offset_ptr);
+ for (uint32_t i = 0; i < count; ++i) {
+ llvm::StringRef str(strtab.Get(data.GetU32(offset_ptr)));
+ // No empty strings allowed in the name to DIE maps.
+ if (str.empty())
+ return false;
+ if (llvm::Optional<DIERef> die_ref = DIERef::Decode(data, offset_ptr))
+ m_map.Append(ConstString(str), die_ref.getValue());
+ else
+ return false;
+ }
+ return true;
+}
+
+void NameToDIE::Encode(DataEncoder &encoder, ConstStringTable &strtab) const {
+ encoder.AppendData(kIdentifierNameToDIE);
+ encoder.AppendU32(m_map.GetSize());
+ for (const auto &entry : m_map) {
+ // Make sure there are no empty strings.
+ assert((bool)entry.cstring);
+ encoder.AppendU32(strtab.Add(entry.cstring));
+ entry.value.Encode(encoder);
+ }
+}
+
+bool NameToDIE::operator==(const NameToDIE &rhs) const {
+ const size_t size = m_map.GetSize();
+ if (size != rhs.m_map.GetSize())
+ return false;
+ for (size_t i = 0; i < size; ++i) {
+ if (m_map.GetCStringAtIndex(i) != rhs.m_map.GetCStringAtIndex(i))
+ return false;
+ if (m_map.GetValueRefAtIndexUnchecked(i) !=
+ rhs.m_map.GetValueRefAtIndexUnchecked(i))
+ return false;
+ }
+ return true;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h
index 994af07189f8..61df1a628ab5 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h
@@ -48,6 +48,44 @@ public:
const DIERef &die_ref)> const
&callback) const;
+ /// Decode a serialized version of this object from data.
+ ///
+ /// \param data
+ /// The decoder object that references the serialized data.
+ ///
+ /// \param offset_ptr
+ /// A pointer that contains the offset from which the data will be decoded
+ /// from that gets updated as data gets decoded.
+ ///
+ /// \param strtab
+ /// All strings in cache files are put into string tables for efficiency
+ /// and cache file size reduction. Strings are stored as uint32_t string
+ /// table offsets in the cache data.
+ bool Decode(const lldb_private::DataExtractor &data,
+ lldb::offset_t *offset_ptr,
+ const lldb_private::StringTableReader &strtab);
+
+ /// Encode this object into a data encoder object.
+ ///
+ /// This allows this object to be serialized to disk.
+ ///
+ /// \param encoder
+ /// A data encoder object that serialized bytes will be encoded into.
+ ///
+ /// \param strtab
+ /// All strings in cache files are put into string tables for efficiency
+ /// and cache file size reduction. Strings are stored as uint32_t string
+ /// table offsets in the cache data.
+ void Encode(lldb_private::DataEncoder &encoder,
+ lldb_private::ConstStringTable &strtab) const;
+
+ /// Used for unit testing the encoding and decoding.
+ bool operator==(const NameToDIE &rhs) const;
+
+ bool IsEmpty() const { return m_map.IsEmpty(); }
+
+ void Clear() { m_map.Clear(); }
+
protected:
lldb_private::UniqueCStringMap<DIERef> m_map;
};
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 8c995ef2eb2a..02d1a6a4a8be 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -2140,7 +2140,8 @@ void SymbolFileDWARF::FindGlobalVariables(
llvm::StringRef basename;
llvm::StringRef context;
- bool name_is_mangled = (bool)Mangled(name);
+ bool name_is_mangled = Mangled::GetManglingScheme(name.GetStringRef()) !=
+ Mangled::eManglingSchemeNone;
if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name.GetCString(),
context, basename))
@@ -4085,8 +4086,8 @@ LanguageType SymbolFileDWARF::GetLanguageFamily(DWARFUnit &unit) {
return LanguageTypeFromDWARF(lang);
}
-StatsDuration SymbolFileDWARF::GetDebugInfoIndexTime() {
+StatsDuration::Duration SymbolFileDWARF::GetDebugInfoIndexTime() {
if (m_index)
return m_index->GetIndexTime();
- return StatsDuration(0.0);
+ return {};
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index e81ce28cb86e..f84a78620e17 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -319,10 +319,10 @@ public:
/// Same as GetLanguage() but reports all C++ versions as C++ (no version).
static lldb::LanguageType GetLanguageFamily(DWARFUnit &unit);
- lldb_private::StatsDuration GetDebugInfoParseTime() override {
+ lldb_private::StatsDuration::Duration GetDebugInfoParseTime() override {
return m_parse_time;
}
- lldb_private::StatsDuration GetDebugInfoIndexTime() override;
+ lldb_private::StatsDuration::Duration GetDebugInfoIndexTime() override;
lldb_private::StatsDuration &GetDebugInfoParseTimeRef() {
return m_parse_time;
@@ -559,7 +559,7 @@ protected:
/// Try to filter out this debug info by comparing it to the lowest code
/// address in the module.
lldb::addr_t m_first_code_address = LLDB_INVALID_ADDRESS;
- lldb_private::StatsDuration m_parse_time{0.0};
+ lldb_private::StatsDuration m_parse_time;
};
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index 2491f6af8c19..6ee189e04250 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -1447,8 +1447,8 @@ uint64_t SymbolFileDWARFDebugMap::GetDebugInfoSize() {
return debug_info_size;
}
-StatsDuration SymbolFileDWARFDebugMap::GetDebugInfoParseTime() {
- StatsDuration elapsed(0.0);
+StatsDuration::Duration SymbolFileDWARFDebugMap::GetDebugInfoParseTime() {
+ StatsDuration::Duration elapsed(0.0);
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
ObjectFile *oso_objfile = oso_dwarf->GetObjectFile();
if (oso_objfile) {
@@ -1464,8 +1464,8 @@ StatsDuration SymbolFileDWARFDebugMap::GetDebugInfoParseTime() {
return elapsed;
}
-StatsDuration SymbolFileDWARFDebugMap::GetDebugInfoIndexTime() {
- StatsDuration elapsed(0.0);
+StatsDuration::Duration SymbolFileDWARFDebugMap::GetDebugInfoIndexTime() {
+ StatsDuration::Duration elapsed(0.0);
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
ObjectFile *oso_objfile = oso_dwarf->GetObjectFile();
if (oso_objfile) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
index 74f32442de2f..2a6232a501b4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -143,8 +143,8 @@ public:
llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
uint64_t GetDebugInfoSize() override;
- lldb_private::StatsDuration GetDebugInfoParseTime() override;
- lldb_private::StatsDuration GetDebugInfoIndexTime() override;
+ lldb_private::StatsDuration::Duration GetDebugInfoParseTime() override;
+ lldb_private::StatsDuration::Duration GetDebugInfoIndexTime() override;
protected:
enum { kHaveInitializedOSOs = (1 << 0), kNumFlags };
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
index 9f09c0accc87..d8f737612c25 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
@@ -106,6 +106,24 @@ static void ParseExtendedInfo(PdbIndex &index, CompilandIndexItem &item) {
}
}
+static void ParseInlineeLineTableForCompileUnit(CompilandIndexItem &item) {
+ for (const auto &ss : item.m_debug_stream.getSubsectionsArray()) {
+ if (ss.kind() != DebugSubsectionKind::InlineeLines)
+ continue;
+
+ DebugInlineeLinesSubsectionRef inlinee_lines;
+ llvm::BinaryStreamReader reader(ss.getRecordData());
+ if (llvm::Error error = inlinee_lines.initialize(reader)) {
+ consumeError(std::move(error));
+ continue;
+ }
+
+ for (const InlineeSourceLine &Line : inlinee_lines) {
+ item.m_inline_map[Line.Header->Inlinee] = Line;
+ }
+ }
+}
+
CompilandIndexItem::CompilandIndexItem(
PdbCompilandId id, llvm::pdb::ModuleDebugStreamRef debug_stream,
llvm::pdb::DbiModuleDescriptor descriptor)
@@ -142,6 +160,7 @@ CompilandIndexItem &CompileUnitIndex::GetOrCreateCompiland(uint16_t modi) {
cci = std::make_unique<CompilandIndexItem>(
PdbCompilandId{modi}, std::move(debug_stream), std::move(descriptor));
ParseExtendedInfo(m_index, *cci);
+ ParseInlineeLineTableForCompileUnit(*cci);
cci->m_strings.initialize(debug_stream.getSubsectionsArray());
PDBStringTable &strings = cantFail(m_index.pdb().getStringTable());
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h
index 088de970cbf3..4ad27de98695 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h
@@ -9,10 +9,12 @@
#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_COMPILEUNITINDEX_H
#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_COMPILEUNITINDEX_H
+#include "lldb/Utility/RangeMap.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/IntervalMap.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
@@ -69,6 +71,17 @@ struct CompilandIndexItem {
// command line, etc. This usually contains exactly 5 items which
// are references to other strings.
llvm::SmallVector<llvm::codeview::TypeIndex, 5> m_build_info;
+
+ // Inlinee lines table in this compile unit.
+ std::map<llvm::codeview::TypeIndex, llvm::codeview::InlineeSourceLine>
+ m_inline_map;
+
+ // It's the line table parsed from DEBUG_S_LINES sections, mapping the file
+ // address range to file index and source line number.
+ using GlobalLineTable =
+ lldb_private::RangeDataVector<lldb::addr_t, uint32_t,
+ std::pair<uint32_t, uint32_t>>;
+ GlobalLineTable m_global_line_table;
};
/// Indexes information about all compile units. This is really just a map of
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index 9473befa6cc3..dc0969a0ce7c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -1081,7 +1081,7 @@ PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) {
clang::FunctionDecl *function_decl = nullptr;
if (parent->isRecord()) {
- clang::QualType parent_qt = llvm::dyn_cast<clang::TypeDecl>(parent)
+ clang::QualType parent_qt = llvm::cast<clang::TypeDecl>(parent)
->getTypeForDecl()
->getCanonicalTypeInternal();
lldb::opaque_compiler_type_t parent_opaque_ty =
@@ -1318,7 +1318,7 @@ void PdbAstBuilder::ParseAllNamespacesPlusChildrenOf(
if (!context->isNamespace())
continue;
- clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(context);
+ clang::NamespaceDecl *ns = llvm::cast<clang::NamespaceDecl>(context);
std::string actual_ns = ns->getQualifiedNameAsString();
if (llvm::StringRef(actual_ns).startswith(*parent)) {
clang::QualType qt = GetOrCreateType(tid);
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h
index 1b382e5263c1..edbdd9ee290b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h
@@ -25,7 +25,6 @@ namespace llvm {
namespace pdb {
class DbiStream;
class TpiStream;
-class TpiStream;
class InfoStream;
class PublicsStream;
class GlobalsStream;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index e859b1d5a86c..a035a791f868 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -330,31 +330,65 @@ uint32_t SymbolFileNativePDB::CalculateNumCompileUnits() {
Block &SymbolFileNativePDB::CreateBlock(PdbCompilandSymId block_id) {
CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi);
CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset);
-
- if (sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32) {
- // This is a function. It must be global. Creating the Function entry for
- // it automatically creates a block for it.
- CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii);
- return GetOrCreateFunction(block_id, *comp_unit)->GetBlock(false);
- }
-
- lldbassert(sym.kind() == S_BLOCK32);
-
- // This is a block. Its parent is either a function or another block. In
- // either case, its parent can be viewed as a block (e.g. a function contains
- // 1 big block. So just get the parent block and add this block to it.
- BlockSym block(static_cast<SymbolRecordKind>(sym.kind()));
- cantFail(SymbolDeserializer::deserializeAs<BlockSym>(sym, block));
- lldbassert(block.Parent != 0);
- PdbCompilandSymId parent_id(block_id.modi, block.Parent);
- Block &parent_block = GetOrCreateBlock(parent_id);
+ CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii);
lldb::user_id_t opaque_block_uid = toOpaqueUid(block_id);
BlockSP child_block = std::make_shared<Block>(opaque_block_uid);
- parent_block.AddChild(child_block);
- m_ast->GetOrCreateBlockDecl(block_id);
+ switch (sym.kind()) {
+ case S_GPROC32:
+ case S_LPROC32: {
+ // This is a function. It must be global. Creating the Function entry
+ // for it automatically creates a block for it.
+ FunctionSP func = GetOrCreateFunction(block_id, *comp_unit);
+ Block &block = func->GetBlock(false);
+ if (block.GetNumRanges() == 0)
+ block.AddRange(Block::Range(0, func->GetAddressRange().GetByteSize()));
+ return block;
+ }
+ case S_BLOCK32: {
+ // This is a block. Its parent is either a function or another block. In
+ // either case, its parent can be viewed as a block (e.g. a function
+ // contains 1 big block. So just get the parent block and add this block
+ // to it.
+ BlockSym block(static_cast<SymbolRecordKind>(sym.kind()));
+ cantFail(SymbolDeserializer::deserializeAs<BlockSym>(sym, block));
+ lldbassert(block.Parent != 0);
+ PdbCompilandSymId parent_id(block_id.modi, block.Parent);
+ Block &parent_block = GetOrCreateBlock(parent_id);
+ parent_block.AddChild(child_block);
+ m_ast->GetOrCreateBlockDecl(block_id);
+ m_blocks.insert({opaque_block_uid, child_block});
+ break;
+ }
+ case S_INLINESITE: {
+ // This ensures line table is parsed first so we have inline sites info.
+ comp_unit->GetLineTable();
+
+ std::shared_ptr<InlineSite> inline_site = m_inline_sites[opaque_block_uid];
+ Block &parent_block = GetOrCreateBlock(inline_site->parent_id);
+ parent_block.AddChild(child_block);
+
+ // Copy ranges from InlineSite to Block.
+ for (size_t i = 0; i < inline_site->ranges.GetSize(); ++i) {
+ auto *entry = inline_site->ranges.GetEntryAtIndex(i);
+ child_block->AddRange(
+ Block::Range(entry->GetRangeBase(), entry->GetByteSize()));
+ }
+ child_block->FinalizeRanges();
+
+ // Get the inlined function callsite info.
+ Declaration &decl = inline_site->inline_function_info->GetDeclaration();
+ Declaration &callsite = inline_site->inline_function_info->GetCallSite();
+ child_block->SetInlinedFunctionInfo(
+ inline_site->inline_function_info->GetName().GetCString(), nullptr,
+ &decl, &callsite);
+ m_blocks.insert({opaque_block_uid, child_block});
+ break;
+ }
+ default:
+ lldbassert(false && "Symbol is not a block!");
+ }
- m_blocks.insert({opaque_block_uid, child_block});
return *child_block;
}
@@ -971,16 +1005,22 @@ uint32_t SymbolFileNativePDB::ResolveSymbolContext(
continue;
if (type == PDB_SymType::Function) {
sc.function = GetOrCreateFunction(csid, *sc.comp_unit).get();
- sc.block = sc.GetFunctionBlock();
+ Block &block = sc.function->GetBlock(true);
+ addr_t func_base =
+ sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
+ addr_t offset = file_addr - func_base;
+ sc.block = block.FindInnermostBlockByOffset(offset);
}
if (type == PDB_SymType::Block) {
sc.block = &GetOrCreateBlock(csid);
sc.function = sc.block->CalculateSymbolContextFunction();
}
- resolved_flags |= eSymbolContextFunction;
- resolved_flags |= eSymbolContextBlock;
- break;
+ if (sc.function)
+ resolved_flags |= eSymbolContextFunction;
+ if (sc.block)
+ resolved_flags |= eSymbolContextBlock;
+ break;
}
}
@@ -998,43 +1038,24 @@ uint32_t SymbolFileNativePDB::ResolveSymbolContext(
uint32_t SymbolFileNativePDB::ResolveSymbolContext(
const SourceLocationSpec &src_location_spec,
lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
- return 0;
-}
-
-static void AppendLineEntryToSequence(LineTable &table, LineSequence &sequence,
- const CompilandIndexItem &cci,
- lldb::addr_t base_addr,
- uint32_t file_number,
- const LineFragmentHeader &block,
- const LineNumberEntry &cur) {
- LineInfo cur_info(cur.Flags);
-
- if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto())
- return;
-
- uint64_t addr = base_addr + cur.Offset;
-
- bool is_statement = cur_info.isStatement();
- bool is_prologue = IsFunctionPrologue(cci, addr);
- bool is_epilogue = IsFunctionEpilogue(cci, addr);
-
- uint32_t lno = cur_info.getStartLine();
-
- table.AppendLineEntryToSequence(&sequence, addr, lno, 0, file_number,
- is_statement, false, is_prologue, is_epilogue,
- false);
-}
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ const uint32_t prev_size = sc_list.GetSize();
+ if (resolve_scope & eSymbolContextCompUnit) {
+ for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus;
+ ++cu_idx) {
+ CompileUnit *cu = ParseCompileUnitAtIndex(cu_idx).get();
+ if (!cu)
+ continue;
-static void TerminateLineSequence(LineTable &table,
- const LineFragmentHeader &block,
- lldb::addr_t base_addr, uint32_t file_number,
- uint32_t last_line,
- std::unique_ptr<LineSequence> seq) {
- // The end is always a terminal entry, so insert it regardless.
- table.AppendLineEntryToSequence(seq.get(), base_addr + block.CodeSize,
- last_line, 0, file_number, false, false,
- false, false, true);
- table.InsertSequence(seq.get());
+ bool file_spec_matches_cu_file_spec = FileSpec::Match(
+ src_location_spec.GetFileSpec(), cu->GetPrimaryFile());
+ if (file_spec_matches_cu_file_spec) {
+ cu->ResolveSymbolContext(src_location_spec, resolve_scope, sc_list);
+ break;
+ }
+ }
+ }
+ return sc_list.GetSize() - prev_size;
}
bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) {
@@ -1045,16 +1066,21 @@ bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
PdbSymUid cu_id(comp_unit.GetID());
lldbassert(cu_id.kind() == PdbSymUidKind::Compiland);
- CompilandIndexItem *cci =
- m_index->compilands().GetCompiland(cu_id.asCompiland().modi);
- lldbassert(cci);
- auto line_table = std::make_unique<LineTable>(&comp_unit);
+ uint16_t modi = cu_id.asCompiland().modi;
+ CompilandIndexItem *cii = m_index->compilands().GetCompiland(modi);
+ lldbassert(cii);
+
+ // Parse DEBUG_S_LINES subsections first, then parse all S_INLINESITE records
+ // in this CU. Add line entries into the set first so that if there are line
+ // entries with same addres, the later is always more accurate than the
+ // former.
+ std::set<LineTable::Entry, LineTableEntryComparator> line_set;
// This is basically a copy of the .debug$S subsections from all original COFF
// object files merged together with address relocations applied. We are
// looking for all DEBUG_S_LINES subsections.
for (const DebugSubsectionRecord &dssr :
- cci->m_debug_stream.getSubsectionsArray()) {
+ cii->m_debug_stream.getSubsectionsArray()) {
if (dssr.kind() != DebugSubsectionKind::Lines)
continue;
@@ -1069,42 +1095,111 @@ bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) {
uint64_t virtual_addr =
m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset);
- const auto &checksums = cci->m_strings.checksums().getArray();
- const auto &strings = cci->m_strings.strings();
for (const LineColumnEntry &group : lines) {
- // Indices in this structure are actually offsets of records in the
- // DEBUG_S_FILECHECKSUMS subsection. Those entries then have an index
- // into the global PDB string table.
- auto iter = checksums.at(group.NameIndex);
- if (iter == checksums.end())
+ llvm::Expected<uint32_t> file_index_or_err =
+ GetFileIndex(*cii, group.NameIndex);
+ if (!file_index_or_err)
continue;
+ uint32_t file_index = file_index_or_err.get();
+ lldbassert(!group.LineNumbers.empty());
+ CompilandIndexItem::GlobalLineTable::Entry line_entry(
+ LLDB_INVALID_ADDRESS, 0);
+ for (const LineNumberEntry &entry : group.LineNumbers) {
+ LineInfo cur_info(entry.Flags);
- llvm::Expected<llvm::StringRef> efn =
- strings.getString(iter->FileNameOffset);
- if (!efn) {
- llvm::consumeError(efn.takeError());
- continue;
- }
+ if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto())
+ continue;
- // LLDB wants the index of the file in the list of support files.
- auto fn_iter = llvm::find(cci->m_file_list, *efn);
- lldbassert(fn_iter != cci->m_file_list.end());
- uint32_t file_index = std::distance(cci->m_file_list.begin(), fn_iter);
+ uint64_t addr = virtual_addr + entry.Offset;
- std::unique_ptr<LineSequence> sequence(
- line_table->CreateLineSequenceContainer());
- lldbassert(!group.LineNumbers.empty());
+ bool is_statement = cur_info.isStatement();
+ bool is_prologue = IsFunctionPrologue(*cii, addr);
+ bool is_epilogue = IsFunctionEpilogue(*cii, addr);
- for (const LineNumberEntry &entry : group.LineNumbers) {
- AppendLineEntryToSequence(*line_table, *sequence, *cci, virtual_addr,
- file_index, *lfh, entry);
+ uint32_t lno = cur_info.getStartLine();
+
+ line_set.emplace(addr, lno, 0, file_index, is_statement, false,
+ is_prologue, is_epilogue, false);
+
+ if (line_entry.GetRangeBase() != LLDB_INVALID_ADDRESS) {
+ line_entry.SetRangeEnd(addr);
+ cii->m_global_line_table.Append(line_entry);
+ }
+ line_entry.SetRangeBase(addr);
+ line_entry.data = {file_index, lno};
}
LineInfo last_line(group.LineNumbers.back().Flags);
- TerminateLineSequence(*line_table, *lfh, virtual_addr, file_index,
- last_line.getEndLine(), std::move(sequence));
+ line_set.emplace(virtual_addr + lfh->CodeSize, last_line.getEndLine(), 0,
+ file_index, false, false, false, false, true);
+
+ if (line_entry.GetRangeBase() != LLDB_INVALID_ADDRESS) {
+ line_entry.SetRangeEnd(virtual_addr + lfh->CodeSize);
+ cii->m_global_line_table.Append(line_entry);
+ }
}
}
+ cii->m_global_line_table.Sort();
+
+ // Parse all S_INLINESITE in this CU.
+ const CVSymbolArray &syms = cii->m_debug_stream.getSymbolArray();
+ for (auto iter = syms.begin(); iter != syms.end();) {
+ if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32) {
+ ++iter;
+ continue;
+ }
+
+ uint32_t record_offset = iter.offset();
+ CVSymbol func_record =
+ cii->m_debug_stream.readSymbolAtOffset(record_offset);
+ SegmentOffsetLength sol = GetSegmentOffsetAndLength(func_record);
+ addr_t file_vm_addr = m_index->MakeVirtualAddress(sol.so);
+ AddressRange func_range(file_vm_addr, sol.length,
+ comp_unit.GetModule()->GetSectionList());
+ Address func_base = func_range.GetBaseAddress();
+ PdbCompilandSymId func_id{modi, record_offset};
+
+ // Iterate all S_INLINESITEs in the function.
+ auto parse_inline_sites = [&](SymbolKind kind, PdbCompilandSymId id) {
+ if (kind != S_INLINESITE)
+ return false;
+
+ ParseInlineSite(id, func_base);
+
+ for (const auto &line_entry :
+ m_inline_sites[toOpaqueUid(id)]->line_entries) {
+ // If line_entry is not terminal entry, remove previous line entry at
+ // the same address and insert new one. Terminal entry inside an inline
+ // site might not be terminal entry for its parent.
+ if (!line_entry.is_terminal_entry)
+ line_set.erase(line_entry);
+ line_set.insert(line_entry);
+ }
+ // No longer useful after adding to line_set.
+ m_inline_sites[toOpaqueUid(id)]->line_entries.clear();
+ return true;
+ };
+ ParseSymbolArrayInScope(func_id, parse_inline_sites);
+ // Jump to the end of the function record.
+ iter = syms.at(getScopeEndOffset(func_record));
+ }
+
+ cii->m_global_line_table.Clear();
+
+ // Add line entries in line_set to line_table.
+ auto line_table = std::make_unique<LineTable>(&comp_unit);
+ std::unique_ptr<LineSequence> sequence(
+ line_table->CreateLineSequenceContainer());
+ for (const auto &line_entry : line_set) {
+ line_table->AppendLineEntryToSequence(
+ sequence.get(), line_entry.file_addr, line_entry.line,
+ line_entry.column, line_entry.file_idx,
+ line_entry.is_start_of_statement, line_entry.is_start_of_basic_block,
+ line_entry.is_prologue_end, line_entry.is_epilogue_begin,
+ line_entry.is_terminal_entry);
+ }
+ line_table->InsertSequence(sequence.get());
+
if (line_table->GetSize() == 0)
return false;
@@ -1117,6 +1212,33 @@ bool SymbolFileNativePDB::ParseDebugMacros(CompileUnit &comp_unit) {
return false;
}
+llvm::Expected<uint32_t>
+SymbolFileNativePDB::GetFileIndex(const CompilandIndexItem &cii,
+ uint32_t file_id) {
+ auto index_iter = m_file_indexes.find(file_id);
+ if (index_iter != m_file_indexes.end())
+ return index_iter->getSecond();
+ const auto &checksums = cii.m_strings.checksums().getArray();
+ const auto &strings = cii.m_strings.strings();
+ // Indices in this structure are actually offsets of records in the
+ // DEBUG_S_FILECHECKSUMS subsection. Those entries then have an index
+ // into the global PDB string table.
+ auto iter = checksums.at(file_id);
+ if (iter == checksums.end())
+ return llvm::make_error<RawError>(raw_error_code::no_entry);
+
+ llvm::Expected<llvm::StringRef> efn = strings.getString(iter->FileNameOffset);
+ if (!efn) {
+ return efn.takeError();
+ }
+
+ // LLDB wants the index of the file in the list of support files.
+ auto fn_iter = llvm::find(cii.m_file_list, *efn);
+ lldbassert(fn_iter != cii.m_file_list.end());
+ m_file_indexes[file_id] = std::distance(cii.m_file_list.begin(), fn_iter);
+ return m_file_indexes[file_id];
+}
+
bool SymbolFileNativePDB::ParseSupportFiles(CompileUnit &comp_unit,
FileSpecList &support_files) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
@@ -1141,11 +1263,223 @@ bool SymbolFileNativePDB::ParseImportedModules(
return false;
}
+void SymbolFileNativePDB::ParseInlineSite(PdbCompilandSymId id,
+ Address func_addr) {
+ lldb::user_id_t opaque_uid = toOpaqueUid(id);
+ if (m_inline_sites.find(opaque_uid) != m_inline_sites.end())
+ return;
+
+ addr_t func_base = func_addr.GetFileAddress();
+ CompilandIndexItem *cii = m_index->compilands().GetCompiland(id.modi);
+ CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(id.offset);
+ CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii);
+
+ InlineSiteSym inline_site(static_cast<SymbolRecordKind>(sym.kind()));
+ cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(sym, inline_site));
+ PdbCompilandSymId parent_id(id.modi, inline_site.Parent);
+
+ std::shared_ptr<InlineSite> inline_site_sp =
+ std::make_shared<InlineSite>(parent_id);
+
+ // Get the inlined function declaration info.
+ auto iter = cii->m_inline_map.find(inline_site.Inlinee);
+ if (iter == cii->m_inline_map.end())
+ return;
+ InlineeSourceLine inlinee_line = iter->second;
+
+ const FileSpecList &files = comp_unit->GetSupportFiles();
+ FileSpec decl_file;
+ llvm::Expected<uint32_t> file_index_or_err =
+ GetFileIndex(*cii, inlinee_line.Header->FileID);
+ if (!file_index_or_err)
+ return;
+ uint32_t decl_file_idx = file_index_or_err.get();
+ decl_file = files.GetFileSpecAtIndex(decl_file_idx);
+ uint32_t decl_line = inlinee_line.Header->SourceLineNum;
+ std::unique_ptr<Declaration> decl_up =
+ std::make_unique<Declaration>(decl_file, decl_line);
+
+ // Parse range and line info.
+ uint32_t code_offset = 0;
+ int32_t line_offset = 0;
+ bool has_base = false;
+ bool is_new_line_offset = false;
+
+ bool is_start_of_statement = false;
+ // The first instruction is the prologue end.
+ bool is_prologue_end = true;
+
+ auto change_code_offset = [&](uint32_t code_delta) {
+ if (has_base) {
+ inline_site_sp->ranges.Append(RangeSourceLineVector::Entry(
+ code_offset, code_delta, decl_line + line_offset));
+ is_prologue_end = false;
+ is_start_of_statement = false;
+ } else {
+ is_start_of_statement = true;
+ }
+ has_base = true;
+ code_offset += code_delta;
+
+ if (is_new_line_offset) {
+ LineTable::Entry line_entry(func_base + code_offset,
+ decl_line + line_offset, 0, decl_file_idx,
+ true, false, is_prologue_end, false, false);
+ inline_site_sp->line_entries.push_back(line_entry);
+ is_new_line_offset = false;
+ }
+ };
+ auto change_code_length = [&](uint32_t length) {
+ inline_site_sp->ranges.Append(RangeSourceLineVector::Entry(
+ code_offset, length, decl_line + line_offset));
+ has_base = false;
+
+ LineTable::Entry end_line_entry(func_base + code_offset + length,
+ decl_line + line_offset, 0, decl_file_idx,
+ false, false, false, false, true);
+ inline_site_sp->line_entries.push_back(end_line_entry);
+ };
+ auto change_line_offset = [&](int32_t line_delta) {
+ line_offset += line_delta;
+ if (has_base) {
+ LineTable::Entry line_entry(
+ func_base + code_offset, decl_line + line_offset, 0, decl_file_idx,
+ is_start_of_statement, false, is_prologue_end, false, false);
+ inline_site_sp->line_entries.push_back(line_entry);
+ } else {
+ // Add line entry in next call to change_code_offset.
+ is_new_line_offset = true;
+ }
+ };
+
+ for (auto &annot : inline_site.annotations()) {
+ switch (annot.OpCode) {
+ case BinaryAnnotationsOpCode::CodeOffset:
+ case BinaryAnnotationsOpCode::ChangeCodeOffset:
+ case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
+ change_code_offset(annot.U1);
+ break;
+ case BinaryAnnotationsOpCode::ChangeLineOffset:
+ change_line_offset(annot.S1);
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeLength:
+ change_code_length(annot.U1);
+ code_offset += annot.U1;
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
+ change_code_offset(annot.U1);
+ change_line_offset(annot.S1);
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
+ change_code_offset(annot.U2);
+ change_code_length(annot.U1);
+ break;
+ default:
+ break;
+ }
+ }
+
+ inline_site_sp->ranges.Sort();
+ inline_site_sp->ranges.CombineConsecutiveEntriesWithEqualData();
+
+ // Get the inlined function callsite info.
+ std::unique_ptr<Declaration> callsite_up;
+ if (!inline_site_sp->ranges.IsEmpty()) {
+ auto *entry = inline_site_sp->ranges.GetEntryAtIndex(0);
+ addr_t base_offset = entry->GetRangeBase();
+ if (cii->m_debug_stream.readSymbolAtOffset(parent_id.offset).kind() ==
+ S_INLINESITE) {
+ // Its parent is another inline site, lookup parent site's range vector
+ // for callsite line.
+ ParseInlineSite(parent_id, func_base);
+ std::shared_ptr<InlineSite> parent_site =
+ m_inline_sites[toOpaqueUid(parent_id)];
+ FileSpec &parent_decl_file =
+ parent_site->inline_function_info->GetDeclaration().GetFile();
+ if (auto *parent_entry =
+ parent_site->ranges.FindEntryThatContains(base_offset)) {
+ callsite_up =
+ std::make_unique<Declaration>(parent_decl_file, parent_entry->data);
+ }
+ } else {
+ // Its parent is a function, lookup global line table for callsite.
+ if (auto *entry = cii->m_global_line_table.FindEntryThatContains(
+ func_base + base_offset)) {
+ const FileSpec &callsite_file =
+ files.GetFileSpecAtIndex(entry->data.first);
+ callsite_up =
+ std::make_unique<Declaration>(callsite_file, entry->data.second);
+ }
+ }
+ }
+
+ // Get the inlined function name.
+ CVType inlinee_cvt = m_index->ipi().getType(inline_site.Inlinee);
+ std::string inlinee_name;
+ if (inlinee_cvt.kind() == LF_MFUNC_ID) {
+ MemberFuncIdRecord mfr;
+ cantFail(
+ TypeDeserializer::deserializeAs<MemberFuncIdRecord>(inlinee_cvt, mfr));
+ LazyRandomTypeCollection &types = m_index->tpi().typeCollection();
+ inlinee_name.append(std::string(types.getTypeName(mfr.ClassType)));
+ inlinee_name.append("::");
+ inlinee_name.append(mfr.getName().str());
+ } else if (inlinee_cvt.kind() == LF_FUNC_ID) {
+ FuncIdRecord fir;
+ cantFail(TypeDeserializer::deserializeAs<FuncIdRecord>(inlinee_cvt, fir));
+ TypeIndex parent_idx = fir.getParentScope();
+ if (!parent_idx.isNoneType()) {
+ LazyRandomTypeCollection &ids = m_index->ipi().typeCollection();
+ inlinee_name.append(std::string(ids.getTypeName(parent_idx)));
+ inlinee_name.append("::");
+ }
+ inlinee_name.append(fir.getName().str());
+ }
+ inline_site_sp->inline_function_info = std::make_shared<InlineFunctionInfo>(
+ inlinee_name.c_str(), llvm::StringRef(), decl_up.get(),
+ callsite_up.get());
+
+ m_inline_sites[opaque_uid] = inline_site_sp;
+}
+
size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- GetOrCreateBlock(PdbSymUid(func.GetID()).asCompilandSym());
- // FIXME: Parse child blocks
- return 1;
+ PdbCompilandSymId func_id = PdbSymUid(func.GetID()).asCompilandSym();
+ // After we iterate through inline sites inside the function, we already get
+ // all the info needed, removing from the map to save memory.
+ std::set<uint64_t> remove_uids;
+ auto parse_blocks = [&](SymbolKind kind, PdbCompilandSymId id) {
+ if (kind == S_GPROC32 || kind == S_LPROC32 || kind == S_BLOCK32 ||
+ kind == S_INLINESITE) {
+ GetOrCreateBlock(id);
+ if (kind == S_INLINESITE)
+ remove_uids.insert(toOpaqueUid(id));
+ return true;
+ }
+ return false;
+ };
+ size_t count = ParseSymbolArrayInScope(func_id, parse_blocks);
+ for (uint64_t uid : remove_uids) {
+ m_inline_sites.erase(uid);
+ }
+ return count;
+}
+
+size_t SymbolFileNativePDB::ParseSymbolArrayInScope(
+ PdbCompilandSymId parent_id,
+ llvm::function_ref<bool(SymbolKind, PdbCompilandSymId)> fn) {
+ CompilandIndexItem *cii = m_index->compilands().GetCompiland(parent_id.modi);
+ CVSymbolArray syms =
+ cii->m_debug_stream.getSymbolArrayForScope(parent_id.offset);
+
+ size_t count = 1;
+ for (auto iter = syms.begin(); iter != syms.end(); ++iter) {
+ PdbCompilandSymId child_id(parent_id.modi, iter.offset());
+ if (fn(iter->kind(), child_id))
+ ++count;
+ }
+
+ return count;
}
void SymbolFileNativePDB::DumpClangAST(Stream &s) { m_ast->Dump(s); }
@@ -1396,6 +1730,9 @@ size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) {
}
case S_BLOCK32:
break;
+ case S_INLINESITE:
+ // TODO: Handle inline site case.
+ return 0;
default:
lldbassert(false && "Symbol is not a block!");
return 0;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index 56a5ec0a464d..f1b6e34ca346 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -9,6 +9,7 @@
#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H
#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H
+#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/SymbolFile.h"
#include "llvm/ADT/DenseMap.h"
@@ -161,6 +162,25 @@ public:
void DumpClangAST(Stream &s) override;
private:
+ struct LineTableEntryComparator {
+ bool operator()(const lldb_private::LineTable::Entry &lhs,
+ const lldb_private::LineTable::Entry &rhs) const {
+ return lhs.file_addr < rhs.file_addr;
+ }
+ };
+
+ // From address range relative to function base to source line number.
+ using RangeSourceLineVector =
+ lldb_private::RangeDataVector<uint32_t, uint32_t, int32_t>;
+ // InlineSite contains information in a S_INLINESITE record.
+ struct InlineSite {
+ PdbCompilandSymId parent_id;
+ std::shared_ptr<InlineFunctionInfo> inline_function_info;
+ RangeSourceLineVector ranges;
+ std::vector<lldb_private::LineTable::Entry> line_entries;
+ InlineSite(PdbCompilandSymId parent_id) : parent_id(parent_id){};
+ };
+
uint32_t CalculateNumCompileUnits() override;
lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
@@ -225,6 +245,16 @@ private:
VariableList &variables);
size_t ParseVariablesForBlock(PdbCompilandSymId block_id);
+ llvm::Expected<uint32_t> GetFileIndex(const CompilandIndexItem &cii,
+ uint32_t file_id);
+
+ size_t ParseSymbolArrayInScope(
+ PdbCompilandSymId parent,
+ llvm::function_ref<bool(llvm::codeview::SymbolKind, PdbCompilandSymId)>
+ fn);
+
+ void ParseInlineSite(PdbCompilandSymId inline_site_id, Address func_addr);
+
llvm::BumpPtrAllocator m_allocator;
lldb::addr_t m_obj_load_address = 0;
@@ -241,6 +271,9 @@ private:
llvm::DenseMap<lldb::user_id_t, lldb::FunctionSP> m_functions;
llvm::DenseMap<lldb::user_id_t, lldb::CompUnitSP> m_compilands;
llvm::DenseMap<lldb::user_id_t, lldb::TypeSP> m_types;
+ llvm::DenseMap<lldb::user_id_t, std::shared_ptr<InlineSite>> m_inline_sites;
+ // A map from file id in records to file index in support files.
+ llvm::DenseMap<uint32_t, uint32_t> m_file_indexes;
};
} // namespace npdb
diff --git a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 57e763176ba0..c71a0120efde 100644
--- a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -1345,7 +1345,30 @@ namespace {
bool IsValueParam(const clang::TemplateArgument &argument) {
return argument.getKind() == TemplateArgument::Integral;
}
+
+void AddAccessSpecifierDecl(clang::CXXRecordDecl *cxx_record_decl,
+ ASTContext &ct,
+ clang::AccessSpecifier previous_access,
+ clang::AccessSpecifier access_specifier) {
+ if (!cxx_record_decl->isClass() && !cxx_record_decl->isStruct())
+ return;
+ if (previous_access != access_specifier) {
+ // For struct, don't add AS_public if it's the first AccessSpecDecl.
+ // For class, don't add AS_private if it's the first AccessSpecDecl.
+ if ((cxx_record_decl->isStruct() &&
+ previous_access == clang::AccessSpecifier::AS_none &&
+ access_specifier == clang::AccessSpecifier::AS_public) ||
+ (cxx_record_decl->isClass() &&
+ previous_access == clang::AccessSpecifier::AS_none &&
+ access_specifier == clang::AccessSpecifier::AS_private)) {
+ return;
+ }
+ cxx_record_decl->addDecl(
+ AccessSpecDecl::Create(ct, access_specifier, cxx_record_decl,
+ SourceLocation(), SourceLocation()));
+ }
}
+} // namespace
static TemplateParameterList *CreateTemplateParameterList(
ASTContext &ast,
@@ -1453,7 +1476,7 @@ void TypeSystemClang::CreateFunctionTemplateSpecializationInfo(
/// as `int I = 3`.
static bool TemplateParameterAllowsValue(NamedDecl *param,
const TemplateArgument &value) {
- if (auto *type_param = llvm::dyn_cast<TemplateTypeParmDecl>(param)) {
+ if (llvm::isa<TemplateTypeParmDecl>(param)) {
// Compare the argument kind, i.e. ensure that <typename> != <int>.
if (value.getKind() != TemplateArgument::Type)
return false;
@@ -2552,6 +2575,22 @@ ClangASTMetadata *TypeSystemClang::GetMetadata(const clang::Type *object) {
return nullptr;
}
+void TypeSystemClang::SetCXXRecordDeclAccess(const clang::CXXRecordDecl *object,
+ clang::AccessSpecifier access) {
+ if (access == clang::AccessSpecifier::AS_none)
+ m_cxx_record_decl_access.erase(object);
+ else
+ m_cxx_record_decl_access[object] = access;
+}
+
+clang::AccessSpecifier
+TypeSystemClang::GetCXXRecordDeclAccess(const clang::CXXRecordDecl *object) {
+ auto It = m_cxx_record_decl_access.find(object);
+ if (It != m_cxx_record_decl_access.end())
+ return It->second;
+ return clang::AccessSpecifier::AS_none;
+}
+
clang::DeclContext *
TypeSystemClang::GetDeclContextForType(const CompilerType &type) {
return GetDeclContextForType(ClangUtil::GetQualType(type));
@@ -7276,9 +7315,17 @@ clang::FieldDecl *TypeSystemClang::AddFieldToRecordType(
}
if (field) {
- field->setAccess(
- TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access));
-
+ clang::AccessSpecifier access_specifier =
+ TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access);
+ field->setAccess(access_specifier);
+
+ if (clang::CXXRecordDecl *cxx_record_decl =
+ llvm::dyn_cast<CXXRecordDecl>(record_decl)) {
+ AddAccessSpecifierDecl(cxx_record_decl, ast->getASTContext(),
+ ast->GetCXXRecordDeclAccess(cxx_record_decl),
+ access_specifier);
+ ast->SetCXXRecordDeclAccess(cxx_record_decl, access_specifier);
+ }
record_decl->addDecl(field);
VerifyDecl(field);
@@ -7657,6 +7704,11 @@ clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType(
cxx_method_decl->setParams(llvm::ArrayRef<clang::ParmVarDecl *>(params));
+ AddAccessSpecifierDecl(cxx_record_decl, getASTContext(),
+ GetCXXRecordDeclAccess(cxx_record_decl),
+ access_specifier);
+ SetCXXRecordDeclAccess(cxx_record_decl, access_specifier);
+
cxx_record_decl->addDecl(cxx_method_decl);
// Sometimes the debug info will mention a constructor (default/copy/move),
@@ -8190,6 +8242,11 @@ bool TypeSystemClang::CompleteTagDeclarationDefinition(
if (qual_type.isNull())
return false;
+ TypeSystemClang *lldb_ast =
+ llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+ if (lldb_ast == nullptr)
+ return false;
+
// Make sure we use the same methodology as
// TypeSystemClang::StartTagDeclarationDefinition() as to how we start/end
// the definition.
@@ -8220,6 +8277,8 @@ bool TypeSystemClang::CompleteTagDeclarationDefinition(
cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
cxx_record_decl->setHasExternalLexicalStorage(false);
cxx_record_decl->setHasExternalVisibleStorage(false);
+ lldb_ast->SetCXXRecordDeclAccess(cxx_record_decl,
+ clang::AccessSpecifier::AS_none);
return true;
}
}
@@ -8233,10 +8292,6 @@ bool TypeSystemClang::CompleteTagDeclarationDefinition(
if (enum_decl->isCompleteDefinition())
return true;
- TypeSystemClang *lldb_ast =
- llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
- if (lldb_ast == nullptr)
- return false;
clang::ASTContext &ast = lldb_ast->getASTContext();
/// TODO This really needs to be fixed.
diff --git a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
index 5e75a8aba9e8..c59ecdb31790 100644
--- a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -196,6 +196,11 @@ public:
ClangASTMetadata *GetMetadata(const clang::Decl *object);
ClangASTMetadata *GetMetadata(const clang::Type *object);
+ void SetCXXRecordDeclAccess(const clang::CXXRecordDecl *object,
+ clang::AccessSpecifier access);
+ clang::AccessSpecifier
+ GetCXXRecordDeclAccess(const clang::CXXRecordDecl *object);
+
// Basic Types
CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding,
size_t bit_size) override;
@@ -1084,6 +1089,12 @@ private:
/// Maps Types to their associated ClangASTMetadata.
TypeMetadataMap m_type_metadata;
+ typedef llvm::DenseMap<const clang::CXXRecordDecl *, clang::AccessSpecifier>
+ CXXRecordDeclAccessMap;
+ /// Maps CXXRecordDecl to their most recent added method/field's
+ /// AccessSpecifier.
+ CXXRecordDeclAccessMap m_cxx_record_decl_access;
+
/// The sema associated that is currently used to build this ASTContext.
/// May be null if we are already done parsing this ASTContext or the
/// ASTContext wasn't created by parsing source code.