aboutsummaryrefslogtreecommitdiff
path: root/lldb
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-12-02 21:02:54 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-12-02 21:02:54 +0000
commitf65dcba83ce5035ab88a85fe17628b447eb56e1b (patch)
tree35f37bb72b3cfc6060193e66c76ee7c9478969b0 /lldb
parent846a2208a8ab099f595fe7e8b2e6d54a7b5e67fb (diff)
Diffstat (limited to 'lldb')
-rw-r--r--lldb/bindings/interface/SBDebugger.i3
-rw-r--r--lldb/bindings/interface/SBTarget.i3
-rw-r--r--lldb/bindings/interface/SBValue.i3
-rw-r--r--lldb/bindings/python/python-swigsafecast.swig58
-rw-r--r--lldb/bindings/python/python-wrapper.swig299
-rw-r--r--lldb/bindings/python/python.swig1
-rw-r--r--lldb/include/lldb/API/SBDebugger.h2
-rw-r--r--lldb/include/lldb/API/SBTarget.h5
-rw-r--r--lldb/include/lldb/API/SBValue.h6
-rw-r--r--lldb/include/lldb/Core/Debugger.h8
-rw-r--r--lldb/include/lldb/Interpreter/OptionGroupFormat.h9
-rw-r--r--lldb/include/lldb/Symbol/ObjectFile.h28
-rw-r--r--lldb/include/lldb/Symbol/Symtab.h9
-rw-r--r--lldb/include/lldb/Target/Platform.h24
-rw-r--r--lldb/include/lldb/Target/Process.h38
-rw-r--r--lldb/source/API/SBDebugger.cpp62
-rw-r--r--lldb/source/API/SBTarget.cpp11
-rw-r--r--lldb/source/API/SBValue.cpp13
-rw-r--r--lldb/source/Commands/CommandObjectMemory.cpp17
-rw-r--r--lldb/source/Core/Debugger.cpp89
-rw-r--r--lldb/source/Core/Module.cpp11
-rw-r--r--lldb/source/Interpreter/CommandObject.cpp3
-rw-r--r--lldb/source/Interpreter/OptionGroupFormat.cpp40
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp2
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp63
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h13
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp22
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp3
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp2
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp13
-rw-r--r--lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp7
-rw-r--r--lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h2
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp238
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h11
-rw-r--r--lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp21
-rw-r--r--lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h2
-rw-r--r--lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h2
-rw-r--r--lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp2
-rw-r--r--lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h2
-rw-r--r--lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp148
-rw-r--r--lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h57
-rw-r--r--lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td12
-rw-r--r--lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp4
-rw-r--r--lldb/source/Plugins/Process/elf-core/ProcessElfCore.h8
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp96
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h23
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp13
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp6
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h4
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp12
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h1
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp62
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h10
-rw-r--r--lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp6
-rw-r--r--lldb/source/Plugins/Process/minidump/ProcessMinidump.h6
-rw-r--r--lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp4
-rw-r--r--lldb/source/Plugins/Process/scripted/ScriptedProcess.h6
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h152
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp183
-rw-r--r--lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp3
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp12
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp5
-rw-r--r--lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp1
-rw-r--r--lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp2
-rw-r--r--lldb/source/Symbol/ObjectFile.cpp38
-rw-r--r--lldb/source/Symbol/Symtab.cpp9
-rw-r--r--lldb/source/Target/Platform.cpp40
-rw-r--r--lldb/source/Target/Process.cpp7
-rw-r--r--lldb/source/Target/RemoteAwarePlatform.cpp11
-rw-r--r--lldb/tools/driver/Driver.cpp88
-rw-r--r--lldb/tools/lldb-server/lldb-platform.cpp26
71 files changed, 1131 insertions, 1071 deletions
diff --git a/lldb/bindings/interface/SBDebugger.i b/lldb/bindings/interface/SBDebugger.i
index aae72dd51394..f21e60d62873 100644
--- a/lldb/bindings/interface/SBDebugger.i
+++ b/lldb/bindings/interface/SBDebugger.i
@@ -207,6 +207,9 @@ public:
}
SBError
+ SetInputString (const char* data);
+
+ SBError
SetInputFile (SBFile file);
SBError
diff --git a/lldb/bindings/interface/SBTarget.i b/lldb/bindings/interface/SBTarget.i
index 3f9e4cdc6d67..b98aa70849be 100644
--- a/lldb/bindings/interface/SBTarget.i
+++ b/lldb/bindings/interface/SBTarget.i
@@ -412,6 +412,9 @@ public:
uint32_t
GetCodeByteSize ();
+ uint32_t
+ GetMaximumNumberOfChildrenToDisplay() const;
+
lldb::SBError
SetSectionLoadAddress (lldb::SBSection section,
lldb::addr_t section_base_addr);
diff --git a/lldb/bindings/interface/SBValue.i b/lldb/bindings/interface/SBValue.i
index dd012e667a20..bc66a4ae28f8 100644
--- a/lldb/bindings/interface/SBValue.i
+++ b/lldb/bindings/interface/SBValue.i
@@ -410,6 +410,9 @@ public:
bool
SetData (lldb::SBData &data, lldb::SBError& error);
+ lldb::SBValue
+ Clone(const char *new_name);
+
lldb::addr_t
GetLoadAddress();
diff --git a/lldb/bindings/python/python-swigsafecast.swig b/lldb/bindings/python/python-swigsafecast.swig
index aa2bcfb8c8ae..fdd3b4e62c10 100644
--- a/lldb/bindings/python/python-swigsafecast.swig
+++ b/lldb/bindings/python/python-swigsafecast.swig
@@ -1,23 +1,14 @@
+namespace lldb_private {
+namespace python {
+
PyObject *SBTypeToSWIGWrapper(lldb::SBEvent &event_sb) {
return SWIG_NewPointerObj(&event_sb, SWIGTYPE_p_lldb__SBEvent, 0);
}
-PyObject *SBTypeToSWIGWrapper(lldb::SBProcess &process_sb) {
- return SWIG_NewPointerObj(&process_sb, SWIGTYPE_p_lldb__SBProcess, 0);
-}
-
PyObject *SBTypeToSWIGWrapper(lldb::SBThread &thread_sb) {
return SWIG_NewPointerObj(&thread_sb, SWIGTYPE_p_lldb__SBThread, 0);
}
-PyObject *SBTypeToSWIGWrapper(lldb::SBThreadPlan &thread_plan_sb) {
- return SWIG_NewPointerObj(&thread_plan_sb, SWIGTYPE_p_lldb__SBThreadPlan, 0);
-}
-
-PyObject *SBTypeToSWIGWrapper(lldb::SBTarget &target_sb) {
- return SWIG_NewPointerObj(&target_sb, SWIGTYPE_p_lldb__SBTarget, 0);
-}
-
PyObject *SBTypeToSWIGWrapper(lldb::SBFrame &frame_sb) {
return SWIG_NewPointerObj(&frame_sb, SWIGTYPE_p_lldb__SBFrame, 0);
}
@@ -26,10 +17,6 @@ PyObject *SBTypeToSWIGWrapper(lldb::SBDebugger &debugger_sb) {
return SWIG_NewPointerObj(&debugger_sb, SWIGTYPE_p_lldb__SBDebugger, 0);
}
-PyObject *SBTypeToSWIGWrapper(lldb::SBBreakpoint &breakpoint_sb) {
- return SWIG_NewPointerObj(&breakpoint_sb, SWIGTYPE_p_lldb__SBBreakpoint, 0);
-}
-
PyObject *SBTypeToSWIGWrapper(lldb::SBWatchpoint &watchpoint_sb) {
return SWIG_NewPointerObj(&watchpoint_sb, SWIGTYPE_p_lldb__SBWatchpoint, 0);
}
@@ -40,10 +27,6 @@ SBTypeToSWIGWrapper(lldb::SBBreakpointLocation &breakpoint_location_sb) {
SWIGTYPE_p_lldb__SBBreakpointLocation, 0);
}
-PyObject *SBTypeToSWIGWrapper(lldb::SBValue &value_sb) {
- return SWIG_NewPointerObj(&value_sb, SWIGTYPE_p_lldb__SBValue, 0);
-}
-
PyObject *SBTypeToSWIGWrapper(lldb::SBCommandReturnObject &cmd_ret_obj_sb) {
return SWIG_NewPointerObj(&cmd_ret_obj_sb,
SWIGTYPE_p_lldb__SBCommandReturnObject, 0);
@@ -70,3 +53,38 @@ PyObject *SBTypeToSWIGWrapper(lldb::SBSymbolContext &sym_ctx_sb) {
PyObject *SBTypeToSWIGWrapper(lldb::SBStream &stream_sb) {
return SWIG_NewPointerObj(&stream_sb, SWIGTYPE_p_lldb__SBStream, 0);
}
+
+PythonObject ToSWIGHelper(void *obj, swig_type_info *info) {
+ return {PyRefType::Owned, SWIG_NewPointerObj(obj, info, SWIG_POINTER_OWN)};
+}
+
+PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBValue> value_sb) {
+ return ToSWIGHelper(value_sb.release(), SWIGTYPE_p_lldb__SBValue);
+}
+
+PythonObject ToSWIGWrapper(lldb::ValueObjectSP value_sp) {
+ return ToSWIGWrapper(std::make_unique<lldb::SBValue>(std::move(value_sp)));
+}
+
+PythonObject ToSWIGWrapper(lldb::TargetSP target_sp) {
+ return ToSWIGHelper(new lldb::SBTarget(std::move(target_sp)),
+ SWIGTYPE_p_lldb__SBTarget);
+}
+
+PythonObject ToSWIGWrapper(lldb::ProcessSP process_sp) {
+ return ToSWIGHelper(new lldb::SBProcess(std::move(process_sp)),
+ SWIGTYPE_p_lldb__SBProcess);
+}
+
+PythonObject ToSWIGWrapper(lldb::ThreadPlanSP thread_plan_sp) {
+ return ToSWIGHelper(new lldb::SBThreadPlan(std::move(thread_plan_sp)),
+ SWIGTYPE_p_lldb__SBThreadPlan);
+}
+
+PythonObject ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp) {
+ return ToSWIGHelper(new lldb::SBBreakpoint(std::move(breakpoint_sp)),
+ SWIGTYPE_p_lldb__SBBreakpoint);
+}
+
+} // namespace python
+} // namespace lldb_private
diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig
index 6dc8ca170390..079f8d12dafa 100644
--- a/lldb/bindings/python/python-wrapper.swig
+++ b/lldb/bindings/python/python-wrapper.swig
@@ -22,32 +22,8 @@ private:
bool m_print;
};
-%}
-
-%wrapper %{
-
-// resolve a dotted Python name in the form
-// foo.bar.baz.Foobar to an actual Python object
-// if pmodule is NULL, the __main__ module will be used
-// as the starting point for the search
-
-
-// This function is called by lldb_private::ScriptInterpreterPython::BreakpointCallbackFunction(...)
-// and is used when a script command is attached to a breakpoint for execution.
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
-
-// Disable warning C4190: 'LLDBSwigPythonBreakpointCallbackFunction' has
-// C-linkage specified, but returns UDT 'llvm::Expected<bool>' which is
-// incompatible with C
-#if _MSC_VER
-#pragma warning (push)
-#pragma warning (disable : 4190)
-#endif
-
-SWIGEXPORT llvm::Expected<bool>
-LLDBSwigPythonBreakpointCallbackFunction
+llvm::Expected<bool>
+lldb_private::LLDBSwigPythonBreakpointCallbackFunction
(
const char *python_function_name,
const char *session_dictionary_name,
@@ -93,17 +69,20 @@ LLDBSwigPythonBreakpointCallbackFunction
return result.get().get() != Py_False;
}
-#if _MSC_VER
-#pragma warning (pop)
-#endif
+// resolve a dotted Python name in the form
+// foo.bar.baz.Foobar to an actual Python object
+// if pmodule is NULL, the __main__ module will be used
+// as the starting point for the search
-#pragma clang diagnostic pop
+
+// This function is called by lldb_private::ScriptInterpreterPython::BreakpointCallbackFunction(...)
+// and is used when a script command is attached to a breakpoint for execution.
// This function is called by lldb_private::ScriptInterpreterPython::WatchpointCallbackFunction(...)
// and is used when a script command is attached to a watchpoint for execution.
-SWIGEXPORT bool
-LLDBSwigPythonWatchpointCallbackFunction
+bool
+lldb_private::LLDBSwigPythonWatchpointCallbackFunction
(
const char *python_function_name,
const char *session_dictionary_name,
@@ -134,8 +113,8 @@ LLDBSwigPythonWatchpointCallbackFunction
return stop_at_watchpoint;
}
-SWIGEXPORT bool
-LLDBSwigPythonCallTypeScript
+bool
+lldb_private::LLDBSwigPythonCallTypeScript
(
const char *python_function_name,
const void *session_dictionary,
@@ -145,7 +124,6 @@ LLDBSwigPythonCallTypeScript
std::string& retval
)
{
- lldb::SBValue sb_value (valobj_sp);
lldb::SBTypeSummaryOptions sb_options(options_sp.get());
retval.clear();
@@ -195,7 +173,7 @@ LLDBSwigPythonCallTypeScript
return false;
}
- PythonObject value_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_value));
+ PythonObject value_arg = ToSWIGWrapper(valobj_sp);
PythonObject options_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_options));
if (argc.get().max_positional_args < 3)
@@ -208,8 +186,8 @@ LLDBSwigPythonCallTypeScript
return true;
}
-SWIGEXPORT void*
-LLDBSwigPythonCreateSyntheticProvider
+void*
+lldb_private::LLDBSwigPythonCreateSyntheticProvider
(
const char *python_class_name,
const char *session_dictionary_name,
@@ -227,11 +205,10 @@ LLDBSwigPythonCreateSyntheticProvider
if (!pfunc.IsAllocated())
Py_RETURN_NONE;
- // FIXME: SBValue leaked here
- lldb::SBValue *sb_value = new lldb::SBValue(valobj_sp);
+ auto sb_value = std::make_unique<lldb::SBValue>(valobj_sp);
sb_value->SetPreferSyntheticValue(false);
- PythonObject val_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*sb_value));
+ PythonObject val_arg = ToSWIGWrapper(std::move(sb_value));
if (!val_arg.IsAllocated())
Py_RETURN_NONE;
@@ -243,8 +220,8 @@ LLDBSwigPythonCreateSyntheticProvider
Py_RETURN_NONE;
}
-SWIGEXPORT void*
-LLDBSwigPythonCreateCommandObject
+void*
+lldb_private::LLDBSwigPythonCreateCommandObject
(
const char *python_class_name,
const char *session_dictionary_name,
@@ -271,8 +248,8 @@ LLDBSwigPythonCreateCommandObject
Py_RETURN_NONE;
}
-SWIGEXPORT void*
-LLDBSwigPythonCreateScriptedProcess
+void*
+lldb_private::LLDBSwigPythonCreateScriptedProcess
(
const char *python_class_name,
const char *session_dictionary_name,
@@ -295,12 +272,7 @@ LLDBSwigPythonCreateScriptedProcess
return nullptr;
}
- // FIXME: SBTarget leaked here
- PythonObject target_arg(
- PyRefType::Owned, SBTypeToSWIGWrapper(*new lldb::SBTarget(target_sp)));
-
- if (!target_arg.IsAllocated())
- Py_RETURN_NONE;
+ PythonObject target_arg = ToSWIGWrapper(target_sp);
llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
if (!arg_info) {
@@ -330,8 +302,8 @@ LLDBSwigPythonCreateScriptedProcess
Py_RETURN_NONE;
}
-SWIGEXPORT void*
-LLDBSwigPythonCreateScriptedThread
+void*
+lldb_private::LLDBSwigPythonCreateScriptedThread
(
const char *python_class_name,
const char *session_dictionary_name,
@@ -354,14 +326,6 @@ LLDBSwigPythonCreateScriptedThread
return nullptr;
}
- // FIXME: This leaks the SBProcess object
- PythonObject process_arg(
- PyRefType::Owned,
- SBTypeToSWIGWrapper(*new lldb::SBProcess(process_sp)));
-
- if (!process_arg.IsAllocated())
- Py_RETURN_NONE;
-
llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
if (!arg_info) {
llvm::handleAllErrors(
@@ -379,7 +343,7 @@ LLDBSwigPythonCreateScriptedThread
if (arg_info.get().max_positional_args == 2) {
// FIXME: SBStructuredData leaked here
PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*new lldb::SBStructuredData(args_impl)));
- result = pfunc(process_arg, args_arg);
+ result = pfunc(ToSWIGWrapper(process_sp), args_arg);
} else {
error_string.assign("wrong number of arguments in __init__, should be 2 (not including self)");
Py_RETURN_NONE;
@@ -390,8 +354,8 @@ LLDBSwigPythonCreateScriptedThread
Py_RETURN_NONE;
}
-SWIGEXPORT void*
-LLDBSwigPythonCreateScriptedThreadPlan
+void*
+lldb_private::LLDBSwigPythonCreateScriptedThreadPlan
(
const char *python_class_name,
const char *session_dictionary_name,
@@ -415,13 +379,7 @@ LLDBSwigPythonCreateScriptedThreadPlan
return nullptr;
}
- // FIXME: SBThreadPlan leaked here
- PythonObject tp_arg(
- PyRefType::Owned,
- SBTypeToSWIGWrapper(*new lldb::SBThreadPlan(thread_plan_sp)));
-
- if (!tp_arg.IsAllocated())
- Py_RETURN_NONE;
+ PythonObject tp_arg = ToSWIGWrapper(thread_plan_sp);
llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
if (!arg_info) {
@@ -460,8 +418,8 @@ LLDBSwigPythonCreateScriptedThreadPlan
Py_RETURN_NONE;
}
-SWIGEXPORT bool
-LLDBSWIGPythonCallThreadPlan
+bool
+lldb_private::LLDBSWIGPythonCallThreadPlan
(
void *implementor,
const char *method_name,
@@ -507,15 +465,11 @@ LLDBSWIGPythonCallThreadPlan
return false;
}
-SWIGEXPORT void *
-LLDBSwigPythonCreateScriptedBreakpointResolver
-(
- const char *python_class_name,
- const char *session_dictionary_name,
+void *lldb_private::LLDBSwigPythonCreateScriptedBreakpointResolver(
+ const char *python_class_name, const char *session_dictionary_name,
lldb_private::StructuredDataImpl *args_impl,
- lldb::BreakpointSP &breakpoint_sp
-)
-{
+ const lldb::BreakpointSP &breakpoint_sp) {
+
if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
Py_RETURN_NONE;
@@ -527,16 +481,11 @@ LLDBSwigPythonCreateScriptedBreakpointResolver
if (!pfunc.IsAllocated())
return nullptr;
- // FIXME: SBBreakpoint leaked here
- lldb::SBBreakpoint *bkpt_value = new lldb::SBBreakpoint(breakpoint_sp);
-
- PythonObject bkpt_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*bkpt_value));
-
// FIXME: SBStructuredData leaked here
lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl);
PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*args_value));
- PythonObject result = pfunc(bkpt_arg, args_arg, dict);
+ PythonObject result = pfunc(ToSWIGWrapper(breakpoint_sp), args_arg, dict);
// FIXME: At this point we should check that the class we found supports all the methods
// that we need.
@@ -552,8 +501,8 @@ LLDBSwigPythonCreateScriptedBreakpointResolver
Py_RETURN_NONE;
}
-SWIGEXPORT unsigned int
-LLDBSwigPythonCallBreakpointResolver
+unsigned int
+lldb_private::LLDBSwigPythonCallBreakpointResolver
(
void *implementor,
const char *method_name,
@@ -603,8 +552,8 @@ LLDBSwigPythonCallBreakpointResolver
return ret_val;
}
-SWIGEXPORT void *
-LLDBSwigPythonCreateScriptedStopHook
+void *
+lldb_private::LLDBSwigPythonCreateScriptedStopHook
(
lldb::TargetSP target_sp,
const char *python_class_name,
@@ -637,16 +586,11 @@ LLDBSwigPythonCreateScriptedStopHook
return nullptr;
}
- // FIXME: SBTarget leaked here
- lldb::SBTarget *target_val
- = new lldb::SBTarget(target_sp);
- PythonObject target_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*target_val));
-
// FIXME: SBStructuredData leaked here
lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl);
PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*args_value));
- PythonObject result = pfunc(target_arg, args_arg, dict);
+ PythonObject result = pfunc(ToSWIGWrapper(target_sp), args_arg, dict);
if (result.IsAllocated())
{
@@ -679,8 +623,8 @@ LLDBSwigPythonCreateScriptedStopHook
Py_RETURN_NONE;
}
-SWIGEXPORT bool
-LLDBSwigPythonStopHookCallHandleStop
+bool
+lldb_private::LLDBSwigPythonStopHookCallHandleStop
(
void *implementor,
lldb::ExecutionContextRefSP exc_ctx_sp,
@@ -755,8 +699,8 @@ LLDBSwigPython_CallOptionalMember
return result.release();
}
-SWIGEXPORT size_t
-LLDBSwigPython_CalculateNumChildren
+size_t
+lldb_private::LLDBSwigPython_CalculateNumChildren
(
PyObject *implementor,
uint32_t max
@@ -793,8 +737,8 @@ LLDBSwigPython_CalculateNumChildren
return ret_val;
}
-SWIGEXPORT PyObject*
-LLDBSwigPython_GetChildAtIndex
+PyObject*
+lldb_private::LLDBSwigPython_GetChildAtIndex
(
PyObject *implementor,
uint32_t idx
@@ -823,8 +767,8 @@ LLDBSwigPython_GetChildAtIndex
return result.release();
}
-SWIGEXPORT int
-LLDBSwigPython_GetIndexOfChildWithName
+int
+lldb_private::LLDBSwigPython_GetIndexOfChildWithName
(
PyObject *implementor,
const char* child_name
@@ -853,8 +797,8 @@ LLDBSwigPython_GetIndexOfChildWithName
return UINT32_MAX;
}
-SWIGEXPORT bool
-LLDBSwigPython_UpdateSynthProviderInstance
+bool
+lldb_private::LLDBSwigPython_UpdateSynthProviderInstance
(
PyObject *implementor
)
@@ -873,8 +817,8 @@ LLDBSwigPython_UpdateSynthProviderInstance
return ret_val;
}
-SWIGEXPORT bool
-LLDBSwigPython_MightHaveChildrenSynthProviderInstance
+bool
+lldb_private::LLDBSwigPython_MightHaveChildrenSynthProviderInstance
(
PyObject *implementor
)
@@ -893,8 +837,8 @@ LLDBSwigPython_MightHaveChildrenSynthProviderInstance
return ret_val;
}
-SWIGEXPORT PyObject*
-LLDBSwigPython_GetValueSynthProviderInstance
+PyObject*
+lldb_private::LLDBSwigPython_GetValueSynthProviderInstance
(
PyObject *implementor
)
@@ -921,8 +865,8 @@ LLDBSwigPython_GetValueSynthProviderInstance
return ret_val;
}
-SWIGEXPORT void*
-LLDBSWIGPython_CastPyObjectToSBData
+void*
+lldb_private::LLDBSWIGPython_CastPyObjectToSBData
(
PyObject* data
)
@@ -938,8 +882,8 @@ LLDBSWIGPython_CastPyObjectToSBData
}
-SWIGEXPORT void*
-LLDBSWIGPython_CastPyObjectToSBError
+void*
+lldb_private::LLDBSWIGPython_CastPyObjectToSBError
(
PyObject* data
)
@@ -955,8 +899,8 @@ LLDBSWIGPython_CastPyObjectToSBError
}
-SWIGEXPORT void*
-LLDBSWIGPython_CastPyObjectToSBValue
+void*
+lldb_private::LLDBSWIGPython_CastPyObjectToSBValue
(
PyObject* data
)
@@ -971,8 +915,8 @@ LLDBSWIGPython_CastPyObjectToSBValue
return sb_ptr;
}
-SWIGEXPORT void*
-LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo
+void*
+lldb_private::LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo
(
PyObject* data
)
@@ -987,8 +931,8 @@ LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo
return sb_ptr;
}
-SWIGEXPORT bool
-LLDBSwigPythonCallCommand
+bool
+lldb_private::LLDBSwigPythonCallCommand
(
const char *python_function_name,
const char *session_dictionary_name,
@@ -1026,8 +970,8 @@ LLDBSwigPythonCallCommand
return true;
}
-SWIGEXPORT bool
-LLDBSwigPythonCallCommandObject
+bool
+lldb_private::LLDBSwigPythonCallCommandObject
(
PyObject *implementor,
lldb::DebuggerSP& debugger,
@@ -1057,8 +1001,8 @@ LLDBSwigPythonCallCommandObject
return true;
}
-SWIGEXPORT void*
-LLDBSWIGPythonCreateOSPlugin
+void*
+lldb_private::LLDBSWIGPythonCreateOSPlugin
(
const char *python_class_name,
const char *session_dictionary_name,
@@ -1076,13 +1020,7 @@ LLDBSWIGPythonCreateOSPlugin
if (!pfunc.IsAllocated())
Py_RETURN_NONE;
- // FIXME: This leaks the SBProcess object
- lldb::SBProcess *process_sb = new lldb::SBProcess(process_sp);
- PythonObject process_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*process_sb));
- if (!process_arg.IsAllocated())
- Py_RETURN_NONE;
-
- auto result = pfunc(process_arg);
+ auto result = pfunc(ToSWIGWrapper(process_sp));
if (result.IsAllocated())
return result.release();
@@ -1090,8 +1028,8 @@ LLDBSWIGPythonCreateOSPlugin
Py_RETURN_NONE;
}
-SWIGEXPORT void*
-LLDBSWIGPython_CreateFrameRecognizer
+void*
+lldb_private::LLDBSWIGPython_CreateFrameRecognizer
(
const char *python_class_name,
const char *session_dictionary_name
@@ -1116,8 +1054,8 @@ LLDBSWIGPython_CreateFrameRecognizer
Py_RETURN_NONE;
}
-SWIGEXPORT PyObject*
-LLDBSwigPython_GetRecognizedArguments
+PyObject*
+lldb_private::LLDBSwigPython_GetRecognizedArguments
(
PyObject *implementor,
const lldb::StackFrameSP& frame_sp
@@ -1134,8 +1072,8 @@ LLDBSwigPython_GetRecognizedArguments
return result;
}
-SWIGEXPORT void*
-LLDBSWIGPython_GetDynamicSetting (void* module, const char* setting, const lldb::TargetSP& target_sp)
+void*
+lldb_private::LLDBSWIGPython_GetDynamicSetting (void* module, const char* setting, const lldb::TargetSP& target_sp)
{
if (!module || !setting)
Py_RETURN_NONE;
@@ -1147,21 +1085,15 @@ LLDBSWIGPython_GetDynamicSetting (void* module, const char* setting, const lldb:
if (!pfunc.IsAllocated())
Py_RETURN_NONE;
- lldb::SBTarget target_sb(target_sp);
- PythonObject target_arg(PyRefType::Owned, SBTypeToSWIGWrapper(target_sb));
- auto result = pfunc(target_arg, PythonString(setting));
+ auto result = pfunc(ToSWIGWrapper(target_sp), PythonString(setting));
return result.release();
}
-SWIGEXPORT bool
-LLDBSWIGPythonRunScriptKeywordProcess
-(const char* python_function_name,
-const char* session_dictionary_name,
-lldb::ProcessSP& process,
-std::string& output)
+bool lldb_private::LLDBSWIGPythonRunScriptKeywordProcess(
+ const char *python_function_name, const char *session_dictionary_name,
+ const lldb::ProcessSP &process, std::string &output) {
-{
if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
return false;
@@ -1173,17 +1105,15 @@ std::string& output)
if (!pfunc.IsAllocated())
return false;
- lldb::SBProcess process_sb(process);
- PythonObject process_arg(PyRefType::Owned, SBTypeToSWIGWrapper(process_sb));
- auto result = pfunc(process_arg, dict);
+ auto result = pfunc(ToSWIGWrapper(process), dict);
output = result.Str().GetString().str();
return true;
}
-SWIGEXPORT bool
-LLDBSWIGPythonRunScriptKeywordThread
+bool
+lldb_private::LLDBSWIGPythonRunScriptKeywordThread
(const char* python_function_name,
const char* session_dictionary_name,
lldb::ThreadSP& thread,
@@ -1210,14 +1140,10 @@ std::string& output)
return true;
}
-SWIGEXPORT bool
-LLDBSWIGPythonRunScriptKeywordTarget
-(const char* python_function_name,
-const char* session_dictionary_name,
-lldb::TargetSP& target,
-std::string& output)
+bool lldb_private::LLDBSWIGPythonRunScriptKeywordTarget(
+ const char *python_function_name, const char *session_dictionary_name,
+ const lldb::TargetSP &target, std::string &output) {
-{
if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
return false;
@@ -1229,17 +1155,15 @@ std::string& output)
if (!pfunc.IsAllocated())
return false;
- lldb::SBTarget target_sb(target);
- PythonObject target_arg(PyRefType::Owned, SBTypeToSWIGWrapper(target_sb));
- auto result = pfunc(target_arg, dict);
+ auto result = pfunc(ToSWIGWrapper(target), dict);
output = result.Str().GetString().str();
return true;
}
-SWIGEXPORT bool
-LLDBSWIGPythonRunScriptKeywordFrame
+bool
+lldb_private::LLDBSWIGPythonRunScriptKeywordFrame
(const char* python_function_name,
const char* session_dictionary_name,
lldb::StackFrameSP& frame,
@@ -1266,14 +1190,10 @@ std::string& output)
return true;
}
-SWIGEXPORT bool
-LLDBSWIGPythonRunScriptKeywordValue
-(const char* python_function_name,
-const char* session_dictionary_name,
-lldb::ValueObjectSP& value,
-std::string& output)
+bool lldb_private::LLDBSWIGPythonRunScriptKeywordValue(
+ const char *python_function_name, const char *session_dictionary_name,
+ const lldb::ValueObjectSP &value, std::string &output) {
-{
if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
return false;
@@ -1285,17 +1205,15 @@ std::string& output)
if (!pfunc.IsAllocated())
return false;
- lldb::SBValue value_sb(value);
- PythonObject value_arg(PyRefType::Owned, SBTypeToSWIGWrapper(value_sb));
- auto result = pfunc(value_arg, dict);
+ auto result = pfunc(ToSWIGWrapper(value), dict);
output = result.Str().GetString().str();
return true;
}
-SWIGEXPORT bool
-LLDBSwigPythonCallModuleInit
+bool
+lldb_private::LLDBSwigPythonCallModuleInit
(
const char *python_module_name,
const char *session_dictionary_name,
@@ -1322,16 +1240,9 @@ LLDBSwigPythonCallModuleInit
return true;
}
-%}
-
-
-%runtime %{
-// Forward declaration to be inserted at the start of LLDBWrapPython.h
-#include "lldb/API/SBDebugger.h"
-#include "lldb/API/SBValue.h"
-SWIGEXPORT lldb::ValueObjectSP
-LLDBSWIGPython_GetValueObjectSPFromSBValue (void* data)
+lldb::ValueObjectSP
+lldb_private::LLDBSWIGPython_GetValueObjectSPFromSBValue (void* data)
{
lldb::ValueObjectSP valobj_sp;
if (data)
@@ -1342,22 +1253,8 @@ LLDBSWIGPython_GetValueObjectSPFromSBValue (void* data)
return valobj_sp;
}
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void LLDBSwigPythonCallPythonLogOutputCallback(const char *str, void *baton);
-
-#ifdef __cplusplus
-}
-#endif
-%}
-
-%wrapper %{
-
-
// For the LogOutputCallback functions
-void LLDBSwigPythonCallPythonLogOutputCallback(const char *str, void *baton) {
+static void LLDBSwigPythonCallPythonLogOutputCallback(const char *str, void *baton) {
if (baton != Py_None) {
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
PyObject *result = PyObject_CallFunction(reinterpret_cast<PyObject*>(baton), const_cast<char*>("s"), str);
diff --git a/lldb/bindings/python/python.swig b/lldb/bindings/python/python.swig
index 9dc4ab87a4bd..5dcbd68d8544 100644
--- a/lldb/bindings/python/python.swig
+++ b/lldb/bindings/python/python.swig
@@ -121,6 +121,7 @@ def lldb_iter(obj, getsize, getelem):
%{
#include "../source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h"
+#include "../source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h"
#include "../bindings/python/python-swigsafecast.swig"
using namespace lldb_private;
using namespace lldb_private::python;
diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h
index 64081f79205d..1c771330cddc 100644
--- a/lldb/include/lldb/API/SBDebugger.h
+++ b/lldb/include/lldb/API/SBDebugger.h
@@ -126,6 +126,8 @@ public:
FILE *GetErrorFileHandle();
+ SBError SetInputString(const char *data);
+
SBError SetInputFile(SBFile file);
SBError SetOutputFile(SBFile file);
diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h
index 5a6908f040b1..abd9ebf07407 100644
--- a/lldb/include/lldb/API/SBTarget.h
+++ b/lldb/include/lldb/API/SBTarget.h
@@ -336,6 +336,11 @@ public:
/// unit from the Architecture's code bus
uint32_t GetCodeByteSize();
+ /// Gets the target.max-children-count value
+ /// It should be used to limit the number of
+ /// children of large data structures to be displayed.
+ uint32_t GetMaximumNumberOfChildrenToDisplay() const;
+
/// Set the base load address for a module section.
///
/// \param[in] section
diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h
index 69be02545b35..a8578abec6b7 100644
--- a/lldb/include/lldb/API/SBValue.h
+++ b/lldb/include/lldb/API/SBValue.h
@@ -246,6 +246,12 @@ public:
bool SetData(lldb::SBData &data, lldb::SBError &error);
+ /// Creates a copy of the SBValue with a new name and setting the current
+ /// SBValue as its parent. It should be used when we want to change the
+ /// name of a SBValue without modifying the actual SBValue itself
+ /// (e.g. sythetic child provider).
+ lldb::SBValue Clone(const char *new_name);
+
lldb::SBDeclaration GetDeclaration();
/// Find out if a SBValue might have children.
diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h
index f0849c9ac950..1ab21bec54c9 100644
--- a/lldb/include/lldb/Core/Debugger.h
+++ b/lldb/include/lldb/Core/Debugger.h
@@ -176,7 +176,13 @@ public:
repro::DataRecorder *GetInputRecorder();
- void SetInputFile(lldb::FileSP file, repro::DataRecorder *recorder = nullptr);
+ Status SetInputString(const char *data);
+
+ // This method will setup data recorder if reproducer enabled.
+ // On reply mode this method should take instructions from reproducer file.
+ Status SetInputFile(lldb::FileSP file);
+
+ void SetInputFile(lldb::FileSP file, repro::DataRecorder *recorder);
void SetOutputFile(lldb::FileSP file);
diff --git a/lldb/include/lldb/Interpreter/OptionGroupFormat.h b/lldb/include/lldb/Interpreter/OptionGroupFormat.h
index 2d445b8a6c20..551688b0d25f 100644
--- a/lldb/include/lldb/Interpreter/OptionGroupFormat.h
+++ b/lldb/include/lldb/Interpreter/OptionGroupFormat.h
@@ -16,6 +16,9 @@
namespace lldb_private {
+typedef std::vector<std::tuple<lldb::CommandArgumentType, const char *>>
+ OptionGroupFormatUsageTextVector;
+
// OptionGroupFormat
class OptionGroupFormat : public OptionGroup {
@@ -30,7 +33,10 @@ public:
uint64_t default_byte_size =
UINT64_MAX, // Pass UINT64_MAX to disable the "--size" option
uint64_t default_count =
- UINT64_MAX); // Pass UINT64_MAX to disable the "--count" option
+ UINT64_MAX, // Pass UINT64_MAX to disable the "--count" option
+ OptionGroupFormatUsageTextVector usage_text_vector = {}
+ // Use to override default option usage text with the command specific one
+ );
~OptionGroupFormat() override = default;
@@ -73,6 +79,7 @@ protected:
char m_prev_gdb_format;
char m_prev_gdb_size;
bool m_has_gdb_format;
+ OptionDefinition m_option_definitions[4];
};
} // namespace lldb_private
diff --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h
index 4ccd7f92064d..0a8b38b2c642 100644
--- a/lldb/include/lldb/Symbol/ObjectFile.h
+++ b/lldb/include/lldb/Symbol/ObjectFile.h
@@ -19,6 +19,7 @@
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/UUID.h"
#include "lldb/lldb-private.h"
+#include "llvm/Support/Threading.h"
#include "llvm/Support/VersionTuple.h"
namespace lldb_private {
@@ -322,12 +323,26 @@ public:
/// Gets the symbol table for the currently selected architecture (and
/// object for archives).
///
- /// Symbol table parsing can be deferred by ObjectFile instances until this
- /// accessor is called the first time.
+ /// This function will manage when ParseSymtab(...) is called to actually do
+ /// the symbol table parsing in each plug-in. This function will take care of
+ /// taking all the necessary locks and finalizing the symbol table when the
+ /// symbol table does get parsed.
///
/// \return
/// The symbol table for this object file.
- virtual Symtab *GetSymtab() = 0;
+ Symtab *GetSymtab();
+
+ /// Parse the symbol table into the provides symbol table object.
+ ///
+ /// Symbol table parsing will be done once when this function is called by
+ /// each object file plugin. All of the necessary locks will already be
+ /// acquired before this function is called and the symbol table object to
+ /// populate is supplied as an argument and doesn't need to be created by
+ /// each plug-in.
+ ///
+ /// \param
+ /// The symbol table to populate.
+ virtual void ParseSymtab(Symtab &symtab) = 0;
/// Perform relocations on the section if necessary.
///
@@ -708,7 +723,12 @@ protected:
const lldb::addr_t m_memory_addr;
std::unique_ptr<lldb_private::SectionList> m_sections_up;
std::unique_ptr<lldb_private::Symtab> m_symtab_up;
- uint32_t m_synthetic_symbol_idx;
+ /// We need a llvm::once_flag that we can use to avoid locking the module
+ /// lock and deadlocking LLDB. See comments in ObjectFile::GetSymtab() for
+ /// the full details. We also need to be able to clear the symbol table, so we
+ /// need to use a std::unique_ptr to a llvm::once_flag so if we clear the
+ /// symbol table, we can have a new once flag to use when it is created again.
+ std::unique_ptr<llvm::once_flag> m_symtab_once_up;
/// Sets the architecture for a module. At present the architecture can
/// only be set if it is invalid. It is not allowed to switch from one
diff --git a/lldb/include/lldb/Symbol/Symtab.h b/lldb/include/lldb/Symbol/Symtab.h
index e1ad0dfd2eb8..e5d21c1bf4b3 100644
--- a/lldb/include/lldb/Symbol/Symtab.h
+++ b/lldb/include/lldb/Symbol/Symtab.h
@@ -119,20 +119,13 @@ public:
lldb::addr_t file_addr, std::function<bool(Symbol *)> const &callback);
void FindFunctionSymbols(ConstString name, uint32_t name_type_mask,
SymbolContextList &sc_list);
- void CalculateSymbolSizes();
void SortSymbolIndexesByValue(std::vector<uint32_t> &indexes,
bool remove_duplicates) const;
static void DumpSymbolHeader(Stream *s);
- void Finalize() {
- // Shrink to fit the symbols so we don't waste memory
- if (m_symbols.capacity() > m_symbols.size()) {
- collection new_symbols(m_symbols.begin(), m_symbols.end());
- m_symbols.swap(new_symbols);
- }
- }
+ void Finalize();
void AppendSymbolNamesToMap(const IndexCollection &indexes,
bool add_demangled, bool add_mangled,
diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h
index 956b29e45dba..26127359a322 100644
--- a/lldb/include/lldb/Target/Platform.h
+++ b/lldb/include/lldb/Target/Platform.h
@@ -310,25 +310,7 @@ public:
/// Get the platform's supported architectures in the order in which they
/// should be searched.
- ///
- /// \param[in] idx
- /// A zero based architecture index
- ///
- /// \param[out] arch
- /// A copy of the architecture at index if the return value is
- /// \b true.
- ///
- /// \return
- /// \b true if \a arch was filled in and is valid, \b false
- /// otherwise.
- virtual bool GetSupportedArchitectureAtIndex(uint32_t idx,
- ArchSpec &arch);
-
- /// Get the platform's supported architectures in the order in which they
- /// should be searched.
- /// NB: This implementation is mutually recursive with
- /// GetSupportedArchitectureAtIndex. Subclasses should implement one of them.
- virtual std::vector<ArchSpec> GetSupportedArchitectures();
+ virtual std::vector<ArchSpec> GetSupportedArchitectures() = 0;
virtual size_t GetSoftwareBreakpointTrapOpcode(Target &target,
BreakpointSite *bp_site);
@@ -971,10 +953,6 @@ private:
bool GetCachedSharedModule(const ModuleSpec &module_spec,
lldb::ModuleSP &module_sp, bool *did_create_ptr);
- Status LoadCachedExecutable(const ModuleSpec &module_spec,
- lldb::ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr);
-
FileSpec GetModuleCacheRoot();
};
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index 4627502abd25..e27cb8cbf2aa 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -1762,7 +1762,7 @@ public:
///
/// If load_addr is within the address space the process has mapped
/// range_info will be filled in with the start and end of that range as
- /// well as the permissions for that range and range_info. GetMapped will
+ /// well as the permissions for that range and range_info.GetMapped will
/// return true.
///
/// If load_addr is outside any mapped region then range_info will have its
@@ -1771,21 +1771,23 @@ public:
/// there are no valid mapped ranges between load_addr and the end of the
/// process address space.
///
- /// GetMemoryRegionInfo calls DoGetMemoryRegionInfo. Override that function in
- /// process subclasses.
+ /// GetMemoryRegionInfo will only return an error if it is unimplemented for
+ /// the current process.
///
/// \param[in] load_addr
- /// The load address to query the range_info for. May include non
- /// address bits, these will be removed by the the ABI plugin if there is
- /// one.
+ /// The load address to query the range_info for.
///
/// \param[out] range_info
/// An range_info value containing the details of the range.
///
/// \return
/// An error value.
- Status GetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &range_info);
+ virtual Status GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) {
+ Status error;
+ error.SetErrorString("Process::GetMemoryRegionInfo() not supported");
+ return error;
+ }
/// Obtain all the mapped memory regions within this process.
///
@@ -2605,26 +2607,6 @@ protected:
virtual size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
Status &error) = 0;
- /// DoGetMemoryRegionInfo is called by GetMemoryRegionInfo after it has
- /// removed non address bits from load_addr. Override this method in
- /// subclasses of Process.
- ///
- /// See GetMemoryRegionInfo for details of the logic.
- ///
- /// \param[in] load_addr
- /// The load address to query the range_info for. (non address bits
- /// removed)
- ///
- /// \param[out] range_info
- /// An range_info value containing the details of the range.
- ///
- /// \return
- /// An error value.
- virtual Status DoGetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &range_info) {
- return Status("Process::DoGetMemoryRegionInfo() not supported");
- }
-
lldb::StateType GetPrivateState();
/// The "private" side of resuming a process. This doesn't alter the state
diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp
index 4bb23c3e705c..844b91de4cd0 100644
--- a/lldb/source/API/SBDebugger.cpp
+++ b/lldb/source/API/SBDebugger.cpp
@@ -327,12 +327,32 @@ void SBDebugger::SkipAppInitFiles(bool b) {
void SBDebugger::SetInputFileHandle(FILE *fh, bool transfer_ownership) {
LLDB_RECORD_METHOD(void, SBDebugger, SetInputFileHandle, (FILE *, bool), fh,
transfer_ownership);
- SetInputFile((FileSP)std::make_shared<NativeFile>(fh, transfer_ownership));
+ if (m_opaque_sp)
+ m_opaque_sp->SetInputFile(
+ (FileSP)std::make_shared<NativeFile>(fh, transfer_ownership));
}
-SBError SBDebugger::SetInputFile(FileSP file_sp) {
- LLDB_RECORD_METHOD(SBError, SBDebugger, SetInputFile, (FileSP), file_sp);
- return LLDB_RECORD_RESULT(SetInputFile(SBFile(file_sp)));
+SBError SBDebugger::SetInputString(const char *data) {
+ LLDB_RECORD_METHOD(SBError, SBDebugger, SetInputString, (const char *), data);
+ SBError sb_error;
+ if (data == nullptr) {
+ sb_error.SetErrorString("String data is null");
+ return LLDB_RECORD_RESULT(sb_error);
+ }
+
+ size_t size = strlen(data);
+ if (size == 0) {
+ sb_error.SetErrorString("String data is empty");
+ return LLDB_RECORD_RESULT(sb_error);
+ }
+
+ if (!m_opaque_sp) {
+ sb_error.SetErrorString("invalid debugger");
+ return LLDB_RECORD_RESULT(sb_error);
+ }
+
+ sb_error.SetError(m_opaque_sp->SetInputString(data));
+ return LLDB_RECORD_RESULT(sb_error);
}
// Shouldn't really be settable after initialization as this could cause lots
@@ -346,36 +366,15 @@ SBError SBDebugger::SetInputFile(SBFile file) {
error.ref().SetErrorString("invalid debugger");
return LLDB_RECORD_RESULT(error);
}
-
- repro::DataRecorder *recorder = nullptr;
- if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator())
- recorder = g->GetOrCreate<repro::CommandProvider>().GetNewRecorder();
-
- FileSP file_sp = file.m_opaque_sp;
-
- static std::unique_ptr<repro::MultiLoader<repro::CommandProvider>> loader =
- repro::MultiLoader<repro::CommandProvider>::Create(
- repro::Reproducer::Instance().GetLoader());
- if (loader) {
- llvm::Optional<std::string> nextfile = loader->GetNextFile();
- FILE *fh = nextfile ? FileSystem::Instance().Fopen(nextfile->c_str(), "r")
- : nullptr;
- // FIXME Jonas Devlieghere: shouldn't this error be propagated out to the
- // reproducer somehow if fh is NULL?
- if (fh) {
- file_sp = std::make_shared<NativeFile>(fh, true);
- }
- }
-
- if (!file_sp || !file_sp->IsValid()) {
- error.ref().SetErrorString("invalid file");
- return LLDB_RECORD_RESULT(error);
- }
-
- m_opaque_sp->SetInputFile(file_sp, recorder);
+ error.SetError(m_opaque_sp->SetInputFile(file.m_opaque_sp));
return LLDB_RECORD_RESULT(error);
}
+SBError SBDebugger::SetInputFile(FileSP file_sp) {
+ LLDB_RECORD_METHOD(SBError, SBDebugger, SetInputFile, (FileSP), file_sp);
+ return LLDB_RECORD_RESULT(SetInputFile(SBFile(file_sp)));
+}
+
SBError SBDebugger::SetOutputFile(FileSP file_sp) {
LLDB_RECORD_METHOD(SBError, SBDebugger, SetOutputFile, (FileSP), file_sp);
return LLDB_RECORD_RESULT(SetOutputFile(SBFile(file_sp)));
@@ -1771,6 +1770,7 @@ template <> void RegisterMethods<SBDebugger>(Registry &R) {
LLDB_REGISTER_METHOD(bool, SBDebugger, GetAsync, ());
LLDB_REGISTER_METHOD(void, SBDebugger, SkipLLDBInitFiles, (bool));
LLDB_REGISTER_METHOD(void, SBDebugger, SkipAppInitFiles, (bool));
+ LLDB_REGISTER_METHOD(SBError, SBDebugger, SetInputString, (const char *));
LLDB_REGISTER_METHOD(void, SBDebugger, SetInputFileHandle, (FILE *, bool));
LLDB_REGISTER_METHOD(FILE *, SBDebugger, GetInputFileHandle, ());
LLDB_REGISTER_METHOD(FILE *, SBDebugger, GetOutputFileHandle, ());
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index 98158f457a04..dc79c77fee9e 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -1745,6 +1745,16 @@ uint32_t SBTarget::GetCodeByteSize() {
return 0;
}
+uint32_t SBTarget::GetMaximumNumberOfChildrenToDisplay() const {
+ LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBTarget, GetMaximumNumberOfChildrenToDisplay);
+
+ TargetSP target_sp(GetSP());
+ if(target_sp){
+ return target_sp->GetMaximumNumberOfChildrenToDisplay();
+ }
+ return 0;
+}
+
uint32_t SBTarget::GetAddressByteSize() {
LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBTarget, GetAddressByteSize);
@@ -2679,6 +2689,7 @@ void RegisterMethods<SBTarget>(Registry &R) {
LLDB_REGISTER_METHOD(const char *, SBTarget, GetTriple, ());
LLDB_REGISTER_METHOD(uint32_t, SBTarget, GetDataByteSize, ());
LLDB_REGISTER_METHOD(uint32_t, SBTarget, GetCodeByteSize, ());
+ LLDB_REGISTER_METHOD_CONST(uint32_t, SBTarget, GetMaximumNumberOfChildrenToDisplay,());
LLDB_REGISTER_METHOD(uint32_t, SBTarget, GetAddressByteSize, ());
LLDB_REGISTER_METHOD(lldb::SBModule, SBTarget, GetModuleAtIndex,
(uint32_t));
diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp
index 9faee102c5e3..e3325b8d36fa 100644
--- a/lldb/source/API/SBValue.cpp
+++ b/lldb/source/API/SBValue.cpp
@@ -1431,6 +1431,18 @@ bool SBValue::SetData(lldb::SBData &data, SBError &error) {
return ret;
}
+lldb::SBValue SBValue::Clone(const char *new_name) {
+ LLDB_RECORD_METHOD(lldb::SBValue, SBValue, Clone, (const char *), new_name);
+
+ ValueLocker locker;
+ lldb::ValueObjectSP value_sp(GetSP(locker));
+
+ if (value_sp)
+ return lldb::SBValue(value_sp->Clone(ConstString(new_name)));
+ else
+ return lldb::SBValue();
+}
+
lldb::SBDeclaration SBValue::GetDeclaration() {
LLDB_RECORD_METHOD_NO_ARGS(lldb::SBDeclaration, SBValue, GetDeclaration);
@@ -1656,6 +1668,7 @@ void RegisterMethods<SBValue>(Registry &R) {
LLDB_REGISTER_METHOD(lldb::SBData, SBValue, GetData, ());
LLDB_REGISTER_METHOD(bool, SBValue, SetData,
(lldb::SBData &, lldb::SBError &));
+ LLDB_REGISTER_METHOD(lldb::SBValue, SBValue, Clone, (const char *));
LLDB_REGISTER_METHOD(lldb::SBDeclaration, SBValue, GetDeclaration, ());
LLDB_REGISTER_METHOD(lldb::SBWatchpoint, SBValue, Watch,
(bool, bool, bool, lldb::SBError &));
diff --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp
index f27d4bd7e4b2..094ce6f8558f 100644
--- a/lldb/source/Commands/CommandObjectMemory.cpp
+++ b/lldb/source/Commands/CommandObjectMemory.cpp
@@ -1222,7 +1222,15 @@ public:
interpreter, "memory write",
"Write to the memory of the current target process.", nullptr,
eCommandRequiresProcess | eCommandProcessMustBeLaunched),
- m_option_group(), m_format_options(eFormatBytes, 1, UINT64_MAX),
+ m_option_group(),
+ m_format_options(
+ eFormatBytes, 1, UINT64_MAX,
+ {std::make_tuple(
+ eArgTypeFormat,
+ "The format to use for each of the value to be written."),
+ std::make_tuple(
+ eArgTypeByteSize,
+ "The size in bytes to write from input file or each value.")}),
m_memory_options() {
CommandArgumentEntry arg1;
CommandArgumentEntry arg2;
@@ -1240,6 +1248,7 @@ public:
// Define the first (and only) variant of this arg.
value_arg.arg_type = eArgTypeValue;
value_arg.arg_repetition = eArgRepeatPlus;
+ value_arg.arg_opt_set_association = LLDB_OPT_SET_1;
// There is only one variant this argument could be; put it into the
// argument entry.
@@ -1278,6 +1287,12 @@ protected:
m_cmd_name.c_str());
return false;
}
+ if (argc > 1) {
+ result.AppendErrorWithFormat(
+ "%s takes only a destination address when writing file contents.\n",
+ m_cmd_name.c_str());
+ return false;
+ }
} else if (argc < 2) {
result.AppendErrorWithFormat(
"%s takes a destination address and at least one value.\n",
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index 32dcfb1ce17b..ae454fae3322 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -45,6 +45,7 @@
#include "lldb/Utility/Listener.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Reproducer.h"
+#include "lldb/Utility/ReproducerProvider.h"
#include "lldb/Utility/State.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StreamCallback.h"
@@ -75,6 +76,14 @@
#include <string>
#include <system_error>
+// Includes for pipe()
+#if defined(_WIN32)
+#include <fcntl.h>
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
namespace lldb_private {
class Address;
}
@@ -810,6 +819,86 @@ void Debugger::SetAsyncExecution(bool async_execution) {
repro::DataRecorder *Debugger::GetInputRecorder() { return m_input_recorder; }
+static inline int OpenPipe(int fds[2], std::size_t size) {
+#ifdef _WIN32
+ return _pipe(fds, size, O_BINARY);
+#else
+ (void)size;
+ return pipe(fds);
+#endif
+}
+
+Status Debugger::SetInputString(const char *data) {
+ Status result;
+ enum PIPES { READ, WRITE }; // Indexes for the read and write fds
+ int fds[2] = {-1, -1};
+
+ if (data == nullptr) {
+ result.SetErrorString("String data is null");
+ return result;
+ }
+
+ size_t size = strlen(data);
+ if (size == 0) {
+ result.SetErrorString("String data is empty");
+ return result;
+ }
+
+ if (OpenPipe(fds, size) != 0) {
+ result.SetErrorString(
+ "can't create pipe file descriptors for LLDB commands");
+ return result;
+ }
+
+ write(fds[WRITE], data, size);
+ // Close the write end of the pipe, so that the command interpreter will exit
+ // when it consumes all the data.
+ llvm::sys::Process::SafelyCloseFileDescriptor(fds[WRITE]);
+
+ // Open the read file descriptor as a FILE * that we can return as an input
+ // handle.
+ FILE *commands_file = fdopen(fds[READ], "rb");
+ if (commands_file == nullptr) {
+ result.SetErrorStringWithFormat("fdopen(%i, \"rb\") failed (errno = %i) "
+ "when trying to open LLDB commands pipe",
+ fds[READ], errno);
+ llvm::sys::Process::SafelyCloseFileDescriptor(fds[READ]);
+ return result;
+ }
+
+ return SetInputFile(
+ (FileSP)std::make_shared<NativeFile>(commands_file, true));
+}
+
+Status Debugger::SetInputFile(FileSP file_sp) {
+ Status error;
+ repro::DataRecorder *recorder = nullptr;
+ if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator())
+ recorder = g->GetOrCreate<repro::CommandProvider>().GetNewRecorder();
+
+ static std::unique_ptr<repro::MultiLoader<repro::CommandProvider>> loader =
+ repro::MultiLoader<repro::CommandProvider>::Create(
+ repro::Reproducer::Instance().GetLoader());
+ if (loader) {
+ llvm::Optional<std::string> nextfile = loader->GetNextFile();
+ FILE *fh = nextfile ? FileSystem::Instance().Fopen(nextfile->c_str(), "r")
+ : nullptr;
+ // FIXME Jonas Devlieghere: shouldn't this error be propagated out to the
+ // reproducer somehow if fh is NULL?
+ if (fh) {
+ file_sp = std::make_shared<NativeFile>(fh, true);
+ }
+ }
+
+ if (!file_sp || !file_sp->IsValid()) {
+ error.SetErrorString("invalid file");
+ return error;
+ }
+
+ SetInputFile(file_sp, recorder);
+ return error;
+}
+
void Debugger::SetInputFile(FileSP file_sp, repro::DataRecorder *recorder) {
assert(file_sp && file_sp->IsValid());
m_input_recorder = recorder;
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index bd0a667171a5..cbecbb9aa5fe 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -1379,12 +1379,15 @@ void Module::PreloadSymbols() {
if (!sym_file)
return;
- // Prime the symbol file first, since it adds symbols to the symbol table.
- sym_file->PreloadSymbols();
-
- // Now we can prime the symbol table.
+ // Load the object file symbol table and any symbols from the SymbolFile that
+ // get appended using SymbolFile::AddSymbols(...).
if (Symtab *symtab = sym_file->GetSymtab())
symtab->PreloadSymbols();
+
+ // Now let the symbol file preload its data and the symbol table will be
+ // available without needing to take the module lock.
+ sym_file->PreloadSymbols();
+
}
void Module::SetSymbolFileFileSpec(const FileSpec &file) {
diff --git a/lldb/source/Interpreter/CommandObject.cpp b/lldb/source/Interpreter/CommandObject.cpp
index 64b23d04abea..dcae27ff5479 100644
--- a/lldb/source/Interpreter/CommandObject.cpp
+++ b/lldb/source/Interpreter/CommandObject.cpp
@@ -454,6 +454,9 @@ void CommandObject::GetFormattedCommandArguments(Stream &str,
opt_set_mask == LLDB_OPT_SET_ALL
? m_arguments[i]
: OptSetFiltered(opt_set_mask, m_arguments[i]);
+ // This argument is not associated with the current option set, so skip it.
+ if (arg_entry.empty())
+ continue;
int num_alternatives = arg_entry.size();
if ((num_alternatives == 2) && IsPairType(arg_entry[0].arg_repetition)) {
diff --git a/lldb/source/Interpreter/OptionGroupFormat.cpp b/lldb/source/Interpreter/OptionGroupFormat.cpp
index 1cc5e70282c1..a2ca9ff39818 100644
--- a/lldb/source/Interpreter/OptionGroupFormat.cpp
+++ b/lldb/source/Interpreter/OptionGroupFormat.cpp
@@ -16,15 +16,7 @@
using namespace lldb;
using namespace lldb_private;
-OptionGroupFormat::OptionGroupFormat(lldb::Format default_format,
- uint64_t default_byte_size,
- uint64_t default_count)
- : m_format(default_format, default_format),
- m_byte_size(default_byte_size, default_byte_size),
- m_count(default_count, default_count), m_prev_gdb_format('x'),
- m_prev_gdb_size('w') {}
-
-static constexpr OptionDefinition g_option_table[] = {
+static constexpr OptionDefinition g_default_option_definitions[] = {
{LLDB_OPT_SET_1, false, "format", 'f', OptionParser::eRequiredArgument,
nullptr, {}, 0, eArgTypeFormat,
"Specify a format to be used for display."},
@@ -39,8 +31,34 @@ static constexpr OptionDefinition g_option_table[] = {
"The number of total items to display."},
};
+OptionGroupFormat::OptionGroupFormat(
+ lldb::Format default_format, uint64_t default_byte_size,
+ uint64_t default_count, OptionGroupFormatUsageTextVector usage_text_vector)
+ : m_format(default_format, default_format),
+ m_byte_size(default_byte_size, default_byte_size),
+ m_count(default_count, default_count), m_prev_gdb_format('x'),
+ m_prev_gdb_size('w') {
+ // Copy the default option definitions.
+ std::copy(std::begin(g_default_option_definitions),
+ std::end(g_default_option_definitions),
+ std::begin(m_option_definitions));
+
+ for (auto usage_text_tuple : usage_text_vector) {
+ switch (std::get<0>(usage_text_tuple)) {
+ case eArgTypeFormat:
+ m_option_definitions[0].usage_text = std::get<1>(usage_text_tuple);
+ break;
+ case eArgTypeByteSize:
+ m_option_definitions[2].usage_text = std::get<1>(usage_text_tuple);
+ break;
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+ }
+}
+
llvm::ArrayRef<OptionDefinition> OptionGroupFormat::GetDefinitions() {
- auto result = llvm::makeArrayRef(g_option_table);
+ auto result = llvm::makeArrayRef(m_option_definitions);
if (m_byte_size.GetDefaultValue() < UINT64_MAX) {
if (m_count.GetDefaultValue() < UINT64_MAX)
return result;
@@ -54,7 +72,7 @@ Status OptionGroupFormat::SetOptionValue(uint32_t option_idx,
llvm::StringRef option_arg,
ExecutionContext *execution_context) {
Status error;
- const int short_option = g_option_table[option_idx].short_option;
+ const int short_option = m_option_definitions[option_idx].short_option;
switch (short_option) {
case 'f':
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index 50e9f7827838..1437d7b58293 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -516,7 +516,7 @@ CppModuleConfiguration GetModuleConfig(lldb::LanguageType language,
// Try to create a configuration from the files. If there is no valid
// configuration possible with the files, this just returns an invalid
// configuration.
- return CppModuleConfiguration(files);
+ return CppModuleConfiguration(files, target->GetArchitecture().GetTriple());
}
bool ClangUserExpression::PrepareForParsing(
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
index ffab16b1682b..befb1f125406 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
@@ -10,6 +10,7 @@
#include "ClangHost.h"
#include "lldb/Host/FileSystem.h"
+#include "llvm/ADT/Triple.h"
using namespace lldb_private;
@@ -30,7 +31,35 @@ bool CppModuleConfiguration::SetOncePath::TrySet(llvm::StringRef path) {
return false;
}
-bool CppModuleConfiguration::analyzeFile(const FileSpec &f) {
+static llvm::SmallVector<std::string, 2>
+getTargetIncludePaths(const llvm::Triple &triple) {
+ llvm::SmallVector<std::string, 2> paths;
+ if (!triple.str().empty()) {
+ paths.push_back("/usr/include/" + triple.str());
+ if (!triple.getArchName().empty() ||
+ triple.getOSAndEnvironmentName().empty())
+ paths.push_back(("/usr/include/" + triple.getArchName() + "-" +
+ triple.getOSAndEnvironmentName())
+ .str());
+ }
+ return paths;
+}
+
+/// Returns the include path matching the given pattern for the given file
+/// path (or None if the path doesn't match the pattern).
+static llvm::Optional<llvm::StringRef>
+guessIncludePath(llvm::StringRef path_to_file, llvm::StringRef pattern) {
+ if (pattern.empty())
+ return llvm::NoneType();
+ size_t pos = path_to_file.find(pattern);
+ if (pos == llvm::StringRef::npos)
+ return llvm::NoneType();
+
+ return path_to_file.substr(0, pos + pattern.size());
+}
+
+bool CppModuleConfiguration::analyzeFile(const FileSpec &f,
+ const llvm::Triple &triple) {
using namespace llvm::sys::path;
// Convert to slashes to make following operations simpler.
std::string dir_buffer = convert_to_slash(f.GetDirectory().GetStringRef());
@@ -43,15 +72,25 @@ bool CppModuleConfiguration::analyzeFile(const FileSpec &f) {
// need to be specified in the header search.
if (libcpp_regex.match(f.GetPath()) &&
parent_path(posix_dir, Style::posix).endswith("c++")) {
- return m_std_inc.TrySet(posix_dir);
+ if (!m_std_inc.TrySet(posix_dir))
+ return false;
+ if (triple.str().empty())
+ return true;
+
+ posix_dir.consume_back("c++/v1");
+ // Check if this is a target-specific libc++ include directory.
+ return m_std_target_inc.TrySet(
+ (posix_dir + triple.str() + "/c++/v1").str());
}
- // Check for /usr/include. On Linux this might be /usr/include/bits, so
- // we should remove that '/bits' suffix to get the actual include directory.
- if (posix_dir.endswith("/usr/include/bits"))
- posix_dir.consume_back("/bits");
- if (posix_dir.endswith("/usr/include"))
- return m_c_inc.TrySet(posix_dir);
+ llvm::Optional<llvm::StringRef> inc_path;
+ // Target specific paths contains /usr/include, so we check them first
+ for (auto &path : getTargetIncludePaths(triple)) {
+ if ((inc_path = guessIncludePath(posix_dir, path)))
+ return m_c_target_inc.TrySet(*inc_path);
+ }
+ if ((inc_path = guessIncludePath(posix_dir, "/usr/include")))
+ return m_c_inc.TrySet(*inc_path);
// File wasn't interesting, continue analyzing.
return true;
@@ -92,11 +131,11 @@ bool CppModuleConfiguration::hasValidConfig() {
}
CppModuleConfiguration::CppModuleConfiguration(
- const FileSpecList &support_files) {
+ const FileSpecList &support_files, const llvm::Triple &triple) {
// Analyze all files we were given to build the configuration.
bool error = !llvm::all_of(support_files,
std::bind(&CppModuleConfiguration::analyzeFile,
- this, std::placeholders::_1));
+ this, std::placeholders::_1, triple));
// If we have a valid configuration at this point, set the
// include directories and module list that should be used.
if (!error && hasValidConfig()) {
@@ -109,6 +148,10 @@ CppModuleConfiguration::CppModuleConfiguration(
// This order matches the way Clang orders these directories.
m_include_dirs = {m_std_inc.Get().str(), m_resource_inc,
m_c_inc.Get().str()};
+ if (m_c_target_inc.Valid())
+ m_include_dirs.push_back(m_c_target_inc.Get().str());
+ if (m_std_target_inc.Valid())
+ m_include_dirs.push_back(m_std_target_inc.Get().str());
m_imported_modules = {"std"};
}
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
index 907db5d625dc..5db8abbdbdf3 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
@@ -42,8 +42,15 @@ class CppModuleConfiguration {
/// If valid, the include path used for the std module.
SetOncePath m_std_inc;
+ /// If valid, the per-target include path used for the std module.
+ /// This is an optional path only required on some systems.
+ SetOncePath m_std_target_inc;
/// If valid, the include path to the C library (e.g. /usr/include).
SetOncePath m_c_inc;
+ /// If valid, the include path to target-specific C library files
+ /// (e.g. /usr/include/x86_64-linux-gnu).
+ /// This is an optional path only required on some systems.
+ SetOncePath m_c_target_inc;
/// The Clang resource include path for this configuration.
std::string m_resource_inc;
@@ -53,11 +60,13 @@ class CppModuleConfiguration {
/// Analyze a given source file to build the current configuration.
/// Returns false iff there was a fatal error that makes analyzing any
/// further files pointless as the configuration is now invalid.
- bool analyzeFile(const FileSpec &f);
+ bool analyzeFile(const FileSpec &f, const llvm::Triple &triple);
public:
/// Creates a configuration by analyzing the given list of used source files.
- explicit CppModuleConfiguration(const FileSpecList &support_files);
+ /// The triple (if valid) is used to search for target-specific include paths.
+ explicit CppModuleConfiguration(const FileSpecList &support_files,
+ const llvm::Triple &triple);
/// Creates an empty and invalid configuration.
CppModuleConfiguration() = default;
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 83e8e52b86f2..f1925990e94a 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -914,11 +914,21 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
stl_deref_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
+ RegularExpression("^std::optional<.+>(( )?&)?$"),
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ stl_synth_flags,
+ "lldb.formatters.cpp.gnu_libstdcpp.StdOptionalSynthProvider")));
+ cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
RegularExpression("^std::multiset<.+> >(( )?&)?$"),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_deref_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
+ RegularExpression("^std::unordered_(multi)?(map|set)<.+> >$"),
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ stl_deref_flags,
+ "lldb.formatters.cpp.gnu_libstdcpp.StdUnorderedMapSynthProvider")));
+ cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$"),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
@@ -928,9 +938,15 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdForwardListSynthProvider")));
+
stl_summary_flags.SetDontShowChildren(false);
stl_summary_flags.SetSkipPointers(false);
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
+ RegularExpression("^std::optional<.+>(( )?&)?$"),
+ TypeSummaryImplSP(new ScriptSummaryFormat(
+ stl_summary_flags,
+ "lldb.formatters.cpp.gnu_libstdcpp.StdOptionalSummaryProvider")));
+ cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
RegularExpression("^std::bitset<.+>(( )?&)?$"),
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
@@ -955,13 +971,17 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
+ RegularExpression("^std::unordered_(multi)?(map|set)<.+> >$"),
+ TypeSummaryImplSP(
+ new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
+ cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$"),
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
RegularExpression("^std::(__cxx11::)?forward_list<.+>(( )?&)?$"),
TypeSummaryImplSP(
- new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
+ new ScriptSummaryFormat(stl_summary_flags, "lldb.formatters.cpp.gnu_libstdcpp.ForwardListSummaryProvider")));
AddCXXSynthetic(
cpp_category_sp,
diff --git a/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp b/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
index fc8255983436..c8063915b178 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
@@ -81,12 +81,11 @@ bool GenericBitsetFrontEnd::Update() {
TargetSP target_sp = m_backend.GetTargetSP();
if (!target_sp)
return false;
- size_t capping_size = target_sp->GetMaximumNumberOfChildrenToDisplay();
size_t size = 0;
if (auto arg = m_backend.GetCompilerType().GetIntegralTemplateArgument(0))
- size = arg->value.getLimitedValue(capping_size);
+ size = arg->value.getLimitedValue();
m_elements.assign(size, ValueObjectSP());
m_first = m_backend.GetChildMemberWithName(GetDataContainerMemberName(), true)
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
index c0c819632851..c1b40ba65e7d 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
@@ -45,7 +45,7 @@ bool OptionalFrontEnd::Update() {
// __engaged_ is a bool flag and is true if the optional contains a value.
// Converting it to unsigned gives us a size of 1 if it contains a value
// and 0 if not.
- m_has_value = engaged_sp->GetValueAsUnsigned(0) == 1;
+ m_has_value = engaged_sp->GetValueAsUnsigned(0) != 0;
return false;
}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
index 3a441973fc73..57c5ba87c397 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
@@ -62,9 +62,7 @@ lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
size_t lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
CalculateNumChildren() {
- if (m_num_elements != UINT32_MAX)
- return m_num_elements;
- return 0;
+ return m_num_elements;
}
lldb::ValueObjectSP lldb_private::formatters::
@@ -160,7 +158,7 @@ lldb::ValueObjectSP lldb_private::formatters::
bool lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
Update() {
- m_num_elements = UINT32_MAX;
+ m_num_elements = 0;
m_next_element = nullptr;
m_elements_cache.clear();
ValueObjectSP table_sp =
@@ -195,8 +193,13 @@ bool lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
if (!num_elements_sp)
return false;
- m_num_elements = num_elements_sp->GetValueAsUnsigned(0);
+
m_tree = table_sp->GetChildAtNamePath(next_path).get();
+ if (m_tree == nullptr)
+ return false;
+
+ m_num_elements = num_elements_sp->GetValueAsUnsigned(0);
+
if (m_num_elements > 0)
m_next_element =
table_sp->GetChildAtNamePath(next_path).get();
diff --git a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
index bad730512ff4..ce701fd823fd 100644
--- a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
+++ b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
@@ -116,9 +116,10 @@ bool ObjectFileBreakpad::ParseHeader() {
return true;
}
-Symtab *ObjectFileBreakpad::GetSymtab() {
- // TODO
- return nullptr;
+void ObjectFileBreakpad::ParseSymtab(Symtab &symtab) {
+ // Nothing to do for breakpad files, all information is parsed as debug info
+ // which means "lldb_private::Function" objects are used, or symbols are added
+ // by the SymbolFileBreakpad::AddSymbols(...) function in the symbol file.
}
void ObjectFileBreakpad::CreateSections(SectionList &unified_section_list) {
diff --git a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
index c320c7ad3e2e..f04e0b4dd7a7 100644
--- a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
+++ b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
@@ -71,7 +71,7 @@ public:
return AddressClass::eInvalid;
}
- Symtab *GetSymtab() override;
+ void ParseSymtab(lldb_private::Symtab &symtab) override;
bool IsStripped() override { return false; }
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 8e0f228a988f..96e94ef08a45 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -2687,155 +2687,131 @@ unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr,
return 0;
}
-Symtab *ObjectFileELF::GetSymtab() {
+void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) {
ModuleSP module_sp(GetModule());
if (!module_sp)
- return nullptr;
+ return;
+
+ Progress progress(
+ llvm::formatv("Parsing symbol table for {0}",
+ m_file.GetFilename().AsCString("<Unknown>")));
+ ElapsedTime elapsed(module_sp->GetSymtabParseTime());
// We always want to use the main object file so we (hopefully) only have one
// cached copy of our symtab, dynamic sections, etc.
ObjectFile *module_obj_file = module_sp->GetObjectFile();
if (module_obj_file && module_obj_file != this)
- return module_obj_file->GetSymtab();
-
- if (m_symtab_up == nullptr) {
- Progress progress(
- llvm::formatv("Parsing symbol table for {0}",
- m_file.GetFilename().AsCString("<Unknown>")));
- ElapsedTime elapsed(module_sp->GetSymtabParseTime());
- SectionList *section_list = module_sp->GetSectionList();
- if (!section_list)
- return nullptr;
+ return module_obj_file->ParseSymtab(lldb_symtab);
- uint64_t symbol_id = 0;
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ SectionList *section_list = module_sp->GetSectionList();
+ if (!section_list)
+ return;
- // Sharable objects and dynamic executables usually have 2 distinct symbol
- // tables, one named ".symtab", and the other ".dynsym". The dynsym is a
- // smaller version of the symtab that only contains global symbols. The
- // information found in the dynsym is therefore also found in the symtab,
- // while the reverse is not necessarily true.
- Section *symtab =
- section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
- if (symtab) {
- m_symtab_up = std::make_unique<Symtab>(symtab->GetObjectFile());
- symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, symtab);
- }
+ uint64_t symbol_id = 0;
- // The symtab section is non-allocable and can be stripped, while the
- // .dynsym section which should always be always be there. To support the
- // minidebuginfo case we parse .dynsym when there's a .gnu_debuginfo
- // section, nomatter if .symtab was already parsed or not. This is because
- // minidebuginfo normally removes the .symtab symbols which have their
- // matching .dynsym counterparts.
- if (!symtab ||
- GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"))) {
- Section *dynsym =
- section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
- .get();
- if (dynsym) {
- if (!m_symtab_up)
- m_symtab_up = std::make_unique<Symtab>(dynsym->GetObjectFile());
- symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, dynsym);
- }
- }
-
- // DT_JMPREL
- // If present, this entry's d_ptr member holds the address of
- // relocation
- // entries associated solely with the procedure linkage table.
- // Separating
- // these relocation entries lets the dynamic linker ignore them during
- // process initialization, if lazy binding is enabled. If this entry is
- // present, the related entries of types DT_PLTRELSZ and DT_PLTREL must
- // also be present.
- const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
- if (symbol) {
- // Synthesize trampoline symbols to help navigate the PLT.
- addr_t addr = symbol->d_ptr;
- Section *reloc_section =
- section_list->FindSectionContainingFileAddress(addr).get();
- if (reloc_section) {
- user_id_t reloc_id = reloc_section->GetID();
- const ELFSectionHeaderInfo *reloc_header =
- GetSectionHeaderByIndex(reloc_id);
- if (reloc_header) {
- if (m_symtab_up == nullptr)
- m_symtab_up =
- std::make_unique<Symtab>(reloc_section->GetObjectFile());
+ // Sharable objects and dynamic executables usually have 2 distinct symbol
+ // tables, one named ".symtab", and the other ".dynsym". The dynsym is a
+ // smaller version of the symtab that only contains global symbols. The
+ // information found in the dynsym is therefore also found in the symtab,
+ // while the reverse is not necessarily true.
+ Section *symtab =
+ section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
+ if (symtab)
+ symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, symtab);
- ParseTrampolineSymbols(m_symtab_up.get(), symbol_id, reloc_header,
- reloc_id);
- }
- }
- }
+ // The symtab section is non-allocable and can be stripped, while the
+ // .dynsym section which should always be always be there. To support the
+ // minidebuginfo case we parse .dynsym when there's a .gnu_debuginfo
+ // section, nomatter if .symtab was already parsed or not. This is because
+ // minidebuginfo normally removes the .symtab symbols which have their
+ // matching .dynsym counterparts.
+ if (!symtab ||
+ GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"))) {
+ Section *dynsym =
+ section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
+ .get();
+ if (dynsym)
+ symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, dynsym);
+ }
- if (DWARFCallFrameInfo *eh_frame =
- GetModule()->GetUnwindTable().GetEHFrameInfo()) {
- if (m_symtab_up == nullptr)
- m_symtab_up = std::make_unique<Symtab>(this);
- ParseUnwindSymbols(m_symtab_up.get(), eh_frame);
+ // DT_JMPREL
+ // If present, this entry's d_ptr member holds the address of
+ // relocation
+ // entries associated solely with the procedure linkage table.
+ // Separating
+ // these relocation entries lets the dynamic linker ignore them during
+ // process initialization, if lazy binding is enabled. If this entry is
+ // present, the related entries of types DT_PLTRELSZ and DT_PLTREL must
+ // also be present.
+ const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
+ if (symbol) {
+ // Synthesize trampoline symbols to help navigate the PLT.
+ addr_t addr = symbol->d_ptr;
+ Section *reloc_section =
+ section_list->FindSectionContainingFileAddress(addr).get();
+ if (reloc_section) {
+ user_id_t reloc_id = reloc_section->GetID();
+ const ELFSectionHeaderInfo *reloc_header =
+ GetSectionHeaderByIndex(reloc_id);
+ if (reloc_header)
+ ParseTrampolineSymbols(&lldb_symtab, symbol_id, reloc_header, reloc_id);
}
+ }
- // If we still don't have any symtab then create an empty instance to avoid
- // do the section lookup next time.
- if (m_symtab_up == nullptr)
- m_symtab_up = std::make_unique<Symtab>(this);
+ if (DWARFCallFrameInfo *eh_frame =
+ GetModule()->GetUnwindTable().GetEHFrameInfo()) {
+ ParseUnwindSymbols(&lldb_symtab, eh_frame);
+ }
- // In the event that there's no symbol entry for the entry point we'll
- // artificially create one. We delegate to the symtab object the figuring
- // out of the proper size, this will usually make it span til the next
- // symbol it finds in the section. This means that if there are missing
- // symbols the entry point might span beyond its function definition.
- // We're fine with this as it doesn't make it worse than not having a
- // symbol entry at all.
- if (CalculateType() == eTypeExecutable) {
- ArchSpec arch = GetArchitecture();
- auto entry_point_addr = GetEntryPointAddress();
- bool is_valid_entry_point =
- entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset();
- addr_t entry_point_file_addr = entry_point_addr.GetFileAddress();
- if (is_valid_entry_point && !m_symtab_up->FindSymbolContainingFileAddress(
- entry_point_file_addr)) {
- uint64_t symbol_id = m_symtab_up->GetNumSymbols();
- // Don't set the name for any synthetic symbols, the Symbol
- // object will generate one if needed when the name is accessed
- // via accessors.
- SectionSP section_sp = entry_point_addr.GetSection();
- Symbol symbol(
- /*symID=*/symbol_id,
- /*name=*/llvm::StringRef(), // Name will be auto generated.
- /*type=*/eSymbolTypeCode,
- /*external=*/true,
- /*is_debug=*/false,
- /*is_trampoline=*/false,
- /*is_artificial=*/true,
- /*section_sp=*/section_sp,
- /*offset=*/0,
- /*size=*/0, // FDE can span multiple symbols so don't use its size.
- /*size_is_valid=*/false,
- /*contains_linker_annotations=*/false,
- /*flags=*/0);
- // When the entry point is arm thumb we need to explicitly set its
- // class address to reflect that. This is important because expression
- // evaluation relies on correctly setting a breakpoint at this
- // address.
- if (arch.GetMachine() == llvm::Triple::arm &&
- (entry_point_file_addr & 1)) {
- symbol.GetAddressRef().SetOffset(entry_point_addr.GetOffset() ^ 1);
- m_address_class_map[entry_point_file_addr ^ 1] =
- AddressClass::eCodeAlternateISA;
- } else {
- m_address_class_map[entry_point_file_addr] = AddressClass::eCode;
- }
- m_symtab_up->AddSymbol(symbol);
+ // In the event that there's no symbol entry for the entry point we'll
+ // artificially create one. We delegate to the symtab object the figuring
+ // out of the proper size, this will usually make it span til the next
+ // symbol it finds in the section. This means that if there are missing
+ // symbols the entry point might span beyond its function definition.
+ // We're fine with this as it doesn't make it worse than not having a
+ // symbol entry at all.
+ if (CalculateType() == eTypeExecutable) {
+ ArchSpec arch = GetArchitecture();
+ auto entry_point_addr = GetEntryPointAddress();
+ bool is_valid_entry_point =
+ entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset();
+ addr_t entry_point_file_addr = entry_point_addr.GetFileAddress();
+ if (is_valid_entry_point && !lldb_symtab.FindSymbolContainingFileAddress(
+ entry_point_file_addr)) {
+ uint64_t symbol_id = lldb_symtab.GetNumSymbols();
+ // Don't set the name for any synthetic symbols, the Symbol
+ // object will generate one if needed when the name is accessed
+ // via accessors.
+ SectionSP section_sp = entry_point_addr.GetSection();
+ Symbol symbol(
+ /*symID=*/symbol_id,
+ /*name=*/llvm::StringRef(), // Name will be auto generated.
+ /*type=*/eSymbolTypeCode,
+ /*external=*/true,
+ /*is_debug=*/false,
+ /*is_trampoline=*/false,
+ /*is_artificial=*/true,
+ /*section_sp=*/section_sp,
+ /*offset=*/0,
+ /*size=*/0, // FDE can span multiple symbols so don't use its size.
+ /*size_is_valid=*/false,
+ /*contains_linker_annotations=*/false,
+ /*flags=*/0);
+ // When the entry point is arm thumb we need to explicitly set its
+ // class address to reflect that. This is important because expression
+ // evaluation relies on correctly setting a breakpoint at this
+ // address.
+ if (arch.GetMachine() == llvm::Triple::arm &&
+ (entry_point_file_addr & 1)) {
+ symbol.GetAddressRef().SetOffset(entry_point_addr.GetOffset() ^ 1);
+ m_address_class_map[entry_point_file_addr ^ 1] =
+ AddressClass::eCodeAlternateISA;
+ } else {
+ m_address_class_map[entry_point_file_addr] = AddressClass::eCode;
}
+ lldb_symtab.AddSymbol(symbol);
}
-
- m_symtab_up->CalculateSymbolSizes();
}
-
- return m_symtab_up.get();
}
void ObjectFileELF::RelocateSection(lldb_private::Section *section)
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index 5738e5cf60d5..554f623ec8af 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -110,7 +110,7 @@ public:
lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override;
- lldb_private::Symtab *GetSymtab() override;
+ void ParseSymtab(lldb_private::Symtab &symtab) override;
bool IsStripped() override;
@@ -123,7 +123,7 @@ public:
lldb_private::UUID GetUUID() override;
/// Return the contents of the .gnu_debuglink section, if the object file
- /// contains it.
+ /// contains it.
llvm::Optional<lldb_private::FileSpec> GetDebugLink();
uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
@@ -278,8 +278,9 @@ private:
/// number of dynamic symbols parsed.
size_t ParseDynamicSymbols();
- /// Populates m_symtab_up will all non-dynamic linker symbols. This method
- /// will parse the symbols only once. Returns the number of symbols parsed.
+ /// Populates the symbol table with all non-dynamic linker symbols. This
+ /// method will parse the symbols only once. Returns the number of symbols
+ /// parsed.
unsigned ParseSymbolTable(lldb_private::Symtab *symbol_table,
lldb::user_id_t start_id,
lldb_private::Section *symtab);
@@ -384,7 +385,7 @@ private:
lldb_private::UUID &uuid);
bool AnySegmentHasPhysicalAddress();
-
+
/// Takes the .gnu_debugdata and returns the decompressed object file that is
/// stored within that section.
///
diff --git a/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
index bec0099517c8..ca9337454889 100644
--- a/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
+++ b/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
@@ -106,23 +106,10 @@ uint32_t ObjectFileJIT::GetAddressByteSize() const {
return m_data.GetAddressByteSize();
}
-Symtab *ObjectFileJIT::GetSymtab() {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_symtab_up == nullptr) {
- ElapsedTime elapsed(module_sp->GetSymtabParseTime());
- m_symtab_up = std::make_unique<Symtab>(this);
- std::lock_guard<std::recursive_mutex> symtab_guard(
- m_symtab_up->GetMutex());
- ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());
- if (delegate_sp)
- delegate_sp->PopulateSymtab(this, *m_symtab_up);
- // TODO: get symbols from delegate
- m_symtab_up->Finalize();
- }
- }
- return m_symtab_up.get();
+void ObjectFileJIT::ParseSymtab(Symtab &symtab) {
+ ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());
+ if (delegate_sp)
+ delegate_sp->PopulateSymtab(this, symtab);
}
bool ObjectFileJIT::IsStripped() {
diff --git a/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h b/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
index 03ac001988a0..be31139df549 100644
--- a/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
+++ b/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
@@ -67,7 +67,7 @@ public:
uint32_t GetAddressByteSize() const override;
- lldb_private::Symtab *GetSymtab() override;
+ void ParseSymtab(lldb_private::Symtab &symtab) override;
bool IsStripped() override;
diff --git a/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h b/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h
index 36e71e21332f..da999d2b55a7 100644
--- a/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h
+++ b/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h
@@ -68,7 +68,7 @@ public:
bool IsExecutable() const override { return false; }
- Symtab *GetSymtab() override { return nullptr; }
+ void ParseSymtab(lldb_private::Symtab &symtab) override {}
bool IsStripped() override { return false; }
diff --git a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
index 0e6329885528..7445f8311c50 100644
--- a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
+++ b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
@@ -246,7 +246,7 @@ bool ObjectFileWasm::ParseHeader() {
return true;
}
-Symtab *ObjectFileWasm::GetSymtab() { return nullptr; }
+void ObjectFileWasm::ParseSymtab(Symtab &symtab) {}
static SectionType GetSectionTypeFromName(llvm::StringRef Name) {
if (Name.consume_front(".debug_") || Name.consume_front(".zdebug_")) {
diff --git a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
index 44939b6d4ea0..d7b5bc22caad 100644
--- a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
+++ b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
@@ -78,7 +78,7 @@ public:
return AddressClass::eInvalid;
}
- Symtab *GetSymtab() override;
+ void ParseSymtab(lldb_private::Symtab &symtab) override;
bool IsStripped() override { return !!GetExternalDebugInfoFileSpec(); }
diff --git a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp
new file mode 100644
index 000000000000..90c290b6fbc7
--- /dev/null
+++ b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp
@@ -0,0 +1,148 @@
+//===-- PlatformQemuUser.cpp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/Platform/QemuUser/PlatformQemuUser.h"
+#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/ProcessLaunchInfo.h"
+#include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/Listener.h"
+#include "lldb/Utility/Log.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE(PlatformQemuUser)
+
+#define LLDB_PROPERTIES_platformqemuuser
+#include "PlatformQemuUserProperties.inc"
+
+enum {
+#define LLDB_PROPERTIES_platformqemuuser
+#include "PlatformQemuUserPropertiesEnum.inc"
+};
+
+class PluginProperties : public Properties {
+public:
+ PluginProperties() {
+ m_collection_sp = std::make_shared<OptionValueProperties>(
+ ConstString(PlatformQemuUser::GetPluginNameStatic()));
+ m_collection_sp->Initialize(g_platformqemuuser_properties);
+ }
+
+ llvm::StringRef GetArchitecture() {
+ return m_collection_sp->GetPropertyAtIndexAsString(
+ nullptr, ePropertyArchitecture, "");
+ }
+
+ FileSpec GetEmulatorPath() {
+ return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr,
+ ePropertyEmulatorPath);
+ }
+};
+
+static PluginProperties &GetGlobalProperties() {
+ static PluginProperties g_settings;
+ return g_settings;
+}
+
+llvm::StringRef PlatformQemuUser::GetPluginDescriptionStatic() {
+ return "Platform for debugging binaries under user mode qemu";
+}
+
+void PlatformQemuUser::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), GetPluginDescriptionStatic(),
+ PlatformQemuUser::CreateInstance, PlatformQemuUser::DebuggerInitialize);
+}
+
+void PlatformQemuUser::Terminate() {
+ PluginManager::UnregisterPlugin(PlatformQemuUser::CreateInstance);
+}
+
+void PlatformQemuUser::DebuggerInitialize(Debugger &debugger) {
+ if (!PluginManager::GetSettingForPlatformPlugin(
+ debugger, ConstString(GetPluginNameStatic()))) {
+ PluginManager::CreateSettingForPlatformPlugin(
+ debugger, GetGlobalProperties().GetValueProperties(),
+ ConstString("Properties for the qemu-user platform plugin."),
+ /*is_global_property=*/true);
+ }
+}
+
+PlatformSP PlatformQemuUser::CreateInstance(bool force, const ArchSpec *arch) {
+ if (force)
+ return PlatformSP(new PlatformQemuUser());
+ return nullptr;
+}
+
+std::vector<ArchSpec> PlatformQemuUser::GetSupportedArchitectures() {
+ llvm::Triple triple = HostInfo::GetArchitecture().GetTriple();
+ triple.setEnvironment(llvm::Triple::UnknownEnvironment);
+ triple.setArchName(GetGlobalProperties().GetArchitecture());
+ if (triple.getArch() != llvm::Triple::UnknownArch)
+ return {ArchSpec(triple)};
+ return {};
+}
+
+static auto get_arg_range(const Args &args) {
+ return llvm::make_range(args.GetArgumentArrayRef().begin(),
+ args.GetArgumentArrayRef().end());
+}
+
+lldb::ProcessSP PlatformQemuUser::DebugProcess(ProcessLaunchInfo &launch_info,
+ Debugger &debugger,
+ Target &target, Status &error) {
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+
+ std::string qemu = GetGlobalProperties().GetEmulatorPath().GetPath();
+
+ llvm::SmallString<0> socket_model, socket_path;
+ HostInfo::GetProcessTempDir().GetPath(socket_model);
+ llvm::sys::path::append(socket_model, "qemu-%%%%%%%%.socket");
+ do {
+ llvm::sys::fs::createUniquePath(socket_model, socket_path, false);
+ } while (FileSystem::Instance().Exists(socket_path));
+
+ Args args(
+ {qemu, "-g", socket_path, launch_info.GetExecutableFile().GetPath()});
+ for (size_t i = 1; i < launch_info.GetArguments().size(); ++i)
+ args.AppendArgument(launch_info.GetArguments()[i].ref());
+
+ LLDB_LOG(log, "{0} -> {1}", get_arg_range(launch_info.GetArguments()),
+ get_arg_range(args));
+
+ launch_info.SetArguments(args, true);
+ launch_info.SetLaunchInSeparateProcessGroup(true);
+ launch_info.GetFlags().Clear(eLaunchFlagDebug);
+ launch_info.SetMonitorProcessCallback(ProcessLaunchInfo::NoOpMonitorCallback,
+ false);
+
+ error = Host::LaunchProcess(launch_info);
+ if (error.Fail())
+ return nullptr;
+
+ ProcessSP process_sp = target.CreateProcess(
+ launch_info.GetListener(),
+ process_gdb_remote::ProcessGDBRemote::GetPluginNameStatic(), nullptr,
+ true);
+ ListenerSP listener_sp =
+ Listener::MakeListener("lldb.platform_qemu_user.debugprocess");
+ launch_info.SetHijackListener(listener_sp);
+ Process::ProcessEventHijacker hijacker(*process_sp, listener_sp);
+
+ error = process_sp->ConnectRemote(("unix-connect://" + socket_path).str());
+ if (error.Fail())
+ return nullptr;
+
+ process_sp->WaitForProcessToStop(llvm::None, nullptr, false, listener_sp);
+ return process_sp;
+}
diff --git a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h
new file mode 100644
index 000000000000..f4f5d224a8cd
--- /dev/null
+++ b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h
@@ -0,0 +1,57 @@
+//===-- PlatformQemuUser.h ------------------------------------------------===//
+//
+// 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/Host/Host.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Target/Platform.h"
+
+namespace lldb_private {
+
+class PlatformQemuUser : public Platform {
+public:
+ static void Initialize();
+ static void Terminate();
+
+ static llvm::StringRef GetPluginNameStatic() { return "qemu-user"; }
+ static llvm::StringRef GetPluginDescriptionStatic();
+
+ llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+ llvm::StringRef GetDescription() override {
+ return GetPluginDescriptionStatic();
+ }
+
+ UserIDResolver &GetUserIDResolver() override {
+ return HostInfo::GetUserIDResolver();
+ }
+
+ std::vector<ArchSpec> GetSupportedArchitectures() override;
+
+ lldb::ProcessSP DebugProcess(ProcessLaunchInfo &launch_info,
+ Debugger &debugger, Target &target,
+ Status &error) override;
+
+ lldb::ProcessSP Attach(ProcessAttachInfo &attach_info, Debugger &debugger,
+ Target *target, Status &status) override {
+ status.SetErrorString("Not supported");
+ return nullptr;
+ }
+
+ bool IsConnected() const override { return true; }
+
+ void CalculateTrapHandlerSymbolNames() override {}
+
+ Environment GetEnvironment() override { return Host::GetEnvironment(); }
+
+private:
+ static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+ static void DebuggerInitialize(Debugger &debugger);
+
+ PlatformQemuUser() : Platform(/*is_host=*/false) {}
+};
+
+} // namespace lldb_private
diff --git a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td
new file mode 100644
index 000000000000..abfab7f59de4
--- /dev/null
+++ b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td
@@ -0,0 +1,12 @@
+include "../../../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "platformqemuuser" in {
+ def Architecture: Property<"architecture", "String">,
+ Global,
+ DefaultStringValue<"">,
+ Desc<"Architecture to emulate.">;
+ def EmulatorPath: Property<"emulator-path", "FileSpec">,
+ Global,
+ DefaultStringValue<"">,
+ Desc<"Path to the emulator binary.">;
+}
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index 23b346d5c17f..b852a0164375 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -281,8 +281,8 @@ size_t ProcessElfCore::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
return DoReadMemory(addr, buf, size, error);
}
-Status ProcessElfCore::DoGetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &region_info) {
+Status ProcessElfCore::GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &region_info) {
region_info.Clear();
const VMRangeToPermissions::Entry *permission_entry =
m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
index fd36e5027816..67df3c5fac76 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -86,6 +86,10 @@ public:
size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
lldb_private::Status &error) override;
+ lldb_private::Status
+ GetMemoryRegionInfo(lldb::addr_t load_addr,
+ lldb_private::MemoryRegionInfo &region_info) override;
+
lldb::addr_t GetImageInfoAddress() override;
lldb_private::ArchSpec GetArchitecture();
@@ -101,10 +105,6 @@ protected:
bool DoUpdateThreadList(lldb_private::ThreadList &old_thread_list,
lldb_private::ThreadList &new_thread_list) override;
- lldb_private::Status
- DoGetMemoryRegionInfo(lldb::addr_t load_addr,
- lldb_private::MemoryRegionInfo &region_info) override;
-
private:
struct NT_FILE_Entry {
lldb::addr_t start;
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 4ce79da48f07..25ae08838bf8 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -81,11 +81,6 @@ GDBRemoteCommunication::~GDBRemoteCommunication() {
if (m_decompression_scratch)
free (m_decompression_scratch);
#endif
-
- // Stop the communications read thread which is used to parse all incoming
- // packets. This function will block until the read thread returns.
- if (m_read_thread_enabled)
- StopReadThread();
}
char GDBRemoteCommunication::CalculcateChecksum(llvm::StringRef payload) {
@@ -193,7 +188,7 @@ GDBRemoteCommunication::SendRawPacketNoLock(llvm::StringRef packet,
GDBRemoteCommunication::PacketResult GDBRemoteCommunication::GetAck() {
StringExtractorGDBRemote packet;
- PacketResult result = ReadPacket(packet, GetPacketTimeout(), false);
+ PacketResult result = WaitForPacketNoLock(packet, GetPacketTimeout(), false);
if (result == PacketResult::Success) {
if (packet.GetResponseType() ==
StringExtractorGDBRemote::ResponseType::eAck)
@@ -225,40 +220,18 @@ GDBRemoteCommunication::PacketResult
GDBRemoteCommunication::ReadPacket(StringExtractorGDBRemote &response,
Timeout<std::micro> timeout,
bool sync_on_timeout) {
- if (m_read_thread_enabled)
- return PopPacketFromQueue(response, timeout);
- else
- return WaitForPacketNoLock(response, timeout, sync_on_timeout);
-}
+ using ResponseType = StringExtractorGDBRemote::ResponseType;
-// This function is called when a packet is requested.
-// A whole packet is popped from the packet queue and returned to the caller.
-// Packets are placed into this queue from the communication read thread. See
-// GDBRemoteCommunication::AppendBytesToCache.
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunication::PopPacketFromQueue(StringExtractorGDBRemote &response,
- Timeout<std::micro> timeout) {
- auto pred = [&] { return !m_packet_queue.empty() && IsConnected(); };
- // lock down the packet queue
- std::unique_lock<std::mutex> lock(m_packet_queue_mutex);
-
- if (!timeout)
- m_condition_queue_not_empty.wait(lock, pred);
- else {
- if (!m_condition_queue_not_empty.wait_for(lock, *timeout, pred))
- return PacketResult::ErrorReplyTimeout;
- if (!IsConnected())
- return PacketResult::ErrorDisconnected;
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
+ for (;;) {
+ PacketResult result =
+ WaitForPacketNoLock(response, timeout, sync_on_timeout);
+ if (result != PacketResult::Success ||
+ (response.GetResponseType() != ResponseType::eAck &&
+ response.GetResponseType() != ResponseType::eNack))
+ return result;
+ LLDB_LOG(log, "discarding spurious `{0}` packet", response.GetStringRef());
}
-
- // get the front element of the queue
- response = m_packet_queue.front();
-
- // remove the front element
- m_packet_queue.pop();
-
- // we got a packet
- return PacketResult::Success;
}
GDBRemoteCommunication::PacketResult
@@ -1287,53 +1260,6 @@ GDBRemoteCommunication::ScopedTimeout::~ScopedTimeout() {
m_gdb_comm.SetPacketTimeout(m_saved_timeout);
}
-// This function is called via the Communications class read thread when bytes
-// become available for this connection. This function will consume all
-// incoming bytes and try to parse whole packets as they become available. Full
-// packets are placed in a queue, so that all packet requests can simply pop
-// from this queue. Async notification packets will be dispatched immediately
-// to the ProcessGDBRemote Async thread via an event.
-void GDBRemoteCommunication::AppendBytesToCache(const uint8_t *bytes,
- size_t len, bool broadcast,
- lldb::ConnectionStatus status) {
- StringExtractorGDBRemote packet;
-
- while (true) {
- PacketType type = CheckForPacket(bytes, len, packet);
-
- // scrub the data so we do not pass it back to CheckForPacket on future
- // passes of the loop
- bytes = nullptr;
- len = 0;
-
- // we may have received no packet so lets bail out
- if (type == PacketType::Invalid)
- break;
-
- if (type == PacketType::Standard) {
- // scope for the mutex
- {
- // lock down the packet queue
- std::lock_guard<std::mutex> guard(m_packet_queue_mutex);
- // push a new packet into the queue
- m_packet_queue.push(packet);
- // Signal condition variable that we have a packet
- m_condition_queue_not_empty.notify_one();
- }
- }
-
- if (type == PacketType::Notify) {
- // put this packet into an event
- const char *pdata = packet.GetStringRef().data();
-
- // as the communication class, we are a broadcaster and the async thread
- // is tuned to listen to us
- BroadcastEvent(eBroadcastBitGdbReadThreadGotNotify,
- new EventDataBytes(pdata));
- }
- }
-}
-
void llvm::format_provider<GDBRemoteCommunication::PacketResult>::format(
const GDBRemoteCommunication::PacketResult &result, raw_ostream &Stream,
StringRef Style) {
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index 5da568e9b4d4..afc7e740d4c9 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -84,8 +84,6 @@ class GDBRemoteCommunication : public Communication {
public:
enum {
eBroadcastBitRunPacketSent = kLoUserBroadcastBit,
- eBroadcastBitGdbReadThreadGotNotify =
- kLoUserBroadcastBit << 1 // Sent when we received a notify packet.
};
enum class PacketType { Invalid = 0, Standard, Notify };
@@ -196,10 +194,6 @@ protected:
bool sync_on_timeout,
llvm::function_ref<void(llvm::StringRef)> output_callback);
- // Pop a packet from the queue in a thread safe manner
- PacketResult PopPacketFromQueue(StringExtractorGDBRemote &response,
- Timeout<std::micro> timeout);
-
PacketResult WaitForPacketNoLock(StringExtractorGDBRemote &response,
Timeout<std::micro> timeout,
bool sync_on_timeout);
@@ -226,24 +220,7 @@ protected:
static lldb::thread_result_t ListenThread(lldb::thread_arg_t arg);
- // GDB-Remote read thread
- // . this thread constantly tries to read from the communication
- // class and stores all packets received in a queue. The usual
- // threads read requests simply pop packets off the queue in the
- // usual order.
- // This setup allows us to intercept and handle async packets, such
- // as the notify packet.
-
- // This method is defined as part of communication.h
- // when the read thread gets any bytes it will pass them on to this function
- void AppendBytesToCache(const uint8_t *bytes, size_t len, bool broadcast,
- lldb::ConnectionStatus status) override;
-
private:
- std::queue<StringExtractorGDBRemote> m_packet_queue; // The packet queue
- std::mutex m_packet_queue_mutex; // Mutex for accessing queue
- std::condition_variable
- m_condition_queue_not_empty; // Condition variable to wait for packets
// Promise used to grab the port number from listening thread
std::promise<uint16_t> m_port_promise;
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 78e722eee080..07dfa5e04ee5 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -86,13 +86,6 @@ bool GDBRemoteCommunicationClient::HandshakeWithServer(Status *error_ptr) {
std::chrono::steady_clock::time_point start_of_handshake =
std::chrono::steady_clock::now();
if (SendAck()) {
- // Wait for any responses that might have been queued up in the remote
- // GDB server and flush them all
- StringExtractorGDBRemote response;
- PacketResult packet_result = PacketResult::Success;
- while (packet_result == PacketResult::Success)
- packet_result = ReadPacket(response, milliseconds(10), false);
-
// The return value from QueryNoAckModeSupported() is true if the packet
// was sent and _any_ response (including UNIMPLEMENTED) was received), or
// false if no response was received. This quickly tells us if we have a
@@ -106,17 +99,15 @@ bool GDBRemoteCommunicationClient::HandshakeWithServer(Status *error_ptr) {
std::chrono::duration<double>(end_of_handshake - start_of_handshake)
.count();
if (error_ptr) {
- if (packet_result == PacketResult::ErrorDisconnected)
+ if (!IsConnected())
error_ptr->SetErrorString("Connection shut down by remote side "
"while waiting for reply to initial "
"handshake packet");
- else if (packet_result == PacketResult::ErrorReplyTimeout)
+ else
error_ptr->SetErrorStringWithFormat(
"failed to get reply to handshake packet within timeout of "
"%.1f seconds",
handshake_timeout);
- else
- error_ptr->SetErrorString("failed to get reply to handshake packet");
}
}
} else {
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index 11cac9fa3a4d..49d88b72b01b 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -46,7 +46,7 @@ GDBRemoteCommunicationServer::GetPacketAndSendResponse(
Timeout<std::micro> timeout, Status &error, bool &interrupt, bool &quit) {
StringExtractorGDBRemote packet;
- PacketResult packet_result = WaitForPacketNoLock(packet, timeout, false);
+ PacketResult packet_result = ReadPacket(packet, timeout, false);
if (packet_result == PacketResult::Success) {
const StringExtractorGDBRemote::ServerPacketType packet_type =
packet.GetServerPacketType();
@@ -150,10 +150,6 @@ GDBRemoteCommunicationServer::SendOKResponse() {
return SendPacketNoLock("OK");
}
-bool GDBRemoteCommunicationServer::HandshakeWithClient() {
- return GetAck() == PacketResult::Success;
-}
-
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::SendJSONResponse(const json::Value &value) {
std::string json_string;
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index 68448eae2b9f..5de344061ec9 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -44,10 +44,6 @@ public:
Status &error, bool &interrupt,
bool &quit);
- // After connecting, do a little handshake with the client to make sure
- // we are at least communicating
- bool HandshakeWithClient();
-
protected:
std::map<StringExtractorGDBRemote::ServerPacketType, PacketHandler>
m_packet_handlers;
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 5360db3d8462..30f14a52dfb5 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -1088,18 +1088,6 @@ void GDBRemoteCommunicationServerLLGS::NewSubprocess(
void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() {
Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_COMM));
- if (!m_handshake_completed) {
- if (!HandshakeWithClient()) {
- LLDB_LOGF(log,
- "GDBRemoteCommunicationServerLLGS::%s handshake with "
- "client failed, exiting",
- __FUNCTION__);
- m_mainloop.RequestTermination();
- return;
- }
- m_handshake_completed = true;
- }
-
bool interrupt = false;
bool done = false;
Status error;
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index 6c75771f6427..17ee4130dc34 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -104,7 +104,6 @@ protected:
std::mutex m_saved_registers_mutex;
std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map;
uint32_t m_next_saved_registers_id = 1;
- bool m_handshake_completed = false;
bool m_thread_suffix_supported = false;
bool m_list_threads_in_stop_reply = false;
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 2233bf675819..3ade8c815feb 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -282,9 +282,7 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
__FUNCTION__);
}
- const uint32_t gdb_event_mask =
- Communication::eBroadcastBitReadThreadDidExit |
- GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify;
+ const uint32_t gdb_event_mask = Communication::eBroadcastBitReadThreadDidExit;
if (m_async_listener_sp->StartListeningForEvents(
&m_gdb_comm, gdb_event_mask) != gdb_event_mask) {
LLDB_LOGF(log,
@@ -1324,24 +1322,6 @@ Status ProcessGDBRemote::DoResume() {
return error;
}
-void ProcessGDBRemote::HandleStopReplySequence() {
- while (true) {
- // Send vStopped
- StringExtractorGDBRemote response;
- m_gdb_comm.SendPacketAndWaitForResponse("vStopped", response);
-
- // OK represents end of signal list
- if (response.IsOKResponse())
- break;
-
- // If not OK or a normal packet we have a problem
- if (!response.IsNormalResponse())
- break;
-
- SetLastStopPacket(response);
- }
-}
-
void ProcessGDBRemote::ClearThreadIDList() {
std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
m_thread_ids.clear();
@@ -2897,8 +2877,8 @@ lldb::addr_t ProcessGDBRemote::DoAllocateMemory(size_t size,
return allocated_addr;
}
-Status ProcessGDBRemote::DoGetMemoryRegionInfo(addr_t load_addr,
- MemoryRegionInfo &region_info) {
+Status ProcessGDBRemote::GetMemoryRegionInfo(addr_t load_addr,
+ MemoryRegionInfo &region_info) {
Status error(m_gdb_comm.GetMemoryRegionInfo(load_addr, region_info));
return error;
@@ -3539,31 +3519,6 @@ void ProcessGDBRemote::StopAsyncThread() {
__FUNCTION__);
}
-bool ProcessGDBRemote::HandleNotifyPacket(StringExtractorGDBRemote &packet) {
- // get the packet at a string
- const std::string &pkt = std::string(packet.GetStringRef());
- // skip %stop:
- StringExtractorGDBRemote stop_info(pkt.c_str() + 5);
-
- // pass as a thread stop info packet
- SetLastStopPacket(stop_info);
-
- // check for more stop reasons
- HandleStopReplySequence();
-
- // if the process is stopped then we need to fake a resume so that we can
- // stop properly with the new break. This is possible due to
- // SetPrivateState() broadcasting the state change as a side effect.
- if (GetPrivateState() == lldb::StateType::eStateStopped) {
- SetPrivateState(lldb::StateType::eStateRunning);
- }
-
- // since we have some stopped packets we can halt the process
- SetPrivateState(lldb::StateType::eStateStopped);
-
- return true;
-}
-
thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
ProcessGDBRemote *process = (ProcessGDBRemote *)arg;
@@ -3712,17 +3667,6 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
done = true;
break;
- case GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify: {
- lldb_private::Event *event = event_sp.get();
- const EventDataBytes *continue_packet =
- EventDataBytes::GetEventDataFromEvent(event);
- StringExtractorGDBRemote notify(
- (const char *)continue_packet->GetBytes());
- // Hand this over to the process to handle
- process->HandleNotifyPacket(notify);
- break;
- }
-
default:
LLDB_LOGF(log,
"ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 8134bc6b530d..488336b8c1b8 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -144,6 +144,9 @@ public:
lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,
Status &error) override;
+ Status GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &region_info) override;
+
Status DoDeallocateMemory(lldb::addr_t ptr) override;
// Process STDIO
@@ -343,8 +346,6 @@ protected:
size_t UpdateThreadIDsFromStopReplyThreadsValue(llvm::StringRef value);
- bool HandleNotifyPacket(StringExtractorGDBRemote &packet);
-
bool StartAsyncThread();
void StopAsyncThread();
@@ -375,8 +376,6 @@ protected:
lldb::addr_t dispatch_queue_t, std::string &queue_name,
lldb::QueueKind queue_kind, uint64_t queue_serial);
- void HandleStopReplySequence();
-
void ClearThreadIDList();
bool UpdateThreadIDList();
@@ -421,9 +420,6 @@ protected:
Status DoWriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type,
const std::vector<uint8_t> &tags) override;
- Status DoGetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &region_info) override;
-
private:
// For ProcessGDBRemote only
std::string m_partial_profile_data;
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
index 736cfa070088..37ee5466c5b9 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -73,7 +73,7 @@ public:
bool IsExecutable() const override { return false; }
ArchSpec GetArchitecture() override { return m_arch; }
UUID GetUUID() override { return m_uuid; }
- Symtab *GetSymtab() override { return m_symtab_up.get(); }
+ void ParseSymtab(lldb_private::Symtab &symtab) override {}
bool IsStripped() override { return true; }
ByteOrder GetByteOrder() const override { return m_arch.GetByteOrder(); }
@@ -439,8 +439,8 @@ void ProcessMinidump::BuildMemoryRegions() {
llvm::sort(*m_memory_regions);
}
-Status ProcessMinidump::DoGetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &region) {
+Status ProcessMinidump::GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &region) {
BuildMemoryRegions();
region = MinidumpParser::GetMemoryRegionInfo(*m_memory_regions, load_addr);
return Status();
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
index 5360269199cd..3501d38a0f27 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -75,6 +75,9 @@ public:
ArchSpec GetArchitecture();
+ Status GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) override;
+
Status GetMemoryRegions(
lldb_private::MemoryRegionInfos &region_list) override;
@@ -95,9 +98,6 @@ protected:
bool DoUpdateThreadList(ThreadList &old_thread_list,
ThreadList &new_thread_list) override;
- Status DoGetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &range_info) override;
-
void ReadModuleList();
lldb::ModuleSP GetOrCreateModule(lldb_private::UUID minidump_uuid,
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
index 15d3d43d9993..c1b7294a7f58 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
+++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
@@ -248,8 +248,8 @@ ArchSpec ScriptedProcess::GetArchitecture() {
return GetTarget().GetArchitecture();
}
-Status ScriptedProcess::DoGetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &region) {
+Status ScriptedProcess::GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &region) {
CheckInterpreterAndScriptObject();
Status error;
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h
index c8355f35548a..d56658a2e48a 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h
+++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h
@@ -84,6 +84,9 @@ public:
ArchSpec GetArchitecture();
+ Status GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) override;
+
Status
GetMemoryRegions(lldb_private::MemoryRegionInfos &region_list) override;
@@ -97,9 +100,6 @@ protected:
bool DoUpdateThreadList(ThreadList &old_thread_list,
ThreadList &new_thread_list) override;
- Status DoGetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &range_info) override;
-
private:
friend class ScriptedThread;
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
index 798d947a0a7d..c7af13598843 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
@@ -15,8 +15,12 @@
#if LLDB_ENABLE_PYTHON
+// LLDB Python header must be included first
+#include "lldb-python.h"
+
#include "lldb/lldb-forward.h"
#include "lldb/lldb-types.h"
+#include "llvm/Support/Error.h"
namespace lldb_private {
@@ -41,20 +45,148 @@ template <> const char *GetPythonValueFormatString(unsigned long long);
template <> const char *GetPythonValueFormatString(float t);
template <> const char *GetPythonValueFormatString(double t);
-extern "C" void *LLDBSwigPythonCreateScriptedProcess(
+void *LLDBSWIGPython_CastPyObjectToSBData(PyObject *data);
+void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data);
+void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data);
+void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data);
+
+// These prototypes are the Pythonic implementations of the required callbacks.
+// Although these are scripting-language specific, their definition depends on
+// the public API.
+
+void *LLDBSwigPythonCreateScriptedProcess(const char *python_class_name,
+ const char *session_dictionary_name,
+ const lldb::TargetSP &target_sp,
+ StructuredDataImpl *args_impl,
+ std::string &error_string);
+
+void *LLDBSwigPythonCreateScriptedThread(const char *python_class_name,
+ const char *session_dictionary_name,
+ const lldb::ProcessSP &process_sp,
+ StructuredDataImpl *args_impl,
+ std::string &error_string);
+
+llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction(
+ const char *python_function_name, const char *session_dictionary_name,
+ const lldb::StackFrameSP &sb_frame,
+ const lldb::BreakpointLocationSP &sb_bp_loc,
+ lldb_private::StructuredDataImpl *args_impl);
+
+bool LLDBSwigPythonWatchpointCallbackFunction(
+ const char *python_function_name, const char *session_dictionary_name,
+ const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp);
+
+bool LLDBSwigPythonCallTypeScript(const char *python_function_name,
+ const void *session_dictionary,
+ const lldb::ValueObjectSP &valobj_sp,
+ void **pyfunct_wrapper,
+ const lldb::TypeSummaryOptionsSP &options_sp,
+ std::string &retval);
+
+void *
+LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name,
+ const char *session_dictionary_name,
+ const lldb::ValueObjectSP &valobj_sp);
+
+void *LLDBSwigPythonCreateCommandObject(const char *python_class_name,
+ const char *session_dictionary_name,
+ const lldb::DebuggerSP debugger_sp);
+
+void *LLDBSwigPythonCreateScriptedThreadPlan(
const char *python_class_name, const char *session_dictionary_name,
- const lldb::TargetSP &target_sp, StructuredDataImpl *args_impl,
- std::string &error_string);
+ lldb_private::StructuredDataImpl *args_data, std::string &error_string,
+ const lldb::ThreadPlanSP &thread_plan_sp);
-extern "C" void *LLDBSwigPythonCreateScriptedThread(
+bool LLDBSWIGPythonCallThreadPlan(void *implementor, const char *method_name,
+ lldb_private::Event *event_sp,
+ bool &got_error);
+
+void *LLDBSwigPythonCreateScriptedBreakpointResolver(
const char *python_class_name, const char *session_dictionary_name,
- const lldb::ProcessSP &process_sp, StructuredDataImpl *args_impl,
- std::string &error_string);
+ lldb_private::StructuredDataImpl *args, const lldb::BreakpointSP &bkpt_sp);
+
+unsigned int
+LLDBSwigPythonCallBreakpointResolver(void *implementor, const char *method_name,
+ lldb_private::SymbolContext *sym_ctx);
+
+void *LLDBSwigPythonCreateScriptedStopHook(
+ lldb::TargetSP target_sp, const char *python_class_name,
+ const char *session_dictionary_name, lldb_private::StructuredDataImpl *args,
+ lldb_private::Status &error);
+
+bool LLDBSwigPythonStopHookCallHandleStop(void *implementor,
+ lldb::ExecutionContextRefSP exc_ctx,
+ lldb::StreamSP stream);
+
+size_t LLDBSwigPython_CalculateNumChildren(PyObject *implementor, uint32_t max);
+
+PyObject *LLDBSwigPython_GetChildAtIndex(PyObject *implementor, uint32_t idx);
+
+int LLDBSwigPython_GetIndexOfChildWithName(PyObject *implementor,
+ const char *child_name);
+
+lldb::ValueObjectSP LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data);
+
+bool LLDBSwigPython_UpdateSynthProviderInstance(PyObject *implementor);
+
+bool LLDBSwigPython_MightHaveChildrenSynthProviderInstance(
+ PyObject *implementor);
+
+PyObject *LLDBSwigPython_GetValueSynthProviderInstance(PyObject *implementor);
+
+bool LLDBSwigPythonCallCommand(const char *python_function_name,
+ const char *session_dictionary_name,
+ lldb::DebuggerSP &debugger, const char *args,
+ lldb_private::CommandReturnObject &cmd_retobj,
+ lldb::ExecutionContextRefSP exe_ctx_ref_sp);
+
+bool LLDBSwigPythonCallCommandObject(
+ PyObject *implementor, lldb::DebuggerSP &debugger, const char *args,
+ lldb_private::CommandReturnObject &cmd_retobj,
+ lldb::ExecutionContextRefSP exe_ctx_ref_sp);
+
+bool LLDBSwigPythonCallModuleInit(const char *python_module_name,
+ const char *session_dictionary_name,
+ lldb::DebuggerSP &debugger);
+
+void *LLDBSWIGPythonCreateOSPlugin(const char *python_class_name,
+ const char *session_dictionary_name,
+ const lldb::ProcessSP &process_sp);
+
+void *LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name,
+ const char *session_dictionary_name);
+
+PyObject *
+LLDBSwigPython_GetRecognizedArguments(PyObject *implementor,
+ const lldb::StackFrameSP &frame_sp);
+
+bool LLDBSWIGPythonRunScriptKeywordProcess(const char *python_function_name,
+ const char *session_dictionary_name,
+ const lldb::ProcessSP &process,
+ std::string &output);
+
+bool LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name,
+ const char *session_dictionary_name,
+ lldb::ThreadSP &thread,
+ std::string &output);
+
+bool LLDBSWIGPythonRunScriptKeywordTarget(const char *python_function_name,
+ const char *session_dictionary_name,
+ const lldb::TargetSP &target,
+ std::string &output);
+
+bool LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name,
+ const char *session_dictionary_name,
+ lldb::StackFrameSP &frame,
+ std::string &output);
+
+bool LLDBSWIGPythonRunScriptKeywordValue(const char *python_function_name,
+ const char *session_dictionary_name,
+ const lldb::ValueObjectSP &value,
+ std::string &output);
-extern "C" void *LLDBSWIGPython_CastPyObjectToSBData(void *data);
-extern "C" void *LLDBSWIGPython_CastPyObjectToSBError(void *data);
-extern "C" void *LLDBSWIGPython_CastPyObjectToSBValue(void *data);
-extern "C" void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(void *data);
+void *LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting,
+ const lldb::TargetSP &target_sp);
} // namespace lldb_private
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index c1f4c2d3b4d3..5f282d74e364 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -70,153 +70,6 @@ extern "C" void init_lldb(void);
#define LLDBSwigPyInit init_lldb
#endif
-// These prototypes are the Pythonic implementations of the required callbacks.
-// Although these are scripting-language specific, their definition depends on
-// the public API.
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
-
-// Disable warning C4190: 'LLDBSwigPythonBreakpointCallbackFunction' has
-// C-linkage specified, but returns UDT 'llvm::Expected<bool>' which is
-// incompatible with C
-#if _MSC_VER
-#pragma warning (push)
-#pragma warning (disable : 4190)
-#endif
-
-extern "C" llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction(
- const char *python_function_name, const char *session_dictionary_name,
- const lldb::StackFrameSP &sb_frame,
- const lldb::BreakpointLocationSP &sb_bp_loc, StructuredDataImpl *args_impl);
-
-#if _MSC_VER
-#pragma warning (pop)
-#endif
-
-#pragma clang diagnostic pop
-
-extern "C" bool LLDBSwigPythonWatchpointCallbackFunction(
- const char *python_function_name, const char *session_dictionary_name,
- const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp);
-
-extern "C" bool LLDBSwigPythonCallTypeScript(
- const char *python_function_name, void *session_dictionary,
- const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper,
- const lldb::TypeSummaryOptionsSP &options_sp, std::string &retval);
-
-extern "C" void *
-LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name,
- const char *session_dictionary_name,
- const lldb::ValueObjectSP &valobj_sp);
-
-extern "C" void *
-LLDBSwigPythonCreateCommandObject(const char *python_class_name,
- const char *session_dictionary_name,
- const lldb::DebuggerSP debugger_sp);
-
-extern "C" void *LLDBSwigPythonCreateScriptedThreadPlan(
- const char *python_class_name, const char *session_dictionary_name,
- StructuredDataImpl *args_data,
- std::string &error_string,
- const lldb::ThreadPlanSP &thread_plan_sp);
-
-extern "C" bool LLDBSWIGPythonCallThreadPlan(void *implementor,
- const char *method_name,
- Event *event_sp, bool &got_error);
-
-extern "C" void *LLDBSwigPythonCreateScriptedBreakpointResolver(
- const char *python_class_name, const char *session_dictionary_name,
- lldb_private::StructuredDataImpl *args, lldb::BreakpointSP &bkpt_sp);
-
-extern "C" unsigned int
-LLDBSwigPythonCallBreakpointResolver(void *implementor, const char *method_name,
- lldb_private::SymbolContext *sym_ctx);
-
-extern "C" void *LLDBSwigPythonCreateScriptedStopHook(
- TargetSP target_sp, const char *python_class_name,
- const char *session_dictionary_name, lldb_private::StructuredDataImpl *args,
- lldb_private::Status &error);
-
-extern "C" bool
-LLDBSwigPythonStopHookCallHandleStop(void *implementor,
- lldb::ExecutionContextRefSP exc_ctx,
- lldb::StreamSP stream);
-
-extern "C" size_t LLDBSwigPython_CalculateNumChildren(void *implementor,
- uint32_t max);
-
-extern "C" void *LLDBSwigPython_GetChildAtIndex(void *implementor,
- uint32_t idx);
-
-extern "C" int LLDBSwigPython_GetIndexOfChildWithName(void *implementor,
- const char *child_name);
-
-extern lldb::ValueObjectSP
-LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data);
-
-extern "C" bool LLDBSwigPython_UpdateSynthProviderInstance(void *implementor);
-
-extern "C" bool
-LLDBSwigPython_MightHaveChildrenSynthProviderInstance(void *implementor);
-
-extern "C" void *
-LLDBSwigPython_GetValueSynthProviderInstance(void *implementor);
-
-extern "C" bool
-LLDBSwigPythonCallCommand(const char *python_function_name,
- const char *session_dictionary_name,
- lldb::DebuggerSP &debugger, const char *args,
- lldb_private::CommandReturnObject &cmd_retobj,
- lldb::ExecutionContextRefSP exe_ctx_ref_sp);
-
-extern "C" bool
-LLDBSwigPythonCallCommandObject(void *implementor, lldb::DebuggerSP &debugger,
- const char *args,
- lldb_private::CommandReturnObject &cmd_retobj,
- lldb::ExecutionContextRefSP exe_ctx_ref_sp);
-
-extern "C" bool
-LLDBSwigPythonCallModuleInit(const char *python_module_name,
- const char *session_dictionary_name,
- lldb::DebuggerSP &debugger);
-
-extern "C" void *
-LLDBSWIGPythonCreateOSPlugin(const char *python_class_name,
- const char *session_dictionary_name,
- const lldb::ProcessSP &process_sp);
-
-extern "C" void *
-LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name,
- const char *session_dictionary_name);
-
-extern "C" void *
-LLDBSwigPython_GetRecognizedArguments(void *implementor,
- const lldb::StackFrameSP &frame_sp);
-
-extern "C" bool LLDBSWIGPythonRunScriptKeywordProcess(
- const char *python_function_name, const char *session_dictionary_name,
- lldb::ProcessSP &process, std::string &output);
-
-extern "C" bool LLDBSWIGPythonRunScriptKeywordThread(
- const char *python_function_name, const char *session_dictionary_name,
- lldb::ThreadSP &thread, std::string &output);
-
-extern "C" bool LLDBSWIGPythonRunScriptKeywordTarget(
- const char *python_function_name, const char *session_dictionary_name,
- lldb::TargetSP &target, std::string &output);
-
-extern "C" bool LLDBSWIGPythonRunScriptKeywordFrame(
- const char *python_function_name, const char *session_dictionary_name,
- lldb::StackFrameSP &frame, std::string &output);
-
-extern "C" bool LLDBSWIGPythonRunScriptKeywordValue(
- const char *python_function_name, const char *session_dictionary_name,
- lldb::ValueObjectSP &value, std::string &output);
-
-extern "C" void *
-LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting,
- const lldb::TargetSP &target_sp);
static ScriptInterpreterPythonImpl *GetPythonInterpreter(Debugger &debugger) {
ScriptInterpreter *script_interpreter =
@@ -1591,9 +1444,9 @@ lldb::ValueObjectListSP ScriptInterpreterPythonImpl::GetRecognizedArguments(
if (!implementor.IsAllocated())
return ValueObjectListSP();
- PythonObject py_return(PyRefType::Owned,
- (PyObject *)LLDBSwigPython_GetRecognizedArguments(
- implementor.get(), frame_sp));
+ PythonObject py_return(
+ PyRefType::Owned,
+ LLDBSwigPython_GetRecognizedArguments(implementor.get(), frame_sp));
// if it fails, print the error but otherwise go on
if (PyErr_Occurred()) {
@@ -2423,7 +2276,7 @@ size_t ScriptInterpreterPythonImpl::CalculateNumChildren(
StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
if (!generic)
return 0;
- void *implementor = generic->GetValue();
+ auto *implementor = static_cast<PyObject *>(generic->GetValue());
if (!implementor)
return 0;
@@ -2446,7 +2299,7 @@ lldb::ValueObjectSP ScriptInterpreterPythonImpl::GetChildAtIndex(
StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
if (!generic)
return lldb::ValueObjectSP();
- void *implementor = generic->GetValue();
+ auto *implementor = static_cast<PyObject *>(generic->GetValue());
if (!implementor)
return lldb::ValueObjectSP();
@@ -2454,7 +2307,7 @@ lldb::ValueObjectSP ScriptInterpreterPythonImpl::GetChildAtIndex(
{
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- void *child_ptr = LLDBSwigPython_GetChildAtIndex(implementor, idx);
+ PyObject *child_ptr = LLDBSwigPython_GetChildAtIndex(implementor, idx);
if (child_ptr != nullptr && child_ptr != Py_None) {
lldb::SBValue *sb_value_ptr =
(lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(child_ptr);
@@ -2478,7 +2331,7 @@ int ScriptInterpreterPythonImpl::GetIndexOfChildWithName(
StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
if (!generic)
return UINT32_MAX;
- void *implementor = generic->GetValue();
+ auto *implementor = static_cast<PyObject *>(generic->GetValue());
if (!implementor)
return UINT32_MAX;
@@ -2503,7 +2356,7 @@ bool ScriptInterpreterPythonImpl::UpdateSynthProviderInstance(
StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
if (!generic)
return ret_val;
- void *implementor = generic->GetValue();
+ auto *implementor = static_cast<PyObject *>(generic->GetValue());
if (!implementor)
return ret_val;
@@ -2526,7 +2379,7 @@ bool ScriptInterpreterPythonImpl::MightHaveChildrenSynthProviderInstance(
StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
if (!generic)
return ret_val;
- void *implementor = generic->GetValue();
+ auto *implementor = static_cast<PyObject *>(generic->GetValue());
if (!implementor)
return ret_val;
@@ -2550,14 +2403,15 @@ lldb::ValueObjectSP ScriptInterpreterPythonImpl::GetSyntheticValue(
StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
if (!generic)
return ret_val;
- void *implementor = generic->GetValue();
+ auto *implementor = static_cast<PyObject *>(generic->GetValue());
if (!implementor)
return ret_val;
{
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- void *child_ptr = LLDBSwigPython_GetValueSynthProviderInstance(implementor);
+ PyObject *child_ptr =
+ LLDBSwigPython_GetValueSynthProviderInstance(implementor);
if (child_ptr != nullptr && child_ptr != Py_None) {
lldb::SBValue *sb_value_ptr =
(lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(child_ptr);
@@ -2653,11 +2507,11 @@ bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
}
{
- ProcessSP process_sp(process->shared_from_this());
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
ret_val = LLDBSWIGPythonRunScriptKeywordProcess(
- impl_function, m_dictionary_name.c_str(), process_sp, output);
+ impl_function, m_dictionary_name.c_str(), process->shared_from_this(),
+ output);
if (!ret_val)
error.SetErrorString("python script evaluation failed");
}
@@ -2753,11 +2607,10 @@ bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
}
{
- ValueObjectSP value_sp(value->GetSP());
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
ret_val = LLDBSWIGPythonRunScriptKeywordValue(
- impl_function, m_dictionary_name.c_str(), value_sp, output);
+ impl_function, m_dictionary_name.c_str(), value->GetSP(), output);
if (!ret_val)
error.SetErrorString("python script evaluation failed");
}
@@ -3076,9 +2929,9 @@ bool ScriptInterpreterPythonImpl::RunScriptBasedCommand(
SynchronicityHandler synch_handler(debugger_sp, synchronicity);
std::string args_str = args.str();
- ret_val = LLDBSwigPythonCallCommandObject(impl_obj_sp->GetValue(),
- debugger_sp, args_str.c_str(),
- cmd_retobj, exe_ctx_ref_sp);
+ ret_val = LLDBSwigPythonCallCommandObject(
+ static_cast<PyObject *>(impl_obj_sp->GetValue()), debugger_sp,
+ args_str.c_str(), cmd_retobj, exe_ctx_ref_sp);
}
if (!ret_val)
diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
index b07674af3bd9..9d23f1baf931 100644
--- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
+++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
@@ -500,7 +500,7 @@ void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
for (Symbol &symbol : symbols)
symtab.AddSymbol(std::move(symbol));
- symtab.CalculateSymbolSizes();
+ symtab.Finalize();
}
llvm::Expected<lldb::addr_t>
@@ -927,4 +927,3 @@ uint64_t SymbolFileBreakpad::GetDebugInfoSize() {
// Breakpad files are all debug info.
return m_objfile_sp->GetByteSize();
}
-
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 2dd7ae60b231..8c20244a6c44 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -2067,6 +2067,13 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(
}
void SymbolFileDWARF::PreloadSymbols() {
+ // Get the symbol table for the symbol file prior to taking the module lock
+ // so that it is available without needing to take the module lock. The DWARF
+ // indexing might end up needing to relocate items when DWARF sections are
+ // loaded as they might end up getting the section contents which can call
+ // ObjectFileELF::RelocateSection() which in turn will ask for the symbol
+ // table and can cause deadlocks.
+ GetSymtab();
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
m_index->Preload();
}
@@ -3271,15 +3278,14 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
}
const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die);
- const dw_tag_t parent_tag = die.GetParent().Tag();
+ const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
+ const dw_tag_t parent_tag = sc_parent_die.Tag();
bool is_static_member = (parent_tag == DW_TAG_compile_unit ||
parent_tag == DW_TAG_partial_unit) &&
(parent_context_die.Tag() == DW_TAG_class_type ||
parent_context_die.Tag() == DW_TAG_structure_type);
ValueType scope = eValueTypeInvalid;
-
- const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
SymbolContextScope *symbol_context_scope = nullptr;
bool has_explicit_mangled = mangled != nullptr;
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 8af90cb66e87..bf101ac1acf1 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -1182,8 +1182,9 @@ void SymbolFileNativePDB::FindFunctions(
FunctionNameType name_type_mask, bool include_inlines,
SymbolContextList &sc_list) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- // For now we only support lookup by method name.
- if (!(name_type_mask & eFunctionNameTypeMethod))
+ // For now we only support lookup by method name or full name.
+ if (!(name_type_mask & eFunctionNameTypeFull ||
+ name_type_mask & eFunctionNameTypeMethod))
return;
using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>;
diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index 45dfc4b9a152..db0ae241be7e 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -1421,7 +1421,6 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
));
}
- symtab.CalculateSymbolSizes();
symtab.Finalize();
}
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index b20ae32a08ac..b1dbc382ff04 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -91,7 +91,7 @@ static void VerifyDecl(clang::Decl *decl) {
assert(decl && "VerifyDecl called with nullptr?");
#ifndef NDEBUG
// We don't care about the actual access value here but only want to trigger
- // that Clang calls its internal Decl::AccessDeclContextSanity check.
+ // that Clang calls its internal Decl::AccessDeclContextCheck validation.
decl->getAccess();
#endif
}
diff --git a/lldb/source/Symbol/ObjectFile.cpp b/lldb/source/Symbol/ObjectFile.cpp
index 101af01341a2..bfab741b0d66 100644
--- a/lldb/source/Symbol/ObjectFile.cpp
+++ b/lldb/source/Symbol/ObjectFile.cpp
@@ -244,7 +244,7 @@ ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp,
m_type(eTypeInvalid), m_strata(eStrataInvalid),
m_file_offset(file_offset), m_length(length), m_data(), m_process_wp(),
m_memory_addr(LLDB_INVALID_ADDRESS), m_sections_up(), m_symtab_up(),
- m_synthetic_symbol_idx(0) {
+ m_symtab_once_up(new llvm::once_flag()) {
if (file_spec_ptr)
m_file = *file_spec_ptr;
if (data_sp)
@@ -265,7 +265,7 @@ ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp,
: ModuleChild(module_sp), m_file(), m_type(eTypeInvalid),
m_strata(eStrataInvalid), m_file_offset(0), m_length(0), m_data(),
m_process_wp(process_sp), m_memory_addr(header_addr), m_sections_up(),
- m_symtab_up(), m_synthetic_symbol_idx(0) {
+ m_symtab_up(), m_symtab_once_up(new llvm::once_flag()) {
if (header_data_sp)
m_data.SetData(header_data_sp, 0, header_data_sp->GetByteSize());
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
@@ -571,11 +571,13 @@ bool ObjectFile::SplitArchivePathWithObject(llvm::StringRef path_with_object,
void ObjectFile::ClearSymtab() {
ModuleSP module_sp(GetModule());
if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
LLDB_LOGF(log, "%p ObjectFile::ClearSymtab () symtab = %p",
static_cast<void *>(this),
static_cast<void *>(m_symtab_up.get()));
+ // Since we need to clear the symbol table, we need a new llvm::once_flag
+ // instance so we can safely create another symbol table
+ m_symtab_once_up.reset(new llvm::once_flag());
m_symtab_up.reset();
}
}
@@ -715,3 +717,33 @@ void llvm::format_provider<ObjectFile::Strata>::format(
break;
}
}
+
+
+Symtab *ObjectFile::GetSymtab() {
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ // We can't take the module lock in ObjectFile::GetSymtab() or we can
+ // deadlock in DWARF indexing when any file asks for the symbol table from
+ // an object file. This currently happens in the preloading of symbols in
+ // SymbolFileDWARF::PreloadSymbols() because the main thread will take the
+ // module lock, and then threads will be spun up to index the DWARF and
+ // any of those threads might end up trying to relocate items in the DWARF
+ // sections which causes ObjectFile::GetSectionData(...) to relocate section
+ // data which requires the symbol table.
+ //
+ // So to work around this, we create the symbol table one time using
+ // llvm::once_flag, lock it, and then set the unique pointer. Any other
+ // thread that gets ahold of the symbol table before parsing is done, will
+ // not be able to access the symbol table contents since all APIs in Symtab
+ // are protected by a mutex in the Symtab object itself.
+ llvm::call_once(*m_symtab_once_up, [&]() {
+ ElapsedTime elapsed(module_sp->GetSymtabParseTime());
+ Symtab *symtab = new Symtab(this);
+ std::lock_guard<std::recursive_mutex> symtab_guard(symtab->GetMutex());
+ m_symtab_up.reset(symtab);
+ ParseSymtab(*m_symtab_up);
+ m_symtab_up->Finalize();
+ });
+ }
+ return m_symtab_up.get();
+}
diff --git a/lldb/source/Symbol/Symtab.cpp b/lldb/source/Symbol/Symtab.cpp
index 19c1fee2bb38..c67955523bfb 100644
--- a/lldb/source/Symbol/Symtab.cpp
+++ b/lldb/source/Symbol/Symtab.cpp
@@ -997,10 +997,15 @@ void Symtab::InitAddressIndexes() {
}
}
-void Symtab::CalculateSymbolSizes() {
+void Symtab::Finalize() {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
- // Size computation happens inside InitAddressIndexes.
+ // Calculate the size of symbols inside InitAddressIndexes.
InitAddressIndexes();
+ // Shrink to fit the symbols so we don't waste memory
+ if (m_symbols.capacity() > m_symbols.size()) {
+ collection new_symbols(m_symbols.begin(), m_symbols.end());
+ m_symbols.swap(new_symbols);
+ }
}
Symbol *Symtab::FindSymbolAtFileAddress(addr_t file_addr) {
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index bd455310f08e..af5ca0225169 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -1222,22 +1222,6 @@ Platform::CreateArchList(llvm::ArrayRef<llvm::Triple::ArchType> archs,
return list;
}
-bool Platform::GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) {
- const auto &archs = GetSupportedArchitectures();
- if (idx >= archs.size())
- return false;
- arch = archs[idx];
- return true;
-}
-
-std::vector<ArchSpec> Platform::GetSupportedArchitectures() {
- std::vector<ArchSpec> result;
- ArchSpec arch;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(idx, arch); ++idx)
- result.push_back(arch);
- return result;
-}
-
/// Lets a platform answer if it is compatible with a given
/// architecture and the target triple contained within.
bool Platform::IsCompatibleArchitecture(const ArchSpec &arch,
@@ -1563,28 +1547,20 @@ Status
Platform::GetCachedExecutable(ModuleSpec &module_spec,
lldb::ModuleSP &module_sp,
const FileSpecList *module_search_paths_ptr) {
- const auto platform_spec = module_spec.GetFileSpec();
- const auto error =
- LoadCachedExecutable(module_spec, module_sp, module_search_paths_ptr);
- if (error.Success()) {
- module_spec.GetFileSpec() = module_sp->GetFileSpec();
- module_spec.GetPlatformFileSpec() = platform_spec;
- }
-
- return error;
-}
-
-Status
-Platform::LoadCachedExecutable(const ModuleSpec &module_spec,
- lldb::ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr) {
- return GetRemoteSharedModule(
+ FileSpec platform_spec = module_spec.GetFileSpec();
+ Status error = GetRemoteSharedModule(
module_spec, nullptr, module_sp,
[&](const ModuleSpec &spec) {
return ResolveRemoteExecutable(spec, module_sp,
module_search_paths_ptr);
},
nullptr);
+ if (error.Success()) {
+ module_spec.GetFileSpec() = module_sp->GetFileSpec();
+ module_spec.GetPlatformFileSpec() = platform_spec;
+ }
+
+ return error;
}
Status Platform::GetRemoteSharedModule(const ModuleSpec &module_spec,
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 84dc2b94a0eb..94f378886e50 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -5853,13 +5853,6 @@ Process::AdvanceAddressToNextBranchInstruction(Address default_stop_addr,
return retval;
}
-Status Process::GetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &range_info) {
- if (auto abi = GetABI())
- load_addr = abi->FixDataAddress(load_addr);
- return DoGetMemoryRegionInfo(load_addr, range_info);
-}
-
Status
Process::GetMemoryRegions(lldb_private::MemoryRegionInfos &region_list) {
diff --git a/lldb/source/Target/RemoteAwarePlatform.cpp b/lldb/source/Target/RemoteAwarePlatform.cpp
index eb39fc6db304..b92d4d5fcaa7 100644
--- a/lldb/source/Target/RemoteAwarePlatform.cpp
+++ b/lldb/source/Target/RemoteAwarePlatform.cpp
@@ -131,9 +131,9 @@ Status RemoteAwarePlatform::ResolveExecutable(
// architectures that we should be using (in the correct order) and see
// if we can find a match that way
StreamString arch_names;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
- idx, resolved_module_spec.GetArchitecture());
- ++idx) {
+ llvm::ListSeparator LS;
+ for (const ArchSpec &arch : GetSupportedArchitectures()) {
+ resolved_module_spec.GetArchitecture() = arch;
error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
module_search_paths_ptr, nullptr, nullptr);
// Did we find an executable using one of the
@@ -144,10 +144,7 @@ Status RemoteAwarePlatform::ResolveExecutable(
error.SetErrorToGenericError();
}
- if (idx > 0)
- arch_names.PutCString(", ");
- arch_names.PutCString(
- resolved_module_spec.GetArchitecture().GetArchitectureName());
+ arch_names << LS << arch.GetArchitectureName();
}
if (error.Fail() || !exe_module_sp) {
diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp
index a51c124f9615..977cc306bb4e 100644
--- a/lldb/tools/driver/Driver.cpp
+++ b/lldb/tools/driver/Driver.cpp
@@ -24,7 +24,6 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/Path.h"
-#include "llvm/Support/Process.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
@@ -44,14 +43,6 @@
#include <cstring>
#include <fcntl.h>
-// Includes for pipe()
-#if defined(_WIN32)
-#include <fcntl.h>
-#include <io.h>
-#else
-#include <unistd.h>
-#endif
-
#if !defined(__APPLE__)
#include "llvm/Support/DataTypes.h"
#endif
@@ -421,60 +412,6 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) {
return error;
}
-static inline int OpenPipe(int fds[2], std::size_t size) {
-#ifdef _WIN32
- return _pipe(fds, size, O_BINARY);
-#else
- (void)size;
- return pipe(fds);
-#endif
-}
-
-static ::FILE *PrepareCommandsForSourcing(const char *commands_data,
- size_t commands_size) {
- enum PIPES { READ, WRITE }; // Indexes for the read and write fds
- int fds[2] = {-1, -1};
-
- if (OpenPipe(fds, commands_size) != 0) {
- WithColor::error()
- << "can't create pipe file descriptors for LLDB commands\n";
- return nullptr;
- }
-
- ssize_t nrwr = write(fds[WRITE], commands_data, commands_size);
- if (size_t(nrwr) != commands_size) {
- WithColor::error()
- << format(
- "write(%i, %p, %" PRIu64
- ") failed (errno = %i) when trying to open LLDB commands pipe",
- fds[WRITE], static_cast<const void *>(commands_data),
- static_cast<uint64_t>(commands_size), errno)
- << '\n';
- llvm::sys::Process::SafelyCloseFileDescriptor(fds[READ]);
- llvm::sys::Process::SafelyCloseFileDescriptor(fds[WRITE]);
- return nullptr;
- }
-
- // Close the write end of the pipe, so that the command interpreter will exit
- // when it consumes all the data.
- llvm::sys::Process::SafelyCloseFileDescriptor(fds[WRITE]);
-
- // Open the read file descriptor as a FILE * that we can return as an input
- // handle.
- ::FILE *commands_file = fdopen(fds[READ], "rb");
- if (commands_file == nullptr) {
- WithColor::error() << format("fdopen(%i, \"rb\") failed (errno = %i) "
- "when trying to open LLDB commands pipe",
- fds[READ], errno)
- << '\n';
- llvm::sys::Process::SafelyCloseFileDescriptor(fds[READ]);
- return nullptr;
- }
-
- // 'commands_file' now owns the read descriptor.
- return commands_file;
-}
-
std::string EscapeString(std::string arg) {
std::string::size_type pos = 0;
while ((pos = arg.find_first_of("\"\\", pos)) != std::string::npos) {
@@ -604,21 +541,15 @@ int Driver::MainLoop() {
// Check if we have any data in the commands stream, and if so, save it to a
// temp file
// so we can then run the command interpreter using the file contents.
- const char *commands_data = commands_stream.GetData();
- const size_t commands_size = commands_stream.GetSize();
-
bool go_interactive = true;
- if ((commands_data != nullptr) && (commands_size != 0u)) {
- FILE *commands_file =
- PrepareCommandsForSourcing(commands_data, commands_size);
-
- if (commands_file == nullptr) {
- // We should have already printed an error in PrepareCommandsForSourcing.
+ if ((commands_stream.GetData() != nullptr) &&
+ (commands_stream.GetSize() != 0u)) {
+ SBError error = m_debugger.SetInputString(commands_stream.GetData());
+ if (error.Fail()) {
+ WithColor::error() << error.GetCString() << '\n';
return 1;
}
- m_debugger.SetInputFileHandle(commands_file, true);
-
// Set the debugger into Sync mode when running the command file. Otherwise
// command files that run the target won't run in a sensible way.
bool old_async = m_debugger.GetAsync();
@@ -651,12 +582,9 @@ int Driver::MainLoop() {
SBStream crash_commands_stream;
WriteCommandsForSourcing(eCommandPlacementAfterCrash,
crash_commands_stream);
- const char *crash_commands_data = crash_commands_stream.GetData();
- const size_t crash_commands_size = crash_commands_stream.GetSize();
- commands_file =
- PrepareCommandsForSourcing(crash_commands_data, crash_commands_size);
- if (commands_file != nullptr) {
- m_debugger.SetInputFileHandle(commands_file, true);
+ SBError error =
+ m_debugger.SetInputString(crash_commands_stream.GetData());
+ if (error.Success()) {
SBCommandInterpreterRunResult local_results =
m_debugger.RunCommandInterpreter(options);
if (local_results.GetResult() ==
diff --git a/lldb/tools/lldb-server/lldb-platform.cpp b/lldb/tools/lldb-server/lldb-platform.cpp
index d4b54362bb46..9e07f4c8debd 100644
--- a/lldb/tools/lldb-server/lldb-platform.cpp
+++ b/lldb/tools/lldb-server/lldb-platform.cpp
@@ -364,23 +364,17 @@ int main_platform(int argc, char *argv[]) {
fprintf(stderr, "failed to start gdbserver: %s\n", error.AsCString());
}
- // After we connected, we need to get an initial ack from...
- if (platform.HandshakeWithClient()) {
- bool interrupt = false;
- bool done = false;
- while (!interrupt && !done) {
- if (platform.GetPacketAndSendResponse(llvm::None, error, interrupt,
- done) !=
- GDBRemoteCommunication::PacketResult::Success)
- break;
- }
-
- if (error.Fail()) {
- WithColor::error() << error.AsCString() << '\n';
- }
- } else {
- WithColor::error() << "handshake with client failed\n";
+ bool interrupt = false;
+ bool done = false;
+ while (!interrupt && !done) {
+ if (platform.GetPacketAndSendResponse(llvm::None, error, interrupt,
+ done) !=
+ GDBRemoteCommunication::PacketResult::Success)
+ break;
}
+
+ if (error.Fail())
+ WithColor::error() << error.AsCString() << '\n';
}
} while (g_server);