aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-12-25 22:30:44 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-12-25 22:30:44 +0000
commit77fc4c146f0870ffb09c1afb823ccbe742c5e6ff (patch)
tree5c0eb39553003b9c75a901af6bc4ddabd6f2f28c /lldb/source/Plugins
parentf65dcba83ce5035ab88a85fe17628b447eb56e1b (diff)
Diffstat (limited to 'lldb/source/Plugins')
-rw-r--r--lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp10
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp2
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp4
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp2
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h2
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp2
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp2
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp2
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp36
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/Generic.h25
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/GenericOptional.cpp139
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxx.h4
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp84
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h4
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp3
-rw-r--r--lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp2
-rw-r--r--lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp90
-rw-r--r--lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h2
-rw-r--r--lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td12
-rw-r--r--lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp16
-rw-r--r--lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp218
-rw-r--r--lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h51
-rw-r--r--lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.cpp110
-rw-r--r--lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.h41
-rw-r--r--lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.cpp83
-rw-r--r--lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.h41
-rw-r--r--lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.cpp88
-rw-r--r--lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.h41
-rw-r--r--lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.cpp85
-rw-r--r--lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.h36
-rw-r--r--lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp4
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp36
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h6
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp102
-rw-r--r--lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp5
-rw-r--r--lldb/source/Plugins/Process/scripted/ScriptedThread.cpp10
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp33
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Lua/SWIGLuaBridge.h28
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h43
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp52
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h11
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h7
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp6
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp6
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp5
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp11
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h12
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp133
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h6
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp30
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h12
-rw-r--r--lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp3
-rw-r--r--lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp3
-rw-r--r--lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp19
56 files changed, 1539 insertions, 285 deletions
diff --git a/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
index ccfbeec3d589..804532acf9f7 100644
--- a/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
+++ b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
@@ -817,6 +817,16 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl(
lldb::addr_t ABIMacOSX_arm64::FixAddress(addr_t pc, addr_t mask) {
lldb::addr_t pac_sign_extension = 0x0080000000000000ULL;
+ // Darwin systems originally couldn't determine the proper value
+ // dynamically, so the most common value was hardcoded. This has
+ // largely been cleaned up, but there are still a handful of
+ // environments that assume the default value is set to this value
+ // and there's no dynamic value to correct it.
+ // When no mask is specified, set it to 39 bits of addressing (0..38).
+ if (mask == 0) {
+ // ~((1ULL<<39)-1)
+ mask = 0xffffff8000000000;
+ }
return (pc & pac_sign_extension) ? pc | mask : pc & (~mask);
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
index 85e2fcfc838c..7844f27139cf 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
@@ -211,7 +211,7 @@ bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body,
Stmt **last_stmt_ptr = Body->body_end() - 1;
Stmt *last_stmt = *last_stmt_ptr;
- while (dyn_cast<NullStmt>(last_stmt)) {
+ while (isa<NullStmt>(last_stmt)) {
if (last_stmt_ptr != Body->body_begin()) {
last_stmt_ptr--;
last_stmt = *last_stmt_ptr;
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
index 80469e292580..6ed3cc9384f0 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
@@ -293,7 +293,7 @@ public:
NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to);
// Check if we already completed this type.
- if (m_decls_already_completed.count(to_named_decl) != 0)
+ if (m_decls_already_completed.contains(to_named_decl))
return;
// Queue this type to be completed.
m_decls_to_complete.insert(to_named_decl);
@@ -806,7 +806,7 @@ void ClangASTImporter::ForgetSource(clang::ASTContext *dst_ast,
md->removeOriginsWithContext(src_ast);
}
-ClangASTImporter::MapCompleter::~MapCompleter() { return; }
+ClangASTImporter::MapCompleter::~MapCompleter() {}
llvm::Expected<Decl *>
ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) {
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
index 410d8a95cb12..510352e8c173 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
@@ -513,8 +513,6 @@ void ClangASTSource::FindExternalLexicalDecls(
// is consulted again when a clang::DeclContext::lookup is called.
const_cast<DeclContext *>(decl_context)->setMustBuildLookupTable();
}
-
- return;
}
void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
index 3afd1fd5f2d1..f3fec3f944a1 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
@@ -59,7 +59,7 @@ public:
GetExternalCXXBaseSpecifiers(uint64_t Offset) override {
return nullptr;
}
- void MaterializeVisibleDecls(const clang::DeclContext *DC) { return; }
+ void MaterializeVisibleDecls(const clang::DeclContext *DC) {}
void InstallASTContext(TypeSystemClang &ast_context);
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index 846c1597292b..4af5d41a5921 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -1954,8 +1954,6 @@ void ClangExpressionDeclMap::AddContextClassType(NameSearchContext &context,
return;
context.AddNamedDecl(typedef_decl);
-
- return;
}
void ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp b/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
index a6e36d81b950..8b132b54b7e6 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
@@ -353,7 +353,7 @@ protected:
}
bool InspectInstruction(llvm::Instruction &i) override {
- if (dyn_cast<llvm::LoadInst>(&i) || dyn_cast<llvm::StoreInst>(&i))
+ if (isa<llvm::LoadInst>(&i) || isa<llvm::StoreInst>(&i))
RegisterInstruction(i);
return true;
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
index f80dc2b14467..e0e41925f7ef 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
@@ -1255,7 +1255,7 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
m_decl_map->AddValueToStruct(named_decl, lldb_private::ConstString(name),
llvm_value_ptr, *value_size,
value_alignment);
- } else if (dyn_cast<llvm::Function>(llvm_value_ptr)) {
+ } else if (isa<llvm::Function>(llvm_value_ptr)) {
LLDB_LOG(log, "Function pointers aren't handled right now");
return false;
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index f1925990e94a..df61cc3853eb 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -35,6 +35,7 @@
#include "BlockPointer.h"
#include "CPlusPlusNameParser.h"
#include "CxxStringTypes.h"
+#include "Generic.h"
#include "LibCxx.h"
#include "LibCxxAtomic.h"
#include "LibCxxVariant.h"
@@ -655,7 +656,7 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"libc++ std::tuple synthetic children",
ConstString("^std::__[[:alnum:]]+::tuple<.*>(( )?&)?$"),
stl_synth_flags, true);
- AddCXXSynthetic(cpp_category_sp, LibcxxOptionalFrontEndCreator,
+ AddCXXSynthetic(cpp_category_sp, LibcxxOptionalSyntheticFrontEndCreator,
"libc++ std::optional synthetic children",
ConstString("^std::__[[:alnum:]]+::optional<.+>(( )?&)?$"),
stl_synth_flags, true);
@@ -772,7 +773,7 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
ConstString("^std::__[[:alnum:]]+::atomic<.+>$"),
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
- lldb_private::formatters::LibcxxOptionalSummaryProvider,
+ lldb_private::formatters::GenericOptionalSummaryProvider,
"libc++ std::optional summary provider",
ConstString("^std::__[[:alnum:]]+::optional<.+>(( )?&)?$"),
stl_summary_flags, true);
@@ -904,6 +905,11 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
stl_synth_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
+ RegularExpression("^std::deque<.+>(( )?&)?$"),
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ stl_deref_flags,
+ "lldb.formatters.cpp.gnu_libstdcpp.StdDequeSynthProvider")));
+ cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
RegularExpression("^std::set<.+> >(( )?&)?$"),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_deref_flags,
@@ -914,11 +920,6 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
stl_deref_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
- RegularExpression("^std::optional<.+>(( )?&)?$"),
- SyntheticChildrenSP(new ScriptedSyntheticChildren(
- stl_synth_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdOptionalSynthProvider")));
- cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
RegularExpression("^std::multiset<.+> >(( )?&)?$"),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_deref_flags,
@@ -931,7 +932,7 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$"),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
- stl_synth_flags,
+ stl_deref_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
RegularExpression("^std::(__cxx11::)?forward_list<.+>(( )?&)?$"),
@@ -942,11 +943,6 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
stl_summary_flags.SetDontShowChildren(false);
stl_summary_flags.SetSkipPointers(false);
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
- RegularExpression("^std::optional<.+>(( )?&)?$"),
- TypeSummaryImplSP(new ScriptSummaryFormat(
- stl_summary_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdOptionalSummaryProvider")));
- cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
RegularExpression("^std::bitset<.+>(( )?&)?$"),
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
@@ -963,6 +959,10 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
+ RegularExpression("^std::deque<.+>(( )?&)?$"),
+ TypeSummaryImplSP(
+ new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
+ cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
RegularExpression("^std::multimap<.+> >(( )?&)?$"),
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
@@ -1022,6 +1022,12 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"std::bitset synthetic child", ConstString("^std::bitset<.+>(( )?&)?$"),
stl_deref_flags, true);
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibStdcppOptionalSyntheticFrontEndCreator,
+ "std::optional synthetic child",
+ ConstString("^std::optional<.+>(( )?&)?$"), stl_deref_flags, true);
+
AddCXXSummary(cpp_category_sp,
lldb_private::formatters::LibStdcppUniquePointerSummaryProvider,
"libstdc++ std::unique_ptr summary provider",
@@ -1037,6 +1043,10 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"libstdc++ std::weak_ptr summary provider",
ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_summary_flags,
true);
+ AddCXXSummary(
+ cpp_category_sp, lldb_private::formatters::GenericOptionalSummaryProvider,
+ "libstd++ std::optional summary provider",
+ ConstString("^std::optional<.+>(( )?&)?$"), stl_summary_flags, true);
}
static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
diff --git a/lldb/source/Plugins/Language/CPlusPlus/Generic.h b/lldb/source/Plugins/Language/CPlusPlus/Generic.h
new file mode 100644
index 000000000000..bfb28bebf90b
--- /dev/null
+++ b/lldb/source/Plugins/Language/CPlusPlus/Generic.h
@@ -0,0 +1,25 @@
+//===-- LibCxx.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_LANGUAGE_CPLUSPLUS_GENERIC_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_GENERIC_H
+
+#include "lldb/Core/ValueObject.h"
+#include "lldb/DataFormatters/TypeSummary.h"
+#include "lldb/Utility/Stream.h"
+
+namespace lldb_private {
+namespace formatters {
+
+bool GenericOptionalSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+} // namespace formatters
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_GENERIC_H
diff --git a/lldb/source/Plugins/Language/CPlusPlus/GenericOptional.cpp b/lldb/source/Plugins/Language/CPlusPlus/GenericOptional.cpp
new file mode 100644
index 000000000000..74b3f711de35
--- /dev/null
+++ b/lldb/source/Plugins/Language/CPlusPlus/GenericOptional.cpp
@@ -0,0 +1,139 @@
+//===-- GenericOptional.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 "Generic.h"
+#include "LibCxx.h"
+#include "LibStdcpp.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+bool lldb_private::formatters::GenericOptionalSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ stream.Printf(" Has Value=%s ",
+ valobj.GetNumChildren() == 0 ? "false" : "true");
+
+ return true;
+}
+
+// Synthetic Children Provider
+namespace {
+
+class GenericOptionalFrontend : public SyntheticChildrenFrontEnd {
+public:
+ enum class StdLib {
+ LibCxx,
+ LibStdcpp,
+ };
+
+ GenericOptionalFrontend(ValueObject &valobj, StdLib stdlib);
+
+ size_t GetIndexOfChildWithName(ConstString name) override {
+ return formatters::ExtractIndexFromString(name.GetCString());
+ }
+
+ bool MightHaveChildren() override { return true; }
+ size_t CalculateNumChildren() override { return m_has_value ? 1U : 0U; }
+
+ ValueObjectSP GetChildAtIndex(size_t idx) override;
+ bool Update() override;
+
+private:
+ bool m_has_value = false;
+ StdLib m_stdlib;
+};
+
+} // namespace
+
+GenericOptionalFrontend::GenericOptionalFrontend(ValueObject &valobj,
+ StdLib stdlib)
+ : SyntheticChildrenFrontEnd(valobj), m_stdlib(stdlib) {
+ if (auto target_sp = m_backend.GetTargetSP()) {
+ Update();
+ }
+}
+
+bool GenericOptionalFrontend::Update() {
+ ValueObjectSP engaged_sp;
+
+ if (m_stdlib == StdLib::LibCxx)
+ engaged_sp =
+ m_backend.GetChildMemberWithName(ConstString("__engaged_"), true);
+ else if (m_stdlib == StdLib::LibStdcpp)
+ engaged_sp =
+ m_backend.GetChildMemberWithName(ConstString("_M_payload"), true)
+ ->GetChildMemberWithName(ConstString("_M_engaged"), true);
+
+ if (!engaged_sp)
+ return false;
+
+ // _M_engaged/__engaged is a bool flag and is true if the optional contains a
+ // value. Converting it to unsigned gives us a size of 1 if it contains a
+ // value and 0 if not.
+ m_has_value = engaged_sp->GetValueAsUnsigned(0) != 0;
+
+ return false;
+}
+
+ValueObjectSP GenericOptionalFrontend::GetChildAtIndex(size_t _idx) {
+ if (!m_has_value)
+ return ValueObjectSP();
+
+ ValueObjectSP val_sp;
+
+ if (m_stdlib == StdLib::LibCxx)
+ // __val_ contains the underlying value of an optional if it has one.
+ // Currently because it is part of an anonymous union
+ // GetChildMemberWithName() does not peer through and find it unless we are
+ // at the parent itself. We can obtain the parent through __engaged_.
+ val_sp = m_backend.GetChildMemberWithName(ConstString("__engaged_"), true)
+ ->GetParent()
+ ->GetChildAtIndex(0, true)
+ ->GetChildMemberWithName(ConstString("__val_"), true);
+ else if (m_stdlib == StdLib::LibStdcpp) {
+ val_sp = m_backend.GetChildMemberWithName(ConstString("_M_payload"), true)
+ ->GetChildMemberWithName(ConstString("_M_payload"), true);
+
+ // In some implementations, _M_value contains the underlying value of an
+ // optional, and in other versions, it's in the payload member.
+ ValueObjectSP candidate =
+ val_sp->GetChildMemberWithName(ConstString("_M_value"), true);
+ if (candidate)
+ val_sp = candidate;
+ }
+
+ if (!val_sp)
+ return ValueObjectSP();
+
+ CompilerType holder_type = val_sp->GetCompilerType();
+
+ if (!holder_type)
+ return ValueObjectSP();
+
+ return val_sp->Clone(ConstString("Value"));
+}
+
+SyntheticChildrenFrontEnd *
+formatters::LibStdcppOptionalSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ if (valobj_sp)
+ return new GenericOptionalFrontend(
+ *valobj_sp, GenericOptionalFrontend::StdLib::LibStdcpp);
+ return nullptr;
+}
+
+SyntheticChildrenFrontEnd *formatters::LibcxxOptionalSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ if (valobj_sp)
+ return new GenericOptionalFrontend(*valobj_sp,
+ GenericOptionalFrontend::StdLib::LibCxx);
+ return nullptr;
+}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
index 99e206543197..80dc71787ceb 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -170,8 +170,8 @@ SyntheticChildrenFrontEnd *LibcxxTupleFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
SyntheticChildrenFrontEnd *
-LibcxxOptionalFrontEndCreator(CXXSyntheticChildren *,
- lldb::ValueObjectSP valobj_sp);
+LibcxxOptionalSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP valobj_sp);
SyntheticChildrenFrontEnd *
LibcxxVariantFrontEndCreator(CXXSyntheticChildren *,
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
deleted file mode 100644
index c1b40ba65e7d..000000000000
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-//===-- LibCxxOptional.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 "LibCxx.h"
-#include "lldb/DataFormatters/FormattersHelpers.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-
-class OptionalFrontEnd : public SyntheticChildrenFrontEnd {
-public:
- OptionalFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) {
- Update();
- }
-
- size_t GetIndexOfChildWithName(ConstString name) override {
- return formatters::ExtractIndexFromString(name.GetCString());
- }
-
- bool MightHaveChildren() override { return true; }
- bool Update() override;
- size_t CalculateNumChildren() override { return m_has_value ? 1U : 0U; }
- ValueObjectSP GetChildAtIndex(size_t idx) override;
-
-private:
- /// True iff the option contains a value.
- bool m_has_value = false;
-};
-} // namespace
-
-bool OptionalFrontEnd::Update() {
- ValueObjectSP engaged_sp(
- m_backend.GetChildMemberWithName(ConstString("__engaged_"), true));
-
- if (!engaged_sp)
- return false;
-
- // __engaged_ is a bool flag and is true if the optional contains a value.
- // Converting it to unsigned gives us a size of 1 if it contains a value
- // and 0 if not.
- m_has_value = engaged_sp->GetValueAsUnsigned(0) != 0;
-
- return false;
-}
-
-ValueObjectSP OptionalFrontEnd::GetChildAtIndex(size_t idx) {
- if (!m_has_value)
- return ValueObjectSP();
-
- // __val_ contains the underlying value of an optional if it has one.
- // Currently because it is part of an anonymous union GetChildMemberWithName()
- // does not peer through and find it unless we are at the parent itself.
- // We can obtain the parent through __engaged_.
- ValueObjectSP val_sp(
- m_backend.GetChildMemberWithName(ConstString("__engaged_"), true)
- ->GetParent()
- ->GetChildAtIndex(0, true)
- ->GetChildMemberWithName(ConstString("__val_"), true));
-
- if (!val_sp)
- return ValueObjectSP();
-
- CompilerType holder_type = val_sp->GetCompilerType();
-
- if (!holder_type)
- return ValueObjectSP();
-
- return val_sp->Clone(ConstString("Value"));
-}
-
-SyntheticChildrenFrontEnd *
-formatters::LibcxxOptionalFrontEndCreator(CXXSyntheticChildren *,
- lldb::ValueObjectSP valobj_sp) {
- if (valobj_sp)
- return new OptionalFrontEnd(*valobj_sp);
- return nullptr;
-}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h
index b6f9c469fedd..1c1c8fdb9ea4 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h
@@ -46,6 +46,10 @@ LibStdcppBitsetSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
SyntheticChildrenFrontEnd *
+LibStdcppOptionalSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *
LibStdcppVectorIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
index 9bc40c16e5d0..af11109ae45d 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
@@ -80,8 +80,6 @@ public:
LLDB_LOG(log, " AOEAS::CT Before:\n{1}", ClangUtil::DumpDecl(tag_decl));
LLDB_LOG(log, " AOEAS::CT After:{1}", ClangUtil::DumpDecl(tag_decl));
-
- return;
}
void CompleteType(clang::ObjCInterfaceDecl *interface_decl) override {
@@ -107,7 +105,6 @@ public:
LLDB_LOGF(log, " [CT] After:");
LLDB_LOG(log, " [CT] {0}", ClangUtil::DumpDecl(interface_decl));
}
- return;
}
bool layoutRecordType(
diff --git a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index 719109c863e7..1d989b268b74 100644
--- a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -589,6 +589,8 @@ PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx,
result_ptr->image_ptr = dlopen(name, RTLD_LAZY);
if (result_ptr->image_ptr)
result_ptr->error_str = nullptr;
+ else
+ result_ptr->error_str = dlerror();
return nullptr;
}
diff --git a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp
index 90c290b6fbc7..67c9484680a4 100644
--- a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp
+++ b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp
@@ -47,6 +47,27 @@ public:
return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr,
ePropertyEmulatorPath);
}
+
+ Args GetEmulatorArgs() {
+ Args result;
+ m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, ePropertyEmulatorArgs,
+ result);
+ return result;
+ }
+
+ Environment GetEmulatorEnvVars() {
+ Args args;
+ m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, ePropertyEmulatorEnvVars,
+ args);
+ return Environment(args);
+ }
+
+ Environment GetTargetEnvVars() {
+ Args args;
+ m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, ePropertyTargetEnvVars,
+ args);
+ return Environment(args);
+ }
};
static PluginProperties &GetGlobalProperties() {
@@ -98,6 +119,44 @@ static auto get_arg_range(const Args &args) {
args.GetArgumentArrayRef().end());
}
+// Returns the emulator environment which result in the desired environment
+// being presented to the emulated process. We want to be careful about
+// preserving the host environment, as it may contain entries (LD_LIBRARY_PATH,
+// for example) needed for the operation of the emulator itself.
+static Environment ComputeLaunchEnvironment(Environment target,
+ Environment host) {
+ std::vector<std::string> set_env;
+ for (const auto &KV : target) {
+ // If the host value differs from the target (or is unset), then set it
+ // through QEMU_SET_ENV. Identical entries will be forwarded automatically.
+ auto host_it = host.find(KV.first());
+ if (host_it == host.end() || host_it->second != KV.second)
+ set_env.push_back(Environment::compose(KV));
+ }
+ llvm::sort(set_env);
+
+ std::vector<llvm::StringRef> unset_env;
+ for (const auto &KV : host) {
+ // If the target is missing some host entries, then unset them through
+ // QEMU_UNSET_ENV.
+ if (target.count(KV.first()) == 0)
+ unset_env.push_back(KV.first());
+ }
+ llvm::sort(unset_env);
+
+ // The actual QEMU_(UN)SET_ENV variables should not be forwarded to the
+ // target.
+ if (!set_env.empty()) {
+ host["QEMU_SET_ENV"] = llvm::join(set_env, ",");
+ unset_env.push_back("QEMU_SET_ENV");
+ }
+ if (!unset_env.empty()) {
+ unset_env.push_back("QEMU_UNSET_ENV");
+ host["QEMU_UNSET_ENV"] = llvm::join(unset_env, ",");
+ }
+ return host;
+}
+
lldb::ProcessSP PlatformQemuUser::DebugProcess(ProcessLaunchInfo &launch_info,
Debugger &debugger,
Target &target, Status &error) {
@@ -112,8 +171,10 @@ 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, launch_info.GetExecutableFile().GetPath()});
+ Args args({qemu, "-g", socket_path});
+ args.AppendArguments(GetGlobalProperties().GetEmulatorArgs());
+ args.AppendArgument("--");
+ args.AppendArgument(launch_info.GetExecutableFile().GetPath());
for (size_t i = 1; i < launch_info.GetArguments().size(); ++i)
args.AppendArgument(launch_info.GetArguments()[i].ref());
@@ -121,11 +182,23 @@ lldb::ProcessSP PlatformQemuUser::DebugProcess(ProcessLaunchInfo &launch_info,
get_arg_range(args));
launch_info.SetArguments(args, true);
+
+ Environment emulator_env = Host::GetEnvironment();
+ for (const auto &KV : GetGlobalProperties().GetEmulatorEnvVars())
+ emulator_env[KV.first()] = KV.second;
+ launch_info.GetEnvironment() = ComputeLaunchEnvironment(
+ std::move(launch_info.GetEnvironment()), std::move(emulator_env));
+
launch_info.SetLaunchInSeparateProcessGroup(true);
launch_info.GetFlags().Clear(eLaunchFlagDebug);
launch_info.SetMonitorProcessCallback(ProcessLaunchInfo::NoOpMonitorCallback,
false);
+ // This is automatically done for host platform in
+ // Target::FinalizeFileActions, but we're not a host platform.
+ llvm::Error Err = launch_info.SetUpPtyRedirection();
+ LLDB_LOG_ERROR(log, std::move(Err), "SetUpPtyRedirection failed: {0}");
+
error = Host::LaunchProcess(launch_info);
if (error.Fail())
return nullptr;
@@ -134,6 +207,7 @@ lldb::ProcessSP PlatformQemuUser::DebugProcess(ProcessLaunchInfo &launch_info,
launch_info.GetListener(),
process_gdb_remote::ProcessGDBRemote::GetPluginNameStatic(), nullptr,
true);
+
ListenerSP listener_sp =
Listener::MakeListener("lldb.platform_qemu_user.debugprocess");
launch_info.SetHijackListener(listener_sp);
@@ -143,6 +217,18 @@ lldb::ProcessSP PlatformQemuUser::DebugProcess(ProcessLaunchInfo &launch_info,
if (error.Fail())
return nullptr;
+ if (launch_info.GetPTY().GetPrimaryFileDescriptor() !=
+ PseudoTerminal::invalid_fd)
+ process_sp->SetSTDIOFileDescriptor(
+ launch_info.GetPTY().ReleasePrimaryFileDescriptor());
+
process_sp->WaitForProcessToStop(llvm::None, nullptr, false, listener_sp);
return process_sp;
}
+
+Environment PlatformQemuUser::GetEnvironment() {
+ Environment env = Host::GetEnvironment();
+ for (const auto &KV : GetGlobalProperties().GetTargetEnvVars())
+ env[KV.first()] = KV.second;
+ return env;
+}
diff --git a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h
index f4f5d224a8cd..71df1b7b7811 100644
--- a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h
+++ b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h
@@ -45,7 +45,7 @@ public:
void CalculateTrapHandlerSymbolNames() override {}
- Environment GetEnvironment() override { return Host::GetEnvironment(); }
+ Environment GetEnvironment() override;
private:
static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
diff --git a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td
index abfab7f59de4..4e8fbcfd6760 100644
--- a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td
+++ b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td
@@ -9,4 +9,16 @@ let Definition = "platformqemuuser" in {
Global,
DefaultStringValue<"">,
Desc<"Path to the emulator binary.">;
+ def EmulatorArgs: Property<"emulator-args", "Args">,
+ Global,
+ DefaultStringValue<"">,
+ Desc<"Extra arguments to pass to the emulator.">;
+ def EmulatorEnvVars: Property<"emulator-env-vars", "Dictionary">,
+ Global,
+ ElementType<"String">,
+ Desc<"Extra variables to add to the emulator environment.">;
+ def TargetEnvVars: Property<"target-env-vars", "Dictionary">,
+ Global,
+ ElementType<"String">,
+ Desc<"Extra variables to add to emulated target environment.">;
}
diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 987f7c7f57e7..3535a5ad739d 100644
--- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -225,18 +225,12 @@ Status PlatformRemoteGDBServer::ConnectRemote(Args &args) {
m_platform_hostname = parsed_url->hostname.str();
m_gdb_client.SetConnection(std::make_unique<ConnectionFileDescriptor>());
- if (repro::Reproducer::Instance().IsReplaying()) {
- error = m_gdb_replay_server.Connect(m_gdb_client);
- if (error.Success())
- m_gdb_replay_server.StartAsyncThread();
- } else {
- if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
- repro::GDBRemoteProvider &provider =
- g->GetOrCreate<repro::GDBRemoteProvider>();
- m_gdb_client.SetPacketRecorder(provider.GetNewPacketRecorder());
- }
- m_gdb_client.Connect(url, &error);
+ if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
+ repro::GDBRemoteProvider &provider =
+ g->GetOrCreate<repro::GDBRemoteProvider>();
+ m_gdb_client.SetPacketRecorder(provider.GetNewPacketRecorder());
}
+ m_gdb_client.Connect(url, &error);
if (error.Fail())
return error;
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
new file mode 100644
index 000000000000..339d33d25110
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
@@ -0,0 +1,218 @@
+//===-- ProcessFreeBSDKernel.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 "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Target/DynamicLoader.h"
+
+#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
+#include "ProcessFreeBSDKernel.h"
+#include "ThreadFreeBSDKernel.h"
+
+#if LLDB_ENABLE_FBSDVMCORE
+#include <fvc.h>
+#endif
+#if defined(__FreeBSD__)
+#include <kvm.h>
+#endif
+
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE(ProcessFreeBSDKernel)
+
+namespace {
+
+#if LLDB_ENABLE_FBSDVMCORE
+class ProcessFreeBSDKernelFVC : public ProcessFreeBSDKernel {
+public:
+ ProcessFreeBSDKernelFVC(lldb::TargetSP target_sp, lldb::ListenerSP listener,
+ fvc_t *fvc);
+
+ ~ProcessFreeBSDKernelFVC();
+
+ size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ lldb_private::Status &error) override;
+
+private:
+ fvc_t *m_fvc;
+
+ const char *GetError();
+};
+#endif // LLDB_ENABLE_FBSDVMCORE
+
+#if defined(__FreeBSD__)
+class ProcessFreeBSDKernelKVM : public ProcessFreeBSDKernel {
+public:
+ ProcessFreeBSDKernelKVM(lldb::TargetSP target_sp, lldb::ListenerSP listener,
+ kvm_t *fvc);
+
+ ~ProcessFreeBSDKernelKVM();
+
+ size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ lldb_private::Status &error) override;
+
+private:
+ kvm_t *m_kvm;
+
+ const char *GetError();
+};
+#endif // defined(__FreeBSD__)
+
+} // namespace
+
+ProcessFreeBSDKernel::ProcessFreeBSDKernel(lldb::TargetSP target_sp,
+ ListenerSP listener_sp)
+ : PostMortemProcess(target_sp, listener_sp) {}
+
+lldb::ProcessSP ProcessFreeBSDKernel::CreateInstance(lldb::TargetSP target_sp,
+ ListenerSP listener_sp,
+ const FileSpec *crash_file,
+ bool can_connect) {
+ ModuleSP executable = target_sp->GetExecutableModule();
+ if (crash_file && !can_connect && executable) {
+#if LLDB_ENABLE_FBSDVMCORE
+ fvc_t *fvc =
+ fvc_open(executable->GetFileSpec().GetPath().c_str(),
+ crash_file->GetPath().c_str(), nullptr, nullptr, nullptr);
+ if (fvc)
+ return std::make_shared<ProcessFreeBSDKernelFVC>(target_sp, listener_sp,
+ fvc);
+#endif
+
+#if defined(__FreeBSD__)
+ kvm_t *kvm =
+ kvm_open2(executable->GetFileSpec().GetPath().c_str(),
+ crash_file->GetPath().c_str(), O_RDONLY, nullptr, nullptr);
+ if (kvm)
+ return std::make_shared<ProcessFreeBSDKernelKVM>(target_sp, listener_sp,
+ kvm);
+#endif
+ }
+ return nullptr;
+}
+
+void ProcessFreeBSDKernel::Initialize() {
+ static llvm::once_flag g_once_flag;
+
+ llvm::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+ });
+}
+
+void ProcessFreeBSDKernel::Terminate() {
+ PluginManager::UnregisterPlugin(ProcessFreeBSDKernel::CreateInstance);
+}
+
+Status ProcessFreeBSDKernel::DoDestroy() { return Status(); }
+
+bool ProcessFreeBSDKernel::CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) {
+ return true;
+}
+
+void ProcessFreeBSDKernel::RefreshStateAfterStop() {}
+
+bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
+ if (old_thread_list.GetSize(false) == 0) {
+ // Make up the thread the first time this is called so we can set our one
+ // and only core thread state up.
+
+ // We cannot construct a thread without a register context as that crashes
+ // LLDB but we can construct a process without threads to provide minimal
+ // memory reading support.
+ switch (GetTarget().GetArchitecture().GetMachine()) {
+ case llvm::Triple::aarch64:
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ break;
+ default:
+ 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);
+ } else {
+ const uint32_t num_threads = old_thread_list.GetSize(false);
+ for (uint32_t i = 0; i < num_threads; ++i)
+ new_thread_list.AddThread(old_thread_list.GetThreadAtIndex(i, false));
+ }
+ return new_thread_list.GetSize(false) > 0;
+}
+
+Status ProcessFreeBSDKernel::DoLoadCore() {
+ // The core is already loaded by CreateInstance().
+ return Status();
+}
+
+DynamicLoader *ProcessFreeBSDKernel::GetDynamicLoader() {
+ if (m_dyld_up.get() == nullptr)
+ m_dyld_up.reset(DynamicLoader::FindPlugin(
+ this, DynamicLoaderStatic::GetPluginNameStatic()));
+ return m_dyld_up.get();
+}
+
+#if LLDB_ENABLE_FBSDVMCORE
+
+ProcessFreeBSDKernelFVC::ProcessFreeBSDKernelFVC(lldb::TargetSP target_sp,
+ ListenerSP listener_sp,
+ fvc_t *fvc)
+ : ProcessFreeBSDKernel(target_sp, listener_sp), m_fvc(fvc) {}
+
+ProcessFreeBSDKernelFVC::~ProcessFreeBSDKernelFVC() {
+ if (m_fvc)
+ fvc_close(m_fvc);
+}
+
+size_t ProcessFreeBSDKernelFVC::DoReadMemory(lldb::addr_t addr, void *buf,
+ size_t size, Status &error) {
+ ssize_t rd = 0;
+ rd = fvc_read(m_fvc, addr, buf, size);
+ if (rd < 0 || static_cast<size_t>(rd) != size) {
+ error.SetErrorStringWithFormat("Reading memory failed: %s", GetError());
+ return rd > 0 ? rd : 0;
+ }
+ return rd;
+}
+
+const char *ProcessFreeBSDKernelFVC::GetError() { return fvc_geterr(m_fvc); }
+
+#endif // LLDB_ENABLE_FBSDVMCORE
+
+#if defined(__FreeBSD__)
+
+ProcessFreeBSDKernelKVM::ProcessFreeBSDKernelKVM(lldb::TargetSP target_sp,
+ ListenerSP listener_sp,
+ kvm_t *fvc)
+ : ProcessFreeBSDKernel(target_sp, listener_sp), m_kvm(fvc) {}
+
+ProcessFreeBSDKernelKVM::~ProcessFreeBSDKernelKVM() {
+ if (m_kvm)
+ kvm_close(m_kvm);
+}
+
+size_t ProcessFreeBSDKernelKVM::DoReadMemory(lldb::addr_t addr, void *buf,
+ size_t size, Status &error) {
+ ssize_t rd = 0;
+ rd = kvm_read2(m_kvm, addr, buf, size);
+ if (rd < 0 || static_cast<size_t>(rd) != size) {
+ error.SetErrorStringWithFormat("Reading memory failed: %s", GetError());
+ return rd > 0 ? rd : 0;
+ }
+ return rd;
+}
+
+const char *ProcessFreeBSDKernelKVM::GetError() { return kvm_geterr(m_kvm); }
+
+#endif // defined(__FreeBSD__)
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
new file mode 100644
index 000000000000..558eec5403db
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
@@ -0,0 +1,51 @@
+//===-- ProcessFreeBSDKernel.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_FREEBSDKERNEL_PROCESSFREEBSDKERNEL_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_PROCESSFREEBSDKERNEL_H
+
+#include "lldb/Target/PostMortemProcess.h"
+
+class ProcessFreeBSDKernel : public lldb_private::PostMortemProcess {
+public:
+ ProcessFreeBSDKernel(lldb::TargetSP target_sp, lldb::ListenerSP listener);
+
+ static lldb::ProcessSP
+ CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener,
+ const lldb_private::FileSpec *crash_file_path,
+ bool can_connect);
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static llvm::StringRef GetPluginNameStatic() { return "freebsd-kernel"; }
+
+ static llvm::StringRef GetPluginDescriptionStatic() {
+ return "FreeBSD kernel vmcore debugging plug-in.";
+ }
+
+ llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+
+ lldb_private::Status DoDestroy() override;
+
+ bool CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) override;
+
+ void RefreshStateAfterStop() override;
+
+ lldb_private::Status DoLoadCore() override;
+
+ lldb_private::DynamicLoader *GetDynamicLoader() override;
+
+protected:
+ bool DoUpdateThreadList(lldb_private::ThreadList &old_thread_list,
+ lldb_private::ThreadList &new_thread_list) override;
+};
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_PROCESSFREEBSDKERNEL_H
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.cpp
new file mode 100644
index 000000000000..11843ddc82d9
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.cpp
@@ -0,0 +1,110 @@
+//===-- RegisterContextFreeBSDKernel_arm64.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 "RegisterContextFreeBSDKernel_arm64.h"
+#include "Plugins/Process/Utility/lldb-arm64-register-enums.h"
+
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "llvm/Support/Endian.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+RegisterContextFreeBSDKernel_arm64::RegisterContextFreeBSDKernel_arm64(
+ Thread &thread, std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up,
+ lldb::addr_t pcb_addr)
+ : RegisterContextPOSIX_arm64(thread, std::move(register_info_up)),
+ m_pcb_addr(pcb_addr) {}
+
+bool RegisterContextFreeBSDKernel_arm64::ReadGPR() { return true; }
+
+bool RegisterContextFreeBSDKernel_arm64::ReadFPR() { return true; }
+
+bool RegisterContextFreeBSDKernel_arm64::WriteGPR() {
+ assert(0);
+ return false;
+}
+
+bool RegisterContextFreeBSDKernel_arm64::WriteFPR() {
+ assert(0);
+ return false;
+}
+
+bool RegisterContextFreeBSDKernel_arm64::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ if (m_pcb_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ struct {
+ llvm::support::ulittle64_t x[30];
+ llvm::support::ulittle64_t lr;
+ llvm::support::ulittle64_t _reserved;
+ llvm::support::ulittle64_t sp;
+ } pcb;
+
+ Status error;
+ size_t rd =
+ m_thread.GetProcess()->ReadMemory(m_pcb_addr, &pcb, sizeof(pcb), error);
+ if (rd != sizeof(pcb))
+ return false;
+
+ uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ switch (reg) {
+ case gpr_x0_arm64:
+ case gpr_x1_arm64:
+ case gpr_x2_arm64:
+ case gpr_x3_arm64:
+ case gpr_x4_arm64:
+ case gpr_x5_arm64:
+ case gpr_x6_arm64:
+ case gpr_x7_arm64:
+ case gpr_x8_arm64:
+ case gpr_x9_arm64:
+ case gpr_x10_arm64:
+ case gpr_x11_arm64:
+ case gpr_x12_arm64:
+ case gpr_x13_arm64:
+ case gpr_x14_arm64:
+ case gpr_x15_arm64:
+ case gpr_x16_arm64:
+ case gpr_x17_arm64:
+ case gpr_x18_arm64:
+ case gpr_x19_arm64:
+ case gpr_x20_arm64:
+ case gpr_x21_arm64:
+ case gpr_x22_arm64:
+ case gpr_x23_arm64:
+ case gpr_x24_arm64:
+ case gpr_x25_arm64:
+ case gpr_x26_arm64:
+ case gpr_x27_arm64:
+ case gpr_x28_arm64:
+ case gpr_fp_arm64:
+ static_assert(gpr_fp_arm64 - gpr_x0_arm64 == 29,
+ "nonconsecutive arm64 register numbers");
+ value = pcb.x[reg - gpr_x0_arm64];
+ break;
+ case gpr_sp_arm64:
+ value = pcb.sp;
+ break;
+ case gpr_pc_arm64:
+ // The pc of crashing thread is stored in lr.
+ value = pcb.lr;
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+bool RegisterContextFreeBSDKernel_arm64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ return false;
+}
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.h b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.h
new file mode 100644
index 000000000000..155dda6e748f
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.h
@@ -0,0 +1,41 @@
+//===-- RegisterContextFreeBSDKernel_arm64.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_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_ARM64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_ARM64_H
+
+#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
+
+class RegisterContextFreeBSDKernel_arm64 : public RegisterContextPOSIX_arm64 {
+public:
+ RegisterContextFreeBSDKernel_arm64(
+ lldb_private::Thread &thread,
+ std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up,
+ lldb::addr_t pcb_addr);
+
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
+
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
+
+protected:
+ bool ReadGPR() override;
+
+ bool ReadFPR() override;
+
+ bool WriteGPR() override;
+
+ bool WriteFPR() override;
+
+private:
+ lldb::addr_t m_pcb_addr;
+};
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_ARM64_H
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.cpp
new file mode 100644
index 000000000000..fde85c9c9f0d
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.cpp
@@ -0,0 +1,83 @@
+//===-- RegisterContextFreeBSDKernel_i386.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 "RegisterContextFreeBSDKernel_i386.h"
+
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "llvm/Support/Endian.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+RegisterContextFreeBSDKernel_i386::RegisterContextFreeBSDKernel_i386(
+ Thread &thread, RegisterInfoInterface *register_info, lldb::addr_t pcb_addr)
+ : RegisterContextPOSIX_x86(thread, 0, register_info), m_pcb_addr(pcb_addr) {
+}
+
+bool RegisterContextFreeBSDKernel_i386::ReadGPR() { return true; }
+
+bool RegisterContextFreeBSDKernel_i386::ReadFPR() { return true; }
+
+bool RegisterContextFreeBSDKernel_i386::WriteGPR() {
+ assert(0);
+ return false;
+}
+
+bool RegisterContextFreeBSDKernel_i386::WriteFPR() {
+ assert(0);
+ return false;
+}
+
+bool RegisterContextFreeBSDKernel_i386::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ if (m_pcb_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ struct {
+ llvm::support::ulittle32_t edi;
+ llvm::support::ulittle32_t esi;
+ llvm::support::ulittle32_t ebp;
+ llvm::support::ulittle32_t esp;
+ llvm::support::ulittle32_t ebx;
+ llvm::support::ulittle32_t eip;
+ } pcb;
+
+ Status error;
+ size_t rd =
+ m_thread.GetProcess()->ReadMemory(m_pcb_addr, &pcb, sizeof(pcb), error);
+ if (rd != sizeof(pcb))
+ return false;
+
+ uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ switch (reg) {
+#define REG(x) \
+ case lldb_##x##_i386: \
+ value = pcb.x; \
+ break;
+
+ REG(edi);
+ REG(esi);
+ REG(ebp);
+ REG(esp);
+ REG(eip);
+
+#undef REG
+
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+bool RegisterContextFreeBSDKernel_i386::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ return false;
+}
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.h b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.h
new file mode 100644
index 000000000000..218e3374f8df
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.h
@@ -0,0 +1,41 @@
+//===-- RegisterContextFreeBSDKernel_i386.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_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_I386_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_I386_H
+
+#include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
+
+class RegisterContextFreeBSDKernel_i386 : public RegisterContextPOSIX_x86 {
+public:
+ RegisterContextFreeBSDKernel_i386(
+ lldb_private::Thread &thread,
+ lldb_private::RegisterInfoInterface *register_info,
+ lldb::addr_t pcb_addr);
+
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
+
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
+
+protected:
+ bool ReadGPR() override;
+
+ bool ReadFPR() override;
+
+ bool WriteGPR() override;
+
+ bool WriteFPR() override;
+
+private:
+ lldb::addr_t m_pcb_addr;
+};
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_I386_H
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.cpp
new file mode 100644
index 000000000000..ff57842e345c
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.cpp
@@ -0,0 +1,88 @@
+//===-- RegisterContextFreeBSDKernel_x86_64.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 "RegisterContextFreeBSDKernel_x86_64.h"
+
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "llvm/Support/Endian.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+RegisterContextFreeBSDKernel_x86_64::RegisterContextFreeBSDKernel_x86_64(
+ Thread &thread, RegisterInfoInterface *register_info, lldb::addr_t pcb_addr)
+ : RegisterContextPOSIX_x86(thread, 0, register_info), m_pcb_addr(pcb_addr) {
+}
+
+bool RegisterContextFreeBSDKernel_x86_64::ReadGPR() { return true; }
+
+bool RegisterContextFreeBSDKernel_x86_64::ReadFPR() { return true; }
+
+bool RegisterContextFreeBSDKernel_x86_64::WriteGPR() {
+ assert(0);
+ return false;
+}
+
+bool RegisterContextFreeBSDKernel_x86_64::WriteFPR() {
+ assert(0);
+ return false;
+}
+
+bool RegisterContextFreeBSDKernel_x86_64::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ if (m_pcb_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ struct {
+ llvm::support::ulittle64_t r15;
+ llvm::support::ulittle64_t r14;
+ llvm::support::ulittle64_t r13;
+ llvm::support::ulittle64_t r12;
+ llvm::support::ulittle64_t rbp;
+ llvm::support::ulittle64_t rsp;
+ llvm::support::ulittle64_t rbx;
+ llvm::support::ulittle64_t rip;
+ } pcb;
+
+ Status error;
+ size_t rd =
+ m_thread.GetProcess()->ReadMemory(m_pcb_addr, &pcb, sizeof(pcb), error);
+ if (rd != sizeof(pcb))
+ return false;
+
+ uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ switch (reg) {
+#define REG(x) \
+ case lldb_##x##_x86_64: \
+ value = pcb.x; \
+ break;
+
+ REG(r15);
+ REG(r14);
+ REG(r13);
+ REG(r12);
+ REG(rbp);
+ REG(rsp);
+ REG(rbx);
+ REG(rip);
+
+#undef REG
+
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+bool RegisterContextFreeBSDKernel_x86_64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ return false;
+}
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.h b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.h
new file mode 100644
index 000000000000..9a2ac638dfea
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.h
@@ -0,0 +1,41 @@
+//===-- RegisterContextFreeBSDKernel_x86_64.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_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_X86_64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_X86_64_H
+
+#include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
+
+class RegisterContextFreeBSDKernel_x86_64 : public RegisterContextPOSIX_x86 {
+public:
+ RegisterContextFreeBSDKernel_x86_64(
+ lldb_private::Thread &thread,
+ lldb_private::RegisterInfoInterface *register_info,
+ lldb::addr_t pcb_addr);
+
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
+
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
+
+protected:
+ bool ReadGPR() override;
+
+ bool ReadFPR() override;
+
+ bool WriteGPR() override;
+
+ bool WriteFPR() override;
+
+private:
+ lldb::addr_t m_pcb_addr;
+};
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_X86_64_H
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.cpp
new file mode 100644
index 000000000000..124c65d587ff
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.cpp
@@ -0,0 +1,85 @@
+//===-- ThreadFreeBSDKernel.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 "ThreadFreeBSDKernel.h"
+
+#include "lldb/Target/Unwind.h"
+#include "lldb/Utility/Log.h"
+
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
+#include "ProcessFreeBSDKernel.h"
+#include "RegisterContextFreeBSDKernel_arm64.h"
+#include "RegisterContextFreeBSDKernel_i386.h"
+#include "RegisterContextFreeBSDKernel_x86_64.h"
+#include "ThreadFreeBSDKernel.h"
+
+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) {}
+
+ThreadFreeBSDKernel::~ThreadFreeBSDKernel() {}
+
+void ThreadFreeBSDKernel::RefreshStateAfterStop() {}
+
+lldb::RegisterContextSP ThreadFreeBSDKernel::GetRegisterContext() {
+ if (!m_reg_context_sp)
+ m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
+ return m_reg_context_sp;
+}
+
+lldb::RegisterContextSP
+ThreadFreeBSDKernel::CreateRegisterContextForFrame(StackFrame *frame) {
+ RegisterContextSP reg_ctx_sp;
+ uint32_t concrete_frame_idx = 0;
+
+ if (frame)
+ concrete_frame_idx = frame->GetConcreteFrameIndex();
+
+ if (concrete_frame_idx == 0) {
+ if (m_thread_reg_ctx_sp)
+ return m_thread_reg_ctx_sp;
+
+ ProcessFreeBSDKernel *process =
+ static_cast<ProcessFreeBSDKernel *>(GetProcess().get());
+ ArchSpec arch = process->GetTarget().GetArchitecture();
+
+ switch (arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ m_thread_reg_ctx_sp =
+ std::make_shared<RegisterContextFreeBSDKernel_arm64>(
+ *this, std::make_unique<RegisterInfoPOSIX_arm64>(arch, 0),
+ 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);
+ break;
+ case llvm::Triple::x86_64:
+ m_thread_reg_ctx_sp =
+ std::make_shared<RegisterContextFreeBSDKernel_x86_64>(
+ *this, new RegisterContextFreeBSD_x86_64(arch), m_pcb_addr);
+ break;
+ default:
+ assert(false && "Unsupported architecture passed to ThreadFreeBSDKernel");
+ break;
+ }
+
+ reg_ctx_sp = m_thread_reg_ctx_sp;
+ } else {
+ reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame);
+ }
+ return reg_ctx_sp;
+}
+
+bool ThreadFreeBSDKernel::CalculateStopInfo() { return false; }
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.h b/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.h
new file mode 100644
index 000000000000..2842eba64e56
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.h
@@ -0,0 +1,36 @@
+//===-- ThreadFreeBSDKernel.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_FREEBSDKERNEL_THREADFREEBSDKERNEL_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_THREADFREEBSDKERNEL_H
+
+#include "lldb/Target/Thread.h"
+
+class ThreadFreeBSDKernel : public lldb_private::Thread {
+public:
+ ThreadFreeBSDKernel(lldb_private::Process &process, lldb::tid_t tid,
+ lldb::addr_t pcb_addr);
+
+ ~ThreadFreeBSDKernel() override;
+
+ void RefreshStateAfterStop() override;
+
+ lldb::RegisterContextSP GetRegisterContext() override;
+
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
+
+protected:
+ bool CalculateStopInfo() override;
+
+private:
+ lldb::RegisterContextSP m_thread_reg_ctx_sp;
+ lldb::addr_t m_pcb_addr;
+};
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_THREADFREEBSDKERNEL_H
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index b852a0164375..65dbc8ea95b3 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -64,6 +64,10 @@ lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp,
DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
lldb::offset_t data_offset = 0;
if (elf_header.Parse(data, &data_offset)) {
+ // Check whether we're dealing with a raw FreeBSD "full memory dump"
+ // ELF vmcore that needs to be handled via FreeBSDKernel plugin instead.
+ if (elf_header.e_ident[7] == 0xFF && elf_header.e_version == 0)
+ return process_sp;
if (elf_header.e_type == llvm::ELF::ET_CORE)
process_sp = std::make_shared<ProcessElfCore>(target_sp, listener_sp,
*crash_file);
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 07dfa5e04ee5..b5b105351de5 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -1006,6 +1006,23 @@ GDBRemoteCommunicationClient::GetProcessArchitecture() {
return m_process_arch;
}
+bool GDBRemoteCommunicationClient::GetProcessStandaloneBinary(
+ UUID &uuid, addr_t &value, bool &value_is_offset) {
+ if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
+ GetCurrentProcessInfo();
+
+ // Return true if we have a UUID or an address/offset of the
+ // main standalone / firmware binary being used.
+ if (!m_process_standalone_uuid.IsValid() &&
+ m_process_standalone_value == LLDB_INVALID_ADDRESS)
+ return false;
+
+ uuid = m_process_standalone_uuid;
+ value = m_process_standalone_value;
+ value_is_offset = m_process_standalone_value_is_offset;
+ return true;
+}
+
bool GDBRemoteCommunicationClient::GetGDBServerVersion() {
if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate) {
m_gdb_server_name.clear();
@@ -2147,6 +2164,25 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
} else if (name.equals("elf_abi")) {
elf_abi = std::string(value);
++num_keys_decoded;
+ } else if (name.equals("main-binary-uuid")) {
+ m_process_standalone_uuid.SetFromStringRef(value);
+ ++num_keys_decoded;
+ } else if (name.equals("main-binary-slide")) {
+ StringExtractor extractor(value);
+ m_process_standalone_value =
+ extractor.GetU64(LLDB_INVALID_ADDRESS, 16);
+ if (m_process_standalone_value != LLDB_INVALID_ADDRESS) {
+ m_process_standalone_value_is_offset = true;
+ ++num_keys_decoded;
+ }
+ } else if (name.equals("main-binary-address")) {
+ StringExtractor extractor(value);
+ m_process_standalone_value =
+ extractor.GetU64(LLDB_INVALID_ADDRESS, 16);
+ if (m_process_standalone_value != LLDB_INVALID_ADDRESS) {
+ m_process_standalone_value_is_offset = false;
+ ++num_keys_decoded;
+ }
}
}
if (num_keys_decoded > 0)
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 6765372ce124..c69c33bb1c15 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -217,6 +217,9 @@ public:
const ArchSpec &GetProcessArchitecture();
+ bool GetProcessStandaloneBinary(UUID &uuid, lldb::addr_t &value,
+ bool &value_is_offset);
+
void GetRemoteQSupported();
bool GetVContSupported(char flavor);
@@ -584,6 +587,9 @@ protected:
ArchSpec m_host_arch;
ArchSpec m_process_arch;
+ UUID m_process_standalone_uuid;
+ lldb::addr_t m_process_standalone_value = LLDB_INVALID_ADDRESS;
+ bool m_process_standalone_value_is_offset = false;
llvm::VersionTuple m_os_version;
llvm::VersionTuple m_maccatalyst_version;
std::string m_os_build;
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 3ade8c815feb..93fe36c0d9d6 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -526,18 +526,15 @@ Status ProcessGDBRemote::WillAttachToProcessWithName(const char *process_name,
Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- Status error(WillLaunchOrAttach());
+ Status error(WillLaunchOrAttach());
if (error.Fail())
return error;
- if (repro::Reproducer::Instance().IsReplaying())
- error = ConnectToReplayServer();
- else
- error = ConnectToDebugserver(remote_url);
-
+ error = ConnectToDebugserver(remote_url);
if (error.Fail())
return error;
+
StartAsyncThread();
lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
@@ -564,6 +561,94 @@ Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) {
}
}
+ // The remote stub may know about the "main binary" in
+ // the context of a firmware debug session, and can
+ // give us a UUID and an address/slide of where the
+ // binary is loaded in memory.
+ UUID standalone_uuid;
+ addr_t standalone_value;
+ bool standalone_value_is_offset;
+ if (m_gdb_comm.GetProcessStandaloneBinary(
+ standalone_uuid, standalone_value, standalone_value_is_offset)) {
+ ModuleSP module_sp;
+
+ if (standalone_uuid.IsValid()) {
+ ModuleSpec module_spec;
+ module_spec.GetUUID() = standalone_uuid;
+
+ // Look up UUID in global module cache before attempting
+ // a more expensive search.
+ Status error = ModuleList::GetSharedModule(module_spec, module_sp,
+ nullptr, nullptr, nullptr);
+
+ if (!module_sp) {
+ // Force a an external lookup, if that tool is available.
+ if (!module_spec.GetSymbolFileSpec())
+ Symbols::DownloadObjectAndSymbolFile(module_spec, true);
+
+ if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
+ module_sp = std::make_shared<Module>(module_spec);
+ }
+ }
+
+ // If we couldn't find the binary anywhere else, as a last resort,
+ // read it out of memory.
+ if (!module_sp.get() && standalone_value != LLDB_INVALID_ADDRESS &&
+ !standalone_value_is_offset) {
+ char namebuf[80];
+ snprintf(namebuf, sizeof(namebuf), "mem-image-0x%" PRIx64,
+ standalone_value);
+ module_sp =
+ ReadModuleFromMemory(FileSpec(namebuf), standalone_value);
+ }
+
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(
+ LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (module_sp.get()) {
+ target.GetImages().AppendIfNeeded(module_sp, false);
+
+ bool changed = false;
+ if (module_sp->GetObjectFile()) {
+ if (standalone_value != LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("Loading binary UUID %s at %s 0x%" PRIx64,
+ standalone_uuid.GetAsString().c_str(),
+ standalone_value_is_offset ? "offset" : "address",
+ standalone_value);
+ module_sp->SetLoadAddress(target, standalone_value,
+ standalone_value_is_offset, changed);
+ } else {
+ // No address/offset/slide, load the binary at file address,
+ // offset 0.
+ if (log)
+ log->Printf("Loading binary UUID %s at file address",
+ standalone_uuid.GetAsString().c_str());
+ const bool value_is_slide = true;
+ module_sp->SetLoadAddress(target, 0, value_is_slide, changed);
+ }
+ } else {
+ // In-memory image, load at its true address, offset 0.
+ if (log)
+ log->Printf("Loading binary UUID %s from memory",
+ standalone_uuid.GetAsString().c_str());
+ const bool value_is_slide = true;
+ module_sp->SetLoadAddress(target, 0, value_is_slide, changed);
+ }
+
+ ModuleList added_module;
+ added_module.Append(module_sp, false);
+ target.ModulesDidLoad(added_module);
+ } else {
+ if (log)
+ log->Printf("Unable to find binary with UUID %s and load it at "
+ "%s 0x%" PRIx64,
+ standalone_uuid.GetAsString().c_str(),
+ standalone_value_is_offset ? "offset" : "address",
+ standalone_value);
+ }
+ }
+ }
+
const StateType state = SetThreadStopInfo(response);
if (state != eStateInvalid) {
SetPrivateState(state);
@@ -3259,9 +3344,6 @@ ProcessGDBRemote::EstablishConnectionIfNeeded(const ProcessInfo &process_info) {
if (platform_sp && !platform_sp->IsHost())
return Status("Lost debug server connection");
- if (repro::Reproducer::Instance().IsReplaying())
- return ConnectToReplayServer();
-
auto error = LaunchAndConnectToDebugserver(process_info);
if (error.Fail()) {
const char *error_string = error.AsCString();
@@ -3540,7 +3622,7 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
// So it is safer to simply ignore any remaining packets by
// explicitly checking for eStateExited before reentering the
// fetch loop.
-
+
bool done = false;
while (!done && process->GetPrivateState() != eStateExited) {
LLDB_LOGF(log,
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
index c1b7294a7f58..cb21a3e7e65f 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
+++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
@@ -311,6 +311,11 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list,
return GetInterface().ErrorWithMessage<bool>(LLVM_PRETTY_FUNCTION,
error.AsCString(), error);
+ RegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext();
+ if (!reg_ctx_sp)
+ return GetInterface().ErrorWithMessage<bool>(
+ LLVM_PRETTY_FUNCTION, "Invalid Register Context", error);
+
new_thread_list.AddThread(thread_sp);
return new_thread_list.GetSize(false) > 0;
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
index 1adbd4e7799d..959b8c581885 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
+++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
@@ -198,13 +198,17 @@ std::shared_ptr<DynamicRegisterInfo> ScriptedThread::GetDynamicRegisterInfo() {
if (!m_register_info_sp) {
StructuredData::DictionarySP reg_info = GetInterface()->GetRegisterInfo();
+
+ Status error;
if (!reg_info)
- return nullptr;
+ return GetInterface()
+ ->ErrorWithMessage<std::shared_ptr<DynamicRegisterInfo>>(
+ LLVM_PRETTY_FUNCTION,
+ "Failed to get scripted thread registers info.", error,
+ LIBLLDB_LOG_THREAD);
m_register_info_sp = std::make_shared<DynamicRegisterInfo>(
*reg_info, m_scripted_process.GetTarget().GetArchitecture());
- assert(m_register_info_sp->GetNumRegisters() > 0);
- assert(m_register_info_sp->GetNumRegisterSets() > 0);
}
return m_register_info_sp;
diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp b/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
index e99b7b88379a..b82a2647e9a0 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "Lua.h"
+#include "SWIGLuaBridge.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Utility/FileSpec.h"
#include "llvm/Support/Error.h"
@@ -15,30 +16,6 @@
using namespace lldb_private;
using namespace lldb;
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
-
-// Disable warning C4190: 'LLDBSwigPythonBreakpointCallbackFunction' has
-// C-linkage specified, but returns UDT 'llvm::Expected<bool>' which is
-// incompatible with C
-#if _MSC_VER
-#pragma warning (push)
-#pragma warning (disable : 4190)
-#endif
-
-extern "C" llvm::Expected<bool> LLDBSwigLuaBreakpointCallbackFunction(
- lua_State *L, lldb::StackFrameSP stop_frame_sp,
- lldb::BreakpointLocationSP bp_loc_sp, StructuredDataImpl *extra_args_impl);
-
-extern "C" llvm::Expected<bool> LLDBSwigLuaWatchpointCallbackFunction(
- lua_State *L, lldb::StackFrameSP stop_frame_sp, lldb::WatchpointSP wp_sp);
-
-#if _MSC_VER
-#pragma warning (pop)
-#endif
-
-#pragma clang diagnostic pop
-
static int lldb_print(lua_State *L) {
int n = lua_gettop(L);
lua_getglobal(L, "io");
@@ -105,13 +82,7 @@ Lua::CallBreakpointCallback(void *baton, lldb::StackFrameSP stop_frame_sp,
lua_pushlightuserdata(m_lua_state, baton);
lua_gettable(m_lua_state, LUA_REGISTRYINDEX);
- auto *extra_args_impl = [&]() -> StructuredDataImpl * {
- if (extra_args_sp == nullptr)
- return nullptr;
- auto *extra_args_impl = new StructuredDataImpl();
- extra_args_impl->SetObjectSP(extra_args_sp);
- return extra_args_impl;
- }();
+ StructuredDataImpl extra_args_impl(std::move(extra_args_sp));
return LLDBSwigLuaBreakpointCallbackFunction(m_lua_state, stop_frame_sp,
bp_loc_sp, extra_args_impl);
}
diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/SWIGLuaBridge.h b/lldb/source/Plugins/ScriptInterpreter/Lua/SWIGLuaBridge.h
new file mode 100644
index 000000000000..5fca18f2dd6d
--- /dev/null
+++ b/lldb/source/Plugins/ScriptInterpreter/Lua/SWIGLuaBridge.h
@@ -0,0 +1,28 @@
+//===-- SWIGLuaBridge.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_PLUGINS_SCRIPTINTERPRETER_LUA_SWIGLUABRIDGE_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_LUA_SWIGLUABRIDGE_H
+
+#include "lldb/lldb-forward.h"
+#include "lua.hpp"
+#include "llvm/Support/Error.h"
+
+namespace lldb_private {
+
+llvm::Expected<bool> LLDBSwigLuaBreakpointCallbackFunction(
+ lua_State *L, lldb::StackFrameSP stop_frame_sp,
+ lldb::BreakpointLocationSP bp_loc_sp,
+ const StructuredDataImpl &extra_args_impl);
+
+llvm::Expected<bool> LLDBSwigLuaWatchpointCallbackFunction(
+ lua_State *L, lldb::StackFrameSP stop_frame_sp, lldb::WatchpointSP wp_sp);
+
+} // namespace lldb_private
+
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_LUA_SWIGLUABRIDGE_H
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
index c7af13598843..2bb69dc47731 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
@@ -57,20 +57,20 @@ void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data);
void *LLDBSwigPythonCreateScriptedProcess(const char *python_class_name,
const char *session_dictionary_name,
const lldb::TargetSP &target_sp,
- StructuredDataImpl *args_impl,
+ 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,
- StructuredDataImpl *args_impl,
+ const StructuredDataImpl &args_impl,
std::string &error_string);
llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction(
const char *python_function_name, const char *session_dictionary_name,
const lldb::StackFrameSP &sb_frame,
const lldb::BreakpointLocationSP &sb_bp_loc,
- lldb_private::StructuredDataImpl *args_impl);
+ const lldb_private::StructuredDataImpl &args_impl);
bool LLDBSwigPythonWatchpointCallbackFunction(
const char *python_function_name, const char *session_dictionary_name,
@@ -90,11 +90,11 @@ LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name,
void *LLDBSwigPythonCreateCommandObject(const char *python_class_name,
const char *session_dictionary_name,
- const lldb::DebuggerSP debugger_sp);
+ lldb::DebuggerSP debugger_sp);
void *LLDBSwigPythonCreateScriptedThreadPlan(
const char *python_class_name, const char *session_dictionary_name,
- lldb_private::StructuredDataImpl *args_data, std::string &error_string,
+ const StructuredDataImpl &args_data, std::string &error_string,
const lldb::ThreadPlanSP &thread_plan_sp);
bool LLDBSWIGPythonCallThreadPlan(void *implementor, const char *method_name,
@@ -103,16 +103,17 @@ bool LLDBSWIGPythonCallThreadPlan(void *implementor, const char *method_name,
void *LLDBSwigPythonCreateScriptedBreakpointResolver(
const char *python_class_name, const char *session_dictionary_name,
- lldb_private::StructuredDataImpl *args, const lldb::BreakpointSP &bkpt_sp);
+ const StructuredDataImpl &args, const lldb::BreakpointSP &bkpt_sp);
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, lldb_private::StructuredDataImpl *args,
- lldb_private::Status &error);
+void *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,
@@ -136,18 +137,18 @@ PyObject *LLDBSwigPython_GetValueSynthProviderInstance(PyObject *implementor);
bool LLDBSwigPythonCallCommand(const char *python_function_name,
const char *session_dictionary_name,
- lldb::DebuggerSP &debugger, const char *args,
+ lldb::DebuggerSP debugger, const char *args,
lldb_private::CommandReturnObject &cmd_retobj,
lldb::ExecutionContextRefSP exe_ctx_ref_sp);
bool LLDBSwigPythonCallCommandObject(
- PyObject *implementor, lldb::DebuggerSP &debugger, const char *args,
+ PyObject *implementor, lldb::DebuggerSP debugger, const char *args,
lldb_private::CommandReturnObject &cmd_retobj,
lldb::ExecutionContextRefSP exe_ctx_ref_sp);
bool LLDBSwigPythonCallModuleInit(const char *python_module_name,
const char *session_dictionary_name,
- lldb::DebuggerSP &debugger);
+ lldb::DebuggerSP debugger);
void *LLDBSWIGPythonCreateOSPlugin(const char *python_class_name,
const char *session_dictionary_name,
@@ -165,20 +166,20 @@ bool LLDBSWIGPythonRunScriptKeywordProcess(const char *python_function_name,
const lldb::ProcessSP &process,
std::string &output);
-bool LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name,
- const char *session_dictionary_name,
- lldb::ThreadSP &thread,
- std::string &output);
+llvm::Optional<std::string>
+LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name,
+ const char *session_dictionary_name,
+ lldb::ThreadSP thread);
bool LLDBSWIGPythonRunScriptKeywordTarget(const char *python_function_name,
const char *session_dictionary_name,
const lldb::TargetSP &target,
std::string &output);
-bool LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name,
- const char *session_dictionary_name,
- lldb::StackFrameSP &frame,
- std::string &output);
+llvm::Optional<std::string>
+LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name,
+ const char *session_dictionary_name,
+ lldb::StackFrameSP frame);
bool LLDBSWIGPythonRunScriptKeywordValue(const char *python_function_name,
const char *session_dictionary_name,
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 5f282d74e364..6afa4742698b 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -1718,7 +1718,7 @@ StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_CreateThread(
}
StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan(
- const char *class_name, StructuredDataImpl *args_data,
+ const char *class_name, const StructuredDataImpl &args_data,
std::string &error_str, lldb::ThreadPlanSP thread_plan_sp) {
if (class_name == nullptr || class_name[0] == '\0')
return StructuredData::ObjectSP();
@@ -1820,7 +1820,7 @@ lldb::StateType ScriptInterpreterPythonImpl::ScriptedThreadPlanGetRunState(
StructuredData::GenericSP
ScriptInterpreterPythonImpl::CreateScriptedBreakpointResolver(
- const char *class_name, StructuredDataImpl *args_data,
+ const char *class_name, const StructuredDataImpl &args_data,
lldb::BreakpointSP &bkpt_sp) {
if (class_name == nullptr || class_name[0] == '\0')
@@ -1890,8 +1890,8 @@ ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchDepth(
}
StructuredData::GenericSP ScriptInterpreterPythonImpl::CreateScriptedStopHook(
- TargetSP target_sp, const char *class_name, StructuredDataImpl *args_data,
- Status &error) {
+ TargetSP target_sp, const char *class_name,
+ const StructuredDataImpl &args_data, Status &error) {
if (!target_sp) {
error.SetErrorString("No target for scripted stop-hook.");
@@ -2197,7 +2197,7 @@ bool ScriptInterpreterPythonImpl::BreakpointCallbackFunction(
LLDBSwigPythonBreakpointCallbackFunction(
python_function_name,
python_interpreter->m_dictionary_name.c_str(), stop_frame_sp,
- bp_loc_sp, bp_option_data->m_extra_args_up.get());
+ bp_loc_sp, bp_option_data->m_extra_args);
if (!maybe_ret_val) {
@@ -2521,7 +2521,6 @@ bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
const char *impl_function, Thread *thread, std::string &output,
Status &error) {
- bool ret_val;
if (!thread) {
error.SetErrorString("no thread");
return false;
@@ -2531,16 +2530,16 @@ bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
return false;
}
- {
- ThreadSP thread_sp(thread->shared_from_this());
- Locker py_lock(this,
- Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = LLDBSWIGPythonRunScriptKeywordThread(
- impl_function, m_dictionary_name.c_str(), thread_sp, output);
- if (!ret_val)
- error.SetErrorString("python script evaluation failed");
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ if (llvm::Optional<std::string> result = LLDBSWIGPythonRunScriptKeywordThread(
+ impl_function, m_dictionary_name.c_str(),
+ thread->shared_from_this())) {
+ output = std::move(*result);
+ return true;
}
- return ret_val;
+ error.SetErrorString("python script evaluation failed");
+ return false;
}
bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
@@ -2571,7 +2570,6 @@ bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
const char *impl_function, StackFrame *frame, std::string &output,
Status &error) {
- bool ret_val;
if (!frame) {
error.SetErrorString("no frame");
return false;
@@ -2581,16 +2579,16 @@ bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
return false;
}
- {
- StackFrameSP frame_sp(frame->shared_from_this());
- Locker py_lock(this,
- Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = LLDBSWIGPythonRunScriptKeywordFrame(
- impl_function, m_dictionary_name.c_str(), frame_sp, output);
- if (!ret_val)
- error.SetErrorString("python script evaluation failed");
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ if (llvm::Optional<std::string> result = LLDBSWIGPythonRunScriptKeywordFrame(
+ impl_function, m_dictionary_name.c_str(),
+ frame->shared_from_this())) {
+ output = std::move(*result);
+ return true;
}
- return ret_val;
+ error.SetErrorString("python script evaluation failed");
+ return false;
}
bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
@@ -2655,7 +2653,6 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule(
}
ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
- lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this();
// Before executing Python code, lock the GIL.
Locker py_lock(this,
@@ -2792,7 +2789,8 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule(
// if we are here, everything worked
// call __lldb_init_module(debugger,dict)
if (!LLDBSwigPythonCallModuleInit(module_name.c_str(),
- m_dictionary_name.c_str(), debugger_sp)) {
+ m_dictionary_name.c_str(),
+ m_debugger.shared_from_this())) {
error.SetErrorString("calling __lldb_init_module failed");
return false;
}
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
index 8cfc24e71283..2e8301a85eb6 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
@@ -33,13 +33,12 @@ public:
CommandDataPython() : BreakpointOptions::CommandData() {
interpreter = lldb::eScriptLanguagePython;
}
- CommandDataPython(StructuredData::ObjectSP extra_args_sp) :
- BreakpointOptions::CommandData(),
- m_extra_args_up(new StructuredDataImpl()) {
- interpreter = lldb::eScriptLanguagePython;
- m_extra_args_up->SetObjectSP(extra_args_sp);
+ CommandDataPython(StructuredData::ObjectSP extra_args_sp)
+ : BreakpointOptions::CommandData(),
+ m_extra_args(std::move(extra_args_sp)) {
+ interpreter = lldb::eScriptLanguagePython;
}
- lldb::StructuredDataImplUP m_extra_args_up;
+ StructuredDataImpl m_extra_args;
};
ScriptInterpreterPython(Debugger &debugger)
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
index a3f83b696ed4..defc2acffcfa 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -79,7 +79,7 @@ public:
StructuredData::ObjectSP
CreateScriptedThreadPlan(const char *class_name,
- StructuredDataImpl *args_data,
+ const StructuredDataImpl &args_data,
std::string &error_str,
lldb::ThreadPlanSP thread_plan) override;
@@ -99,7 +99,7 @@ public:
StructuredData::GenericSP
CreateScriptedBreakpointResolver(const char *class_name,
- StructuredDataImpl *args_data,
+ const StructuredDataImpl &args_data,
lldb::BreakpointSP &bkpt_sp) override;
bool ScriptedBreakpointResolverSearchCallback(
StructuredData::GenericSP implementor_sp,
@@ -110,7 +110,8 @@ public:
StructuredData::GenericSP
CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name,
- StructuredDataImpl *args_data, Status &error) override;
+ const StructuredDataImpl &args_data,
+ Status &error) override;
bool ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp,
ExecutionContext &exc_ctx,
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
index 29680dab5a14..e3c1931a565a 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
@@ -37,11 +37,7 @@ StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject(
return {};
TargetSP target_sp = exe_ctx.GetTargetSP();
- StructuredDataImpl *args_impl = nullptr;
- if (args_sp) {
- args_impl = new StructuredDataImpl();
- args_impl->SetObjectSP(args_sp);
- }
+ StructuredDataImpl args_impl(args_sp);
std::string error_string;
Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
index d2c28bc426ee..6a881bfe625c 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
@@ -37,11 +37,7 @@ StructuredData::GenericSP ScriptedThreadPythonInterface::CreatePluginObject(
return {};
ProcessSP process_sp = exe_ctx.GetProcessSP();
- StructuredDataImpl *args_impl = nullptr;
- if (args_sp) {
- args_impl = new StructuredDataImpl();
- args_impl->SetObjectSP(args_sp);
- }
+ StructuredDataImpl args_impl(args_sp);
std::string error_string;
Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 4ac6e165dda3..b90f104c4d21 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -1530,7 +1530,6 @@ TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType(
return type_sp;
SymbolFileDWARF *dwarf = die.GetDWARF();
- TypeList &type_list = dwarf->GetTypeList();
DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
dw_tag_t sc_parent_tag = sc_parent_die.Tag();
@@ -1550,10 +1549,6 @@ TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType(
if (symbol_context_scope != nullptr)
type_sp->SetSymbolContextScope(symbol_context_scope);
- // We are ready to put this type into the uniqued list up at the module
- // level.
- type_list.Insert(type_sp);
-
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
return type_sp;
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index cece29dcf9ac..71d4c1e6c52f 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -153,7 +153,7 @@ public:
const DWARFAbbreviationDeclarationSet *GetAbbreviations() const;
dw_offset_t GetAbbrevOffset() const;
uint8_t GetAddressByteSize() const { return m_header.GetAddressByteSize(); }
- dw_addr_t GetAddrBase() const { return m_addr_base ? *m_addr_base : 0; }
+ dw_addr_t GetAddrBase() const { return m_addr_base.getValueOr(0); }
dw_addr_t GetBaseAddress() const { return m_base_addr; }
dw_offset_t GetLineTableOffset();
dw_addr_t GetRangesBase() const { return m_ranges_base; }
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 8c20244a6c44..8c995ef2eb2a 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1097,7 +1097,8 @@ bool SymbolFileDWARF::ParseImportedModules(
if (const char *include_path = module_die.GetAttributeValueAsString(
DW_AT_LLVM_include_path, nullptr)) {
FileSpec include_spec(include_path, dwarf_cu->GetPathStyle());
- MakeAbsoluteAndRemap(include_spec, *dwarf_cu, m_objfile_sp->GetModule());
+ MakeAbsoluteAndRemap(include_spec, *dwarf_cu,
+ m_objfile_sp->GetModule());
module.search_path = ConstString(include_spec.GetPath());
}
if (const char *sysroot = dwarf_cu->DIE().GetAttributeValueAsString(
@@ -1924,7 +1925,7 @@ void SymbolFileDWARF::ResolveFunctionAndBlock(lldb::addr_t file_vm_addr,
block_die = function_die.LookupDeepestBlock(file_vm_addr);
}
- if (!sc.function || ! lookup_block)
+ if (!sc.function || !lookup_block)
return;
Block &block = sc.function->GetBlock(true);
@@ -2319,7 +2320,8 @@ void SymbolFileDWARF::FindFunctions(ConstString name,
if (log) {
GetObjectFile()->GetModule()->LogMessage(
log,
- "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, sc_list)",
+ "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, "
+ "sc_list)",
name.GetCString(), name_type_mask);
}
@@ -2352,8 +2354,7 @@ void SymbolFileDWARF::FindFunctions(ConstString name,
log,
"SymbolFileDWARF::FindFunctions (name=\"%s\", "
"name_type_mask=0x%x, include_inlines=%d, sc_list) => %u",
- name.GetCString(), name_type_mask, include_inlines,
- num_matches);
+ name.GetCString(), name_type_mask, include_inlines, num_matches);
}
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 271ce7be1eea..e81ce28cb86e 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -253,8 +253,8 @@ public:
ExternalTypeModuleMap;
/// Return the list of Clang modules imported by this SymbolFile.
- const ExternalTypeModuleMap& getExternalTypeModules() const {
- return m_external_type_modules;
+ const ExternalTypeModuleMap &getExternalTypeModules() const {
+ return m_external_type_modules;
}
virtual DWARFDIE GetDIE(const DIERef &die_ref);
@@ -328,7 +328,6 @@ public:
return m_parse_time;
}
-
protected:
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *>
DIEToTypePtr;
@@ -428,9 +427,10 @@ protected:
virtual lldb::TypeSP
FindDefinitionTypeForDWARFDeclContext(const DWARFDeclContext &die_decl_ctx);
- virtual lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
- const DWARFDIE &die, lldb_private::ConstString type_name,
- bool must_be_implementation);
+ virtual lldb::TypeSP
+ FindCompleteObjCDefinitionTypeForDIE(const DWARFDIE &die,
+ lldb_private::ConstString type_name,
+ bool must_be_implementation);
lldb_private::Symbol *
GetObjCClassSymbol(lldb_private::ConstString objc_class_name);
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index c29fc2230a67..9473befa6cc3 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -30,6 +30,70 @@ using namespace lldb_private::npdb;
using namespace llvm::codeview;
using namespace llvm::pdb;
+namespace {
+struct CreateMethodDecl : public TypeVisitorCallbacks {
+ CreateMethodDecl(PdbIndex &m_index, TypeSystemClang &m_clang,
+ TypeIndex func_type_index,
+ clang::FunctionDecl *&function_decl,
+ lldb::opaque_compiler_type_t parent_ty,
+ llvm::StringRef proc_name, CompilerType func_ct)
+ : m_index(m_index), m_clang(m_clang), func_type_index(func_type_index),
+ function_decl(function_decl), parent_ty(parent_ty),
+ proc_name(proc_name), func_ct(func_ct) {}
+ PdbIndex &m_index;
+ TypeSystemClang &m_clang;
+ TypeIndex func_type_index;
+ clang::FunctionDecl *&function_decl;
+ lldb::opaque_compiler_type_t parent_ty;
+ llvm::StringRef proc_name;
+ CompilerType func_ct;
+
+ llvm::Error visitKnownMember(CVMemberRecord &cvr,
+ OverloadedMethodRecord &overloaded) override {
+ TypeIndex method_list_idx = overloaded.MethodList;
+
+ CVType method_list_type = m_index.tpi().getType(method_list_idx);
+ assert(method_list_type.kind() == LF_METHODLIST);
+
+ MethodOverloadListRecord method_list;
+ llvm::cantFail(TypeDeserializer::deserializeAs<MethodOverloadListRecord>(
+ method_list_type, method_list));
+
+ for (const OneMethodRecord &method : method_list.Methods) {
+ if (method.getType().getIndex() == func_type_index.getIndex())
+ AddMethod(overloaded.Name, method.getAccess(), method.getOptions(),
+ method.Attrs);
+ }
+
+ return llvm::Error::success();
+ }
+
+ llvm::Error visitKnownMember(CVMemberRecord &cvr,
+ OneMethodRecord &record) override {
+ AddMethod(record.getName(), record.getAccess(), record.getOptions(),
+ record.Attrs);
+ return llvm::Error::success();
+ }
+
+ void AddMethod(llvm::StringRef name, MemberAccess access,
+ MethodOptions options, MemberAttributes attrs) {
+ if (name != proc_name || function_decl)
+ return;
+ lldb::AccessType access_type = TranslateMemberAccess(access);
+ bool is_virtual = attrs.isVirtual();
+ bool is_static = attrs.isStatic();
+ bool is_artificial = (options & MethodOptions::CompilerGenerated) ==
+ MethodOptions::CompilerGenerated;
+ function_decl = m_clang.AddMethodToCXXRecordType(
+ parent_ty, proc_name,
+ /*mangled_name=*/nullptr, func_ct, /*access=*/access_type,
+ /*is_virtual=*/is_virtual, /*is_static=*/is_static,
+ /*is_inline=*/false, /*is_explicit=*/false,
+ /*is_attr_used=*/false, /*is_artificial=*/is_artificial);
+ }
+};
+} // namespace
+
static llvm::Optional<PdbCompilandSymId> FindSymbolScope(PdbIndex &index,
PdbCompilandSymId id) {
CVSymbol sym = index.ReadSymbolRecord(id);
@@ -681,7 +745,8 @@ bool PdbAstBuilder::CompleteTagDecl(clang::TagDecl &tag) {
// Visit all members of this class, then perform any finalization necessary
// to complete the class.
CompilerType ct = ToCompilerType(tag_qt);
- UdtRecordCompleter completer(best_ti, ct, tag, *this, m_index);
+ UdtRecordCompleter completer(best_ti, ct, tag, *this, m_index,
+ m_cxx_record_map);
auto error =
llvm::codeview::visitMemberRecordStream(field_list_cvt.data(), completer);
completer.complete();
@@ -1014,8 +1079,62 @@ PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) {
proc_name.consume_front(context_name);
proc_name.consume_front("::");
- clang::FunctionDecl *function_decl = m_clang.CreateFunctionDeclaration(
- parent, OptionalClangModuleID(), proc_name, func_ct, storage, false);
+ clang::FunctionDecl *function_decl = nullptr;
+ if (parent->isRecord()) {
+ clang::QualType parent_qt = llvm::dyn_cast<clang::TypeDecl>(parent)
+ ->getTypeForDecl()
+ ->getCanonicalTypeInternal();
+ lldb::opaque_compiler_type_t parent_opaque_ty =
+ ToCompilerType(parent_qt).GetOpaqueQualType();
+
+ auto iter = m_cxx_record_map.find(parent_opaque_ty);
+ if (iter != m_cxx_record_map.end()) {
+ if (iter->getSecond().contains({proc_name, func_ct})) {
+ return nullptr;
+ }
+ }
+
+ CVType cvt = m_index.tpi().getType(type_id.index);
+ MemberFunctionRecord func_record(static_cast<TypeRecordKind>(cvt.kind()));
+ llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>(
+ cvt, func_record));
+ TypeIndex class_index = func_record.getClassType();
+ CVType parent_cvt = m_index.tpi().getType(class_index);
+ ClassRecord class_record = CVTagRecord::create(parent_cvt).asClass();
+ // If it's a forward reference, try to get the real TypeIndex.
+ if (class_record.isForwardRef()) {
+ llvm::Expected<TypeIndex> eti =
+ m_index.tpi().findFullDeclForForwardRef(class_index);
+ if (eti) {
+ class_record =
+ CVTagRecord::create(m_index.tpi().getType(*eti)).asClass();
+ }
+ }
+ if (!class_record.FieldList.isSimple()) {
+ CVType field_list = m_index.tpi().getType(class_record.FieldList);
+ CreateMethodDecl process(m_index, m_clang, type_id.index, function_decl,
+ parent_opaque_ty, proc_name, func_ct);
+ if (llvm::Error err = visitMemberRecordStream(field_list.data(), process))
+ llvm::consumeError(std::move(err));
+ }
+
+ if (!function_decl) {
+ function_decl = m_clang.AddMethodToCXXRecordType(
+ parent_opaque_ty, proc_name,
+ /*mangled_name=*/nullptr, func_ct,
+ /*access=*/lldb::AccessType::eAccessPublic,
+ /*is_virtual=*/false, /*is_static=*/false,
+ /*is_inline=*/false, /*is_explicit=*/false,
+ /*is_attr_used=*/false, /*is_artificial=*/false);
+ }
+
+ m_cxx_record_map[parent_opaque_ty].insert({proc_name, func_ct});
+ } else {
+ function_decl = m_clang.CreateFunctionDeclaration(
+ parent, OptionalClangModuleID(), proc_name, func_ct, storage, false);
+ CreateFunctionParameters(func_id, *function_decl,
+ func_type->getNumParams());
+ }
lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0);
m_uid_to_decl[toOpaqueUid(func_id)] = function_decl;
@@ -1024,8 +1143,6 @@ PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) {
status.uid = toOpaqueUid(func_id);
m_decl_to_status.insert({function_decl, status});
- CreateFunctionParameters(func_id, *function_decl, func_type->getNumParams());
-
return function_decl;
}
@@ -1163,15 +1280,15 @@ clang::QualType PdbAstBuilder::CreateFunctionType(
}
static bool isTagDecl(clang::DeclContext &context) {
- return !!llvm::dyn_cast<clang::TagDecl>(&context);
+ return llvm::isa<clang::TagDecl>(&context);
}
static bool isFunctionDecl(clang::DeclContext &context) {
- return !!llvm::dyn_cast<clang::FunctionDecl>(&context);
+ return llvm::isa<clang::FunctionDecl>(&context);
}
static bool isBlockDecl(clang::DeclContext &context) {
- return !!llvm::dyn_cast<clang::BlockDecl>(&context);
+ return llvm::isa<clang::BlockDecl>(&context);
}
void PdbAstBuilder::ParseAllNamespacesPlusChildrenOf(
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
index 7bb2584d19a3..73accf5e5e68 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
@@ -137,6 +137,12 @@ private:
llvm::DenseMap<clang::Decl *, DeclStatus> m_decl_to_status;
llvm::DenseMap<lldb::user_id_t, clang::Decl *> m_uid_to_decl;
llvm::DenseMap<lldb::user_id_t, clang::QualType> m_uid_to_type;
+
+ // From class/struct's opaque_compiler_type_t to a set containing the pairs of
+ // method's name and CompilerType.
+ llvm::DenseMap<lldb::opaque_compiler_type_t,
+ llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>, 8>>
+ m_cxx_record_map;
};
} // namespace npdb
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index bf101ac1acf1..e859b1d5a86c 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -900,7 +900,7 @@ lldb::LanguageType SymbolFileNativePDB::ParseLanguage(CompileUnit &comp_unit) {
return TranslateLanguage(item->m_compile_opts->getLanguage());
}
-void SymbolFileNativePDB::AddSymbols(Symtab &symtab) { return; }
+void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {}
size_t SymbolFileNativePDB::ParseFunctions(CompileUnit &comp_unit) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
index c8fb46c75034..d0b27bc5bf79 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
@@ -28,13 +28,15 @@ using namespace lldb_private::npdb;
using Error = llvm::Error;
-UdtRecordCompleter::UdtRecordCompleter(PdbTypeSymId id,
- CompilerType &derived_ct,
- clang::TagDecl &tag_decl,
- PdbAstBuilder &ast_builder,
- PdbIndex &index)
+UdtRecordCompleter::UdtRecordCompleter(
+ PdbTypeSymId id, CompilerType &derived_ct, clang::TagDecl &tag_decl,
+ PdbAstBuilder &ast_builder, PdbIndex &index,
+ llvm::DenseMap<lldb::opaque_compiler_type_t,
+ llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>, 8>>
+ &cxx_record_map)
: m_id(id), m_derived_ct(derived_ct), m_tag_decl(tag_decl),
- m_ast_builder(ast_builder), m_index(index) {
+ m_ast_builder(ast_builder), m_index(index),
+ m_cxx_record_map(cxx_record_map) {
CVType cvt = m_index.tpi().getType(m_id.index);
switch (cvt.kind()) {
case LF_ENUM:
@@ -78,14 +80,24 @@ void UdtRecordCompleter::AddMethod(llvm::StringRef name, TypeIndex type_idx,
clang::QualType method_qt =
m_ast_builder.GetOrCreateType(PdbTypeSymId(type_idx));
m_ast_builder.CompleteType(method_qt);
+ CompilerType method_ct = m_ast_builder.ToCompilerType(method_qt);
+ lldb::opaque_compiler_type_t derived_opaque_ty = m_derived_ct.GetOpaqueQualType();
+ auto iter = m_cxx_record_map.find(derived_opaque_ty);
+ if (iter != m_cxx_record_map.end()) {
+ if (iter->getSecond().contains({name, method_ct})) {
+ return;
+ }
+ }
lldb::AccessType access_type = TranslateMemberAccess(access);
bool is_artificial = (options & MethodOptions::CompilerGenerated) ==
MethodOptions::CompilerGenerated;
m_ast_builder.clang().AddMethodToCXXRecordType(
- m_derived_ct.GetOpaqueQualType(), name.data(), nullptr,
- m_ast_builder.ToCompilerType(method_qt), access_type, attrs.isVirtual(),
- attrs.isStatic(), false, false, false, is_artificial);
+ derived_opaque_ty, name.data(), nullptr, method_ct,
+ access_type, attrs.isVirtual(), attrs.isStatic(), false, false, false,
+ is_artificial);
+
+ m_cxx_record_map[derived_opaque_ty].insert({name, method_ct});
}
Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
index ae7e47c82fe5..9c6b5ed28bc2 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
@@ -54,11 +54,17 @@ class UdtRecordCompleter : public llvm::codeview::TypeVisitorCallbacks {
PdbIndex &m_index;
std::vector<IndexedBase> m_bases;
ClangASTImporter::LayoutInfo m_layout;
+ llvm::DenseMap<lldb::opaque_compiler_type_t,
+ llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>, 8>>
+ &m_cxx_record_map;
public:
- UdtRecordCompleter(PdbTypeSymId id, CompilerType &derived_ct,
- clang::TagDecl &tag_decl, PdbAstBuilder &ast_builder,
- PdbIndex &index);
+ UdtRecordCompleter(
+ PdbTypeSymId id, CompilerType &derived_ct, clang::TagDecl &tag_decl,
+ PdbAstBuilder &ast_builder, PdbIndex &index,
+ llvm::DenseMap<lldb::opaque_compiler_type_t,
+ llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>,
+ 8>> &cxx_record_map);
#define MEMBER_RECORD(EnumName, EnumVal, Name) \
llvm::Error visitKnownMember(llvm::codeview::CVMemberRecord &CVR, \
diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index db0ae241be7e..a40b6ec9a635 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -239,7 +239,6 @@ void SymbolFilePDB::GetCompileUnitIndex(
}
}
index = UINT32_MAX;
- return;
}
std::unique_ptr<llvm::pdb::PDBSymbolCompiland>
@@ -402,7 +401,7 @@ static size_t ParseFunctionBlocksForPDBSymbol(
block = parent_block;
else
break;
- } else if (llvm::dyn_cast<PDBSymbolBlock>(pdb_symbol)) {
+ } else if (llvm::isa<PDBSymbolBlock>(pdb_symbol)) {
auto uid = pdb_symbol->getSymIndexId();
if (parent_block->FindBlockByID(uid))
break;
diff --git a/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp b/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp
index 919cdf46a5c0..a72e46a0b703 100644
--- a/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp
+++ b/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp
@@ -73,8 +73,7 @@ bool CommandObjectThreadTraceExportCTF::DoExecute(Args &command,
if (thread == nullptr) {
const uint32_t num_threads = process->GetThreadList().GetSize();
- size_t tid = m_options.m_thread_index ? *m_options.m_thread_index
- : LLDB_INVALID_THREAD_ID;
+ size_t tid = m_options.m_thread_index.getValueOr(LLDB_INVALID_THREAD_ID);
result.AppendErrorWithFormatv(
"Thread index {0} is out of range (valid values are 1 - {1}).\n", tid,
num_threads);
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index b1dbc382ff04..88c3aedb4c6b 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -2581,6 +2581,7 @@ RemoveWrappingTypes(QualType type, ArrayRef<clang::Type::TypeClass> mask = {}) {
case clang::Type::Typedef:
case clang::Type::TypeOf:
case clang::Type::TypeOfExpr:
+ case clang::Type::Using:
type = type->getLocallyUnqualifiedSingleStepDesugaredType();
break;
default:
@@ -4063,6 +4064,7 @@ TypeSystemClang::GetTypeClass(lldb::opaque_compiler_type_t type) {
case clang::Type::Paren:
case clang::Type::TypeOf:
case clang::Type::TypeOfExpr:
+ case clang::Type::Using:
llvm_unreachable("Handled in RemoveWrappingTypes!");
case clang::Type::UnaryTransform:
break;
@@ -4088,8 +4090,8 @@ TypeSystemClang::GetTypeClass(lldb::opaque_compiler_type_t type) {
return lldb::eTypeClassVector;
case clang::Type::Builtin:
// Ext-Int is just an integer type.
- case clang::Type::ExtInt:
- case clang::Type::DependentExtInt:
+ case clang::Type::BitInt:
+ case clang::Type::DependentBitInt:
return lldb::eTypeClassBuiltin;
case clang::Type::ObjCObjectPointer:
return lldb::eTypeClassObjCObjectPointer;
@@ -4722,6 +4724,7 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type,
case clang::Type::Typedef:
case clang::Type::TypeOf:
case clang::Type::TypeOfExpr:
+ case clang::Type::Using:
llvm_unreachable("Handled in RemoveWrappingTypes!");
case clang::Type::UnaryTransform:
@@ -4744,8 +4747,8 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type,
// TODO: Set this to more than one???
break;
- case clang::Type::ExtInt:
- case clang::Type::DependentExtInt:
+ case clang::Type::BitInt:
+ case clang::Type::DependentBitInt:
return qual_type->isUnsignedIntegerType() ? lldb::eEncodingUint
: lldb::eEncodingSint;
@@ -5104,6 +5107,7 @@ lldb::Format TypeSystemClang::GetFormat(lldb::opaque_compiler_type_t type) {
case clang::Type::Typedef:
case clang::Type::TypeOf:
case clang::Type::TypeOfExpr:
+ case clang::Type::Using:
llvm_unreachable("Handled in RemoveWrappingTypes!");
case clang::Type::UnaryTransform:
break;
@@ -5124,8 +5128,8 @@ lldb::Format TypeSystemClang::GetFormat(lldb::opaque_compiler_type_t type) {
case clang::Type::Vector:
break;
- case clang::Type::ExtInt:
- case clang::Type::DependentExtInt:
+ case clang::Type::BitInt:
+ case clang::Type::DependentBitInt:
return qual_type->isUnsignedIntegerType() ? lldb::eFormatUnsigned
: lldb::eFormatDecimal;
@@ -5145,6 +5149,8 @@ lldb::Format TypeSystemClang::GetFormat(lldb::opaque_compiler_type_t type) {
case clang::BuiltinType::UChar:
case clang::BuiltinType::WChar_U:
return lldb::eFormatChar;
+ case clang::BuiltinType::Char8:
+ return lldb::eFormatUnicode8;
case clang::BuiltinType::Char16:
return lldb::eFormatUnicode16;
case clang::BuiltinType::Char32:
@@ -8953,6 +8959,7 @@ bool TypeSystemClang::DumpTypeValue(
case eFormatCharPrintable:
case eFormatCharArray:
case eFormatBytes:
+ case eFormatUnicode8:
case eFormatBytesWithASCII:
item_count = byte_size;
byte_size = 1;