aboutsummaryrefslogtreecommitdiff
path: root/lldb
diff options
context:
space:
mode:
Diffstat (limited to 'lldb')
-rw-r--r--lldb/bindings/python/python-wrapper.swig84
-rw-r--r--lldb/docs/resources/lldbgdbremote.md67
-rw-r--r--lldb/include/lldb/API/SBSymbolContext.h2
-rw-r--r--lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h4
-rw-r--r--lldb/include/lldb/Core/ModuleList.h6
-rw-r--r--lldb/include/lldb/Expression/DWARFExpression.h12
-rw-r--r--lldb/include/lldb/Interpreter/Interfaces/ScriptedBreakpointInterface.h32
-rw-r--r--lldb/include/lldb/Interpreter/ScriptInterpreter.h30
-rw-r--r--lldb/include/lldb/lldb-forward.h3
-rw-r--r--lldb/packages/Python/lldbsuite/test/builders/__init__.py10
-rw-r--r--lldb/packages/Python/lldbsuite/test/dotest.py8
-rw-r--r--lldb/packages/Python/lldbsuite/test/lldbgdbclient.py4
-rw-r--r--lldb/packages/Python/lldbsuite/test/lldbplatformutil.py3
-rw-r--r--lldb/packages/Python/lldbsuite/test/lldbtest.py22
-rwxr-xr-xlldb/scripts/framework-header-fix.py2
-rw-r--r--lldb/source/API/CMakeLists.txt2
-rw-r--r--lldb/source/Breakpoint/BreakpointResolverScripted.cpp52
-rw-r--r--lldb/source/Commands/CommandCompletions.cpp2
-rw-r--r--lldb/source/Core/ModuleList.cpp6
-rw-r--r--lldb/source/Expression/DWARFExpression.cpp10
-rw-r--r--lldb/source/Expression/Materializer.cpp21
-rw-r--r--lldb/source/Host/windows/MainLoopWindows.cpp4
-rw-r--r--lldb/source/Interpreter/ScriptInterpreter.cpp7
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp2
-rw-r--r--lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp6
-rw-r--r--lldb/source/Plugins/InstrumentationRuntime/Utility/Utility.cpp4
-rw-r--r--lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp6
-rw-r--r--lldb/source/Plugins/Process/CMakeLists.txt1
-rw-r--r--lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp3
-rw-r--r--lldb/source/Plugins/Process/Linux/CMakeLists.txt1
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp49
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h23
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp67
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64dbreg.cpp77
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64dbreg.h31
-rw-r--r--lldb/source/Plugins/Process/Utility/AuxVector.cpp3
-rw-r--r--lldb/source/Plugins/Process/Utility/AuxVector.h5
-rw-r--r--lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg.h2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp53
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h25
-rw-r--r--lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp13
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp20
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h2
-rw-r--r--lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp2
-rw-r--r--lldb/source/Plugins/Process/wasm/CMakeLists.txt11
-rw-r--r--lldb/source/Plugins/Process/wasm/ProcessWasm.cpp166
-rw-r--r--lldb/source/Plugins/Process/wasm/ProcessWasm.h99
-rw-r--r--lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp109
-rw-r--r--lldb/source/Plugins/Process/wasm/RegisterContextWasm.h69
-rw-r--r--lldb/source/Plugins/Process/wasm/ThreadWasm.cpp51
-rw-r--r--lldb/source/Plugins/Process/wasm/ThreadWasm.h41
-rw-r--r--lldb/source/Plugins/Process/wasm/UnwindWasm.cpp85
-rw-r--r--lldb/source/Plugins/Process/wasm/UnwindWasm.h51
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt1
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp2
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h1
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.cpp100
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.h53
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp15
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h13
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h10
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp74
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h14
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt1
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp28
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp4
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h8
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp4
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h3
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp8
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h3
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.cpp100
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.h34
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp6
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h2
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp5
-rw-r--r--lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp5
-rw-r--r--lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp24
-rw-r--r--lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h4
-rw-r--r--lldb/source/Target/InstrumentationRuntime.cpp8
-rw-r--r--lldb/source/Target/Platform.cpp7
-rw-r--r--lldb/source/Target/Target.cpp5
-rw-r--r--lldb/source/Utility/WasmVirtualRegisters.h53
-rw-r--r--lldb/test/API/commands/expression/import-std-module/array/TestArrayFromStdModule.py1
-rw-r--r--lldb/test/API/commands/expression/import-std-module/basic/TestImportStdModule.py2
-rw-r--r--lldb/test/API/commands/expression/import-std-module/conflicts/TestStdModuleWithConflicts.py1
-rw-r--r--lldb/test/API/commands/expression/import-std-module/deque-basic/TestDequeFromStdModule.py1
-rw-r--r--lldb/test/API/commands/expression/import-std-module/deque-dbg-info-content/TestDbgInfoContentDequeFromStdModule.py1
-rw-r--r--lldb/test/API/commands/expression/import-std-module/forward_list-dbg-info-content/TestDbgInfoContentForwardListFromStdModule.py1
-rw-r--r--lldb/test/API/commands/expression/import-std-module/forward_list/TestForwardListFromStdModule.py1
-rw-r--r--lldb/test/API/commands/expression/import-std-module/iterator/TestIteratorFromStdModule.py1
-rw-r--r--lldb/test/API/commands/expression/import-std-module/list-dbg-info-content/TestDbgInfoContentListFromStdModule.py2
-rw-r--r--lldb/test/API/commands/expression/import-std-module/list/TestListFromStdModule.py1
-rw-r--r--lldb/test/API/commands/expression/import-std-module/non-module-type-separation/TestNonModuleTypeSeparation.py1
-rw-r--r--lldb/test/API/commands/expression/import-std-module/retry-with-std-module/TestRetryWithStdModule.py1
-rw-r--r--lldb/test/API/commands/expression/import-std-module/shared_ptr-dbg-info-content/TestSharedPtrDbgInfoContentFromStdModule.py1
-rw-r--r--lldb/test/API/commands/expression/import-std-module/shared_ptr/TestSharedPtrFromStdModule.py1
-rw-r--r--lldb/test/API/commands/expression/import-std-module/unique_ptr-dbg-info-content/TestUniquePtrDbgInfoContent.py1
-rw-r--r--lldb/test/API/commands/expression/import-std-module/unique_ptr/TestUniquePtrFromStdModule.py1
-rw-r--r--lldb/test/API/commands/expression/import-std-module/vector-of-vectors/TestVectorOfVectorsFromStdModule.py1
-rw-r--r--lldb/test/API/commands/expression/import-std-module/weak_ptr-dbg-info-content/TestDbgInfoContentWeakPtrFromStdModule.py1
-rw-r--r--lldb/test/API/commands/expression/import-std-module/weak_ptr/TestWeakPtrFromStdModule.py1
-rw-r--r--lldb/test/API/commands/register/register/aarch64_mte_ctrl_register/TestMTECtrlRegister.py32
-rw-r--r--lldb/test/API/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py4
-rw-r--r--lldb/test/API/functionalities/breakpoint/scripted_bkpt/resolver.py24
-rw-r--r--lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py11
-rw-r--r--lldb/test/API/functionalities/gdb_remote_client/TestWasm.py223
-rw-r--r--lldb/test/API/functionalities/gdb_remote_client/simple.c10
-rw-r--r--lldb/test/API/functionalities/gdb_remote_client/simple.yaml228
-rw-r--r--lldb/test/API/functionalities/postmortem/elf-core/expr/TestExpr.py4
-rw-r--r--lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py11
-rw-r--r--lldb/test/API/linux/aarch64/mte_core_file/core.mtebin20608 -> 417920 bytes
-rw-r--r--lldb/test/API/linux/aarch64/mte_core_file/core.nomtebin20480 -> 32768 bytes
-rw-r--r--lldb/test/API/linux/aarch64/mte_core_file/main.c2
-rw-r--r--lldb/test/Shell/Commands/command-disassemble-process.yaml11
-rw-r--r--lldb/test/Shell/Commands/command-image-lookup.yaml9
-rw-r--r--lldb/test/Shell/Minidump/Windows/arm-fp-unwind.test9
-rw-r--r--lldb/test/Shell/Minidump/Windows/broken-unwind.test9
-rw-r--r--lldb/test/Shell/Minidump/Windows/find-module.test13
-rw-r--r--lldb/test/Shell/Minidump/memory-region-from-module.yaml6
-rw-r--r--lldb/test/Shell/ObjectFile/Breakpad/uuid-matching-mac.test5
-rw-r--r--lldb/test/Shell/ObjectFile/ELF/minidebuginfo-set-and-hit-breakpoint.test4
-rw-r--r--lldb/test/Shell/Recognizer/Inputs/ubsan_add_overflow.c3
-rw-r--r--lldb/test/Shell/Recognizer/ubsan_add_overflow.test20
-rw-r--r--lldb/test/Shell/Scripts/TestFrameworkFixScript.test2
-rw-r--r--lldb/test/Shell/Scripts/TestFrameworkFixUnifdef.test2
-rw-r--r--lldb/test/Shell/Scripts/TestRPCFrameworkFixScript.test2
-rw-r--r--lldb/test/Shell/SymbolFile/Breakpad/inline-record.test5
-rw-r--r--lldb/test/Shell/SymbolFile/Breakpad/line-table-discontinuous-file-ids.test5
-rw-r--r--lldb/test/Shell/SymbolFile/Breakpad/line-table-edgecases.test5
-rw-r--r--lldb/test/Shell/SymbolFile/Breakpad/line-table-missing-file.test5
-rw-r--r--lldb/test/Shell/SymbolFile/Breakpad/line-table-mixed-path-styles.test5
-rw-r--r--lldb/test/Shell/SymbolFile/Breakpad/line-table.test5
-rw-r--r--lldb/test/Shell/SymbolFile/Breakpad/symtab-macho.test5
-rw-r--r--lldb/test/Shell/SymbolFile/Breakpad/symtab-sorted-by-size.test5
-rw-r--r--lldb/test/Shell/SymbolFile/Breakpad/symtab.test5
-rw-r--r--lldb/test/Shell/SymbolFile/Breakpad/unwind-via-stack-win-no-memory-info.yaml5
-rw-r--r--lldb/test/Shell/SymbolFile/DWARF/dwo-missing-error.test1
-rw-r--r--lldb/test/Shell/SymbolFile/DWARF/dwo-relative-path.s7
-rw-r--r--lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwo.s3
-rw-r--r--lldb/test/Shell/SymbolFile/DWARF/x86/debug_rnglists-dwo.s3
-rw-r--r--lldb/test/Shell/SymbolFile/DWARF/x86/dwo-type-in-main-file.s8
-rw-r--r--lldb/test/Shell/SymbolFile/PDB/class-layout.test25
-rw-r--r--lldb/test/Shell/SymbolFile/PDB/compilands.test9
-rw-r--r--lldb/test/Shell/SymbolFile/PDB/enums-layout.test15
-rw-r--r--lldb/test/Shell/SymbolFile/PDB/func-symbols.test7
-rw-r--r--lldb/test/Shell/SymbolFile/PDB/pointers.test15
-rw-r--r--lldb/test/Shell/SymbolFile/PDB/type-quals.test7
-rw-r--r--lldb/test/Shell/SymbolFile/PDB/typedefs.test5
-rw-r--r--lldb/test/Shell/SymbolFile/PDB/variables.test17
-rw-r--r--lldb/tools/lldb-rpc/LLDBRPCHeaders.cmake2
-rw-r--r--lldb/unittests/Expression/CMakeLists.txt2
-rw-r--r--lldb/unittests/Expression/DWARFExpressionTest.cpp579
-rw-r--r--lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp19
-rw-r--r--lldb/unittests/Symbol/TestTypeSystemClang.cpp12
155 files changed, 2743 insertions, 773 deletions
diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig
index 3d1d04e..2c30d53 100644
--- a/lldb/bindings/python/python-wrapper.swig
+++ b/lldb/bindings/python/python-wrapper.swig
@@ -229,78 +229,6 @@ PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateCommandObject
return pfunc(SWIGBridge::ToSWIGWrapper(std::move(debugger_sp)), dict);
}
-PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateScriptedBreakpointResolver(
- const char *python_class_name, const char *session_dictionary_name,
- const StructuredDataImpl &args_impl,
- const lldb::BreakpointSP &breakpoint_sp) {
-
- if (python_class_name == NULL || python_class_name[0] == '\0' ||
- !session_dictionary_name)
- return PythonObject();
-
- PyErr_Cleaner py_err_cleaner(true);
-
- auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
- session_dictionary_name);
- auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
- python_class_name, dict);
-
- if (!pfunc.IsAllocated())
- return PythonObject();
-
- PythonObject result =
- pfunc(SWIGBridge::ToSWIGWrapper(breakpoint_sp), SWIGBridge::ToSWIGWrapper(args_impl), dict);
- // FIXME: At this point we should check that the class we found supports all
- // the methods that we need.
-
- if (result.IsAllocated()) {
- // Check that __callback__ is defined:
- auto callback_func = result.ResolveName<PythonCallable>("__callback__");
- if (callback_func.IsAllocated())
- return result;
- }
- return PythonObject();
-}
-
-unsigned int lldb_private::python::SWIGBridge::LLDBSwigPythonCallBreakpointResolver(
- void *implementor, const char *method_name,
- lldb_private::SymbolContext *sym_ctx) {
- PyErr_Cleaner py_err_cleaner(false);
- PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
- auto pfunc = self.ResolveName<PythonCallable>(method_name);
-
- if (!pfunc.IsAllocated())
- return 0;
-
- PythonObject result = sym_ctx ? pfunc(SWIGBridge::ToSWIGWrapper(*sym_ctx)) : pfunc();
-
- if (PyErr_Occurred()) {
- PyErr_Print();
- PyErr_Clear();
- return 0;
- }
-
- // The callback will return a bool, but we're need to also return ints
- // so we're squirrelling the bool through as an int... And if you return
- // nothing, we'll continue.
- if (strcmp(method_name, "__callback__") == 0) {
- if (result.get() == Py_False)
- return 0;
- else
- return 1;
- }
-
- long long ret_val = unwrapOrSetPythonException(As<long long>(result));
-
- if (PyErr_Occurred()) {
- PyErr_Print();
- PyErr_Clear();
- return 0;
- }
-
- return ret_val;
-}
-
// wrapper that calls an optional instance member of an object taking no
// arguments
static PyObject *LLDBSwigPython_CallOptionalMember(
@@ -554,6 +482,18 @@ void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBStream(PyObject * dat
return sb_ptr;
}
+void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBSymbolContext(PyObject * data) {
+ lldb::SBSymbolContext *sb_ptr = nullptr;
+
+ int valid_cast =
+ SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBSymbolContext, 0);
+
+ if (valid_cast == -1)
+ return NULL;
+
+ return sb_ptr;
+}
+
void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBValue(PyObject * data) {
lldb::SBValue *sb_ptr = NULL;
diff --git a/lldb/docs/resources/lldbgdbremote.md b/lldb/docs/resources/lldbgdbremote.md
index 80c6809..36b95f1 100644
--- a/lldb/docs/resources/lldbgdbremote.md
+++ b/lldb/docs/resources/lldbgdbremote.md
@@ -2463,3 +2463,70 @@ omitting them will work fine; these numbers are always base 16.
The length of the payload is not provided. A reliable, 8-bit clean,
transport layer is assumed.
+
+## Wasm Packets
+
+The packet below are supported by the
+[WAMR](https://github.com/bytecodealliance/wasm-micro-runtime) and
+[V8](https://v8.dev) Wasm runtimes.
+
+
+### qWasmCallStack
+
+Get the Wasm call stack for the given thread id. This returns a hex-encoded
+list of PC values, one for each frame of the call stack. To match the Wasm
+specification, the addresses are encoded in little endian byte order, even if
+the endian of the Wasm runtime's host is not little endian.
+
+```
+send packet: $qWasmCallStack:202dbe040#08
+read packet: $9c01000000000040e501000000000040fe01000000000040#
+```
+
+**Priority to Implement:** Only required for Wasm support. Necessary to show
+stack traces.
+
+### qWasmGlobal
+
+Get the value of a Wasm global variable for the given frame index at the given
+variable index. The indexes are encoded as base 10. The result is a hex-encoded
+address from where to read the value.
+
+```
+send packet: $qWasmGlobal:0;2#cb
+read packet: $e0030100#b9
+```
+
+**Priority to Implement:** Only required for Wasm support. Necessary to show
+variables.
+
+
+### qWasmLocal
+
+Get the value of a Wasm function argument or local variable for the given frame
+index at the given variable index. The indexes are encoded as base 10. The
+result is a hex-encoded address from where to read the value.
+
+
+```
+send packet: $qWasmLocal:0;2#cb
+read packet: $e0030100#b9
+```
+
+**Priority to Implement:** Only required for Wasm support. Necessary to show
+variables.
+
+
+### qWasmStackValue
+
+Get the value of a Wasm local variable from the Wasm operand stack, for the
+given frame index at the given variable index. The indexes are encoded as base
+10. The result is a hex-encoded address from where to read value.
+
+```
+send packet: $qWasmStackValue:0;2#cb
+read packet: $e0030100#b9
+```
+
+**Priority to Implement:** Only required for Wasm support. Necessary to show
+variables.
diff --git a/lldb/include/lldb/API/SBSymbolContext.h b/lldb/include/lldb/API/SBSymbolContext.h
index ae9fd84..128b0b6 100644
--- a/lldb/include/lldb/API/SBSymbolContext.h
+++ b/lldb/include/lldb/API/SBSymbolContext.h
@@ -80,6 +80,8 @@ protected:
lldb_private::SymbolContext *get() const;
+ friend class lldb_private::ScriptInterpreter;
+
private:
std::unique_ptr<lldb_private::SymbolContext> m_opaque_up;
};
diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h b/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h
index 0e4a1d7..0322fd9 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h
@@ -12,6 +12,7 @@
#include "lldb/Breakpoint/BreakpointResolver.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/StructuredDataImpl.h"
+#include "lldb/Interpreter/Interfaces/ScriptedBreakpointInterface.h"
#include "lldb/lldb-forward.h"
namespace lldb_private {
@@ -64,7 +65,8 @@ private:
std::string m_class_name;
lldb::SearchDepth m_depth;
StructuredDataImpl m_args;
- StructuredData::GenericSP m_implementation_sp;
+ Status m_error;
+ lldb::ScriptedBreakpointInterfaceSP m_interface_sp;
BreakpointResolverScripted(const BreakpointResolverScripted &) = delete;
const BreakpointResolverScripted &
diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h
index 909ee08..d5e291f3 100644
--- a/lldb/include/lldb/Core/ModuleList.h
+++ b/lldb/include/lldb/Core/ModuleList.h
@@ -17,6 +17,7 @@
#include "lldb/Utility/Status.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-enumerations.h"
#include "lldb/lldb-types.h"
#include "llvm/ADT/DenseSet.h"
@@ -488,8 +489,9 @@ public:
/// be non-null.
///
/// This function is thread-safe.
- void ForEach(std::function<bool(const lldb::ModuleSP &module_sp)> const
- &callback) const;
+ void
+ ForEach(std::function<IterationAction(const lldb::ModuleSP &module_sp)> const
+ &callback) const;
/// Returns true if 'callback' returns true for one of the modules
/// in this ModuleList.
diff --git a/lldb/include/lldb/Expression/DWARFExpression.h b/lldb/include/lldb/Expression/DWARFExpression.h
index 37853c0..8fcc5d3 100644
--- a/lldb/include/lldb/Expression/DWARFExpression.h
+++ b/lldb/include/lldb/Expression/DWARFExpression.h
@@ -52,10 +52,10 @@ public:
GetVendorDWARFOpcodeSize(const DataExtractor &data,
const lldb::offset_t data_offset,
const uint8_t op) const = 0;
- virtual bool ParseVendorDWARFOpcode(uint8_t op,
- const DataExtractor &opcodes,
- lldb::offset_t &offset,
- Stack &stack) const = 0;
+ virtual bool
+ ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes,
+ lldb::offset_t &offset, RegisterContext *reg_ctx,
+ lldb::RegisterKind reg_kind, Stack &stack) const = 0;
Delegate(const Delegate &) = delete;
Delegate &operator=(const Delegate &) = delete;
@@ -163,6 +163,10 @@ public:
bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op) const;
+ static llvm::Error ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
+ lldb::RegisterKind reg_kind,
+ uint32_t reg_num, Value &value);
+
private:
/// A data extractor capable of reading opcode bytes
DataExtractor m_data;
diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedBreakpointInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedBreakpointInterface.h
new file mode 100644
index 0000000..28d6ed9
--- /dev/null
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedBreakpointInterface.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_INTERPRETER_INTERFACES_SCRIPTEDBREAKPOINTINTERFACE_H
+#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDBREAKPOINTINTERFACE_H
+
+#include "ScriptedInterface.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+class ScriptedBreakpointInterface : public ScriptedInterface {
+public:
+ virtual llvm::Expected<StructuredData::GenericSP>
+ CreatePluginObject(llvm::StringRef class_name, lldb::BreakpointSP break_sp,
+ const StructuredDataImpl &args_sp) = 0;
+
+ /// "ResolverCallback" will get called when a new module is loaded. The
+ /// new module information is passed in sym_ctx. The Resolver will add
+ /// any breakpoint locations it found in that module.
+ virtual bool ResolverCallback(SymbolContext sym_ctx) { return true; }
+ virtual lldb::SearchDepth GetDepth() { return lldb::eSearchDepthModule; }
+ virtual std::optional<std::string> GetShortHelp() { return nullptr; }
+};
+} // namespace lldb_private
+
+#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDSTOPHOOKINTERFACE_H
diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
index f1c3eef..dffb9b8 100644
--- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -18,6 +18,7 @@
#include "lldb/API/SBLaunchInfo.h"
#include "lldb/API/SBMemoryRegionInfo.h"
#include "lldb/API/SBStream.h"
+#include "lldb/API/SBSymbolContext.h"
#include "lldb/Breakpoint/BreakpointOptions.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/SearchFilter.h"
@@ -29,6 +30,7 @@
#include "lldb/Interpreter/Interfaces/ScriptedProcessInterface.h"
#include "lldb/Interpreter/Interfaces/ScriptedThreadInterface.h"
#include "lldb/Interpreter/ScriptObject.h"
+#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Utility/Broadcaster.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StructuredData.h"
@@ -257,26 +259,6 @@ public:
return false;
}
- virtual StructuredData::GenericSP
- CreateScriptedBreakpointResolver(const char *class_name,
- const StructuredDataImpl &args_data,
- lldb::BreakpointSP &bkpt_sp) {
- return StructuredData::GenericSP();
- }
-
- virtual bool
- ScriptedBreakpointResolverSearchCallback(StructuredData::GenericSP implementor_sp,
- SymbolContext *sym_ctx)
- {
- return false;
- }
-
- virtual lldb::SearchDepth
- ScriptedBreakpointResolverSearchDepth(StructuredData::GenericSP implementor_sp)
- {
- return lldb::eSearchDepthModule;
- }
-
virtual StructuredData::ObjectSP
LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) {
return StructuredData::ObjectSP();
@@ -566,6 +548,11 @@ public:
return {};
}
+ virtual lldb::ScriptedBreakpointInterfaceSP
+ CreateScriptedBreakpointInterface() {
+ return {};
+ }
+
virtual StructuredData::ObjectSP
CreateStructuredDataFromScriptObject(ScriptObject obj) {
return {};
@@ -580,6 +567,9 @@ public:
lldb::StreamSP GetOpaqueTypeFromSBStream(const lldb::SBStream &stream) const;
+ SymbolContext
+ GetOpaqueTypeFromSBSymbolContext(const lldb::SBSymbolContext &sym_ctx) const;
+
lldb::BreakpointSP
GetOpaqueTypeFromSBBreakpoint(const lldb::SBBreakpoint &breakpoint) const;
diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index 2bc85a2..483dce9 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -188,6 +188,7 @@ class Scalar;
class ScriptInterpreter;
class ScriptInterpreterLocker;
class ScriptedMetadata;
+class ScriptedBreakpointInterface;
class ScriptedPlatformInterface;
class ScriptedProcessInterface;
class ScriptedStopHookInterface;
@@ -418,6 +419,8 @@ typedef std::shared_ptr<lldb_private::ScriptedThreadInterface>
ScriptedThreadInterfaceSP;
typedef std::shared_ptr<lldb_private::ScriptedThreadPlanInterface>
ScriptedThreadPlanInterfaceSP;
+typedef std::shared_ptr<lldb_private::ScriptedBreakpointInterface>
+ ScriptedBreakpointInterfaceSP;
typedef std::shared_ptr<lldb_private::Section> SectionSP;
typedef std::unique_ptr<lldb_private::SectionList> SectionListUP;
typedef std::weak_ptr<lldb_private::Section> SectionWP;
diff --git a/lldb/packages/Python/lldbsuite/test/builders/__init__.py b/lldb/packages/Python/lldbsuite/test/builders/__init__.py
index 9dd82cb..7331526 100644
--- a/lldb/packages/Python/lldbsuite/test/builders/__init__.py
+++ b/lldb/packages/Python/lldbsuite/test/builders/__init__.py
@@ -8,7 +8,15 @@ factory method below hands out builders based on the given platform.
def get_builder(platform):
"""Returns a Builder instance for the given platform."""
- if platform == "darwin":
+ if platform in [
+ "bridgeos",
+ "darwin",
+ "ios",
+ "macosx",
+ "tvos",
+ "watchos",
+ "xros",
+ ]:
from .darwin import BuilderDarwin
return BuilderDarwin()
diff --git a/lldb/packages/Python/lldbsuite/test/dotest.py b/lldb/packages/Python/lldbsuite/test/dotest.py
index 90c8e32..24236e7 100644
--- a/lldb/packages/Python/lldbsuite/test/dotest.py
+++ b/lldb/packages/Python/lldbsuite/test/dotest.py
@@ -294,9 +294,11 @@ def parseOptionsAndInitTestdirs():
"Custom libc++ requires both --libcxx-include-dir and --libcxx-library-dir"
)
sys.exit(-1)
- configuration.libcxx_include_dir = args.libcxx_include_dir
- configuration.libcxx_include_target_dir = args.libcxx_include_target_dir
- configuration.libcxx_library_dir = args.libcxx_library_dir
+ else:
+ configuration.libcxx_include_dir = args.libcxx_include_dir
+ configuration.libcxx_include_target_dir = args.libcxx_include_target_dir
+ configuration.libcxx_library_dir = args.libcxx_library_dir
+
configuration.cmake_build_type = args.cmake_build_type.lower()
if args.channels:
diff --git a/lldb/packages/Python/lldbsuite/test/lldbgdbclient.py b/lldb/packages/Python/lldbsuite/test/lldbgdbclient.py
index 459460b..599f787 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbgdbclient.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbgdbclient.py
@@ -45,7 +45,7 @@ class GDBRemoteTestBase(TestBase):
self.yaml2obj(yaml_path, obj_path)
return self.dbg.CreateTarget(obj_path)
- def connect(self, target):
+ def connect(self, target, plugin="gdb-remote"):
"""
Create a process by connecting to the mock GDB server.
@@ -54,7 +54,7 @@ class GDBRemoteTestBase(TestBase):
listener = self.dbg.GetListener()
error = lldb.SBError()
process = target.ConnectRemote(
- listener, self.server.get_connect_url(), "gdb-remote", error
+ listener, self.server.get_connect_url(), plugin, error
)
self.assertTrue(error.Success(), error.description)
self.assertTrue(process, PROCESS_IS_VALID)
diff --git a/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py b/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py
index a1ab060..cea6270 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py
@@ -229,7 +229,8 @@ def hasChattyStderr(test_case):
def builder_module():
- return get_builder(sys.platform)
+ """Return the builder for the target platform."""
+ return get_builder(getPlatform())
def getArchitecture():
diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index 63fadb5..0fc85fc 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -1380,6 +1380,9 @@ class Base(unittest.TestCase):
def isAArch64MTE(self):
return self.isAArch64() and "mte" in self.getCPUInfo()
+ def isAArch64MTEStoreOnly(self):
+ return self.isAArch64() and "mtestoreonly" in self.getCPUInfo()
+
def isAArch64GCS(self):
return self.isAArch64() and "gcs" in self.getCPUInfo()
@@ -1514,7 +1517,7 @@ class Base(unittest.TestCase):
testname = self.getBuildDirBasename()
module = builder_module()
- command = builder_module().getBuildCommand(
+ command = module.getBuildCommand(
debug_info,
architecture,
compiler,
@@ -1775,16 +1778,15 @@ class LLDBTestCaseFactory(type):
attrvalue, "__no_debug_info_test__", False
):
# If any debug info categories were explicitly tagged, assume that list to be
- # authoritative. If none were specified, try with all debug
- # info formats.
+ # authoritative. If none were specified, try with all debug info formats.
+ test_method_categories = set(getattr(attrvalue, "categories", []))
all_dbginfo_categories = set(
test_categories.debug_info_categories.keys()
)
- categories = (
- set(getattr(attrvalue, "categories", [])) & all_dbginfo_categories
- )
- if not categories:
- categories = [
+ dbginfo_categories = test_method_categories & all_dbginfo_categories
+ other_categories = list(test_method_categories - all_dbginfo_categories)
+ if not dbginfo_categories:
+ dbginfo_categories = [
category
for category, can_replicate in test_categories.debug_info_categories.items()
if can_replicate
@@ -1796,9 +1798,8 @@ class LLDBTestCaseFactory(type):
skip_for_debug_info_cat_fn = getattr(
attrvalue, "__skip_for_debug_info_cat_fn__", no_reason
)
- for cat in categories:
+ for cat in dbginfo_categories:
- @decorators.add_test_categories([cat])
@wraps(attrvalue)
def test_method(self, attrvalue=attrvalue):
return attrvalue(self)
@@ -1806,6 +1807,7 @@ class LLDBTestCaseFactory(type):
method_name = attrname + "_" + cat
test_method.__name__ = method_name
test_method.debug_info = cat
+ test_method.categories = other_categories + [cat]
xfail_reason = xfail_for_debug_info_cat_fn(cat)
if xfail_reason:
diff --git a/lldb/scripts/framework-header-fix.py b/lldb/scripts/framework-header-fix.py
index aa034db..36c5c67 100755
--- a/lldb/scripts/framework-header-fix.py
+++ b/lldb/scripts/framework-header-fix.py
@@ -112,7 +112,7 @@ def main():
# but passing them in with dashes for this script causes argparse to think that they're
# arguments in and of themself, so they need to passed in without dashes.
if args.unifdef_guards:
- unifdef_guards = ["-" + guard for guard in args.unifdef_guards]
+ unifdef_guards = ["-U" + guard for guard in args.unifdef_guards]
# Create the framework's header dir if it doesn't already exist
if not os.path.exists(os.path.dirname(output_file_path)):
diff --git a/lldb/source/API/CMakeLists.txt b/lldb/source/API/CMakeLists.txt
index 0687c84..fdd6b3b 100644
--- a/lldb/source/API/CMakeLists.txt
+++ b/lldb/source/API/CMakeLists.txt
@@ -327,6 +327,7 @@ foreach(header
endif()
add_custom_target(liblldb-stage-header-${basename} DEPENDS ${staged_header})
+ add_dependencies(liblldb-stage-header-${basename} lldb-sbapi-dwarf-enums)
add_dependencies(liblldb-header-staging liblldb-stage-header-${basename})
add_custom_command(
DEPENDS ${header} OUTPUT ${staged_header}
@@ -339,6 +340,7 @@ foreach(header
set(output_header $<TARGET_FILE_DIR:liblldb>/Headers/${basename})
add_custom_target(lldb-framework-fixup-header-${basename} DEPENDS ${staged_header})
+ add_dependencies(lldb-framework-fixup-header-${basename} liblldb-stage-header-${basename})
add_dependencies(lldb-framework-fixup-all-headers lldb-framework-fixup-header-${basename})
add_custom_command(TARGET lldb-framework-fixup-header-${basename} POST_BUILD
diff --git a/lldb/source/Breakpoint/BreakpointResolverScripted.cpp b/lldb/source/Breakpoint/BreakpointResolverScripted.cpp
index 2457052..701caba 100644
--- a/lldb/source/Breakpoint/BreakpointResolverScripted.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolverScripted.cpp
@@ -35,7 +35,7 @@ BreakpointResolverScripted::BreakpointResolverScripted(
void BreakpointResolverScripted::CreateImplementationIfNeeded(
BreakpointSP breakpoint_sp) {
- if (m_implementation_sp)
+ if (m_interface_sp)
return;
if (m_class_name.empty())
@@ -50,8 +50,27 @@ void BreakpointResolverScripted::CreateImplementationIfNeeded(
if (!script_interp)
return;
- m_implementation_sp = script_interp->CreateScriptedBreakpointResolver(
- m_class_name.c_str(), m_args, breakpoint_sp);
+ m_interface_sp = script_interp->CreateScriptedBreakpointInterface();
+ if (!m_interface_sp) {
+ m_error = Status::FromErrorStringWithFormat(
+ "BreakpointResolverScripted::%s () - ERROR: %s", __FUNCTION__,
+ "Script interpreter couldn't create Scripted Breakpoint Interface");
+ return;
+ }
+
+ auto obj_or_err =
+ m_interface_sp->CreatePluginObject(m_class_name, breakpoint_sp, m_args);
+ if (!obj_or_err) {
+ m_error = Status::FromError(obj_or_err.takeError());
+ return;
+ }
+
+ StructuredData::ObjectSP object_sp = *obj_or_err;
+ if (!object_sp || !object_sp->IsValid()) {
+ m_error = Status::FromErrorStringWithFormat(
+ "ScriptedBreakpoint::%s () - ERROR: %s", __FUNCTION__,
+ "Failed to create valid script object");
+ }
}
void BreakpointResolverScripted::NotifyBreakpointSet() {
@@ -104,13 +123,10 @@ ScriptInterpreter *BreakpointResolverScripted::GetScriptInterpreter() {
Searcher::CallbackReturn BreakpointResolverScripted::SearchCallback(
SearchFilter &filter, SymbolContext &context, Address *addr) {
bool should_continue = true;
- if (!m_implementation_sp)
+ if (!m_interface_sp)
return Searcher::eCallbackReturnStop;
- ScriptInterpreter *interp = GetScriptInterpreter();
- should_continue = interp->ScriptedBreakpointResolverSearchCallback(
- m_implementation_sp,
- &context);
+ should_continue = m_interface_sp->ResolverCallback(context);
if (should_continue)
return Searcher::eCallbackReturnContinue;
@@ -120,25 +136,21 @@ Searcher::CallbackReturn BreakpointResolverScripted::SearchCallback(
lldb::SearchDepth
BreakpointResolverScripted::GetDepth() {
lldb::SearchDepth depth = lldb::eSearchDepthModule;
- if (m_implementation_sp) {
- ScriptInterpreter *interp = GetScriptInterpreter();
- depth = interp->ScriptedBreakpointResolverSearchDepth(
- m_implementation_sp);
- }
+ if (m_interface_sp)
+ depth = m_interface_sp->GetDepth();
+
return depth;
}
void BreakpointResolverScripted::GetDescription(Stream *s) {
StructuredData::GenericSP generic_sp;
- std::string short_help;
+ std::optional<std::string> short_help;
- if (m_implementation_sp) {
- ScriptInterpreter *interp = GetScriptInterpreter();
- interp->GetShortHelpForCommandObject(m_implementation_sp,
- short_help);
+ if (m_interface_sp) {
+ short_help = m_interface_sp->GetShortHelp();
}
- if (!short_help.empty())
- s->PutCString(short_help.c_str());
+ if (short_help && !short_help->empty())
+ s->PutCString(short_help->c_str());
else
s->Printf("python class = %s", m_class_name.c_str());
}
diff --git a/lldb/source/Commands/CommandCompletions.cpp b/lldb/source/Commands/CommandCompletions.cpp
index 3e22309..b2fc893 100644
--- a/lldb/source/Commands/CommandCompletions.cpp
+++ b/lldb/source/Commands/CommandCompletions.cpp
@@ -571,7 +571,7 @@ void CommandCompletions::ModuleUUIDs(CommandInterpreter &interpreter,
lldb::eDescriptionLevelInitial);
request.TryCompleteCurrentArg(module->GetUUID().GetAsString(),
strm.GetString());
- return true;
+ return IterationAction::Continue;
});
}
diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp
index d5ddf6e..d2e5be8 100644
--- a/lldb/source/Core/ModuleList.cpp
+++ b/lldb/source/Core/ModuleList.cpp
@@ -1077,12 +1077,12 @@ bool ModuleList::LoadScriptingResourcesInTarget(Target *target,
}
void ModuleList::ForEach(
- std::function<bool(const ModuleSP &module_sp)> const &callback) const {
+ std::function<IterationAction(const ModuleSP &module_sp)> const &callback)
+ const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
for (const auto &module_sp : m_modules) {
assert(module_sp != nullptr);
- // If the callback returns false, then stop iterating and break out
- if (!callback(module_sp))
+ if (callback(module_sp) == IterationAction::Stop)
break;
}
}
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index 79bc6c8..391e277 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -91,9 +91,10 @@ void DWARFExpression::SetRegisterKind(RegisterKind reg_kind) {
m_reg_kind = reg_kind;
}
-static llvm::Error ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
- lldb::RegisterKind reg_kind,
- uint32_t reg_num, Value &value) {
+llvm::Error
+DWARFExpression::ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
+ lldb::RegisterKind reg_kind,
+ uint32_t reg_num, Value &value) {
if (reg_ctx == nullptr)
return llvm::createStringError("no register context in frame");
@@ -2302,7 +2303,8 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
default:
if (dwarf_cu) {
- if (dwarf_cu->ParseVendorDWARFOpcode(op, opcodes, offset, stack)) {
+ if (dwarf_cu->ParseVendorDWARFOpcode(op, opcodes, offset, reg_ctx,
+ reg_kind, stack)) {
break;
}
}
diff --git a/lldb/source/Expression/Materializer.cpp b/lldb/source/Expression/Materializer.cpp
index 17ea159..329768d 100644
--- a/lldb/source/Expression/Materializer.cpp
+++ b/lldb/source/Expression/Materializer.cpp
@@ -102,22 +102,23 @@ public:
m_persistent_variable_sp->GetName(), mem, eAddressTypeLoad,
map.GetAddressByteSize());
- if (m_persistent_variable_sp->m_flags &
- ExpressionVariable::EVKeepInTarget) {
- if (used_policy == IRMemoryMap::eAllocationPolicyMirror) {
+ if (used_policy == IRMemoryMap::eAllocationPolicyMirror) {
+ if (m_persistent_variable_sp->m_flags &
+ ExpressionVariable::EVKeepInTarget) {
// Clear the flag if the variable will never be deallocated.
Status leak_error;
map.Leak(mem, leak_error);
m_persistent_variable_sp->m_flags &=
~ExpressionVariable::EVNeedsAllocation;
- } else {
- // If the variable cannot be kept in target, clear this flag...
- m_persistent_variable_sp->m_flags &=
- ~ExpressionVariable::EVKeepInTarget;
- // ...and set the flag to copy the value during dematerialization.
- m_persistent_variable_sp->m_flags |=
- ExpressionVariable::EVNeedsFreezeDry;
}
+ } else {
+ // If we cannot allocate memory in the process,
+ // - clear the 'EVKeepInTarget' flag to ensure that 'm_live_sp' is reset
+ // during dematerialization,
+ m_persistent_variable_sp->m_flags &= ~ExpressionVariable::EVKeepInTarget;
+ // - set the 'EVNeedsFreezeDry' flag so that the value is copied to
+ // 'm_frozen_sp' during dematerialization.
+ m_persistent_variable_sp->m_flags |= ExpressionVariable::EVNeedsFreezeDry;
}
// Write the contents of the variable to the area.
diff --git a/lldb/source/Host/windows/MainLoopWindows.cpp b/lldb/source/Host/windows/MainLoopWindows.cpp
index c1a0182..c0b1079 100644
--- a/lldb/source/Host/windows/MainLoopWindows.cpp
+++ b/lldb/source/Host/windows/MainLoopWindows.cpp
@@ -223,7 +223,7 @@ MainLoopWindows::RegisterReadObject(const IOObjectSP &object_sp,
if (m_read_fds.find(waitable_handle) != m_read_fds.end()) {
error = Status::FromErrorStringWithFormat(
- "File descriptor %d already monitored.", waitable_handle);
+ "File descriptor %p already monitored.", waitable_handle);
return nullptr;
}
@@ -235,7 +235,7 @@ MainLoopWindows::RegisterReadObject(const IOObjectSP &object_sp,
} else {
DWORD file_type = GetFileType(waitable_handle);
if (file_type != FILE_TYPE_PIPE) {
- error = Status::FromErrorStringWithFormat("Unsupported file type %d",
+ error = Status::FromErrorStringWithFormat("Unsupported file type %ld",
file_type);
return nullptr;
}
diff --git a/lldb/source/Interpreter/ScriptInterpreter.cpp b/lldb/source/Interpreter/ScriptInterpreter.cpp
index ae913e6..6a654a0 100644
--- a/lldb/source/Interpreter/ScriptInterpreter.cpp
+++ b/lldb/source/Interpreter/ScriptInterpreter.cpp
@@ -116,6 +116,13 @@ lldb::StreamSP ScriptInterpreter::GetOpaqueTypeFromSBStream(
return nullptr;
}
+SymbolContext ScriptInterpreter::GetOpaqueTypeFromSBSymbolContext(
+ const lldb::SBSymbolContext &sb_sym_ctx) const {
+ if (sb_sym_ctx.m_opaque_up)
+ return *sb_sym_ctx.m_opaque_up;
+ return {};
+}
+
std::optional<MemoryRegionInfo>
ScriptInterpreter::GetOpaqueTypeFromSBMemoryRegionInfo(
const lldb::SBMemoryRegionInfo &mem_region) const {
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index 9f77fbc..214e260 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -1991,7 +1991,7 @@ void ClangExpressionDeclMap::AddContextClassType(NameSearchContext &context,
const bool is_artificial = false;
CXXMethodDecl *method_decl = m_clang_ast_context->AddMethodToCXXRecordType(
- copied_clang_type.GetOpaqueQualType(), "$__lldb_expr", nullptr,
+ copied_clang_type.GetOpaqueQualType(), "$__lldb_expr", /*asm_label=*/{},
method_type, lldb::eAccessPublic, is_virtual, is_static, is_inline,
is_explicit, is_attr_used, is_artificial);
diff --git a/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp b/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp
index 2adde02..5e429a9 100644
--- a/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp
+++ b/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp
@@ -1807,7 +1807,7 @@ RISCVSingleStepBreakpointLocationsPredictor::GetBreakpointLocations(
Log *log = GetLog(LLDBLog::Unwind);
LLDB_LOGF(log,
"RISCVSingleStepBreakpointLocationsPredictor::%s: can't find "
- "corresponding load reserve insturuction",
+ "corresponding load reserve instruction",
__FUNCTION__);
return {*pc + (inst->is_rvc ? 2u : 4u)};
}
@@ -1839,7 +1839,7 @@ RISCVSingleStepBreakpointLocationsPredictor::HandleAtomicSequence(
EmulateInstructionRISCV *riscv_emulator =
static_cast<EmulateInstructionRISCV *>(m_emulator_up.get());
- // Handle instructions between LR and SC. According to unprivilleged
+ // Handle instructions between LR and SC. According to unprivileged
// RISC-V ISA there can be at most 16 instructions in the sequence.
lldb::addr_t entry_pc = pc; // LR instruction address
@@ -1872,7 +1872,7 @@ RISCVSingleStepBreakpointLocationsPredictor::HandleAtomicSequence(
Log *log = GetLog(LLDBLog::Unwind);
LLDB_LOGF(log,
"RISCVSingleStepBreakpointLocationsPredictor::%s: can't find "
- "corresponding store conditional insturuction",
+ "corresponding store conditional instruction",
__FUNCTION__);
return {entry_pc + (lr_inst->is_rvc ? 2u : 4u)};
}
diff --git a/lldb/source/Plugins/InstrumentationRuntime/Utility/Utility.cpp b/lldb/source/Plugins/InstrumentationRuntime/Utility/Utility.cpp
index 7fe76a6..a5cee5d 100644
--- a/lldb/source/Plugins/InstrumentationRuntime/Utility/Utility.cpp
+++ b/lldb/source/Plugins/InstrumentationRuntime/Utility/Utility.cpp
@@ -23,10 +23,10 @@ lldb::ModuleSP GetPreferredAsanModule(const Target &target) {
target.GetImages().ForEach([&](const lldb::ModuleSP &m) {
if (pattern.match(m->GetFileSpec().GetFilename().GetStringRef())) {
module = m;
- return false;
+ return IterationAction::Stop;
}
- return true;
+ return IterationAction::Continue;
});
return module;
diff --git a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
index 67963a7..b1efd25 100644
--- a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
+++ b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
@@ -376,9 +376,13 @@ DataExtractor ObjectFileWasm::ReadImageData(offset_t offset, uint32_t size) {
DataBufferSP buffer_sp(data_up.release());
data.SetData(buffer_sp, 0, buffer_sp->GetByteSize());
}
+ } else if (offset < m_data.GetByteSize()) {
+ size =
+ std::min(static_cast<uint64_t>(size), m_data.GetByteSize() - offset);
+ return DataExtractor(m_data.GetDataStart() + offset, size, GetByteOrder(),
+ GetAddressByteSize());
}
}
-
data.SetByteOrder(GetByteOrder());
return data;
}
diff --git a/lldb/source/Plugins/Process/CMakeLists.txt b/lldb/source/Plugins/Process/CMakeLists.txt
index bd9b1b8..3413360 100644
--- a/lldb/source/Plugins/Process/CMakeLists.txt
+++ b/lldb/source/Plugins/Process/CMakeLists.txt
@@ -29,3 +29,4 @@ add_subdirectory(elf-core)
add_subdirectory(mach-core)
add_subdirectory(minidump)
add_subdirectory(FreeBSDKernel)
+add_subdirectory(wasm)
diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
index 7adc006..d21dac2 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
@@ -44,7 +44,8 @@ NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
NativeProcessFreeBSD &process = native_thread.GetProcess();
g_register_flags_detector.DetectFields(
process.GetAuxValue(AuxVector::AUXV_FREEBSD_AT_HWCAP).value_or(0),
- process.GetAuxValue(AuxVector::AUXV_AT_HWCAP2).value_or(0));
+ process.GetAuxValue(AuxVector::AUXV_AT_HWCAP2).value_or(0),
+ /*hwcap3=*/0);
}
return new NativeRegisterContextFreeBSD_arm64(target_arch, native_thread);
diff --git a/lldb/source/Plugins/Process/Linux/CMakeLists.txt b/lldb/source/Plugins/Process/Linux/CMakeLists.txt
index 33af2e2..bb69016 100644
--- a/lldb/source/Plugins/Process/Linux/CMakeLists.txt
+++ b/lldb/source/Plugins/Process/Linux/CMakeLists.txt
@@ -8,6 +8,7 @@ add_lldb_library(lldbPluginProcessLinux
NativeRegisterContextLinux.cpp
NativeRegisterContextLinux_arm.cpp
NativeRegisterContextLinux_arm64.cpp
+ NativeRegisterContextLinux_arm64dbreg.cpp
NativeRegisterContextLinux_loongarch64.cpp
NativeRegisterContextLinux_ppc64le.cpp
NativeRegisterContextLinux_riscv64.cpp
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
index dc7fb10..fdafacf 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
@@ -23,13 +23,19 @@
#include <elf.h>
#include <sys/uio.h>
+#if defined(__arm64__) || defined(__aarch64__)
+#include "NativeRegisterContextLinux_arm64dbreg.h"
+#include "lldb/Host/linux/Ptrace.h"
+#include <asm/ptrace.h>
+#endif
+
#define REG_CONTEXT_SIZE (GetGPRSize() + sizeof(m_fpr))
#ifndef PTRACE_GETVFPREGS
#define PTRACE_GETVFPREGS 27
#define PTRACE_SETVFPREGS 28
#endif
-#ifndef PTRACE_GETHBPREGS
+#if defined(__arm__) && !defined(PTRACE_GETHBPREGS)
#define PTRACE_GETHBPREGS 29
#define PTRACE_SETHBPREGS 30
#endif
@@ -342,7 +348,8 @@ NativeRegisterContextLinux_arm::SetHardwareBreakpoint(lldb::addr_t addr,
m_hbr_regs[bp_index].control = control_value;
// PTRACE call to set corresponding hardware breakpoint register.
- error = WriteHardwareDebugRegs(eDREGTypeBREAK, bp_index);
+ error = WriteHardwareDebugRegs(NativeRegisterContextDBReg::eDREGTypeBREAK,
+ bp_index);
if (error.Fail()) {
m_hbr_regs[bp_index].address = 0;
@@ -375,7 +382,8 @@ bool NativeRegisterContextLinux_arm::ClearHardwareBreakpoint(uint32_t hw_idx) {
m_hbr_regs[hw_idx].address = 0;
// PTRACE call to clear corresponding hardware breakpoint register.
- error = WriteHardwareDebugRegs(eDREGTypeBREAK, hw_idx);
+ error = WriteHardwareDebugRegs(NativeRegisterContextDBReg::eDREGTypeBREAK,
+ hw_idx);
if (error.Fail()) {
m_hbr_regs[hw_idx].control = tempControl;
@@ -435,7 +443,8 @@ Status NativeRegisterContextLinux_arm::ClearAllHardwareBreakpoints() {
m_hbr_regs[i].address = 0;
// Ptrace call to update hardware debug registers
- error = WriteHardwareDebugRegs(eDREGTypeBREAK, i);
+ error =
+ WriteHardwareDebugRegs(NativeRegisterContextDBReg::eDREGTypeBREAK, i);
if (error.Fail()) {
m_hbr_regs[i].control = tempControl;
@@ -555,7 +564,8 @@ uint32_t NativeRegisterContextLinux_arm::SetHardwareWatchpoint(
m_hwp_regs[wp_index].control = control_value;
// PTRACE call to set corresponding watchpoint register.
- error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index);
+ error = WriteHardwareDebugRegs(NativeRegisterContextDBReg::eDREGTypeWATCH,
+ wp_index);
if (error.Fail()) {
m_hwp_regs[wp_index].address = 0;
@@ -590,7 +600,8 @@ bool NativeRegisterContextLinux_arm::ClearHardwareWatchpoint(
m_hwp_regs[wp_index].address = 0;
// Ptrace call to update hardware debug registers
- error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index);
+ error = WriteHardwareDebugRegs(NativeRegisterContextDBReg::eDREGTypeWATCH,
+ wp_index);
if (error.Fail()) {
m_hwp_regs[wp_index].control = tempControl;
@@ -623,7 +634,8 @@ Status NativeRegisterContextLinux_arm::ClearAllHardwareWatchpoints() {
m_hwp_regs[i].address = 0;
// Ptrace call to update hardware debug registers
- error = WriteHardwareDebugRegs(eDREGTypeWATCH, i);
+ error =
+ WriteHardwareDebugRegs(NativeRegisterContextDBReg::eDREGTypeWATCH, i);
if (error.Fail()) {
m_hwp_regs[i].control = tempControl;
@@ -723,6 +735,7 @@ Status NativeRegisterContextLinux_arm::ReadHardwareDebugInfo() {
return Status();
}
+#ifdef __arm__
unsigned int cap_val;
error = NativeProcessLinux::PtraceWrapper(PTRACE_GETHBPREGS, m_thread.GetID(),
@@ -737,16 +750,21 @@ Status NativeRegisterContextLinux_arm::ReadHardwareDebugInfo() {
m_refresh_hwdebug_info = false;
return error;
+#else // __aarch64__
+ return arm64::ReadHardwareDebugInfo(m_thread.GetID(), m_max_hwp_supported,
+ m_max_hbp_supported);
+#endif // ifdef __arm__
}
-Status NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(int hwbType,
- int hwb_index) {
+Status NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(
+ NativeRegisterContextDBReg::DREGType hwbType, int hwb_index) {
Status error;
+#ifdef __arm__
lldb::addr_t *addr_buf;
uint32_t *ctrl_buf;
- if (hwbType == eDREGTypeWATCH) {
+ if (hwbType == NativeRegisterContextDBReg::eDREGTypeWATCH) {
addr_buf = &m_hwp_regs[hwb_index].address;
ctrl_buf = &m_hwp_regs[hwb_index].control;
@@ -781,6 +799,17 @@ Status NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(int hwbType,
}
return error;
+#else // __aarch64__
+ uint32_t max_supported =
+ (hwbType == NativeRegisterContextDBReg::eDREGTypeWATCH)
+ ? m_max_hwp_supported
+ : m_max_hbp_supported;
+ auto &regs = (hwbType == NativeRegisterContextDBReg::eDREGTypeWATCH)
+ ? m_hwp_regs
+ : m_hbr_regs;
+ return arm64::WriteHardwareDebugRegs(hwbType, m_thread.GetID(), max_supported,
+ regs);
+#endif // ifdef __arm__
}
uint32_t NativeRegisterContextLinux_arm::CalculateFprOffset(
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
index 15b4660..3a31d68 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
@@ -12,6 +12,7 @@
#define lldb_NativeRegisterContextLinux_arm_h
#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
+#include "Plugins/Process/Utility/NativeRegisterContextDBReg.h"
#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
#include "Plugins/Process/Utility/lldb-arm-register-enums.h"
@@ -74,9 +75,6 @@ public:
bool WatchpointIsEnabled(uint32_t wp_index);
- // Debug register type select
- enum DREGType { eDREGTypeWATCH = 0, eDREGTypeBREAK };
-
protected:
Status DoReadRegisterValue(uint32_t offset, const char *reg_name,
uint32_t size, RegisterValue &value) override;
@@ -102,18 +100,10 @@ private:
uint32_t m_gpr_arm[k_num_gpr_registers_arm];
RegisterInfoPOSIX_arm::FPU m_fpr;
- // Debug register info for hardware breakpoints and watchpoints management.
- struct DREG {
- lldb::addr_t address; // Breakpoint/watchpoint address value.
- lldb::addr_t hit_addr; // Address at which last watchpoint trigger exception
- // occurred.
- lldb::addr_t real_addr; // Address value that should cause target to stop.
- uint32_t control; // Breakpoint/watchpoint control value.
- uint32_t refcount; // Serves as enable/disable and reference counter.
- };
-
- struct DREG m_hbr_regs[16]; // Arm native linux hardware breakpoints
- struct DREG m_hwp_regs[16]; // Arm native linux hardware watchpoints
+ std::array<NativeRegisterContextDBReg::DREG, 16>
+ m_hbr_regs; // Arm native linux hardware breakpoints
+ std::array<NativeRegisterContextDBReg::DREG, 16>
+ m_hwp_regs; // Arm native linux hardware watchpoints
uint32_t m_max_hwp_supported;
uint32_t m_max_hbp_supported;
@@ -125,7 +115,8 @@ private:
Status ReadHardwareDebugInfo();
- Status WriteHardwareDebugRegs(int hwbType, int hwb_index);
+ Status WriteHardwareDebugRegs(NativeRegisterContextDBReg::DREGType hwbType,
+ int hwb_index);
uint32_t CalculateFprOffset(const RegisterInfo *reg_info) const;
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
index 884c7d4b..294a446 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
@@ -8,8 +8,9 @@
#if defined(__arm64__) || defined(__aarch64__)
-#include "NativeRegisterContextLinux_arm.h"
#include "NativeRegisterContextLinux_arm64.h"
+#include "NativeRegisterContextLinux_arm.h"
+#include "NativeRegisterContextLinux_arm64dbreg.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/common/NativeProcessProtocol.h"
@@ -162,10 +163,13 @@ NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskTLS);
+ std::optional<uint64_t> auxv_at_hwcap3 =
+ process.GetAuxValue(AuxVector::AUXV_AT_HWCAP3);
std::lock_guard<std::mutex> lock(g_register_flags_detector_mutex);
if (!g_register_flags_detector.HasDetected())
g_register_flags_detector.DetectFields(auxv_at_hwcap.value_or(0),
- auxv_at_hwcap2.value_or(0));
+ auxv_at_hwcap2.value_or(0),
+ auxv_at_hwcap3.value_or(0));
auto register_info_up =
std::make_unique<RegisterInfoPOSIX_arm64>(target_arch, opt_regsets);
@@ -1143,29 +1147,11 @@ llvm::Error NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() {
::pid_t tid = m_thread.GetID();
- int regset = NT_ARM_HW_WATCH;
- struct iovec ioVec;
- struct user_hwdebug_state dreg_state;
- Status error;
-
- ioVec.iov_base = &dreg_state;
- ioVec.iov_len = sizeof(dreg_state);
- error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset,
- &ioVec, ioVec.iov_len);
-
+ Status error = arm64::ReadHardwareDebugInfo(tid, m_max_hwp_supported,
+ m_max_hbp_supported);
if (error.Fail())
return error.ToError();
- m_max_hwp_supported = dreg_state.dbg_info & 0xff;
-
- regset = NT_ARM_HW_BREAK;
- error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset,
- &ioVec, ioVec.iov_len);
-
- if (error.Fail())
- return error.ToError();
-
- m_max_hbp_supported = dreg_state.dbg_info & 0xff;
m_refresh_hwdebug_info = false;
return llvm::Error::success();
@@ -1173,38 +1159,11 @@ llvm::Error NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() {
llvm::Error
NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(DREGType hwbType) {
- struct iovec ioVec;
- struct user_hwdebug_state dreg_state;
- int regset;
-
- memset(&dreg_state, 0, sizeof(dreg_state));
- ioVec.iov_base = &dreg_state;
-
- switch (hwbType) {
- case eDREGTypeWATCH:
- regset = NT_ARM_HW_WATCH;
- ioVec.iov_len = sizeof(dreg_state.dbg_info) + sizeof(dreg_state.pad) +
- (sizeof(dreg_state.dbg_regs[0]) * m_max_hwp_supported);
-
- for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
- dreg_state.dbg_regs[i].addr = m_hwp_regs[i].address;
- dreg_state.dbg_regs[i].ctrl = m_hwp_regs[i].control;
- }
- break;
- case eDREGTypeBREAK:
- regset = NT_ARM_HW_BREAK;
- ioVec.iov_len = sizeof(dreg_state.dbg_info) + sizeof(dreg_state.pad) +
- (sizeof(dreg_state.dbg_regs[0]) * m_max_hbp_supported);
-
- for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
- dreg_state.dbg_regs[i].addr = m_hbp_regs[i].address;
- dreg_state.dbg_regs[i].ctrl = m_hbp_regs[i].control;
- }
- break;
- }
-
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
- &regset, &ioVec, ioVec.iov_len)
+ uint32_t max_supported =
+ (hwbType == eDREGTypeWATCH) ? m_max_hwp_supported : m_max_hbp_supported;
+ auto &regs = (hwbType == eDREGTypeWATCH) ? m_hwp_regs : m_hbp_regs;
+ return arm64::WriteHardwareDebugRegs(hwbType, m_thread.GetID(), max_supported,
+ regs)
.ToError();
}
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64dbreg.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64dbreg.cpp
new file mode 100644
index 0000000..53ee8fd
--- /dev/null
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64dbreg.cpp
@@ -0,0 +1,77 @@
+//===-- NativeRegisterContextLinux_arm64dbreg.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
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__arm64__) || defined(__aarch64__)
+
+#include "NativeRegisterContextLinux_arm64dbreg.h"
+#include "lldb/Host/linux/Ptrace.h"
+
+#include <asm/ptrace.h>
+// System includes - They have to be included after framework includes because
+// they define some macros which collide with variable names in other modules
+#include <sys/uio.h>
+// NT_PRSTATUS and NT_FPREGSET definition
+#include <elf.h>
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_linux;
+
+static Status ReadHardwareDebugInfoHelper(int regset, ::pid_t tid,
+ uint32_t &max_supported) {
+ struct iovec ioVec;
+ struct user_hwdebug_state dreg_state;
+ Status error;
+
+ ioVec.iov_base = &dreg_state;
+ ioVec.iov_len = sizeof(dreg_state);
+ error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset,
+ &ioVec, ioVec.iov_len);
+
+ if (error.Fail())
+ return error;
+
+ max_supported = dreg_state.dbg_info & 0xff;
+ return error;
+}
+
+Status lldb_private::process_linux::arm64::ReadHardwareDebugInfo(
+ ::pid_t tid, uint32_t &max_hwp_supported, uint32_t &max_hbp_supported) {
+ Status error =
+ ReadHardwareDebugInfoHelper(NT_ARM_HW_WATCH, tid, max_hwp_supported);
+
+ if (error.Fail())
+ return error;
+
+ return ReadHardwareDebugInfoHelper(NT_ARM_HW_BREAK, tid, max_hbp_supported);
+}
+
+Status lldb_private::process_linux::arm64::WriteHardwareDebugRegs(
+ int hwbType, ::pid_t tid, uint32_t max_supported,
+ const std::array<NativeRegisterContextDBReg::DREG, 16> &regs) {
+ int regset = hwbType == NativeRegisterContextDBReg::eDREGTypeWATCH
+ ? NT_ARM_HW_WATCH
+ : NT_ARM_HW_BREAK;
+
+ struct user_hwdebug_state dreg_state;
+ memset(&dreg_state, 0, sizeof(dreg_state));
+ for (uint32_t i = 0; i < max_supported; i++) {
+ dreg_state.dbg_regs[i].addr = regs[i].address;
+ dreg_state.dbg_regs[i].ctrl = regs[i].control;
+ }
+
+ struct iovec ioVec;
+ ioVec.iov_base = &dreg_state;
+ ioVec.iov_len = sizeof(dreg_state.dbg_info) + sizeof(dreg_state.pad) +
+ (sizeof(dreg_state.dbg_regs[0]) * max_supported);
+
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, tid, &regset,
+ &ioVec, ioVec.iov_len);
+}
+
+#endif // defined (__arm64__) || defined (__aarch64__)
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64dbreg.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64dbreg.h
new file mode 100644
index 0000000..bca2178
--- /dev/null
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64dbreg.h
@@ -0,0 +1,31 @@
+//===-- NativeRegisterContextLinux_arm64dbreg.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
+//
+//===----------------------------------------------------------------------===//
+
+// When debugging 32-bit processes, Arm64 lldb-server should use 64-bit ptrace
+// interfaces. 32-bit ptrace interfaces should only be used by 32-bit server.
+// These functions are split out to be reused in both 32-bit and 64-bit register
+// context for 64-bit server.
+
+#include "Plugins/Process/Linux/NativeProcessLinux.h"
+#include "Plugins/Process/Utility/NativeRegisterContextDBReg.h"
+#include "lldb/Utility/Status.h"
+
+namespace lldb_private {
+namespace process_linux {
+namespace arm64 {
+
+Status ReadHardwareDebugInfo(::pid_t tid, uint32_t &max_hwp_supported,
+ uint32_t &max_hbp_supported);
+
+Status WriteHardwareDebugRegs(
+ int hwbType, ::pid_t tid, uint32_t max_supported,
+ const std::array<NativeRegisterContextDBReg::DREG, 16> &regs);
+
+} // namespace arm64
+} // namespace process_linux
+} // namespace lldb_private
diff --git a/lldb/source/Plugins/Process/Utility/AuxVector.cpp b/lldb/source/Plugins/Process/Utility/AuxVector.cpp
index f495ffb..d660bfe 100644
--- a/lldb/source/Plugins/Process/Utility/AuxVector.cpp
+++ b/lldb/source/Plugins/Process/Utility/AuxVector.cpp
@@ -84,6 +84,7 @@ const char *AuxVector::GetEntryName(EntryType type) const {
case ENTRY_NAME(AUXV_AT_BASE_PLATFORM); break;
case ENTRY_NAME(AUXV_AT_RANDOM); break;
case ENTRY_NAME(AUXV_AT_HWCAP2); break;
+ case ENTRY_NAME(AUXV_AT_HWCAP3); break;
case ENTRY_NAME(AUXV_AT_EXECFN); break;
case ENTRY_NAME(AUXV_AT_SYSINFO); break;
case ENTRY_NAME(AUXV_AT_SYSINFO_EHDR); break;
@@ -91,6 +92,8 @@ const char *AuxVector::GetEntryName(EntryType type) const {
case ENTRY_NAME(AUXV_AT_L1D_CACHESHAPE); break;
case ENTRY_NAME(AUXV_AT_L2_CACHESHAPE); break;
case ENTRY_NAME(AUXV_AT_L3_CACHESHAPE); break;
+ case ENTRY_NAME(AUXV_FREEBSD_AT_HWCAP3); break;
+ case ENTRY_NAME(AUXV_FREEBSD_AT_HWCAP4); break;
}
#undef ENTRY_NAME
diff --git a/lldb/source/Plugins/Process/Utility/AuxVector.h b/lldb/source/Plugins/Process/Utility/AuxVector.h
index 2670b34..ad6b70e 100644
--- a/lldb/source/Plugins/Process/Utility/AuxVector.h
+++ b/lldb/source/Plugins/Process/Utility/AuxVector.h
@@ -57,6 +57,7 @@ public:
AUXV_AT_BASE_PLATFORM = 24, ///< String identifying real platforms.
AUXV_AT_RANDOM = 25, ///< Address of 16 random bytes.
AUXV_AT_HWCAP2 = 26, ///< Extension of AT_HWCAP.
+ AUXV_AT_HWCAP3 = 29, ///< Extension of AT_HWCAP.
AUXV_AT_EXECFN = 31, ///< Filename of executable.
AUXV_AT_SYSINFO = 32, ///< Pointer to the global system page used for system
/// calls and other nice things.
@@ -69,6 +70,10 @@ public:
// Platform specific values which may overlap the Linux values.
AUXV_FREEBSD_AT_HWCAP = 25, ///< FreeBSD specific AT_HWCAP value.
+ // FreeBSD and Linux use the same AT_HWCAP2 value.
+ AUXV_FREEBSD_AT_HWCAP3 = 38, ///< FreeBSD specific AT_HWCAP3 value.
+ AUXV_FREEBSD_AT_HWCAP4 = 39, ///< FreeBSD specific AT_HWCAP4 value.
+
};
std::optional<uint64_t> GetAuxValue(enum EntryType entry_type) const;
diff --git a/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg.h b/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg.h
index e17a700..9b6ecd3 100644
--- a/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg.h
+++ b/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg.h
@@ -51,7 +51,6 @@ public:
lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
-protected:
// Debug register type select
enum DREGType { eDREGTypeWATCH = 0, eDREGTypeBREAK };
@@ -64,6 +63,7 @@ protected:
uint32_t control; // Breakpoint/watchpoint control value.
};
+protected:
std::array<struct DREG, 16> m_hbp_regs; // hardware breakpoints
std::array<struct DREG, 16> m_hwp_regs; // hardware watchpoints
diff --git a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp
index 042940b..330a24a 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp
@@ -26,11 +26,15 @@
#define HWCAP2_EBF16 (1ULL << 32)
#define HWCAP2_FPMR (1ULL << 48)
+#define HWCAP3_MTE_STORE_ONLY (1ULL << 1)
+
using namespace lldb_private;
Arm64RegisterFlagsDetector::Fields
-Arm64RegisterFlagsDetector::DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2) {
+Arm64RegisterFlagsDetector::DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3) {
(void)hwcap;
+ (void)hwcap3;
if (!(hwcap2 & HWCAP2_FPMR))
return {};
@@ -53,8 +57,10 @@ Arm64RegisterFlagsDetector::DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2) {
Arm64RegisterFlagsDetector::Fields
Arm64RegisterFlagsDetector::DetectGCSFeatureFields(uint64_t hwcap,
- uint64_t hwcap2) {
+ uint64_t hwcap2,
+ uint64_t hwcap3) {
(void)hwcap2;
+ (void)hwcap3;
if (!(hwcap & HWCAP_GCS))
return {};
@@ -67,8 +73,10 @@ Arm64RegisterFlagsDetector::DetectGCSFeatureFields(uint64_t hwcap,
}
Arm64RegisterFlagsDetector::Fields
-Arm64RegisterFlagsDetector::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2) {
+Arm64RegisterFlagsDetector::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3) {
(void)hwcap;
+ (void)hwcap3;
if (!(hwcap2 & HWCAP2_SME))
return {};
@@ -83,8 +91,8 @@ Arm64RegisterFlagsDetector::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2) {
}
Arm64RegisterFlagsDetector::Fields
-Arm64RegisterFlagsDetector::DetectMTECtrlFields(uint64_t hwcap,
- uint64_t hwcap2) {
+Arm64RegisterFlagsDetector::DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3) {
(void)hwcap;
if (!(hwcap2 & HWCAP2_MTE))
@@ -94,16 +102,29 @@ Arm64RegisterFlagsDetector::DetectMTECtrlFields(uint64_t hwcap,
// to prctl(PR_TAGGED_ADDR_CTRL...). Fields are derived from the defines
// used to build the value.
+ std::vector<RegisterFlags::Field> fields;
+ fields.reserve(4);
+ if (hwcap3 & HWCAP3_MTE_STORE_ONLY)
+ fields.push_back({"STORE_ONLY", 19});
+
static const FieldEnum tcf_enum(
"tcf_enum",
{{0, "TCF_NONE"}, {1, "TCF_SYNC"}, {2, "TCF_ASYNC"}, {3, "TCF_ASYMM"}});
- return {{"TAGS", 3, 18}, // 16 bit bitfield shifted up by PR_MTE_TAG_SHIFT.
- {"TCF", 1, 2, &tcf_enum},
- {"TAGGED_ADDR_ENABLE", 0}};
+
+ fields.insert(
+ std::end(fields),
+ {{"TAGS", 3, 18}, // 16 bit bitfield shifted up by PR_MTE_TAG_SHIFT.
+ {"TCF", 1, 2, &tcf_enum},
+ {"TAGGED_ADDR_ENABLE", 0}});
+
+ return fields;
}
Arm64RegisterFlagsDetector::Fields
-Arm64RegisterFlagsDetector::DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2) {
+Arm64RegisterFlagsDetector::DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3) {
+ (void)hwcap3;
+
static const FieldEnum rmode_enum(
"rmode_enum", {{0, "RN"}, {1, "RP"}, {2, "RM"}, {3, "RZ"}});
@@ -142,10 +163,12 @@ Arm64RegisterFlagsDetector::DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2) {
}
Arm64RegisterFlagsDetector::Fields
-Arm64RegisterFlagsDetector::DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2) {
+Arm64RegisterFlagsDetector::DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3) {
// fpsr's contents are constant.
(void)hwcap;
(void)hwcap2;
+ (void)hwcap3;
return {
// Bits 31-28 are N/Z/C/V, only used by AArch32.
@@ -162,7 +185,10 @@ Arm64RegisterFlagsDetector::DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2) {
}
Arm64RegisterFlagsDetector::Fields
-Arm64RegisterFlagsDetector::DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2) {
+Arm64RegisterFlagsDetector::DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3) {
+ (void)hwcap3;
+
// The fields here are a combination of the Arm manual's SPSR_EL1,
// plus a few changes where Linux has decided not to make use of them at all,
// or at least not from userspace.
@@ -207,9 +233,10 @@ Arm64RegisterFlagsDetector::DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2) {
return cpsr_fields;
}
-void Arm64RegisterFlagsDetector::DetectFields(uint64_t hwcap, uint64_t hwcap2) {
+void Arm64RegisterFlagsDetector::DetectFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3) {
for (auto &reg : m_registers)
- reg.m_flags.SetFields(reg.m_detector(hwcap, hwcap2));
+ reg.m_flags.SetFields(reg.m_detector(hwcap, hwcap2, hwcap3));
m_has_detected = true;
}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h
index 7daebcc..aec2bf9 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h
@@ -40,7 +40,7 @@ public:
/// If called more than once, fields will be redetected each time from
/// scratch. If the target would not have this register at all, the list of
/// fields will be left empty.
- void DetectFields(uint64_t hwcap, uint64_t hwcap2);
+ void DetectFields(uint64_t hwcap, uint64_t hwcap2, uint64_t hwcap3);
/// Add the field information of any registers named in this class,
/// to the relevant RegisterInfo instances. Note that this will be done
@@ -53,15 +53,22 @@ public:
private:
using Fields = std::vector<RegisterFlags::Field>;
- using DetectorFn = std::function<Fields(uint64_t, uint64_t)>;
+ using DetectorFn = std::function<Fields(uint64_t, uint64_t, uint64_t)>;
- static Fields DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2);
- static Fields DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2);
- static Fields DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2);
- static Fields DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2);
- static Fields DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2);
- static Fields DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2);
- static Fields DetectGCSFeatureFields(uint64_t hwcap, uint64_t hwcap2);
+ static Fields DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3);
+ static Fields DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3);
+ static Fields DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3);
+ static Fields DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3);
+ static Fields DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3);
+ static Fields DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3);
+ static Fields DetectGCSFeatureFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3);
struct RegisterEntry {
RegisterEntry(llvm::StringRef name, unsigned size, DetectorFn detector)
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
index bd02bb0..d5046d3 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
@@ -96,14 +96,19 @@ RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
llvm::Triple::OSType os = process->GetArchitecture().GetTriple().getOS();
if ((os == llvm::Triple::Linux) || (os == llvm::Triple::FreeBSD)) {
AuxVector aux_vec(process->GetAuxvData());
- std::optional<uint64_t> auxv_at_hwcap = aux_vec.GetAuxValue(
- os == llvm::Triple::FreeBSD ? AuxVector::AUXV_FREEBSD_AT_HWCAP
- : AuxVector::AUXV_AT_HWCAP);
+ bool is_freebsd = os == llvm::Triple::FreeBSD;
+ std::optional<uint64_t> auxv_at_hwcap =
+ aux_vec.GetAuxValue(is_freebsd ? AuxVector::AUXV_FREEBSD_AT_HWCAP
+ : AuxVector::AUXV_AT_HWCAP);
std::optional<uint64_t> auxv_at_hwcap2 =
aux_vec.GetAuxValue(AuxVector::AUXV_AT_HWCAP2);
+ std::optional<uint64_t> auxv_at_hwcap3 =
+ is_freebsd ? std::nullopt
+ : aux_vec.GetAuxValue(AuxVector::AUXV_AT_HWCAP3);
m_register_flags_detector.DetectFields(auxv_at_hwcap.value_or(0),
- auxv_at_hwcap2.value_or(0));
+ auxv_at_hwcap2.value_or(0),
+ auxv_at_hwcap3.value_or(0));
m_register_flags_detector.UpdateRegisterInfo(GetRegisterInfo(),
GetRegisterCount());
}
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index a2c34dd..f610422 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -323,6 +323,11 @@ ProcessGDBRemote::~ProcessGDBRemote() {
KillDebugserverProcess();
}
+std::shared_ptr<ThreadGDBRemote>
+ProcessGDBRemote::CreateThread(lldb::tid_t tid) {
+ return std::make_shared<ThreadGDBRemote>(*this, tid);
+}
+
bool ProcessGDBRemote::ParsePythonTargetDefinition(
const FileSpec &target_definition_fspec) {
ScriptInterpreter *interpreter =
@@ -1594,7 +1599,7 @@ bool ProcessGDBRemote::DoUpdateThreadList(ThreadList &old_thread_list,
ThreadSP thread_sp(
old_thread_list_copy.RemoveThreadByProtocolID(tid, false));
if (!thread_sp) {
- thread_sp = std::make_shared<ThreadGDBRemote>(*this, tid);
+ thread_sp = CreateThread(tid);
LLDB_LOGV(log, "Making new thread: {0} for thread ID: {1:x}.",
thread_sp.get(), thread_sp->GetID());
} else {
@@ -1726,7 +1731,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
if (!thread_sp) {
// Create the thread if we need to
- thread_sp = std::make_shared<ThreadGDBRemote>(*this, tid);
+ thread_sp = CreateThread(tid);
m_thread_list_real.AddThread(thread_sp);
}
}
@@ -4783,7 +4788,8 @@ bool ParseRegisters(
} else if (gdb_type == "data_ptr" || gdb_type == "code_ptr") {
reg_info.format = eFormatAddressInfo;
reg_info.encoding = eEncodingUint;
- } else if (gdb_type == "float") {
+ } else if (gdb_type == "float" || gdb_type == "ieee_single" ||
+ gdb_type == "ieee_double") {
reg_info.format = eFormatFloat;
reg_info.encoding = eEncodingIEEE754;
} else if (gdb_type == "aarch64v" ||
@@ -5260,17 +5266,17 @@ llvm::Error ProcessGDBRemote::LoadModules() {
loaded_modules.Remove(removed_modules);
m_process->GetTarget().ModulesDidUnload(removed_modules, false);
- new_modules.ForEach([&target](const lldb::ModuleSP module_sp) -> bool {
+ new_modules.ForEach([&target](const lldb::ModuleSP module_sp) {
lldb_private::ObjectFile *obj = module_sp->GetObjectFile();
if (!obj)
- return true;
+ return IterationAction::Continue;
if (obj->GetType() != ObjectFile::Type::eTypeExecutable)
- return true;
+ return IterationAction::Continue;
lldb::ModuleSP module_copy_sp = module_sp;
target.SetExecutableModule(module_copy_sp, eLoadDependentsNo);
- return false;
+ return IterationAction::Stop;
});
loaded_modules.AppendIfNeeded(new_modules);
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 7ae3383..7c3dfb1 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -246,6 +246,8 @@ protected:
ProcessGDBRemote(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
+ virtual std::shared_ptr<ThreadGDBRemote> CreateThread(lldb::tid_t tid);
+
bool SupportsMemoryTagging() override;
/// Broadcaster event bits definitions.
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
index 17a421a..b0b8fae 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -408,7 +408,7 @@ void ProcessMinidump::BuildMemoryRegions() {
to_add.back().SetName(module_sp->GetFileSpec().GetPath().c_str());
}
}
- return true;
+ return IterationAction::Continue;
});
m_memory_regions->insert(m_memory_regions->end(), to_add.begin(),
to_add.end());
diff --git a/lldb/source/Plugins/Process/wasm/CMakeLists.txt b/lldb/source/Plugins/Process/wasm/CMakeLists.txt
new file mode 100644
index 0000000..779b97e
--- /dev/null
+++ b/lldb/source/Plugins/Process/wasm/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_lldb_library(lldbPluginProcessWasm PLUGIN
+ ProcessWasm.cpp
+ RegisterContextWasm.cpp
+ ThreadWasm.cpp
+ UnwindWasm.cpp
+
+ LINK_LIBS
+ lldbCore
+ LINK_COMPONENTS
+ Support
+ )
diff --git a/lldb/source/Plugins/Process/wasm/ProcessWasm.cpp b/lldb/source/Plugins/Process/wasm/ProcessWasm.cpp
new file mode 100644
index 0000000..580e8c1
--- /dev/null
+++ b/lldb/source/Plugins/Process/wasm/ProcessWasm.cpp
@@ -0,0 +1,166 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "ProcessWasm.h"
+#include "ThreadWasm.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Utility/DataBufferHeap.h"
+
+#include "lldb/Target/UnixSignals.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_gdb_remote;
+using namespace lldb_private::wasm;
+
+LLDB_PLUGIN_DEFINE(ProcessWasm)
+
+ProcessWasm::ProcessWasm(lldb::TargetSP target_sp, ListenerSP listener_sp)
+ : ProcessGDBRemote(target_sp, listener_sp) {
+ assert(target_sp);
+ // Wasm doesn't have any Unix-like signals as a platform concept, but pretend
+ // like it does to appease LLDB.
+ m_unix_signals_sp = UnixSignals::Create(target_sp->GetArchitecture());
+}
+
+void ProcessWasm::Initialize() {
+ static llvm::once_flag g_once_flag;
+
+ llvm::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ DebuggerInitialize);
+ });
+}
+
+void ProcessWasm::DebuggerInitialize(Debugger &debugger) {
+ ProcessGDBRemote::DebuggerInitialize(debugger);
+}
+
+llvm::StringRef ProcessWasm::GetPluginName() { return GetPluginNameStatic(); }
+
+llvm::StringRef ProcessWasm::GetPluginNameStatic() { return "wasm"; }
+
+llvm::StringRef ProcessWasm::GetPluginDescriptionStatic() {
+ return "GDB Remote protocol based WebAssembly debugging plug-in.";
+}
+
+void ProcessWasm::Terminate() {
+ PluginManager::UnregisterPlugin(ProcessWasm::CreateInstance);
+}
+
+lldb::ProcessSP ProcessWasm::CreateInstance(lldb::TargetSP target_sp,
+ ListenerSP listener_sp,
+ const FileSpec *crash_file_path,
+ bool can_connect) {
+ if (crash_file_path == nullptr)
+ return std::make_shared<ProcessWasm>(target_sp, listener_sp);
+ return {};
+}
+
+bool ProcessWasm::CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) {
+ if (plugin_specified_by_name)
+ return true;
+
+ if (Module *exe_module = target_sp->GetExecutableModulePointer()) {
+ if (ObjectFile *exe_objfile = exe_module->GetObjectFile())
+ return exe_objfile->GetArchitecture().GetMachine() ==
+ llvm::Triple::wasm32;
+ }
+
+ // However, if there is no wasm module, we return false, otherwise,
+ // we might use ProcessWasm to attach gdb remote.
+ return false;
+}
+
+std::shared_ptr<ThreadGDBRemote> ProcessWasm::CreateThread(lldb::tid_t tid) {
+ return std::make_shared<ThreadWasm>(*this, tid);
+}
+
+size_t ProcessWasm::ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
+ Status &error) {
+ wasm_addr_t wasm_addr(vm_addr);
+
+ switch (wasm_addr.GetType()) {
+ case WasmAddressType::Memory:
+ case WasmAddressType::Object:
+ return ProcessGDBRemote::ReadMemory(vm_addr, buf, size, error);
+ case WasmAddressType::Invalid:
+ error.FromErrorStringWithFormat(
+ "Wasm read failed for invalid address 0x%" PRIx64, vm_addr);
+ return 0;
+ }
+}
+
+llvm::Expected<std::vector<lldb::addr_t>>
+ProcessWasm::GetWasmCallStack(lldb::tid_t tid) {
+ StreamString packet;
+ packet.Printf("qWasmCallStack:");
+ packet.Printf("%" PRIx64, tid);
+
+ StringExtractorGDBRemote response;
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) !=
+ GDBRemoteCommunication::PacketResult::Success)
+ return llvm::createStringError("failed to send qWasmCallStack");
+
+ if (!response.IsNormalResponse())
+ return llvm::createStringError("failed to get response for qWasmCallStack");
+
+ WritableDataBufferSP data_buffer_sp =
+ std::make_shared<DataBufferHeap>(response.GetStringRef().size() / 2, 0);
+ const size_t bytes = response.GetHexBytes(data_buffer_sp->GetData(), '\xcc');
+ if (bytes == 0 || bytes % sizeof(uint64_t) != 0)
+ return llvm::createStringError("invalid response for qWasmCallStack");
+
+ // To match the Wasm specification, the addresses are encoded in little endian
+ // byte order.
+ DataExtractor data(data_buffer_sp, lldb::eByteOrderLittle,
+ GetAddressByteSize());
+ lldb::offset_t offset = 0;
+ std::vector<lldb::addr_t> call_stack_pcs;
+ while (offset < bytes)
+ call_stack_pcs.push_back(data.GetU64(&offset));
+
+ return call_stack_pcs;
+}
+
+llvm::Expected<lldb::DataBufferSP>
+ProcessWasm::GetWasmVariable(WasmVirtualRegisterKinds kind, int frame_index,
+ int index) {
+ StreamString packet;
+ switch (kind) {
+ case eWasmTagLocal:
+ packet.Printf("qWasmLocal:");
+ break;
+ case eWasmTagGlobal:
+ packet.Printf("qWasmGlobal:");
+ break;
+ case eWasmTagOperandStack:
+ packet.PutCString("qWasmStackValue:");
+ break;
+ case eWasmTagNotAWasmLocation:
+ return llvm::createStringError("not a Wasm location");
+ }
+ packet.Printf("%d;%d", frame_index, index);
+
+ StringExtractorGDBRemote response;
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) !=
+ GDBRemoteCommunication::PacketResult::Success)
+ return llvm::createStringError("failed to send Wasm variable");
+
+ if (!response.IsNormalResponse())
+ return llvm::createStringError("failed to get response for Wasm variable");
+
+ WritableDataBufferSP buffer_sp(
+ new DataBufferHeap(response.GetStringRef().size() / 2, 0));
+ response.GetHexBytes(buffer_sp->GetData(), '\xcc');
+ return buffer_sp;
+}
diff --git a/lldb/source/Plugins/Process/wasm/ProcessWasm.h b/lldb/source/Plugins/Process/wasm/ProcessWasm.h
new file mode 100644
index 0000000..22effe7
--- /dev/null
+++ b/lldb/source/Plugins/Process/wasm/ProcessWasm.h
@@ -0,0 +1,99 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_WASM_PROCESSWASM_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_WASM_PROCESSWASM_H
+
+#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
+#include "Utility/WasmVirtualRegisters.h"
+
+namespace lldb_private {
+namespace wasm {
+
+/// Each WebAssembly module has separated address spaces for Code and Memory.
+/// A WebAssembly module also has a Data section which, when the module is
+/// loaded, gets mapped into a region in the module Memory.
+enum WasmAddressType : uint8_t { Memory = 0x00, Object = 0x01, Invalid = 0xff };
+
+/// For the purpose of debugging, we can represent all these separated 32-bit
+/// address spaces with a single virtual 64-bit address space. The
+/// wasm_addr_t provides this encoding using bitfields.
+struct wasm_addr_t {
+ uint64_t offset : 32;
+ uint64_t module_id : 30;
+ uint64_t type : 2;
+
+ wasm_addr_t(lldb::addr_t addr)
+ : offset(addr & 0x00000000ffffffff),
+ module_id((addr & 0x00ffffff00000000) >> 32), type(addr >> 62) {}
+
+ wasm_addr_t(WasmAddressType type, uint32_t module_id, uint32_t offset)
+ : offset(offset), module_id(module_id), type(type) {}
+
+ WasmAddressType GetType() { return static_cast<WasmAddressType>(type); }
+
+ operator lldb::addr_t() { return *(uint64_t *)this; }
+};
+
+static_assert(sizeof(wasm_addr_t) == 8, "");
+
+/// ProcessWasm provides the access to the Wasm program state
+/// retrieved from the Wasm engine.
+class ProcessWasm : public process_gdb_remote::ProcessGDBRemote {
+public:
+ ProcessWasm(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
+ ~ProcessWasm() override = default;
+
+ static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const FileSpec *crash_file_path,
+ bool can_connect);
+
+ static void Initialize();
+ static void DebuggerInitialize(Debugger &debugger);
+ static void Terminate();
+
+ static llvm::StringRef GetPluginNameStatic();
+ static llvm::StringRef GetPluginDescriptionStatic();
+
+ llvm::StringRef GetPluginName() override;
+
+ size_t ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
+ Status &error) override;
+
+ bool CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) override;
+
+ /// Retrieve the current call stack from the WebAssembly remote process.
+ llvm::Expected<std::vector<lldb::addr_t>> GetWasmCallStack(lldb::tid_t tid);
+
+ /// Query the value of a WebAssembly variable from the WebAssembly
+ /// remote process.
+ llvm::Expected<lldb::DataBufferSP>
+ GetWasmVariable(WasmVirtualRegisterKinds kind, int frame_index, int index);
+
+protected:
+ std::shared_ptr<process_gdb_remote::ThreadGDBRemote>
+ CreateThread(lldb::tid_t tid) override;
+
+private:
+ friend class UnwindWasm;
+ friend class ThreadWasm;
+
+ process_gdb_remote::GDBRemoteDynamicRegisterInfoSP &GetRegisterInfo() {
+ return m_register_info_sp;
+ }
+
+ ProcessWasm(const ProcessWasm &);
+ const ProcessWasm &operator=(const ProcessWasm &) = delete;
+};
+
+} // namespace wasm
+} // namespace lldb_private
+
+#endif
diff --git a/lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp b/lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp
new file mode 100644
index 0000000..b468171
--- /dev/null
+++ b/lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp
@@ -0,0 +1,109 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "RegisterContextWasm.h"
+#include "Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h"
+#include "ProcessWasm.h"
+#include "ThreadWasm.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "llvm/Support/Error.h"
+#include <memory>
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_gdb_remote;
+using namespace lldb_private::wasm;
+
+RegisterContextWasm::RegisterContextWasm(
+ wasm::ThreadWasm &thread, uint32_t concrete_frame_idx,
+ GDBRemoteDynamicRegisterInfoSP reg_info_sp)
+ : GDBRemoteRegisterContext(thread, concrete_frame_idx, reg_info_sp, false,
+ false) {}
+
+RegisterContextWasm::~RegisterContextWasm() = default;
+
+uint32_t RegisterContextWasm::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ return num;
+}
+
+size_t RegisterContextWasm::GetRegisterCount() {
+ // Wasm has no registers.
+ return 0;
+}
+
+const RegisterInfo *RegisterContextWasm::GetRegisterInfoAtIndex(size_t reg) {
+ uint32_t tag = GetWasmVirtualRegisterTag(reg);
+ if (tag == eWasmTagNotAWasmLocation)
+ return m_reg_info_sp->GetRegisterInfoAtIndex(
+ GetWasmVirtualRegisterIndex(reg));
+
+ auto it = m_register_map.find(reg);
+ if (it == m_register_map.end()) {
+ WasmVirtualRegisterKinds kind = static_cast<WasmVirtualRegisterKinds>(tag);
+ std::tie(it, std::ignore) = m_register_map.insert(
+ {reg, std::make_unique<WasmVirtualRegisterInfo>(
+ kind, GetWasmVirtualRegisterIndex(reg))});
+ }
+ return it->second.get();
+}
+
+size_t RegisterContextWasm::GetRegisterSetCount() { return 0; }
+
+const RegisterSet *RegisterContextWasm::GetRegisterSet(size_t reg_set) {
+ // Wasm has no registers.
+ return nullptr;
+}
+
+bool RegisterContextWasm::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ // The only real registers is the PC.
+ if (reg_info->name)
+ return GDBRemoteRegisterContext::ReadRegister(reg_info, value);
+
+ // Read the virtual registers.
+ ThreadWasm *thread = static_cast<ThreadWasm *>(&GetThread());
+ ProcessWasm *process = static_cast<ProcessWasm *>(thread->GetProcess().get());
+ if (!thread)
+ return false;
+
+ uint32_t frame_index = m_concrete_frame_idx;
+ WasmVirtualRegisterInfo *wasm_reg_info =
+ static_cast<WasmVirtualRegisterInfo *>(
+ const_cast<RegisterInfo *>(reg_info));
+
+ llvm::Expected<DataBufferSP> maybe_buffer = process->GetWasmVariable(
+ wasm_reg_info->kind, frame_index, wasm_reg_info->index);
+ if (!maybe_buffer) {
+ LLDB_LOG_ERROR(GetLog(LLDBLog::Process), maybe_buffer.takeError(),
+ "Failed to read Wasm local: {0}");
+ return false;
+ }
+
+ DataBufferSP buffer_sp = *maybe_buffer;
+ DataExtractor reg_data(buffer_sp, process->GetByteOrder(),
+ process->GetAddressByteSize());
+ wasm_reg_info->byte_size = buffer_sp->GetByteSize();
+ wasm_reg_info->encoding = lldb::eEncodingUint;
+
+ Status error = value.SetValueFromData(
+ *reg_info, reg_data, reg_info->byte_offset, /*partial_data_ok=*/false);
+ return error.Success();
+}
+
+void RegisterContextWasm::InvalidateAllRegisters() {}
+
+bool RegisterContextWasm::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) {
+ // The only real registers is the PC.
+ if (reg_info->name)
+ return GDBRemoteRegisterContext::WriteRegister(reg_info, value);
+ return false;
+}
diff --git a/lldb/source/Plugins/Process/wasm/RegisterContextWasm.h b/lldb/source/Plugins/Process/wasm/RegisterContextWasm.h
new file mode 100644
index 0000000..7e63eb8
--- /dev/null
+++ b/lldb/source/Plugins/Process/wasm/RegisterContextWasm.h
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_WASM_REGISTERCONTEXTWASM_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_WASM_REGISTERCONTEXTWASM_H
+
+#include "Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h"
+#include "ThreadWasm.h"
+#include "Utility/WasmVirtualRegisters.h"
+#include "lldb/lldb-private-types.h"
+#include <unordered_map>
+
+namespace lldb_private {
+namespace wasm {
+
+class RegisterContextWasm;
+
+typedef std::shared_ptr<RegisterContextWasm> RegisterContextWasmSP;
+
+struct WasmVirtualRegisterInfo : public RegisterInfo {
+ WasmVirtualRegisterKinds kind;
+ uint32_t index;
+
+ WasmVirtualRegisterInfo(WasmVirtualRegisterKinds kind, uint32_t index)
+ : RegisterInfo(), kind(kind), index(index) {}
+};
+
+class RegisterContextWasm
+ : public process_gdb_remote::GDBRemoteRegisterContext {
+public:
+ RegisterContextWasm(
+ wasm::ThreadWasm &thread, uint32_t concrete_frame_idx,
+ process_gdb_remote::GDBRemoteDynamicRegisterInfoSP reg_info_sp);
+
+ ~RegisterContextWasm() override;
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
+
+ void InvalidateAllRegisters() override;
+
+ size_t GetRegisterCount() override;
+
+ const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
+
+ size_t GetRegisterSetCount() override;
+
+ const RegisterSet *GetRegisterSet(size_t reg_set) override;
+
+ bool ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) override;
+
+ bool WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) override;
+
+private:
+ std::unordered_map<size_t, std::unique_ptr<WasmVirtualRegisterInfo>>
+ m_register_map;
+};
+
+} // namespace wasm
+} // namespace lldb_private
+
+#endif
diff --git a/lldb/source/Plugins/Process/wasm/ThreadWasm.cpp b/lldb/source/Plugins/Process/wasm/ThreadWasm.cpp
new file mode 100644
index 0000000..0666b75
--- /dev/null
+++ b/lldb/source/Plugins/Process/wasm/ThreadWasm.cpp
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "ThreadWasm.h"
+
+#include "ProcessWasm.h"
+#include "RegisterContextWasm.h"
+#include "UnwindWasm.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::wasm;
+
+Unwind &ThreadWasm::GetUnwinder() {
+ if (!m_unwinder_up) {
+ assert(CalculateTarget()->GetArchitecture().GetMachine() ==
+ llvm::Triple::wasm32);
+ m_unwinder_up.reset(new wasm::UnwindWasm(*this));
+ }
+ return *m_unwinder_up;
+}
+
+llvm::Expected<std::vector<lldb::addr_t>> ThreadWasm::GetWasmCallStack() {
+ if (ProcessSP process_sp = GetProcess()) {
+ ProcessWasm *wasm_process = static_cast<ProcessWasm *>(process_sp.get());
+ return wasm_process->GetWasmCallStack(GetID());
+ }
+ return llvm::createStringError("no process");
+}
+
+lldb::RegisterContextSP
+ThreadWasm::CreateRegisterContextForFrame(StackFrame *frame) {
+ uint32_t concrete_frame_idx = 0;
+ ProcessSP process_sp(GetProcess());
+ ProcessWasm *wasm_process = static_cast<ProcessWasm *>(process_sp.get());
+
+ if (frame)
+ concrete_frame_idx = frame->GetConcreteFrameIndex();
+
+ if (concrete_frame_idx == 0)
+ return std::make_shared<RegisterContextWasm>(
+ *this, concrete_frame_idx, wasm_process->GetRegisterInfo());
+
+ return GetUnwinder().CreateRegisterContextForFrame(frame);
+}
diff --git a/lldb/source/Plugins/Process/wasm/ThreadWasm.h b/lldb/source/Plugins/Process/wasm/ThreadWasm.h
new file mode 100644
index 0000000..c2f5762
--- /dev/null
+++ b/lldb/source/Plugins/Process/wasm/ThreadWasm.h
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_WASM_THREADWASM_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_WASM_THREADWASM_H
+
+#include "Plugins/Process/gdb-remote/ThreadGDBRemote.h"
+
+namespace lldb_private {
+namespace wasm {
+
+/// ProcessWasm provides the access to the Wasm program state
+/// retrieved from the Wasm engine.
+class ThreadWasm : public process_gdb_remote::ThreadGDBRemote {
+public:
+ ThreadWasm(Process &process, lldb::tid_t tid)
+ : process_gdb_remote::ThreadGDBRemote(process, tid) {}
+ ~ThreadWasm() override = default;
+
+ /// Retrieve the current call stack from the WebAssembly remote process.
+ llvm::Expected<std::vector<lldb::addr_t>> GetWasmCallStack();
+
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame(StackFrame *frame) override;
+
+protected:
+ Unwind &GetUnwinder() override;
+
+ ThreadWasm(const ThreadWasm &);
+ const ThreadWasm &operator=(const ThreadWasm &) = delete;
+};
+
+} // namespace wasm
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_WASM_THREADWASM_H
diff --git a/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp b/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp
new file mode 100644
index 0000000..99845dd
--- /dev/null
+++ b/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "UnwindWasm.h"
+#include "Plugins/Process/gdb-remote/ThreadGDBRemote.h"
+#include "ProcessWasm.h"
+#include "ThreadWasm.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace process_gdb_remote;
+using namespace wasm;
+
+class WasmGDBRemoteRegisterContext : public GDBRemoteRegisterContext {
+public:
+ WasmGDBRemoteRegisterContext(ThreadGDBRemote &thread,
+ uint32_t concrete_frame_idx,
+ GDBRemoteDynamicRegisterInfoSP &reg_info_sp,
+ uint64_t pc)
+ : GDBRemoteRegisterContext(thread, concrete_frame_idx, reg_info_sp, false,
+ false) {
+ // Wasm does not have a fixed set of registers but relies on a mechanism
+ // named local and global variables to store information such as the stack
+ // pointer. The only actual register is the PC.
+ PrivateSetRegisterValue(0, pc);
+ }
+};
+
+lldb::RegisterContextSP
+UnwindWasm::DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) {
+ if (m_frames.size() <= frame->GetFrameIndex())
+ return lldb::RegisterContextSP();
+
+ ThreadSP thread = frame->GetThread();
+ ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *>(thread.get());
+ ProcessWasm *wasm_process =
+ static_cast<ProcessWasm *>(thread->GetProcess().get());
+
+ return std::make_shared<WasmGDBRemoteRegisterContext>(
+ *gdb_thread, frame->GetConcreteFrameIndex(),
+ wasm_process->GetRegisterInfo(), m_frames[frame->GetFrameIndex()]);
+}
+
+uint32_t UnwindWasm::DoGetFrameCount() {
+ if (m_unwind_complete)
+ return m_frames.size();
+
+ m_unwind_complete = true;
+ m_frames.clear();
+
+ ThreadWasm &wasm_thread = static_cast<ThreadWasm &>(GetThread());
+ llvm::Expected<std::vector<lldb::addr_t>> call_stack_pcs =
+ wasm_thread.GetWasmCallStack();
+ if (!call_stack_pcs) {
+ LLDB_LOG_ERROR(GetLog(LLDBLog::Unwind), call_stack_pcs.takeError(),
+ "Failed to get Wasm callstack: {0}");
+ m_frames.clear();
+ return 0;
+ }
+
+ m_frames = *call_stack_pcs;
+ return m_frames.size();
+}
+
+bool UnwindWasm::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
+ lldb::addr_t &pc,
+ bool &behaves_like_zeroth_frame) {
+ if (m_frames.size() == 0)
+ DoGetFrameCount();
+
+ if (frame_idx >= m_frames.size())
+ return false;
+
+ behaves_like_zeroth_frame = (frame_idx == 0);
+ cfa = 0;
+ pc = m_frames[frame_idx];
+ return true;
+}
diff --git a/lldb/source/Plugins/Process/wasm/UnwindWasm.h b/lldb/source/Plugins/Process/wasm/UnwindWasm.h
new file mode 100644
index 0000000..ff5e06d
--- /dev/null
+++ b/lldb/source/Plugins/Process/wasm/UnwindWasm.h
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_WASM_UNWINDWASM_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_WASM_UNWINDWASM_H
+
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Unwind.h"
+#include <vector>
+
+namespace lldb_private {
+namespace wasm {
+
+/// UnwindWasm manages stack unwinding for a WebAssembly process.
+class UnwindWasm : public lldb_private::Unwind {
+public:
+ UnwindWasm(lldb_private::Thread &thread) : Unwind(thread) {}
+ ~UnwindWasm() override = default;
+
+protected:
+ void DoClear() override {
+ m_frames.clear();
+ m_unwind_complete = false;
+ }
+
+ uint32_t DoGetFrameCount() override;
+
+ bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
+ lldb::addr_t &pc,
+ bool &behaves_like_zeroth_frame) override;
+
+ lldb::RegisterContextSP
+ DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
+
+private:
+ std::vector<lldb::addr_t> m_frames;
+ bool m_unwind_complete = false;
+
+ UnwindWasm(const UnwindWasm &);
+ const UnwindWasm &operator=(const UnwindWasm &) = delete;
+};
+
+} // namespace wasm
+} // namespace lldb_private
+
+#endif
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt
index db9e11b..0437094 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt
@@ -26,6 +26,7 @@ add_lldb_library(lldbPluginScriptInterpreterPythonInterfaces PLUGIN
ScriptedProcessPythonInterface.cpp
ScriptedPythonInterface.cpp
ScriptedStopHookPythonInterface.cpp
+ ScriptedBreakpointPythonInterface.cpp
ScriptedThreadPlanPythonInterface.cpp
ScriptedThreadPythonInterface.cpp
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp
index 1fd3299..d43036d 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp
@@ -29,6 +29,7 @@ void ScriptInterpreterPythonInterfaces::Initialize() {
ScriptedPlatformPythonInterface::Initialize();
ScriptedProcessPythonInterface::Initialize();
ScriptedStopHookPythonInterface::Initialize();
+ ScriptedBreakpointPythonInterface::Initialize();
ScriptedThreadPlanPythonInterface::Initialize();
}
@@ -37,6 +38,7 @@ void ScriptInterpreterPythonInterfaces::Terminate() {
ScriptedPlatformPythonInterface::Terminate();
ScriptedProcessPythonInterface::Terminate();
ScriptedStopHookPythonInterface::Terminate();
+ ScriptedBreakpointPythonInterface::Terminate();
ScriptedThreadPlanPythonInterface::Terminate();
}
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h
index 26c80b7..02dc065 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h
@@ -16,6 +16,7 @@
#if LLDB_ENABLE_PYTHON
#include "OperatingSystemPythonInterface.h"
+#include "ScriptedBreakpointPythonInterface.h"
#include "ScriptedPlatformPythonInterface.h"
#include "ScriptedProcessPythonInterface.h"
#include "ScriptedStopHookPythonInterface.h"
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.cpp
new file mode 100644
index 0000000..660edaa
--- /dev/null
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.cpp
@@ -0,0 +1,100 @@
+//===----------------------------------------------------------------------===//
+//
+// 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/PluginManager.h"
+#include "lldb/Host/Config.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/lldb-enumerations.h"
+
+#if LLDB_ENABLE_PYTHON
+
+// LLDB Python header must be included first
+#include "../lldb-python.h"
+
+#include "../SWIGPythonBridge.h"
+#include "../ScriptInterpreterPythonImpl.h"
+#include "ScriptedBreakpointPythonInterface.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::python;
+
+ScriptedBreakpointPythonInterface::ScriptedBreakpointPythonInterface(
+ ScriptInterpreterPythonImpl &interpreter)
+ : ScriptedBreakpointInterface(), ScriptedPythonInterface(interpreter) {}
+
+llvm::Expected<StructuredData::GenericSP>
+ScriptedBreakpointPythonInterface::CreatePluginObject(
+ llvm::StringRef class_name, lldb::BreakpointSP break_sp,
+ const StructuredDataImpl &args_sp) {
+ return ScriptedPythonInterface::CreatePluginObject(class_name, nullptr,
+ break_sp, args_sp);
+}
+
+bool ScriptedBreakpointPythonInterface::ResolverCallback(
+ SymbolContext sym_ctx) {
+ Status error;
+
+ StructuredData::ObjectSP obj = Dispatch("__callback__", error, sym_ctx);
+
+ if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
+ error)) {
+ Log *log = GetLog(LLDBLog::Script);
+ LLDB_LOG(log, "Error calling __callback__ method: {1}", error);
+ return true;
+ }
+ return obj->GetBooleanValue();
+}
+
+lldb::SearchDepth ScriptedBreakpointPythonInterface::GetDepth() {
+ Status error;
+ StructuredData::ObjectSP obj = Dispatch("__get_depth__", error);
+
+ if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
+ error)) {
+ return lldb::eSearchDepthModule;
+ }
+ uint64_t value = obj->GetUnsignedIntegerValue();
+ if (value <= lldb::kLastSearchDepthKind)
+ return (lldb::SearchDepth)value;
+ // This is what we were doing on error before, though I'm not sure that's
+ // better than returning eSearchDepthInvalid.
+ return lldb::eSearchDepthModule;
+}
+
+std::optional<std::string> ScriptedBreakpointPythonInterface::GetShortHelp() {
+ Status error;
+ StructuredData::ObjectSP obj = Dispatch("get_short_help", error);
+
+ if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
+ error)) {
+ return {};
+ }
+
+ return obj->GetAsString()->GetValue().str();
+}
+
+void ScriptedBreakpointPythonInterface::Initialize() {
+ const std::vector<llvm::StringRef> ci_usages = {
+ "breakpoint set -P classname [-k key -v value ...]"};
+ const std::vector<llvm::StringRef> api_usages = {
+ "SBTarget.BreakpointCreateFromScript"};
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(),
+ llvm::StringRef("Create a breakpoint that chooses locations based on "
+ "user-created callbacks"),
+ CreateInstance, eScriptLanguagePython, {ci_usages, api_usages});
+}
+
+void ScriptedBreakpointPythonInterface::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+#endif
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.h
new file mode 100644
index 0000000..27bdd871
--- /dev/null
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.h
@@ -0,0 +1,53 @@
+//===-- ScriptedBreakpointPythonInterface.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_PYTHON_INTERFACES_SCRIPTEDBREAKPOINTPYTHONINTERFACE_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDBREAKPOINTPYTHONINTERFACE_H
+
+#include "lldb/Host/Config.h"
+#include "lldb/Interpreter/Interfaces/ScriptedBreakpointInterface.h"
+
+#if LLDB_ENABLE_PYTHON
+
+#include "ScriptedPythonInterface.h"
+
+namespace lldb_private {
+class ScriptedBreakpointPythonInterface : public ScriptedBreakpointInterface,
+ public ScriptedPythonInterface,
+ public PluginInterface {
+public:
+ ScriptedBreakpointPythonInterface(ScriptInterpreterPythonImpl &interpreter);
+
+ llvm::Expected<StructuredData::GenericSP>
+ CreatePluginObject(llvm::StringRef class_name, lldb::BreakpointSP break_sp,
+ const StructuredDataImpl &args_sp) override;
+
+ llvm::SmallVector<AbstractMethodRequirement>
+ GetAbstractMethodRequirements() const override {
+ return llvm::SmallVector<AbstractMethodRequirement>({{"__callback__", 2}});
+ }
+
+ bool ResolverCallback(SymbolContext sym_ctx) override;
+ lldb::SearchDepth GetDepth() override;
+ std::optional<std::string> GetShortHelp() override;
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static llvm::StringRef GetPluginNameStatic() {
+ return "ScriptedBreakpointPythonInterface";
+ }
+
+ llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+};
+} // namespace lldb_private
+
+#endif // LLDB_ENABLE_PYTHON
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDBREAKPOINTPYTHONINTERFACE_H
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
index cf11c06..b49d1d8 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
@@ -17,6 +17,7 @@
#include "../ScriptInterpreterPythonImpl.h"
#include "ScriptedPythonInterface.h"
+#include "lldb/Symbol/SymbolContext.h"
#include <optional>
using namespace lldb;
@@ -80,6 +81,20 @@ ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::StreamSP>(
}
template <>
+SymbolContext
+ScriptedPythonInterface::ExtractValueFromPythonObject<SymbolContext>(
+ python::PythonObject &p, Status &error) {
+ if (lldb::SBSymbolContext *sb_symbol_context =
+ reinterpret_cast<lldb::SBSymbolContext *>(
+ python::LLDBSWIGPython_CastPyObjectToSBSymbolContext(p.get())))
+ return m_interpreter.GetOpaqueTypeFromSBSymbolContext(*sb_symbol_context);
+ error = Status::FromErrorString(
+ "Couldn't cast lldb::SBSymbolContext to lldb_private::SymbolContext.");
+
+ return {};
+}
+
+template <>
lldb::DataExtractorSP
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DataExtractorSP>(
python::PythonObject &p, Status &error) {
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
index b38b65e..f769d3d 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
@@ -432,6 +432,10 @@ protected:
return python::SWIGBridge::ToSWIGWrapper(arg);
}
+ python::PythonObject Transform(lldb::BreakpointSP arg) {
+ return python::SWIGBridge::ToSWIGWrapper(arg);
+ }
+
python::PythonObject Transform(lldb::ProcessSP arg) {
return python::SWIGBridge::ToSWIGWrapper(arg);
}
@@ -452,6 +456,10 @@ protected:
return python::SWIGBridge::ToSWIGWrapper(arg);
}
+ python::PythonObject Transform(const SymbolContext &arg) {
+ return python::SWIGBridge::ToSWIGWrapper(arg);
+ }
+
python::PythonObject Transform(lldb::StreamSP arg) {
return python::SWIGBridge::ToSWIGWrapper(arg.get());
}
@@ -556,6 +564,11 @@ Event *ScriptedPythonInterface::ExtractValueFromPythonObject<Event *>(
python::PythonObject &p, Status &error);
template <>
+SymbolContext
+ScriptedPythonInterface::ExtractValueFromPythonObject<SymbolContext>(
+ python::PythonObject &p, Status &error);
+
+template <>
lldb::StreamSP
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::StreamSP>(
python::PythonObject &p, Status &error);
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
index 504b3aa..4137786 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
@@ -151,15 +151,6 @@ public:
const char *session_dictionary_name,
lldb::DebuggerSP debugger_sp);
- static python::PythonObject LLDBSwigPythonCreateScriptedBreakpointResolver(
- const char *python_class_name, const char *session_dictionary_name,
- const StructuredDataImpl &args, const lldb::BreakpointSP &bkpt_sp);
-
- static unsigned int
- LLDBSwigPythonCallBreakpointResolver(void *implementor,
- const char *method_name,
- lldb_private::SymbolContext *sym_ctx);
-
static size_t LLDBSwigPython_CalculateNumChildren(PyObject *implementor,
uint32_t max);
@@ -270,6 +261,7 @@ void *LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBEvent(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data);
+void *LLDBSWIGPython_CastPyObjectToSBSymbolContext(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBExecutionContext(PyObject *data);
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 457182a..ce77569 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -1550,6 +1550,11 @@ ScriptInterpreterPythonImpl::CreateScriptedStopHookInterface() {
return std::make_shared<ScriptedStopHookPythonInterface>(*this);
}
+ScriptedBreakpointInterfaceSP
+ScriptInterpreterPythonImpl::CreateScriptedBreakpointInterface() {
+ return std::make_shared<ScriptedBreakpointPythonInterface>(*this);
+}
+
ScriptedThreadInterfaceSP
ScriptInterpreterPythonImpl::CreateScriptedThreadInterface() {
return std::make_shared<ScriptedThreadPythonInterface>(*this);
@@ -1576,75 +1581,6 @@ ScriptInterpreterPythonImpl::CreateStructuredDataFromScriptObject(
return py_obj.CreateStructuredObject();
}
-StructuredData::GenericSP
-ScriptInterpreterPythonImpl::CreateScriptedBreakpointResolver(
- const char *class_name, const StructuredDataImpl &args_data,
- lldb::BreakpointSP &bkpt_sp) {
-
- if (class_name == nullptr || class_name[0] == '\0')
- return StructuredData::GenericSP();
-
- if (!bkpt_sp.get())
- return StructuredData::GenericSP();
-
- Debugger &debugger = bkpt_sp->GetTarget().GetDebugger();
- ScriptInterpreterPythonImpl *python_interpreter =
- GetPythonInterpreter(debugger);
-
- if (!python_interpreter)
- return StructuredData::GenericSP();
-
- Locker py_lock(this,
- Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
-
- PythonObject ret_val =
- SWIGBridge::LLDBSwigPythonCreateScriptedBreakpointResolver(
- class_name, python_interpreter->m_dictionary_name.c_str(), args_data,
- bkpt_sp);
-
- return StructuredData::GenericSP(
- new StructuredPythonObject(std::move(ret_val)));
-}
-
-bool ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchCallback(
- StructuredData::GenericSP implementor_sp, SymbolContext *sym_ctx) {
- bool should_continue = false;
-
- if (implementor_sp) {
- Locker py_lock(this,
- Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- should_continue = SWIGBridge::LLDBSwigPythonCallBreakpointResolver(
- implementor_sp->GetValue(), "__callback__", sym_ctx);
- if (PyErr_Occurred()) {
- PyErr_Print();
- PyErr_Clear();
- }
- }
- return should_continue;
-}
-
-lldb::SearchDepth
-ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchDepth(
- StructuredData::GenericSP implementor_sp) {
- int depth_as_int = lldb::eSearchDepthModule;
- if (implementor_sp) {
- Locker py_lock(this,
- Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- depth_as_int = SWIGBridge::LLDBSwigPythonCallBreakpointResolver(
- implementor_sp->GetValue(), "__get_depth__", nullptr);
- if (PyErr_Occurred()) {
- PyErr_Print();
- PyErr_Clear();
- }
- }
- if (depth_as_int == lldb::eSearchDepthInvalid)
- return lldb::eSearchDepthModule;
-
- if (depth_as_int <= lldb::kLastSearchDepthKind)
- return (lldb::SearchDepth)depth_as_int;
- return lldb::eSearchDepthModule;
-}
-
StructuredData::ObjectSP
ScriptInterpreterPythonImpl::LoadPluginModule(const FileSpec &file_spec,
lldb_private::Status &error) {
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
index 5d77608..4698b82a 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -81,17 +81,6 @@ public:
CreateStructuredDataFromScriptObject(ScriptObject obj) override;
StructuredData::GenericSP
- CreateScriptedBreakpointResolver(const char *class_name,
- const StructuredDataImpl &args_data,
- lldb::BreakpointSP &bkpt_sp) override;
- bool ScriptedBreakpointResolverSearchCallback(
- StructuredData::GenericSP implementor_sp,
- SymbolContext *sym_ctx) override;
-
- lldb::SearchDepth ScriptedBreakpointResolverSearchDepth(
- StructuredData::GenericSP implementor_sp) override;
-
- StructuredData::GenericSP
CreateFrameRecognizer(const char *class_name) override;
lldb::ValueObjectListSP
@@ -105,6 +94,9 @@ public:
lldb::ScriptedStopHookInterfaceSP CreateScriptedStopHookInterface() override;
+ lldb::ScriptedBreakpointInterfaceSP
+ CreateScriptedBreakpointInterface() override;
+
lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override;
lldb::ScriptedThreadPlanInterfaceSP
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt b/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
index 212cc36..c3f1bb5 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
+++ b/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
@@ -35,6 +35,7 @@ add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN
SymbolFileDWARF.cpp
SymbolFileDWARFDwo.cpp
SymbolFileDWARFDebugMap.cpp
+ SymbolFileWasm.cpp
UniqueDWARFASTType.cpp
LINK_COMPONENTS
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index ba65f50..e58e28a 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -249,6 +249,14 @@ static unsigned GetCXXMethodCVQuals(const DWARFDIE &subprogram,
return cv_quals;
}
+static std::string MakeLLDBFuncAsmLabel(const DWARFDIE &die) {
+ char const *name = die.GetMangledName(/*substitute_name_allowed*/ false);
+ if (!name)
+ return {};
+
+ return name;
+}
+
TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
const DWARFDIE &die,
Log *log) {
@@ -1231,7 +1239,7 @@ std::pair<bool, TypeSP> DWARFASTParserClang::ParseCXXMethod(
clang::CXXMethodDecl *cxx_method_decl = m_ast.AddMethodToCXXRecordType(
class_opaque_type.GetOpaqueQualType(), attrs.name.GetCString(),
- attrs.mangled_name, clang_type, accessibility, attrs.is_virtual,
+ MakeLLDBFuncAsmLabel(die), clang_type, accessibility, attrs.is_virtual,
is_static, attrs.is_inline, attrs.is_explicit, is_attr_used,
attrs.is_artificial);
@@ -1384,7 +1392,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
ignore_containing_context ? m_ast.GetTranslationUnitDecl()
: containing_decl_ctx,
GetOwningClangModule(die), name, clang_type, attrs.storage,
- attrs.is_inline);
+ attrs.is_inline, MakeLLDBFuncAsmLabel(die));
std::free(name_buf);
if (has_template_params) {
@@ -1394,7 +1402,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
ignore_containing_context ? m_ast.GetTranslationUnitDecl()
: containing_decl_ctx,
GetOwningClangModule(die), attrs.name.GetStringRef(), clang_type,
- attrs.storage, attrs.is_inline);
+ attrs.storage, attrs.is_inline, /*asm_label=*/{});
clang::FunctionTemplateDecl *func_template_decl =
m_ast.CreateFunctionTemplateDecl(
containing_decl_ctx, GetOwningClangModule(die),
@@ -1406,20 +1414,6 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
lldbassert(function_decl);
if (function_decl) {
- // Attach an asm(<mangled_name>) label to the FunctionDecl.
- // This ensures that clang::CodeGen emits function calls
- // using symbols that are mangled according to the DW_AT_linkage_name.
- // If we didn't do this, the external symbols wouldn't exactly
- // match the mangled name LLDB knows about and the IRExecutionUnit
- // would have to fall back to searching object files for
- // approximately matching function names. The motivating
- // example is generating calls to ABI-tagged template functions.
- // This is done separately for member functions in
- // AddMethodToCXXRecordType.
- if (attrs.mangled_name)
- function_decl->addAttr(clang::AsmLabelAttr::CreateImplicit(
- m_ast.getASTContext(), attrs.mangled_name, /*literal=*/false));
-
LinkDeclContextToDIE(function_decl, die);
const clang::FunctionProtoType *function_prototype(
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index a66af5b..94fc2e83 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -736,9 +736,11 @@ DWARFUnit::GetVendorDWARFOpcodeSize(const DataExtractor &data,
bool DWARFUnit::ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes,
lldb::offset_t &offset,
+ RegisterContext *reg_ctx,
+ lldb::RegisterKind reg_kind,
std::vector<Value> &stack) const {
return GetSymbolFileDWARF().ParseVendorDWARFOpcode(op, opcodes, offset,
- stack);
+ reg_ctx, reg_kind, stack);
}
bool DWARFUnit::ParseDWARFLocationList(
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index f55400e..91a6938 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -164,9 +164,11 @@ public:
const lldb::offset_t data_offset,
const uint8_t op) const override;
- bool ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes,
- lldb::offset_t &offset,
- std::vector<Value> &stack) const override;
+ virtual bool ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes,
+ lldb::offset_t &offset,
+ RegisterContext *reg_ctx,
+ lldb::RegisterKind reg_kind,
+ std::vector<Value> &stack) const override;
bool ParseDWARFLocationList(const DataExtractor &data,
DWARFExpressionList &loc_list) const;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 4b4a582..41ab8d1 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -41,6 +41,7 @@
#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
#include "Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h"
+#include "Plugins/SymbolFile/DWARF/SymbolFileWasm.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/CompileUnit.h"
@@ -327,6 +328,9 @@ llvm::StringRef SymbolFileDWARF::GetPluginDescriptionStatic() {
}
SymbolFile *SymbolFileDWARF::CreateInstance(ObjectFileSP objfile_sp) {
+ if (objfile_sp->GetArchitecture().GetTriple().isWasm())
+ return new SymbolFileWasm(std::move(objfile_sp),
+ /*dwo_section_list*/ nullptr);
return new SymbolFileDWARF(std::move(objfile_sp),
/*dwo_section_list*/ nullptr);
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 2dc862c..56d8ccb 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -329,6 +329,8 @@ public:
virtual bool ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes,
lldb::offset_t &offset,
+ RegisterContext *reg_ctx,
+ lldb::RegisterKind reg_kind,
std::vector<Value> &stack) const {
return false;
}
@@ -556,6 +558,7 @@ protected:
/// an index that identifies the .DWO or .o file.
std::optional<uint64_t> m_file_index;
};
+
} // namespace dwarf
} // namespace lldb_private::plugin
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
index c1829ab..52de3ab 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -97,9 +97,11 @@ uint64_t SymbolFileDWARFDwo::GetDebugInfoSize(bool load_all_debug_info) {
}
bool SymbolFileDWARFDwo::ParseVendorDWARFOpcode(
- uint8_t op, const lldb_private::DataExtractor &opcodes,
- lldb::offset_t &offset, std::vector<lldb_private::Value> &stack) const {
- return GetBaseSymbolFile().ParseVendorDWARFOpcode(op, opcodes, offset, stack);
+ uint8_t op, const DataExtractor &opcodes, lldb::offset_t &offset,
+ RegisterContext *reg_ctx, lldb::RegisterKind reg_kind,
+ std::vector<Value> &stack) const {
+ return GetBaseSymbolFile().ParseVendorDWARFOpcode(op, opcodes, offset,
+ reg_ctx, reg_kind, stack);
}
llvm::DenseMap<const DWARFDebugInfoEntry *, Type *> &
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
index 75f5986..1ab6494 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -50,7 +50,8 @@ public:
uint64_t GetDebugInfoSize(bool load_all_debug_info = false) override;
bool ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes,
- lldb::offset_t &offset,
+ lldb::offset_t &offset, RegisterContext *reg_ctx,
+ lldb::RegisterKind reg_kind,
std::vector<Value> &stack) const override;
void FindGlobalVariables(ConstString name,
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.cpp
new file mode 100644
index 0000000..e25a89c
--- /dev/null
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.cpp
@@ -0,0 +1,100 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "SymbolFileWasm.h"
+#include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
+#include "Utility/WasmVirtualRegisters.h"
+#include "lldb/Utility/LLDBLog.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::plugin::dwarf;
+
+SymbolFileWasm::SymbolFileWasm(ObjectFileSP objfile_sp,
+ SectionList *dwo_section_list)
+ : SymbolFileDWARF(objfile_sp, dwo_section_list) {}
+
+SymbolFileWasm::~SymbolFileWasm() = default;
+
+lldb::offset_t
+SymbolFileWasm::GetVendorDWARFOpcodeSize(const DataExtractor &data,
+ const lldb::offset_t data_offset,
+ const uint8_t op) const {
+ if (op != llvm::dwarf::DW_OP_WASM_location)
+ return LLDB_INVALID_OFFSET;
+
+ lldb::offset_t offset = data_offset;
+ const uint8_t wasm_op = data.GetU8(&offset);
+ switch (wasm_op) {
+ case 0: // LOCAL
+ case 1: // GLOBAL_FIXED
+ case 2: // OPERAND_STACK
+ data.GetULEB128(&offset);
+ break;
+ case 3: // GLOBAL_RELOC
+ data.GetU32(&offset);
+ break;
+ default:
+ return LLDB_INVALID_OFFSET;
+ }
+
+ return offset - data_offset;
+}
+
+bool SymbolFileWasm::ParseVendorDWARFOpcode(uint8_t op,
+ const DataExtractor &opcodes,
+ lldb::offset_t &offset,
+ RegisterContext *reg_ctx,
+ lldb::RegisterKind reg_kind,
+ std::vector<Value> &stack) const {
+ if (op != llvm::dwarf::DW_OP_WASM_location)
+ return false;
+
+ uint32_t index = 0;
+ uint8_t tag = eWasmTagNotAWasmLocation;
+
+ /// |DWARF Location Index | WebAssembly Construct |
+ /// |---------------------|-----------------------|
+ /// |0 | Local |
+ /// |1 or 3 | Global |
+ /// |2 | Operand Stack |
+ const uint8_t wasm_op = opcodes.GetU8(&offset);
+ switch (wasm_op) {
+ case 0: // LOCAL
+ index = opcodes.GetULEB128(&offset);
+ tag = eWasmTagLocal;
+ break;
+ case 1: // GLOBAL_FIXED
+ index = opcodes.GetULEB128(&offset);
+ tag = eWasmTagGlobal;
+ break;
+ case 2: // OPERAND_STACK
+ index = opcodes.GetULEB128(&offset);
+ tag = eWasmTagOperandStack;
+ break;
+ case 3: // GLOBAL_RELOC
+ index = opcodes.GetU32(&offset);
+ tag = eWasmTagGlobal;
+ break;
+ default:
+ return false;
+ }
+
+ const uint32_t reg_num = GetWasmRegister(tag, index);
+
+ Value tmp;
+ llvm::Error error = DWARFExpression::ReadRegisterValueAsScalar(
+ reg_ctx, reg_kind, reg_num, tmp);
+ if (error) {
+ LLDB_LOG_ERROR(GetLog(DWARFLog::DebugInfo), std::move(error), "{0}");
+ return false;
+ }
+
+ stack.push_back(tmp);
+ return true;
+}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.h
new file mode 100644
index 0000000..0e0b742
--- /dev/null
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_SYMBOLFILE_DWARF_SYMBOLFILEWASM_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEWASM_H
+
+#include "SymbolFileDWARF.h"
+
+namespace lldb_private::plugin {
+namespace dwarf {
+class SymbolFileWasm : public SymbolFileDWARF {
+public:
+ SymbolFileWasm(lldb::ObjectFileSP objfile_sp, SectionList *dwo_section_list);
+
+ ~SymbolFileWasm() override;
+
+ lldb::offset_t GetVendorDWARFOpcodeSize(const DataExtractor &data,
+ const lldb::offset_t data_offset,
+ const uint8_t op) const override;
+
+ bool ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes,
+ lldb::offset_t &offset, RegisterContext *reg_ctx,
+ lldb::RegisterKind reg_kind,
+ std::vector<Value> &stack) const override;
+};
+} // namespace dwarf
+} // namespace lldb_private::plugin
+
+#endif
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index 702ec5e..8137622 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -88,7 +88,7 @@ struct CreateMethodDecl : public TypeVisitorCallbacks {
MethodOptions::CompilerGenerated;
function_decl = m_clang.AddMethodToCXXRecordType(
parent_ty, proc_name,
- /*mangled_name=*/nullptr, func_ct, /*access=*/access_type,
+ /*asm_label=*/{}, 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);
@@ -903,7 +903,7 @@ PdbAstBuilder::CreateFunctionDecl(PdbCompilandSymId func_id,
if (!function_decl) {
function_decl = m_clang.AddMethodToCXXRecordType(
parent_opaque_ty, func_name,
- /*mangled_name=*/nullptr, func_ct,
+ /*asm_label=*/{}, func_ct,
/*access=*/lldb::AccessType::eAccessPublic,
/*is_virtual=*/false, /*is_static=*/false,
/*is_inline=*/false, /*is_explicit=*/false,
@@ -913,7 +913,7 @@ PdbAstBuilder::CreateFunctionDecl(PdbCompilandSymId func_id,
} else {
function_decl = m_clang.CreateFunctionDeclaration(
parent, OptionalClangModuleID(), func_name, func_ct, func_storage,
- is_inline);
+ is_inline, /*asm_label=*/{});
CreateFunctionParameters(func_id, *function_decl, param_count);
}
return function_decl;
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
index 1f888f4..98b965c 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
@@ -65,7 +65,7 @@ struct CVTagRecord {
}
llvm::StringRef name() const {
- if (m_kind == Struct || m_kind == Union)
+ if (m_kind == Struct || m_kind == Class)
return cvclass.Name;
if (m_kind == Enum)
return cvenum.Name;
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
index 807ee5b..1c575e9 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
@@ -111,9 +111,8 @@ void UdtRecordCompleter::AddMethod(llvm::StringRef name, TypeIndex type_idx,
bool is_artificial = (options & MethodOptions::CompilerGenerated) ==
MethodOptions::CompilerGenerated;
m_ast_builder.clang().AddMethodToCXXRecordType(
- derived_opaque_ty, name.data(), nullptr, method_ct,
- access_type, attrs.isVirtual(), attrs.isStatic(), false, false, false,
- is_artificial);
+ derived_opaque_ty, name.data(), /*asm_label=*/{}, method_ct, access_type,
+ attrs.isVirtual(), attrs.isStatic(), false, false, false, is_artificial);
m_cxx_record_map[derived_opaque_ty].insert({name, method_ct});
}
diff --git a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
index 0090d8f..8b8eac6e 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -954,7 +954,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
auto decl = m_ast.CreateFunctionDeclaration(
decl_context, OptionalClangModuleID(), name,
- type->GetForwardCompilerType(), storage, func->hasInlineAttribute());
+ type->GetForwardCompilerType(), storage, func->hasInlineAttribute(),
+ /*asm_label=*/{});
std::vector<clang::ParmVarDecl *> params;
if (std::unique_ptr<PDBSymbolTypeFunctionSig> sig = func->getSignature()) {
@@ -1446,7 +1447,7 @@ PDBASTParser::AddRecordMethod(lldb_private::SymbolFile &symbol_file,
// TODO: get mangled name for the method.
return m_ast.AddMethodToCXXRecordType(
record_type.GetOpaqueQualType(), name.c_str(),
- /*mangled_name*/ nullptr, method_comp_type, access, method.isVirtual(),
+ /*asm_label=*/{}, method_comp_type, access, method.isVirtual(),
method.isStatic(), method.hasInlineAttribute(),
/*is_explicit*/ false, // FIXME: Need this field in CodeView.
/*is_attr_used*/ false,
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 256952dc..836f9fe 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -2137,7 +2137,7 @@ std::string TypeSystemClang::GetTypeNameForDecl(const NamedDecl *named_decl,
FunctionDecl *TypeSystemClang::CreateFunctionDeclaration(
clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
llvm::StringRef name, const CompilerType &function_clang_type,
- clang::StorageClass storage, bool is_inline) {
+ clang::StorageClass storage, bool is_inline, llvm::StringRef asm_label) {
FunctionDecl *func_decl = nullptr;
ASTContext &ast = getASTContext();
if (!decl_ctx)
@@ -2158,6 +2158,21 @@ FunctionDecl *TypeSystemClang::CreateFunctionDeclaration(
func_decl->setConstexprKind(isConstexprSpecified
? ConstexprSpecKind::Constexpr
: ConstexprSpecKind::Unspecified);
+
+ // Attach an asm(<mangled_name>) label to the FunctionDecl.
+ // This ensures that clang::CodeGen emits function calls
+ // using symbols that are mangled according to the DW_AT_linkage_name.
+ // If we didn't do this, the external symbols wouldn't exactly
+ // match the mangled name LLDB knows about and the IRExecutionUnit
+ // would have to fall back to searching object files for
+ // approximately matching function names. The motivating
+ // example is generating calls to ABI-tagged template functions.
+ // This is done separately for member functions in
+ // AddMethodToCXXRecordType.
+ if (!asm_label.empty())
+ func_decl->addAttr(clang::AsmLabelAttr::CreateImplicit(ast, asm_label,
+ /*literal=*/true));
+
SetOwningModule(func_decl, owning_module);
decl_ctx->addDecl(func_decl);
@@ -7651,7 +7666,7 @@ TypeSystemClang::CreateParameterDeclarations(
clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType(
lldb::opaque_compiler_type_t type, llvm::StringRef name,
- const char *mangled_name, const CompilerType &method_clang_type,
+ llvm::StringRef asm_label, const CompilerType &method_clang_type,
lldb::AccessType access, bool is_virtual, bool is_static, bool is_inline,
bool is_explicit, bool is_attr_used, bool is_artificial) {
if (!type || !method_clang_type.IsValid() || name.empty())
@@ -7784,10 +7799,9 @@ clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType(
if (is_attr_used)
cxx_method_decl->addAttr(clang::UsedAttr::CreateImplicit(getASTContext()));
- if (mangled_name != nullptr) {
+ if (!asm_label.empty())
cxx_method_decl->addAttr(clang::AsmLabelAttr::CreateImplicit(
- getASTContext(), mangled_name, /*literal=*/false));
- }
+ getASTContext(), asm_label, /*literal=*/true));
// Parameters on member function declarations in DWARF generally don't
// have names, so we omit them when creating the ParmVarDecls.
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
index 63dee9d..de66bb68 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -477,7 +477,7 @@ public:
clang::FunctionDecl *CreateFunctionDeclaration(
clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
llvm::StringRef name, const CompilerType &function_Type,
- clang::StorageClass storage, bool is_inline);
+ clang::StorageClass storage, bool is_inline, llvm::StringRef asm_label);
CompilerType
CreateFunctionType(const CompilerType &result_type,
@@ -1001,7 +1001,7 @@ public:
clang::CXXMethodDecl *AddMethodToCXXRecordType(
lldb::opaque_compiler_type_t type, llvm::StringRef name,
- const char *mangled_name, const CompilerType &method_type,
+ llvm::StringRef asm_label, const CompilerType &method_type,
lldb::AccessType access, bool is_virtual, bool is_static, bool is_inline,
bool is_explicit, bool is_attr_used, bool is_artificial);
diff --git a/lldb/source/Target/InstrumentationRuntime.cpp b/lldb/source/Target/InstrumentationRuntime.cpp
index d5a2e2e..7e58e8b 100644
--- a/lldb/source/Target/InstrumentationRuntime.cpp
+++ b/lldb/source/Target/InstrumentationRuntime.cpp
@@ -49,10 +49,10 @@ void InstrumentationRuntime::ModulesDidLoad(
return;
}
- module_list.ForEach([this](const lldb::ModuleSP module_sp) -> bool {
+ module_list.ForEach([this](const lldb::ModuleSP module_sp) {
const FileSpec &file_spec = module_sp->GetFileSpec();
if (!file_spec)
- return true; // Keep iterating.
+ return IterationAction::Continue;
const RegularExpression &runtime_regex = GetPatternForRuntimeLibrary();
if (runtime_regex.Execute(file_spec.GetFilename().GetCString()) ||
@@ -62,11 +62,11 @@ void InstrumentationRuntime::ModulesDidLoad(
Activate();
if (!IsActive())
SetRuntimeModuleSP({}); // Don't cache module if activation failed.
- return false; // Stop iterating, we're done.
+ return IterationAction::Stop;
}
}
- return true;
+ return IterationAction::Continue;
});
}
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index 8000cd0..e9d9c8f 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -2076,6 +2076,13 @@ size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target,
trap_opcode_size = sizeof(g_loongarch_opcode);
} break;
+ case llvm::Triple::wasm32: {
+ // Unreachable (0x00) triggers an unconditional trap.
+ static const uint8_t g_wasm_opcode[] = {0x00};
+ trap_opcode = g_wasm_opcode;
+ trap_opcode_size = sizeof(g_wasm_opcode);
+ } break;
+
default:
return 0;
}
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 86ae7dd..4f39f60 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -36,6 +36,7 @@
#include "lldb/Host/StreamFile.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/Interfaces/ScriptedBreakpointInterface.h"
#include "lldb/Interpreter/Interfaces/ScriptedStopHookInterface.h"
#include "lldb/Interpreter/OptionGroupWatchpoint.h"
#include "lldb/Interpreter/OptionValues.h"
@@ -2487,9 +2488,9 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &orig_module_spec,
ModuleList found_modules;
m_images.FindModules(module_spec_copy, found_modules);
- found_modules.ForEach([&](const ModuleSP &found_module) -> bool {
+ found_modules.ForEach([&](const ModuleSP &found_module) {
old_modules.push_back(found_module);
- return true;
+ return IterationAction::Continue;
});
}
diff --git a/lldb/source/Utility/WasmVirtualRegisters.h b/lldb/source/Utility/WasmVirtualRegisters.h
new file mode 100644
index 0000000..404a5ae
--- /dev/null
+++ b/lldb/source/Utility/WasmVirtualRegisters.h
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_UTILITY_WASM_VIRTUAL_REGISTERS_H
+#define LLDB_SOURCE_UTILITY_WASM_VIRTUAL_REGISTERS_H
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+// LLDB doesn't have an address space to represents WebAssembly locals,
+// globals and operand stacks. We encode these elements into virtual
+// registers:
+//
+// | tag: 2 bits | index: 30 bits |
+//
+// Where tag is:
+// 0: Not a Wasm location
+// 1: Local
+// 2: Global
+// 3: Operand stack value
+enum WasmVirtualRegisterKinds {
+ eWasmTagNotAWasmLocation = 0,
+ eWasmTagLocal = 1,
+ eWasmTagGlobal = 2,
+ eWasmTagOperandStack = 3,
+};
+
+static const uint32_t kWasmVirtualRegisterTagMask = 0x03;
+static const uint32_t kWasmVirtualRegisterIndexMask = 0x3fffffff;
+static const uint32_t kWasmVirtualRegisterTagShift = 30;
+
+inline uint32_t GetWasmVirtualRegisterTag(size_t reg) {
+ return (reg >> kWasmVirtualRegisterTagShift) & kWasmVirtualRegisterTagMask;
+}
+
+inline uint32_t GetWasmVirtualRegisterIndex(size_t reg) {
+ return reg & kWasmVirtualRegisterIndexMask;
+}
+
+inline uint32_t GetWasmRegister(uint8_t tag, uint32_t index) {
+ return ((tag & kWasmVirtualRegisterTagMask) << kWasmVirtualRegisterTagShift) |
+ (index & kWasmVirtualRegisterIndexMask);
+}
+
+} // namespace lldb_private
+
+#endif
diff --git a/lldb/test/API/commands/expression/import-std-module/array/TestArrayFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/array/TestArrayFromStdModule.py
index 1b21fe3..a488276 100644
--- a/lldb/test/API/commands/expression/import-std-module/array/TestArrayFromStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/array/TestArrayFromStdModule.py
@@ -10,6 +10,7 @@ from lldbsuite.test import lldbutil
class TestCase(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
+ @skipIf(macos_version=["<", "15.0"])
@skipUnlessDarwin
def test(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/basic/TestImportStdModule.py b/lldb/test/API/commands/expression/import-std-module/basic/TestImportStdModule.py
index 0632328..0c242d5 100644
--- a/lldb/test/API/commands/expression/import-std-module/basic/TestImportStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/basic/TestImportStdModule.py
@@ -10,6 +10,7 @@ from lldbsuite.test import lldbutil
class ImportStdModule(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
+ @skipIf(macos_version=["<", "15.0"])
def test(self):
self.build()
@@ -38,6 +39,7 @@ class ImportStdModule(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
+ @skipIf(macos_version=["<", "15.0"])
def test_non_cpp_language(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/conflicts/TestStdModuleWithConflicts.py b/lldb/test/API/commands/expression/import-std-module/conflicts/TestStdModuleWithConflicts.py
index 95953de..b3241aa 100644
--- a/lldb/test/API/commands/expression/import-std-module/conflicts/TestStdModuleWithConflicts.py
+++ b/lldb/test/API/commands/expression/import-std-module/conflicts/TestStdModuleWithConflicts.py
@@ -15,6 +15,7 @@ from lldbsuite.test import lldbutil
class TestImportStdModuleConflicts(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
+ @skipIf(macos_version=["<", "15.0"])
def test(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/deque-basic/TestDequeFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/deque-basic/TestDequeFromStdModule.py
index cfc480a..38b8508 100644
--- a/lldb/test/API/commands/expression/import-std-module/deque-basic/TestDequeFromStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/deque-basic/TestDequeFromStdModule.py
@@ -10,6 +10,7 @@ from lldbsuite.test import lldbutil
class TestBasicDeque(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
+ @skipIf(macos_version=["<", "15.0"])
@skipUnlessDarwin
def test(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/deque-dbg-info-content/TestDbgInfoContentDequeFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/deque-dbg-info-content/TestDbgInfoContentDequeFromStdModule.py
index 06f47e5..85eaa8f 100644
--- a/lldb/test/API/commands/expression/import-std-module/deque-dbg-info-content/TestDbgInfoContentDequeFromStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/deque-dbg-info-content/TestDbgInfoContentDequeFromStdModule.py
@@ -11,6 +11,7 @@ class TestDbgInfoContentDeque(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
@skipIf(compiler="clang", compiler_version=["<", "18.0"])
+ @skipIf(macos_version=["<", "15.0"])
@skipUnlessDarwin
def test(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/forward_list-dbg-info-content/TestDbgInfoContentForwardListFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/forward_list-dbg-info-content/TestDbgInfoContentForwardListFromStdModule.py
index d69f0ac..a3a409d 100644
--- a/lldb/test/API/commands/expression/import-std-module/forward_list-dbg-info-content/TestDbgInfoContentForwardListFromStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/forward_list-dbg-info-content/TestDbgInfoContentForwardListFromStdModule.py
@@ -10,6 +10,7 @@ from lldbsuite.test import lldbutil
class TestDbgInfoContentForwardList(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
+ @skipIf(macos_version=["<", "15.0"])
@skipUnlessDarwin
def test(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/forward_list/TestForwardListFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/forward_list/TestForwardListFromStdModule.py
index e3ed8f8..c9f4a15 100644
--- a/lldb/test/API/commands/expression/import-std-module/forward_list/TestForwardListFromStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/forward_list/TestForwardListFromStdModule.py
@@ -10,6 +10,7 @@ from lldbsuite.test import lldbutil
class TestBasicForwardList(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
+ @skipIf(macos_version=["<", "15.0"])
@skipUnlessDarwin
def test(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/iterator/TestIteratorFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/iterator/TestIteratorFromStdModule.py
index 190bc5f..5c82ac3 100644
--- a/lldb/test/API/commands/expression/import-std-module/iterator/TestIteratorFromStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/iterator/TestIteratorFromStdModule.py
@@ -10,6 +10,7 @@ from lldbsuite.test import lldbutil
class TestCase(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
+ @skipIf(macos_version=["<", "15.0"])
@skipUnlessDarwin
def test(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/list-dbg-info-content/TestDbgInfoContentListFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/list-dbg-info-content/TestDbgInfoContentListFromStdModule.py
index 67ea6c6..0ecc244 100644
--- a/lldb/test/API/commands/expression/import-std-module/list-dbg-info-content/TestDbgInfoContentListFromStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/list-dbg-info-content/TestDbgInfoContentListFromStdModule.py
@@ -12,7 +12,7 @@ class TestDbgInfoContentList(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
@skipIf(compiler="clang", compiler_version=["<", "12.0"])
- @skipIf(macos_version=["<", "14.0"])
+ @skipIf(macos_version=["<", "15.0"])
@skipUnlessDarwin
def test(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/list/TestListFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/list/TestListFromStdModule.py
index 85158ee..f29f353 100644
--- a/lldb/test/API/commands/expression/import-std-module/list/TestListFromStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/list/TestListFromStdModule.py
@@ -10,6 +10,7 @@ from lldbsuite.test import lldbutil
class TestBasicList(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
+ @skipIf(macos_version=["<", "15.0"])
@skipUnlessDarwin
def test(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/non-module-type-separation/TestNonModuleTypeSeparation.py b/lldb/test/API/commands/expression/import-std-module/non-module-type-separation/TestNonModuleTypeSeparation.py
index 5558c86..5e0ab48 100644
--- a/lldb/test/API/commands/expression/import-std-module/non-module-type-separation/TestNonModuleTypeSeparation.py
+++ b/lldb/test/API/commands/expression/import-std-module/non-module-type-separation/TestNonModuleTypeSeparation.py
@@ -11,6 +11,7 @@ from lldbsuite.test import lldbutil
class TestCase(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
+ @skipIf(macos_version=["<", "15.0"])
@skipUnlessDarwin
def test(self):
"""
diff --git a/lldb/test/API/commands/expression/import-std-module/retry-with-std-module/TestRetryWithStdModule.py b/lldb/test/API/commands/expression/import-std-module/retry-with-std-module/TestRetryWithStdModule.py
index aa8646b..d003558 100644
--- a/lldb/test/API/commands/expression/import-std-module/retry-with-std-module/TestRetryWithStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/retry-with-std-module/TestRetryWithStdModule.py
@@ -6,6 +6,7 @@ from lldbsuite.test import lldbutil
class TestCase(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
+ @skipIf(macos_version=["<", "15.0"])
def test(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/shared_ptr-dbg-info-content/TestSharedPtrDbgInfoContentFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/shared_ptr-dbg-info-content/TestSharedPtrDbgInfoContentFromStdModule.py
index 85755a6..50419b6 100644
--- a/lldb/test/API/commands/expression/import-std-module/shared_ptr-dbg-info-content/TestSharedPtrDbgInfoContentFromStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/shared_ptr-dbg-info-content/TestSharedPtrDbgInfoContentFromStdModule.py
@@ -10,6 +10,7 @@ from lldbsuite.test import lldbutil
class TestSharedPtrDbgInfoContent(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
+ @skipIf(macos_version=["<", "15.0"])
@skipUnlessDarwin
def test(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/shared_ptr/TestSharedPtrFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/shared_ptr/TestSharedPtrFromStdModule.py
index 35d62ae5..9f04361 100644
--- a/lldb/test/API/commands/expression/import-std-module/shared_ptr/TestSharedPtrFromStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/shared_ptr/TestSharedPtrFromStdModule.py
@@ -11,6 +11,7 @@ class TestSharedPtr(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
@skipIf(compiler="clang", compiler_version=["<", "17.0"])
+ @skipIf(macos_version=["<", "15.0"])
@skipUnlessDarwin
def test(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/unique_ptr-dbg-info-content/TestUniquePtrDbgInfoContent.py b/lldb/test/API/commands/expression/import-std-module/unique_ptr-dbg-info-content/TestUniquePtrDbgInfoContent.py
index e21a4cc..39b720b 100644
--- a/lldb/test/API/commands/expression/import-std-module/unique_ptr-dbg-info-content/TestUniquePtrDbgInfoContent.py
+++ b/lldb/test/API/commands/expression/import-std-module/unique_ptr-dbg-info-content/TestUniquePtrDbgInfoContent.py
@@ -11,6 +11,7 @@ class TestUniquePtrDbgInfoContent(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
@skipIf(compiler="clang", compiler_version=["<", "9.0"])
+ @skipIf(macos_version=["<", "15.0"])
@skipIfLinux # s.reset() causes link errors on ubuntu 18.04/Clang 9
def test(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/unique_ptr/TestUniquePtrFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/unique_ptr/TestUniquePtrFromStdModule.py
index 2952b2e..90384d5 100644
--- a/lldb/test/API/commands/expression/import-std-module/unique_ptr/TestUniquePtrFromStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/unique_ptr/TestUniquePtrFromStdModule.py
@@ -11,6 +11,7 @@ class TestUniquePtr(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
@skipIf(compiler="clang", compiler_version=["<", "9.0"])
+ @skipIf(macos_version=["<", "15.0"])
@skipIfLinux # s.reset() causes link errors on ubuntu 18.04/Clang 9
def test(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/vector-of-vectors/TestVectorOfVectorsFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/vector-of-vectors/TestVectorOfVectorsFromStdModule.py
index 5a168aa..6fa9dd5 100644
--- a/lldb/test/API/commands/expression/import-std-module/vector-of-vectors/TestVectorOfVectorsFromStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/vector-of-vectors/TestVectorOfVectorsFromStdModule.py
@@ -10,6 +10,7 @@ from lldbsuite.test import lldbutil
class TestVectorOfVectors(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
+ @skipIf(macos_version=["<", "15.0"])
@skipUnlessDarwin
def test(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/weak_ptr-dbg-info-content/TestDbgInfoContentWeakPtrFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/weak_ptr-dbg-info-content/TestDbgInfoContentWeakPtrFromStdModule.py
index e95214d..19d24c1 100644
--- a/lldb/test/API/commands/expression/import-std-module/weak_ptr-dbg-info-content/TestDbgInfoContentWeakPtrFromStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/weak_ptr-dbg-info-content/TestDbgInfoContentWeakPtrFromStdModule.py
@@ -11,6 +11,7 @@ class TestDbgInfoContentWeakPtr(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
@skipIf(compiler="clang", compiler_version=["<", "17.0"])
+ @skipIf(macos_version=["<", "15.0"])
@skipUnlessDarwin
def test(self):
self.build()
diff --git a/lldb/test/API/commands/expression/import-std-module/weak_ptr/TestWeakPtrFromStdModule.py b/lldb/test/API/commands/expression/import-std-module/weak_ptr/TestWeakPtrFromStdModule.py
index 0bc0fd4..e3cc9b9 100644
--- a/lldb/test/API/commands/expression/import-std-module/weak_ptr/TestWeakPtrFromStdModule.py
+++ b/lldb/test/API/commands/expression/import-std-module/weak_ptr/TestWeakPtrFromStdModule.py
@@ -11,6 +11,7 @@ class TestSharedPtr(TestBase):
@add_test_categories(["libc++"])
@skipIf(compiler=no_match("clang"))
@skipIf(compiler="clang", compiler_version=["<", "17.0"])
+ @skipIf(macos_version=["<", "15.0"])
@skipUnlessDarwin
def test(self):
self.build()
diff --git a/lldb/test/API/commands/register/register/aarch64_mte_ctrl_register/TestMTECtrlRegister.py b/lldb/test/API/commands/register/register/aarch64_mte_ctrl_register/TestMTECtrlRegister.py
index 2570f26..c003d87 100644
--- a/lldb/test/API/commands/register/register/aarch64_mte_ctrl_register/TestMTECtrlRegister.py
+++ b/lldb/test/API/commands/register/register/aarch64_mte_ctrl_register/TestMTECtrlRegister.py
@@ -34,29 +34,41 @@ class MTECtrlRegisterTestCase(TestBase):
substrs=["stop reason = breakpoint 1."],
)
- def check_mte_ctrl(async_err, sync_err):
+ has_store_only = self.isAArch64MTEStoreOnly()
+
+ def check_mte_ctrl(async_err, sync_err, store_only):
# Bit 0 = tagged addressing enabled
# Bit 1 = synchronous faults
# Bit 2 = asynchronous faults
- value = "0x{:016x}".format((async_err << 2) | (sync_err << 1) | 1)
+ # Bit 19 = store only checking mode
+ value = "0x{:016x}".format(
+ (store_only << 19) | (async_err << 2) | (sync_err << 1) | 1
+ )
expected = [value]
if self.hasXMLSupport():
+ fields = "("
+ if has_store_only:
+ fields += f"STORE_ONLY = {store_only}, "
+
tfc_modes = ["NONE", "SYNC", "ASYNC", "ASYMM"]
- expected.append(
- f"(TAGS = 0, TCF = TCF_{tfc_modes[async_err << 1 | sync_err]}, TAGGED_ADDR_ENABLE = 1)".format(
- async_err, sync_err
- )
- )
+ fields += f"TAGS = 0, TCF = TCF_{tfc_modes[async_err << 1 | sync_err]}, TAGGED_ADDR_ENABLE = 1)"
+
+ expected.append(fields)
self.expect("register read mte_ctrl", substrs=expected)
# We start enabled with synchronous faults.
- check_mte_ctrl(0, 1)
+ check_mte_ctrl(0, 1, 0)
# Change to asynchronous faults.
self.runCmd("register write mte_ctrl 5")
- check_mte_ctrl(1, 0)
+ check_mte_ctrl(1, 0, 0)
# This would return to synchronous faults if we did not restore the
# previous value.
self.expect("expression setup_mte()", substrs=["= 0"])
- check_mte_ctrl(1, 0)
+ check_mte_ctrl(1, 0, 0)
+
+ # Store only checking requires FEAT_MTE_STORE_ONLY.
+ if has_store_only:
+ self.runCmd(f"register write mte_ctrl {1 | (1 << 19)}")
+ check_mte_ctrl(0, 0, 1)
diff --git a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py
index 0a1003a..634940d 100644
--- a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py
+++ b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py
@@ -235,11 +235,13 @@ class TestScriptedResolver(TestBase):
substrs=["2"],
msg="Was only passed modules",
)
-
+ print(f"Made first breakpoint: {bkpt}")
+ bkpt = None
# Make a breakpoint that asks for modules, check that we didn't get any files:
bkpt = target.BreakpointCreateFromScript(
"resolver.ResolverModuleDepth", extra_args, module_list, file_list
)
+ print(f"Made Second breakpoint: {bkpt}")
self.assertGreater(
bkpt.GetNumLocations(), 0, "ResolverModuleDepth got no locations."
)
diff --git a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/resolver.py b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/resolver.py
index 8b91702..85c73401 100644
--- a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/resolver.py
+++ b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/resolver.py
@@ -13,6 +13,7 @@ class Resolver:
Resolver.got_files = 0
def __callback__(self, sym_ctx):
+ print("Resolver callback called")
sym_name = "not_a_real_function_name"
sym_item = self.extra_args.GetValueForKey("symbol")
if sym_item.IsValid():
@@ -34,9 +35,18 @@ class Resolver:
return
if sym_ctx.module.IsValid():
+ print(f"Looking for {sym_name}")
sym = sym_ctx.module.FindSymbol(sym_name, lldb.eSymbolTypeCode)
if sym.IsValid():
+ print(f"Adding location at {sym.GetStartAddress()} to {self.bkpt}")
self.bkpt.AddLocation(sym.GetStartAddress())
+ print(f"After addition: {self.bkpt}")
+ else:
+ print("Didn't find it, however...")
+
+ print(f"GotFiles: {Resolver.got_files}")
+ for func in Resolver.func_list:
+ print(f"Function: func")
def get_short_help(self):
return "I am a python breakpoint resolver"
@@ -46,17 +56,31 @@ class ResolverModuleDepth(Resolver):
def __get_depth__(self):
return lldb.eSearchDepthModule
+ def __callback__(self, sym_ctx):
+ print(f"About to call the Resolver callback for {self.bkpt}")
+ Resolver.__callback__(self, sym_ctx)
+ print("Called the callback for ResolverModuleDepth")
+
class ResolverCUDepth(Resolver):
def __get_depth__(self):
return lldb.eSearchDepthCompUnit
+ def __callback__(self, sym_ctx):
+ Resolver.__callback__(self, sym_ctx)
+
class ResolverFuncDepth(Resolver):
def __get_depth__(self):
return lldb.eSearchDepthFunction
+ def __callback__(self, sym_ctx):
+ Resolver.__callback__(self, sym_ctx)
+
class ResolverBadDepth(Resolver):
def __get_depth__(self):
return lldb.kLastSearchDepthKind + 1
+
+ def __callback__(self, sym_ctx):
+ Resolver.__callback__(self, sym_ctx)
diff --git a/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py b/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py
index 9a70f67..db5b5a0 100644
--- a/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py
+++ b/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py
@@ -692,6 +692,9 @@ class TestGDBServerTargetXML(GDBRemoteTestBase):
"0102030405060708" # t4
"0102030405060708" # t5
"0102030405060708" # t6
+ "6162636465666768" # pc
+ "0000C03F" # ft0
+ "e07a6147a8a40940" # ft1
)
def qXferRead(self, obj, annex, offset, length):
@@ -737,6 +740,10 @@ class TestGDBServerTargetXML(GDBRemoteTestBase):
<reg name="t6" bitsize="64" type="int"/>
<reg name="pc" bitsize="64" type="code_ptr"/>
</feature>
+ <feature name='org.gnu.gdb.riscv.fpu'>
+ <reg name='ft0' bitsize='32' type='ieee_single'/>
+ <reg name='ft1' bitsize='64' type='ieee_double'/>
+ </feature>
</target>""",
False,
)
@@ -799,6 +806,10 @@ class TestGDBServerTargetXML(GDBRemoteTestBase):
self.match("register read x29", ["t4 = 0x0807060504030201"])
self.match("register read x30", ["t5 = 0x0807060504030201"])
self.match("register read x31", ["t6 = 0x0807060504030201"])
+ self.match("register read pc", ["pc = 0x6867666564636261"])
+ # test FPU registers
+ self.match("register read ft0", ["ft0 = 1.5"])
+ self.match("register read ft1", ["ft1 = 3.2053990913985757"])
@skipIfXmlSupportMissing
@skipIfRemote
diff --git a/lldb/test/API/functionalities/gdb_remote_client/TestWasm.py b/lldb/test/API/functionalities/gdb_remote_client/TestWasm.py
index 733f40b..73c81ef 100644
--- a/lldb/test/API/functionalities/gdb_remote_client/TestWasm.py
+++ b/lldb/test/API/functionalities/gdb_remote_client/TestWasm.py
@@ -1,12 +1,14 @@
import lldb
+import os
import binascii
from lldbsuite.test.lldbtest import *
from lldbsuite.test.decorators import *
from lldbsuite.test.gdbclientutils import *
from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
-LLDB_INVALID_ADDRESS = lldb.LLDB_INVALID_ADDRESS
-load_address = 0x400000000
+MODULE_ID = 4
+LOAD_ADDRESS = MODULE_ID << 32
+WASM_LOCAL_ADDR = 0x103E0
def format_register_value(val):
@@ -24,17 +26,68 @@ def format_register_value(val):
return result
+class WasmStackFrame:
+ def __init__(self, address):
+ self._address = address
+
+ def __str__(self):
+ return format_register_value(LOAD_ADDRESS | self._address)
+
+
+class WasmCallStack:
+ def __init__(self, wasm_stack_frames):
+ self._wasm_stack_frames = wasm_stack_frames
+
+ def __str__(self):
+ result = ""
+ for frame in self._wasm_stack_frames:
+ result += str(frame)
+ return result
+
+
+class FakeMemory:
+ def __init__(self, start_addr, end_addr):
+ self._base_addr = start_addr
+ self._memory = bytearray(end_addr - start_addr)
+ self._memoryview = memoryview(self._memory)
+
+ def store_bytes(self, addr, bytes_obj):
+ assert addr > self._base_addr
+ assert addr < self._base_addr + len(self._memoryview)
+ offset = addr - self._base_addr
+ chunk = self._memoryview[offset : offset + len(bytes_obj)]
+ for i in range(len(bytes_obj)):
+ chunk[i] = bytes_obj[i]
+
+ def get_bytes(self, addr, length):
+ assert addr > self._base_addr
+ assert addr < self._base_addr + len(self._memoryview)
+
+ offset = addr - self._base_addr
+ return self._memoryview[offset : offset + length]
+
+ def contains(self, addr):
+ return addr - self._base_addr < len(self._memoryview)
+
+
class MyResponder(MockGDBServerResponder):
- current_pc = load_address + 0x0A
+ current_pc = LOAD_ADDRESS | 0x01AD
- def __init__(self, obj_path, module_name=""):
+ def __init__(self, obj_path, module_name="", wasm_call_stacks=[], memory=None):
self._obj_path = obj_path
self._module_name = module_name or obj_path
+ self._wasm_call_stacks = wasm_call_stacks
+ self._call_stack_request_count = 0
+ self._memory = memory
MockGDBServerResponder.__init__(self)
def respond(self, packet):
if packet[0:13] == "qRegisterInfo":
return self.qRegisterInfo(packet[13:])
+ if packet.startswith("qWasmCallStack"):
+ return self.qWasmCallStack()
+ if packet.startswith("qWasmLocal"):
+ return self.qWasmLocal(packet)
return MockGDBServerResponder.respond(self, packet)
def qSupported(self, client_supported):
@@ -47,7 +100,7 @@ class MyResponder(MockGDBServerResponder):
return ""
def qfThreadInfo(self):
- return "OK"
+ return "m1,"
def qRegisterInfo(self, index):
if index == 0:
@@ -61,7 +114,7 @@ class MyResponder(MockGDBServerResponder):
)
def haltReason(self):
- return "T05thread:1;"
+ return "T02thread:1;"
def readRegister(self, register):
return format_register_value(self.current_pc)
@@ -70,25 +123,62 @@ class MyResponder(MockGDBServerResponder):
if obj == "libraries":
xml = (
'<library-list><library name="%s"><section address="%d"/></library></library-list>'
- % (self._module_name, load_address)
+ % (self._module_name, LOAD_ADDRESS)
)
return xml, False
else:
return None, False
def readMemory(self, addr, length):
- if addr < load_address:
+ if self._memory and self._memory.contains(addr):
+ chunk = self._memory.get_bytes(addr, length)
+ return chunk.hex()
+ if addr < LOAD_ADDRESS:
return "E02"
result = ""
with open(self._obj_path, mode="rb") as file:
file_content = bytearray(file.read())
- addr_from = addr - load_address
+ if addr >= LOAD_ADDRESS + len(file_content):
+ return "E03"
+ addr_from = addr - LOAD_ADDRESS
addr_to = addr_from + min(length, len(file_content) - addr_from)
for i in range(addr_from, addr_to):
result += format(file_content[i], "02x")
file.close()
return result
+ def setBreakpoint(self, packet):
+ bp_data = packet[1:].split(",")
+ self._bp_address = bp_data[1]
+ return "OK"
+
+ def qfThreadInfo(self):
+ return "m1"
+
+ def cont(self):
+ # Continue execution. Simulates running the Wasm engine until a breakpoint is hit.
+ return (
+ "T05thread-pcs:"
+ + format(int(self._bp_address, 16) & 0x3FFFFFFFFFFFFFFF, "x")
+ + ";thread:1"
+ )
+
+ def qWasmCallStack(self):
+ if len(self._wasm_call_stacks) == 0:
+ return ""
+ result = str(self._wasm_call_stacks[self._call_stack_request_count])
+ self._call_stack_request_count += 1
+ return result
+
+ def qWasmLocal(self, packet):
+ # Format: qWasmLocal:frame_index;index
+ data = packet.split(":")
+ data = data[1].split(";")
+ frame_index, local_index = data
+ if frame_index == "0" and local_index == "2":
+ return format_register_value(WASM_LOCAL_ADDR)
+ return "E03"
+
class TestWasm(GDBRemoteTestBase):
@skipIfAsan
@@ -104,7 +194,7 @@ class TestWasm(GDBRemoteTestBase):
self.server.responder = MyResponder(obj_path, "test_wasm")
target = self.dbg.CreateTarget("")
- process = self.connect(target)
+ process = self.connect(target, "wasm")
lldbutil.expect_state_changes(
self, self.dbg.GetListener(), process, [lldb.eStateStopped]
)
@@ -119,35 +209,35 @@ class TestWasm(GDBRemoteTestBase):
code_section = module.GetSectionAtIndex(0)
self.assertEqual("code", code_section.GetName())
self.assertEqual(
- load_address | code_section.GetFileOffset(),
+ LOAD_ADDRESS | code_section.GetFileOffset(),
code_section.GetLoadAddress(target),
)
debug_info_section = module.GetSectionAtIndex(1)
self.assertEqual(".debug_info", debug_info_section.GetName())
self.assertEqual(
- load_address | debug_info_section.GetFileOffset(),
+ LOAD_ADDRESS | debug_info_section.GetFileOffset(),
debug_info_section.GetLoadAddress(target),
)
debug_abbrev_section = module.GetSectionAtIndex(2)
self.assertEqual(".debug_abbrev", debug_abbrev_section.GetName())
self.assertEqual(
- load_address | debug_abbrev_section.GetFileOffset(),
+ LOAD_ADDRESS | debug_abbrev_section.GetFileOffset(),
debug_abbrev_section.GetLoadAddress(target),
)
debug_line_section = module.GetSectionAtIndex(3)
self.assertEqual(".debug_line", debug_line_section.GetName())
self.assertEqual(
- load_address | debug_line_section.GetFileOffset(),
+ LOAD_ADDRESS | debug_line_section.GetFileOffset(),
debug_line_section.GetLoadAddress(target),
)
debug_str_section = module.GetSectionAtIndex(4)
self.assertEqual(".debug_str", debug_str_section.GetName())
self.assertEqual(
- load_address | debug_line_section.GetFileOffset(),
+ LOAD_ADDRESS | debug_line_section.GetFileOffset(),
debug_line_section.GetLoadAddress(target),
)
@@ -174,7 +264,7 @@ class TestWasm(GDBRemoteTestBase):
)
target = self.dbg.CreateTarget("")
- process = self.connect(target)
+ process = self.connect(target, "wasm")
lldbutil.expect_state_changes(
self, self.dbg.GetListener(), process, [lldb.eStateStopped]
)
@@ -189,86 +279,103 @@ class TestWasm(GDBRemoteTestBase):
code_section = module.GetSectionAtIndex(0)
self.assertEqual("code", code_section.GetName())
self.assertEqual(
- load_address | code_section.GetFileOffset(),
+ LOAD_ADDRESS | code_section.GetFileOffset(),
code_section.GetLoadAddress(target),
)
debug_info_section = module.GetSectionAtIndex(1)
self.assertEqual(".debug_info", debug_info_section.GetName())
self.assertEqual(
- LLDB_INVALID_ADDRESS, debug_info_section.GetLoadAddress(target)
+ lldb.LLDB_INVALID_ADDRESS, debug_info_section.GetLoadAddress(target)
)
debug_abbrev_section = module.GetSectionAtIndex(2)
self.assertEqual(".debug_abbrev", debug_abbrev_section.GetName())
self.assertEqual(
- LLDB_INVALID_ADDRESS, debug_abbrev_section.GetLoadAddress(target)
+ lldb.LLDB_INVALID_ADDRESS, debug_abbrev_section.GetLoadAddress(target)
)
debug_line_section = module.GetSectionAtIndex(3)
self.assertEqual(".debug_line", debug_line_section.GetName())
self.assertEqual(
- LLDB_INVALID_ADDRESS, debug_line_section.GetLoadAddress(target)
+ lldb.LLDB_INVALID_ADDRESS, debug_line_section.GetLoadAddress(target)
)
debug_str_section = module.GetSectionAtIndex(4)
self.assertEqual(".debug_str", debug_str_section.GetName())
self.assertEqual(
- LLDB_INVALID_ADDRESS, debug_line_section.GetLoadAddress(target)
+ lldb.LLDB_INVALID_ADDRESS, debug_line_section.GetLoadAddress(target)
)
@skipIfAsan
@skipIfXmlSupportMissing
- def test_load_module_from_file(self):
- """Test connecting to a WebAssembly engine via GDB-remote and loading a Wasm module from a file"""
-
- yaml_path = "test_wasm_embedded_debug_sections.yaml"
- yaml_base, ext = os.path.splitext(yaml_path)
+ def test_simple_wasm_debugging_session(self):
+ """Test connecting to a WebAssembly engine via GDB-remote, loading a
+ Wasm module with embedded DWARF symbols, setting a breakpoint and
+ checking the debuggee state"""
+
+ # simple.yaml was created by compiling simple.c to wasm and using
+ # obj2yaml on the output.
+ #
+ # $ clang -target wasm32 -nostdlib -Wl,--no-entry -Wl,--export-all -O0 -g -o simple.wasm simple.c
+ # $ obj2yaml simple.wasm -o simple.yaml
+ yaml_path = "simple.yaml"
+ yaml_base, _ = os.path.splitext(yaml_path)
obj_path = self.getBuildArtifact(yaml_base)
self.yaml2obj(yaml_path, obj_path)
- self.server.responder = MyResponder(obj_path)
+ # Create a fake call stack.
+ call_stacks = [
+ WasmCallStack(
+ [WasmStackFrame(0x019C), WasmStackFrame(0x01E5), WasmStackFrame(0x01FE)]
+ ),
+ ]
+
+ # Create fake memory for our wasm locals.
+ self.memory = FakeMemory(0x10000, 0x20000)
+ self.memory.store_bytes(
+ WASM_LOCAL_ADDR,
+ bytes.fromhex(
+ "0000000000000000020000000100000000000000020000000100000000000000"
+ ),
+ )
+
+ self.server.responder = MyResponder(
+ obj_path, "test_wasm", call_stacks, self.memory
+ )
target = self.dbg.CreateTarget("")
- process = self.connect(target)
+ breakpoint = target.BreakpointCreateByName("add")
+ process = self.connect(target, "wasm")
lldbutil.expect_state_changes(
self, self.dbg.GetListener(), process, [lldb.eStateStopped]
)
+ location = breakpoint.GetLocationAtIndex(0)
+ self.assertTrue(location and location.IsEnabled(), VALID_BREAKPOINT_LOCATION)
+
num_modules = target.GetNumModules()
self.assertEqual(1, num_modules)
- module = target.GetModuleAtIndex(0)
- num_sections = module.GetNumSections()
- self.assertEqual(5, num_sections)
+ thread = process.GetThreadAtIndex(0)
+ self.assertTrue(thread.IsValid())
- code_section = module.GetSectionAtIndex(0)
- self.assertEqual("code", code_section.GetName())
- self.assertEqual(
- load_address | code_section.GetFileOffset(),
- code_section.GetLoadAddress(target),
- )
+ # Check that our frames match our fake call stack.
+ frame0 = thread.GetFrameAtIndex(0)
+ self.assertTrue(frame0.IsValid())
+ self.assertEqual(frame0.GetPC(), LOAD_ADDRESS | 0x019C)
+ self.assertIn("add", frame0.GetFunctionName())
- debug_info_section = module.GetSectionAtIndex(1)
- self.assertEqual(".debug_info", debug_info_section.GetName())
- self.assertEqual(
- LLDB_INVALID_ADDRESS, debug_info_section.GetLoadAddress(target)
- )
+ frame1 = thread.GetFrameAtIndex(1)
+ self.assertTrue(frame1.IsValid())
+ self.assertEqual(frame1.GetPC(), LOAD_ADDRESS | 0x01E5)
+ self.assertIn("main", frame1.GetFunctionName())
- debug_abbrev_section = module.GetSectionAtIndex(2)
- self.assertEqual(".debug_abbrev", debug_abbrev_section.GetName())
- self.assertEqual(
- LLDB_INVALID_ADDRESS, debug_abbrev_section.GetLoadAddress(target)
- )
+ # Check that we can resolve local variables.
+ a = frame0.FindVariable("a")
+ self.assertTrue(a.IsValid())
+ self.assertEqual(a.GetValueAsUnsigned(), 1)
- debug_line_section = module.GetSectionAtIndex(3)
- self.assertEqual(".debug_line", debug_line_section.GetName())
- self.assertEqual(
- LLDB_INVALID_ADDRESS, debug_line_section.GetLoadAddress(target)
- )
-
- debug_str_section = module.GetSectionAtIndex(4)
- self.assertEqual(".debug_str", debug_str_section.GetName())
- self.assertEqual(
- LLDB_INVALID_ADDRESS, debug_line_section.GetLoadAddress(target)
- )
+ b = frame0.FindVariable("b")
+ self.assertTrue(b.IsValid())
+ self.assertEqual(b.GetValueAsUnsigned(), 2)
diff --git a/lldb/test/API/functionalities/gdb_remote_client/simple.c b/lldb/test/API/functionalities/gdb_remote_client/simple.c
new file mode 100644
index 0000000..62ca1fe
--- /dev/null
+++ b/lldb/test/API/functionalities/gdb_remote_client/simple.c
@@ -0,0 +1,10 @@
+int add(int a, int b) {
+ // Break here
+ return a + b;
+}
+
+int main() {
+ int i = 1;
+ int j = 2;
+ return add(i, j);
+}
diff --git a/lldb/test/API/functionalities/gdb_remote_client/simple.yaml b/lldb/test/API/functionalities/gdb_remote_client/simple.yaml
new file mode 100644
index 0000000..cf1b7d8
--- /dev/null
+++ b/lldb/test/API/functionalities/gdb_remote_client/simple.yaml
@@ -0,0 +1,228 @@
+--- !WASM
+FileHeader:
+ Version: 0x1
+Sections:
+ - Type: TYPE
+ Signatures:
+ - Index: 0
+ ParamTypes: []
+ ReturnTypes: []
+ - Index: 1
+ ParamTypes:
+ - I32
+ - I32
+ ReturnTypes:
+ - I32
+ - Index: 2
+ ParamTypes: []
+ ReturnTypes:
+ - I32
+ - Type: FUNCTION
+ FunctionTypes: [ 0, 1, 2, 1 ]
+ - Type: TABLE
+ Tables:
+ - Index: 0
+ ElemType: FUNCREF
+ Limits:
+ Flags: [ HAS_MAX ]
+ Minimum: 0x1
+ Maximum: 0x1
+ - Type: MEMORY
+ Memories:
+ - Minimum: 0x2
+ - Type: GLOBAL
+ Globals:
+ - Index: 0
+ Type: I32
+ Mutable: true
+ InitExpr:
+ Opcode: I32_CONST
+ Value: 66560
+ - Index: 1
+ Type: I32
+ Mutable: false
+ InitExpr:
+ Opcode: I32_CONST
+ Value: 1024
+ - Index: 2
+ Type: I32
+ Mutable: false
+ InitExpr:
+ Opcode: I32_CONST
+ Value: 1024
+ - Index: 3
+ Type: I32
+ Mutable: false
+ InitExpr:
+ Opcode: I32_CONST
+ Value: 1024
+ - Index: 4
+ Type: I32
+ Mutable: false
+ InitExpr:
+ Opcode: I32_CONST
+ Value: 66560
+ - Index: 5
+ Type: I32
+ Mutable: false
+ InitExpr:
+ Opcode: I32_CONST
+ Value: 1024
+ - Index: 6
+ Type: I32
+ Mutable: false
+ InitExpr:
+ Opcode: I32_CONST
+ Value: 66560
+ - Index: 7
+ Type: I32
+ Mutable: false
+ InitExpr:
+ Opcode: I32_CONST
+ Value: 131072
+ - Index: 8
+ Type: I32
+ Mutable: false
+ InitExpr:
+ Opcode: I32_CONST
+ Value: 0
+ - Index: 9
+ Type: I32
+ Mutable: false
+ InitExpr:
+ Opcode: I32_CONST
+ Value: 1
+ - Index: 10
+ Type: I32
+ Mutable: false
+ InitExpr:
+ Opcode: I32_CONST
+ Value: 65536
+ - Type: EXPORT
+ Exports:
+ - Name: memory
+ Kind: MEMORY
+ Index: 0
+ - Name: __wasm_call_ctors
+ Kind: FUNCTION
+ Index: 0
+ - Name: add
+ Kind: FUNCTION
+ Index: 1
+ - Name: __original_main
+ Kind: FUNCTION
+ Index: 2
+ - Name: main
+ Kind: FUNCTION
+ Index: 3
+ - Name: __main_void
+ Kind: FUNCTION
+ Index: 2
+ - Name: __indirect_function_table
+ Kind: TABLE
+ Index: 0
+ - Name: __dso_handle
+ Kind: GLOBAL
+ Index: 1
+ - Name: __data_end
+ Kind: GLOBAL
+ Index: 2
+ - Name: __stack_low
+ Kind: GLOBAL
+ Index: 3
+ - Name: __stack_high
+ Kind: GLOBAL
+ Index: 4
+ - Name: __global_base
+ Kind: GLOBAL
+ Index: 5
+ - Name: __heap_base
+ Kind: GLOBAL
+ Index: 6
+ - Name: __heap_end
+ Kind: GLOBAL
+ Index: 7
+ - Name: __memory_base
+ Kind: GLOBAL
+ Index: 8
+ - Name: __table_base
+ Kind: GLOBAL
+ Index: 9
+ - Name: __wasm_first_page_end
+ Kind: GLOBAL
+ Index: 10
+ - Type: CODE
+ Functions:
+ - Index: 0
+ Locals: []
+ Body: 0B
+ - Index: 1
+ Locals:
+ - Type: I32
+ Count: 1
+ Body: 23808080800041106B21022002200036020C20022001360208200228020C20022802086A0F0B
+ - Index: 2
+ Locals:
+ - Type: I32
+ Count: 2
+ Body: 23808080800041106B210020002480808080002000410036020C2000410136020820004102360204200028020820002802041081808080002101200041106A24808080800020010F0B
+ - Index: 3
+ Locals: []
+ Body: 1082808080000F0B
+ - Type: CUSTOM
+ Name: .debug_abbrev
+ Payload: 011101250E1305030E10171B0E110155170000022E01110112064018030E3A0B3B0B271949133F1900000305000218030E3A0B3B0B49130000042E01110112064018030E3A0B3B0B49133F1900000534000218030E3A0B3B0B49130000062400030E3E0B0B0B000000
+ - Type: CUSTOM
+ Name: .debug_info
+ Payload: 940000000400000000000401620000001D0055000000000000000D000000000000000000000002050000002900000004ED00029F510000000101900000000302910C60000000010190000000030291085E00000001019000000000042F0000004C00000004ED00009F04000000010690000000050291080B0000000107900000000502910409000000010890000000000600000000050400
+ - Type: CUSTOM
+ Name: .debug_ranges
+ Payload: 050000002E0000002F0000007B0000000000000000000000
+ - Type: CUSTOM
+ Name: .debug_str
+ Payload: 696E74006D61696E006A0069002F55736572732F6A6F6E61732F7761736D2D6D6963726F2D72756E74696D652F70726F647563742D6D696E692F706C6174666F726D732F64617277696E2F6275696C64006164640073696D706C652E630062006100636C616E672076657273696F6E2032322E302E306769742028676974406769746875622E636F6D3A4A4465766C696567686572652F6C6C766D2D70726F6A6563742E67697420343161363839613132323834633834623632383933393461356338306264636534383733656466302900
+ - Type: CUSTOM
+ Name: .debug_line
+ Payload: 62000000040020000000010101FB0E0D0001010101000000010000010073696D706C652E6300000000000005020500000001050A0A08AE050E0658050C5805032002020001010005022F0000001705070A08BB75050E7505110658050A58050382020F000101
+ - Type: CUSTOM
+ Name: name
+ FunctionNames:
+ - Index: 0
+ Name: __wasm_call_ctors
+ - Index: 1
+ Name: add
+ - Index: 2
+ Name: __original_main
+ - Index: 3
+ Name: main
+ GlobalNames:
+ - Index: 0
+ Name: __stack_pointer
+ - Type: CUSTOM
+ Name: producers
+ Languages:
+ - Name: C11
+ Version: ''
+ Tools:
+ - Name: clang
+ Version: '22.0.0git'
+ - Type: CUSTOM
+ Name: target_features
+ Features:
+ - Prefix: USED
+ Name: bulk-memory
+ - Prefix: USED
+ Name: bulk-memory-opt
+ - Prefix: USED
+ Name: call-indirect-overlong
+ - Prefix: USED
+ Name: multivalue
+ - Prefix: USED
+ Name: mutable-globals
+ - Prefix: USED
+ Name: nontrapping-fptoint
+ - Prefix: USED
+ Name: reference-types
+ - Prefix: USED
+ Name: sign-ext
+...
diff --git a/lldb/test/API/functionalities/postmortem/elf-core/expr/TestExpr.py b/lldb/test/API/functionalities/postmortem/elf-core/expr/TestExpr.py
index dd03a0c..9dfc685 100644
--- a/lldb/test/API/functionalities/postmortem/elf-core/expr/TestExpr.py
+++ b/lldb/test/API/functionalities/postmortem/elf-core/expr/TestExpr.py
@@ -37,6 +37,10 @@ class CoreExprTestCase(TestBase):
self.target.EvaluateExpression("int $my_int = 5")
self.expect_expr("$my_int * 2", result_type="int", result_value="10")
+ # Try assigning the persistent variable a new value.
+ self.target.EvaluateExpression("$my_int = 55")
+ self.expect_expr("$my_int", result_type="int", result_value="55")
+
def test_context_object(self):
"""Test expression evaluation in context of an object."""
diff --git a/lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py b/lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py
index bfdc822..825e1a4 100644
--- a/lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py
+++ b/lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py
@@ -10,8 +10,8 @@ from lldbsuite.test.lldbtest import *
class AArch64LinuxMTEMemoryTagCoreFileTestCase(TestBase):
NO_DEBUG_INFO_TESTCASE = True
- MTE_BUF_ADDR = hex(0xFFFF82C74000)
- BUF_ADDR = hex(0xFFFF82C73000)
+ MTE_BUF_ADDR = hex(0xFFFFA733B000)
+ BUF_ADDR = hex(0xFFFFA733A000)
@skipIfLLVMTargetMissing("AArch64")
def test_mte_tag_core_file_memory_region(self):
@@ -215,7 +215,7 @@ class AArch64LinuxMTEMemoryTagCoreFileTestCase(TestBase):
self.expect(
"bt",
substrs=[
- "* thread #1, name = 'a.out.mte', stop reason = SIGSEGV: sync tag check fault (fault address=0xffff82c74010)"
+ "* thread #1, name = 'a.out.mte', stop reason = SIGSEGV: sync tag check fault (fault address=0xffffa733b010)"
],
)
@@ -231,12 +231,15 @@ class AArch64LinuxMTEMemoryTagCoreFileTestCase(TestBase):
self.runCmd("target create --core core.mte")
# The expected value is:
# * Allowed tags value of 0xFFFF, shifted up by 3 resulting in 0x7fff8.
+ # * Bit 19 set to 0, which means that store only checking is disabled.
# * Bit 1 set to enable synchronous tag faults.
# * Bit 0 set to enable the tagged address ABI.
expected = ["mte_ctrl = 0x000000000007fffb"]
if self.hasXMLSupport():
- expected.append("(TAGS = 65535, TCF = TCF_SYNC, TAGGED_ADDR_ENABLE = 1)")
+ expected.append(
+ "(STORE_ONLY = 0, TAGS = 65535, TCF = TCF_SYNC, TAGGED_ADDR_ENABLE = 1)"
+ )
self.expect("register read mte_ctrl", substrs=expected)
diff --git a/lldb/test/API/linux/aarch64/mte_core_file/core.mte b/lldb/test/API/linux/aarch64/mte_core_file/core.mte
index 84a3266..188d06d 100644
--- a/lldb/test/API/linux/aarch64/mte_core_file/core.mte
+++ b/lldb/test/API/linux/aarch64/mte_core_file/core.mte
Binary files differ
diff --git a/lldb/test/API/linux/aarch64/mte_core_file/core.nomte b/lldb/test/API/linux/aarch64/mte_core_file/core.nomte
index 201f288..454ff83 100644
--- a/lldb/test/API/linux/aarch64/mte_core_file/core.nomte
+++ b/lldb/test/API/linux/aarch64/mte_core_file/core.nomte
Binary files differ
diff --git a/lldb/test/API/linux/aarch64/mte_core_file/main.c b/lldb/test/API/linux/aarch64/mte_core_file/main.c
index 6537edd..5974594 100644
--- a/lldb/test/API/linux/aarch64/mte_core_file/main.c
+++ b/lldb/test/API/linux/aarch64/mte_core_file/main.c
@@ -23,7 +23,7 @@
int main(int argc, char const *argv[]) {
#ifdef NO_MTE
- *(char *)(0) = 0;
+ __builtin_trap();
#endif
if (prctl(PR_SET_TAGGED_ADDR_CTRL,
diff --git a/lldb/test/Shell/Commands/command-disassemble-process.yaml b/lldb/test/Shell/Commands/command-disassemble-process.yaml
index ce1b37b..931e0b9 100644
--- a/lldb/test/Shell/Commands/command-disassemble-process.yaml
+++ b/lldb/test/Shell/Commands/command-disassemble-process.yaml
@@ -1,19 +1,20 @@
# REQUIRES: x86
-# RUN: yaml2obj --docnum=1 -DMAIN_SIZE=8 %s -o %T/command-disassemble-process.exe
-# RUN: yaml2obj --docnum=1 -DMAIN_SIZE=8000 %s -o %T/command-disassemble-process.big.exe
+# RUN: mkdir -p %t.dir
+# RUN: yaml2obj --docnum=1 -DMAIN_SIZE=8 %s -o %t.dir/command-disassemble-process.exe
+# RUN: yaml2obj --docnum=1 -DMAIN_SIZE=8000 %s -o %t.dir/command-disassemble-process.big.exe
# RUN: yaml2obj --docnum=2 %s -o %t
-# RUN: %lldb -c %t %T/command-disassemble-process.exe \
+# RUN: %lldb -c %t %t.dir/command-disassemble-process.exe \
# RUN: -o "settings set interpreter.stop-command-source-on-error false" \
# RUN: -s %S/Inputs/command-disassemble-process.lldbinit -o exit \
# RUN: | FileCheck %s
-# RUN: %lldb -c %t %T/command-disassemble-process.big.exe \
+# RUN: %lldb -c %t %t.dir/command-disassemble-process.big.exe \
# RUN: -o "settings set stop-disassembly-max-size 8000" \
# RUN: -o disassemble -o exit 2>&1 | FileCheck %s --check-prefix=BIG
-# RUN: %lldb -c %t %T/command-disassemble-process.exe \
+# RUN: %lldb -c %t %t.dir/command-disassemble-process.exe \
# RUN: -o "settings set interpreter.stop-command-source-on-error false" \
# RUN: -o "disassemble --address 0xdead" -o exit 2>&1 \
# RUN: | FileCheck %s --check-prefix=INVALID
diff --git a/lldb/test/Shell/Commands/command-image-lookup.yaml b/lldb/test/Shell/Commands/command-image-lookup.yaml
index cf7be93..fc12b99 100644
--- a/lldb/test/Shell/Commands/command-image-lookup.yaml
+++ b/lldb/test/Shell/Commands/command-image-lookup.yaml
@@ -1,7 +1,8 @@
-# RUN: yaml2obj %s -o %T/a.out
-# RUN: %lldb %T/a.out -o "image lookup --verbose --address 0x0000000100003fa1" -o exit | FileCheck %s --check-prefix=NOINLINE
-# RUN: %lldb %T/a.out -o "image lookup --verbose --address 0x0000000100003fa2" -o exit | FileCheck %s --check-prefix=INLINE_1
-# RUN: %lldb %T/a.out -o "image lookup --verbose --address 0x0000000100003fa8" -o exit | FileCheck %s --check-prefix=INLINE_2
+# RUN: mkdir -p %t.dir
+# RUN: yaml2obj %s -o %t.dir/a.out
+# RUN: %lldb %t.dir/a.out -o "image lookup --verbose --address 0x0000000100003fa1" -o exit | FileCheck %s --check-prefix=NOINLINE
+# RUN: %lldb %t.dir/a.out -o "image lookup --verbose --address 0x0000000100003fa2" -o exit | FileCheck %s --check-prefix=INLINE_1
+# RUN: %lldb %t.dir/a.out -o "image lookup --verbose --address 0x0000000100003fa8" -o exit | FileCheck %s --check-prefix=INLINE_2
# NOINLINE: Summary: a.out`main + 33 at main.cpp:10
# NOINLINE-NEXT: Module: file =
diff --git a/lldb/test/Shell/Minidump/Windows/arm-fp-unwind.test b/lldb/test/Shell/Minidump/Windows/arm-fp-unwind.test
index 7c056b6..ec70027 100644
--- a/lldb/test/Shell/Minidump/Windows/arm-fp-unwind.test
+++ b/lldb/test/Shell/Minidump/Windows/arm-fp-unwind.test
@@ -2,10 +2,11 @@ Test that unwind plans use the frame pointer register correctly.
REQUIRES: arm
-RUN: yaml2obj %S/Inputs/arm-fp-unwind.exe.yaml -o %T/arm-fp-unwind.exe
-RUN: yaml2obj %S/Inputs/arm-fp-unwind.dmp.yaml -o %T/arm-fp-unwind.dmp
-RUN: %lldb -O "settings set target.exec-search-paths %T" \
-RUN: -c %T/arm-fp-unwind.dmp -o "image show-unwind -a 0x00c71010" -b \
+RUN: mkdir -p %t.dir
+RUN: yaml2obj %S/Inputs/arm-fp-unwind.exe.yaml -o %t.dir/arm-fp-unwind.exe
+RUN: yaml2obj %S/Inputs/arm-fp-unwind.dmp.yaml -o %t.dir/arm-fp-unwind.dmp
+RUN: %lldb -O "settings set target.exec-search-paths %t.dir" \
+RUN: -c %t.dir/arm-fp-unwind.dmp -o "image show-unwind -a 0x00c71010" -b \
RUN: | FileCheck %s
CHECK: Assembly language inspection UnwindPlan:
diff --git a/lldb/test/Shell/Minidump/Windows/broken-unwind.test b/lldb/test/Shell/Minidump/Windows/broken-unwind.test
index 464624b..d8e1866 100644
--- a/lldb/test/Shell/Minidump/Windows/broken-unwind.test
+++ b/lldb/test/Shell/Minidump/Windows/broken-unwind.test
@@ -1,7 +1,8 @@
Test that we can cope with broken unwind information that suggests
reading out of bounds.
-RUN: yaml2obj %S/Inputs/broken-unwind.exe.yaml -o %T/broken-unwind.exe
-RUN: yaml2obj %S/Inputs/broken-unwind.dmp.yaml -o %T/broken-unwind.dmp
-RUN: %lldb -O "settings set target.exec-search-paths %T" \
-RUN: -c %T/broken-unwind.dmp -o "image show-unwind -a 0xb1000" -o exit
+RUN: mkdir -p %t.dir
+RUN: yaml2obj %S/Inputs/broken-unwind.exe.yaml -o %t.dir/broken-unwind.exe
+RUN: yaml2obj %S/Inputs/broken-unwind.dmp.yaml -o %t.dir/broken-unwind.dmp
+RUN: %lldb -O "settings set target.exec-search-paths %t.dir" \
+RUN: -c %t.dir/broken-unwind.dmp -o "image show-unwind -a 0xb1000" -o exit
diff --git a/lldb/test/Shell/Minidump/Windows/find-module.test b/lldb/test/Shell/Minidump/Windows/find-module.test
index 39d9dab..724d524 100644
--- a/lldb/test/Shell/Minidump/Windows/find-module.test
+++ b/lldb/test/Shell/Minidump/Windows/find-module.test
@@ -3,18 +3,19 @@ use it when opening minidumps.
XFAIL: system-windows && remote-linux
-RUN: yaml2obj %S/Inputs/find-module.exe.yaml -o %T/find-module.exe
-RUN: yaml2obj %S/Inputs/find-module.dmp.yaml -o %T/find-module.dmp
-RUN: %lldb -O "settings set target.exec-search-paths %T" \
-RUN: -c %T/find-module.dmp -o "image dump objfile" -o "target list" -o exit \
+RUN: mkdir -p %t.dir
+RUN: yaml2obj %S/Inputs/find-module.exe.yaml -o %t.dir/find-module.exe
+RUN: yaml2obj %S/Inputs/find-module.dmp.yaml -o %t.dir/find-module.dmp
+RUN: %lldb -O "settings set target.exec-search-paths %t.dir" \
+RUN: -c %t.dir/find-module.dmp -o "image dump objfile" -o "target list" -o exit \
RUN: | FileCheck --check-prefix=DEFAULT %s
RUN: %lldb -O "settings set plugin.object-file.pe-coff.abi msvc" \
-RUN: -O "settings set target.exec-search-paths %T" -c %T/find-module.dmp \
+RUN: -O "settings set target.exec-search-paths %t.dir" -c %t.dir/find-module.dmp \
RUN: -o "target list" -o exit | FileCheck --check-prefix=MSVC %s
RUN: %lldb -O "settings set plugin.object-file.pe-coff.abi gnu" \
-RUN: -O "settings set target.exec-search-paths %T" -c %T/find-module.dmp \
+RUN: -O "settings set target.exec-search-paths %t.dir" -c %t.dir/find-module.dmp \
RUN: -o "target list" -o exit | FileCheck --check-prefix=GNU %s
DEFAULT-LABEL: image dump objfile
diff --git a/lldb/test/Shell/Minidump/memory-region-from-module.yaml b/lldb/test/Shell/Minidump/memory-region-from-module.yaml
index 3ebc03c..bc8c899 100644
--- a/lldb/test/Shell/Minidump/memory-region-from-module.yaml
+++ b/lldb/test/Shell/Minidump/memory-region-from-module.yaml
@@ -3,14 +3,14 @@
# RUN: yaml2obj --docnum=1 %s -o %t1.dmp
# RUN: yaml2obj --docnum=2 %s -o %t2.dmp
-# RUN: yaml2obj %S/Inputs/basic-elf.yaml -o %T/memory-region-from-module.exe
+# RUN: yaml2obj %S/Inputs/basic-elf.yaml -o %t.memory-region-from-module.exe
-# RUN: %lldb -b -c %t1.dmp %T/memory-region-from-module.exe \
+# RUN: %lldb -b -c %t1.dmp %t.memory-region-from-module.exe \
# RUN: -o "memory region 0" -o "memory region 0x4000" \
# RUN: -o "memory region 0x5000" -o "memory region 0x6000" \
# RUN: | FileCheck --check-prefix=ALL --check-prefix=CHECK1 %s
-# RUN: %lldb -b -c %t2.dmp %T/memory-region-from-module.exe \
+# RUN: %lldb -b -c %t2.dmp %t.memory-region-from-module.exe \
# RUN: -o "memory region 0" -o "memory region 0x4000" \
# RUN: -o "memory region 0x5000" -o "memory region 0x6000" \
# RUN: | FileCheck --check-prefix=ALL --check-prefix=CHECK2 %s
diff --git a/lldb/test/Shell/ObjectFile/Breakpad/uuid-matching-mac.test b/lldb/test/Shell/ObjectFile/Breakpad/uuid-matching-mac.test
index f2dd2e5..26899ea 100644
--- a/lldb/test/Shell/ObjectFile/Breakpad/uuid-matching-mac.test
+++ b/lldb/test/Shell/ObjectFile/Breakpad/uuid-matching-mac.test
@@ -1,6 +1,7 @@
-# RUN: yaml2obj %S/Inputs/uuid-matching-mac.yaml -o %T/uuid-matching-mac.out
+# RUN: mkdir -p %t.dir
+# RUN: yaml2obj %S/Inputs/uuid-matching-mac.yaml -o %t.dir/uuid-matching-mac.out
# RUN: cd %S
-# RUN: %lldb %T/uuid-matching-mac.out -s %s -o exit | FileCheck %s
+# RUN: %lldb %t.dir/uuid-matching-mac.out -s %s -o exit | FileCheck %s
target symbols add Inputs/uuid-matching-mac.syms
# CHECK-LABEL: target symbols add
diff --git a/lldb/test/Shell/ObjectFile/ELF/minidebuginfo-set-and-hit-breakpoint.test b/lldb/test/Shell/ObjectFile/ELF/minidebuginfo-set-and-hit-breakpoint.test
index a965061..0ffc51a 100644
--- a/lldb/test/Shell/ObjectFile/ELF/minidebuginfo-set-and-hit-breakpoint.test
+++ b/lldb/test/Shell/ObjectFile/ELF/minidebuginfo-set-and-hit-breakpoint.test
@@ -2,8 +2,8 @@
# We want to keep the symbol "multiplyByThree" in the .dynamic section and not
# have it put the default .symtab section.
-# RUN: echo "{multiplyByThree;};" > %T/dynmic-symbols.txt
-# RUN: %clang_host -Wl,--dynamic-list=%T/dynmic-symbols.txt -g -o %t.binary %p/Inputs/minidebuginfo-main.c
+# RUN: echo "{multiplyByThree;};" > %t.dynmic-symbols.txt
+# RUN: %clang_host -Wl,--dynamic-list=%t.dynmic-symbols.txt -g -o %t.binary %p/Inputs/minidebuginfo-main.c
# The following section is adapted from GDB's official documentation:
# http://sourceware.org/gdb/current/onlinedocs/gdb/MiniDebugInfo.html#MiniDebugInfo
diff --git a/lldb/test/Shell/Recognizer/Inputs/ubsan_add_overflow.c b/lldb/test/Shell/Recognizer/Inputs/ubsan_add_overflow.c
new file mode 100644
index 0000000..9f12c32
--- /dev/null
+++ b/lldb/test/Shell/Recognizer/Inputs/ubsan_add_overflow.c
@@ -0,0 +1,3 @@
+#include <limits.h>
+
+int main() { return INT_MAX + 1; }
diff --git a/lldb/test/Shell/Recognizer/ubsan_add_overflow.test b/lldb/test/Shell/Recognizer/ubsan_add_overflow.test
new file mode 100644
index 0000000..9dac039
--- /dev/null
+++ b/lldb/test/Shell/Recognizer/ubsan_add_overflow.test
@@ -0,0 +1,20 @@
+# RUN: %clang_host -g -O0 %S/Inputs/ubsan_add_overflow.c -o %t.out \
+# RUN: -fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow
+
+# RUN: %lldb -b -s %s %t.out | FileCheck %s
+
+run
+# CHECK: thread #{{.*}} stop reason = Undefined Behavior Sanitizer: Integer addition overflowed
+# CHECK-NEXT: frame #1: {{.*}}`main at ubsan_add_overflow.c
+
+bt
+# CHECK: frame #0: {{.*}}`__clang_trap_msg$Undefined Behavior Sanitizer$Integer addition overflowed{{.*}}
+# CHECK: frame #1: {{.*}}`main at ubsan_add_overflow.c
+
+frame info
+# CHECK: frame #{{.*}}`main at ubsan_add_overflow.c
+
+frame recognizer info 0
+# CHECK: frame 0 is recognized by Verbose Trap StackFrame Recognizer
+
+quit \ No newline at end of file
diff --git a/lldb/test/Shell/Scripts/TestFrameworkFixScript.test b/lldb/test/Shell/Scripts/TestFrameworkFixScript.test
index 2b1818e..183ea3a 100644
--- a/lldb/test/Shell/Scripts/TestFrameworkFixScript.test
+++ b/lldb/test/Shell/Scripts/TestFrameworkFixScript.test
@@ -1,6 +1,6 @@
# Create a temp dir for output and run the framework fix script on the truncated version of SBAddress.h in the inputs dir.
RUN: mkdir -p %t/Outputs
-RUN: %python %p/../../../scripts/framework-header-fix.py -f lldb_main -i %p/Inputs/Main/SBAddress.h -o %t/Outputs/SBAddress.h -p /usr/bin/unifdef --unifdef_guards USWIG
+RUN: %python %p/../../../scripts/framework-header-fix.py -f lldb_main -i %p/Inputs/Main/SBAddress.h -o %t/Outputs/SBAddress.h -p /usr/bin/unifdef --unifdef_guards SWIG
# Check the output
RUN: cat %t/Outputs/SBAddress.h | FileCheck %s
diff --git a/lldb/test/Shell/Scripts/TestFrameworkFixUnifdef.test b/lldb/test/Shell/Scripts/TestFrameworkFixUnifdef.test
index ba18b4b..a4fffe4 100644
--- a/lldb/test/Shell/Scripts/TestFrameworkFixUnifdef.test
+++ b/lldb/test/Shell/Scripts/TestFrameworkFixUnifdef.test
@@ -1,7 +1,7 @@
# REQUIRES: system-darwin
# Create a temp dir for output and run the framework fix script on the truncated version of SBAddress.h in the inputs dir.
RUN: mkdir -p %t/Outputs
-RUN: %python %p/../../../scripts/framework-header-fix.py -f lldb_main -i %p/Inputs/Main/SBAddress.h -o %t/Outputs/SBAddress.h -p /usr/bin/unifdef --unifdef_guards USWIG
+RUN: %python %p/../../../scripts/framework-header-fix.py -f lldb_main -i %p/Inputs/Main/SBAddress.h -o %t/Outputs/SBAddress.h -p /usr/bin/unifdef --unifdef_guards SWIG
# Check the output
RUN: cat %t/Outputs/SBAddress.h | FileCheck %s
diff --git a/lldb/test/Shell/Scripts/TestRPCFrameworkFixScript.test b/lldb/test/Shell/Scripts/TestRPCFrameworkFixScript.test
index e2080ca..d7775c2 100644
--- a/lldb/test/Shell/Scripts/TestRPCFrameworkFixScript.test
+++ b/lldb/test/Shell/Scripts/TestRPCFrameworkFixScript.test
@@ -1,6 +1,6 @@
# Create a temp dir for output and run the framework fix script on the truncated version of SBAddress.h in the inputs dir.
RUN: mkdir -p %t/Outputs
-RUN: %python %p/../../../scripts/framework-header-fix.py -f lldb_rpc -i %p/Inputs/RPC/RPCSBAddress.h -o %t/Outputs/RPCSBAddress.h -p /usr/bin/unifdef --unifdef_guards USWIG
+RUN: %python %p/../../../scripts/framework-header-fix.py -f lldb_rpc -i %p/Inputs/RPC/RPCSBAddress.h -o %t/Outputs/RPCSBAddress.h -p /usr/bin/unifdef --unifdef_guards SWIG
# Check the output
RUN: cat %t/Outputs/RPCSBAddress.h | FileCheck %s
diff --git a/lldb/test/Shell/SymbolFile/Breakpad/inline-record.test b/lldb/test/Shell/SymbolFile/Breakpad/inline-record.test
index 280fc961..614a13b 100644
--- a/lldb/test/Shell/SymbolFile/Breakpad/inline-record.test
+++ b/lldb/test/Shell/SymbolFile/Breakpad/inline-record.test
@@ -1,5 +1,6 @@
-# RUN: yaml2obj %S/Inputs/basic-elf.yaml -o %T/inline-record.out
-# RUN: %lldb %T/inline-record.out -o "target symbols add -s inline-record.out %S/Inputs/inline-record.syms" \
+# RUN: mkdir -p %t.dir
+# RUN: yaml2obj %S/Inputs/basic-elf.yaml -o %t.dir/inline-record.out
+# RUN: %lldb %t.dir/inline-record.out -o "target symbols add -s inline-record.out %S/Inputs/inline-record.syms" \
# RUN: -s %s | FileCheck --match-full-lines %s
# CHECK-LABEL: (lldb) image lookup -a 0x400010 -v
diff --git a/lldb/test/Shell/SymbolFile/Breakpad/line-table-discontinuous-file-ids.test b/lldb/test/Shell/SymbolFile/Breakpad/line-table-discontinuous-file-ids.test
index 0780cab..3b4e046 100644
--- a/lldb/test/Shell/SymbolFile/Breakpad/line-table-discontinuous-file-ids.test
+++ b/lldb/test/Shell/SymbolFile/Breakpad/line-table-discontinuous-file-ids.test
@@ -1,7 +1,8 @@
# Test that we handle files which has gaps in the FILE record IDs.
-# RUN: yaml2obj %S/Inputs/basic-elf.yaml -o %T/line-table-discontinuous-file-ids.out
-# RUN: %lldb %T/line-table-discontinuous-file-ids.out \
+# RUN: mkdir -p %t.dir
+# RUN: yaml2obj %S/Inputs/basic-elf.yaml -o %t.dir/line-table-discontinuous-file-ids.out
+# RUN: %lldb %t.dir/line-table-discontinuous-file-ids.out \
# RUN: -o "target symbols add -s line-table-discontinuous-file-ids.out %S/Inputs/line-table-discontinuous-file-ids.syms" \
# RUN: -s %s -o exit | FileCheck %s
diff --git a/lldb/test/Shell/SymbolFile/Breakpad/line-table-edgecases.test b/lldb/test/Shell/SymbolFile/Breakpad/line-table-edgecases.test
index 805f280..f1c631f 100644
--- a/lldb/test/Shell/SymbolFile/Breakpad/line-table-edgecases.test
+++ b/lldb/test/Shell/SymbolFile/Breakpad/line-table-edgecases.test
@@ -2,8 +2,9 @@
# input contains a LINE record which does not belong to any function as well as
# a FUNC record without any LINE records.
-# RUN: yaml2obj %S/Inputs/basic-elf.yaml -o %T/line-table-edgecases.out
-# RUN: %lldb %T/line-table-edgecases.out \
+# RUN: mkdir -p %t.dir
+# RUN: yaml2obj %S/Inputs/basic-elf.yaml -o %t.dir/line-table-edgecases.out
+# RUN: %lldb %t.dir/line-table-edgecases.out \
# RUN: -o "target symbols add -s line-table-edgecases.out %S/Inputs/line-table-edgecases.syms" \
# RUN: -s %s -o exit | FileCheck %s
diff --git a/lldb/test/Shell/SymbolFile/Breakpad/line-table-missing-file.test b/lldb/test/Shell/SymbolFile/Breakpad/line-table-missing-file.test
index 1018d02..e9e1ef4 100644
--- a/lldb/test/Shell/SymbolFile/Breakpad/line-table-missing-file.test
+++ b/lldb/test/Shell/SymbolFile/Breakpad/line-table-missing-file.test
@@ -3,8 +3,9 @@
# Right now, "something reasonable" means creating a line entry with an empty
# file.
-# RUN: yaml2obj %S/Inputs/basic-elf.yaml -o %T/line-table-missing-file.out
-# RUN: %lldb %T/line-table-missing-file.out \
+# RUN: mkdir -p %t.dir
+# RUN: yaml2obj %S/Inputs/basic-elf.yaml -o %t.dir/line-table-missing-file.out
+# RUN: %lldb %t.dir/line-table-missing-file.out \
# RUN: -o "target symbols add -s line-table-missing-file.out %S/Inputs/line-table-missing-file.syms" \
# RUN: -s %s -o exit | FileCheck %s
diff --git a/lldb/test/Shell/SymbolFile/Breakpad/line-table-mixed-path-styles.test b/lldb/test/Shell/SymbolFile/Breakpad/line-table-mixed-path-styles.test
index cb3349f..c299c46 100644
--- a/lldb/test/Shell/SymbolFile/Breakpad/line-table-mixed-path-styles.test
+++ b/lldb/test/Shell/SymbolFile/Breakpad/line-table-mixed-path-styles.test
@@ -1,5 +1,6 @@
-# RUN: yaml2obj %S/Inputs/basic-elf.yaml -o %T/line-table-mixed-path-styles.out
-# RUN: %lldb %T/line-table-mixed-path-styles.out \
+# RUN: mkdir -p %t.dir
+# RUN: yaml2obj %S/Inputs/basic-elf.yaml -o %t.dir/line-table-mixed-path-styles.out
+# RUN: %lldb %t.dir/line-table-mixed-path-styles.out \
# RUN: -o "target symbols add -s line-table-mixed-path-styles.out %S/Inputs/line-table-mixed-path-styles.syms" \
# RUN: -s %s -o exit | FileCheck %s
diff --git a/lldb/test/Shell/SymbolFile/Breakpad/line-table.test b/lldb/test/Shell/SymbolFile/Breakpad/line-table.test
index 2099571..c0c6e90 100644
--- a/lldb/test/Shell/SymbolFile/Breakpad/line-table.test
+++ b/lldb/test/Shell/SymbolFile/Breakpad/line-table.test
@@ -1,5 +1,6 @@
-# RUN: yaml2obj %S/Inputs/basic-elf.yaml -o %T/line-table.out
-# RUN: %lldb %T/line-table.out -o "target symbols add -s line-table.out %S/Inputs/line-table.syms" \
+# RUN: mkdir -p %t.dir
+# RUN: yaml2obj %S/Inputs/basic-elf.yaml -o %t.dir/line-table.out
+# RUN: %lldb %t.dir/line-table.out -o "target symbols add -s line-table.out %S/Inputs/line-table.syms" \
# RUN: -s %s -o exit | FileCheck %s
# We create a compile unit for each function. The compile unit name is the first
diff --git a/lldb/test/Shell/SymbolFile/Breakpad/symtab-macho.test b/lldb/test/Shell/SymbolFile/Breakpad/symtab-macho.test
index ebfc31c..90f3c53 100644
--- a/lldb/test/Shell/SymbolFile/Breakpad/symtab-macho.test
+++ b/lldb/test/Shell/SymbolFile/Breakpad/symtab-macho.test
@@ -1,5 +1,6 @@
-# RUN: yaml2obj %S/Inputs/basic-macho.yaml -o %T/symtab-macho.out
-# RUN: %lldb %T/symtab-macho.out -o "target symbols add %S/Inputs/symtab-macho.syms" \
+# RUN: mkdir -p %t.dir
+# RUN: yaml2obj %S/Inputs/basic-macho.yaml -o %t.dir/symtab-macho.out
+# RUN: %lldb %t.dir/symtab-macho.out -o "target symbols add %S/Inputs/symtab-macho.syms" \
# RUN: -s %s | FileCheck %s
image dump symtab symtab-macho.out
diff --git a/lldb/test/Shell/SymbolFile/Breakpad/symtab-sorted-by-size.test b/lldb/test/Shell/SymbolFile/Breakpad/symtab-sorted-by-size.test
index 00e04eb3..5aedbb4 100644
--- a/lldb/test/Shell/SymbolFile/Breakpad/symtab-sorted-by-size.test
+++ b/lldb/test/Shell/SymbolFile/Breakpad/symtab-sorted-by-size.test
@@ -1,5 +1,6 @@
-# RUN: yaml2obj %S/Inputs/basic-elf.yaml -o %T/symtab-sorted-by-size.out
-# RUN: %lldb %T/symtab-sorted-by-size.out -o "target symbols add -s symtab-sorted-by-size.out %S/Inputs/symtab.syms" \
+# RUN: mkdir -p %t.dir
+# RUN: yaml2obj %S/Inputs/basic-elf.yaml -o %t.dir/symtab-sorted-by-size.out
+# RUN: %lldb %t.dir/symtab-sorted-by-size.out -o "target symbols add -s symtab-sorted-by-size.out %S/Inputs/symtab.syms" \
# RUN: -s %s | FileCheck %s
# CHECK: num_symbols = 4 (sorted by size):
diff --git a/lldb/test/Shell/SymbolFile/Breakpad/symtab.test b/lldb/test/Shell/SymbolFile/Breakpad/symtab.test
index a32eb58..0187ba3 100644
--- a/lldb/test/Shell/SymbolFile/Breakpad/symtab.test
+++ b/lldb/test/Shell/SymbolFile/Breakpad/symtab.test
@@ -1,5 +1,6 @@
-# RUN: yaml2obj %S/Inputs/basic-elf.yaml -o %T/symtab.out
-# RUN: %lldb %T/symtab.out -o "target symbols add -s symtab.out %S/Inputs/symtab.syms" \
+# RUN: mkdir -p %t.dir
+# RUN: yaml2obj %S/Inputs/basic-elf.yaml -o %t.dir/symtab.out
+# RUN: %lldb %t.dir/symtab.out -o "target symbols add -s symtab.out %S/Inputs/symtab.syms" \
# RUN: -s %s | FileCheck %s
# CHECK-LABEL: (lldb) image dump symtab symtab.out
diff --git a/lldb/test/Shell/SymbolFile/Breakpad/unwind-via-stack-win-no-memory-info.yaml b/lldb/test/Shell/SymbolFile/Breakpad/unwind-via-stack-win-no-memory-info.yaml
index 8981c84..fbf7c14 100644
--- a/lldb/test/Shell/SymbolFile/Breakpad/unwind-via-stack-win-no-memory-info.yaml
+++ b/lldb/test/Shell/SymbolFile/Breakpad/unwind-via-stack-win-no-memory-info.yaml
@@ -1,8 +1,9 @@
# REQUIRES: x86
# RUN: yaml2obj --docnum=1 %s -o %t.dmp
-# RUN: yaml2obj --docnum=2 %s -o %T/unwind-via-stack-win-no-memory-info.exe
-# RUN: %lldb -c %t.dmp %T/unwind-via-stack-win-no-memory-info.exe \
+# RUN: mkdir -p %t.dir
+# RUN: yaml2obj --docnum=2 %s -o %t.dir/unwind-via-stack-win-no-memory-info.exe
+# RUN: %lldb -c %t.dmp %t.dir/unwind-via-stack-win-no-memory-info.exe \
# RUN: -o "target symbols add %S/Inputs/unwind-via-raSearch.syms" \
# RUN: -o "thread backtrace" -b | FileCheck %s
diff --git a/lldb/test/Shell/SymbolFile/DWARF/dwo-missing-error.test b/lldb/test/Shell/SymbolFile/DWARF/dwo-missing-error.test
index 4f7e70e..2805bbb 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/dwo-missing-error.test
+++ b/lldb/test/Shell/SymbolFile/DWARF/dwo-missing-error.test
@@ -9,7 +9,6 @@
# Creating and compiling to %t.compdir makes it easy to remove the dwo files.
# DW_AT_comp_dir should be "./a/b/", and DW_AT_dwo_name should be
# "a.out-dwo-missing-error.dwo".
-# since %T is deprecated.
# RUN: rm -rf %t.compdir/
# RUN: mkdir -p %t.compdir/a/b/
# RUN: cd %t.compdir/a/b/
diff --git a/lldb/test/Shell/SymbolFile/DWARF/dwo-relative-path.s b/lldb/test/Shell/SymbolFile/DWARF/dwo-relative-path.s
index f3d4457..2c9c584 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/dwo-relative-path.s
+++ b/lldb/test/Shell/SymbolFile/DWARF/dwo-relative-path.s
@@ -3,12 +3,13 @@
# REQUIRES: x86
-# RUN: llvm-mc --filetype=obj --triple x86_64-pc-linux %s -o %t.o
-# RUN: llvm-objcopy --split-dwo=%T/dwo-relative-path.dwo %t.o
+# RUN: mkdir -p %t.dir
+# RUN: llvm-mc --filetype=obj --triple x86_64-pc-linux %s -o %t.dir/obj.o
+# RUN: llvm-objcopy --split-dwo=%t.dir/dwo-relative-path.dwo %t.dir/obj.o
# RUN: cd ../..
-# RUN: %lldb %t.o -o "target var x" -b 2>&1 | FileCheck %s
+# RUN: %lldb %t.dir/obj.o -o "target var x" -b 2>&1 | FileCheck %s
# CHECK: x = 10
diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwo.s b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwo.s
index 393c045..b67c001 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwo.s
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwo.s
@@ -1,4 +1,5 @@
-# RUN: cd %T
+# RUN: mkdir -p %t.dir
+# RUN: cd %t.dir
# RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %s >debug_loclists-dwo.o
# RUN: %lldb debug_loclists-dwo.o -o "image lookup -v -s lookup_loclists" -o exit | FileCheck %s
diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_rnglists-dwo.s b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_rnglists-dwo.s
index edc8345..7089be1 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_rnglists-dwo.s
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_rnglists-dwo.s
@@ -1,4 +1,5 @@
-# RUN: cd %T
+# RUN: mkdir -p %t.dir
+# RUN: cd %t.dir
# RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %s >debug_rnglists-dwo.o
# RUN: %lldb debug_rnglists-dwo.o -o "image lookup -v -s lookup_rnglists" \
# RUN: -o exit | FileCheck %s
diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/dwo-type-in-main-file.s b/lldb/test/Shell/SymbolFile/DWARF/x86/dwo-type-in-main-file.s
index 6c63912..5ef85b9f 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/dwo-type-in-main-file.s
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/dwo-type-in-main-file.s
@@ -2,10 +2,10 @@
# type, but that type is defined in another compile unit in the main object
# file.
-# RUN: llvm-mc %s -o %t --triple=x86_64-pc-linux --filetype=obj --defsym MAIN=0
-# RUN: llvm-mc %s -o %T/dwo-type-in-main-file-cu2.dwo --triple=x86_64-pc-linux --filetype=obj --defsym DWO=0
-# RUN: cd %T
-# RUN: %lldb %t -o "target var a" -b 2>&1 | FileCheck %s
+# RUN: mkdir -p %t.dir
+# RUN: llvm-mc %s -o %t.dir/obj.o --triple=x86_64-pc-linux --filetype=obj --defsym MAIN=0
+# RUN: llvm-mc %s -o %t.dir/dwo-type-in-main-file-cu2.dwo --triple=x86_64-pc-linux --filetype=obj --defsym DWO=0
+# RUN: %lldb %t.dir/obj.o -o "target var a" -b 2>&1 | FileCheck %s
# CHECK: (A) a = (b = 47)
diff --git a/lldb/test/Shell/SymbolFile/PDB/class-layout.test b/lldb/test/Shell/SymbolFile/PDB/class-layout.test
index efd52b8..e9a7d1c 100644
--- a/lldb/test/Shell/SymbolFile/PDB/class-layout.test
+++ b/lldb/test/Shell/SymbolFile/PDB/class-layout.test
@@ -1,16 +1,17 @@
REQUIRES: target-windows, msvc
-RUN: %build --compiler=clang-cl --mode=compile --arch=32 --nodefaultlib --output=%T/ClassLayoutTest.cpp.obj %S/Inputs/ClassLayoutTest.cpp
-RUN: %build --compiler=msvc --mode=link --arch=32 --nodefaultlib --output=%T/ClassLayoutTest.cpp.exe %T/ClassLayoutTest.cpp.obj
-RUN: lldb-test symbols %T/ClassLayoutTest.cpp.exe | FileCheck %s
-RUN: lldb-test symbols %T/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=ENUM %s
-RUN: lldb-test symbols %T/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=UNION %s
-RUN: lldb-test symbols %T/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=STRUCT %s
-RUN: lldb-test symbols %T/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=COMPLEX %s
-RUN: lldb-test symbols %T/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=LIST %s
-RUN: lldb-test symbols %T/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=UNNAMED-STRUCT %s
-RUN: lldb-test symbols %T/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=BASE %s
-RUN: lldb-test symbols %T/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=FRIEND %s
-RUN: lldb-test symbols %T/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=CLASS %s
+RUN: mkdir -p %t.dir
+RUN: %build --compiler=clang-cl --mode=compile --arch=32 --nodefaultlib --output=%t.dir/ClassLayoutTest.cpp.obj %S/Inputs/ClassLayoutTest.cpp
+RUN: %build --compiler=msvc --mode=link --arch=32 --nodefaultlib --output=%t.dir/ClassLayoutTest.cpp.exe %t.dir/ClassLayoutTest.cpp.obj
+RUN: lldb-test symbols %t.dir/ClassLayoutTest.cpp.exe | FileCheck %s
+RUN: lldb-test symbols %t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=ENUM %s
+RUN: lldb-test symbols %t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=UNION %s
+RUN: lldb-test symbols %t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=STRUCT %s
+RUN: lldb-test symbols %t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=COMPLEX %s
+RUN: lldb-test symbols %t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=LIST %s
+RUN: lldb-test symbols %t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=UNNAMED-STRUCT %s
+RUN: lldb-test symbols %t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=BASE %s
+RUN: lldb-test symbols %t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=FRIEND %s
+RUN: lldb-test symbols %t.dir/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=CLASS %s
CHECK: Module [[MOD:.*]]
CHECK: SymbolFile pdb ([[MOD]])
diff --git a/lldb/test/Shell/SymbolFile/PDB/compilands.test b/lldb/test/Shell/SymbolFile/PDB/compilands.test
index 6ea9082..ed28256 100644
--- a/lldb/test/Shell/SymbolFile/PDB/compilands.test
+++ b/lldb/test/Shell/SymbolFile/PDB/compilands.test
@@ -1,8 +1,9 @@
REQUIRES: target-windows, msvc
-RUN: %build --compiler=clang-cl --mode=compile --arch=32 --nodefaultlib --output=%T/CompilandsTest.cpp.obj %S/Inputs/CompilandsTest.cpp
-RUN: %build --compiler=msvc --mode=link --arch=32 --nodefaultlib --output=%T/CompilandsTest.cpp.exe %T/CompilandsTest.cpp.obj
-RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols %T/CompilandsTest.cpp.exe | FileCheck %s
-RUN: lldb-test symbols %T/CompilandsTest.cpp.exe | FileCheck %s
+RUN: mkdir -p %t.dir
+RUN: %build --compiler=clang-cl --mode=compile --arch=32 --nodefaultlib --output=%t.dir/CompilandsTest.cpp.obj %S/Inputs/CompilandsTest.cpp
+RUN: %build --compiler=msvc --mode=link --arch=32 --nodefaultlib --output=%t.dir/CompilandsTest.cpp.exe %t.dir/CompilandsTest.cpp.obj
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols %t.dir/CompilandsTest.cpp.exe | FileCheck %s
+RUN: lldb-test symbols %t.dir/CompilandsTest.cpp.exe | FileCheck %s
; Link default libraries
diff --git a/lldb/test/Shell/SymbolFile/PDB/enums-layout.test b/lldb/test/Shell/SymbolFile/PDB/enums-layout.test
index ad7d154..6f861c6d 100644
--- a/lldb/test/Shell/SymbolFile/PDB/enums-layout.test
+++ b/lldb/test/Shell/SymbolFile/PDB/enums-layout.test
@@ -1,11 +1,12 @@
REQUIRES: system-windows, msvc
-RUN: %build --compiler=msvc --arch=32 --nodefaultlib --output=%T/SimpleTypesTest.cpp.enums.exe %S/Inputs/SimpleTypesTest.cpp
-RUN: lldb-test symbols %T/SimpleTypesTest.cpp.enums.exe | FileCheck --check-prefix=ENUM %s
-RUN: lldb-test symbols %T/SimpleTypesTest.cpp.enums.exe | FileCheck --check-prefix=CONST-ENUM %s
-RUN: lldb-test symbols %T/SimpleTypesTest.cpp.enums.exe | FileCheck --check-prefix=EMPTY-ENUM %s
-RUN: lldb-test symbols %T/SimpleTypesTest.cpp.enums.exe | FileCheck --check-prefix=UCHAR-ENUM %s
-RUN: lldb-test symbols %T/SimpleTypesTest.cpp.enums.exe | FileCheck --check-prefix=CLASS-ENUM %s
-RUN: lldb-test symbols %T/SimpleTypesTest.cpp.enums.exe | FileCheck --check-prefix=STRUCT-ENUM %s
+RUN: mkdir -p %t.dir
+RUN: %build --compiler=msvc --arch=32 --nodefaultlib --output=%t.dir/SimpleTypesTest.cpp.enums.exe %S/Inputs/SimpleTypesTest.cpp
+RUN: lldb-test symbols %t.dir/SimpleTypesTest.cpp.enums.exe | FileCheck --check-prefix=ENUM %s
+RUN: lldb-test symbols %t.dir/SimpleTypesTest.cpp.enums.exe | FileCheck --check-prefix=CONST-ENUM %s
+RUN: lldb-test symbols %t.dir/SimpleTypesTest.cpp.enums.exe | FileCheck --check-prefix=EMPTY-ENUM %s
+RUN: lldb-test symbols %t.dir/SimpleTypesTest.cpp.enums.exe | FileCheck --check-prefix=UCHAR-ENUM %s
+RUN: lldb-test symbols %t.dir/SimpleTypesTest.cpp.enums.exe | FileCheck --check-prefix=CLASS-ENUM %s
+RUN: lldb-test symbols %t.dir/SimpleTypesTest.cpp.enums.exe | FileCheck --check-prefix=STRUCT-ENUM %s
; FIXME: PDB does not have information about scoped enumeration (Enum class) so the
; compiler type used is the same as the one for unscoped enumeration.
diff --git a/lldb/test/Shell/SymbolFile/PDB/func-symbols.test b/lldb/test/Shell/SymbolFile/PDB/func-symbols.test
index 95e0dd5e..408db14 100644
--- a/lldb/test/Shell/SymbolFile/PDB/func-symbols.test
+++ b/lldb/test/Shell/SymbolFile/PDB/func-symbols.test
@@ -1,7 +1,8 @@
REQUIRES: target-windows, lld
-RUN: %build --compiler=clang-cl --arch=32 --nodefaultlib --output=%T/FuncSymbolsTest.exe %S/Inputs/FuncSymbolsTestMain.cpp %S/Inputs/FuncSymbols.cpp
-RUN: lldb-test symbols %T/FuncSymbolsTest.exe | FileCheck --check-prefix=CHECK-ONE %s
-RUN: lldb-test symbols %T/FuncSymbolsTest.exe | FileCheck --check-prefix=CHECK-TWO %s
+RUN: mkdir -p %t.dir
+RUN: %build --compiler=clang-cl --arch=32 --nodefaultlib --output=%t.dir/FuncSymbolsTest.exe %S/Inputs/FuncSymbolsTestMain.cpp %S/Inputs/FuncSymbols.cpp
+RUN: lldb-test symbols %t.dir/FuncSymbolsTest.exe | FileCheck --check-prefix=CHECK-ONE %s
+RUN: lldb-test symbols %t.dir/FuncSymbolsTest.exe | FileCheck --check-prefix=CHECK-TWO %s
; Link multiple objects
; In this test, We don't check demangled name of a mangled function.
diff --git a/lldb/test/Shell/SymbolFile/PDB/pointers.test b/lldb/test/Shell/SymbolFile/PDB/pointers.test
index 355b5fa..29fe171 100644
--- a/lldb/test/Shell/SymbolFile/PDB/pointers.test
+++ b/lldb/test/Shell/SymbolFile/PDB/pointers.test
@@ -1,11 +1,12 @@
REQUIRES: target-windows, msvc
-RUN: %build --compiler=clang-cl --mode=compile --arch=32 --nodefaultlib --output=%T/PointerTypeTest.cpp.obj %S/Inputs/PointerTypeTest.cpp
-RUN: %build --compiler=msvc --mode=link --arch=32 --nodefaultlib --output=%T/PointerTypeTest.cpp.exe %T/PointerTypeTest.cpp.obj
-RUN: lldb-test symbols %T/PointerTypeTest.cpp.exe | FileCheck %s
-RUN: lldb-test symbols %T/PointerTypeTest.cpp.exe | FileCheck --check-prefix=MAIN-ST-F %s
-RUN: lldb-test symbols %T/PointerTypeTest.cpp.exe | FileCheck --check-prefix=MAIN-ST %s
-RUN: lldb-test symbols %T/PointerTypeTest.cpp.exe | FileCheck --check-prefix=MAIN %s
-RUN: lldb-test symbols %T/PointerTypeTest.cpp.exe | FileCheck --check-prefix=F %s
+RUN: mkdir -p %t.dir
+RUN: %build --compiler=clang-cl --mode=compile --arch=32 --nodefaultlib --output=%t.dir/PointerTypeTest.cpp.obj %S/Inputs/PointerTypeTest.cpp
+RUN: %build --compiler=msvc --mode=link --arch=32 --nodefaultlib --output=%t.dir/PointerTypeTest.cpp.exe %t.dir/PointerTypeTest.cpp.obj
+RUN: lldb-test symbols %t.dir/PointerTypeTest.cpp.exe | FileCheck %s
+RUN: lldb-test symbols %t.dir/PointerTypeTest.cpp.exe | FileCheck --check-prefix=MAIN-ST-F %s
+RUN: lldb-test symbols %t.dir/PointerTypeTest.cpp.exe | FileCheck --check-prefix=MAIN-ST %s
+RUN: lldb-test symbols %t.dir/PointerTypeTest.cpp.exe | FileCheck --check-prefix=MAIN %s
+RUN: lldb-test symbols %t.dir/PointerTypeTest.cpp.exe | FileCheck --check-prefix=F %s
CHECK: Module [[MOD:.*]]
CHECK: {{^[0-9A-F]+}}: CompileUnit{{[{]0x[0-9a-f]+[}]}}, language = "c++", file = '{{.*}}\PointerTypeTest.cpp'
diff --git a/lldb/test/Shell/SymbolFile/PDB/type-quals.test b/lldb/test/Shell/SymbolFile/PDB/type-quals.test
index 982bb70..e0d79ac 100644
--- a/lldb/test/Shell/SymbolFile/PDB/type-quals.test
+++ b/lldb/test/Shell/SymbolFile/PDB/type-quals.test
@@ -1,7 +1,8 @@
REQUIRES: target-windows, msvc
-RUN: %build --compiler=clang-cl --mode=compile --arch=32 --nodefaultlib --output=%T/TypeQualsTest.cpp.obj %S/Inputs/TypeQualsTest.cpp
-RUN: %build --compiler=msvc --mode=link --arch=32 --nodefaultlib --output=%T/TypeQualsTest.cpp.exe %T/TypeQualsTest.cpp.obj
-RUN: lldb-test symbols %T/TypeQualsTest.cpp.exe | FileCheck %s
+RUN: mkdir -p %t.dir
+RUN: %build --compiler=clang-cl --mode=compile --arch=32 --nodefaultlib --output=%t.dir/TypeQualsTest.cpp.obj %S/Inputs/TypeQualsTest.cpp
+RUN: %build --compiler=msvc --mode=link --arch=32 --nodefaultlib --output=%t.dir/TypeQualsTest.cpp.exe %t.dir/TypeQualsTest.cpp.obj
+RUN: lldb-test symbols %t.dir/TypeQualsTest.cpp.exe | FileCheck %s
CHECK: Module [[MOD:.*]]
CHECK-DAG: SymbolFile pdb ([[MOD]])
diff --git a/lldb/test/Shell/SymbolFile/PDB/typedefs.test b/lldb/test/Shell/SymbolFile/PDB/typedefs.test
index ebbcc4b..86846fb 100644
--- a/lldb/test/Shell/SymbolFile/PDB/typedefs.test
+++ b/lldb/test/Shell/SymbolFile/PDB/typedefs.test
@@ -1,6 +1,7 @@
REQUIRES: system-windows, msvc
-RUN: %build --compiler=msvc --arch=32 --nodefaultlib --output=%T/SimpleTypesTest.cpp.typedefs.exe %S/Inputs/SimpleTypesTest.cpp
-RUN: lldb-test symbols %T/SimpleTypesTest.cpp.typedefs.exe | FileCheck %s
+RUN: mkdir -p %t.dir
+RUN: %build --compiler=msvc --arch=32 --nodefaultlib --output=%t.dir/SimpleTypesTest.cpp.typedefs.exe %S/Inputs/SimpleTypesTest.cpp
+RUN: lldb-test symbols %t.dir/SimpleTypesTest.cpp.typedefs.exe | FileCheck %s
; Generate 32-bit target
diff --git a/lldb/test/Shell/SymbolFile/PDB/variables.test b/lldb/test/Shell/SymbolFile/PDB/variables.test
index 0043ebb..9ee10f7 100644
--- a/lldb/test/Shell/SymbolFile/PDB/variables.test
+++ b/lldb/test/Shell/SymbolFile/PDB/variables.test
@@ -1,12 +1,13 @@
REQUIRES: system-windows, msvc
-RUN: %build --compiler=clang-cl --mode=compile --arch=64 --nodefaultlib --output=%T/VariablesTest.cpp.obj %S/Inputs/VariablesTest.cpp
-RUN: %build --compiler=msvc --mode=link --arch=64 --nodefaultlib --output=%T/VariablesTest.cpp.exe %T/VariablesTest.cpp.obj
-RUN: lldb-test symbols %T/VariablesTest.cpp.exe > %T/VariablesTest.out
-RUN: FileCheck --check-prefix=GLOBALS --input-file=%T/VariablesTest.out %s
-RUN: FileCheck --check-prefix=FUNC-F --input-file=%T/VariablesTest.out %s
-RUN: FileCheck --check-prefix=FUNC-MAIN --input-file=%T/VariablesTest.out %s
-RUN: FileCheck --check-prefix=FUNC-CONSTRUCTOR --input-file=%T/VariablesTest.out %s
-RUN: FileCheck --check-prefix=FUNC-MEMBER --input-file=%T/VariablesTest.out %s
+RUN: mkdir -p %t.dir
+RUN: %build --compiler=clang-cl --mode=compile --arch=64 --nodefaultlib --output=%t.dir/VariablesTest.cpp.obj %S/Inputs/VariablesTest.cpp
+RUN: %build --compiler=msvc --mode=link --arch=64 --nodefaultlib --output=%t.dir/VariablesTest.cpp.exe %t.dir/VariablesTest.cpp.obj
+RUN: lldb-test symbols %t.dir/VariablesTest.cpp.exe > %t.dir/VariablesTest.out
+RUN: FileCheck --check-prefix=GLOBALS --input-file=%t.dir/VariablesTest.out %s
+RUN: FileCheck --check-prefix=FUNC-F --input-file=%t.dir/VariablesTest.out %s
+RUN: FileCheck --check-prefix=FUNC-MAIN --input-file=%t.dir/VariablesTest.out %s
+RUN: FileCheck --check-prefix=FUNC-CONSTRUCTOR --input-file=%t.dir/VariablesTest.out %s
+RUN: FileCheck --check-prefix=FUNC-MEMBER --input-file=%t.dir/VariablesTest.out %s
GLOBALS: Module [[MOD:.*]]
GLOBALS: SymbolFile pdb ([[MOD]])
diff --git a/lldb/tools/lldb-rpc/LLDBRPCHeaders.cmake b/lldb/tools/lldb-rpc/LLDBRPCHeaders.cmake
index 6c363f4..2376e23 100644
--- a/lldb/tools/lldb-rpc/LLDBRPCHeaders.cmake
+++ b/lldb/tools/lldb-rpc/LLDBRPCHeaders.cmake
@@ -79,7 +79,7 @@ function(FixIncludePaths in subfolder out)
add_custom_command(OUTPUT ${parked_header}
COMMAND ${LLDB_SOURCE_DIR}/scripts/framework-header-fix.py
- -f lldb_rpc -i ${in} -o ${parked_header} -p ${unifdef_EXECUTABLE} --unifdef_guards USWIG
+ -f lldb_rpc -i ${in} -o ${parked_header} -p ${unifdef_EXECUTABLE} --unifdef_guards SWIG
DEPENDS ${in}
COMMENT "Fixing includes in ${in}"
)
diff --git a/lldb/unittests/Expression/CMakeLists.txt b/lldb/unittests/Expression/CMakeLists.txt
index 185b19f..533cdc6 100644
--- a/lldb/unittests/Expression/CMakeLists.txt
+++ b/lldb/unittests/Expression/CMakeLists.txt
@@ -8,6 +8,8 @@ add_lldb_unittest(ExpressionTests
LINK_LIBS
lldbCore
lldbPluginObjectFileELF
+ lldbPluginObjectFileWasm
+ lldbPluginSymbolVendorWasm
lldbPluginPlatformLinux
lldbPluginExpressionParserClang
lldbPluginTypeSystemClang
diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp b/lldb/unittests/Expression/DWARFExpressionTest.cpp
index 819c973..8b1b933 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -7,9 +7,12 @@
//===----------------------------------------------------------------------===//
#include "lldb/Expression/DWARFExpression.h"
+#include "Plugins/ObjectFile/wasm/ObjectFileWasm.h"
#include "Plugins/Platform/Linux/PlatformLinux.h"
#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h"
+#include "Plugins/SymbolFile/DWARF/SymbolFileWasm.h"
+#include "Plugins/SymbolVendor/wasm/SymbolVendorWasm.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "TestingSupport/Symbol/YAMLModuleTester.h"
#include "lldb/Core/Debugger.h"
@@ -18,27 +21,127 @@
#include "lldb/Core/dwarf.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/StreamString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"
-using namespace lldb_private;
using namespace lldb_private::plugin::dwarf;
+using namespace lldb_private::wasm;
+using namespace lldb_private;
using namespace llvm::dwarf;
+namespace {
+struct MockProcess : Process {
+ MockProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
+ : Process(target_sp, listener_sp) {}
+
+ llvm::StringRef GetPluginName() override { return "mock process"; }
+
+ bool CanDebug(lldb::TargetSP target, bool plugin_specified_by_name) override {
+ return false;
+ };
+
+ Status DoDestroy() override { return {}; }
+
+ void RefreshStateAfterStop() override {}
+
+ bool DoUpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) override {
+ return false;
+ };
+
+ size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
+ Status &error) override {
+ for (size_t i = 0; i < size; ++i)
+ ((char *)buf)[i] = (vm_addr + i) & 0xff;
+ error.Clear();
+ return size;
+ }
+};
+
+class MockThread : public Thread {
+public:
+ MockThread(Process &process) : Thread(process, /*tid=*/1), m_reg_ctx_sp() {}
+ ~MockThread() override { DestroyThread(); }
+
+ void RefreshStateAfterStop() override {}
+
+ lldb::RegisterContextSP GetRegisterContext() override { return m_reg_ctx_sp; }
+
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame(StackFrame *frame) override {
+ return m_reg_ctx_sp;
+ }
+
+ bool CalculateStopInfo() override { return false; }
+
+ void SetRegisterContext(lldb::RegisterContextSP reg_ctx_sp) {
+ m_reg_ctx_sp = reg_ctx_sp;
+ }
+
+private:
+ lldb::RegisterContextSP m_reg_ctx_sp;
+};
+
+class MockRegisterContext : public RegisterContext {
+public:
+ MockRegisterContext(Thread &thread, const RegisterValue &reg_value)
+ : RegisterContext(thread, 0 /*concrete_frame_idx*/),
+ m_reg_value(reg_value) {}
+
+ void InvalidateAllRegisters() override {}
+
+ size_t GetRegisterCount() override { return 0; }
+
+ const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override {
+ return &m_reg_info;
+ }
+
+ size_t GetRegisterSetCount() override { return 0; }
+
+ const RegisterSet *GetRegisterSet(size_t reg_set) override { return nullptr; }
+
+ lldb::ByteOrder GetByteOrder() override {
+ return lldb::ByteOrder::eByteOrderLittle;
+ }
+
+ bool ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override {
+ reg_value = m_reg_value;
+ return true;
+ }
+
+ bool WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override {
+ return false;
+ }
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override {
+ return num;
+ }
+
+private:
+ RegisterInfo m_reg_info;
+ RegisterValue m_reg_value;
+};
+} // namespace
+
static llvm::Expected<Scalar> Evaluate(llvm::ArrayRef<uint8_t> expr,
lldb::ModuleSP module_sp = {},
DWARFUnit *unit = nullptr,
- ExecutionContext *exe_ctx = nullptr) {
+ ExecutionContext *exe_ctx = nullptr,
+ RegisterContext *reg_ctx = nullptr) {
DataExtractor extractor(expr.data(), expr.size(), lldb::eByteOrderLittle,
/*addr_size*/ 4);
- llvm::Expected<Value> result =
- DWARFExpression::Evaluate(exe_ctx, /*reg_ctx*/ nullptr, module_sp,
- extractor, unit, lldb::eRegisterKindLLDB,
- /*initial_value_ptr*/ nullptr,
- /*object_address_ptr*/ nullptr);
+ llvm::Expected<Value> result = DWARFExpression::Evaluate(
+ exe_ctx, reg_ctx, module_sp, extractor, unit, lldb::eRegisterKindLLDB,
+ /*initial_value_ptr=*/nullptr,
+ /*object_address_ptr=*/nullptr);
if (!result)
return result.takeError();
@@ -53,7 +156,7 @@ static llvm::Expected<Scalar> Evaluate(llvm::ArrayRef<uint8_t> expr,
if (buf.GetByteSize() <= 8) {
uint64_t val = 0;
memcpy(&val, buf.GetBytes(), buf.GetByteSize());
- return Scalar(llvm::APInt(buf.GetByteSize()*8, val, false));
+ return Scalar(llvm::APInt(buf.GetByteSize() * 8, val, false));
}
}
[[fallthrough]];
@@ -65,8 +168,8 @@ static llvm::Expected<Scalar> Evaluate(llvm::ArrayRef<uint8_t> expr,
class DWARFExpressionTester : public YAMLModuleTester {
public:
- DWARFExpressionTester(llvm::StringRef yaml_data, size_t cu_index) :
- YAMLModuleTester(yaml_data, cu_index) {}
+ DWARFExpressionTester(llvm::StringRef yaml_data, size_t cu_index)
+ : YAMLModuleTester(yaml_data, cu_index) {}
using YAMLModuleTester::YAMLModuleTester;
llvm::Expected<Scalar> Eval(llvm::ArrayRef<uint8_t> expr) {
@@ -377,30 +480,6 @@ TEST(DWARFExpression, DW_OP_unknown) {
TEST_F(DWARFExpressionMockProcessTest, DW_OP_deref) {
EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit0, DW_OP_deref}), llvm::Failed());
- struct MockProcess : Process {
- MockProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
- : Process(target_sp, listener_sp) {}
-
- llvm::StringRef GetPluginName() override { return "mock process"; }
- bool CanDebug(lldb::TargetSP target,
- bool plugin_specified_by_name) override {
- return false;
- };
- Status DoDestroy() override { return {}; }
- void RefreshStateAfterStop() override {}
- bool DoUpdateThreadList(ThreadList &old_thread_list,
- ThreadList &new_thread_list) override {
- return false;
- };
- size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
- Status &error) override {
- for (size_t i = 0; i < size; ++i)
- ((char *)buf)[i] = (vm_addr + i) & 0xff;
- error.Clear();
- return size;
- }
- };
-
// Set up a mock process.
ArchSpec arch("i386-pc-linux");
Platform::SetHostPlatform(
@@ -421,9 +500,9 @@ TEST_F(DWARFExpressionMockProcessTest, DW_OP_deref) {
ExecutionContext exe_ctx(process_sp);
// Implicit location: *0x4.
- EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit4, DW_OP_deref, DW_OP_stack_value},
- {}, {}, &exe_ctx),
- llvm::HasValue(GetScalar(32, 0x07060504, false)));
+ EXPECT_THAT_EXPECTED(
+ Evaluate({DW_OP_lit4, DW_OP_deref, DW_OP_stack_value}, {}, {}, &exe_ctx),
+ llvm::HasValue(GetScalar(32, 0x07060504, false)));
// Memory location: *(*0x4).
// Evaluate returns LLDB_INVALID_ADDRESS for all load addresses.
EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit4, DW_OP_deref}, {}, {}, &exe_ctx),
@@ -618,10 +697,12 @@ public:
return offset - data_offset;
}
- bool
- ParseVendorDWARFOpcode(uint8_t op, const lldb_private::DataExtractor &opcodes,
- lldb::offset_t &offset,
- std::vector<lldb_private::Value> &stack) const final {
+ virtual bool ParseVendorDWARFOpcode(
+ uint8_t op, const lldb_private::DataExtractor &opcodes,
+ lldb::offset_t &offset,
+
+ RegisterContext *reg_ctx, lldb::RegisterKind reg_kind,
+ std::vector<lldb_private::Value> &stack) const override {
if (op != DW_OP_WASM_location) {
return false;
}
@@ -647,13 +728,14 @@ public:
char CustomSymbolFileDWARF::ID;
static auto testExpressionVendorExtensions(lldb::ModuleSP module_sp,
- DWARFUnit &dwarf_unit) {
+ DWARFUnit &dwarf_unit,
+ RegisterContext *reg_ctx) {
// Test that expression extensions can be evaluated, for example
// DW_OP_WASM_location which is not currently handled by DWARFExpression:
EXPECT_THAT_EXPECTED(Evaluate({DW_OP_WASM_location, 0x03, // WASM_GLOBAL:0x03
0x04, 0x00, 0x00, // index:u32
0x00, DW_OP_stack_value},
- module_sp, &dwarf_unit),
+ module_sp, &dwarf_unit, nullptr, reg_ctx),
llvm::HasValue(GetScalar(32, 42, false)));
// Test that searches for opcodes work in the presence of extensions:
@@ -667,138 +749,331 @@ static auto testExpressionVendorExtensions(lldb::ModuleSP module_sp,
TEST(DWARFExpression, Extensions) {
const char *yamldata = R"(
---- !ELF
+--- !WASM
FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_EXEC
- Machine: EM_386
-DWARF:
- debug_abbrev:
- - Table:
- - Code: 0x00000001
- Tag: DW_TAG_compile_unit
- Children: DW_CHILDREN_no
- debug_info:
- - Version: 4
- AddrSize: 4
- Entries:
- - AbbrCode: 0x1
- - AbbrCode: 0x0
+ Version: 0x1
+Sections:
+ - Type: TYPE
+ Signatures:
+ - Index: 0
+ ParamTypes:
+ - I32
+ ReturnTypes:
+ - I32
+ - Type: FUNCTION
+ FunctionTypes: [ 0 ]
+ - Type: TABLE
+ Tables:
+ - Index: 0
+ ElemType: FUNCREF
+ Limits:
+ Flags: [ HAS_MAX ]
+ Minimum: 0x1
+ Maximum: 0x1
+ - Type: MEMORY
+ Memories:
+ - Flags: [ HAS_MAX ]
+ Minimum: 0x100
+ Maximum: 0x100
+ - Type: GLOBAL
+ Globals:
+ - Index: 0
+ Type: I32
+ Mutable: true
+ InitExpr:
+ Opcode: I32_CONST
+ Value: 65536
+ - Type: EXPORT
+ Exports:
+ - Name: memory
+ Kind: MEMORY
+ Index: 0
+ - Name: square
+ Kind: FUNCTION
+ Index: 0
+ - Name: __indirect_function_table
+ Kind: TABLE
+ Index: 0
+ - Type: CODE
+ Functions:
+ - Index: 0
+ Locals:
+ - Type: I32
+ Count: 1
+ - Type: I32
+ Count: 1
+ - Type: I32
+ Count: 1
+ - Type: I32
+ Count: 1
+ - Type: I32
+ Count: 1
+ - Type: I32
+ Count: 1
+ Body: 2300210141102102200120026B21032003200036020C200328020C2104200328020C2105200420056C210620060F0B
+ - Type: CUSTOM
+ Name: name
+ FunctionNames:
+ - Index: 0
+ Name: square
+ GlobalNames:
+ - Index: 0
+ Name: __stack_pointer
+ - Type: CUSTOM
+ Name: .debug_abbrev
+ Payload: 011101250E1305030E10171B0E110112060000022E01110112064018030E3A0B3B0B271949133F1900000305000218030E3A0B3B0B49130000042400030E3E0B0B0B000000
+ - Type: CUSTOM
+ Name: .debug_info
+ Payload: 510000000400000000000401670000001D005E000000000000000A000000020000003C00000002020000003C00000004ED00039F5700000001014D0000000302910C0400000001014D000000000400000000050400
+ - Type: CUSTOM
+ Name: .debug_str
+ Payload: 696E740076616C756500513A5C70616F6C6F7365764D5346545C6C6C766D2D70726F6A6563745C6C6C64625C746573745C4150495C66756E6374696F6E616C69746965735C6764625F72656D6F74655F636C69656E745C737175617265007371756172652E6300636C616E672076657273696F6E2031382E302E30202868747470733A2F2F6769746875622E636F6D2F6C6C766D2F6C6C766D2D70726F6A65637420373535303166353336323464653932616166636532663164613639386232343961373239336463372900
+ - Type: CUSTOM
+ Name: .debug_line
+ Payload: 64000000040020000000010101FB0E0D000101010100000001000001007371756172652E6300000000000005020200000001000502250000000301050A0A010005022C00000005120601000502330000000510010005023A0000000503010005023E000000000101
)";
- SubsystemRAII<FileSystem, HostInfo, TypeSystemClang, ObjectFileELF,
- CustomSymbolFileDWARF>
+ SubsystemRAII<FileSystem, HostInfo, ObjectFileWasm, SymbolVendorWasm>
subsystems;
+ // Set up a wasm target.
+ ArchSpec arch("wasm32-unknown-unknown-wasm");
+ lldb::PlatformSP host_platform_sp =
+ platform_linux::PlatformLinux::CreateInstance(true, &arch);
+ ASSERT_TRUE(host_platform_sp);
+ Platform::SetHostPlatform(host_platform_sp);
+ lldb::DebuggerSP debugger_sp = Debugger::CreateInstance();
+ ASSERT_TRUE(debugger_sp);
+ lldb::TargetSP target_sp;
+ lldb::PlatformSP platform_sp;
+ debugger_sp->GetTargetList().CreateTarget(*debugger_sp, "", arch,
+ lldb_private::eLoadDependentsNo,
+ platform_sp, target_sp);
+ // Set up a mock process and thread.
+ lldb::ListenerSP listener_sp(Listener::MakeListener("dummy"));
+ lldb::ProcessSP process_sp =
+ std::make_shared<MockProcess>(target_sp, listener_sp);
+ ASSERT_TRUE(process_sp);
+ MockThread thread(*process_sp);
+ const uint32_t kExpectedValue = 42;
+ lldb::RegisterContextSP reg_ctx_sp = std::make_shared<MockRegisterContext>(
+ thread, RegisterValue(kExpectedValue));
+ thread.SetRegisterContext(reg_ctx_sp);
+
llvm::Expected<TestFile> file = TestFile::fromYaml(yamldata);
EXPECT_THAT_EXPECTED(file, llvm::Succeeded());
-
auto module_sp = std::make_shared<Module>(file->moduleSpec());
- auto &symfile =
- *llvm::cast<CustomSymbolFileDWARF>(module_sp->GetSymbolFile());
- auto *dwarf_unit = symfile.DebugInfo().GetUnitAtIndex(0);
+ auto obj_file_sp = module_sp->GetObjectFile()->shared_from_this();
+ SymbolFileWasm sym_file_wasm(obj_file_sp, nullptr);
+ auto *dwarf_unit = sym_file_wasm.DebugInfo().GetUnitAtIndex(0);
- testExpressionVendorExtensions(module_sp, *dwarf_unit);
+ testExpressionVendorExtensions(module_sp, *dwarf_unit, reg_ctx_sp.get());
}
-TEST(DWARFExpression, ExtensionsDWO) {
+TEST(DWARFExpression, ExtensionsSplitSymbols) {
const char *skeleton_yamldata = R"(
---- !ELF
+--- !WASM
FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_EXEC
- Machine: EM_386
-DWARF:
- debug_abbrev:
- - Table:
- - Code: 0x00000001
- Tag: DW_TAG_skeleton_unit
- Children: DW_CHILDREN_no
- Attributes:
- - Attribute: DW_AT_dwo_name
- Form: DW_FORM_string
- - Attribute: DW_AT_dwo_id
- Form: DW_FORM_data4
- debug_info:
- - Version: 4
- AddrSize: 4
- Entries:
- - AbbrCode: 0x1
- Values:
- - CStr: "dwo_unit"
- - Value: 0x01020304
- - AbbrCode: 0x0
+ Version: 0x1
+Sections:
+ - Type: TYPE
+ Signatures:
+ - Index: 0
+ ParamTypes:
+ - I32
+ ReturnTypes:
+ - I32
+ - Type: FUNCTION
+ FunctionTypes: [ 0 ]
+ - Type: TABLE
+ Tables:
+ - Index: 0
+ ElemType: FUNCREF
+ Limits:
+ Flags: [ HAS_MAX ]
+ Minimum: 0x1
+ Maximum: 0x1
+ - Type: MEMORY
+ Memories:
+ - Flags: [ HAS_MAX ]
+ Minimum: 0x100
+ Maximum: 0x100
+ - Type: GLOBAL
+ Globals:
+ - Index: 0
+ Type: I32
+ Mutable: true
+ InitExpr:
+ Opcode: I32_CONST
+ Value: 65536
+ - Type: EXPORT
+ Exports:
+ - Name: memory
+ Kind: MEMORY
+ Index: 0
+ - Name: square
+ Kind: FUNCTION
+ Index: 0
+ - Name: __indirect_function_table
+ Kind: TABLE
+ Index: 0
+ - Type: CODE
+ Functions:
+ - Index: 0
+ Locals:
+ - Type: I32
+ Count: 1
+ - Type: I32
+ Count: 1
+ - Type: I32
+ Count: 1
+ - Type: I32
+ Count: 1
+ - Type: I32
+ Count: 1
+ - Type: I32
+ Count: 1
+ Body: 2300210141102102200120026B21032003200036020C200328020C2104200328020C2105200420056C210620060F0B
+ - Type: CUSTOM
+ Name: name
+ FunctionNames:
+ - Index: 0
+ Name: square
+ GlobalNames:
+ - Index: 0
+ Name: __stack_pointer
+ - Type: CUSTOM
+ Name: external_debug_info
+ Payload: 167371756172652E7761736D2E64656275672E7761736D
)";
- // .dwo sections aren't currently supported by dwarfyaml. The dwo_yamldata
- // contents where generated by roundtripping the following yaml through
- // yaml2obj | obj2yaml and renaming the sections. This works because the
- // structure of the .dwo and non-.dwo sections is identical.
- //
- // --- !ELF
- // FileHeader:
- // Class: ELFCLASS64
- // Data: ELFDATA2LSB
- // Type: ET_EXEC
- // Machine: EM_386
- // DWARF:
- // debug_abbrev: #.dwo
- // - Table:
- // - Code: 0x00000001
- // Tag: DW_TAG_compile_unit
- // Children: DW_CHILDREN_no
- // Attributes:
- // - Attribute: DW_AT_dwo_id
- // Form: DW_FORM_data4
- // debug_info: #.dwo
- // - Version: 4
- // AddrSize: 4
- // Entries:
- // - AbbrCode: 0x1
- // Values:
- // - Value: 0x0120304
- // - AbbrCode: 0x0
- const char *dwo_yamldata = R"(
---- !ELF
+ const char *sym_yamldata = R"(
+--- !WASM
FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_EXEC
- Machine: EM_386
+ Version: 0x1
Sections:
- - Name: .debug_abbrev.dwo
- Type: SHT_PROGBITS
- AddressAlign: 0x1
- Content: '0111007506000000'
- - Name: .debug_info.dwo
- Type: SHT_PROGBITS
- AddressAlign: 0x1
- Content: 0D00000004000000000004010403020100
+ - Type: TYPE
+ Signatures:
+ - Index: 0
+ ParamTypes:
+ - I32
+ ReturnTypes:
+ - I32
+ - Type: FUNCTION
+ FunctionTypes: [ 0 ]
+ - Type: TABLE
+ Tables:
+ - Index: 0
+ ElemType: FUNCREF
+ Limits:
+ Flags: [ HAS_MAX ]
+ Minimum: 0x1
+ Maximum: 0x1
+ - Type: MEMORY
+ Memories:
+ - Flags: [ HAS_MAX ]
+ Minimum: 0x100
+ Maximum: 0x100
+ - Type: GLOBAL
+ Globals:
+ - Index: 0
+ Type: I32
+ Mutable: true
+ InitExpr:
+ Opcode: I32_CONST
+ Value: 65536
+ - Type: EXPORT
+ Exports:
+ - Name: memory
+ Kind: MEMORY
+ Index: 0
+ - Name: square
+ Kind: FUNCTION
+ Index: 0
+ - Name: __indirect_function_table
+ Kind: TABLE
+ Index: 0
+ - Type: CODE
+ Functions:
+ - Index: 0
+ Locals:
+ - Type: I32
+ Count: 1
+ - Type: I32
+ Count: 1
+ - Type: I32
+ Count: 1
+ - Type: I32
+ Count: 1
+ - Type: I32
+ Count: 1
+ - Type: I32
+ Count: 1
+ Body: 2300210141102102200120026B21032003200036020C200328020C2104200328020C2105200420056C210620060F0B
+ - Type: CUSTOM
+ Name: name
+ FunctionNames:
+ - Index: 0
+ Name: square
+ GlobalNames:
+ - Index: 0
+ Name: __stack_pointer
+ - Type: CUSTOM
+ Name: .debug_abbrev
+ Payload: 011101250E1305030E10171B0E110112060000022E01110112064018030E3A0B3B0B271949133F1900000305000218030E3A0B3B0B49130000042400030E3E0B0B0B000000
+ - Type: CUSTOM
+ Name: .debug_info
+ Payload: 510000000400000000000401670000001D005E0000000000000004000000020000003C00000002020000003C00000004ED00039F5700000001014D0000000302910C5100000001014D000000000400000000050400
+ - Type: CUSTOM
+ Name: .debug_str
+ Payload: 696E7400513A5C70616F6C6F7365764D5346545C6C6C766D2D70726F6A6563745C6C6C64625C746573745C4150495C66756E6374696F6E616C69746965735C6764625F72656D6F74655F636C69656E740076616C756500737175617265007371756172652E6300636C616E672076657273696F6E2031382E302E30202868747470733A2F2F6769746875622E636F6D2F6C6C766D2F6C6C766D2D70726F6A65637420373535303166353336323464653932616166636532663164613639386232343961373239336463372900
+ - Type: CUSTOM
+ Name: .debug_line
+ Payload: 64000000040020000000010101FB0E0D000101010100000001000001007371756172652E6300000000000005020200000001000502250000000301050A0A010005022C00000005120601000502330000000510010005023A0000000503010005023E000000000101
)";
- SubsystemRAII<FileSystem, HostInfo, ObjectFileELF, CustomSymbolFileDWARF>
+ SubsystemRAII<FileSystem, HostInfo, ObjectFileWasm, SymbolVendorWasm>
subsystems;
+ // Set up a wasm target.
+ ArchSpec arch("wasm32-unknown-unknown-wasm");
+ lldb::PlatformSP host_platform_sp =
+ platform_linux::PlatformLinux::CreateInstance(true, &arch);
+ ASSERT_TRUE(host_platform_sp);
+ Platform::SetHostPlatform(host_platform_sp);
+ lldb::DebuggerSP debugger_sp = Debugger::CreateInstance();
+ ASSERT_TRUE(debugger_sp);
+ lldb::TargetSP target_sp;
+ lldb::PlatformSP platform_sp;
+ debugger_sp->GetTargetList().CreateTarget(*debugger_sp, "", arch,
+ lldb_private::eLoadDependentsNo,
+ platform_sp, target_sp);
+ // Set up a mock process and thread.
+ lldb::ListenerSP listener_sp(Listener::MakeListener("dummy"));
+ lldb::ProcessSP process_sp =
+ std::make_shared<MockProcess>(target_sp, listener_sp);
+ ASSERT_TRUE(process_sp);
+ MockThread thread(*process_sp);
+ const uint32_t kExpectedValue = 42;
+ lldb::RegisterContextSP reg_ctx_sp = std::make_shared<MockRegisterContext>(
+ thread, RegisterValue(kExpectedValue));
+ thread.SetRegisterContext(reg_ctx_sp);
+
llvm::Expected<TestFile> skeleton_file =
TestFile::fromYaml(skeleton_yamldata);
EXPECT_THAT_EXPECTED(skeleton_file, llvm::Succeeded());
- llvm::Expected<TestFile> dwo_file = TestFile::fromYaml(dwo_yamldata);
- EXPECT_THAT_EXPECTED(dwo_file, llvm::Succeeded());
-
auto skeleton_module_sp =
std::make_shared<Module>(skeleton_file->moduleSpec());
- auto &skeleton_symfile =
- *llvm::cast<CustomSymbolFileDWARF>(skeleton_module_sp->GetSymbolFile());
- auto dwo_module_sp = std::make_shared<Module>(dwo_file->moduleSpec());
- SymbolFileDWARFDwo dwo_symfile(
- skeleton_symfile, dwo_module_sp->GetObjectFile()->shared_from_this(),
- 0x0120304);
- auto *dwo_dwarf_unit = dwo_symfile.DebugInfo().GetUnitAtIndex(0);
+ llvm::Expected<TestFile> sym_file = TestFile::fromYaml(sym_yamldata);
+ EXPECT_THAT_EXPECTED(sym_file, llvm::Succeeded());
+ auto sym_module_sp = std::make_shared<Module>(sym_file->moduleSpec());
- testExpressionVendorExtensions(dwo_module_sp, *dwo_dwarf_unit);
+ auto obj_file_sp = sym_module_sp->GetObjectFile()->shared_from_this();
+ SymbolFileWasm sym_file_wasm(obj_file_sp, nullptr);
+ auto *dwarf_unit = sym_file_wasm.DebugInfo().GetUnitAtIndex(0);
+
+ testExpressionVendorExtensions(sym_module_sp, *dwarf_unit, reg_ctx_sp.get());
}
TEST_F(DWARFExpressionMockProcessTest, DW_OP_piece_file_addr) {
@@ -828,12 +1103,12 @@ TEST_F(DWARFExpressionMockProcessTest, DW_OP_piece_file_addr) {
uint8_t expr[] = {DW_OP_addr, 0x40, 0x0, 0x0, 0x0, DW_OP_piece, 1,
DW_OP_addr, 0x50, 0x0, 0x0, 0x0, DW_OP_piece, 1};
DataExtractor extractor(expr, sizeof(expr), lldb::eByteOrderLittle,
- /*addr_size*/ 4);
+ /*addr_size=*/4);
llvm::Expected<Value> result = DWARFExpression::Evaluate(
- &exe_ctx, /*reg_ctx*/ nullptr, /*module_sp*/ {}, extractor,
- /*unit*/ nullptr, lldb::eRegisterKindLLDB,
- /*initial_value_ptr*/ nullptr,
- /*object_address_ptr*/ nullptr);
+ &exe_ctx, /*reg_ctx=*/nullptr, /*module_sp=*/{}, extractor,
+ /*unit=*/nullptr, lldb::eRegisterKindLLDB,
+ /*initial_value_ptr=*/nullptr,
+ /*object_address_ptr=*/nullptr);
ASSERT_THAT_EXPECTED(result, llvm::Succeeded());
ASSERT_EQ(result->GetValueType(), Value::ValueType::HostAddress);
diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
index f7b5e3a..fbb005b 100644
--- a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
+++ b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
@@ -80,20 +80,6 @@ lldb_private::python::SWIGBridge::LLDBSwigPythonCreateCommandObject(
return python::PythonObject();
}
-python::PythonObject lldb_private::python::SWIGBridge::
- LLDBSwigPythonCreateScriptedBreakpointResolver(
- const char *python_class_name, const char *session_dictionary_name,
- const StructuredDataImpl &args, const lldb::BreakpointSP &bkpt_sp) {
- return python::PythonObject();
-}
-
-unsigned int
-lldb_private::python::SWIGBridge::LLDBSwigPythonCallBreakpointResolver(
- void *implementor, const char *method_name,
- lldb_private::SymbolContext *sym_ctx) {
- return 0;
-}
-
size_t lldb_private::python::SWIGBridge::LLDBSwigPython_CalculateNumChildren(
PyObject *implementor, uint32_t max) {
return 0;
@@ -144,6 +130,11 @@ lldb_private::python::LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data) {
return nullptr;
}
+void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBSymbolContext(
+ PyObject *data) {
+ return nullptr;
+}
+
void *
lldb_private::python::LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data) {
return nullptr;
diff --git a/lldb/unittests/Symbol/TestTypeSystemClang.cpp b/lldb/unittests/Symbol/TestTypeSystemClang.cpp
index 71930ab..5785767 100644
--- a/lldb/unittests/Symbol/TestTypeSystemClang.cpp
+++ b/lldb/unittests/Symbol/TestTypeSystemClang.cpp
@@ -869,7 +869,7 @@ TEST_F(TestTypeSystemClang, TestFunctionTemplateConstruction) {
CompilerType clang_type = m_ast->CreateFunctionType(int_type, {}, false, 0U);
FunctionDecl *func = m_ast->CreateFunctionDeclaration(
TU, OptionalClangModuleID(), "foo", clang_type, StorageClass::SC_None,
- false);
+ false, /*asm_label=*/{});
TypeSystemClang::TemplateParameterInfos empty_params;
// Create the actual function template.
@@ -900,7 +900,7 @@ TEST_F(TestTypeSystemClang, TestFunctionTemplateInRecordConstruction) {
// 2. It is mirroring the behavior of DWARFASTParserClang::ParseSubroutine.
FunctionDecl *func = m_ast->CreateFunctionDeclaration(
TU, OptionalClangModuleID(), "foo", clang_type, StorageClass::SC_None,
- false);
+ false, /*asm_label=*/{});
TypeSystemClang::TemplateParameterInfos empty_params;
// Create the actual function template.
@@ -938,7 +938,7 @@ TEST_F(TestTypeSystemClang, TestDeletingImplicitCopyCstrDueToMoveCStr) {
bool is_attr_used = false;
bool is_artificial = false;
m_ast->AddMethodToCXXRecordType(
- t.GetOpaqueQualType(), class_name, nullptr, function_type,
+ t.GetOpaqueQualType(), class_name, /*asm_label=*/{}, function_type,
lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,
is_explicit, is_attr_used, is_artificial);
@@ -975,7 +975,7 @@ TEST_F(TestTypeSystemClang, TestNotDeletingUserCopyCstrDueToMoveCStr) {
CompilerType function_type = m_ast->CreateFunctionType(
return_type, args, /*variadic=*/false, /*quals*/ 0U);
m_ast->AddMethodToCXXRecordType(
- t.GetOpaqueQualType(), class_name, nullptr, function_type,
+ t.GetOpaqueQualType(), class_name, /*asm_label=*/{}, function_type,
lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,
is_explicit, is_attr_used, is_artificial);
}
@@ -987,7 +987,7 @@ TEST_F(TestTypeSystemClang, TestNotDeletingUserCopyCstrDueToMoveCStr) {
m_ast->CreateFunctionType(return_type, args,
/*variadic=*/false, /*quals*/ 0U);
m_ast->AddMethodToCXXRecordType(
- t.GetOpaqueQualType(), class_name, nullptr, function_type,
+ t.GetOpaqueQualType(), class_name, /*asm_label=*/{}, function_type,
lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,
is_explicit, is_attr_used, is_artificial);
}
@@ -1098,7 +1098,7 @@ TEST_F(TestTypeSystemClang, AddMethodToCXXRecordType_ParmVarDecls) {
m_ast->CreateFunctionType(return_type, param_types,
/*variadic=*/false, /*quals*/ 0U);
m_ast->AddMethodToCXXRecordType(
- t.GetOpaqueQualType(), "myFunc", nullptr, function_type,
+ t.GetOpaqueQualType(), "myFunc", /*asm_label=*/{}, function_type,
lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,
is_explicit, is_attr_used, is_artificial);