aboutsummaryrefslogtreecommitdiff
path: root/lldb
diff options
context:
space:
mode:
Diffstat (limited to 'lldb')
-rw-r--r--lldb/bindings/interface/SBData.i4
-rw-r--r--lldb/bindings/lua/lua-swigsafecast.swig31
-rw-r--r--lldb/bindings/lua/lua-typemaps.swig225
-rw-r--r--lldb/bindings/lua/lua-wrapper.swig155
-rw-r--r--lldb/bindings/lua/lua.swig1
-rw-r--r--lldb/bindings/python/python-swigsafecast.swig96
-rw-r--r--lldb/bindings/python/python-typemaps.swig348
-rw-r--r--lldb/bindings/python/python-wrapper.swig1715
-rw-r--r--lldb/include/lldb/API/SBData.h3
-rw-r--r--lldb/include/lldb/API/SBStructuredData.h2
-rw-r--r--lldb/include/lldb/API/SBSymbolContext.h4
-rw-r--r--lldb/include/lldb/API/SBTypeSummary.h4
-rw-r--r--lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h11
-rw-r--r--lldb/include/lldb/Core/DataFileCache.h216
-rw-r--r--lldb/include/lldb/Core/Mangled.h41
-rw-r--r--lldb/include/lldb/Core/Module.h94
-rw-r--r--lldb/include/lldb/Core/ModuleList.h7
-rw-r--r--lldb/include/lldb/Core/PluginManager.h2
-rw-r--r--lldb/include/lldb/Core/StructuredDataImpl.h3
-rw-r--r--lldb/include/lldb/Core/ValueObject.h2
-rw-r--r--lldb/include/lldb/Expression/UserExpression.h6
-rw-r--r--lldb/include/lldb/Host/Config.h.cmake2
-rw-r--r--lldb/include/lldb/Host/FileSystem.h8
-rw-r--r--lldb/include/lldb/Interpreter/CommandReturnObject.h8
-rw-r--r--lldb/include/lldb/Interpreter/ScriptInterpreter.h6
-rw-r--r--lldb/include/lldb/Symbol/ObjectFile.h31
-rw-r--r--lldb/include/lldb/Symbol/Symbol.h40
-rw-r--r--lldb/include/lldb/Symbol/SymbolFile.h10
-rw-r--r--lldb/include/lldb/Symbol/Symtab.h81
-rw-r--r--lldb/include/lldb/Symbol/Type.h46
-rw-r--r--lldb/include/lldb/Target/LanguageRuntime.h2
-rw-r--r--lldb/include/lldb/Target/Target.h4
-rw-r--r--lldb/include/lldb/Target/ThreadPlanPython.h14
-rw-r--r--lldb/include/lldb/Utility/DataEncoder.h249
-rw-r--r--lldb/include/lldb/Utility/RangeMap.h1
-rw-r--r--lldb/include/lldb/Utility/Reproducer.h7
-rw-r--r--lldb/include/lldb/Version/Version.h23
-rw-r--r--lldb/include/lldb/Version/Version.inc.in6
-rw-r--r--lldb/include/lldb/lldb-forward.h5
-rw-r--r--lldb/include/lldb/lldb-private.h6
-rw-r--r--lldb/source/API/SBData.cpp19
-rw-r--r--lldb/source/API/SBDebugger.cpp6
-rw-r--r--lldb/source/API/SBFrame.cpp6
-rw-r--r--lldb/source/API/SBReproducer.cpp97
-rw-r--r--lldb/source/API/SBStructuredData.cpp8
-rw-r--r--lldb/source/API/SBSymbolContext.cpp17
-rw-r--r--lldb/source/API/SBSymbolContextList.cpp5
-rw-r--r--lldb/source/API/SBThreadPlan.cpp6
-rw-r--r--lldb/source/API/SBTypeSummary.cpp21
-rw-r--r--lldb/source/API/SystemInitializerFull.cpp9
-rw-r--r--lldb/source/Breakpoint/BreakpointResolverScripted.cpp33
-rw-r--r--lldb/source/Commands/CommandObjectMemory.cpp2
-rw-r--r--lldb/source/Commands/CommandObjectReproducer.cpp15
-rw-r--r--lldb/source/Commands/CommandObjectVersion.cpp2
-rw-r--r--lldb/source/Core/CoreProperties.td20
-rw-r--r--lldb/source/Core/DataFileCache.cpp307
-rw-r--r--lldb/source/Core/IOHandlerCursesGUI.cpp15
-rw-r--r--lldb/source/Core/Mangled.cpp110
-rw-r--r--lldb/source/Core/Module.cpp72
-rw-r--r--lldb/source/Core/ModuleList.cpp49
-rw-r--r--lldb/source/Core/PluginManager.cpp6
-rw-r--r--lldb/source/DataFormatters/CXXFunctionPointer.cpp31
-rw-r--r--lldb/source/DataFormatters/FormatManager.cpp9
-rw-r--r--lldb/source/Expression/DWARFExpression.cpp30
-rw-r--r--lldb/source/Expression/IRExecutionUnit.cpp2
-rw-r--r--lldb/source/Expression/IRMemoryMap.cpp4
-rw-r--r--lldb/source/Expression/REPL.cpp6
-rw-r--r--lldb/source/Expression/UserExpression.cpp11
-rw-r--r--lldb/source/Host/common/FileSystem.cpp8
-rw-r--r--lldb/source/Host/common/ProcessLaunchInfo.cpp20
-rw-r--r--lldb/source/Host/posix/ProcessLauncherPosixFork.cpp1
-rw-r--r--lldb/source/Initialization/SystemInitializerCommon.cpp2
-rw-r--r--lldb/source/Interpreter/CommandInterpreter.cpp3
-rw-r--r--lldb/source/Interpreter/CommandReturnObject.cpp8
-rw-r--r--lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp10
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp2
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp4
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp2
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h2
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp2
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp2
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp2
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp36
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/Generic.h25
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/GenericOptional.cpp139
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxx.h4
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp84
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h4
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp3
-rw-r--r--lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp2
-rw-r--r--lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp90
-rw-r--r--lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h2
-rw-r--r--lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td12
-rw-r--r--lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp16
-rw-r--r--lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp218
-rw-r--r--lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h51
-rw-r--r--lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.cpp110
-rw-r--r--lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.h41
-rw-r--r--lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.cpp83
-rw-r--r--lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.h41
-rw-r--r--lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.cpp88
-rw-r--r--lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.h41
-rw-r--r--lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.cpp85
-rw-r--r--lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.h36
-rw-r--r--lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp4
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp36
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h6
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp102
-rw-r--r--lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp5
-rw-r--r--lldb/source/Plugins/Process/scripted/ScriptedThread.cpp10
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp33
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Lua/SWIGLuaBridge.h28
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h43
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp52
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h11
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h7
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp6
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp6
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp5
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp11
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h12
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp133
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h6
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp30
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h12
-rw-r--r--lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp3
-rw-r--r--lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp3
-rw-r--r--lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp19
-rw-r--r--lldb/source/Symbol/ObjectFile.cpp25
-rw-r--r--lldb/source/Symbol/Symbol.cpp129
-rw-r--r--lldb/source/Symbol/SymbolFile.cpp12
-rw-r--r--lldb/source/Symbol/Symtab.cpp199
-rw-r--r--lldb/source/Symbol/Type.cpp2
-rw-r--r--lldb/source/Target/StackFrame.cpp24
-rw-r--r--lldb/source/Target/Target.cpp19
-rw-r--r--lldb/source/Target/Thread.cpp10
-rw-r--r--lldb/source/Target/ThreadPlanPython.cpp7
-rw-r--r--lldb/source/Target/ThreadPlanStack.cpp1
-rw-r--r--lldb/source/Target/UnwindLLDB.cpp1
-rw-r--r--lldb/source/Utility/DataEncoder.cpp157
-rw-r--r--lldb/source/Utility/FileSpec.cpp2
-rw-r--r--lldb/source/Utility/Reproducer.cpp27
-rw-r--r--lldb/source/Version/Version.cpp (renamed from lldb/source/lldb.cpp)26
-rw-r--r--lldb/tools/driver/Driver.cpp49
-rw-r--r--lldb/tools/driver/Options.td11
-rw-r--r--lldb/tools/lldb-server/lldb-server.cpp2
148 files changed, 4618 insertions, 2388 deletions
diff --git a/lldb/bindings/interface/SBData.i b/lldb/bindings/interface/SBData.i
index a1fb4472cd23..1f2f9fbf05e2 100644
--- a/lldb/bindings/interface/SBData.i
+++ b/lldb/bindings/interface/SBData.i
@@ -96,6 +96,10 @@ public:
void
SetData (lldb::SBError& error, const void *buf, size_t size, lldb::ByteOrder endian, uint8_t addr_size);
+ void
+ SetDataWithOwnership (lldb::SBError& error, const void *buf, size_t size,
+ lldb::ByteOrder endian, uint8_t addr_size);
+
bool
Append (const SBData& rhs);
diff --git a/lldb/bindings/lua/lua-swigsafecast.swig b/lldb/bindings/lua/lua-swigsafecast.swig
index 0b67c41434e9..35cb5e22a4c5 100644
--- a/lldb/bindings/lua/lua-swigsafecast.swig
+++ b/lldb/bindings/lua/lua-swigsafecast.swig
@@ -1,27 +1,20 @@
-template <typename SBClass>
-void
-PushSBClass (lua_State* L, SBClass* obj);
+template <typename SBClass> void PushSBClass(lua_State *L, SBClass *obj);
-void
-PushSBClass (lua_State* L, lldb::SBFrame* frame_sb)
-{
- SWIG_NewPointerObj(L, frame_sb, SWIGTYPE_p_lldb__SBFrame, 0);
+void PushSBClass(lua_State *L, lldb::SBFrame *frame_sb) {
+ SWIG_NewPointerObj(L, frame_sb, SWIGTYPE_p_lldb__SBFrame, 0);
}
-void
-PushSBClass (lua_State* L, lldb::SBBreakpointLocation* breakpoint_location_sb)
-{
- SWIG_NewPointerObj(L, breakpoint_location_sb, SWIGTYPE_p_lldb__SBBreakpointLocation, 0);
+void PushSBClass(lua_State *L,
+ lldb::SBBreakpointLocation *breakpoint_location_sb) {
+ SWIG_NewPointerObj(L, breakpoint_location_sb,
+ SWIGTYPE_p_lldb__SBBreakpointLocation, 0);
}
-void
-PushSBClass (lua_State* L, lldb::SBWatchpoint* watchpoint_sb)
-{
- SWIG_NewPointerObj(L, watchpoint_sb, SWIGTYPE_p_lldb__SBWatchpoint, 0);
+void PushSBClass(lua_State *L, lldb::SBWatchpoint *watchpoint_sb) {
+ SWIG_NewPointerObj(L, watchpoint_sb, SWIGTYPE_p_lldb__SBWatchpoint, 0);
}
-void
-PushSBClass (lua_State* L, lldb::SBStructuredData* structured_data_sb)
-{
- SWIG_NewPointerObj(L, structured_data_sb, SWIGTYPE_p_lldb__SBStructuredData, 0);
+void PushSBClass(lua_State *L, lldb::SBStructuredData *structured_data_sb) {
+ SWIG_NewPointerObj(L, structured_data_sb, SWIGTYPE_p_lldb__SBStructuredData,
+ 0);
}
diff --git a/lldb/bindings/lua/lua-typemaps.swig b/lldb/bindings/lua/lua-typemaps.swig
index e3b3f5718d15..15a18deaa3a4 100644
--- a/lldb/bindings/lua/lua-typemaps.swig
+++ b/lldb/bindings/lua/lua-typemaps.swig
@@ -76,11 +76,11 @@ LLDB_NUMBER_TYPEMAP(enum SWIGTYPE);
// typemap for a char buffer
%typemap(in) (char *dst, size_t dst_len) {
- $2 = luaL_checkinteger(L, $input);
- if ($2 <= 0) {
- return luaL_error(L, "Positive integer expected");
- }
- $1 = (char *) malloc($2);
+ $2 = luaL_checkinteger(L, $input);
+ if ($2 <= 0) {
+ return luaL_error(L, "Positive integer expected");
+ }
+ $1 = (char *)malloc($2);
}
// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated
@@ -92,14 +92,14 @@ LLDB_NUMBER_TYPEMAP(enum SWIGTYPE);
// Return the char buffer. Discarding any previous return result
%typemap(argout) (char *dst, size_t dst_len) {
- lua_pop(L, 1); // Blow away the previous result
- if ($result == 0) {
- lua_pushliteral(L, "");
- } else {
- lua_pushlstring(L, (const char *)$1, $result);
- }
- free($1);
- // SWIG_arg was already incremented
+ lua_pop(L, 1); // Blow away the previous result
+ if ($result == 0) {
+ lua_pushliteral(L, "");
+ } else {
+ lua_pushlstring(L, (const char *)$1, $result);
+ }
+ free($1);
+ // SWIG_arg was already incremented
}
// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated
@@ -114,18 +114,18 @@ LLDB_NUMBER_TYPEMAP(enum SWIGTYPE);
// Typemap for handling a snprintf-like API like SBThread::GetStopDescription.
%typemap(in) (char *dst_or_null, size_t dst_len) {
- $2 = luaL_checkinteger(L, $input);
- if ($2 <= 0) {
- return luaL_error(L, "Positive integer expected");
- }
- $1 = (char *)malloc($2);
+ $2 = luaL_checkinteger(L, $input);
+ if ($2 <= 0) {
+ return luaL_error(L, "Positive integer expected");
+ }
+ $1 = (char *)malloc($2);
}
%typemap(argout) (char *dst_or_null, size_t dst_len) {
- lua_pop(L, 1); // Blow away the previous result
- lua_pushlstring(L, (const char *)$1, $result);
- free($1);
- // SWIG_arg was already incremented
+ lua_pop(L, 1); // Blow away the previous result
+ lua_pushlstring(L, (const char *)$1, $result);
+ free($1);
+ // SWIG_arg was already incremented
}
//===----------------------------------------------------------------------===//
@@ -133,22 +133,22 @@ LLDB_NUMBER_TYPEMAP(enum SWIGTYPE);
// Typemap for handling SBModule::GetVersion
%typemap(in) (uint32_t *versions, uint32_t num_versions) {
- $2 = 99;
- $1 = (uint32_t *)malloc(sizeof(uint32_t) * $2);
+ $2 = 99;
+ $1 = (uint32_t *)malloc(sizeof(uint32_t) * $2);
}
%typemap(argout) (uint32_t *versions, uint32_t num_versions) {
- uint32_t count = result;
- if (count >= $2)
- count = $2;
- lua_newtable(L);
- int i = 0;
- while (i++ < count) {
- lua_pushinteger(L, $1[i - 1]);
- lua_seti(L, -2, i);
- }
- SWIG_arg++;
- free($1);
+ uint32_t count = result;
+ if (count >= $2)
+ count = $2;
+ lua_newtable(L);
+ int i = 0;
+ while (i++ < count) {
+ lua_pushinteger(L, $1[i - 1]);
+ lua_seti(L, -2, i);
+ }
+ SWIG_arg++;
+ free($1);
}
//===----------------------------------------------------------------------===//
@@ -156,15 +156,15 @@ LLDB_NUMBER_TYPEMAP(enum SWIGTYPE);
// Typemap for handling SBDebugger::SetLoggingCallback
%typemap(in) (lldb::LogOutputCallback log_callback, void *baton) {
- $1 = LLDBSwigLuaCallLuaLogOutputCallback;
- $2 = (void *)L;
+ $1 = LLDBSwigLuaCallLuaLogOutputCallback;
+ $2 = (void *)L;
- luaL_checktype(L, 2, LUA_TFUNCTION);
- lua_settop(L, 2);
+ luaL_checktype(L, 2, LUA_TFUNCTION);
+ lua_settop(L, 2);
- lua_pushlightuserdata(L, (void *)&LLDBSwigLuaCallLuaLogOutputCallback);
- lua_insert(L, 2);
- lua_settable(L, LUA_REGISTRYINDEX);
+ lua_pushlightuserdata(L, (void *)&LLDBSwigLuaCallLuaLogOutputCallback);
+ lua_insert(L, 2);
+ lua_settable(L, LUA_REGISTRYINDEX);
}
//===----------------------------------------------------------------------===//
@@ -172,20 +172,20 @@ LLDB_NUMBER_TYPEMAP(enum SWIGTYPE);
// Typemap for handling SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len)
%typemap(in) (const char *cstr, uint32_t cstr_len) {
- $1 = (char *)luaL_checklstring(L, $input, (size_t *)&$2);
+ $1 = (char *)luaL_checklstring(L, $input, (size_t *)&$2);
}
// Typemap for handling SBProcess::PutSTDIN
%typemap(in) (const char *src, size_t src_len) {
- $1 = (char *)luaL_checklstring(L, $input, &$2);
+ $1 = (char *)luaL_checklstring(L, $input, &$2);
}
// Typemap for handling SBProcess::WriteMemory, SBTarget::GetInstructions...
%typemap(in) (const void *buf, size_t size),
(const void *data, size_t data_len) {
- $1 = (void *)luaL_checklstring(L, $input, &$2);
+ $1 = (void *)luaL_checklstring(L, $input, &$2);
}
//===----------------------------------------------------------------------===//
@@ -195,35 +195,35 @@ LLDB_NUMBER_TYPEMAP(enum SWIGTYPE);
// It should accept a Lua table of strings, for stuff like "argv" and "envp".
%typemap(in) char ** {
- if (lua_istable(L, $input)) {
- size_t size = lua_rawlen(L, $input);
- $1 = (char **)malloc((size + 1) * sizeof(char *));
- int i = 0, j = 0;
- while (i++ < size) {
- lua_rawgeti(L, $input, i);
- if (!lua_isstring(L, -1)) {
- // if current element cannot be converted to string, raise an error
- lua_pop(L, 1);
- return luaL_error(L, "List should only contain strings");
- }
- $1[j++] = (char *)lua_tostring(L, -1);
- lua_pop(L, 1);
+ if (lua_istable(L, $input)) {
+ size_t size = lua_rawlen(L, $input);
+ $1 = (char **)malloc((size + 1) * sizeof(char *));
+ int i = 0, j = 0;
+ while (i++ < size) {
+ lua_rawgeti(L, $input, i);
+ if (!lua_isstring(L, -1)) {
+ // if current element cannot be converted to string, raise an error
+ lua_pop(L, 1);
+ return luaL_error(L, "List should only contain strings");
}
- $1[j] = 0;
- } else if (lua_isnil(L, $input)) {
- // "nil" is also acceptable, equivalent as an empty table
- $1 = NULL;
- } else {
- return luaL_error(L, "A list of strings expected");
- }
+ $1[j++] = (char *)lua_tostring(L, -1);
+ lua_pop(L, 1);
+ }
+ $1[j] = 0;
+ } else if (lua_isnil(L, $input)) {
+ // "nil" is also acceptable, equivalent as an empty table
+ $1 = NULL;
+ } else {
+ return luaL_error(L, "A list of strings expected");
+ }
}
%typemap(freearg) char ** {
- free((char *) $1);
+ free((char *) $1);
}
%typecheck(SWIG_TYPECHECK_STRING_ARRAY) char ** {
- $1 = (lua_istable(L, $input) || lua_isnil(L, $input));
+ $1 = (lua_istable(L, $input) || lua_isnil(L, $input));
}
//===----------------------------------------------------------------------===//
@@ -231,30 +231,30 @@ LLDB_NUMBER_TYPEMAP(enum SWIGTYPE);
// Typemap for file handles (e.g. used in SBDebugger::SetOutputFile)
%typemap(in) lldb::FileSP {
- luaL_Stream *p = (luaL_Stream *)luaL_checkudata(L, $input, LUA_FILEHANDLE);
- lldb::FileSP file_sp;
- file_sp = std::make_shared<lldb_private::NativeFile>(p->f, false);
- if (!file_sp->IsValid())
- return luaL_error(L, "Invalid file");
- $1 = file_sp;
+ luaL_Stream *p = (luaL_Stream *)luaL_checkudata(L, $input, LUA_FILEHANDLE);
+ lldb::FileSP file_sp;
+ file_sp = std::make_shared<lldb_private::NativeFile>(p->f, false);
+ if (!file_sp->IsValid())
+ return luaL_error(L, "Invalid file");
+ $1 = file_sp;
}
%typecheck(SWIG_TYPECHECK_POINTER) lldb::FileSP {
- $1 = (lua_isuserdata(L, $input)) &&
- (luaL_testudata(L, $input, LUA_FILEHANDLE) != nullptr);
+ $1 = (lua_isuserdata(L, $input)) &&
+ (luaL_testudata(L, $input, LUA_FILEHANDLE) != nullptr);
}
// Typemap for file handles (e.g. used in SBDebugger::GetOutputFileHandle)
%typemap(out) lldb::FileSP {
- lldb::FileSP &sp = $1;
- if (sp && sp->IsValid()) {
- luaL_Stream *p = (luaL_Stream *)lua_newuserdata(L, sizeof(luaL_Stream));
- p->closef = &LLDBSwigLuaCloseFileHandle;
- p->f = sp->GetStream();
- luaL_setmetatable(L, LUA_FILEHANDLE);
- SWIG_arg++;
- }
+ lldb::FileSP &sp = $1;
+ if (sp && sp->IsValid()) {
+ luaL_Stream *p = (luaL_Stream *)lua_newuserdata(L, sizeof(luaL_Stream));
+ p->closef = &LLDBSwigLuaCloseFileHandle;
+ p->f = sp->GetStream();
+ luaL_setmetatable(L, LUA_FILEHANDLE);
+ SWIG_arg++;
+ }
}
//===----------------------------------------------------------------------===//
@@ -266,29 +266,29 @@ LLDB_NUMBER_TYPEMAP(enum SWIGTYPE);
(int64_t* array, size_t array_len),
(int32_t* array, size_t array_len),
(double* array, size_t array_len) {
- if (lua_istable(L, $input)) {
- // It should accept a table of numbers.
- $2 = lua_rawlen(L, $input);
- $1 = ($1_ltype)malloc(($2) * sizeof($*1_type));
- int i = 0, j = 0;
- while (i++ < $2) {
- lua_rawgeti(L, $input, i);
- if (!lua_isnumber(L, -1)) {
- // if current element cannot be converted to number, raise an error
- lua_pop(L, 1);
- return luaL_error(L, "List should only contain numbers");
- }
- $1[j++] = ($*1_ltype)lua_tonumber(L, -1);
- lua_pop(L, 1);
+ if (lua_istable(L, $input)) {
+ // It should accept a table of numbers.
+ $2 = lua_rawlen(L, $input);
+ $1 = ($1_ltype)malloc(($2) * sizeof($*1_type));
+ int i = 0, j = 0;
+ while (i++ < $2) {
+ lua_rawgeti(L, $input, i);
+ if (!lua_isnumber(L, -1)) {
+ // if current element cannot be converted to number, raise an error
+ lua_pop(L, 1);
+ return luaL_error(L, "List should only contain numbers");
}
- } else if (lua_isnil(L, $input)) {
- // "nil" is also acceptable, equivalent as an empty table
- $1 = NULL;
- $2 = 0;
- } else {
- // else raise an error
- return luaL_error(L, "A list of numbers expected.");
- }
+ $1[j++] = ($*1_ltype) lua_tonumber(L, -1);
+ lua_pop(L, 1);
+ }
+ } else if (lua_isnil(L, $input)) {
+ // "nil" is also acceptable, equivalent as an empty table
+ $1 = NULL;
+ $2 = 0;
+ } else {
+ // else raise an error
+ return luaL_error(L, "A list of numbers expected.");
+ }
}
%typemap(freearg) (uint64_t* array, size_t array_len),
@@ -296,7 +296,7 @@ LLDB_NUMBER_TYPEMAP(enum SWIGTYPE);
(int64_t* array, size_t array_len),
(int32_t* array, size_t array_len),
(double* array, size_t array_len) {
- free($1);
+ free($1);
}
//===----------------------------------------------------------------------===//
@@ -304,13 +304,12 @@ LLDB_NUMBER_TYPEMAP(enum SWIGTYPE);
// Typemap for SBCommandReturnObject::PutCString
%typemap(in) (const char *string, int len) {
- if (lua_isnil(L, $input)) {
- $1 = NULL;
- $2 = 0;
- }
- else {
- $1 = (char *)luaL_checklstring(L, $input, (size_t *)&$2);
- }
+ if (lua_isnil(L, $input)) {
+ $1 = NULL;
+ $2 = 0;
+ } else {
+ $1 = (char *)luaL_checklstring(L, $input, (size_t *)&$2);
+ }
}
//===----------------------------------------------------------------------===//
diff --git a/lldb/bindings/lua/lua-wrapper.swig b/lldb/bindings/lua/lua-wrapper.swig
index c51911bb6bf7..a36e69a6fc93 100644
--- a/lldb/bindings/lua/lua-wrapper.swig
+++ b/lldb/bindings/lua/lua-wrapper.swig
@@ -1,120 +1,87 @@
%header %{
-template <typename T>
-void
-PushSBClass(lua_State* L, T* obj);
-
-%}
-
-%runtime %{
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void LLDBSwigLuaCallLuaLogOutputCallback(const char *str, void *baton);
-int LLDBSwigLuaCloseFileHandle(lua_State *L);
-
-#ifdef __cplusplus
-}
-#endif
-%}
-
-%wrapper %{
+template <typename T> void PushSBClass(lua_State * L, T * obj);
// This function is called from Lua::CallBreakpointCallback
-SWIGEXPORT llvm::Expected<bool>
-LLDBSwigLuaBreakpointCallbackFunction
-(
- lua_State *L,
- lldb::StackFrameSP stop_frame_sp,
- lldb::BreakpointLocationSP bp_loc_sp,
- StructuredDataImpl *extra_args_impl
-)
-{
- lldb::SBFrame sb_frame(stop_frame_sp);
- lldb::SBBreakpointLocation sb_bp_loc(bp_loc_sp);
- int nargs = 2;
+llvm::Expected<bool> lldb_private::LLDBSwigLuaBreakpointCallbackFunction(
+ lua_State * L, lldb::StackFrameSP stop_frame_sp,
+ lldb::BreakpointLocationSP bp_loc_sp,
+ const StructuredDataImpl &extra_args_impl) {
+ lldb::SBFrame sb_frame(stop_frame_sp);
+ lldb::SBBreakpointLocation sb_bp_loc(bp_loc_sp);
+ int nargs = 2;
- llvm::Optional<lldb::SBStructuredData> extra_args;
- if (extra_args_impl)
- extra_args = lldb::SBStructuredData(extra_args_impl);
+ lldb::SBStructuredData extra_args(extra_args_impl);
- // Push the Lua wrappers
- PushSBClass(L, &sb_frame);
- PushSBClass(L, &sb_bp_loc);
+ // Push the Lua wrappers
+ PushSBClass(L, &sb_frame);
+ PushSBClass(L, &sb_bp_loc);
- if (extra_args.hasValue()) {
- PushSBClass(L, extra_args.getPointer());
- nargs++;
- }
+ if (extra_args.IsValid()) {
+ PushSBClass(L, &extra_args);
+ nargs++;
+ }
- // Call into the Lua callback passing 'sb_frame' and 'sb_bp_loc'.
- // Expects a boolean return.
- if (lua_pcall(L, nargs, 1, 0) != LUA_OK) {
- llvm::Error E = llvm::make_error<llvm::StringError>(
- llvm::formatv("{0}\n", lua_tostring(L, -1)),
- llvm::inconvertibleErrorCode());
- // Pop error message from the stack.
- lua_pop(L, 1);
- return std::move(E);
- }
+ // Call into the Lua callback passing 'sb_frame' and 'sb_bp_loc'.
+ // Expects a boolean return.
+ if (lua_pcall(L, nargs, 1, 0) != LUA_OK) {
+ llvm::Error E = llvm::make_error<llvm::StringError>(
+ llvm::formatv("{0}\n", lua_tostring(L, -1)),
+ llvm::inconvertibleErrorCode());
+ // Pop error message from the stack.
+ lua_pop(L, 1);
+ return std::move(E);
+ }
- // Boolean return from the callback
- bool stop = lua_toboolean(L, -1);
- lua_pop(L, 1);
+ // Boolean return from the callback
+ bool stop = lua_toboolean(L, -1);
+ lua_pop(L, 1);
- return stop;
+ return stop;
}
// This function is called from Lua::CallWatchpointCallback
-SWIGEXPORT llvm::Expected<bool>
-LLDBSwigLuaWatchpointCallbackFunction
-(
- lua_State *L,
- lldb::StackFrameSP stop_frame_sp,
- lldb::WatchpointSP wp_sp
-)
-{
- lldb::SBFrame sb_frame(stop_frame_sp);
- lldb::SBWatchpoint sb_wp(wp_sp);
- int nargs = 2;
+llvm::Expected<bool> lldb_private::LLDBSwigLuaWatchpointCallbackFunction(
+ lua_State * L, lldb::StackFrameSP stop_frame_sp, lldb::WatchpointSP wp_sp) {
+ lldb::SBFrame sb_frame(stop_frame_sp);
+ lldb::SBWatchpoint sb_wp(wp_sp);
+ int nargs = 2;
- // Push the Lua wrappers
- PushSBClass(L, &sb_frame);
- PushSBClass(L, &sb_wp);
+ // Push the Lua wrappers
+ PushSBClass(L, &sb_frame);
+ PushSBClass(L, &sb_wp);
- // Call into the Lua callback passing 'sb_frame' and 'sb_wp'.
- // Expects a boolean return.
- if (lua_pcall(L, nargs, 1, 0) != LUA_OK) {
- llvm::Error E = llvm::make_error<llvm::StringError>(
- llvm::formatv("{0}\n", lua_tostring(L, -1)),
- llvm::inconvertibleErrorCode());
- // Pop error message from the stack.
- lua_pop(L, 1);
- return std::move(E);
- }
+ // Call into the Lua callback passing 'sb_frame' and 'sb_wp'.
+ // Expects a boolean return.
+ if (lua_pcall(L, nargs, 1, 0) != LUA_OK) {
+ llvm::Error E = llvm::make_error<llvm::StringError>(
+ llvm::formatv("{0}\n", lua_tostring(L, -1)),
+ llvm::inconvertibleErrorCode());
+ // Pop error message from the stack.
+ lua_pop(L, 1);
+ return std::move(E);
+ }
- // Boolean return from the callback
- bool stop = lua_toboolean(L, -1);
- lua_pop(L, 1);
+ // Boolean return from the callback
+ bool stop = lua_toboolean(L, -1);
+ lua_pop(L, 1);
- return stop;
+ return stop;
}
-SWIGEXPORT void
-LLDBSwigLuaCallLuaLogOutputCallback(const char *str, void *baton) {
- lua_State *L = (lua_State *)baton;
+static void LLDBSwigLuaCallLuaLogOutputCallback(const char *str, void *baton) {
+ lua_State *L = (lua_State *)baton;
- lua_pushlightuserdata(L, (void *)&LLDBSwigLuaCallLuaLogOutputCallback);
- lua_gettable(L, LUA_REGISTRYINDEX);
+ lua_pushlightuserdata(L, (void *)&LLDBSwigLuaCallLuaLogOutputCallback);
+ lua_gettable(L, LUA_REGISTRYINDEX);
- // FIXME: There's no way to report errors back to the user
- lua_pushstring(L, str);
- lua_pcall(L, 1, 0, 0);
+ // FIXME: There's no way to report errors back to the user
+ lua_pushstring(L, str);
+ lua_pcall(L, 1, 0, 0);
}
-int LLDBSwigLuaCloseFileHandle(lua_State *L) {
- return luaL_error(L, "You cannot close a file handle used by lldb.");
+static int LLDBSwigLuaCloseFileHandle(lua_State * L) {
+ return luaL_error(L, "You cannot close a file handle used by lldb.");
}
%}
diff --git a/lldb/bindings/lua/lua.swig b/lldb/bindings/lua/lua.swig
index 21fa44c8b4d8..92f85fee22fc 100644
--- a/lldb/bindings/lua/lua.swig
+++ b/lldb/bindings/lua/lua.swig
@@ -17,6 +17,7 @@
#include "llvm/Support/Error.h"
#include "llvm/Support/FormatVariadic.h"
#include "../bindings/lua/lua-swigsafecast.swig"
+#include "../source/Plugins/ScriptInterpreter/Lua/SWIGLuaBridge.h"
// required headers for typemaps
#include "lldb/Host/File.h"
diff --git a/lldb/bindings/python/python-swigsafecast.swig b/lldb/bindings/python/python-swigsafecast.swig
index fdd3b4e62c10..7d639e664f53 100644
--- a/lldb/bindings/python/python-swigsafecast.swig
+++ b/lldb/bindings/python/python-swigsafecast.swig
@@ -5,55 +5,11 @@ PyObject *SBTypeToSWIGWrapper(lldb::SBEvent &event_sb) {
return SWIG_NewPointerObj(&event_sb, SWIGTYPE_p_lldb__SBEvent, 0);
}
-PyObject *SBTypeToSWIGWrapper(lldb::SBThread &thread_sb) {
- return SWIG_NewPointerObj(&thread_sb, SWIGTYPE_p_lldb__SBThread, 0);
-}
-
-PyObject *SBTypeToSWIGWrapper(lldb::SBFrame &frame_sb) {
- return SWIG_NewPointerObj(&frame_sb, SWIGTYPE_p_lldb__SBFrame, 0);
-}
-
-PyObject *SBTypeToSWIGWrapper(lldb::SBDebugger &debugger_sb) {
- return SWIG_NewPointerObj(&debugger_sb, SWIGTYPE_p_lldb__SBDebugger, 0);
-}
-
-PyObject *SBTypeToSWIGWrapper(lldb::SBWatchpoint &watchpoint_sb) {
- return SWIG_NewPointerObj(&watchpoint_sb, SWIGTYPE_p_lldb__SBWatchpoint, 0);
-}
-
-PyObject *
-SBTypeToSWIGWrapper(lldb::SBBreakpointLocation &breakpoint_location_sb) {
- return SWIG_NewPointerObj(&breakpoint_location_sb,
- SWIGTYPE_p_lldb__SBBreakpointLocation, 0);
-}
-
PyObject *SBTypeToSWIGWrapper(lldb::SBCommandReturnObject &cmd_ret_obj_sb) {
return SWIG_NewPointerObj(&cmd_ret_obj_sb,
SWIGTYPE_p_lldb__SBCommandReturnObject, 0);
}
-PyObject *SBTypeToSWIGWrapper(lldb::SBExecutionContext &ctx_sb) {
- return SWIG_NewPointerObj(&ctx_sb, SWIGTYPE_p_lldb__SBExecutionContext, 0);
-}
-
-PyObject *SBTypeToSWIGWrapper(lldb::SBTypeSummaryOptions &summary_options_sb) {
- return SWIG_NewPointerObj(&summary_options_sb,
- SWIGTYPE_p_lldb__SBTypeSummaryOptions, 0);
-}
-
-PyObject *SBTypeToSWIGWrapper(lldb::SBStructuredData &structured_data_sb) {
- return SWIG_NewPointerObj(&structured_data_sb,
- SWIGTYPE_p_lldb__SBStructuredData, 0);
-}
-
-PyObject *SBTypeToSWIGWrapper(lldb::SBSymbolContext &sym_ctx_sb) {
- return SWIG_NewPointerObj(&sym_ctx_sb, SWIGTYPE_p_lldb__SBSymbolContext, 0);
-}
-
-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)};
}
@@ -86,5 +42,57 @@ PythonObject ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp) {
SWIGTYPE_p_lldb__SBBreakpoint);
}
+PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBStream> stream_sb) {
+ return ToSWIGHelper(stream_sb.release(), SWIGTYPE_p_lldb__SBStream);
+}
+
+PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb) {
+ return ToSWIGHelper(data_sb.release(), SWIGTYPE_p_lldb__SBStructuredData);
+}
+
+PythonObject ToSWIGWrapper(const StructuredDataImpl &data_impl) {
+ return ToSWIGWrapper(std::make_unique<lldb::SBStructuredData>(data_impl));
+}
+
+PythonObject ToSWIGWrapper(lldb::ThreadSP thread_sp) {
+ return ToSWIGHelper(new lldb::SBThread(std::move(thread_sp)),
+ SWIGTYPE_p_lldb__SBThread);
+}
+
+PythonObject ToSWIGWrapper(lldb::StackFrameSP frame_sp) {
+ return ToSWIGHelper(new lldb::SBFrame(std::move(frame_sp)),
+ SWIGTYPE_p_lldb__SBFrame);
+}
+
+PythonObject ToSWIGWrapper(lldb::DebuggerSP debugger_sp) {
+ return ToSWIGHelper(new lldb::SBDebugger(std::move(debugger_sp)),
+ SWIGTYPE_p_lldb__SBDebugger);
+}
+
+PythonObject ToSWIGWrapper(lldb::WatchpointSP watchpoint_sp) {
+ return ToSWIGHelper(new lldb::SBWatchpoint(std::move(watchpoint_sp)),
+ SWIGTYPE_p_lldb__SBWatchpoint);
+}
+
+PythonObject ToSWIGWrapper(lldb::BreakpointLocationSP bp_loc_sp) {
+ return ToSWIGHelper(new lldb::SBBreakpointLocation(std::move(bp_loc_sp)),
+ SWIGTYPE_p_lldb__SBBreakpointLocation);
+}
+
+PythonObject ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp) {
+ return ToSWIGHelper(new lldb::SBExecutionContext(std::move(ctx_sp)),
+ SWIGTYPE_p_lldb__SBExecutionContext);
+}
+
+PythonObject ToSWIGWrapper(const TypeSummaryOptions &summary_options) {
+ return ToSWIGHelper(new lldb::SBTypeSummaryOptions(summary_options),
+ SWIGTYPE_p_lldb__SBTypeSummaryOptions);
+}
+
+PythonObject ToSWIGWrapper(const SymbolContext &sym_ctx) {
+ return ToSWIGHelper(new lldb::SBSymbolContext(sym_ctx),
+ SWIGTYPE_p_lldb__SBSymbolContext);
+}
+
} // namespace python
} // namespace lldb_private
diff --git a/lldb/bindings/python/python-typemaps.swig b/lldb/bindings/python/python-typemaps.swig
index b1ace4ff3b1e..bf3de66b91bf 100644
--- a/lldb/bindings/python/python-typemaps.swig
+++ b/lldb/bindings/python/python-typemaps.swig
@@ -12,22 +12,22 @@
PythonList list(PyRefType::Borrowed, $input);
int size = list.GetSize();
int i = 0;
- $1 = (char**)malloc((size+1)*sizeof(char*));
+ $1 = (char **)malloc((size + 1) * sizeof(char *));
for (i = 0; i < size; i++) {
PythonString py_str = list.GetItemAtIndex(i).AsType<PythonString>();
if (!py_str.IsAllocated()) {
- PyErr_SetString(PyExc_TypeError,"list must contain strings");
+ PyErr_SetString(PyExc_TypeError, "list must contain strings");
free($1);
return nullptr;
}
- $1[i] = const_cast<char*>(py_str.GetString().data());
+ $1[i] = const_cast<char *>(py_str.GetString().data());
}
$1[i] = 0;
} else if ($input == Py_None) {
- $1 = NULL;
+ $1 = NULL;
} else {
- PyErr_SetString(PyExc_TypeError,"not a list");
+ PyErr_SetString(PyExc_TypeError, "not a list");
return NULL;
}
}
@@ -41,12 +41,12 @@
int i = 0;
for (i = 0; i < size; i++) {
PythonString s = list.GetItemAtIndex(i).AsType<PythonString>();
- if (!s.IsAllocated()) { $1 = 0; }
+ if (!s.IsAllocated()) {
+ $1 = 0;
+ }
}
- }
- else
- {
- $1 = ( ($input == Py_None) ? 1 : 0);
+ } else {
+ $1 = (($input == Py_None) ? 1 : 0);
}
}
@@ -58,7 +58,8 @@
int len;
int i;
len = 0;
- while ($1[len]) len++;
+ while ($1[len])
+ len++;
PythonList list(len);
for (i = 0; i < len; i++)
list.SetItemAtIndex(i, PythonString($1[i]));
@@ -76,7 +77,7 @@
%typemap(in) lldb::StateType {
PythonObject obj = Retain<PythonObject>($input);
unsigned long long state_type_value =
- unwrapOrSetPythonException(As<unsigned long long>(obj));
+ unwrapOrSetPythonException(As<unsigned long long>(obj));
if (PyErr_Occurred())
return nullptr;
if (state_type_value > lldb::StateType::kLastStateType) {
@@ -90,16 +91,16 @@
// typemap for a char buffer
%typemap(in) (char *dst, size_t dst_len) {
- if (!PyInt_Check($input)) {
- PyErr_SetString(PyExc_ValueError, "Expecting an integer");
- return NULL;
- }
- $2 = PyInt_AsLong($input);
- if ($2 <= 0) {
- PyErr_SetString(PyExc_ValueError, "Positive integer expected");
- return NULL;
- }
- $1 = (char *) malloc($2);
+ if (!PyInt_Check($input)) {
+ PyErr_SetString(PyExc_ValueError, "Expecting an integer");
+ return NULL;
+ }
+ $2 = PyInt_AsLong($input);
+ if ($2 <= 0) {
+ PyErr_SetString(PyExc_ValueError, "Positive integer expected");
+ return NULL;
+ }
+ $1 = (char *)malloc($2);
}
// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated
// as char data instead of byte data.
@@ -107,17 +108,17 @@
// Return the char buffer. Discarding any previous return result
%typemap(argout) (char *dst, size_t dst_len) {
- Py_XDECREF($result); /* Blow away any previous result */
- if (result == 0) {
- PythonString string("");
- $result = string.release();
- Py_INCREF($result);
- } else {
- llvm::StringRef ref(static_cast<const char*>($1), result);
- PythonString string(ref);
- $result = string.release();
- }
- free($1);
+ Py_XDECREF($result); /* Blow away any previous result */
+ if (result == 0) {
+ PythonString string("");
+ $result = string.release();
+ Py_INCREF($result);
+ } else {
+ llvm::StringRef ref(static_cast<const char *>($1), result);
+ PythonString string(ref);
+ $result = string.release();
+ }
+ free($1);
}
// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated
// as char data instead of byte data.
@@ -126,23 +127,23 @@
// typemap for handling an snprintf-like API like SBThread::GetStopDescription.
%typemap(in) (char *dst_or_null, size_t dst_len) {
- if (!PyInt_Check($input)) {
- PyErr_SetString(PyExc_ValueError, "Expecting an integer");
- return NULL;
- }
- $2 = PyInt_AsLong($input);
- if ($2 <= 0) {
- PyErr_SetString(PyExc_ValueError, "Positive integer expected");
- return NULL;
- }
- $1 = (char *) malloc($2);
+ if (!PyInt_Check($input)) {
+ PyErr_SetString(PyExc_ValueError, "Expecting an integer");
+ return NULL;
+ }
+ $2 = PyInt_AsLong($input);
+ if ($2 <= 0) {
+ PyErr_SetString(PyExc_ValueError, "Positive integer expected");
+ return NULL;
+ }
+ $1 = (char *)malloc($2);
}
%typemap(argout) (char *dst_or_null, size_t dst_len) {
- Py_XDECREF($result); /* Blow away any previous result */
- llvm::StringRef ref($1);
- PythonString string(ref);
- $result = string.release();
- free($1);
+ Py_XDECREF($result); /* Blow away any previous result */
+ llvm::StringRef ref($1);
+ PythonString string(ref);
+ $result = string.release();
+ free($1);
}
@@ -151,80 +152,74 @@
// Ditto for SBProcess::PutSTDIN(const char *src, size_t src_len).
%typemap(in) (const char *cstr, uint32_t cstr_len),
(const char *src, size_t src_len) {
- if (PythonString::Check($input)) {
- PythonString str(PyRefType::Borrowed, $input);
- $1 = (char*)str.GetString().data();
- $2 = str.GetSize();
- }
- else if(PythonByteArray::Check($input)) {
- PythonByteArray bytearray(PyRefType::Borrowed, $input);
- $1 = (char*)bytearray.GetBytes().data();
- $2 = bytearray.GetSize();
- }
- else if (PythonBytes::Check($input)) {
- PythonBytes bytes(PyRefType::Borrowed, $input);
- $1 = (char*)bytes.GetBytes().data();
- $2 = bytes.GetSize();
- }
- else {
- PyErr_SetString(PyExc_ValueError, "Expecting a string");
- return NULL;
- }
+ if (PythonString::Check($input)) {
+ PythonString str(PyRefType::Borrowed, $input);
+ $1 = (char *)str.GetString().data();
+ $2 = str.GetSize();
+ } else if (PythonByteArray::Check($input)) {
+ PythonByteArray bytearray(PyRefType::Borrowed, $input);
+ $1 = (char *)bytearray.GetBytes().data();
+ $2 = bytearray.GetSize();
+ } else if (PythonBytes::Check($input)) {
+ PythonBytes bytes(PyRefType::Borrowed, $input);
+ $1 = (char *)bytes.GetBytes().data();
+ $2 = bytes.GetSize();
+ } else {
+ PyErr_SetString(PyExc_ValueError, "Expecting a string");
+ return NULL;
+ }
}
// For SBProcess::WriteMemory, SBTarget::GetInstructions and SBDebugger::DispatchInput.
%typemap(in) (const void *buf, size_t size),
(const void *data, size_t data_len) {
- if (PythonString::Check($input)) {
- PythonString str(PyRefType::Borrowed, $input);
- $1 = (void*)str.GetString().data();
- $2 = str.GetSize();
- }
- else if(PythonByteArray::Check($input)) {
- PythonByteArray bytearray(PyRefType::Borrowed, $input);
- $1 = (void*)bytearray.GetBytes().data();
- $2 = bytearray.GetSize();
- }
- else if (PythonBytes::Check($input)) {
- PythonBytes bytes(PyRefType::Borrowed, $input);
- $1 = (void*)bytes.GetBytes().data();
- $2 = bytes.GetSize();
- }
- else {
- PyErr_SetString(PyExc_ValueError, "Expecting a buffer");
- return NULL;
- }
+ if (PythonString::Check($input)) {
+ PythonString str(PyRefType::Borrowed, $input);
+ $1 = (void *)str.GetString().data();
+ $2 = str.GetSize();
+ } else if (PythonByteArray::Check($input)) {
+ PythonByteArray bytearray(PyRefType::Borrowed, $input);
+ $1 = (void *)bytearray.GetBytes().data();
+ $2 = bytearray.GetSize();
+ } else if (PythonBytes::Check($input)) {
+ PythonBytes bytes(PyRefType::Borrowed, $input);
+ $1 = (void *)bytes.GetBytes().data();
+ $2 = bytes.GetSize();
+ } else {
+ PyErr_SetString(PyExc_ValueError, "Expecting a buffer");
+ return NULL;
+ }
}
// typemap for an incoming buffer
// See also SBProcess::ReadMemory.
%typemap(in) (void *buf, size_t size) {
- if (PyInt_Check($input)) {
- $2 = PyInt_AsLong($input);
- } else if (PyLong_Check($input)) {
- $2 = PyLong_AsLong($input);
- } else {
- PyErr_SetString(PyExc_ValueError, "Expecting an integer or long object");
- return NULL;
- }
- if ($2 <= 0) {
- PyErr_SetString(PyExc_ValueError, "Positive integer expected");
- return NULL;
- }
- $1 = (void *) malloc($2);
+ if (PyInt_Check($input)) {
+ $2 = PyInt_AsLong($input);
+ } else if (PyLong_Check($input)) {
+ $2 = PyLong_AsLong($input);
+ } else {
+ PyErr_SetString(PyExc_ValueError, "Expecting an integer or long object");
+ return NULL;
+ }
+ if ($2 <= 0) {
+ PyErr_SetString(PyExc_ValueError, "Positive integer expected");
+ return NULL;
+ }
+ $1 = (void *)malloc($2);
}
// Return the buffer. Discarding any previous return result
// See also SBProcess::ReadMemory.
%typemap(argout) (void *buf, size_t size) {
- Py_XDECREF($result); /* Blow away any previous result */
- if (result == 0) {
- $result = Py_None;
- Py_INCREF($result);
- } else {
- PythonBytes bytes(static_cast<const uint8_t*>($1), result);
- $result = bytes.release();
- }
- free($1);
+ Py_XDECREF($result); /* Blow away any previous result */
+ if (result == 0) {
+ $result = Py_None;
+ Py_INCREF($result);
+ } else {
+ PythonBytes bytes(static_cast<const uint8_t *>($1), result);
+ $result = bytes.release();
+ }
+ free($1);
}
%{
@@ -250,19 +245,18 @@ template <> int32_t PyLongAsT<int32_t>(PyObject *obj) {
return static_cast<int32_t>(PyLong_AsLong(obj));
}
-template <class T>
-bool SetNumberFromPyObject(T &number, PyObject *obj) {
+template <class T> bool SetNumberFromPyObject(T &number, PyObject *obj) {
if (PyInt_Check(obj))
number = static_cast<T>(PyInt_AsLong(obj));
else if (PyLong_Check(obj))
number = PyLongAsT<T>(obj);
- else return false;
+ else
+ return false;
return true;
}
-template <>
-bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
+template <> bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
if (PyFloat_Check(obj)) {
number = PyFloat_AsDouble(obj);
return true;
@@ -287,11 +281,11 @@ bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
int size = PyList_Size($input);
int i = 0;
$2 = size;
- $1 = ($1_type) malloc(size * sizeof($*1_type));
+ $1 = ($1_type)malloc(size * sizeof($*1_type));
for (i = 0; i < size; i++) {
- PyObject *o = PyList_GetItem($input,i);
+ PyObject *o = PyList_GetItem($input, i);
if (!SetNumberFromPyObject($1[i], o)) {
- PyErr_SetString(PyExc_TypeError,"list must contain numbers");
+ PyErr_SetString(PyExc_TypeError, "list must contain numbers");
free($1);
return NULL;
}
@@ -302,10 +296,10 @@ bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
}
}
} else if ($input == Py_None) {
- $1 = NULL;
+ $1 = NULL;
$2 = 0;
} else {
- PyErr_SetString(PyExc_TypeError,"not a list");
+ PyErr_SetString(PyExc_TypeError, "not a list");
return NULL;
}
}
@@ -322,43 +316,42 @@ bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
// to the more Pythonic style where a list is returned and no previous allocation
// is necessary - this will break if more than 50 versions are ever returned
%typemap(typecheck) (uint32_t *versions, uint32_t num_versions) {
- $1 = ($input == Py_None ? 1 : 0);
+ $1 = ($input == Py_None ? 1 : 0);
}
%typemap(in, numinputs=0) (uint32_t *versions) {
- $1 = (uint32_t*)malloc(sizeof(uint32_t) * 50);
+ $1 = (uint32_t *)malloc(sizeof(uint32_t) * 50);
}
%typemap(in, numinputs=0) (uint32_t num_versions) {
- $1 = 50;
+ $1 = 50;
}
%typemap(argout) (uint32_t *versions, uint32_t num_versions) {
- uint32_t count = result;
- if (count >= $2)
- count = $2;
- PyObject* list = PyList_New(count);
- for (uint32_t j = 0; j < count; j++)
- {
- PyObject* item = PyInt_FromLong($1[j]);
- int ok = PyList_SetItem(list,j,item);
- if (ok != 0)
- {
- $result = Py_None;
- break;
- }
+ uint32_t count = result;
+ if (count >= $2)
+ count = $2;
+ PyObject *list = PyList_New(count);
+ for (uint32_t j = 0; j < count; j++) {
+ PyObject *item = PyInt_FromLong($1[j]);
+ int ok = PyList_SetItem(list, j, item);
+ if (ok != 0) {
+ $result = Py_None;
+ break;
}
- $result = list;
+ }
+ $result = list;
}
%typemap(freearg) (uint32_t *versions) {
- free($1);
+ free($1);
}
// For Log::LogOutputCallback
%typemap(in) (lldb::LogOutputCallback log_callback, void *baton) {
- if (!($input == Py_None || PyCallable_Check(reinterpret_cast<PyObject*>($input)))) {
+ if (!($input == Py_None ||
+ PyCallable_Check(reinterpret_cast<PyObject *>($input)))) {
PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
return NULL;
}
@@ -376,7 +369,7 @@ bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
%typemap(typecheck) (lldb::LogOutputCallback log_callback, void *baton) {
$1 = $input == Py_None;
- $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject*>($input));
+ $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input));
}
@@ -398,7 +391,8 @@ bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
PyErr_SetString(PyExc_TypeError, "not a file");
return nullptr;
}
- auto sp = unwrapOrSetPythonException(py_file.ConvertToFileForcingUseOfScriptingIOMethods());
+ auto sp = unwrapOrSetPythonException(
+ py_file.ConvertToFileForcingUseOfScriptingIOMethods());
if (!sp)
return nullptr;
$1 = sp;
@@ -410,7 +404,8 @@ bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
PyErr_SetString(PyExc_TypeError, "not a file");
return nullptr;
}
- auto sp = unwrapOrSetPythonException(py_file.ConvertToFile(/*borrowed=*/true));
+ auto sp =
+ unwrapOrSetPythonException(py_file.ConvertToFile(/*borrowed=*/true));
if (!sp)
return nullptr;
$1 = sp;
@@ -422,7 +417,8 @@ bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
PyErr_SetString(PyExc_TypeError, "not a file");
return nullptr;
}
- auto sp = unwrapOrSetPythonException(py_file.ConvertToFileForcingUseOfScriptingIOMethods(/*borrowed=*/true));
+ auto sp = unwrapOrSetPythonException(
+ py_file.ConvertToFileForcingUseOfScriptingIOMethods(/*borrowed=*/true));
if (!sp)
return nullptr;
$1 = sp;
@@ -446,40 +442,34 @@ bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
return nullptr;
$result = pyfile.release();
}
- if (!$result)
- {
- $result = Py_None;
- Py_INCREF(Py_None);
+ if (!$result) {
+ $result = Py_None;
+ Py_INCREF(Py_None);
}
}
%typemap(in) (const char* string, int len) {
- if ($input == Py_None)
- {
- $1 = NULL;
- $2 = 0;
- }
- else if (PythonString::Check($input))
- {
- PythonString py_str(PyRefType::Borrowed, $input);
- llvm::StringRef str = py_str.GetString();
- $1 = const_cast<char*>(str.data());
- $2 = str.size();
- // In Python 2, if $input is a PyUnicode object then this
- // will trigger a Unicode -> String conversion, in which
- // case the `PythonString` will now own the PyString. Thus
- // if it goes out of scope, the data will be deleted. The
- // only way to avoid this is to leak the Python object in
- // that case. Note that if there was no conversion, then
- // releasing the string will not leak anything, since we
- // created this as a borrowed reference.
- py_str.release();
- }
- else
- {
- PyErr_SetString(PyExc_TypeError,"not a string-like object");
- return NULL;
- }
+ if ($input == Py_None) {
+ $1 = NULL;
+ $2 = 0;
+ } else if (PythonString::Check($input)) {
+ PythonString py_str(PyRefType::Borrowed, $input);
+ llvm::StringRef str = py_str.GetString();
+ $1 = const_cast<char *>(str.data());
+ $2 = str.size();
+ // In Python 2, if $input is a PyUnicode object then this
+ // will trigger a Unicode -> String conversion, in which
+ // case the `PythonString` will now own the PyString. Thus
+ // if it goes out of scope, the data will be deleted. The
+ // only way to avoid this is to leak the Python object in
+ // that case. Note that if there was no conversion, then
+ // releasing the string will not leak anything, since we
+ // created this as a borrowed reference.
+ py_str.release();
+ } else {
+ PyErr_SetString(PyExc_TypeError, "not a string-like object");
+ return NULL;
+ }
}
// These two pybuffer macros are copied out of swig/Lib/python/pybuffer.i,
@@ -491,7 +481,9 @@ bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
%define %pybuffer_mutable_binary(TYPEMAP, SIZE)
%typemap(in) (TYPEMAP, SIZE) (Py_buffer_RAII view) {
- int res; Py_ssize_t size = 0; void *buf = 0;
+ int res;
+ Py_ssize_t size = 0;
+ void *buf = 0;
res = PyObject_GetBuffer($input, &view.buffer, PyBUF_WRITABLE);
if (res < 0) {
PyErr_Clear();
@@ -499,14 +491,16 @@ bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
}
size = view.buffer.len;
buf = view.buffer.buf;
- $1 = ($1_ltype) buf;
- $2 = ($2_ltype) (size/sizeof($*1_type));
+ $1 = ($1_ltype)buf;
+ $2 = ($2_ltype)(size / sizeof($*1_type));
}
%enddef
%define %pybuffer_binary(TYPEMAP, SIZE)
%typemap(in) (TYPEMAP, SIZE) (Py_buffer_RAII view) {
- int res; Py_ssize_t size = 0; const void *buf = 0;
+ int res;
+ Py_ssize_t size = 0;
+ const void *buf = 0;
res = PyObject_GetBuffer($input, &view.buffer, PyBUF_CONTIG_RO);
if (res < 0) {
PyErr_Clear();
@@ -514,8 +508,8 @@ bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
}
size = view.buffer.len;
buf = view.buffer.buf;
- $1 = ($1_ltype) buf;
- $2 = ($2_ltype) (size / sizeof($*1_type));
+ $1 = ($1_ltype)buf;
+ $2 = ($2_ltype)(size / sizeof($*1_type));
}
%enddef
diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig
index 079f8d12dafa..a2c1f756a0a2 100644
--- a/lldb/bindings/python/python-wrapper.swig
+++ b/lldb/bindings/python/python-wrapper.swig
@@ -1,72 +1,55 @@
%header %{
-class PyErr_Cleaner
-{
+class PyErr_Cleaner {
public:
- PyErr_Cleaner(bool print=false) :
- m_print(print)
- {
- }
+ PyErr_Cleaner(bool print = false) : m_print(print) {}
- ~PyErr_Cleaner()
- {
- if (PyErr_Occurred())
- {
- if(m_print && !PyErr_ExceptionMatches(PyExc_SystemExit))
- PyErr_Print();
- PyErr_Clear();
- }
+ ~PyErr_Cleaner() {
+ if (PyErr_Occurred()) {
+ if (m_print && !PyErr_ExceptionMatches(PyExc_SystemExit))
+ PyErr_Print();
+ PyErr_Clear();
}
+ }
private:
- bool m_print;
+ bool m_print;
};
-llvm::Expected<bool>
-lldb_private::LLDBSwigPythonBreakpointCallbackFunction
-(
- const char *python_function_name,
- const char *session_dictionary_name,
- const lldb::StackFrameSP& frame_sp,
- const lldb::BreakpointLocationSP& bp_loc_sp,
- lldb_private::StructuredDataImpl *args_impl
-)
-{
- using namespace llvm;
+llvm::Expected<bool> lldb_private::LLDBSwigPythonBreakpointCallbackFunction(
+ const char *python_function_name, const char *session_dictionary_name,
+ const lldb::StackFrameSP &frame_sp,
+ const lldb::BreakpointLocationSP &bp_loc_sp,
+ const lldb_private::StructuredDataImpl &args_impl) {
+ using namespace llvm;
- lldb::SBFrame sb_frame (frame_sp);
- lldb::SBBreakpointLocation sb_bp_loc(bp_loc_sp);
+ lldb::SBBreakpointLocation sb_bp_loc(bp_loc_sp);
- PyErr_Cleaner py_err_cleaner(true);
- auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
- auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
+ PyErr_Cleaner py_err_cleaner(true);
+ auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
+ session_dictionary_name);
+ auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
+ python_function_name, dict);
- unsigned max_positional_args;
- if (auto arg_info = pfunc.GetArgInfo())
- max_positional_args = arg_info.get().max_positional_args;
- else
- return arg_info.takeError();
+ unsigned max_positional_args;
+ if (auto arg_info = pfunc.GetArgInfo())
+ max_positional_args = arg_info.get().max_positional_args;
+ else
+ return arg_info.takeError();
- PythonObject frame_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_frame));
- PythonObject bp_loc_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_bp_loc));
+ PythonObject frame_arg = ToSWIGWrapper(frame_sp);
+ PythonObject bp_loc_arg = ToSWIGWrapper(bp_loc_sp);
- auto result = [&] () -> Expected<PythonObject> {
- // If the called function doesn't take extra_args, drop them here:
- if (max_positional_args < 4) {
- return pfunc.Call(frame_arg, bp_loc_arg, dict);
- } else {
- // FIXME: SBStructuredData leaked here
- lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl);
- PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*args_value));
- return pfunc.Call(frame_arg, bp_loc_arg, args_arg, dict);
- }
- } ();
+ auto result =
+ max_positional_args < 4
+ ? pfunc.Call(frame_arg, bp_loc_arg, dict)
+ : pfunc.Call(frame_arg, bp_loc_arg, ToSWIGWrapper(args_impl), dict);
- if (!result)
- return result.takeError();
+ if (!result)
+ return result.takeError();
- // Only False counts as false!
- return result.get().get() != Py_False;
+ // Only False counts as false!
+ return result.get().get() != Py_False;
}
// resolve a dotted Python name in the form
@@ -74,1192 +57,1036 @@ lldb_private::LLDBSwigPythonBreakpointCallbackFunction
// 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.
-// 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.
+// This function is called by
+// lldb_private::ScriptInterpreterPython::WatchpointCallbackFunction(...) and is
+// used when a script command is attached to a watchpoint for execution.
-bool
-lldb_private::LLDBSwigPythonWatchpointCallbackFunction
-(
- const char *python_function_name,
- const char *session_dictionary_name,
- const lldb::StackFrameSP& frame_sp,
- const lldb::WatchpointSP& wp_sp
-)
-{
- lldb::SBFrame sb_frame (frame_sp);
- lldb::SBWatchpoint sb_wp(wp_sp);
+bool lldb_private::LLDBSwigPythonWatchpointCallbackFunction(
+ const char *python_function_name, const char *session_dictionary_name,
+ const lldb::StackFrameSP &frame_sp, const lldb::WatchpointSP &wp_sp) {
- bool stop_at_watchpoint = true;
+ bool stop_at_watchpoint = true;
- PyErr_Cleaner py_err_cleaner(true);
+ PyErr_Cleaner py_err_cleaner(true);
- auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
- auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
+ auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
+ session_dictionary_name);
+ auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
+ python_function_name, dict);
- if (!pfunc.IsAllocated())
- return stop_at_watchpoint;
+ if (!pfunc.IsAllocated())
+ return stop_at_watchpoint;
- PythonObject frame_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_frame));
- PythonObject wp_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_wp));
- PythonObject result = pfunc(frame_arg, wp_arg, dict);
+ PythonObject result =
+ pfunc(ToSWIGWrapper(frame_sp), ToSWIGWrapper(wp_sp), dict);
- if (result.get() == Py_False)
- stop_at_watchpoint = false;
+ if (result.get() == Py_False)
+ stop_at_watchpoint = false;
- return stop_at_watchpoint;
+ return stop_at_watchpoint;
}
-bool
-lldb_private::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
-)
-{
- lldb::SBTypeSummaryOptions sb_options(options_sp.get());
+bool lldb_private::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) {
- retval.clear();
+ retval.clear();
- if (!python_function_name || !session_dictionary)
- return false;
+ if (!python_function_name || !session_dictionary)
+ return false;
- PyObject *pfunc_impl = nullptr;
+ PyObject *pfunc_impl = nullptr;
- if (pyfunct_wrapper && *pyfunct_wrapper && PyFunction_Check (*pyfunct_wrapper))
- {
- pfunc_impl = (PyObject*)(*pyfunct_wrapper);
- if (pfunc_impl->ob_refcnt == 1)
- {
- Py_XDECREF(pfunc_impl);
- pfunc_impl = NULL;
- }
+ if (pyfunct_wrapper && *pyfunct_wrapper &&
+ PyFunction_Check(*pyfunct_wrapper)) {
+ pfunc_impl = (PyObject *)(*pyfunct_wrapper);
+ if (pfunc_impl->ob_refcnt == 1) {
+ Py_XDECREF(pfunc_impl);
+ pfunc_impl = NULL;
}
+ }
- PyObject *py_dict = (PyObject*)session_dictionary;
- if (!PythonDictionary::Check(py_dict))
- return true;
+ PyObject *py_dict = (PyObject *)session_dictionary;
+ if (!PythonDictionary::Check(py_dict))
+ return true;
- PythonDictionary dict(PyRefType::Borrowed, py_dict);
+ PythonDictionary dict(PyRefType::Borrowed, py_dict);
- PyErr_Cleaner pyerr_cleanup(true); // show Python errors
+ PyErr_Cleaner pyerr_cleanup(true); // show Python errors
- PythonCallable pfunc(PyRefType::Borrowed, pfunc_impl);
+ PythonCallable pfunc(PyRefType::Borrowed, pfunc_impl);
+ if (!pfunc.IsAllocated()) {
+ pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
+ python_function_name, dict);
if (!pfunc.IsAllocated())
- {
- pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
- if (!pfunc.IsAllocated())
- return false;
+ return false;
- if (pyfunct_wrapper)
- {
- *pyfunct_wrapper = pfunc.get();
- Py_XINCREF(pfunc.get());
- }
+ if (pyfunct_wrapper) {
+ *pyfunct_wrapper = pfunc.get();
+ Py_XINCREF(pfunc.get());
}
+ }
- PythonObject result;
- auto argc = pfunc.GetArgInfo();
- if (!argc) {
- llvm::consumeError(argc.takeError());
- return false;
- }
+ PythonObject result;
+ auto argc = pfunc.GetArgInfo();
+ if (!argc) {
+ llvm::consumeError(argc.takeError());
+ return false;
+ }
- PythonObject value_arg = ToSWIGWrapper(valobj_sp);
- PythonObject options_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_options));
+ PythonObject value_arg = ToSWIGWrapper(valobj_sp);
- if (argc.get().max_positional_args < 3)
- result = pfunc(value_arg,dict);
- else
- result = pfunc(value_arg,dict,options_arg);
+ if (argc.get().max_positional_args < 3)
+ result = pfunc(value_arg, dict);
+ else
+ result = pfunc(value_arg, dict, ToSWIGWrapper(*options_sp));
- retval = result.Str().GetString().str();
+ retval = result.Str().GetString().str();
- return true;
+ return true;
}
-void*
-lldb_private::LLDBSwigPythonCreateSyntheticProvider
-(
- const char *python_class_name,
- const char *session_dictionary_name,
- const lldb::ValueObjectSP& valobj_sp
-)
-{
- if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
- Py_RETURN_NONE;
+void *lldb_private::LLDBSwigPythonCreateSyntheticProvider(
+ const char *python_class_name, const char *session_dictionary_name,
+ const lldb::ValueObjectSP &valobj_sp) {
+ if (python_class_name == NULL || python_class_name[0] == '\0' ||
+ !session_dictionary_name)
+ Py_RETURN_NONE;
- PyErr_Cleaner py_err_cleaner(true);
+ PyErr_Cleaner py_err_cleaner(true);
- auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
- auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name,dict);
+ auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
+ session_dictionary_name);
+ auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
+ python_class_name, dict);
- if (!pfunc.IsAllocated())
- Py_RETURN_NONE;
+ if (!pfunc.IsAllocated())
+ Py_RETURN_NONE;
- auto sb_value = std::make_unique<lldb::SBValue>(valobj_sp);
- sb_value->SetPreferSyntheticValue(false);
+ auto sb_value = std::make_unique<lldb::SBValue>(valobj_sp);
+ sb_value->SetPreferSyntheticValue(false);
- PythonObject val_arg = ToSWIGWrapper(std::move(sb_value));
- if (!val_arg.IsAllocated())
- Py_RETURN_NONE;
+ PythonObject val_arg = ToSWIGWrapper(std::move(sb_value));
+ if (!val_arg.IsAllocated())
+ Py_RETURN_NONE;
- PythonObject result = pfunc(val_arg, dict);
+ PythonObject result = pfunc(val_arg, dict);
- if (result.IsAllocated())
- return result.release();
+ if (result.IsAllocated())
+ return result.release();
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
-void*
-lldb_private::LLDBSwigPythonCreateCommandObject
-(
- const char *python_class_name,
- const char *session_dictionary_name,
- const lldb::DebuggerSP debugger_sp
-)
-{
- if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
- Py_RETURN_NONE;
+void *lldb_private::LLDBSwigPythonCreateCommandObject(
+ const char *python_class_name, const char *session_dictionary_name,
+ lldb::DebuggerSP debugger_sp) {
+ if (python_class_name == NULL || python_class_name[0] == '\0' ||
+ !session_dictionary_name)
+ Py_RETURN_NONE;
- PyErr_Cleaner py_err_cleaner(true);
- auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
- auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
+ PyErr_Cleaner py_err_cleaner(true);
+ auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
+ session_dictionary_name);
+ auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
+ python_class_name, dict);
- if (!pfunc.IsAllocated())
- return nullptr;
+ if (!pfunc.IsAllocated())
+ return nullptr;
- lldb::SBDebugger debugger_sb(debugger_sp);
- PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb));
- PythonObject result = pfunc(debugger_arg, dict);
+ PythonObject result = pfunc(ToSWIGWrapper(std::move(debugger_sp)), dict);
- if (result.IsAllocated())
- return result.release();
+ if (result.IsAllocated())
+ return result.release();
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
-void*
-lldb_private::LLDBSwigPythonCreateScriptedProcess
-(
- const char *python_class_name,
- const char *session_dictionary_name,
- const lldb::TargetSP& target_sp,
- lldb_private::StructuredDataImpl *args_impl,
- std::string &error_string
-)
-{
- if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
- Py_RETURN_NONE;
+void *lldb_private::LLDBSwigPythonCreateScriptedProcess(
+ const char *python_class_name, const char *session_dictionary_name,
+ const lldb::TargetSP &target_sp,
+ const lldb_private::StructuredDataImpl &args_impl,
+ std::string &error_string) {
+ if (python_class_name == NULL || python_class_name[0] == '\0' ||
+ !session_dictionary_name)
+ Py_RETURN_NONE;
- PyErr_Cleaner py_err_cleaner(true);
+ PyErr_Cleaner py_err_cleaner(true);
- auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
- auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
+ auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
+ session_dictionary_name);
+ auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
+ python_class_name, dict);
- if (!pfunc.IsAllocated()) {
- error_string.append("could not find script class: ");
- error_string.append(python_class_name);
- return nullptr;
- }
+ if (!pfunc.IsAllocated()) {
+ error_string.append("could not find script class: ");
+ error_string.append(python_class_name);
+ return nullptr;
+ }
- PythonObject target_arg = ToSWIGWrapper(target_sp);
+ PythonObject target_arg = ToSWIGWrapper(target_sp);
- llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
- if (!arg_info) {
- llvm::handleAllErrors(
- arg_info.takeError(),
- [&](PythonException &E) {
- error_string.append(E.ReadBacktrace());
- },
- [&](const llvm::ErrorInfoBase &E) {
- error_string.append(E.message());
- });
- Py_RETURN_NONE;
- }
-
- PythonObject result = {};
- 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(target_arg, args_arg);
- } else {
- error_string.assign("wrong number of arguments in __init__, should be 2 (not including self)");
- Py_RETURN_NONE;
- }
+ llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
+ if (!arg_info) {
+ llvm::handleAllErrors(
+ arg_info.takeError(),
+ [&](PythonException &E) { error_string.append(E.ReadBacktrace()); },
+ [&](const llvm::ErrorInfoBase &E) {
+ error_string.append(E.message());
+ });
+ Py_RETURN_NONE;
+ }
- if (result.IsAllocated())
- return result.release();
+ PythonObject result = {};
+ if (arg_info.get().max_positional_args == 2) {
+ result = pfunc(target_arg, ToSWIGWrapper(args_impl));
+ } else {
+ error_string.assign("wrong number of arguments in __init__, should be 2 "
+ "(not including self)");
Py_RETURN_NONE;
+ }
+
+ if (result.IsAllocated())
+ return result.release();
+ Py_RETURN_NONE;
}
-void*
-lldb_private::LLDBSwigPythonCreateScriptedThread
-(
- const char *python_class_name,
- const char *session_dictionary_name,
- const lldb::ProcessSP& process_sp,
- lldb_private::StructuredDataImpl *args_impl,
- std::string &error_string
-)
-{
- if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
- Py_RETURN_NONE;
+void *lldb_private::LLDBSwigPythonCreateScriptedThread(
+ const char *python_class_name, const char *session_dictionary_name,
+ const lldb::ProcessSP &process_sp, const StructuredDataImpl &args_impl,
+ std::string &error_string) {
+ if (python_class_name == NULL || python_class_name[0] == '\0' ||
+ !session_dictionary_name)
+ Py_RETURN_NONE;
- PyErr_Cleaner py_err_cleaner(true);
+ PyErr_Cleaner py_err_cleaner(true);
- auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
- auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
+ auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
+ session_dictionary_name);
+ auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
+ python_class_name, dict);
- if (!pfunc.IsAllocated()) {
- error_string.append("could not find script class: ");
- error_string.append(python_class_name);
- return nullptr;
- }
+ if (!pfunc.IsAllocated()) {
+ error_string.append("could not find script class: ");
+ error_string.append(python_class_name);
+ return nullptr;
+ }
- llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
- if (!arg_info) {
- llvm::handleAllErrors(
- arg_info.takeError(),
- [&](PythonException &E) {
- error_string.append(E.ReadBacktrace());
- },
- [&](const llvm::ErrorInfoBase &E) {
- error_string.append(E.message());
- });
- Py_RETURN_NONE;
- }
-
- PythonObject result = {};
- 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(ToSWIGWrapper(process_sp), args_arg);
- } else {
- error_string.assign("wrong number of arguments in __init__, should be 2 (not including self)");
- Py_RETURN_NONE;
- }
+ llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
+ if (!arg_info) {
+ llvm::handleAllErrors(
+ arg_info.takeError(),
+ [&](PythonException &E) { error_string.append(E.ReadBacktrace()); },
+ [&](const llvm::ErrorInfoBase &E) {
+ error_string.append(E.message());
+ });
+ Py_RETURN_NONE;
+ }
- if (result.IsAllocated())
- return result.release();
+ PythonObject result = {};
+ if (arg_info.get().max_positional_args == 2) {
+ result = pfunc(ToSWIGWrapper(process_sp), ToSWIGWrapper(args_impl));
+ } else {
+ error_string.assign("wrong number of arguments in __init__, should be 2 "
+ "(not including self)");
Py_RETURN_NONE;
+ }
+
+ if (result.IsAllocated())
+ return result.release();
+ Py_RETURN_NONE;
}
-void*
-lldb_private::LLDBSwigPythonCreateScriptedThreadPlan
-(
- const char *python_class_name,
- const char *session_dictionary_name,
- lldb_private::StructuredDataImpl *args_impl,
- std::string &error_string,
- const lldb::ThreadPlanSP& thread_plan_sp
-)
-{
- if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
- Py_RETURN_NONE;
+void *lldb_private::LLDBSwigPythonCreateScriptedThreadPlan(
+ const char *python_class_name, const char *session_dictionary_name,
+ const lldb_private::StructuredDataImpl &args_impl,
+ std::string &error_string, const lldb::ThreadPlanSP &thread_plan_sp) {
+ if (python_class_name == NULL || python_class_name[0] == '\0' ||
+ !session_dictionary_name)
+ Py_RETURN_NONE;
+ PyErr_Cleaner py_err_cleaner(true);
- PyErr_Cleaner py_err_cleaner(true);
+ auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
+ session_dictionary_name);
+ auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
+ python_class_name, dict);
- auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
- auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
+ if (!pfunc.IsAllocated()) {
+ error_string.append("could not find script class: ");
+ error_string.append(python_class_name);
+ return nullptr;
+ }
- if (!pfunc.IsAllocated()) {
- error_string.append("could not find script class: ");
- error_string.append(python_class_name);
- return nullptr;
- }
+ PythonObject tp_arg = ToSWIGWrapper(thread_plan_sp);
- PythonObject tp_arg = ToSWIGWrapper(thread_plan_sp);
-
- llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
- if (!arg_info) {
- llvm::handleAllErrors(
- arg_info.takeError(),
- [&](PythonException &E) {
- error_string.append(E.ReadBacktrace());
- },
- [&](const llvm::ErrorInfoBase &E) {
- error_string.append(E.message());
- });
- Py_RETURN_NONE;
- }
+ llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo();
+ if (!arg_info) {
+ llvm::handleAllErrors(
+ arg_info.takeError(),
+ [&](PythonException &E) { error_string.append(E.ReadBacktrace()); },
+ [&](const llvm::ErrorInfoBase &E) {
+ error_string.append(E.message());
+ });
+ Py_RETURN_NONE;
+ }
- PythonObject result = {};
- if (arg_info.get().max_positional_args == 2) {
- if (args_impl != nullptr) {
- error_string.assign("args passed, but __init__ does not take an args dictionary");
- Py_RETURN_NONE;
- }
- result = pfunc(tp_arg, dict);
- } else if (arg_info.get().max_positional_args >= 3) {
- // FIXME: SBStructuredData leaked here
- PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*new lldb::SBStructuredData(args_impl)));
- result = pfunc(tp_arg, args_arg, dict);
- } else {
- error_string.assign("wrong number of arguments in __init__, should be 2 or 3 (not including self)");
- Py_RETURN_NONE;
+ PythonObject result = {};
+ auto args_sb = std::make_unique<lldb::SBStructuredData>(args_impl);
+ if (arg_info.get().max_positional_args == 2) {
+ if (args_sb->IsValid()) {
+ error_string.assign(
+ "args passed, but __init__ does not take an args dictionary");
+ Py_RETURN_NONE;
}
-
- // FIXME: At this point we should check that the class we found supports all the methods
- // that we need.
-
- if (result.IsAllocated())
- return result.release();
+ result = pfunc(tp_arg, dict);
+ } else if (arg_info.get().max_positional_args >= 3) {
+ result = pfunc(tp_arg, ToSWIGWrapper(std::move(args_sb)), dict);
+ } else {
+ error_string.assign("wrong number of arguments in __init__, should be 2 or "
+ "3 (not including self)");
Py_RETURN_NONE;
-}
+ }
-bool
-lldb_private::LLDBSWIGPythonCallThreadPlan
-(
- void *implementor,
- const char *method_name,
- lldb_private::Event *event,
- bool &got_error
-)
-{
- got_error = false;
+ // FIXME: At this point we should check that the class we found supports all
+ // the methods that we need.
- PyErr_Cleaner py_err_cleaner(false);
- PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor));
- auto pfunc = self.ResolveName<PythonCallable>(method_name);
+ if (result.IsAllocated())
+ return result.release();
+ Py_RETURN_NONE;
+}
- if (!pfunc.IsAllocated())
- return false;
+bool lldb_private::LLDBSWIGPythonCallThreadPlan(
+ void *implementor, const char *method_name, lldb_private::Event *event,
+ bool &got_error) {
+ got_error = false;
- PythonObject result;
- if (event != nullptr)
- {
- lldb::SBEvent sb_event(event);
- PythonObject event_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_event));
- result = pfunc(event_arg);
- }
- else
- result = pfunc();
+ PyErr_Cleaner py_err_cleaner(false);
+ PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
+ auto pfunc = self.ResolveName<PythonCallable>(method_name);
- if (PyErr_Occurred())
- {
- got_error = true;
- printf ("Return value was neither false nor true for call to %s.\n", method_name);
- PyErr_Print();
- return false;
- }
+ if (!pfunc.IsAllocated())
+ return false;
- if (result.get() == Py_True)
- return true;
- else if (result.get() == Py_False)
- return false;
+ PythonObject result;
+ if (event != nullptr) {
+ lldb::SBEvent sb_event(event);
+ PythonObject event_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_event));
+ result = pfunc(event_arg);
+ } else
+ result = pfunc();
- // Somebody returned the wrong thing...
+ if (PyErr_Occurred()) {
got_error = true;
- printf ("Wrong return value type for call to %s.\n", method_name);
+ printf("Return value was neither false nor true for call to %s.\n",
+ method_name);
+ PyErr_Print();
return false;
+ }
+
+ if (result.get() == Py_True)
+ return true;
+ else if (result.get() == Py_False)
+ return false;
+
+ // Somebody returned the wrong thing...
+ got_error = true;
+ printf("Wrong return value type for call to %s.\n", method_name);
+ return false;
}
void *lldb_private::LLDBSwigPythonCreateScriptedBreakpointResolver(
const char *python_class_name, const char *session_dictionary_name,
- lldb_private::StructuredDataImpl *args_impl,
+ const StructuredDataImpl &args_impl,
const lldb::BreakpointSP &breakpoint_sp) {
- if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
- Py_RETURN_NONE;
+ if (python_class_name == NULL || python_class_name[0] == '\0' ||
+ !session_dictionary_name)
+ Py_RETURN_NONE;
- PyErr_Cleaner py_err_cleaner(true);
+ PyErr_Cleaner py_err_cleaner(true);
- auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
- auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
+ auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
+ session_dictionary_name);
+ auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
+ python_class_name, dict);
- if (!pfunc.IsAllocated())
- return nullptr;
+ if (!pfunc.IsAllocated())
+ return nullptr;
- // FIXME: SBStructuredData leaked here
- lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl);
- PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*args_value));
+ PythonObject result =
+ pfunc(ToSWIGWrapper(breakpoint_sp), ToSWIGWrapper(args_impl), dict);
+ // FIXME: At this point we should check that the class we found supports all
+ // the methods that we need.
- 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.
-
- if (result.IsAllocated())
- {
- // Check that __callback__ is defined:
- auto callback_func = result.ResolveName<PythonCallable>("__callback__");
- if (callback_func.IsAllocated())
- return result.release();
- else
- result.release();
- }
- Py_RETURN_NONE;
+ if (result.IsAllocated()) {
+ // Check that __callback__ is defined:
+ auto callback_func = result.ResolveName<PythonCallable>("__callback__");
+ if (callback_func.IsAllocated())
+ return result.release();
+ else
+ result.release();
+ }
+ Py_RETURN_NONE;
}
-unsigned int
-lldb_private::LLDBSwigPythonCallBreakpointResolver
-(
- void *implementor,
- const char *method_name,
- lldb_private::SymbolContext *sym_ctx
-)
-{
- PyErr_Cleaner py_err_cleaner(false);
- PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor));
- auto pfunc = self.ResolveName<PythonCallable>(method_name);
+unsigned int lldb_private::LLDBSwigPythonCallBreakpointResolver(
+ void *implementor, const char *method_name,
+ lldb_private::SymbolContext *sym_ctx) {
+ PyErr_Cleaner py_err_cleaner(false);
+ PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
+ auto pfunc = self.ResolveName<PythonCallable>(method_name);
- if (!pfunc.IsAllocated())
- return 0;
+ if (!pfunc.IsAllocated())
+ return 0;
- PythonObject result;
- if (sym_ctx != nullptr) {
- lldb::SBSymbolContext sb_sym_ctx(sym_ctx);
- PythonObject sym_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_sym_ctx));
- result = pfunc(sym_ctx_arg);
- } else
- result = pfunc();
+ PythonObject result = sym_ctx ? pfunc(ToSWIGWrapper(*sym_ctx)) : pfunc();
- if (PyErr_Occurred())
- {
- PyErr_Print();
- PyErr_Clear();
- return 0;
- }
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ PyErr_Clear();
+ return 0;
+ }
- // The callback will return a bool, but we're need to also return ints
- // so we're squirrelling the bool through as an int... And if you return
- // nothing, we'll continue.
- if (strcmp(method_name, "__callback__") == 0) {
- if (result.get() == Py_False)
- return 0;
- else
- return 1;
- }
+ // The callback will return a bool, but we're need to also return ints
+ // so we're squirrelling the bool through as an int... And if you return
+ // nothing, we'll continue.
+ if (strcmp(method_name, "__callback__") == 0) {
+ if (result.get() == Py_False)
+ return 0;
+ else
+ return 1;
+ }
- long long ret_val = unwrapOrSetPythonException(As<long long>(result));
+ long long ret_val = unwrapOrSetPythonException(As<long long>(result));
- if (PyErr_Occurred()) {
- PyErr_Print();
- PyErr_Clear();
- return 0;
- }
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ PyErr_Clear();
+ return 0;
+ }
- return ret_val;
+ return ret_val;
}
-void *
-lldb_private::LLDBSwigPythonCreateScriptedStopHook
-(
- lldb::TargetSP target_sp,
- const char *python_class_name,
- const char *session_dictionary_name,
- lldb_private::StructuredDataImpl *args_impl,
- Status &error
-)
-{
- if (python_class_name == NULL || python_class_name[0] == '\0') {
- error.SetErrorString("Empty class name.");
- Py_RETURN_NONE;
- }
- if (!session_dictionary_name) {
- error.SetErrorString("No session dictionary");
- Py_RETURN_NONE;
- }
-
- PyErr_Cleaner py_err_cleaner(true);
+void *lldb_private::LLDBSwigPythonCreateScriptedStopHook(
+ lldb::TargetSP target_sp, const char *python_class_name,
+ const char *session_dictionary_name, const StructuredDataImpl &args_impl,
+ Status &error) {
+ if (python_class_name == NULL || python_class_name[0] == '\0') {
+ error.SetErrorString("Empty class name.");
+ Py_RETURN_NONE;
+ }
+ if (!session_dictionary_name) {
+ error.SetErrorString("No session dictionary");
+ Py_RETURN_NONE;
+ }
- auto dict =
- PythonModule::MainModule().ResolveName<PythonDictionary>(
- session_dictionary_name);
- auto pfunc =
- PythonObject::ResolveNameWithDictionary<PythonCallable>(
- python_class_name, dict);
+ PyErr_Cleaner py_err_cleaner(true);
- if (!pfunc.IsAllocated()) {
- error.SetErrorStringWithFormat("Could not find class: %s.",
- python_class_name);
- return nullptr;
- }
+ auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
+ session_dictionary_name);
+ auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
+ python_class_name, dict);
- // FIXME: SBStructuredData leaked here
- lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl);
- PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*args_value));
+ if (!pfunc.IsAllocated()) {
+ error.SetErrorStringWithFormat("Could not find class: %s.",
+ python_class_name);
+ return nullptr;
+ }
- PythonObject result = pfunc(ToSWIGWrapper(target_sp), args_arg, dict);
+ PythonObject result =
+ pfunc(ToSWIGWrapper(target_sp), ToSWIGWrapper(args_impl), dict);
- if (result.IsAllocated())
- {
- // Check that the handle_stop callback is defined:
- auto callback_func = result.ResolveName<PythonCallable>("handle_stop");
- if (callback_func.IsAllocated()) {
- if (auto args_info = callback_func.GetArgInfo()) {
- size_t num_args = (*args_info).max_positional_args;
- if (num_args != 2) {
- error.SetErrorStringWithFormat("Wrong number of args for "
+ if (result.IsAllocated()) {
+ // Check that the handle_stop callback is defined:
+ auto callback_func = result.ResolveName<PythonCallable>("handle_stop");
+ if (callback_func.IsAllocated()) {
+ if (auto args_info = callback_func.GetArgInfo()) {
+ size_t num_args = (*args_info).max_positional_args;
+ if (num_args != 2) {
+ error.SetErrorStringWithFormat(
+ "Wrong number of args for "
"handle_stop callback, should be 2 (excluding self), got: %zu",
num_args);
- Py_RETURN_NONE;
- } else
- return result.release();
- } else {
- error.SetErrorString("Couldn't get num arguments for handle_stop "
- "callback.");
- Py_RETURN_NONE;
- }
+ Py_RETURN_NONE;
+ } else
return result.release();
- }
- else {
- error.SetErrorStringWithFormat("Class \"%s\" is missing the required "
- "handle_stop callback.",
- python_class_name);
- result.release();
- }
+ } else {
+ error.SetErrorString("Couldn't get num arguments for handle_stop "
+ "callback.");
+ Py_RETURN_NONE;
+ }
+ return result.release();
+ } else {
+ error.SetErrorStringWithFormat("Class \"%s\" is missing the required "
+ "handle_stop callback.",
+ python_class_name);
+ result.release();
}
- Py_RETURN_NONE;
+ }
+ Py_RETURN_NONE;
}
-bool
-lldb_private::LLDBSwigPythonStopHookCallHandleStop
-(
- void *implementor,
- lldb::ExecutionContextRefSP exc_ctx_sp,
- lldb::StreamSP stream
-)
-{
- // handle_stop will return a bool with the meaning "should_stop"...
- // If you return nothing we'll assume we are going to stop.
- // Also any errors should return true, since we should stop on error.
+bool lldb_private::LLDBSwigPythonStopHookCallHandleStop(
+ void *implementor, lldb::ExecutionContextRefSP exc_ctx_sp,
+ lldb::StreamSP stream) {
+ // handle_stop will return a bool with the meaning "should_stop"...
+ // If you return nothing we'll assume we are going to stop.
+ // Also any errors should return true, since we should stop on error.
- PyErr_Cleaner py_err_cleaner(false);
- PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor));
- auto pfunc = self.ResolveName<PythonCallable>("handle_stop");
+ PyErr_Cleaner py_err_cleaner(false);
+ PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
+ auto pfunc = self.ResolveName<PythonCallable>("handle_stop");
- if (!pfunc.IsAllocated())
- return true;
+ if (!pfunc.IsAllocated())
+ return true;
- PythonObject result;
- lldb::SBExecutionContext sb_exc_ctx(exc_ctx_sp);
- PythonObject exc_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_exc_ctx));
- lldb::SBStream sb_stream;
- PythonObject sb_stream_arg(PyRefType::Owned,
- SBTypeToSWIGWrapper(sb_stream));
- result = pfunc(exc_ctx_arg, sb_stream_arg);
+ auto *sb_stream = new lldb::SBStream();
+ PythonObject sb_stream_arg =
+ ToSWIGWrapper(std::unique_ptr<lldb::SBStream>(sb_stream));
+ PythonObject result =
+ pfunc(ToSWIGWrapper(std::move(exc_ctx_sp)), sb_stream_arg);
- if (PyErr_Occurred())
- {
- stream->PutCString("Python error occurred handling stop-hook.");
- PyErr_Print();
- PyErr_Clear();
- return true;
- }
-
- // Now add the result to the output stream. SBStream only
- // makes an internally help StreamString which I can't interpose, so I
- // have to copy it over here.
- stream->PutCString(sb_stream.GetData());
-
- if (result.get() == Py_False)
- return false;
- else
- return true;
-}
+ if (PyErr_Occurred()) {
+ stream->PutCString("Python error occurred handling stop-hook.");
+ PyErr_Print();
+ PyErr_Clear();
+ return true;
+ }
-// wrapper that calls an optional instance member of an object taking no arguments
-static PyObject*
-LLDBSwigPython_CallOptionalMember
-(
- PyObject* implementor,
- char* callee_name,
- PyObject* ret_if_not_found = Py_None,
- bool* was_found = NULL
-)
-{
- PyErr_Cleaner py_err_cleaner(false);
+ // Now add the result to the output stream. SBStream only
+ // makes an internally help StreamString which I can't interpose, so I
+ // have to copy it over here.
+ stream->PutCString(sb_stream->GetData());
- PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor));
- auto pfunc = self.ResolveName<PythonCallable>(callee_name);
+ if (result.get() == Py_False)
+ return false;
+ else
+ return true;
+}
- if (!pfunc.IsAllocated())
- {
- if (was_found)
- *was_found = false;
- Py_XINCREF(ret_if_not_found);
- return ret_if_not_found;
- }
+// wrapper that calls an optional instance member of an object taking no
+// arguments
+static PyObject *LLDBSwigPython_CallOptionalMember(
+ PyObject * implementor, char *callee_name,
+ PyObject *ret_if_not_found = Py_None, bool *was_found = NULL) {
+ PyErr_Cleaner py_err_cleaner(false);
+
+ PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
+ auto pfunc = self.ResolveName<PythonCallable>(callee_name);
+ if (!pfunc.IsAllocated()) {
if (was_found)
- *was_found = true;
+ *was_found = false;
+ Py_XINCREF(ret_if_not_found);
+ return ret_if_not_found;
+ }
- PythonObject result = pfunc();
- return result.release();
+ if (was_found)
+ *was_found = true;
+
+ PythonObject result = pfunc();
+ return result.release();
}
-size_t
-lldb_private::LLDBSwigPython_CalculateNumChildren
-(
- PyObject *implementor,
- uint32_t max
-)
-{
- PythonObject self(PyRefType::Borrowed, implementor);
- auto pfunc = self.ResolveName<PythonCallable>("num_children");
+size_t lldb_private::LLDBSwigPython_CalculateNumChildren(PyObject * implementor,
+ uint32_t max) {
+ PythonObject self(PyRefType::Borrowed, implementor);
+ auto pfunc = self.ResolveName<PythonCallable>("num_children");
- if (!pfunc.IsAllocated())
- return 0;
+ if (!pfunc.IsAllocated())
+ return 0;
- auto arg_info = pfunc.GetArgInfo();
- if (!arg_info) {
- llvm::consumeError(arg_info.takeError());
- return 0;
- }
+ auto arg_info = pfunc.GetArgInfo();
+ if (!arg_info) {
+ llvm::consumeError(arg_info.takeError());
+ return 0;
+ }
- size_t ret_val;
- if (arg_info.get().max_positional_args < 1)
- ret_val = unwrapOrSetPythonException(As<long long>(pfunc.Call()));
- else
- ret_val = unwrapOrSetPythonException(As<long long>(pfunc.Call(PythonInteger(max))));
+ size_t ret_val;
+ if (arg_info.get().max_positional_args < 1)
+ ret_val = unwrapOrSetPythonException(As<long long>(pfunc.Call()));
+ else
+ ret_val = unwrapOrSetPythonException(
+ As<long long>(pfunc.Call(PythonInteger(max))));
- if (PyErr_Occurred())
- {
- PyErr_Print();
- PyErr_Clear();
- return 0;
- }
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ PyErr_Clear();
+ return 0;
+ }
- if (arg_info.get().max_positional_args < 1)
- ret_val = std::min(ret_val, static_cast<size_t>(max));
+ if (arg_info.get().max_positional_args < 1)
+ ret_val = std::min(ret_val, static_cast<size_t>(max));
- return ret_val;
+ return ret_val;
}
-PyObject*
-lldb_private::LLDBSwigPython_GetChildAtIndex
-(
- PyObject *implementor,
- uint32_t idx
-)
-{
- PyErr_Cleaner py_err_cleaner(true);
+PyObject *lldb_private::LLDBSwigPython_GetChildAtIndex(PyObject * implementor,
+ uint32_t idx) {
+ PyErr_Cleaner py_err_cleaner(true);
- PythonObject self(PyRefType::Borrowed, implementor);
- auto pfunc = self.ResolveName<PythonCallable>("get_child_at_index");
+ PythonObject self(PyRefType::Borrowed, implementor);
+ auto pfunc = self.ResolveName<PythonCallable>("get_child_at_index");
- if (!pfunc.IsAllocated())
- return nullptr;
+ if (!pfunc.IsAllocated())
+ return nullptr;
- PythonObject result = pfunc(PythonInteger(idx));
+ PythonObject result = pfunc(PythonInteger(idx));
- if (!result.IsAllocated())
- return nullptr;
+ if (!result.IsAllocated())
+ return nullptr;
- lldb::SBValue* sbvalue_ptr = nullptr;
- if (SWIG_ConvertPtr(result.get(), (void**)&sbvalue_ptr, SWIGTYPE_p_lldb__SBValue, 0) == -1)
- return nullptr;
+ lldb::SBValue *sbvalue_ptr = nullptr;
+ if (SWIG_ConvertPtr(result.get(), (void **)&sbvalue_ptr,
+ SWIGTYPE_p_lldb__SBValue, 0) == -1)
+ return nullptr;
- if (sbvalue_ptr == nullptr)
- return nullptr;
+ if (sbvalue_ptr == nullptr)
+ return nullptr;
- return result.release();
+ return result.release();
}
-int
-lldb_private::LLDBSwigPython_GetIndexOfChildWithName
-(
- PyObject *implementor,
- const char* child_name
-)
-{
- PyErr_Cleaner py_err_cleaner(true);
+int lldb_private::LLDBSwigPython_GetIndexOfChildWithName(
+ PyObject * implementor, const char *child_name) {
+ PyErr_Cleaner py_err_cleaner(true);
- PythonObject self(PyRefType::Borrowed, implementor);
- auto pfunc = self.ResolveName<PythonCallable>("get_child_index");
+ PythonObject self(PyRefType::Borrowed, implementor);
+ auto pfunc = self.ResolveName<PythonCallable>("get_child_index");
- if (!pfunc.IsAllocated())
- return UINT32_MAX;
+ if (!pfunc.IsAllocated())
+ return UINT32_MAX;
- llvm::Expected<PythonObject> result = pfunc.Call(PythonString(child_name));
+ llvm::Expected<PythonObject> result = pfunc.Call(PythonString(child_name));
- long long retval = unwrapOrSetPythonException(As<long long>(std::move(result)));
+ long long retval =
+ unwrapOrSetPythonException(As<long long>(std::move(result)));
- if (PyErr_Occurred()) {
- PyErr_Clear(); // FIXME print this? do something else
- return UINT32_MAX;
- }
+ if (PyErr_Occurred()) {
+ PyErr_Clear(); // FIXME print this? do something else
+ return UINT32_MAX;
+ }
- if (retval >= 0)
- return (uint32_t)retval;
+ if (retval >= 0)
+ return (uint32_t)retval;
- return UINT32_MAX;
+ return UINT32_MAX;
}
-bool
-lldb_private::LLDBSwigPython_UpdateSynthProviderInstance
-(
- PyObject *implementor
-)
-{
- bool ret_val = false;
+bool lldb_private::LLDBSwigPython_UpdateSynthProviderInstance(PyObject *
+ implementor) {
+ bool ret_val = false;
- static char callee_name[] = "update";
+ static char callee_name[] = "update";
- PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name);
+ PyObject *py_return =
+ LLDBSwigPython_CallOptionalMember(implementor, callee_name);
- if (py_return == Py_True)
- ret_val = true;
+ if (py_return == Py_True)
+ ret_val = true;
- Py_XDECREF(py_return);
+ Py_XDECREF(py_return);
- return ret_val;
+ return ret_val;
}
-bool
-lldb_private::LLDBSwigPython_MightHaveChildrenSynthProviderInstance
-(
- PyObject *implementor
-)
-{
- bool ret_val = false;
+bool lldb_private::LLDBSwigPython_MightHaveChildrenSynthProviderInstance(
+ PyObject * implementor) {
+ bool ret_val = false;
- static char callee_name[] = "has_children";
+ static char callee_name[] = "has_children";
- PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name, Py_True);
+ PyObject *py_return =
+ LLDBSwigPython_CallOptionalMember(implementor, callee_name, Py_True);
- if (py_return == Py_True)
- ret_val = true;
+ if (py_return == Py_True)
+ ret_val = true;
- Py_XDECREF(py_return);
+ Py_XDECREF(py_return);
- return ret_val;
+ return ret_val;
}
-PyObject*
-lldb_private::LLDBSwigPython_GetValueSynthProviderInstance
-(
- PyObject *implementor
-)
-{
- PyObject* ret_val = nullptr;
+PyObject *lldb_private::LLDBSwigPython_GetValueSynthProviderInstance(
+ PyObject * implementor) {
+ PyObject *ret_val = nullptr;
- static char callee_name[] = "get_value";
+ static char callee_name[] = "get_value";
- PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name, Py_None);
+ PyObject *py_return =
+ LLDBSwigPython_CallOptionalMember(implementor, callee_name, Py_None);
- if (py_return == Py_None || py_return == nullptr)
- ret_val = nullptr;
+ if (py_return == Py_None || py_return == nullptr)
+ ret_val = nullptr;
- lldb::SBValue* sbvalue_ptr = NULL;
+ lldb::SBValue *sbvalue_ptr = NULL;
- if (SWIG_ConvertPtr(py_return, (void**)&sbvalue_ptr, SWIGTYPE_p_lldb__SBValue, 0) == -1)
- ret_val = nullptr;
- else if (sbvalue_ptr == NULL)
- ret_val = nullptr;
- else
- ret_val = py_return;
+ if (SWIG_ConvertPtr(py_return, (void **)&sbvalue_ptr,
+ SWIGTYPE_p_lldb__SBValue, 0) == -1)
+ ret_val = nullptr;
+ else if (sbvalue_ptr == NULL)
+ ret_val = nullptr;
+ else
+ ret_val = py_return;
- Py_XDECREF(py_return);
- return ret_val;
+ Py_XDECREF(py_return);
+ return ret_val;
}
-void*
-lldb_private::LLDBSWIGPython_CastPyObjectToSBData
-(
- PyObject* data
-)
-{
- lldb::SBData* sb_ptr = nullptr;
+void *lldb_private::LLDBSWIGPython_CastPyObjectToSBData(PyObject * data) {
+ lldb::SBData *sb_ptr = nullptr;
- int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBData, 0);
+ int valid_cast =
+ SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBData, 0);
- if (valid_cast == -1)
- return NULL;
+ if (valid_cast == -1)
+ return NULL;
- return sb_ptr;
+ return sb_ptr;
}
+void *lldb_private::LLDBSWIGPython_CastPyObjectToSBError(PyObject * data) {
+ lldb::SBError *sb_ptr = nullptr;
-void*
-lldb_private::LLDBSWIGPython_CastPyObjectToSBError
-(
- PyObject* data
-)
-{
- lldb::SBError* sb_ptr = nullptr;
-
- int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBError, 0);
+ int valid_cast =
+ SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBError, 0);
- if (valid_cast == -1)
- return NULL;
+ if (valid_cast == -1)
+ return NULL;
- return sb_ptr;
+ return sb_ptr;
}
+void *lldb_private::LLDBSWIGPython_CastPyObjectToSBValue(PyObject * data) {
+ lldb::SBValue *sb_ptr = NULL;
-void*
-lldb_private::LLDBSWIGPython_CastPyObjectToSBValue
-(
- PyObject* data
-)
-{
- lldb::SBValue* sb_ptr = NULL;
+ int valid_cast =
+ SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBValue, 0);
- int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBValue, 0);
+ if (valid_cast == -1)
+ return NULL;
- if (valid_cast == -1)
- return NULL;
-
- return sb_ptr;
+ return sb_ptr;
}
-void*
-lldb_private::LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo
-(
- PyObject* data
-)
-{
- lldb::SBMemoryRegionInfo* sb_ptr = NULL;
+void *lldb_private::LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *
+ data) {
+ lldb::SBMemoryRegionInfo *sb_ptr = NULL;
- int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBMemoryRegionInfo, 0);
+ int valid_cast = SWIG_ConvertPtr(data, (void **)&sb_ptr,
+ SWIGTYPE_p_lldb__SBMemoryRegionInfo, 0);
- if (valid_cast == -1)
- return NULL;
+ if (valid_cast == -1)
+ return NULL;
- return sb_ptr;
+ return sb_ptr;
}
-bool
-lldb_private::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
-)
-{
- lldb::SBCommandReturnObject cmd_retobj_sb(cmd_retobj);
- lldb::SBDebugger debugger_sb(debugger);
- lldb::SBExecutionContext exe_ctx_sb(exe_ctx_ref_sp);
+bool lldb_private::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) {
+ lldb::SBCommandReturnObject cmd_retobj_sb(cmd_retobj);
- PyErr_Cleaner py_err_cleaner(true);
- auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
- auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
+ PyErr_Cleaner py_err_cleaner(true);
+ auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
+ session_dictionary_name);
+ auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
+ python_function_name, dict);
- if (!pfunc.IsAllocated())
- return false;
+ if (!pfunc.IsAllocated())
+ return false;
- auto argc = pfunc.GetArgInfo();
- if (!argc) {
- llvm::consumeError(argc.takeError());
- return false;
- }
- PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb));
- PythonObject exe_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(exe_ctx_sb));
- PythonObject cmd_retobj_arg(PyRefType::Owned, SBTypeToSWIGWrapper(cmd_retobj_sb));
+ auto argc = pfunc.GetArgInfo();
+ if (!argc) {
+ llvm::consumeError(argc.takeError());
+ return false;
+ }
+ PythonObject debugger_arg = ToSWIGWrapper(std::move(debugger));
+ PythonObject cmd_retobj_arg(PyRefType::Owned,
+ SBTypeToSWIGWrapper(cmd_retobj_sb));
- if (argc.get().max_positional_args < 5u)
- pfunc(debugger_arg, PythonString(args), cmd_retobj_arg, dict);
- else
- pfunc(debugger_arg, PythonString(args), exe_ctx_arg, cmd_retobj_arg, dict);
+ if (argc.get().max_positional_args < 5u)
+ pfunc(debugger_arg, PythonString(args), cmd_retobj_arg, dict);
+ else
+ pfunc(debugger_arg, PythonString(args),
+ ToSWIGWrapper(std::move(exe_ctx_ref_sp)), cmd_retobj_arg, dict);
- return true;
+ return true;
}
-bool
-lldb_private::LLDBSwigPythonCallCommandObject
-(
- PyObject *implementor,
- lldb::DebuggerSP& debugger,
- const char* args,
- lldb_private::CommandReturnObject& cmd_retobj,
- lldb::ExecutionContextRefSP exe_ctx_ref_sp
-)
-{
- lldb::SBCommandReturnObject cmd_retobj_sb(cmd_retobj);
- lldb::SBDebugger debugger_sb(debugger);
- lldb::SBExecutionContext exe_ctx_sb(exe_ctx_ref_sp);
+bool lldb_private::LLDBSwigPythonCallCommandObject(
+ PyObject *implementor, lldb::DebuggerSP debugger, const char *args,
+ lldb_private::CommandReturnObject &cmd_retobj,
+ lldb::ExecutionContextRefSP exe_ctx_ref_sp) {
+ lldb::SBCommandReturnObject cmd_retobj_sb(cmd_retobj);
- PyErr_Cleaner py_err_cleaner(true);
+ PyErr_Cleaner py_err_cleaner(true);
- PythonObject self(PyRefType::Borrowed, implementor);
- auto pfunc = self.ResolveName<PythonCallable>("__call__");
+ PythonObject self(PyRefType::Borrowed, implementor);
+ auto pfunc = self.ResolveName<PythonCallable>("__call__");
- if (!pfunc.IsAllocated())
- return false;
+ if (!pfunc.IsAllocated())
+ return false;
- PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb));
- PythonObject exe_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(exe_ctx_sb));
- PythonObject cmd_retobj_arg(PyRefType::Owned, SBTypeToSWIGWrapper(cmd_retobj_sb));
+ PythonObject cmd_retobj_arg(PyRefType::Owned,
+ SBTypeToSWIGWrapper(cmd_retobj_sb));
- pfunc(debugger_arg, PythonString(args), exe_ctx_arg, cmd_retobj_arg);
+ pfunc(ToSWIGWrapper(std::move(debugger)), PythonString(args),
+ ToSWIGWrapper(exe_ctx_ref_sp), cmd_retobj_arg);
- return true;
+ return true;
}
-void*
-lldb_private::LLDBSWIGPythonCreateOSPlugin
-(
- const char *python_class_name,
- const char *session_dictionary_name,
- const lldb::ProcessSP& process_sp
-)
-{
- if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
- Py_RETURN_NONE;
+void *lldb_private::LLDBSWIGPythonCreateOSPlugin(
+ const char *python_class_name, const char *session_dictionary_name,
+ const lldb::ProcessSP &process_sp) {
+ if (python_class_name == NULL || python_class_name[0] == '\0' ||
+ !session_dictionary_name)
+ Py_RETURN_NONE;
- PyErr_Cleaner py_err_cleaner(true);
+ PyErr_Cleaner py_err_cleaner(true);
- auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
- auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
+ auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
+ session_dictionary_name);
+ auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
+ python_class_name, dict);
- if (!pfunc.IsAllocated())
- Py_RETURN_NONE;
+ if (!pfunc.IsAllocated())
+ Py_RETURN_NONE;
- auto result = pfunc(ToSWIGWrapper(process_sp));
+ auto result = pfunc(ToSWIGWrapper(process_sp));
- if (result.IsAllocated())
- return result.release();
+ if (result.IsAllocated())
+ return result.release();
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
-void*
-lldb_private::LLDBSWIGPython_CreateFrameRecognizer
-(
- const char *python_class_name,
- const char *session_dictionary_name
-)
-{
- if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
- Py_RETURN_NONE;
+void *lldb_private::LLDBSWIGPython_CreateFrameRecognizer(
+ const char *python_class_name, const char *session_dictionary_name) {
+ if (python_class_name == NULL || python_class_name[0] == '\0' ||
+ !session_dictionary_name)
+ Py_RETURN_NONE;
- PyErr_Cleaner py_err_cleaner(true);
+ PyErr_Cleaner py_err_cleaner(true);
- auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
- auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
+ auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
+ session_dictionary_name);
+ auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
+ python_class_name, dict);
- if (!pfunc.IsAllocated())
- Py_RETURN_NONE;
+ if (!pfunc.IsAllocated())
+ Py_RETURN_NONE;
- auto result = pfunc();
+ auto result = pfunc();
- if (result.IsAllocated())
- return result.release();
+ if (result.IsAllocated())
+ return result.release();
- Py_RETURN_NONE;
+ Py_RETURN_NONE;
}
-PyObject*
-lldb_private::LLDBSwigPython_GetRecognizedArguments
-(
- PyObject *implementor,
- const lldb::StackFrameSP& frame_sp
-)
-{
- static char callee_name[] = "get_recognized_arguments";
+PyObject *lldb_private::LLDBSwigPython_GetRecognizedArguments(
+ PyObject * implementor, const lldb::StackFrameSP &frame_sp) {
+ static char callee_name[] = "get_recognized_arguments";
- lldb::SBFrame frame_sb(frame_sp);
- PyObject *arg = SBTypeToSWIGWrapper(frame_sb);
+ PythonObject arg = ToSWIGWrapper(frame_sp);
- PythonString str(callee_name);
- PyObject* result = PyObject_CallMethodObjArgs(implementor, str.get(), arg,
- NULL);
- return result;
+ PythonString str(callee_name);
+ PyObject *result =
+ PyObject_CallMethodObjArgs(implementor, str.get(), arg.get(), NULL);
+ return result;
}
-void*
-lldb_private::LLDBSWIGPython_GetDynamicSetting (void* module, const char* setting, const lldb::TargetSP& target_sp)
-{
- if (!module || !setting)
- Py_RETURN_NONE;
+void *lldb_private::LLDBSWIGPython_GetDynamicSetting(
+ void *module, const char *setting, const lldb::TargetSP &target_sp) {
+ if (!module || !setting)
+ Py_RETURN_NONE;
- PyErr_Cleaner py_err_cleaner(true);
- PythonObject py_module(PyRefType::Borrowed, (PyObject *)module);
- auto pfunc = py_module.ResolveName<PythonCallable>("get_dynamic_setting");
+ PyErr_Cleaner py_err_cleaner(true);
+ PythonObject py_module(PyRefType::Borrowed, (PyObject *)module);
+ auto pfunc = py_module.ResolveName<PythonCallable>("get_dynamic_setting");
- if (!pfunc.IsAllocated())
- Py_RETURN_NONE;
+ if (!pfunc.IsAllocated())
+ Py_RETURN_NONE;
- auto result = pfunc(ToSWIGWrapper(target_sp), PythonString(setting));
+ auto result = pfunc(ToSWIGWrapper(target_sp), PythonString(setting));
- return result.release();
+ return result.release();
}
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;
+ if (python_function_name == NULL || python_function_name[0] == '\0' ||
+ !session_dictionary_name)
+ return false;
- PyErr_Cleaner py_err_cleaner(true);
+ PyErr_Cleaner py_err_cleaner(true);
- auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
- auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
+ auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
+ session_dictionary_name);
+ auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
+ python_function_name, dict);
- if (!pfunc.IsAllocated())
- return false;
+ if (!pfunc.IsAllocated())
+ return false;
- auto result = pfunc(ToSWIGWrapper(process), dict);
+ auto result = pfunc(ToSWIGWrapper(process), dict);
- output = result.Str().GetString().str();
+ output = result.Str().GetString().str();
- return true;
+ return true;
}
-bool
-lldb_private::LLDBSWIGPythonRunScriptKeywordThread
-(const char* python_function_name,
-const char* session_dictionary_name,
-lldb::ThreadSP& thread,
-std::string& output)
-
-{
- if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
- return false;
-
- PyErr_Cleaner py_err_cleaner(true);
+llvm::Optional<std::string> lldb_private::LLDBSWIGPythonRunScriptKeywordThread(
+ const char *python_function_name, const char *session_dictionary_name,
+ lldb::ThreadSP thread) {
+ if (python_function_name == NULL || python_function_name[0] == '\0' ||
+ !session_dictionary_name)
+ return llvm::None;
- auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
- auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
+ PyErr_Cleaner py_err_cleaner(true);
- if (!pfunc.IsAllocated())
- return false;
+ auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
+ session_dictionary_name);
+ auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
+ python_function_name, dict);
- lldb::SBThread thread_sb(thread);
- PythonObject thread_arg(PyRefType::Owned, SBTypeToSWIGWrapper(thread_sb));
- auto result = pfunc(thread_arg, dict);
+ if (!pfunc.IsAllocated())
+ return llvm::None;
- output = result.Str().GetString().str();
+ auto result = pfunc(ToSWIGWrapper(std::move(thread)), dict);
- return true;
+ return result.Str().GetString().str();
}
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;
+ if (python_function_name == NULL || python_function_name[0] == '\0' ||
+ !session_dictionary_name)
+ return false;
- PyErr_Cleaner py_err_cleaner(true);
+ PyErr_Cleaner py_err_cleaner(true);
- auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
- auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name,dict);
+ auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
+ session_dictionary_name);
+ auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
+ python_function_name, dict);
- if (!pfunc.IsAllocated())
- return false;
+ if (!pfunc.IsAllocated())
+ return false;
- auto result = pfunc(ToSWIGWrapper(target), dict);
+ auto result = pfunc(ToSWIGWrapper(target), dict);
- output = result.Str().GetString().str();
+ output = result.Str().GetString().str();
- return true;
+ return true;
}
-bool
-lldb_private::LLDBSWIGPythonRunScriptKeywordFrame
-(const char* python_function_name,
-const char* session_dictionary_name,
-lldb::StackFrameSP& frame,
-std::string& output)
-
-{
- if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
- return false;
-
- PyErr_Cleaner py_err_cleaner(true);
+llvm::Optional<std::string> lldb_private::LLDBSWIGPythonRunScriptKeywordFrame(
+ const char *python_function_name, const char *session_dictionary_name,
+ lldb::StackFrameSP frame) {
+ if (python_function_name == NULL || python_function_name[0] == '\0' ||
+ !session_dictionary_name)
+ return llvm::None;
- auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
- auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name,dict);
+ PyErr_Cleaner py_err_cleaner(true);
- if (!pfunc.IsAllocated())
- return false;
+ auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
+ session_dictionary_name);
+ auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
+ python_function_name, dict);
- lldb::SBFrame frame_sb(frame);
- PythonObject frame_arg(PyRefType::Owned, SBTypeToSWIGWrapper(frame_sb));
- auto result = pfunc(frame_arg, dict);
+ if (!pfunc.IsAllocated())
+ return llvm::None;
- output = result.Str().GetString().str();
+ auto result = pfunc(ToSWIGWrapper(std::move(frame)), dict);
- return true;
+ return result.Str().GetString().str();
}
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;
+ if (python_function_name == NULL || python_function_name[0] == '\0' ||
+ !session_dictionary_name)
+ return false;
- PyErr_Cleaner py_err_cleaner(true);
+ PyErr_Cleaner py_err_cleaner(true);
- auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
- auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
+ auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
+ session_dictionary_name);
+ auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
+ python_function_name, dict);
- if (!pfunc.IsAllocated())
- return false;
+ if (!pfunc.IsAllocated())
+ return false;
- auto result = pfunc(ToSWIGWrapper(value), dict);
+ auto result = pfunc(ToSWIGWrapper(value), dict);
- output = result.Str().GetString().str();
+ output = result.Str().GetString().str();
- return true;
+ return true;
}
-bool
-lldb_private::LLDBSwigPythonCallModuleInit
-(
- const char *python_module_name,
- const char *session_dictionary_name,
- lldb::DebuggerSP& debugger
-)
-{
- std::string python_function_name_string = python_module_name;
- python_function_name_string += ".__lldb_init_module";
- const char* python_function_name = python_function_name_string.c_str();
+bool lldb_private::LLDBSwigPythonCallModuleInit(
+ const char *python_module_name, const char *session_dictionary_name,
+ lldb::DebuggerSP debugger) {
+ std::string python_function_name_string = python_module_name;
+ python_function_name_string += ".__lldb_init_module";
+ const char *python_function_name = python_function_name_string.c_str();
- PyErr_Cleaner py_err_cleaner(true);
+ PyErr_Cleaner py_err_cleaner(true);
- auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
- auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict);
+ auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
+ session_dictionary_name);
+ auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
+ python_function_name, dict);
- // This method is optional and need not exist. So if we don't find it,
- // it's actually a success, not a failure.
- if (!pfunc.IsAllocated())
- return true;
+ // This method is optional and need not exist. So if we don't find it,
+ // it's actually a success, not a failure.
+ if (!pfunc.IsAllocated())
+ return true;
- lldb::SBDebugger debugger_sb(debugger);
- PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb));
- pfunc(debugger_arg, dict);
+ pfunc(ToSWIGWrapper(std::move(debugger)), dict);
- return true;
+ return true;
}
-lldb::ValueObjectSP
-lldb_private::LLDBSWIGPython_GetValueObjectSPFromSBValue (void* data)
-{
- lldb::ValueObjectSP valobj_sp;
- if (data)
- {
- lldb::SBValue* sb_ptr = (lldb::SBValue *)data;
- valobj_sp = sb_ptr->GetSP();
- }
- return valobj_sp;
+lldb::ValueObjectSP lldb_private::LLDBSWIGPython_GetValueObjectSPFromSBValue(
+ void *data) {
+ lldb::ValueObjectSP valobj_sp;
+ if (data) {
+ lldb::SBValue *sb_ptr = (lldb::SBValue *)data;
+ valobj_sp = sb_ptr->GetSP();
+ }
+ return valobj_sp;
}
// For the LogOutputCallback functions
-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);
- Py_XDECREF(result);
- SWIG_PYTHON_THREAD_END_BLOCK;
- }
+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);
+ Py_XDECREF(result);
+ SWIG_PYTHON_THREAD_END_BLOCK;
+ }
}
%}
diff --git a/lldb/include/lldb/API/SBData.h b/lldb/include/lldb/API/SBData.h
index 85c8110e181c..89a699f2f713 100644
--- a/lldb/include/lldb/API/SBData.h
+++ b/lldb/include/lldb/API/SBData.h
@@ -83,6 +83,9 @@ public:
void SetData(lldb::SBError &error, const void *buf, size_t size,
lldb::ByteOrder endian, uint8_t addr_size);
+ void SetDataWithOwnership(lldb::SBError &error, const void *buf, size_t size,
+ lldb::ByteOrder endian, uint8_t addr_size);
+
// see SetData() for why we don't have Append(const void* buf, size_t size)
bool Append(const SBData &rhs);
diff --git a/lldb/include/lldb/API/SBStructuredData.h b/lldb/include/lldb/API/SBStructuredData.h
index 07075abbf1d0..533dcc8fc07c 100644
--- a/lldb/include/lldb/API/SBStructuredData.h
+++ b/lldb/include/lldb/API/SBStructuredData.h
@@ -22,7 +22,7 @@ public:
SBStructuredData(const lldb::EventSP &event_sp);
- SBStructuredData(lldb_private::StructuredDataImpl *impl);
+ SBStructuredData(const lldb_private::StructuredDataImpl &impl);
~SBStructuredData();
diff --git a/lldb/include/lldb/API/SBSymbolContext.h b/lldb/include/lldb/API/SBSymbolContext.h
index 16ad29ea8730..b4c5921d81a9 100644
--- a/lldb/include/lldb/API/SBSymbolContext.h
+++ b/lldb/include/lldb/API/SBSymbolContext.h
@@ -25,7 +25,7 @@ public:
SBSymbolContext(const lldb::SBSymbolContext &rhs);
- SBSymbolContext(const lldb_private::SymbolContext *sc_ptr);
+ SBSymbolContext(const lldb_private::SymbolContext &sc_ptr);
~SBSymbolContext();
@@ -72,8 +72,6 @@ protected:
lldb_private::SymbolContext *get() const;
- void SetSymbolContext(const lldb_private::SymbolContext *sc_ptr);
-
private:
std::unique_ptr<lldb_private::SymbolContext> m_opaque_up;
};
diff --git a/lldb/include/lldb/API/SBTypeSummary.h b/lldb/include/lldb/API/SBTypeSummary.h
index 929bfb6124b2..e9963682f7ab 100644
--- a/lldb/include/lldb/API/SBTypeSummary.h
+++ b/lldb/include/lldb/API/SBTypeSummary.h
@@ -19,7 +19,7 @@ public:
SBTypeSummaryOptions(const lldb::SBTypeSummaryOptions &rhs);
- SBTypeSummaryOptions(const lldb_private::TypeSummaryOptions *lldb_object_ptr);
+ SBTypeSummaryOptions(const lldb_private::TypeSummaryOptions &lldb_object);
~SBTypeSummaryOptions();
@@ -48,8 +48,6 @@ protected:
const lldb_private::TypeSummaryOptions &ref() const;
- void SetOptions(const lldb_private::TypeSummaryOptions *lldb_object_ptr);
-
private:
std::unique_ptr<lldb_private::TypeSummaryOptions> m_opaque_up;
};
diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h b/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h
index 26fd6f2f04d7..cecd0f92a21a 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h
@@ -9,10 +9,10 @@
#ifndef LLDB_BREAKPOINT_BREAKPOINTRESOLVERSCRIPTED_H
#define LLDB_BREAKPOINT_BREAKPOINTRESOLVERSCRIPTED_H
-#include "lldb/lldb-forward.h"
#include "lldb/Breakpoint/BreakpointResolver.h"
#include "lldb/Core/ModuleSpec.h"
-
+#include "lldb/Core/StructuredDataImpl.h"
+#include "lldb/lldb-forward.h"
namespace lldb_private {
@@ -26,7 +26,7 @@ public:
BreakpointResolverScripted(const lldb::BreakpointSP &bkpt,
const llvm::StringRef class_name,
lldb::SearchDepth depth,
- StructuredDataImpl *args_data);
+ const StructuredDataImpl &args_data);
~BreakpointResolverScripted() override = default;
@@ -64,10 +64,7 @@ private:
std::string m_class_name;
lldb::SearchDepth m_depth;
- StructuredDataImpl *m_args_ptr; // We own this, but the implementation
- // has to manage the UP (since that is
- // how it gets stored in the
- // SBStructuredData).
+ StructuredDataImpl m_args;
StructuredData::GenericSP m_implementation_sp;
BreakpointResolverScripted(const BreakpointResolverScripted &) = delete;
diff --git a/lldb/include/lldb/Core/DataFileCache.h b/lldb/include/lldb/Core/DataFileCache.h
new file mode 100644
index 000000000000..3016c531f674
--- /dev/null
+++ b/lldb/include/lldb/Core/DataFileCache.h
@@ -0,0 +1,216 @@
+//===-- DataFileCache.h -----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_CORE_DATAFILECACHE_H
+#define LLDB_CORE_DATAFILECACHE_H
+
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/Utility/UUID.h"
+#include "lldb/lldb-forward.h"
+#include "llvm/Support/Caching.h"
+#include <mutex>
+
+namespace lldb_private {
+
+/// This class enables data to be cached into a directory using the llvm
+/// caching code. Data can be stored and accessed using a unique string key.
+/// The data will be stored in the directory that is specified in the
+/// DataFileCache constructor. The data will be stored in files that start with
+/// "llvmcache-<key>" where <key> is the key name specified when getting to
+/// setting cached data.
+///
+/// Sample code for how to use the cache:
+///
+/// DataFileCache cache("/tmp/lldb-test-cache");
+/// StringRef key("Key1");
+/// auto mem_buffer_up = cache.GetCachedData(key);
+/// if (mem_buffer_up) {
+/// printf("cached data:\n%s", mem_buffer_up->getBufferStart());
+/// } else {
+/// std::vector<uint8_t> data = { 'h', 'e', 'l', 'l', 'o', '\n' };
+/// cache.SetCachedData(key, data);
+/// }
+
+class DataFileCache {
+public:
+ /// Create a data file cache in the directory path that is specified.
+ ///
+ /// Data will be cached in files created in this directory when clients call
+ /// DataFileCache::SetCacheData.
+ DataFileCache(llvm::StringRef path);
+
+ /// Get cached data from the cache directory for the specified key.
+ ///
+ /// Keys must be unique for any given data. This function attempts to see if
+ /// the data is available for the specified key and will return a valid memory
+ /// buffer is data is available.
+ ///
+ /// \param key
+ /// The unique string key that identifies data being cached.
+ ///
+ /// \return
+ /// A valid unique pointer to a memory buffer if the data is available, or
+ /// a unique pointer that contains NULL if the data is not available.
+ std::unique_ptr<llvm::MemoryBuffer> GetCachedData(llvm::StringRef key);
+
+ /// Set cached data for the specified key.
+ ///
+ /// Setting the cached data will save a file in the cache directory to contain
+ /// the specified data.
+ ///
+ /// \param key
+ /// The unique string key that identifies data being cached.
+ ///
+ /// \return
+ /// True if the data was successfully cached, false otherwise.
+ bool SetCachedData(llvm::StringRef key, llvm::ArrayRef<uint8_t> data);
+
+ /// Remove the cache file associated with the key.
+ Status RemoveCacheFile(llvm::StringRef key);
+
+private:
+ /// Return the cache file that is associated with the key.
+ FileSpec GetCacheFilePath(llvm::StringRef key);
+
+ llvm::FileCache m_cache_callback;
+ FileSpec m_cache_dir;
+ std::mutex m_mutex;
+ std::unique_ptr<llvm::MemoryBuffer> m_mem_buff_up;
+ bool m_take_ownership = false;
+};
+
+/// A signature for a given file on disk.
+///
+/// Any files that are cached in the LLDB index cached need some data that
+/// uniquely identifies a file on disk and this information should be written
+/// into each cache file so we can validate if the cache file still matches
+/// the file we are trying to load cached data for. Objects can fill out this
+/// signature and then encode and decode them to validate the signatures
+/// match. If they do not match, the cache file on disk should be removed as
+/// it is out of date.
+struct CacheSignature {
+ /// UUID of object file or module.
+ llvm::Optional<UUID> m_uuid = llvm::None;
+ /// Modification time of file on disk.
+ llvm::Optional<std::time_t> m_mod_time = llvm::None;
+ /// If this describes a .o file with a BSD archive, the BSD archive's
+ /// modification time will be in m_mod_time, and the .o file's modification
+ /// time will be in this m_obj_mod_time.
+ llvm::Optional<std::time_t> m_obj_mod_time = llvm::None;
+
+ CacheSignature() = default;
+
+ /// Create a signature from a module.
+ CacheSignature(lldb_private::Module *module);
+
+ /// Create a signature from an object file.
+ CacheSignature(lldb_private::ObjectFile *objfile);
+
+ void Clear() {
+ m_uuid = llvm::None;
+ m_mod_time = llvm::None;
+ m_obj_mod_time = llvm::None;
+ }
+
+ /// Return true if any of the signature member variables have valid values.
+ bool IsValid() const {
+ return m_uuid.hasValue() || m_mod_time.hasValue() ||
+ m_obj_mod_time.hasValue();
+ }
+
+ /// Check if two signatures are the same.
+ bool operator!=(const CacheSignature &rhs) {
+ if (m_uuid != rhs.m_uuid)
+ return true;
+ if (m_mod_time != rhs.m_mod_time)
+ return true;
+ if (m_obj_mod_time != rhs.m_obj_mod_time)
+ return true;
+ return false;
+ }
+ /// Encode this object into a data encoder object.
+ ///
+ /// This allows this object to be serialized to disk. The CacheSignature
+ /// object must have at least one member variable that has a value in order to
+ /// be serialized so that we can match this data to when the cached file is
+ /// loaded at a later time.
+ ///
+ /// \param encoder
+ /// A data encoder object that serialized bytes will be encoded into.
+ ///
+ /// \return
+ /// True if a signature was encoded, and false if there were no member
+ /// variables that had value. False indicates this data should not be
+ /// cached to disk because we were unable to encode a valid signature.
+ bool Encode(DataEncoder &encoder);
+
+ /// Decode a serialized version of this object from data.
+ ///
+ /// \param data
+ /// The decoder object that references the serialized data.
+ ///
+ /// \param offset_ptr
+ /// A pointer that contains the offset from which the data will be decoded
+ /// from that gets updated as data gets decoded.
+ ///
+ /// \return
+ /// True if the signature was successfully decoded, false otherwise.
+ bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr);
+};
+
+/// Many cache files require string tables to store data efficiently. This
+/// class helps create string tables.
+class ConstStringTable {
+public:
+ ConstStringTable() = default;
+ /// Add a string into the string table.
+ ///
+ /// Add a string to the string table will only add the same string one time
+ /// and will return the offset in the string table buffer to that string.
+ /// String tables are easy to build with ConstString objects since most LLDB
+ /// classes for symbol or debug info use them already and they provide
+ /// permanent storage for the string.
+ ///
+ /// \param s
+ /// The string to insert into the string table.
+ ///
+ /// \return
+ /// The byte offset from the start of the string table for the inserted
+ /// string. Duplicate strings that get inserted will return the same
+ /// byte offset.
+ uint32_t Add(ConstString s);
+
+ bool Encode(DataEncoder &encoder);
+
+private:
+ std::vector<ConstString> m_strings;
+ std::map<ConstString, uint32_t> m_string_to_offset;
+ /// Skip one byte to start the string table off with an empty string.
+ uint32_t m_next_offset = 1;
+};
+
+/// Many cache files require string tables to store data efficiently. This
+/// class helps give out strings from a string table that was read from a
+/// cache file.
+class StringTableReader {
+public:
+ StringTableReader() = default;
+
+ llvm::StringRef Get(uint32_t offset) const;
+
+ bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr);
+
+protected:
+ /// All of the strings in the string table are contained in m_data.
+ llvm::StringRef m_data;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_CORE_DATAFILECACHE_H
diff --git a/lldb/include/lldb/Core/Mangled.h b/lldb/include/lldb/Core/Mangled.h
index c0542157f85d..6c92591a0881 100644
--- a/lldb/include/lldb/Core/Mangled.h
+++ b/lldb/include/lldb/Core/Mangled.h
@@ -12,9 +12,8 @@
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
-
+#include "lldb/lldb-types.h"
#include "lldb/Utility/ConstString.h"
-
#include "llvm/ADT/StringRef.h"
#include <cstddef>
@@ -64,6 +63,15 @@ public:
explicit Mangled(llvm::StringRef name);
+ bool operator==(const Mangled &rhs) const {
+ return m_mangled == rhs.m_mangled &&
+ GetDemangledName() == rhs.GetDemangledName();
+ }
+
+ bool operator!=(const Mangled &rhs) const {
+ return !(*this == rhs);
+ }
+
/// Convert to pointer operator.
///
/// This allows code to check a Mangled object to see if it contains a valid
@@ -270,6 +278,35 @@ public:
/// for s, otherwise the enumerator for the mangling scheme detected.
static Mangled::ManglingScheme GetManglingScheme(llvm::StringRef const name);
+ /// Decode a serialized version of this object from data.
+ ///
+ /// \param data
+ /// The decoder object that references the serialized data.
+ ///
+ /// \param offset_ptr
+ /// A pointer that contains the offset from which the data will be decoded
+ /// from that gets updated as data gets decoded.
+ ///
+ /// \param strtab
+ /// All strings in cache files are put into string tables for efficiency
+ /// and cache file size reduction. Strings are stored as uint32_t string
+ /// table offsets in the cache data.
+ bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
+ const StringTableReader &strtab);
+
+ /// Encode this object into a data encoder object.
+ ///
+ /// This allows this object to be serialized to disk.
+ ///
+ /// \param encoder
+ /// A data encoder object that serialized bytes will be encoded into.
+ ///
+ /// \param strtab
+ /// All strings in cache files are put into string tables for efficiency
+ /// and cache file size reduction. Strings are stored as uint32_t string
+ /// table offsets in the cache data.
+ void Encode(DataEncoder &encoder, ConstStringTable &strtab) const;
+
private:
/// Mangled member variables.
ConstString m_mangled; ///< The mangled version of the name
diff --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h
index b80f4fd9b85a..6b1e4f8f3704 100644
--- a/lldb/include/lldb/Core/Module.h
+++ b/lldb/include/lldb/Core/Module.h
@@ -21,8 +21,8 @@
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Status.h"
-#include "lldb/Utility/XcodeSDK.h"
#include "lldb/Utility/UUID.h"
+#include "lldb/Utility/XcodeSDK.h"
#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
@@ -128,7 +128,7 @@ public:
Module(const ModuleSpec &module_spec);
template <typename ObjFilePlugin, typename... Args>
- static lldb::ModuleSP CreateModuleFromObjectFile(Args &&... args) {
+ static lldb::ModuleSP CreateModuleFromObjectFile(Args &&...args) {
// Must create a module and place it into a shared pointer before we can
// create an object file since it has a std::weak_ptr back to the module,
// so we need to control the creation carefully in this static function
@@ -255,8 +255,7 @@ public:
/// Returns a valid symbol pointer if a symbol was found,
/// nullptr otherwise.
const Symbol *FindFirstSymbolWithNameAndType(
- ConstString name,
- lldb::SymbolType symbol_type = lldb::eSymbolTypeAny);
+ ConstString name, lldb::SymbolType symbol_type = lldb::eSymbolTypeAny);
void FindSymbolsWithNameAndType(ConstString name,
lldb::SymbolType symbol_type,
@@ -439,12 +438,13 @@ public:
///
/// \param searched_symbol_files
/// Prevents one file from being visited multiple times.
- void FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeMap &types);
+ void
+ FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
+ TypeMap &types);
- lldb::TypeSP FindFirstType(const SymbolContext &sc,
- ConstString type_name, bool exact_match);
+ lldb::TypeSP FindFirstType(const SymbolContext &sc, ConstString type_name,
+ bool exact_match);
/// Find types by name that are in a namespace. This function is used by the
/// expression parser when searches need to happen in an exact namespace
@@ -788,8 +788,7 @@ public:
const FileSpec &file_spec, uint32_t line, bool check_inlines,
lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list);
- void SetFileSpecAndObjectName(const FileSpec &file,
- ConstString object_name);
+ void SetFileSpecAndObjectName(const FileSpec &file, ConstString object_name);
bool GetIsDynamicLinkEditor();
@@ -876,7 +875,7 @@ public:
/// The value is returned as a reference to allow it to be updated by the
/// ElapsedTime RAII object.
StatsDuration &GetSymtabParseTime() { return m_symtab_parse_time; }
-
+
/// Accessor for the symbol table index time metric.
///
/// The value is returned as a reference to allow it to be updated by the
@@ -946,30 +945,67 @@ public:
bool m_match_name_after_lookup = false;
};
+ /// Get a unique hash for this module.
+ ///
+ /// The hash should be enough to identify the file on disk and the
+ /// architecture of the file. If the module represents an object inside of a
+ /// file, then the hash should include the object name and object offset to
+ /// ensure a unique hash. Some examples:
+ /// - just a regular object file (mach-o, elf, coff, etc) should create a hash
+ /// - a universal mach-o file that contains to multiple architectures,
+ /// each architecture slice should have a unique hash even though they come
+ /// from the same file
+ /// - a .o file inside of a BSD archive. Each .o file will have an object name
+ /// and object offset that should produce a unique hash. The object offset
+ /// is needed as BSD archive files can contain multiple .o files that have
+ /// the same name.
+ uint32_t Hash();
+
+ /// Get a unique cache key for the current module.
+ ///
+ /// The cache key must be unique for a file on disk and not change if the file
+ /// is updated. This allows cache data to use this key as a prefix and as
+ /// files are modified in disk, we will overwrite the cache files. If one file
+ /// can contain multiple files, like a universal mach-o file or like a BSD
+ /// archive, the cache key must contain enough information to differentiate
+ /// these different files.
+ std::string GetCacheKey();
+
+ /// Get the global index file cache.
+ ///
+ /// LLDB can cache data for a module between runs. This cache directory can be
+ /// used to stored data that previously was manually created each time you debug.
+ /// Examples include debug information indexes, symbol tables, symbol table
+ /// indexes, and more.
+ ///
+ /// \returns
+ /// If caching is enabled in the lldb settings, return a pointer to the data
+ /// file cache. If caching is not enabled, return NULL.
+ static DataFileCache *GetIndexCache();
protected:
// Member Variables
mutable std::recursive_mutex m_mutex; ///< A mutex to keep this object happy
- ///in multi-threaded environments.
+ /// in multi-threaded environments.
/// The modification time for this module when it was created.
llvm::sys::TimePoint<> m_mod_time;
- ArchSpec m_arch; ///< The architecture for this module.
+ ArchSpec m_arch; ///< The architecture for this module.
UUID m_uuid; ///< Each module is assumed to have a unique identifier to help
- ///match it up to debug symbols.
+ /// match it up to debug symbols.
FileSpec m_file; ///< The file representation on disk for this module (if
- ///there is one).
+ /// there is one).
FileSpec m_platform_file; ///< The path to the module on the platform on which
- ///it is being debugged
+ /// it is being debugged
FileSpec m_remote_install_file; ///< If set when debugging on remote
- ///platforms, this module will be installed at
- ///this location
+ /// platforms, this module will be installed
+ /// at this location
FileSpec m_symfile_spec; ///< If this path is valid, then this is the file
- ///that _will_ be used as the symbol file for this
- ///module
+ /// that _will_ be used as the symbol file for this
+ /// module
ConstString m_object_name; ///< The name an object within this module that is
- ///selected, or empty of the module is represented
- ///by \a m_file.
+ /// selected, or empty of the module is represented
+ /// by \a m_file.
uint64_t m_object_offset = 0;
llvm::sys::TimePoint<> m_object_mod_time;
@@ -979,8 +1015,8 @@ protected:
lldb::DataBufferSP m_data_sp;
lldb::ObjectFileSP m_objfile_sp; ///< A shared pointer to the object file
- ///parser for this module as it may or may
- ///not be shared with the SymbolFile
+ /// parser for this module as it may or may
+ /// not be shared with the SymbolFile
llvm::Optional<UnwindTable> m_unwind_table; ///< Table of FuncUnwinders
/// objects created for this
/// Module's functions
@@ -988,11 +1024,11 @@ protected:
m_symfile_up; ///< A pointer to the symbol vendor for this module.
std::vector<lldb::SymbolVendorUP>
m_old_symfiles; ///< If anyone calls Module::SetSymbolFileFileSpec() and
- ///changes the symbol file,
+ /// changes the symbol file,
///< we need to keep all old symbol files around in case anyone has type
- ///references to them
- TypeSystemMap m_type_system_map; ///< A map of any type systems associated
- ///with this module
+ /// references to them
+ TypeSystemMap m_type_system_map; ///< A map of any type systems associated
+ /// with this module
/// Module specific source remappings for when you have debug info for a
/// module that doesn't match where the sources currently are.
PathMappingList m_source_mappings =
diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h
index 6ca5813d9662..01b9991129eb 100644
--- a/lldb/include/lldb/Core/ModuleList.h
+++ b/lldb/include/lldb/Core/ModuleList.h
@@ -60,6 +60,13 @@ public:
bool SetClangModulesCachePath(const FileSpec &path);
bool GetEnableExternalLookup() const;
bool SetEnableExternalLookup(bool new_value);
+ bool GetEnableLLDBIndexCache() const;
+ bool SetEnableLLDBIndexCache(bool new_value);
+ uint64_t GetLLDBIndexCacheMaxByteSize();
+ uint64_t GetLLDBIndexCacheMaxPercent();
+ uint64_t GetLLDBIndexCacheExpirationDays();
+ FileSpec GetLLDBIndexCachePath() const;
+ bool SetLLDBIndexCachePath(const FileSpec &path);
PathMappingList GetSymlinkMappings() const;
};
diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h
index 7dc99bf3e755..1ab9d26d3af4 100644
--- a/lldb/include/lldb/Core/PluginManager.h
+++ b/lldb/include/lldb/Core/PluginManager.h
@@ -449,6 +449,8 @@ public:
static REPLCreateInstance GetREPLCreateCallbackAtIndex(uint32_t idx);
+ static LanguageSet GetREPLSupportedLanguagesAtIndex(uint32_t idx);
+
static LanguageSet GetREPLAllTypeSystemSupportedLanguages();
// Some plug-ins might register a DebuggerInitializeCallback callback when
diff --git a/lldb/include/lldb/Core/StructuredDataImpl.h b/lldb/include/lldb/Core/StructuredDataImpl.h
index d6f64451e5c2..8930ebff8166 100644
--- a/lldb/include/lldb/Core/StructuredDataImpl.h
+++ b/lldb/include/lldb/Core/StructuredDataImpl.h
@@ -29,6 +29,9 @@ public:
StructuredDataImpl(const StructuredDataImpl &rhs) = default;
+ StructuredDataImpl(StructuredData::ObjectSP obj)
+ : m_data_sp(std::move(obj)) {}
+
StructuredDataImpl(const lldb::EventSP &event_sp)
: m_plugin_wp(
EventDataStructuredData::GetPluginFromEvent(event_sp.get())),
diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h
index 5f1cbc65b320..192149f05436 100644
--- a/lldb/include/lldb/Core/ValueObject.h
+++ b/lldb/include/lldb/Core/ValueObject.h
@@ -1000,7 +1000,7 @@ protected:
void SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType);
protected:
- virtual void DoUpdateChildrenAddressType(ValueObject &valobj) { return; };
+ virtual void DoUpdateChildrenAddressType(ValueObject &valobj){};
private:
virtual CompilerType MaybeCalculateCompleteType();
diff --git a/lldb/include/lldb/Expression/UserExpression.h b/lldb/include/lldb/Expression/UserExpression.h
index 8236c417f73a..3874a60e06f0 100644
--- a/lldb/include/lldb/Expression/UserExpression.h
+++ b/lldb/include/lldb/Expression/UserExpression.h
@@ -266,10 +266,8 @@ public:
0x1001; ///< ValueObject::GetError() returns this if there is no result
/// from the expression.
- const char *GetFixedText() {
- if (m_fixed_text.empty())
- return nullptr;
- return m_fixed_text.c_str();
+ llvm::StringRef GetFixedText() {
+ return m_fixed_text;
}
protected:
diff --git a/lldb/include/lldb/Host/Config.h.cmake b/lldb/include/lldb/Host/Config.h.cmake
index 777a6d1be541..ffe919aa9956 100644
--- a/lldb/include/lldb/Host/Config.h.cmake
+++ b/lldb/include/lldb/Host/Config.h.cmake
@@ -45,6 +45,8 @@
#cmakedefine01 LLDB_ENABLE_PYTHON
+#cmakedefine01 LLDB_ENABLE_FBSDVMCORE
+
#cmakedefine01 LLDB_EMBED_PYTHON_HOME
#cmakedefine LLDB_PYTHON_HOME R"(${LLDB_PYTHON_HOME})"
diff --git a/lldb/include/lldb/Host/FileSystem.h b/lldb/include/lldb/Host/FileSystem.h
index 93563d4d26e3..54f7ac5ddb58 100644
--- a/lldb/include/lldb/Host/FileSystem.h
+++ b/lldb/include/lldb/Host/FileSystem.h
@@ -142,6 +142,14 @@ public:
void Resolve(FileSpec &file_spec);
/// \}
+ /// Remove a single file.
+ ///
+ /// The path must specify a file and not a directory.
+ /// \{
+ Status RemoveFile(const FileSpec &file_spec);
+ Status RemoveFile(const llvm::Twine &path);
+ /// \}
+
//// Create memory buffer from path.
/// \{
std::shared_ptr<DataBufferLLVM> CreateDataBuffer(const llvm::Twine &path,
diff --git a/lldb/include/lldb/Interpreter/CommandReturnObject.h b/lldb/include/lldb/Interpreter/CommandReturnObject.h
index 0c995b73c463..72518a902144 100644
--- a/lldb/include/lldb/Interpreter/CommandReturnObject.h
+++ b/lldb/include/lldb/Interpreter/CommandReturnObject.h
@@ -132,15 +132,15 @@ public:
void SetError(const Status &error, const char *fallback_error_cstr = nullptr);
- lldb::ReturnStatus GetStatus();
+ lldb::ReturnStatus GetStatus() const;
void SetStatus(lldb::ReturnStatus status);
- bool Succeeded();
+ bool Succeeded() const;
- bool HasResult();
+ bool HasResult() const;
- bool GetDidChangeProcessState();
+ bool GetDidChangeProcessState() const;
void SetDidChangeProcessState(bool b);
diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
index 2b96021fffc9..83f784bde712 100644
--- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -274,7 +274,7 @@ public:
virtual StructuredData::ObjectSP
CreateScriptedThreadPlan(const char *class_name,
- StructuredDataImpl *args_data,
+ const StructuredDataImpl &args_data,
std::string &error_str,
lldb::ThreadPlanSP thread_plan_sp) {
return StructuredData::ObjectSP();
@@ -310,7 +310,7 @@ public:
virtual StructuredData::GenericSP
CreateScriptedBreakpointResolver(const char *class_name,
- StructuredDataImpl *args_data,
+ const StructuredDataImpl &args_data,
lldb::BreakpointSP &bkpt_sp) {
return StructuredData::GenericSP();
}
@@ -330,7 +330,7 @@ public:
virtual StructuredData::GenericSP
CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name,
- StructuredDataImpl *args_data, Status &error) {
+ const StructuredDataImpl &args_data, Status &error) {
error.SetErrorString("Creating scripted stop-hooks with the current "
"script interpreter is not supported.");
return StructuredData::GenericSP();
diff --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h
index 0a8b38b2c642..8bf047cd4514 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/ADT/Optional.h"
#include "llvm/Support/Threading.h"
#include "llvm/Support/VersionTuple.h"
@@ -526,11 +527,15 @@ public:
/// binary is exactly which removes ambiguity when there are multiple
/// binaries present in the captured memory pages.
///
- /// \param[out] address
- /// If the address of the binary is specified, this will be set.
- /// This is an address is the virtual address space of the core file
- /// memory segments; it is not an offset into the object file.
- /// If no address is available, will be set to LLDB_INVALID_ADDRESS.
+ /// \param[out] value
+ /// The address or offset (slide) where the binary is loaded in memory.
+ /// LLDB_INVALID_ADDRESS for unspecified. If an offset is given,
+ /// this offset should be added to the binary's file address to get
+ /// the load address.
+ ///
+ /// \param[out] value_is_offset
+ /// Specifies if \b value is a load address, or an offset to calculate
+ /// the load address.
///
/// \param[out] uuid
/// If the uuid of the binary is specified, this will be set.
@@ -542,9 +547,11 @@ public:
///
/// \return
/// Returns true if either address or uuid has been set.
- virtual bool GetCorefileMainBinaryInfo(lldb::addr_t &address, UUID &uuid,
+ virtual bool GetCorefileMainBinaryInfo(lldb::addr_t &value,
+ bool &value_is_offset, UUID &uuid,
ObjectFile::BinaryType &type) {
- address = LLDB_INVALID_ADDRESS;
+ value = LLDB_INVALID_ADDRESS;
+ value_is_offset = false;
uuid.Clear();
return false;
}
@@ -707,6 +714,15 @@ public:
return false;
}
+ /// Get a hash that can be used for caching object file releated information.
+ ///
+ /// Data for object files can be cached between runs of debug sessions and
+ /// a module can end up using a main file and a symbol file, both of which
+ /// can be object files. So we need a unique hash that identifies an object
+ /// file when storing cached data.
+ uint32_t GetCacheHash();
+
+
protected:
// Member variables.
FileSpec m_file;
@@ -729,6 +745,7 @@ protected:
/// 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;
+ llvm::Optional<uint32_t> m_cache_hash;
/// 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/Symbol.h b/lldb/include/lldb/Symbol/Symbol.h
index cb2385468702..23a68090ff4d 100644
--- a/lldb/include/lldb/Symbol/Symbol.h
+++ b/lldb/include/lldb/Symbol/Symbol.h
@@ -235,6 +235,46 @@ public:
return "___lldb_unnamed_symbol";
}
+ /// Decode a serialized version of this object from data.
+ ///
+ /// \param data
+ /// The decoder object that references the serialized data.
+ ///
+ /// \param offset_ptr
+ /// A pointer that contains the offset from which the data will be decoded
+ /// from that gets updated as data gets decoded.
+ ///
+ /// \param section_list
+ /// A section list that allows lldb_private::Address objects to be filled
+ /// in. The address information for symbols are serilized as file addresses
+ /// and must be converted into Address objects with the right section and
+ /// offset.
+ ///
+ /// \param strtab
+ /// All strings in cache files are put into string tables for efficiency
+ /// and cache file size reduction. Strings are stored as uint32_t string
+ /// table offsets in the cache data.
+ ///
+ /// \return
+ /// True if the symbol is successfully decoded, false otherwise.
+ bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
+ const SectionList *section_list, const StringTableReader &strtab);
+
+ /// Encode this object into a data encoder object.
+ ///
+ /// This allows this object to be serialized to disk.
+ ///
+ /// \param encoder
+ /// A data encoder object that serialized bytes will be encoded into.
+ ///
+ /// \param strtab
+ /// All strings in cache files are put into string tables for efficiency
+ /// and cache file size reduction. Strings are stored as uint32_t string
+ /// table offsets in the cache data.
+ void Encode(DataEncoder &encoder, ConstStringTable &strtab) const;
+
+ bool operator==(const Symbol &rhs) const;
+
protected:
// This is the internal guts of ResolveReExportedSymbol, it assumes
// reexport_name is not null, and that module_spec is valid. We track the
diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h
index 9ab63cac56dd..7c0365483c12 100644
--- a/lldb/include/lldb/Symbol/SymbolFile.h
+++ b/lldb/include/lldb/Symbol/SymbolFile.h
@@ -181,7 +181,6 @@ public:
virtual size_t ParseVariablesForContext(const SymbolContext &sc) = 0;
virtual Type *ResolveTypeUID(lldb::user_id_t type_uid) = 0;
-
/// The characteristics of an array type.
struct ArrayInfo {
int64_t first_index = 0;
@@ -318,19 +317,14 @@ public:
///
/// \returns 0.0 if no information has been parsed or if there is
/// no computational cost to parsing the debug information.
- virtual StatsDuration GetDebugInfoParseTime() {
- return StatsDuration(0.0);
- }
+ virtual StatsDuration GetDebugInfoParseTime() { return StatsDuration(0.0); }
/// Return the time it took to index the debug information in the object
/// file.
///
/// \returns 0.0 if the file doesn't need to be indexed or if it
/// hasn't been indexed yet, or a valid duration if it has.
- virtual StatsDuration GetDebugInfoIndexTime() {
- return StatsDuration(0.0);
- }
-
+ virtual StatsDuration GetDebugInfoIndexTime() { return StatsDuration(0.0); }
protected:
void AssertModuleLock();
diff --git a/lldb/include/lldb/Symbol/Symtab.h b/lldb/include/lldb/Symbol/Symtab.h
index e5d21c1bf4b3..fe0a82306c4f 100644
--- a/lldb/include/lldb/Symbol/Symtab.h
+++ b/lldb/include/lldb/Symbol/Symtab.h
@@ -131,7 +131,86 @@ public:
bool add_demangled, bool add_mangled,
NameToIndexMap &name_to_index_map) const;
- ObjectFile *GetObjectFile() { return m_objfile; }
+ ObjectFile *GetObjectFile() const { return m_objfile; }
+
+ /// Decode a serialized version of this object from data.
+ ///
+ /// \param data
+ /// The decoder object that references the serialized data.
+ ///
+ /// \param offset_ptr
+ /// A pointer that contains the offset from which the data will be decoded
+ /// from that gets updated as data gets decoded.
+ ///
+ /// \param[out] uuid_mismatch
+ /// Set to true if a cache file exists but the UUID didn't match, false
+ /// otherwise.
+ ///
+ /// \return
+ /// True if the symbol table is successfully decoded and can be used,
+ /// false otherwise.
+ bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
+ bool &uuid_mismatch);
+
+ /// Encode this object into a data encoder object.
+ ///
+ /// This allows this object to be serialized to disk. The object file must
+ /// have a valid Signature in order to be serialized as it is used to make
+ /// sure the cached information matches when cached data is loaded at a later
+ /// time. If the object file doesn't have a valid signature false will be
+ /// returned and it will indicate we should not cache this data.
+ ///
+ /// \param encoder
+ /// A data encoder object that serialized bytes will be encoded into.
+ ///
+ /// \return
+ /// True if the symbol table's object file can generate a valid signature
+ /// and all data for the symbol table was encoded, false otherwise.
+ bool Encode(DataEncoder &encoder) const;
+
+ /// Get the cache key string for this symbol table.
+ ///
+ /// The cache key must start with the module's cache key and is followed
+ /// by information that indicates this key is for caching the symbol table
+ /// contents and should also include the has of the object file. A module can
+ /// be represented by an ObjectFile object for the main executable, but can
+ /// also have a symbol file that is from the same or a different object file.
+ /// This means we might have two symbol tables cached in the index cache, one
+ /// for the main executable and one for the symbol file.
+ ///
+ /// \return
+ /// The unique cache key used to save and retrieve data from the index cache.
+ std::string GetCacheKey();
+
+ /// Save the symbol table data out into a cache.
+ ///
+ /// The symbol table will only be saved to a cache file if caching is enabled.
+ ///
+ /// We cache the contents of the symbol table since symbol tables in LLDB take
+ /// some time to initialize. This is due to the many sources for data that are
+ /// used to create a symbol table:
+ /// - standard symbol table
+ /// - dynamic symbol table (ELF)
+ /// - compressed debug info sections
+ /// - unwind information
+ /// - function pointers found in runtimes for global constructor/destructors
+ /// - other sources.
+ /// All of the above sources are combined and one symbol table results after
+ /// all sources have been considered.
+ void SaveToCache();
+
+ /// Load the symbol table from the index cache.
+ ///
+ /// Quickly load the finalized symbol table from the index cache. This saves
+ /// time when the debugger starts up. The index cache file for the symbol
+ /// table has the modification time set to the same time as the main module.
+ /// If the cache file exists and the modification times match, we will load
+ /// the symbol table from the serlized cache file.
+ ///
+ /// \return
+ /// True if the symbol table was successfully loaded from the index cache,
+ /// false if the symbol table wasn't cached or was out of date.
+ bool LoadFromCache();
protected:
typedef std::vector<Symbol> collection;
diff --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h
index 9e671a565dd1..7754e0299096 100644
--- a/lldb/include/lldb/Symbol/Type.h
+++ b/lldb/include/lldb/Symbol/Type.h
@@ -66,24 +66,30 @@ protected:
class Type : public std::enable_shared_from_this<Type>, public UserID {
public:
enum EncodingDataType {
+ /// Invalid encoding.
eEncodingInvalid,
- eEncodingIsUID, ///< This type is the type whose UID is m_encoding_uid
- eEncodingIsConstUID, ///< This type is the type whose UID is m_encoding_uid
- /// with the const qualifier added
- eEncodingIsRestrictUID, ///< This type is the type whose UID is
- /// m_encoding_uid with the restrict qualifier added
- eEncodingIsVolatileUID, ///< This type is the type whose UID is
- /// m_encoding_uid with the volatile qualifier added
- eEncodingIsTypedefUID, ///< This type is pointer to a type whose UID is
- /// m_encoding_uid
- eEncodingIsPointerUID, ///< This type is pointer to a type whose UID is
- /// m_encoding_uid
- eEncodingIsLValueReferenceUID, ///< This type is L value reference to a type
- /// whose UID is m_encoding_uid
- eEncodingIsRValueReferenceUID, ///< This type is R value reference to a type
- /// whose UID is m_encoding_uid,
- eEncodingIsAtomicUID, ///< This type is the type whose UID is
- /// m_encoding_uid as an atomic type.
+ /// This type is the type whose UID is m_encoding_uid.
+ eEncodingIsUID,
+ /// This type is the type whose UID is m_encoding_uid with the const
+ /// qualifier added.
+ eEncodingIsConstUID,
+ /// This type is the type whose UID is m_encoding_uid with the restrict
+ /// qualifier added.
+ eEncodingIsRestrictUID,
+ /// This type is the type whose UID is m_encoding_uid with the volatile
+ /// qualifier added.
+ eEncodingIsVolatileUID,
+ /// This type is alias to a type whose UID is m_encoding_uid.
+ eEncodingIsTypedefUID,
+ /// This type is pointer to a type whose UID is m_encoding_uid.
+ eEncodingIsPointerUID,
+ /// This type is L value reference to a type whose UID is m_encoding_uid.
+ eEncodingIsLValueReferenceUID,
+ /// This type is R value reference to a type whose UID is m_encoding_uid.
+ eEncodingIsRValueReferenceUID,
+ /// This type is the type whose UID is m_encoding_uid as an atomic type.
+ eEncodingIsAtomicUID,
+ /// This type is the synthetic type whose UID is m_encoding_uid.
eEncodingIsSyntheticUID
};
@@ -197,7 +203,7 @@ public:
// From a fully qualified typename, split the type into the type basename and
// the remaining type scope (namespaces/classes).
- static bool GetTypeScopeAndBasename(const llvm::StringRef& name,
+ static bool GetTypeScopeAndBasename(llvm::StringRef name,
llvm::StringRef &scope,
llvm::StringRef &basename,
lldb::TypeClass &type_class);
@@ -473,8 +479,8 @@ class TypeEnumMemberImpl {
public:
TypeEnumMemberImpl() : m_integer_type_sp(), m_name("<invalid>"), m_value() {}
- TypeEnumMemberImpl(const lldb::TypeImplSP &integer_type_sp,
- ConstString name, const llvm::APSInt &value);
+ TypeEnumMemberImpl(const lldb::TypeImplSP &integer_type_sp, ConstString name,
+ const llvm::APSInt &value);
TypeEnumMemberImpl(const TypeEnumMemberImpl &rhs) = default;
diff --git a/lldb/include/lldb/Target/LanguageRuntime.h b/lldb/include/lldb/Target/LanguageRuntime.h
index 2f95c2643318..ba96d080f908 100644
--- a/lldb/include/lldb/Target/LanguageRuntime.h
+++ b/lldb/include/lldb/Target/LanguageRuntime.h
@@ -141,7 +141,7 @@ public:
return false;
}
- virtual void SymbolsDidLoad(const ModuleList &module_list) { return; }
+ virtual void SymbolsDidLoad(const ModuleList &module_list) {}
virtual lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
bool stop_others) = 0;
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 7e8e1373a506..b85839c15b2f 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -21,6 +21,7 @@
#include "lldb/Core/Architecture.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/ModuleList.h"
+#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Core/UserSettingsController.h"
#include "lldb/Expression/Expression.h"
#include "lldb/Host/ProcessLaunchInfo.h"
@@ -1309,8 +1310,7 @@ public:
std::string m_class_name;
/// This holds the dictionary of keys & values that can be used to
/// parametrize any given callback's behavior.
- StructuredDataImpl *m_extra_args; // We own this structured data,
- // but the SD itself manages the UP.
+ StructuredDataImpl m_extra_args;
/// This holds the python callback object.
StructuredData::GenericSP m_implementation_sp;
diff --git a/lldb/include/lldb/Target/ThreadPlanPython.h b/lldb/include/lldb/Target/ThreadPlanPython.h
index 7b37b2b9ce5a..f148f88d4c46 100644
--- a/lldb/include/lldb/Target/ThreadPlanPython.h
+++ b/lldb/include/lldb/Target/ThreadPlanPython.h
@@ -12,8 +12,7 @@
#include <string>
-#include "lldb/lldb-forward.h"
-
+#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
@@ -22,6 +21,7 @@
#include "lldb/Target/ThreadPlanTracer.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/UserID.h"
+#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"
namespace lldb_private {
@@ -31,9 +31,8 @@ namespace lldb_private {
class ThreadPlanPython : public ThreadPlan {
public:
- ThreadPlanPython(Thread &thread, const char *class_name,
- StructuredDataImpl *args_data);
- ~ThreadPlanPython() override;
+ ThreadPlanPython(Thread &thread, const char *class_name,
+ const StructuredDataImpl &args_data);
void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
@@ -62,10 +61,7 @@ protected:
private:
std::string m_class_name;
- StructuredDataImpl *m_args_data; // We own this, but the implementation
- // has to manage the UP (since that is
- // how it gets stored in the
- // SBStructuredData).
+ StructuredDataImpl m_args_data;
std::string m_error_str;
StructuredData::ObjectSP m_implementation_sp;
bool m_did_push;
diff --git a/lldb/include/lldb/Utility/DataEncoder.h b/lldb/include/lldb/Utility/DataEncoder.h
index b944c09d5c47..7e1dec6992b2 100644
--- a/lldb/include/lldb/Utility/DataEncoder.h
+++ b/lldb/include/lldb/Utility/DataEncoder.h
@@ -16,6 +16,9 @@
#include "lldb/lldb-forward.h"
#include "lldb/lldb-types.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+
#include <cstddef>
#include <cstdint>
@@ -26,21 +29,34 @@ namespace lldb_private {
/// An binary data encoding class.
///
/// DataEncoder is a class that can encode binary data (swapping if needed) to
-/// a data buffer. The data buffer can be caller owned, or can be shared data
-/// that can be shared between multiple DataEncoder or DataEncoder instances.
+/// a data buffer. The DataEncoder can be constructed with data that will be
+/// copied into the internally owned buffer. This allows data to be modified
+/// in the internal buffer. The DataEncoder object can also be constructed with
+/// just a byte order and address size and data can be appended to the
+/// internally owned buffer.
+///
+/// Clients can get a shared pointer to the data buffer when done modifying or
+/// creating the data to keep the data around after the lifetime of a
+/// DataEncoder object. \see GetDataBuffer
///
-/// \see DataBuffer
+/// Client can get a reference to the object owned data as an array by calling
+/// the GetData method. \see GetData
class DataEncoder {
public:
/// Default constructor.
///
- /// Initialize all members to a default empty state.
+ /// Initialize all members to a default empty state and create a empty memory
+ /// buffer that can be appended to. The ByteOrder and address size will be set
+ /// to match the current host system.
DataEncoder();
- /// Construct with a buffer that is owned by the caller.
+ /// Construct an encoder that copies the specified data into the object owned
+ /// data buffer.
///
- /// This constructor allows us to use data that is owned by the caller. The
- /// data must stay around as long as this object is valid.
+ /// This constructor is designed to be used when you have a data buffer and
+ /// want to modify values within the buffer. A copy of the data will be made
+ /// in the internally owned buffer and that data can be fixed up and appended
+ /// to.
///
/// \param[in] data
/// A pointer to caller owned data.
@@ -49,54 +65,37 @@ public:
/// The length in bytes of \a data.
///
/// \param[in] byte_order
- /// A byte order of the data that we are extracting from.
+ /// A byte order for the data that will be encoded.
///
/// \param[in] addr_size
- /// A new address byte size value.
- DataEncoder(void *data, uint32_t data_length, lldb::ByteOrder byte_order,
- uint8_t addr_size);
+ /// A size of an address in bytes. \see PutAddress, AppendAddress
+ DataEncoder(const void *data, uint32_t data_length,
+ lldb::ByteOrder byte_order, uint8_t addr_size);
- /// Construct with shared data.
- ///
- /// Copies the data shared pointer which adds a reference to the contained
- /// in \a data_sp. The shared data reference is reference counted to ensure
- /// the data lives as long as anyone still has a valid shared pointer to the
- /// data in \a data_sp.
+ /// Construct an encoder that owns a heap based memory buffer.
///
- /// \param[in] data_sp
- /// A shared pointer to data.
+ /// This allows clients to create binary data from scratch by appending values
+ /// with the methods that start with "Append".
///
/// \param[in] byte_order
- /// A byte order of the data that we are extracting from.
+ /// A byte order for the data that will be encoded.
///
/// \param[in] addr_size
- /// A new address byte size value.
- DataEncoder(const lldb::DataBufferSP &data_sp, lldb::ByteOrder byte_order,
- uint8_t addr_size);
+ /// A size of an address in bytes. \see PutAddress, AppendAddress
+ DataEncoder(lldb::ByteOrder byte_order, uint8_t addr_size);
- /// Destructor
- ///
- /// If this object contains a valid shared data reference, the reference
- /// count on the data will be decremented, and if zero, the data will be
- /// freed.
~DataEncoder();
- /// Clears the object state.
- ///
- /// Clears the object contents back to a default invalid state, and release
- /// any references to shared data that this object may contain.
- void Clear();
-
/// Encode an unsigned integer of size \a byte_size to \a offset.
///
/// Encode a single integer value at \a offset and return the offset that
/// follows the newly encoded integer when the data is successfully encoded
- /// into the existing data. There must be enough room in the data, else
- /// UINT32_MAX will be returned to indicate that encoding failed.
+ /// into the existing data. There must be enough room in the existing data,
+ /// else UINT32_MAX will be returned to indicate that encoding failed.
///
/// \param[in] offset
- /// The offset within the contained data at which to put the
- /// encoded integer.
+ /// The offset within the contained data at which to put the encoded
+ /// integer.
///
/// \param[in] byte_size
/// The size in byte of the integer to encode.
@@ -111,6 +110,72 @@ public:
/// was successfully encoded, UINT32_MAX if the encoding failed.
uint32_t PutUnsigned(uint32_t offset, uint32_t byte_size, uint64_t value);
+ /// Encode an unsigned integer at offset \a offset.
+ ///
+ /// Encode a single unsigned integer value at \a offset and return the offset
+ /// that follows the newly encoded integer when the data is successfully
+ /// encoded into the existing data. There must be enough room in the data,
+ /// else UINT32_MAX will be returned to indicate that encoding failed.
+ ///
+ /// \param[in] offset
+ /// The offset within the contained data at which to put the encoded
+ /// integer.
+ ///
+ /// \param[in] value
+ /// The integer value to write.
+ ///
+ /// \return
+ /// The next offset in the bytes of this data if the integer was
+ /// successfully encoded, UINT32_MAX if the encoding failed.
+ uint32_t PutU8(uint32_t offset, uint8_t value);
+ uint32_t PutU16(uint32_t offset, uint16_t value);
+ uint32_t PutU32(uint32_t offset, uint32_t value);
+ uint32_t PutU64(uint32_t offset, uint64_t value);
+
+ /// Append a unsigned integer to the end of the owned data.
+ ///
+ /// \param value
+ /// A unsigned integer value to append.
+ void AppendU8(uint8_t value);
+ void AppendU16(uint16_t value);
+ void AppendU32(uint32_t value);
+ void AppendU64(uint64_t value);
+
+ /// Append an address sized integer to the end of the owned data.
+ ///
+ /// \param addr
+ /// A unsigned integer address value to append. The size of the address
+ /// will be determined by the address size specified in the constructor.
+ void AppendAddress(lldb::addr_t addr);
+
+ /// Append a bytes to the end of the owned data.
+ ///
+ /// Append the bytes contained in the string reference. This function will
+ /// not append a NULL termination character for a C string. Use the
+ /// AppendCString function for this purpose.
+ ///
+ /// \param data
+ /// A string reference that contains bytes to append.
+ void AppendData(llvm::StringRef data);
+
+ /// Append a bytes to the end of the owned data.
+ ///
+ /// Append the bytes contained in the array reference.
+ ///
+ /// \param data
+ /// A array reference that contains bytes to append.
+ void AppendData(llvm::ArrayRef<uint8_t> data);
+
+ /// Append a C string to the end of the owned data.
+ ///
+ /// Append the bytes contained in the string reference along with an extra
+ /// NULL termination character if the StringRef bytes doesn't include one as
+ /// the last byte.
+ ///
+ /// \param data
+ /// A string reference that contains bytes to append.
+ void AppendCString(llvm::StringRef data);
+
/// Encode an arbitrary number of bytes.
///
/// \param[in] offset
@@ -131,11 +196,10 @@ public:
/// Encode an address in the existing buffer at \a offset bytes into the
/// buffer.
///
- /// Encode a single address (honoring the m_addr_size member) to the data
- /// and return the next offset where subsequent data would go. pointed to by
- /// \a offset_ptr. The size of the extracted address comes from the \a
- /// m_addr_size member variable and should be set correctly prior to
- /// extracting any address values.
+ /// Encode a single address to the data and return the next offset where
+ /// subsequent data would go. The size of the address comes from the \a
+ /// m_addr_size member variable and should be set correctly prior to encoding
+ /// any address values.
///
/// \param[in] offset
/// The offset where to encode the address.
@@ -150,7 +214,10 @@ public:
/// Put a C string to \a offset.
///
- /// Encodes a C string into the existing data including the terminating
+ /// Encodes a C string into the existing data including the terminating. If
+ /// there is not enough room in the buffer to fit the entire C string and the
+ /// NULL terminator in the existing buffer bounds, then this function will
+ /// fail.
///
/// \param[in] offset
/// The offset where to encode the string.
@@ -159,18 +226,43 @@ public:
/// The string to encode.
///
/// \return
- /// A pointer to the C string value in the data. If the offset
- /// pointed to by \a offset_ptr is out of bounds, or if the
- /// offset plus the length of the C string is out of bounds,
- /// NULL will be returned.
+ /// The next valid offset within data if the put operation was successful,
+ /// else UINT32_MAX to indicate the put failed.
uint32_t PutCString(uint32_t offset, const char *cstr);
-private:
- uint32_t PutU8(uint32_t offset, uint8_t value);
- uint32_t PutU16(uint32_t offset, uint16_t value);
- uint32_t PutU32(uint32_t offset, uint32_t value);
- uint32_t PutU64(uint32_t offset, uint64_t value);
+ /// Get a shared copy of the heap based memory buffer owned by this object.
+ ///
+ /// This allows a data encoder to be used to create a data buffer that can
+ /// be extracted and used elsewhere after this object is destroyed.
+ ///
+ /// \return
+ /// A shared pointer to the DataBufferHeap that contains the data that was
+ /// encoded into this object.
+ std::shared_ptr<lldb_private::DataBufferHeap> GetDataBuffer() {
+ return m_data_sp;
+ }
+
+ /// Get a access to the bytes that this references.
+ ///
+ /// This value will always return the data that this object references even if
+ /// the object was constructed with caller owned data.
+ ///
+ /// \return
+ /// A array reference to the data that this object references.
+ llvm::ArrayRef<uint8_t> GetData() const;
+
+ /// Get the number of bytes contained in this object.
+ ///
+ /// \return
+ /// The total number of bytes of data this object refers to.
+ size_t GetByteSize() const;
+
+ lldb::ByteOrder GetByteOrder() const { return m_byte_order; }
+
+ /// The address size to use when encoding pointers or addresses.
+ uint8_t GetAddressByteSize() const { return m_addr_size; }
+private:
uint32_t BytesLeft(uint32_t offset) const {
const uint32_t size = GetByteSize();
if (size > offset)
@@ -187,31 +279,6 @@ private:
return length <= BytesLeft(offset);
}
- /// Adopt a subset of shared data in \a data_sp.
- ///
- /// Copies the data shared pointer which adds a reference to the contained
- /// in \a data_sp. The shared data reference is reference counted to ensure
- /// the data lives as long as anyone still has a valid shared pointer to the
- /// data in \a data_sp. The byte order and address byte size settings remain
- /// the same. If \a offset is not a valid offset in \a data_sp, then no
- /// reference to the shared data will be added. If there are not \a length
- /// bytes available in \a data starting at \a offset, the length will be
- /// truncated to contains as many bytes as possible.
- ///
- /// \param[in] data_sp
- /// A shared pointer to data.
- ///
- /// \param[in] offset
- /// The offset into \a data_sp at which the subset starts.
- ///
- /// \param[in] length
- /// The length in bytes of the subset of \a data_sp.
- ///
- /// \return
- /// The number of bytes that this object now contains.
- uint32_t SetData(const lldb::DataBufferSP &data_sp, uint32_t offset = 0,
- uint32_t length = UINT32_MAX);
-
/// Test the validity of \a offset.
///
/// \return
@@ -219,28 +286,14 @@ private:
/// object, \b false otherwise.
bool ValidOffset(uint32_t offset) const { return offset < GetByteSize(); }
- /// Get the number of bytes contained in this object.
- ///
- /// \return
- /// The total number of bytes of data this object refers to.
- size_t GetByteSize() const { return m_end - m_start; }
-
- /// A pointer to the first byte of data.
- uint8_t *m_start = nullptr;
-
- /// A pointer to the byte that is past the end of the data.
- uint8_t *m_end = nullptr;
-
- /// The byte order of the data we are extracting from.
- lldb::ByteOrder m_byte_order;
+ /// The shared pointer to data that can grow as data is added
+ std::shared_ptr<lldb_private::DataBufferHeap> m_data_sp;
- /// The address size to use when extracting pointers or
- /// addresses
- uint8_t m_addr_size;
+ /// The byte order of the data we are encoding to.
+ const lldb::ByteOrder m_byte_order;
- /// The shared pointer to data that can
- /// be shared among multiple instances
- mutable lldb::DataBufferSP m_data_sp;
+ /// The address size to use when encoding pointers or addresses.
+ const uint8_t m_addr_size;
DataEncoder(const DataEncoder &) = delete;
const DataEncoder &operator=(const DataEncoder &) = delete;
diff --git a/lldb/include/lldb/Utility/RangeMap.h b/lldb/include/lldb/Utility/RangeMap.h
index 118fdfd85fa9..422f90d807a7 100644
--- a/lldb/include/lldb/Utility/RangeMap.h
+++ b/lldb/include/lldb/Utility/RangeMap.h
@@ -360,7 +360,6 @@ protected:
m_entries.erase(next);
}
}
- return;
}
Collection m_entries;
diff --git a/lldb/include/lldb/Utility/Reproducer.h b/lldb/include/lldb/Utility/Reproducer.h
index 4659254e57d6..35043d688511 100644
--- a/lldb/include/lldb/Utility/Reproducer.h
+++ b/lldb/include/lldb/Utility/Reproducer.h
@@ -29,8 +29,6 @@ class Reproducer;
enum class ReproducerMode {
Capture,
- Replay,
- PassiveReplay,
Off,
};
@@ -179,15 +177,12 @@ public:
const FileSpec &GetRoot() const { return m_root; }
- bool IsPassiveReplay() const { return m_passive_replay; }
-
private:
bool HasFile(llvm::StringRef file);
FileSpec m_root;
std::vector<std::string> m_files;
bool m_loaded;
- bool m_passive_replay;
};
/// The reproducer enables clients to obtain access to the Generator and
@@ -212,11 +207,9 @@ public:
FileSpec GetReproducerPath() const;
bool IsCapturing() { return static_cast<bool>(m_generator); };
- bool IsReplaying() { return static_cast<bool>(m_loader); };
protected:
llvm::Error SetCapture(llvm::Optional<FileSpec> root);
- llvm::Error SetReplay(llvm::Optional<FileSpec> root, bool passive = false);
private:
static llvm::Optional<Reproducer> &InstanceImpl();
diff --git a/lldb/include/lldb/Version/Version.h b/lldb/include/lldb/Version/Version.h
new file mode 100644
index 000000000000..15b613560187
--- /dev/null
+++ b/lldb/include/lldb/Version/Version.h
@@ -0,0 +1,23 @@
+//===-- Version.h -----------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_VERSION_VERSION_H
+#define LLDB_VERSION_VERSION_H
+
+#include <string>
+
+namespace lldb_private {
+
+/// Retrieves a string representing the complete LLDB version, which includes
+/// the lldb version number, as well as embedded compiler versions and the
+/// vendor tag.
+const char *GetVersion();
+
+} // namespace lldb_private
+
+#endif // LLDB_VERSION_VERSION_H
diff --git a/lldb/include/lldb/Version/Version.inc.in b/lldb/include/lldb/Version/Version.inc.in
new file mode 100644
index 000000000000..5098bb1c2be5
--- /dev/null
+++ b/lldb/include/lldb/Version/Version.inc.in
@@ -0,0 +1,6 @@
+#define LLDB_VERSION @LLDB_VERSION@
+#define LLDB_VERSION_STRING "@LLDB_VERSION@"
+#define LLDB_VERSION_MAJOR @LLDB_VERSION_MAJOR@
+#define LLDB_VERSION_MINOR @LLDB_VERSION_MINOR@
+#define LLDB_VERSION_PATCHLEVEL @LLDB_VERSION_PATCHLEVEL@
+#cmakedefine LLDB_FULL_VERSION_STRING "@LLDB_FULL_VERSION_STRING@"
diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index 482da17bfacb..6f8c52ff3749 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -46,6 +46,7 @@ class BroadcastEventSpec;
class Broadcaster;
class BroadcasterManager;
class CXXSyntheticChildren;
+struct CacheSignature;
class CallFrameInfo;
class CommandInterpreter;
class CommandInterpreterRunOptions;
@@ -61,12 +62,15 @@ class CompilerType;
class Connection;
class ConnectionFileDescriptor;
class ConstString;
+class ConstStringTable;
class DWARFCallFrameInfo;
class DWARFDataExtractor;
class DWARFExpression;
class DataBuffer;
+class DataBufferHeap;
class DataEncoder;
class DataExtractor;
+class DataFileCache;
class Debugger;
class Declaration;
class DiagnosticManager;
@@ -198,6 +202,7 @@ class Stream;
class StreamFile;
class StreamString;
class StringList;
+class StringTableReader;
class StructuredDataImpl;
class StructuredDataPlugin;
class Symbol;
diff --git a/lldb/include/lldb/lldb-private.h b/lldb/include/lldb/lldb-private.h
index d65773aecd6d..ac07047fb4ed 100644
--- a/lldb/include/lldb/lldb-private.h
+++ b/lldb/include/lldb/lldb-private.h
@@ -17,12 +17,6 @@
#include "lldb/lldb-private-types.h"
#include "lldb/lldb-public.h"
-namespace lldb_private {
-
-const char *GetVersion();
-
-} // namespace lldb_private
-
#endif // defined(__cplusplus)
#endif // LLDB_LLDB_PRIVATE_H
diff --git a/lldb/source/API/SBData.cpp b/lldb/source/API/SBData.cpp
index daf313ad55c9..9fc590578bce 100644
--- a/lldb/source/API/SBData.cpp
+++ b/lldb/source/API/SBData.cpp
@@ -374,6 +374,25 @@ void SBData::SetData(lldb::SBError &error, const void *buf, size_t size,
}
}
+void SBData::SetDataWithOwnership(lldb::SBError &error, const void *buf,
+ size_t size, lldb::ByteOrder endian,
+ uint8_t addr_size) {
+ LLDB_RECORD_DUMMY(
+ void, SBData, SetData,
+ (lldb::SBError &, const void *, size_t, lldb::ByteOrder, uint8_t, bool),
+ error, buf, size, endian, addr_size, copy);
+
+ lldb::DataBufferSP buffer_sp = std::make_shared<DataBufferHeap>(buf, size);
+
+ if (!m_opaque_sp.get())
+ m_opaque_sp = std::make_shared<DataExtractor>(buf, size, endian, addr_size);
+ else {
+ m_opaque_sp->SetData(buffer_sp);
+ m_opaque_sp->SetByteOrder(endian);
+ m_opaque_sp->SetAddressByteSize(addr_size);
+ }
+}
+
bool SBData::Append(const SBData &rhs) {
LLDB_RECORD_METHOD(bool, SBData, Append, (const lldb::SBData &), rhs);
diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp
index 844b91de4cd0..fa5dcb57de7e 100644
--- a/lldb/source/API/SBDebugger.cpp
+++ b/lldb/source/API/SBDebugger.cpp
@@ -11,8 +11,6 @@
#include "lldb/API/SBDebugger.h"
-#include "lldb/lldb-private.h"
-
#include "lldb/API/SBBroadcaster.h"
#include "lldb/API/SBCommandInterpreter.h"
#include "lldb/API/SBCommandInterpreterRunOptions.h"
@@ -52,6 +50,7 @@
#include "lldb/Target/TargetList.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/State.h"
+#include "lldb/Version/Version.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
@@ -750,6 +749,9 @@ SBStructuredData SBDebugger::GetBuildConfiguration() {
AddBoolConfigEntry(
*config_up, "lua", LLDB_ENABLE_LUA,
"A boolean value that indicates if lua support is enabled in LLDB");
+ AddBoolConfigEntry(*config_up, "fbsdvmcore", LLDB_ENABLE_FBSDVMCORE,
+ "A boolean value that indicates if fbsdvmcore support is "
+ "enabled in LLDB");
AddLLVMTargets(*config_up);
SBStructuredData data;
diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp
index 7107768ba884..c6bc3288c4b2 100644
--- a/lldb/source/API/SBFrame.cpp
+++ b/lldb/source/API/SBFrame.cpp
@@ -119,15 +119,13 @@ SBSymbolContext SBFrame::GetSymbolContext(uint32_t resolve_scope) const {
std::unique_lock<std::recursive_mutex> lock;
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
SymbolContextItem scope = static_cast<SymbolContextItem>(resolve_scope);
- StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
Process *process = exe_ctx.GetProcessPtr();
if (target && process) {
Process::StopLocker stop_locker;
if (stop_locker.TryLock(&process->GetRunLock())) {
- frame = exe_ctx.GetFramePtr();
- if (frame)
- sb_sym_ctx.SetSymbolContext(&frame->GetSymbolContext(scope));
+ if (StackFrame *frame = exe_ctx.GetFramePtr())
+ sb_sym_ctx = frame->GetSymbolContext(scope);
}
}
diff --git a/lldb/source/API/SBReproducer.cpp b/lldb/source/API/SBReproducer.cpp
index 68e632da1bde..c9c9a03c694a 100644
--- a/lldb/source/API/SBReproducer.cpp
+++ b/lldb/source/API/SBReproducer.cpp
@@ -23,7 +23,7 @@
#include "lldb/API/SBHostOS.h"
#include "lldb/API/SBReproducer.h"
#include "lldb/Host/FileSystem.h"
-#include "lldb/lldb-private.h"
+#include "lldb/Version/Version.h"
using namespace lldb;
using namespace lldb_private;
@@ -165,111 +165,24 @@ const char *SBReproducer::Capture(const char *path) {
}
const char *SBReproducer::PassiveReplay(const char *path) {
- static std::string error;
- if (auto e = Reproducer::Initialize(ReproducerMode::PassiveReplay,
- FileSpec(path))) {
- error = llvm::toString(std::move(e));
- return error.c_str();
- }
-
- if (auto *l = lldb_private::repro::Reproducer::Instance().GetLoader()) {
- FileSpec file = l->GetFile<SBProvider::Info>();
- auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath());
- if (!error_or_file) {
- error =
- "unable to read SB API data: " + error_or_file.getError().message();
- return error.c_str();
- }
- static ReplayData r(std::move(*error_or_file));
- InstrumentationData::Initialize(r.GetDeserializer(), r.GetRegistry());
- }
-
- return nullptr;
+ return "Reproducer replay has been removed";
}
const char *SBReproducer::Replay(const char *path) {
- SBReplayOptions options;
- return SBReproducer::Replay(path, options);
+ return "Reproducer replay has been removed";
}
const char *SBReproducer::Replay(const char *path, bool skip_version_check) {
- SBReplayOptions options;
- options.SetCheckVersion(!skip_version_check);
- return SBReproducer::Replay(path, options);
+ return Replay(path);
}
const char *SBReproducer::Replay(const char *path,
const SBReplayOptions &options) {
- static std::string error;
- if (auto e = Reproducer::Initialize(ReproducerMode::Replay, FileSpec(path))) {
- error = llvm::toString(std::move(e));
- return error.c_str();
- }
-
- repro::Loader *loader = repro::Reproducer::Instance().GetLoader();
- if (!loader) {
- error = "unable to get replay loader.";
- return error.c_str();
- }
-
- if (options.GetCheckVersion()) {
- llvm::Expected<std::string> version = loader->LoadBuffer<VersionProvider>();
- if (!version) {
- error = llvm::toString(version.takeError());
- return error.c_str();
- }
- if (lldb_private::GetVersion() != llvm::StringRef(*version).rtrim()) {
- error = "reproducer capture and replay version don't match:\n";
- error.append("reproducer captured with:\n");
- error.append(*version);
- error.append("reproducer replayed with:\n");
- error.append(lldb_private::GetVersion());
- return error.c_str();
- }
- }
-
- if (options.GetVerify()) {
- bool verification_failed = false;
- llvm::raw_string_ostream os(error);
- auto error_callback = [&](llvm::StringRef error) {
- verification_failed = true;
- os << "\nerror: " << error;
- };
-
- auto warning_callback = [&](llvm::StringRef warning) {
- verification_failed = true;
- os << "\nwarning: " << warning;
- };
-
- auto note_callback = [&](llvm::StringRef warning) {};
-
- Verifier verifier(loader);
- verifier.Verify(error_callback, warning_callback, note_callback);
-
- if (verification_failed) {
- os.flush();
- return error.c_str();
- }
- }
-
- FileSpec file = loader->GetFile<SBProvider::Info>();
- if (!file) {
- error = "unable to get replay data from reproducer.";
- return error.c_str();
- }
-
- SBRegistry registry;
- registry.Replay(file);
-
- return nullptr;
+ return Replay(path);
}
const char *SBReproducer::Finalize(const char *path) {
static std::string error;
- if (auto e = Reproducer::Initialize(ReproducerMode::Replay, FileSpec(path))) {
- error = llvm::toString(std::move(e));
- return error.c_str();
- }
repro::Loader *loader = repro::Reproducer::Instance().GetLoader();
if (!loader) {
diff --git a/lldb/source/API/SBStructuredData.cpp b/lldb/source/API/SBStructuredData.cpp
index 97a9eadcaf07..e99c6194c516 100644
--- a/lldb/source/API/SBStructuredData.cpp
+++ b/lldb/source/API/SBStructuredData.cpp
@@ -39,10 +39,10 @@ SBStructuredData::SBStructuredData(const lldb::EventSP &event_sp)
LLDB_RECORD_CONSTRUCTOR(SBStructuredData, (const lldb::EventSP &), event_sp);
}
-SBStructuredData::SBStructuredData(lldb_private::StructuredDataImpl *impl)
- : m_impl_up(impl ? impl : new StructuredDataImpl()) {
+SBStructuredData::SBStructuredData(const lldb_private::StructuredDataImpl &impl)
+ : m_impl_up(new StructuredDataImpl(impl)) {
LLDB_RECORD_CONSTRUCTOR(SBStructuredData,
- (lldb_private::StructuredDataImpl *), impl);
+ (const lldb_private::StructuredDataImpl &), impl);
}
SBStructuredData::~SBStructuredData() = default;
@@ -210,7 +210,7 @@ template <> void RegisterMethods<SBStructuredData>(Registry &R) {
LLDB_REGISTER_CONSTRUCTOR(SBStructuredData, (const lldb::SBStructuredData &));
LLDB_REGISTER_CONSTRUCTOR(SBStructuredData, (const lldb::EventSP &));
LLDB_REGISTER_CONSTRUCTOR(SBStructuredData,
- (lldb_private::StructuredDataImpl *));
+ (const lldb_private::StructuredDataImpl &));
LLDB_REGISTER_METHOD(
lldb::SBStructuredData &,
SBStructuredData, operator=,(const lldb::SBStructuredData &));
diff --git a/lldb/source/API/SBSymbolContext.cpp b/lldb/source/API/SBSymbolContext.cpp
index 488d49884903..89fe051658ff 100644
--- a/lldb/source/API/SBSymbolContext.cpp
+++ b/lldb/source/API/SBSymbolContext.cpp
@@ -22,12 +22,10 @@ SBSymbolContext::SBSymbolContext() : m_opaque_up() {
LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBSymbolContext);
}
-SBSymbolContext::SBSymbolContext(const SymbolContext *sc_ptr) : m_opaque_up() {
+SBSymbolContext::SBSymbolContext(const SymbolContext &sc)
+ : m_opaque_up(std::make_unique<SymbolContext>(sc)) {
LLDB_RECORD_CONSTRUCTOR(SBSymbolContext,
- (const lldb_private::SymbolContext *), sc_ptr);
-
- if (sc_ptr)
- m_opaque_up = std::make_unique<SymbolContext>(*sc_ptr);
+ (const lldb_private::SymbolContext &), sc);
}
SBSymbolContext::SBSymbolContext(const SBSymbolContext &rhs) : m_opaque_up() {
@@ -49,13 +47,6 @@ const SBSymbolContext &SBSymbolContext::operator=(const SBSymbolContext &rhs) {
return LLDB_RECORD_RESULT(*this);
}
-void SBSymbolContext::SetSymbolContext(const SymbolContext *sc_ptr) {
- if (sc_ptr)
- m_opaque_up = std::make_unique<SymbolContext>(*sc_ptr);
- else
- m_opaque_up->Clear(true);
-}
-
bool SBSymbolContext::IsValid() const {
LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBSymbolContext, IsValid);
return this->operator bool();
@@ -237,7 +228,7 @@ template <>
void RegisterMethods<SBSymbolContext>(Registry &R) {
LLDB_REGISTER_CONSTRUCTOR(SBSymbolContext, ());
LLDB_REGISTER_CONSTRUCTOR(SBSymbolContext,
- (const lldb_private::SymbolContext *));
+ (const lldb_private::SymbolContext &));
LLDB_REGISTER_CONSTRUCTOR(SBSymbolContext, (const lldb::SBSymbolContext &));
LLDB_REGISTER_METHOD(
const lldb::SBSymbolContext &,
diff --git a/lldb/source/API/SBSymbolContextList.cpp b/lldb/source/API/SBSymbolContextList.cpp
index 9db84dc1bf4b..70a8bbe6694c 100644
--- a/lldb/source/API/SBSymbolContextList.cpp
+++ b/lldb/source/API/SBSymbolContextList.cpp
@@ -56,9 +56,8 @@ SBSymbolContext SBSymbolContextList::GetContextAtIndex(uint32_t idx) {
SBSymbolContext sb_sc;
if (m_opaque_up) {
SymbolContext sc;
- if (m_opaque_up->GetContextAtIndex(idx, sc)) {
- sb_sc.SetSymbolContext(&sc);
- }
+ if (m_opaque_up->GetContextAtIndex(idx, sc))
+ sb_sc = sc;
}
return LLDB_RECORD_RESULT(sb_sc);
}
diff --git a/lldb/source/API/SBThreadPlan.cpp b/lldb/source/API/SBThreadPlan.cpp
index 9af673b0f3a9..99ecb321595f 100644
--- a/lldb/source/API/SBThreadPlan.cpp
+++ b/lldb/source/API/SBThreadPlan.cpp
@@ -69,8 +69,8 @@ SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name) {
Thread *thread = sb_thread.get();
if (thread)
- m_opaque_wp =
- std::make_shared<ThreadPlanPython>(*thread, class_name, nullptr);
+ m_opaque_wp = std::make_shared<ThreadPlanPython>(*thread, class_name,
+ StructuredDataImpl());
}
SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name,
@@ -82,7 +82,7 @@ SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name,
Thread *thread = sb_thread.get();
if (thread)
m_opaque_wp = std::make_shared<ThreadPlanPython>(*thread, class_name,
- args_data.m_impl_up.get());
+ *args_data.m_impl_up);
}
// Assignment operator
diff --git a/lldb/source/API/SBTypeSummary.cpp b/lldb/source/API/SBTypeSummary.cpp
index 3800ae940c70..2d7f8ef340c9 100644
--- a/lldb/source/API/SBTypeSummary.cpp
+++ b/lldb/source/API/SBTypeSummary.cpp
@@ -100,20 +100,11 @@ const lldb_private::TypeSummaryOptions &SBTypeSummaryOptions::ref() const {
}
SBTypeSummaryOptions::SBTypeSummaryOptions(
- const lldb_private::TypeSummaryOptions *lldb_object_ptr) {
+ const lldb_private::TypeSummaryOptions &lldb_object)
+ : m_opaque_up(std::make_unique<TypeSummaryOptions>(lldb_object)) {
LLDB_RECORD_CONSTRUCTOR(SBTypeSummaryOptions,
- (const lldb_private::TypeSummaryOptions *),
- lldb_object_ptr);
-
- SetOptions(lldb_object_ptr);
-}
-
-void SBTypeSummaryOptions::SetOptions(
- const lldb_private::TypeSummaryOptions *lldb_object_ptr) {
- if (lldb_object_ptr)
- m_opaque_up = std::make_unique<TypeSummaryOptions>(*lldb_object_ptr);
- else
- m_opaque_up = std::make_unique<TypeSummaryOptions>();
+ (const lldb_private::TypeSummaryOptions &),
+ lldb_object);
}
SBTypeSummary::SBTypeSummary() : m_opaque_sp() {
@@ -175,7 +166,7 @@ SBTypeSummary SBTypeSummary::CreateWithCallback(FormatCallback cb,
const TypeSummaryOptions &opt) -> bool {
SBStream stream;
SBValue sb_value(valobj.GetSP());
- SBTypeSummaryOptions options(&opt);
+ SBTypeSummaryOptions options(opt);
if (!cb(sb_value, options, stream))
return false;
stm.Write(stream.GetData(), stream.GetSize());
@@ -492,7 +483,7 @@ void RegisterMethods<SBTypeSummaryOptions>(Registry &R) {
LLDB_REGISTER_METHOD(void, SBTypeSummaryOptions, SetCapping,
(lldb::TypeSummaryCapping));
LLDB_REGISTER_CONSTRUCTOR(SBTypeSummaryOptions,
- (const lldb_private::TypeSummaryOptions *));
+ (const lldb_private::TypeSummaryOptions &));
}
template <>
diff --git a/lldb/source/API/SystemInitializerFull.cpp b/lldb/source/API/SystemInitializerFull.cpp
index cc6cb6925bd0..b01cb2ff545b 100644
--- a/lldb/source/API/SystemInitializerFull.cpp
+++ b/lldb/source/API/SystemInitializerFull.cpp
@@ -50,15 +50,8 @@ SystemInitializerFull::~SystemInitializerFull() = default;
llvm::Error SystemInitializerFull::Initialize() {
llvm::Error error = SystemInitializerCommon::Initialize();
- if (error) {
- // During active replay, the ::Initialize call is replayed like any other
- // SB API call and the return value is ignored. Since we can't intercept
- // this, we terminate here before the uninitialized debugger inevitably
- // crashes.
- if (repro::Reproducer::Instance().IsReplaying())
- llvm::report_fatal_error(std::move(error));
+ if (error)
return error;
- }
// Initialize LLVM and Clang
llvm::InitializeAllTargets();
diff --git a/lldb/source/Breakpoint/BreakpointResolverScripted.cpp b/lldb/source/Breakpoint/BreakpointResolverScripted.cpp
index 92297fbc7c4b..308c3b987f58 100644
--- a/lldb/source/Breakpoint/BreakpointResolverScripted.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolverScripted.cpp
@@ -27,10 +27,9 @@ using namespace lldb_private;
// BreakpointResolverScripted:
BreakpointResolverScripted::BreakpointResolverScripted(
const BreakpointSP &bkpt, const llvm::StringRef class_name,
- lldb::SearchDepth depth, StructuredDataImpl *args_data)
+ lldb::SearchDepth depth, const StructuredDataImpl &args_data)
: BreakpointResolver(bkpt, BreakpointResolver::PythonResolver),
- m_class_name(std::string(class_name)), m_depth(depth),
- m_args_ptr(args_data) {
+ m_class_name(std::string(class_name)), m_depth(depth), m_args(args_data) {
CreateImplementationIfNeeded(bkpt);
}
@@ -52,7 +51,7 @@ void BreakpointResolverScripted::CreateImplementationIfNeeded(
return;
m_implementation_sp = script_interp->CreateScriptedBreakpointResolver(
- m_class_name.c_str(), m_args_ptr, breakpoint_sp);
+ m_class_name.c_str(), m_args, breakpoint_sp);
}
void BreakpointResolverScripted::NotifyBreakpointSet() {
@@ -75,14 +74,12 @@ BreakpointResolverScripted::CreateFromStructuredData(
// The Python function will actually provide the search depth, this is a
// placeholder.
lldb::SearchDepth depth = lldb::eSearchDepthTarget;
-
- StructuredDataImpl *args_data_impl = new StructuredDataImpl();
+
+ StructuredDataImpl args_data_impl;
StructuredData::Dictionary *args_dict = nullptr;
- success = options_dict.GetValueForKeyAsDictionary(
- GetKey(OptionNames::ScriptArgs), args_dict);
- if (success) {
- args_data_impl->SetObjectSP(args_dict->shared_from_this());
- }
+ if (options_dict.GetValueForKeyAsDictionary(GetKey(OptionNames::ScriptArgs),
+ args_dict))
+ args_data_impl.SetObjectSP(args_dict->shared_from_this());
return new BreakpointResolverScripted(bkpt, class_name, depth,
args_data_impl);
}
@@ -94,9 +91,9 @@ BreakpointResolverScripted::SerializeToStructuredData() {
options_dict_sp->AddStringItem(GetKey(OptionNames::PythonClassName),
m_class_name);
- if (m_args_ptr->IsValid())
- options_dict_sp->AddItem(GetKey(OptionNames::ScriptArgs),
- m_args_ptr->GetObjectSP());
+ if (m_args.IsValid())
+ options_dict_sp->AddItem(GetKey(OptionNames::ScriptArgs),
+ m_args.GetObjectSP());
return WrapOptionsDict(options_dict_sp);
}
@@ -151,10 +148,6 @@ void BreakpointResolverScripted::Dump(Stream *s) const {}
lldb::BreakpointResolverSP
BreakpointResolverScripted::CopyForBreakpoint(BreakpointSP &breakpoint) {
- // FIXME: Have to make a copy of the arguments from the m_args_ptr and then
- // pass that to the new resolver.
- lldb::BreakpointResolverSP ret_sp(
- new BreakpointResolverScripted(breakpoint, m_class_name, m_depth,
- nullptr));
- return ret_sp;
+ return std::make_shared<BreakpointResolverScripted>(breakpoint, m_class_name,
+ m_depth, m_args);
}
diff --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp
index 094ce6f8558f..9df42f36fafd 100644
--- a/lldb/source/Commands/CommandObjectMemory.cpp
+++ b/lldb/source/Commands/CommandObjectMemory.cpp
@@ -716,7 +716,7 @@ protected:
if (item_byte_size == read) {
result.AppendWarningWithFormat(
"unable to find a NULL terminated string at 0x%" PRIx64
- ".Consider increasing the maximum read length.\n",
+ ". Consider increasing the maximum read length.\n",
data_addr);
--read;
break_on_no_NULL = true;
diff --git a/lldb/source/Commands/CommandObjectReproducer.cpp b/lldb/source/Commands/CommandObjectReproducer.cpp
index 01f9dc64e6f0..4db3e070df3c 100644
--- a/lldb/source/Commands/CommandObjectReproducer.cpp
+++ b/lldb/source/Commands/CommandObjectReproducer.cpp
@@ -195,10 +195,6 @@ protected:
SetError(result, std::move(e));
return result.Succeeded();
}
- } else if (r.IsReplaying()) {
- // Make this operation a NO-OP in replay mode.
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return result.Succeeded();
} else {
result.AppendErrorWithFormat("Unable to get the reproducer generator");
return false;
@@ -276,7 +272,7 @@ protected:
auto &r = Reproducer::Instance();
- if (!r.IsCapturing() && !r.IsReplaying()) {
+ if (!r.IsCapturing()) {
result.AppendError(
"forcing a crash is only supported when capturing a reproducer.");
result.SetStatus(eReturnStatusSuccessFinishNoResult);
@@ -326,15 +322,10 @@ protected:
auto &r = Reproducer::Instance();
if (r.IsCapturing()) {
result.GetOutputStream() << "Reproducer is in capture mode.\n";
- } else if (r.IsReplaying()) {
- result.GetOutputStream() << "Reproducer is in replay mode.\n";
- } else {
- result.GetOutputStream() << "Reproducer is off.\n";
- }
-
- if (r.IsCapturing() || r.IsReplaying()) {
result.GetOutputStream()
<< "Path: " << r.GetReproducerPath().GetPath() << '\n';
+ } else {
+ result.GetOutputStream() << "Reproducer is off.\n";
}
// Auto generate is hidden unless enabled because this is mostly for
diff --git a/lldb/source/Commands/CommandObjectVersion.cpp b/lldb/source/Commands/CommandObjectVersion.cpp
index 20c2d25b745c..e15faba5661e 100644
--- a/lldb/source/Commands/CommandObjectVersion.cpp
+++ b/lldb/source/Commands/CommandObjectVersion.cpp
@@ -9,7 +9,7 @@
#include "CommandObjectVersion.h"
#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/lldb-private.h"
+#include "lldb/Version/Version.h"
using namespace lldb;
using namespace lldb_private;
diff --git a/lldb/source/Core/CoreProperties.td b/lldb/source/Core/CoreProperties.td
index e48879660403..038ed00905f1 100644
--- a/lldb/source/Core/CoreProperties.td
+++ b/lldb/source/Core/CoreProperties.td
@@ -13,6 +13,26 @@ let Definition = "modulelist" in {
Global,
DefaultStringValue<"">,
Desc<"Debug info path which should be resolved while parsing, relative to the host filesystem.">;
+ def EnableLLDBIndexCache: Property<"enable-lldb-index-cache", "Boolean">,
+ Global,
+ DefaultFalse,
+ Desc<"Enable caching for debug sessions in LLDB. LLDB can cache data for each module for improved performance in subsequent debug sessions.">;
+ def LLDBIndexCachePath: Property<"lldb-index-cache-path", "FileSpec">,
+ Global,
+ DefaultStringValue<"">,
+ Desc<"The path to the LLDB index cache directory.">;
+ def LLDBIndexCacheMaxByteSize: Property<"lldb-index-cache-max-byte-size", "UInt64">,
+ Global,
+ DefaultUnsignedValue<0>,
+ Desc<"The maximum size for the LLDB index cache directory in bytes. A value over the amount of available space on the disk will be reduced to the amount of available space. A value of 0 disables the absolute size-based pruning.">;
+ def LLDBIndexCacheMaxPercent: Property<"lldb-index-cache-max-percent", "UInt64">,
+ Global,
+ DefaultUnsignedValue<0>,
+ Desc<"The maximum size for the cache directory in terms of percentage of the available space on the disk. Set to 100 to indicate no limit, 50 to indicate that the cache size will not be left over half the available disk space. A value over 100 will be reduced to 100. A value of 0 disables the percentage size-based pruning.">;
+ def LLDBIndexCacheExpirationDays: Property<"lldb-index-cache-expiration-days", "UInt64">,
+ Global,
+ DefaultUnsignedValue<7>,
+ Desc<"The expiration time in days for a file. When a file hasn't been accessed for the specified amount of days, it is removed from the cache. A value of 0 disables the expiration-based pruning.">;
}
let Definition = "debugger" in {
diff --git a/lldb/source/Core/DataFileCache.cpp b/lldb/source/Core/DataFileCache.cpp
new file mode 100644
index 000000000000..3f52b925ef46
--- /dev/null
+++ b/lldb/source/Core/DataFileCache.cpp
@@ -0,0 +1,307 @@
+//===-- DataFileCache.cpp -------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Core/DataFileCache.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleList.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/DataEncoder.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Logging.h"
+#include "llvm/Support/CachePruning.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+using namespace llvm;
+using namespace lldb_private;
+
+DataFileCache::DataFileCache(StringRef path) {
+ m_cache_dir.SetPath(path);
+
+ // Prune the cache based off of the LLDB settings each time we create a cache
+ // object.
+ ModuleListProperties &properties =
+ ModuleList::GetGlobalModuleListProperties();
+ CachePruningPolicy policy;
+ // Only scan once an hour. If we have lots of debug sessions we don't want
+ // to scan this directory too often. A timestamp file is written to the
+ // directory to ensure different processes don't scan the directory too often.
+ // This setting doesn't mean that a thread will continually scan the cache
+ // directory within this process.
+ policy.Interval = std::chrono::hours(1);
+ // Get the user settings for pruning.
+ policy.MaxSizeBytes = properties.GetLLDBIndexCacheMaxByteSize();
+ policy.MaxSizePercentageOfAvailableSpace =
+ properties.GetLLDBIndexCacheMaxPercent();
+ policy.Expiration =
+ std::chrono::hours(properties.GetLLDBIndexCacheExpirationDays() * 24);
+ pruneCache(path, policy);
+
+ // This lambda will get called when the data is gotten from the cache and
+ // also after the data was set for a given key. We only need to take
+ // ownership of the data if we are geting the data, so we use the
+ // m_take_ownership member variable to indicate if we need to take
+ // ownership.
+
+ auto add_buffer = [this](unsigned task, std::unique_ptr<llvm::MemoryBuffer> m) {
+ if (m_take_ownership)
+ m_mem_buff_up = std::move(m);
+ };
+ Expected<FileCache> cache_or_err =
+ llvm::localCache("LLDBModuleCache", "lldb-module", path, add_buffer);
+ if (cache_or_err)
+ m_cache_callback = std::move(*cache_or_err);
+ else {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES));
+ LLDB_LOG_ERROR(log, cache_or_err.takeError(),
+ "failed to create lldb index cache directory: {0}");
+ }
+}
+
+std::unique_ptr<llvm::MemoryBuffer>
+DataFileCache::GetCachedData(StringRef key) {
+ std::lock_guard<std::mutex> guard(m_mutex);
+
+ const unsigned task = 1;
+ m_take_ownership = true;
+ // If we call the "m_cache_callback" function and the data is cached, it will
+ // call the "add_buffer" lambda function from the constructor which will in
+ // turn take ownership of the member buffer that is passed to the callback and
+ // put it into a member variable.
+ Expected<AddStreamFn> add_stream_or_err = m_cache_callback(task, key);
+ m_take_ownership = false;
+ // At this point we either already called the "add_buffer" lambda with
+ // the data or we haven't. We can tell if we got the cached data by checking
+ // the add_stream function pointer value below.
+ if (add_stream_or_err) {
+ AddStreamFn &add_stream = *add_stream_or_err;
+ // If the "add_stream" is nullptr, then the data was cached and we already
+ // called the "add_buffer" lambda. If it is valid, then if we were to call
+ // the add_stream function it would cause a cache file to get generated
+ // and we would be expected to fill in the data. In this function we only
+ // want to check if the data was cached, so we don't want to call
+ // "add_stream" in this function.
+ if (!add_stream)
+ return std::move(m_mem_buff_up);
+ } else {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES));
+ LLDB_LOG_ERROR(log, add_stream_or_err.takeError(),
+ "failed to get the cache add stream callback for key: {0}");
+ }
+ // Data was not cached.
+ return std::unique_ptr<llvm::MemoryBuffer>();
+}
+
+bool DataFileCache::SetCachedData(StringRef key, llvm::ArrayRef<uint8_t> data) {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ const unsigned task = 2;
+ // If we call this function and the data is cached, it will call the
+ // add_buffer lambda function from the constructor which will ignore the
+ // data.
+ Expected<AddStreamFn> add_stream_or_err = m_cache_callback(task, key);
+ // If we reach this code then we either already called the callback with
+ // the data or we haven't. We can tell if we had the cached data by checking
+ // the CacheAddStream function pointer value below.
+ if (add_stream_or_err) {
+ AddStreamFn &add_stream = *add_stream_or_err;
+ // If the "add_stream" is nullptr, then the data was cached. If it is
+ // valid, then if we call the add_stream function with a task it will
+ // cause the file to get generated, but we only want to check if the data
+ // is cached here, so we don't want to call it here. Note that the
+ // add_buffer will also get called in this case after the data has been
+ // provided, but we won't take ownership of the memory buffer as we just
+ // want to write the data.
+ if (add_stream) {
+ Expected<std::unique_ptr<CachedFileStream>> file_or_err =
+ add_stream(task);
+ if (file_or_err) {
+ CachedFileStream *cfs = file_or_err->get();
+ cfs->OS->write((const char *)data.data(), data.size());
+ return true;
+ } else {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES));
+ LLDB_LOG_ERROR(log, file_or_err.takeError(),
+ "failed to get the cache file stream for key: {0}");
+ }
+ }
+ } else {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES));
+ LLDB_LOG_ERROR(log, add_stream_or_err.takeError(),
+ "failed to get the cache add stream callback for key: {0}");
+ }
+ return false;
+}
+
+FileSpec DataFileCache::GetCacheFilePath(llvm::StringRef key) {
+ FileSpec cache_file(m_cache_dir);
+ std::string filename("llvmcache-");
+ filename += key.str();
+ cache_file.AppendPathComponent(filename);
+ return cache_file;
+}
+
+Status DataFileCache::RemoveCacheFile(llvm::StringRef key) {
+ FileSpec cache_file = GetCacheFilePath(key);
+ FileSystem &fs = FileSystem::Instance();
+ if (!fs.Exists(cache_file))
+ return Status();
+ return fs.RemoveFile(cache_file);
+}
+
+CacheSignature::CacheSignature(lldb_private::Module *module) {
+ Clear();
+ UUID uuid = module->GetUUID();
+ if (uuid.IsValid())
+ m_uuid = uuid;
+
+ std::time_t mod_time = 0;
+ mod_time = llvm::sys::toTimeT(module->GetModificationTime());
+ if (mod_time != 0)
+ m_mod_time = mod_time;
+
+ mod_time = llvm::sys::toTimeT(module->GetObjectModificationTime());
+ if (mod_time != 0)
+ m_obj_mod_time = mod_time;
+}
+
+CacheSignature::CacheSignature(lldb_private::ObjectFile *objfile) {
+ Clear();
+ UUID uuid = objfile->GetUUID();
+ if (uuid.IsValid())
+ m_uuid = uuid;
+
+ std::time_t mod_time = 0;
+ // Grab the modification time of the object file's file. It isn't always the
+ // same as the module's file when you have a executable file as the main
+ // executable, and you have a object file for a symbol file.
+ FileSystem &fs = FileSystem::Instance();
+ mod_time = llvm::sys::toTimeT(fs.GetModificationTime(objfile->GetFileSpec()));
+ if (mod_time != 0)
+ m_mod_time = mod_time;
+
+ mod_time =
+ llvm::sys::toTimeT(objfile->GetModule()->GetObjectModificationTime());
+ if (mod_time != 0)
+ m_obj_mod_time = mod_time;
+}
+
+enum SignatureEncoding {
+ eSignatureUUID = 1u,
+ eSignatureModTime = 2u,
+ eSignatureObjectModTime = 3u,
+ eSignatureEnd = 255u,
+};
+
+bool CacheSignature::Encode(DataEncoder &encoder) {
+ if (!IsValid())
+ return false; // Invalid signature, return false!
+
+ if (m_uuid.hasValue()) {
+ llvm::ArrayRef<uint8_t> uuid_bytes = m_uuid->GetBytes();
+ encoder.AppendU8(eSignatureUUID);
+ encoder.AppendU8(uuid_bytes.size());
+ encoder.AppendData(uuid_bytes);
+ }
+ if (m_mod_time.hasValue()) {
+ encoder.AppendU8(eSignatureModTime);
+ encoder.AppendU32(*m_mod_time);
+ }
+ if (m_obj_mod_time.hasValue()) {
+ encoder.AppendU8(eSignatureObjectModTime);
+ encoder.AppendU32(*m_obj_mod_time);
+ }
+ encoder.AppendU8(eSignatureEnd);
+ return true;
+}
+
+bool CacheSignature::Decode(const DataExtractor &data,
+ lldb::offset_t *offset_ptr) {
+ Clear();
+ while (uint8_t sig_encoding = data.GetU8(offset_ptr)) {
+ switch (sig_encoding) {
+ case eSignatureUUID: {
+ const uint8_t length = data.GetU8(offset_ptr);
+ const uint8_t *bytes = (const uint8_t *)data.GetData(offset_ptr, length);
+ if (bytes != nullptr && length > 0)
+ m_uuid = UUID::fromData(llvm::ArrayRef<uint8_t>(bytes, length));
+ } break;
+ case eSignatureModTime: {
+ uint32_t mod_time = data.GetU32(offset_ptr);
+ if (mod_time > 0)
+ m_mod_time = mod_time;
+ } break;
+ case eSignatureObjectModTime: {
+ uint32_t mod_time = data.GetU32(offset_ptr);
+ if (mod_time > 0)
+ m_mod_time = mod_time;
+ } break;
+ case eSignatureEnd:
+ return true;
+ default:
+ break;
+ }
+ }
+ return false;
+}
+
+uint32_t ConstStringTable::Add(ConstString s) {
+ auto pos = m_string_to_offset.find(s);
+ if (pos != m_string_to_offset.end())
+ return pos->second;
+ const uint32_t offset = m_next_offset;
+ m_strings.push_back(s);
+ m_string_to_offset[s] = offset;
+ m_next_offset += s.GetLength() + 1;
+ return offset;
+}
+
+static const llvm::StringRef kStringTableIdentifier("STAB");
+
+bool ConstStringTable::Encode(DataEncoder &encoder) {
+ // Write an 4 character code into the stream. This will help us when decoding
+ // to make sure we find this identifier when decoding the string table to make
+ // sure we have the rigth data. It also helps to identify the string table
+ // when dumping the hex bytes in a cache file.
+ encoder.AppendData(kStringTableIdentifier);
+ size_t length_offset = encoder.GetByteSize();
+ encoder.AppendU32(0); // Total length of all strings which will be fixed up.
+ size_t strtab_offset = encoder.GetByteSize();
+ encoder.AppendU8(0); // Start the string table with with an empty string.
+ for (auto s: m_strings) {
+ // Make sure all of the offsets match up with what we handed out!
+ assert(m_string_to_offset.find(s)->second ==
+ encoder.GetByteSize() - strtab_offset);
+ // Append the C string into the encoder
+ encoder.AppendCString(s.GetStringRef());
+ }
+ // Fixup the string table length.
+ encoder.PutU32(length_offset, encoder.GetByteSize() - strtab_offset);
+ return true;
+}
+
+bool StringTableReader::Decode(const DataExtractor &data,
+ lldb::offset_t *offset_ptr) {
+ llvm::StringRef identifier((const char *)data.GetData(offset_ptr, 4), 4);
+ if (identifier != kStringTableIdentifier)
+ return false;
+ const uint32_t length = data.GetU32(offset_ptr);
+ // We always have at least one byte for the empty string at offset zero.
+ if (length == 0)
+ return false;
+ const char *bytes = (const char *)data.GetData(offset_ptr, length);
+ if (bytes == nullptr)
+ return false;
+ m_data = StringRef(bytes, length);
+ return true;
+}
+
+StringRef StringTableReader::Get(uint32_t offset) const {
+ if (offset >= m_data.size())
+ return StringRef();
+ return StringRef(m_data.data() + offset);
+}
diff --git a/lldb/source/Core/IOHandlerCursesGUI.cpp b/lldb/source/Core/IOHandlerCursesGUI.cpp
index 9122117ef5ff..60207f75b7df 100644
--- a/lldb/source/Core/IOHandlerCursesGUI.cpp
+++ b/lldb/source/Core/IOHandlerCursesGUI.cpp
@@ -1034,7 +1034,7 @@ public:
// navigates to the next or the previous field. This is particularly useful to
// do in-field validation and error setting. Fields with internal navigation
// should call this method on their fields.
- virtual void FieldDelegateExitCallback() { return; }
+ virtual void FieldDelegateExitCallback() {}
// Fields may have internal navigation, for instance, a List Field have
// multiple internal elements, which needs to be navigated. To allow for this
@@ -1055,10 +1055,10 @@ public:
virtual bool FieldDelegateOnLastOrOnlyElement() { return true; }
// Select the first element in the field if multiple elements exists.
- virtual void FieldDelegateSelectFirstElement() { return; }
+ virtual void FieldDelegateSelectFirstElement() {}
// Select the last element in the field if multiple elements exists.
- virtual void FieldDelegateSelectLastElement() { return; }
+ virtual void FieldDelegateSelectLastElement() {}
// Returns true if the field has an error, false otherwise.
virtual bool FieldDelegateHasError() { return false; }
@@ -2000,7 +2000,6 @@ public:
void FieldDelegateSelectLastElement() override {
m_selection_type = SelectionType::NewButton;
- return;
}
int GetNumberOfFields() { return m_fields.size(); }
@@ -2292,7 +2291,7 @@ public:
virtual std::string GetName() = 0;
- virtual void UpdateFieldsVisibility() { return; }
+ virtual void UpdateFieldsVisibility() {}
FieldDelegate *GetField(uint32_t field_index) {
if (field_index < m_fields.size())
@@ -3765,13 +3764,11 @@ public:
void SelectNext() {
if (m_selected_match != m_delegate_sp->GetNumberOfMatches() - 1)
m_selected_match++;
- return;
}
void SelectPrevious() {
if (m_selected_match != 0)
m_selected_match--;
- return;
}
void ExecuteCallback(Window &window) {
@@ -4608,9 +4605,7 @@ public:
virtual void TreeDelegateDrawTreeItem(TreeItem &item, Window &window) = 0;
virtual void TreeDelegateGenerateChildren(TreeItem &item) = 0;
virtual void TreeDelegateUpdateSelection(TreeItem &root, int &selection_index,
- TreeItem *&selected_item) {
- return;
- }
+ TreeItem *&selected_item) {}
// This is invoked when a tree item is selected. If true is returned, the
// views are updated.
virtual bool TreeDelegateItemSelected(TreeItem &item) = 0;
diff --git a/lldb/source/Core/Mangled.cpp b/lldb/source/Core/Mangled.cpp
index 20f4dbdb419f..c8aacdefefa2 100644
--- a/lldb/source/Core/Mangled.cpp
+++ b/lldb/source/Core/Mangled.cpp
@@ -8,9 +8,11 @@
#include "lldb/Core/Mangled.h"
+#include "lldb/Core/DataFileCache.h"
#include "lldb/Core/RichManglingContext.h"
#include "lldb/Target/Language.h"
#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/DataEncoder.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Logging.h"
#include "lldb/Utility/RegularExpression.h"
@@ -411,3 +413,111 @@ Stream &operator<<(Stream &s, const Mangled &obj) {
s << ", demangled = <error>";
return s;
}
+
+// When encoding Mangled objects we can get away with encoding as little
+// information as is required. The enumeration below helps us to efficiently
+// encode Mangled objects.
+enum MangledEncoding {
+ /// If the Mangled object has neither a mangled name or demangled name we can
+ /// encode the object with one zero byte using the Empty enumeration.
+ Empty = 0u,
+ /// If the Mangled object has only a demangled name and no mangled named, we
+ /// can encode only the demangled name.
+ DemangledOnly = 1u,
+ /// If the mangle name can calculate the demangled name (it is the
+ /// mangled/demangled counterpart), then we only need to encode the mangled
+ /// name as the demangled name can be recomputed.
+ MangledOnly = 2u,
+ /// If we have a Mangled object with two different names that are not related
+ /// then we need to save both strings. This can happen if we have a name that
+ /// isn't a true mangled name, but we want to be able to lookup a symbol by
+ /// name and type in the symbol table. We do this for Objective C symbols like
+ /// "OBJC_CLASS_$_NSValue" where the mangled named will be set to
+ /// "OBJC_CLASS_$_NSValue" and the demangled name will be manually set to
+ /// "NSValue". If we tried to demangled the name "OBJC_CLASS_$_NSValue" it
+ /// would fail, but in these cases we want these unrelated names to be
+ /// preserved.
+ MangledAndDemangled = 3u
+};
+
+bool Mangled::Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
+ const StringTableReader &strtab) {
+ m_mangled.Clear();
+ m_demangled.Clear();
+ MangledEncoding encoding = (MangledEncoding)data.GetU8(offset_ptr);
+ switch (encoding) {
+ case Empty:
+ return true;
+
+ case DemangledOnly:
+ m_demangled.SetString(strtab.Get(data.GetU32(offset_ptr)));
+ return true;
+
+ case MangledOnly:
+ m_mangled.SetString(strtab.Get(data.GetU32(offset_ptr)));
+ return true;
+
+ case MangledAndDemangled:
+ m_mangled.SetString(strtab.Get(data.GetU32(offset_ptr)));
+ m_demangled.SetString(strtab.Get(data.GetU32(offset_ptr)));
+ return true;
+ }
+ return false;
+}
+/// The encoding format for the Mangled object is as follows:
+///
+/// uint8_t encoding;
+/// char str1[]; (only if DemangledOnly, MangledOnly)
+/// char str2[]; (only if MangledAndDemangled)
+///
+/// The strings are stored as NULL terminated UTF8 strings and str1 and str2
+/// are only saved if we need them based on the encoding.
+///
+/// Some mangled names have a mangled name that can be demangled by the built
+/// in demanglers. These kinds of mangled objects know when the mangled and
+/// demangled names are the counterparts for each other. This is done because
+/// demangling is very expensive and avoiding demangling the same name twice
+/// saves us a lot of compute time. For these kinds of names we only need to
+/// save the mangled name and have the encoding set to "MangledOnly".
+///
+/// If a mangled obejct has only a demangled name, then we save only that string
+/// and have the encoding set to "DemangledOnly".
+///
+/// Some mangled objects have both mangled and demangled names, but the
+/// demangled name can not be computed from the mangled name. This is often used
+/// for runtime named, like Objective C runtime V2 and V3 names. Both these
+/// names must be saved and the encoding is set to "MangledAndDemangled".
+///
+/// For a Mangled object with no names, we only need to set the encoding to
+/// "Empty" and not store any string values.
+void Mangled::Encode(DataEncoder &file, ConstStringTable &strtab) const {
+ MangledEncoding encoding = Empty;
+ if (m_mangled) {
+ encoding = MangledOnly;
+ if (m_demangled) {
+ // We have both mangled and demangled names. If the demangled name is the
+ // counterpart of the mangled name, then we only need to save the mangled
+ // named. If they are different, we need to save both.
+ ConstString s;
+ if (!(m_mangled.GetMangledCounterpart(s) && s == m_demangled))
+ encoding = MangledAndDemangled;
+ }
+ } else if (m_demangled) {
+ encoding = DemangledOnly;
+ }
+ file.AppendU8(encoding);
+ switch (encoding) {
+ case Empty:
+ break;
+ case DemangledOnly:
+ file.AppendU32(strtab.Add(m_demangled));
+ break;
+ case MangledOnly:
+ file.AppendU32(strtab.Add(m_mangled));
+ break;
+ case MangledAndDemangled:
+ file.AppendU32(strtab.Add(m_mangled));
+ file.AppendU32(strtab.Add(m_demangled));
+ break;
+ }
+}
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index cbecbb9aa5fe..feecf984f7bf 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -10,6 +10,7 @@
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/AddressResolverFileLine.h"
+#include "lldb/Core/DataFileCache.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/FileSpecList.h"
#include "lldb/Core/Mangled.h"
@@ -55,7 +56,10 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DJB.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/JSON.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/raw_ostream.h"
@@ -233,8 +237,8 @@ Module::Module(const ModuleSpec &module_spec)
Module::Module(const FileSpec &file_spec, const ArchSpec &arch,
const ConstString *object_name, lldb::offset_t object_offset,
const llvm::sys::TimePoint<> &object_mod_time)
- : m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)), m_arch(arch),
- m_file(file_spec), m_object_offset(object_offset),
+ : m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)),
+ m_arch(arch), m_file(file_spec), m_object_offset(object_offset),
m_object_mod_time(object_mod_time), m_file_has_changed(false),
m_first_file_changed_log(false) {
// Scope for locker below...
@@ -559,9 +563,8 @@ uint32_t Module::ResolveSymbolContextForAddress(
// that the symbol has been resolved.
if (so_addr.GetOffset() ==
addr_range.GetBaseAddress().GetOffset() ||
- so_addr.GetOffset() ==
- addr_range.GetBaseAddress().GetOffset() +
- addr_range.GetByteSize()) {
+ so_addr.GetOffset() == addr_range.GetBaseAddress().GetOffset() +
+ addr_range.GetByteSize()) {
resolved_flags |= flags;
}
} else {
@@ -765,8 +768,7 @@ void Module::LookupInfo::Prune(SymbolContextList &sc_list,
// pull anything out
ConstString mangled_name(sc.GetFunctionName(Mangled::ePreferMangled));
ConstString full_name(sc.GetFunctionName());
- if (mangled_name != m_name && full_name != m_name)
- {
+ if (mangled_name != m_name && full_name != m_name) {
CPlusPlusLanguage::MethodName cpp_method(full_name);
if (cpp_method.IsValid()) {
if (cpp_method.GetContext().empty()) {
@@ -940,7 +942,6 @@ void Module::FindTypes_Impl(
size_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap &types) {
- LLDB_SCOPED_TIMER();
if (SymbolFile *symbols = GetSymbolFile())
symbols->FindTypes(name, parent_decl_ctx, max_matches,
searched_symbol_files, types);
@@ -960,8 +961,8 @@ void Module::FindTypesInNamespace(ConstString type_name,
}
}
-lldb::TypeSP Module::FindFirstType(const SymbolContext &sc,
- ConstString name, bool exact_match) {
+lldb::TypeSP Module::FindFirstType(const SymbolContext &sc, ConstString name,
+ bool exact_match) {
TypeList type_list;
llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
FindTypes(name, exact_match, 1, searched_symbol_files, type_list);
@@ -1332,9 +1333,8 @@ void Module::SymbolIndicesToSymbolContextList(
}
}
-void Module::FindFunctionSymbols(ConstString name,
- uint32_t name_type_mask,
- SymbolContextList &sc_list) {
+void Module::FindFunctionSymbols(ConstString name, uint32_t name_type_mask,
+ SymbolContextList &sc_list) {
LLDB_SCOPED_TIMERF("Module::FindSymbolsFunctions (name = %s, mask = 0x%8.8x)",
name.AsCString(), name_type_mask);
if (Symtab *symtab = GetSymtab())
@@ -1342,13 +1342,10 @@ void Module::FindFunctionSymbols(ConstString name,
}
void Module::FindSymbolsWithNameAndType(ConstString name,
- SymbolType symbol_type,
- SymbolContextList &sc_list) {
+ SymbolType symbol_type,
+ SymbolContextList &sc_list) {
// No need to protect this call using m_mutex all other method calls are
// already thread safe.
- LLDB_SCOPED_TIMERF(
- "Module::FindSymbolsWithNameAndType (name = %s, type = %i)",
- name.AsCString(), symbol_type);
if (Symtab *symtab = GetSymtab()) {
std::vector<uint32_t> symbol_indexes;
symtab->FindAllSymbolsWithNameAndType(name, symbol_type, symbol_indexes);
@@ -1608,14 +1605,16 @@ bool Module::FindSourceFile(const FileSpec &orig_spec,
return false;
}
-llvm::Optional<std::string> Module::RemapSourceFile(llvm::StringRef path) const {
+llvm::Optional<std::string>
+Module::RemapSourceFile(llvm::StringRef path) const {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (auto remapped = m_source_mappings.RemapPath(path))
return remapped->GetPath();
return {};
}
-void Module::RegisterXcodeSDK(llvm::StringRef sdk_name, llvm::StringRef sysroot) {
+void Module::RegisterXcodeSDK(llvm::StringRef sdk_name,
+ llvm::StringRef sysroot) {
XcodeSDK sdk(sdk_name.str());
llvm::StringRef sdk_path(HostInfo::GetXcodeSDKPath(sdk));
if (sdk_path.empty())
@@ -1661,3 +1660,36 @@ bool Module::GetIsDynamicLinkEditor() {
return false;
}
+
+uint32_t Module::Hash() {
+ std::string identifier;
+ llvm::raw_string_ostream id_strm(identifier);
+ id_strm << m_arch.GetTriple().str() << '-' << m_file.GetPath();
+ if (m_object_name)
+ id_strm << '(' << m_object_name.GetStringRef() << ')';
+ if (m_object_offset > 0)
+ id_strm << m_object_offset;
+ const auto mtime = llvm::sys::toTimeT(m_object_mod_time);
+ if (mtime > 0)
+ id_strm << mtime;
+ return llvm::djbHash(id_strm.str());
+}
+
+std::string Module::GetCacheKey() {
+ std::string key;
+ llvm::raw_string_ostream strm(key);
+ strm << m_arch.GetTriple().str() << '-' << m_file.GetFilename();
+ if (m_object_name)
+ strm << '(' << m_object_name.GetStringRef() << ')';
+ strm << '-' << llvm::format_hex(Hash(), 10);
+ return strm.str();
+}
+
+DataFileCache *Module::GetIndexCache() {
+ if (!ModuleList::GetGlobalModuleListProperties().GetEnableLLDBIndexCache())
+ return nullptr;
+ // NOTE: intentional leak so we don't crash if global destructor chain gets
+ // called as other threads still use the result of this function
+ static DataFileCache *g_data_file_cache = new DataFileCache(ModuleList::GetGlobalModuleListProperties().GetLLDBIndexCachePath().GetPath());
+ return g_data_file_cache;
+}
diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp
index 9176c9dbb357..48412137546d 100644
--- a/lldb/source/Core/ModuleList.cpp
+++ b/lldb/source/Core/ModuleList.cpp
@@ -85,6 +85,14 @@ ModuleListProperties::ModuleListProperties() {
if (clang::driver::Driver::getDefaultModuleCachePath(path)) {
lldbassert(SetClangModulesCachePath(FileSpec(path)));
}
+
+ path.clear();
+ if (llvm::sys::path::cache_directory(path)) {
+ llvm::sys::path::append(path, "lldb");
+ llvm::sys::path::append(path, "IndexCache");
+ lldbassert(SetLLDBIndexCachePath(FileSpec(path)));
+ }
+
}
bool ModuleListProperties::GetEnableExternalLookup() const {
@@ -110,6 +118,47 @@ bool ModuleListProperties::SetClangModulesCachePath(const FileSpec &path) {
nullptr, ePropertyClangModulesCachePath, path);
}
+FileSpec ModuleListProperties::GetLLDBIndexCachePath() const {
+ return m_collection_sp
+ ->GetPropertyAtIndexAsOptionValueFileSpec(nullptr, false,
+ ePropertyLLDBIndexCachePath)
+ ->GetCurrentValue();
+}
+
+bool ModuleListProperties::SetLLDBIndexCachePath(const FileSpec &path) {
+ return m_collection_sp->SetPropertyAtIndexAsFileSpec(
+ nullptr, ePropertyLLDBIndexCachePath, path);
+}
+
+bool ModuleListProperties::GetEnableLLDBIndexCache() const {
+ const uint32_t idx = ePropertyEnableLLDBIndexCache;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_modulelist_properties[idx].default_uint_value != 0);
+}
+
+bool ModuleListProperties::SetEnableLLDBIndexCache(bool new_value) {
+ return m_collection_sp->SetPropertyAtIndexAsBoolean(
+ nullptr, ePropertyEnableLLDBIndexCache, new_value);
+}
+
+uint64_t ModuleListProperties::GetLLDBIndexCacheMaxByteSize() {
+ const uint32_t idx = ePropertyLLDBIndexCacheMaxByteSize;
+ return m_collection_sp->GetPropertyAtIndexAsUInt64(
+ nullptr, idx, g_modulelist_properties[idx].default_uint_value);
+}
+
+uint64_t ModuleListProperties::GetLLDBIndexCacheMaxPercent() {
+ const uint32_t idx = ePropertyLLDBIndexCacheMaxPercent;
+ return m_collection_sp->GetPropertyAtIndexAsUInt64(
+ nullptr, idx, g_modulelist_properties[idx].default_uint_value);
+}
+
+uint64_t ModuleListProperties::GetLLDBIndexCacheExpirationDays() {
+ const uint32_t idx = ePropertyLLDBIndexCacheExpirationDays;
+ return m_collection_sp->GetPropertyAtIndexAsUInt64(
+ nullptr, idx, g_modulelist_properties[idx].default_uint_value);
+}
+
void ModuleListProperties::UpdateSymlinkMappings() {
FileSpecList list = m_collection_sp
->GetPropertyAtIndexAsOptionValueFileSpecList(
diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp
index 801591129244..37050494aa2e 100644
--- a/lldb/source/Core/PluginManager.cpp
+++ b/lldb/source/Core/PluginManager.cpp
@@ -1345,6 +1345,12 @@ REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) {
return GetREPLInstances().GetCallbackAtIndex(idx);
}
+LanguageSet PluginManager::GetREPLSupportedLanguagesAtIndex(uint32_t idx) {
+ const auto &instances = GetREPLInstances().GetInstances();
+ return idx < instances.size() ? instances[idx].supported_languages
+ : LanguageSet();
+}
+
LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() {
const auto &instances = GetREPLInstances().GetInstances();
LanguageSet all;
diff --git a/lldb/source/DataFormatters/CXXFunctionPointer.cpp b/lldb/source/DataFormatters/CXXFunctionPointer.cpp
index 3b7b0bc27cf8..d7df280e56ef 100644
--- a/lldb/source/DataFormatters/CXXFunctionPointer.cpp
+++ b/lldb/source/DataFormatters/CXXFunctionPointer.cpp
@@ -9,6 +9,7 @@
#include "lldb/DataFormatters/CXXFunctionPointer.h"
#include "lldb/Core/ValueObject.h"
+#include "lldb/Target/ABI.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/Stream.h"
@@ -38,8 +39,34 @@ bool lldb_private::formatters::CXXFunctionPointerSummaryProvider(
Address so_addr;
Target *target = exe_ctx.GetTargetPtr();
if (target && !target->GetSectionLoadList().IsEmpty()) {
- if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address,
- so_addr)) {
+ target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address,
+ so_addr);
+ if (so_addr.GetSection() == nullptr) {
+ // If we have an address that doesn't correspond to any symbol,
+ // it might have authentication bits. Strip them & see if it
+ // now points to a symbol -- if so, do the SymbolContext lookup
+ // based on the stripped address.
+ // If we find a symbol with the ptrauth bits stripped, print the
+ // raw value into the stream, and replace the Address with the
+ // one that points to a symbol for a fuller description.
+ if (Process *process = exe_ctx.GetProcessPtr()) {
+ if (ABISP abi_sp = process->GetABI()) {
+ addr_t fixed_addr = abi_sp->FixCodeAddress(func_ptr_address);
+ if (fixed_addr != func_ptr_address) {
+ Address test_address;
+ test_address.SetLoadAddress(fixed_addr, target);
+ if (test_address.GetSection() != nullptr) {
+ int addrsize = target->GetArchitecture().GetAddressByteSize();
+ sstr.Printf("actual=0x%*.*" PRIx64 " ", addrsize * 2,
+ addrsize * 2, fixed_addr);
+ so_addr = test_address;
+ }
+ }
+ }
+ }
+ }
+
+ if (so_addr.IsValid()) {
so_addr.Dump(&sstr, exe_ctx.GetBestExecutionContextScope(),
Address::DumpStyleResolvedDescription,
Address::DumpStyleSectionNameOffset);
diff --git a/lldb/source/DataFormatters/FormatManager.cpp b/lldb/source/DataFormatters/FormatManager.cpp
index cda1ae60d857..0ef5f0adc832 100644
--- a/lldb/source/DataFormatters/FormatManager.cpp
+++ b/lldb/source/DataFormatters/FormatManager.cpp
@@ -724,15 +724,14 @@ void FormatManager::LoadSystemFormatters() {
lldb::TypeSummaryImplSP string_array_format(
new StringSummaryFormat(string_array_flags, "${var%char[]}"));
- RegularExpression any_size_char_arr(llvm::StringRef("char ?\\[[0-9]+\\]"));
+ RegularExpression any_size_char_arr(R"(^((un)?signed )?char ?\[[0-9]+\]$)");
TypeCategoryImpl::SharedPointer sys_category_sp =
GetCategory(m_system_category_name);
- sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("char *"),
- string_format);
- sys_category_sp->GetTypeSummariesContainer()->Add(
- ConstString("unsigned char *"), string_format);
+ sys_category_sp->GetRegexTypeSummariesContainer()->Add(
+ RegularExpression(R"(^((un)?signed )?char ?(\*|\[\])$)"), string_format);
+
sys_category_sp->GetRegexTypeSummariesContainer()->Add(
std::move(any_size_char_arr), string_array_format);
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index a10546c1deae..890d8b5d3107 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -460,22 +460,19 @@ bool DWARFExpression::Update_DW_OP_addr(lldb::addr_t file_addr) {
// first, then modify it, and if all goes well, we then replace the data
// for this expression
- // So first we copy the data into a heap buffer
- std::unique_ptr<DataBufferHeap> head_data_up(
- new DataBufferHeap(m_data.GetDataStart(), m_data.GetByteSize()));
-
- // Make en encoder so we can write the address into the buffer using the
- // correct byte order (endianness)
- DataEncoder encoder(head_data_up->GetBytes(), head_data_up->GetByteSize(),
+ // Make en encoder that contains a copy of the location expression data
+ // so we can write the address into the buffer using the correct byte
+ // order.
+ DataEncoder encoder(m_data.GetDataStart(), m_data.GetByteSize(),
m_data.GetByteOrder(), addr_byte_size);
// Replace the address in the new buffer
- if (encoder.PutUnsigned(offset, addr_byte_size, file_addr) == UINT32_MAX)
+ if (encoder.PutAddress(offset, file_addr) == UINT32_MAX)
return false;
// All went well, so now we can reset the data using a shared pointer to
// the heap data so "m_data" will now correctly manage the heap data.
- m_data.SetData(DataBufferSP(head_data_up.release()));
+ m_data.SetData(encoder.GetDataBuffer());
return true;
} else {
const offset_t op_arg_size = GetOpcodeDataSize(m_data, offset, op);
@@ -521,15 +518,11 @@ bool DWARFExpression::LinkThreadLocalStorage(
// We have to make a copy of the data as we don't know if this data is from a
// read only memory mapped buffer, so we duplicate all of the data first,
// then modify it, and if all goes well, we then replace the data for this
- // expression
-
- // So first we copy the data into a heap buffer
- std::shared_ptr<DataBufferHeap> heap_data_sp(
- new DataBufferHeap(m_data.GetDataStart(), m_data.GetByteSize()));
+ // expression.
- // Make en encoder so we can write the address into the buffer using the
- // correct byte order (endianness)
- DataEncoder encoder(heap_data_sp->GetBytes(), heap_data_sp->GetByteSize(),
+ // Make en encoder that contains a copy of the location expression data so we
+ // can write the address into the buffer using the correct byte order.
+ DataEncoder encoder(m_data.GetDataStart(), m_data.GetByteSize(),
m_data.GetByteOrder(), addr_byte_size);
lldb::offset_t offset = 0;
@@ -603,7 +596,7 @@ bool DWARFExpression::LinkThreadLocalStorage(
// and read the
// TLS data
m_module_wp = new_module_sp;
- m_data.SetData(heap_data_sp);
+ m_data.SetData(encoder.GetDataBuffer());
return true;
}
@@ -2817,4 +2810,3 @@ bool DWARFExpression::MatchesOperand(StackFrame &frame,
return MatchRegOp(*reg)(operand);
}
}
-
diff --git a/lldb/source/Expression/IRExecutionUnit.cpp b/lldb/source/Expression/IRExecutionUnit.cpp
index f2d22f7ed9cc..3c4a87c27e20 100644
--- a/lldb/source/Expression/IRExecutionUnit.cpp
+++ b/lldb/source/Expression/IRExecutionUnit.cpp
@@ -483,8 +483,6 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
func_addr = m_function_load_addr;
func_end = m_function_end_load_addr;
-
- return;
}
IRExecutionUnit::~IRExecutionUnit() {
diff --git a/lldb/source/Expression/IRMemoryMap.cpp b/lldb/source/Expression/IRMemoryMap.cpp
index 4ae2724d4dd8..9eee5cf5b9a2 100644
--- a/lldb/source/Expression/IRMemoryMap.cpp
+++ b/lldb/source/Expression/IRMemoryMap.cpp
@@ -609,7 +609,6 @@ void IRMemoryMap::WriteScalarToMemory(lldb::addr_t process_address,
error.SetErrorToGenericError();
error.SetErrorString("Couldn't write scalar: its size was zero");
}
- return;
}
void IRMemoryMap::WritePointerToMemory(lldb::addr_t process_address,
@@ -757,7 +756,6 @@ void IRMemoryMap::ReadScalarFromMemory(Scalar &scalar,
error.SetErrorToGenericError();
error.SetErrorString("Couldn't read scalar: its size was zero");
}
- return;
}
void IRMemoryMap::ReadPointerFromMemory(lldb::addr_t *address,
@@ -773,8 +771,6 @@ void IRMemoryMap::ReadPointerFromMemory(lldb::addr_t *address,
return;
*address = pointer_scalar.ULongLong();
-
- return;
}
void IRMemoryMap::GetMemoryData(DataExtractor &extractor,
diff --git a/lldb/source/Expression/REPL.cpp b/lldb/source/Expression/REPL.cpp
index 9cd6129eedd7..be41c60ebb5f 100644
--- a/lldb/source/Expression/REPL.cpp
+++ b/lldb/source/Expression/REPL.cpp
@@ -39,7 +39,11 @@ lldb::REPLSP REPL::Create(Status &err, lldb::LanguageType language,
lldb::REPLSP ret;
while (REPLCreateInstance create_instance =
- PluginManager::GetREPLCreateCallbackAtIndex(idx++)) {
+ PluginManager::GetREPLCreateCallbackAtIndex(idx)) {
+ LanguageSet supported_languages =
+ PluginManager::GetREPLSupportedLanguagesAtIndex(idx++);
+ if (!supported_languages[language])
+ continue;
ret = (*create_instance)(err, language, debugger, target, repl_options);
if (ret) {
break;
diff --git a/lldb/source/Expression/UserExpression.cpp b/lldb/source/Expression/UserExpression.cpp
index b61781c0b82b..692594b03f16 100644
--- a/lldb/source/Expression/UserExpression.cpp
+++ b/lldb/source/Expression/UserExpression.cpp
@@ -254,9 +254,7 @@ UserExpression::Evaluate(ExecutionContext &exe_ctx,
if (fixed_expression == nullptr)
fixed_expression = &tmp_fixed_expression;
- const char *fixed_text = user_expression_sp->GetFixedText();
- if (fixed_text != nullptr)
- fixed_expression->append(fixed_text);
+ *fixed_expression = user_expression_sp->GetFixedText().str();
// If there is a fixed expression, try to parse it:
if (!parse_success) {
@@ -265,8 +263,7 @@ UserExpression::Evaluate(ExecutionContext &exe_ctx,
user_expression_sp.reset();
execution_results = lldb::eExpressionParseError;
- if (fixed_expression && !fixed_expression->empty() &&
- options.GetAutoApplyFixIts()) {
+ if (!fixed_expression->empty() && options.GetAutoApplyFixIts()) {
const uint64_t max_fix_retries = options.GetRetriesWithFixIts();
for (uint64_t i = 0; i < max_fix_retries; ++i) {
// Try parsing the fixed expression.
@@ -285,8 +282,8 @@ UserExpression::Evaluate(ExecutionContext &exe_ctx,
} else {
// The fixed expression also didn't parse. Let's check for any new
// Fix-Its we could try.
- if (fixed_expression_sp->GetFixedText()) {
- *fixed_expression = fixed_expression_sp->GetFixedText();
+ if (!fixed_expression_sp->GetFixedText().empty()) {
+ *fixed_expression = fixed_expression_sp->GetFixedText().str();
} else {
// Fixed expression didn't compile without a fixit, don't retry and
// don't tell the user about it.
diff --git a/lldb/source/Host/common/FileSystem.cpp b/lldb/source/Host/common/FileSystem.cpp
index 7687ad6c20a6..1e4a24abe301 100644
--- a/lldb/source/Host/common/FileSystem.cpp
+++ b/lldb/source/Host/common/FileSystem.cpp
@@ -513,3 +513,11 @@ void FileSystem::Collect(const llvm::Twine &file) {
void FileSystem::SetHomeDirectory(std::string home_directory) {
m_home_directory = std::move(home_directory);
}
+
+Status FileSystem::RemoveFile(const FileSpec &file_spec) {
+ return RemoveFile(file_spec.GetPath());
+}
+
+Status FileSystem::RemoveFile(const llvm::Twine &path) {
+ return Status(llvm::sys::fs::remove(path));
+}
diff --git a/lldb/source/Host/common/ProcessLaunchInfo.cpp b/lldb/source/Host/common/ProcessLaunchInfo.cpp
index 8d281b80e8f0..07e4f15c9e9e 100644
--- a/lldb/source/Host/common/ProcessLaunchInfo.cpp
+++ b/lldb/source/Host/common/ProcessLaunchInfo.cpp
@@ -212,6 +212,14 @@ void ProcessLaunchInfo::SetDetachOnError(bool enable) {
llvm::Error ProcessLaunchInfo::SetUpPtyRedirection() {
Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS);
+
+ bool stdin_free = GetFileActionForFD(STDIN_FILENO) == nullptr;
+ bool stdout_free = GetFileActionForFD(STDOUT_FILENO) == nullptr;
+ bool stderr_free = GetFileActionForFD(STDERR_FILENO) == nullptr;
+ bool any_free = stdin_free || stdout_free || stderr_free;
+ if (!any_free)
+ return llvm::Error::success();
+
LLDB_LOG(log, "Generating a pty to use for stdin/out/err");
int open_flags = O_RDWR | O_NOCTTY;
@@ -226,19 +234,13 @@ llvm::Error ProcessLaunchInfo::SetUpPtyRedirection() {
const FileSpec secondary_file_spec(m_pty->GetSecondaryName());
- // Only use the secondary tty if we don't have anything specified for
- // input and don't have an action for stdin
- if (GetFileActionForFD(STDIN_FILENO) == nullptr)
+ if (stdin_free)
AppendOpenFileAction(STDIN_FILENO, secondary_file_spec, true, false);
- // Only use the secondary tty if we don't have anything specified for
- // output and don't have an action for stdout
- if (GetFileActionForFD(STDOUT_FILENO) == nullptr)
+ if (stdout_free)
AppendOpenFileAction(STDOUT_FILENO, secondary_file_spec, false, true);
- // Only use the secondary tty if we don't have anything specified for
- // error and don't have an action for stderr
- if (GetFileActionForFD(STDERR_FILENO) == nullptr)
+ if (stderr_free)
AppendOpenFileAction(STDERR_FILENO, secondary_file_spec, false, true);
return llvm::Error::success();
}
diff --git a/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp b/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp
index 63178e6c8a7a..2f08b9fa8857 100644
--- a/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp
+++ b/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp
@@ -86,7 +86,6 @@ static void DupDescriptor(int error_fd, const FileSpec &file_spec, int fd,
ExitWithError(error_fd, "DupDescriptor-dup2");
::close(target_fd);
- return;
}
[[noreturn]] static void ChildFunc(int error_fd,
diff --git a/lldb/source/Initialization/SystemInitializerCommon.cpp b/lldb/source/Initialization/SystemInitializerCommon.cpp
index 84c5a472332a..1c8406f68784 100644
--- a/lldb/source/Initialization/SystemInitializerCommon.cpp
+++ b/lldb/source/Initialization/SystemInitializerCommon.cpp
@@ -15,7 +15,7 @@
#include "lldb/Utility/Log.h"
#include "lldb/Utility/ReproducerProvider.h"
#include "lldb/Utility/Timer.h"
-#include "lldb/lldb-private.h"
+#include "lldb/Version/Version.h"
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp
index 301bf949feef..bd03f18b47c0 100644
--- a/lldb/source/Interpreter/CommandInterpreter.cpp
+++ b/lldb/source/Interpreter/CommandInterpreter.cpp
@@ -2216,7 +2216,6 @@ void CommandInterpreter::BuildAliasCommandArgs(CommandObject *alias_cmd_obj,
}
result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return;
}
int CommandInterpreter::GetOptionArgumentPosition(const char *in_string) {
@@ -2563,8 +2562,6 @@ void CommandInterpreter::HandleCommands(const StringList &commands,
result.SetStatus(eReturnStatusSuccessFinishResult);
m_debugger.SetAsyncExecution(old_async_execution);
-
- return;
}
// Make flags that we can pass into the IOHandler so our delegates can do the
diff --git a/lldb/source/Interpreter/CommandReturnObject.cpp b/lldb/source/Interpreter/CommandReturnObject.cpp
index 506b0d6e7cde..1b1e6996764c 100644
--- a/lldb/source/Interpreter/CommandReturnObject.cpp
+++ b/lldb/source/Interpreter/CommandReturnObject.cpp
@@ -120,13 +120,13 @@ void CommandReturnObject::AppendRawError(llvm::StringRef in_string) {
void CommandReturnObject::SetStatus(ReturnStatus status) { m_status = status; }
-ReturnStatus CommandReturnObject::GetStatus() { return m_status; }
+ReturnStatus CommandReturnObject::GetStatus() const { return m_status; }
-bool CommandReturnObject::Succeeded() {
+bool CommandReturnObject::Succeeded() const {
return m_status <= eReturnStatusSuccessContinuingResult;
}
-bool CommandReturnObject::HasResult() {
+bool CommandReturnObject::HasResult() const {
return (m_status == eReturnStatusSuccessFinishResult ||
m_status == eReturnStatusSuccessContinuingResult);
}
@@ -145,7 +145,7 @@ void CommandReturnObject::Clear() {
m_interactive = true;
}
-bool CommandReturnObject::GetDidChangeProcessState() {
+bool CommandReturnObject::GetDidChangeProcessState() const {
return m_did_change_process_state;
}
diff --git a/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
index ccfbeec3d589..804532acf9f7 100644
--- a/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
+++ b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
@@ -817,6 +817,16 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl(
lldb::addr_t ABIMacOSX_arm64::FixAddress(addr_t pc, addr_t mask) {
lldb::addr_t pac_sign_extension = 0x0080000000000000ULL;
+ // Darwin systems originally couldn't determine the proper value
+ // dynamically, so the most common value was hardcoded. This has
+ // largely been cleaned up, but there are still a handful of
+ // environments that assume the default value is set to this value
+ // and there's no dynamic value to correct it.
+ // When no mask is specified, set it to 39 bits of addressing (0..38).
+ if (mask == 0) {
+ // ~((1ULL<<39)-1)
+ mask = 0xffffff8000000000;
+ }
return (pc & pac_sign_extension) ? pc | mask : pc & (~mask);
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
index 85e2fcfc838c..7844f27139cf 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
@@ -211,7 +211,7 @@ bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body,
Stmt **last_stmt_ptr = Body->body_end() - 1;
Stmt *last_stmt = *last_stmt_ptr;
- while (dyn_cast<NullStmt>(last_stmt)) {
+ while (isa<NullStmt>(last_stmt)) {
if (last_stmt_ptr != Body->body_begin()) {
last_stmt_ptr--;
last_stmt = *last_stmt_ptr;
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
index 80469e292580..6ed3cc9384f0 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
@@ -293,7 +293,7 @@ public:
NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to);
// Check if we already completed this type.
- if (m_decls_already_completed.count(to_named_decl) != 0)
+ if (m_decls_already_completed.contains(to_named_decl))
return;
// Queue this type to be completed.
m_decls_to_complete.insert(to_named_decl);
@@ -806,7 +806,7 @@ void ClangASTImporter::ForgetSource(clang::ASTContext *dst_ast,
md->removeOriginsWithContext(src_ast);
}
-ClangASTImporter::MapCompleter::~MapCompleter() { return; }
+ClangASTImporter::MapCompleter::~MapCompleter() {}
llvm::Expected<Decl *>
ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) {
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
index 410d8a95cb12..510352e8c173 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
@@ -513,8 +513,6 @@ void ClangASTSource::FindExternalLexicalDecls(
// is consulted again when a clang::DeclContext::lookup is called.
const_cast<DeclContext *>(decl_context)->setMustBuildLookupTable();
}
-
- return;
}
void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
index 3afd1fd5f2d1..f3fec3f944a1 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
@@ -59,7 +59,7 @@ public:
GetExternalCXXBaseSpecifiers(uint64_t Offset) override {
return nullptr;
}
- void MaterializeVisibleDecls(const clang::DeclContext *DC) { return; }
+ void MaterializeVisibleDecls(const clang::DeclContext *DC) {}
void InstallASTContext(TypeSystemClang &ast_context);
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index 846c1597292b..4af5d41a5921 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -1954,8 +1954,6 @@ void ClangExpressionDeclMap::AddContextClassType(NameSearchContext &context,
return;
context.AddNamedDecl(typedef_decl);
-
- return;
}
void ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp b/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
index a6e36d81b950..8b132b54b7e6 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
@@ -353,7 +353,7 @@ protected:
}
bool InspectInstruction(llvm::Instruction &i) override {
- if (dyn_cast<llvm::LoadInst>(&i) || dyn_cast<llvm::StoreInst>(&i))
+ if (isa<llvm::LoadInst>(&i) || isa<llvm::StoreInst>(&i))
RegisterInstruction(i);
return true;
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
index f80dc2b14467..e0e41925f7ef 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
@@ -1255,7 +1255,7 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
m_decl_map->AddValueToStruct(named_decl, lldb_private::ConstString(name),
llvm_value_ptr, *value_size,
value_alignment);
- } else if (dyn_cast<llvm::Function>(llvm_value_ptr)) {
+ } else if (isa<llvm::Function>(llvm_value_ptr)) {
LLDB_LOG(log, "Function pointers aren't handled right now");
return false;
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index f1925990e94a..df61cc3853eb 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -35,6 +35,7 @@
#include "BlockPointer.h"
#include "CPlusPlusNameParser.h"
#include "CxxStringTypes.h"
+#include "Generic.h"
#include "LibCxx.h"
#include "LibCxxAtomic.h"
#include "LibCxxVariant.h"
@@ -655,7 +656,7 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"libc++ std::tuple synthetic children",
ConstString("^std::__[[:alnum:]]+::tuple<.*>(( )?&)?$"),
stl_synth_flags, true);
- AddCXXSynthetic(cpp_category_sp, LibcxxOptionalFrontEndCreator,
+ AddCXXSynthetic(cpp_category_sp, LibcxxOptionalSyntheticFrontEndCreator,
"libc++ std::optional synthetic children",
ConstString("^std::__[[:alnum:]]+::optional<.+>(( )?&)?$"),
stl_synth_flags, true);
@@ -772,7 +773,7 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
ConstString("^std::__[[:alnum:]]+::atomic<.+>$"),
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
- lldb_private::formatters::LibcxxOptionalSummaryProvider,
+ lldb_private::formatters::GenericOptionalSummaryProvider,
"libc++ std::optional summary provider",
ConstString("^std::__[[:alnum:]]+::optional<.+>(( )?&)?$"),
stl_summary_flags, true);
@@ -904,6 +905,11 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
stl_synth_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
+ RegularExpression("^std::deque<.+>(( )?&)?$"),
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ stl_deref_flags,
+ "lldb.formatters.cpp.gnu_libstdcpp.StdDequeSynthProvider")));
+ cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
RegularExpression("^std::set<.+> >(( )?&)?$"),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_deref_flags,
@@ -914,11 +920,6 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
stl_deref_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
- RegularExpression("^std::optional<.+>(( )?&)?$"),
- SyntheticChildrenSP(new ScriptedSyntheticChildren(
- stl_synth_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdOptionalSynthProvider")));
- cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
RegularExpression("^std::multiset<.+> >(( )?&)?$"),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_deref_flags,
@@ -931,7 +932,7 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$"),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
- stl_synth_flags,
+ stl_deref_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
RegularExpression("^std::(__cxx11::)?forward_list<.+>(( )?&)?$"),
@@ -942,11 +943,6 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
stl_summary_flags.SetDontShowChildren(false);
stl_summary_flags.SetSkipPointers(false);
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
- RegularExpression("^std::optional<.+>(( )?&)?$"),
- TypeSummaryImplSP(new ScriptSummaryFormat(
- stl_summary_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdOptionalSummaryProvider")));
- cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
RegularExpression("^std::bitset<.+>(( )?&)?$"),
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
@@ -963,6 +959,10 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
+ RegularExpression("^std::deque<.+>(( )?&)?$"),
+ TypeSummaryImplSP(
+ new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
+ cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
RegularExpression("^std::multimap<.+> >(( )?&)?$"),
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
@@ -1022,6 +1022,12 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"std::bitset synthetic child", ConstString("^std::bitset<.+>(( )?&)?$"),
stl_deref_flags, true);
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibStdcppOptionalSyntheticFrontEndCreator,
+ "std::optional synthetic child",
+ ConstString("^std::optional<.+>(( )?&)?$"), stl_deref_flags, true);
+
AddCXXSummary(cpp_category_sp,
lldb_private::formatters::LibStdcppUniquePointerSummaryProvider,
"libstdc++ std::unique_ptr summary provider",
@@ -1037,6 +1043,10 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"libstdc++ std::weak_ptr summary provider",
ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_summary_flags,
true);
+ AddCXXSummary(
+ cpp_category_sp, lldb_private::formatters::GenericOptionalSummaryProvider,
+ "libstd++ std::optional summary provider",
+ ConstString("^std::optional<.+>(( )?&)?$"), stl_summary_flags, true);
}
static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
diff --git a/lldb/source/Plugins/Language/CPlusPlus/Generic.h b/lldb/source/Plugins/Language/CPlusPlus/Generic.h
new file mode 100644
index 000000000000..bfb28bebf90b
--- /dev/null
+++ b/lldb/source/Plugins/Language/CPlusPlus/Generic.h
@@ -0,0 +1,25 @@
+//===-- LibCxx.h -----------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_GENERIC_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_GENERIC_H
+
+#include "lldb/Core/ValueObject.h"
+#include "lldb/DataFormatters/TypeSummary.h"
+#include "lldb/Utility/Stream.h"
+
+namespace lldb_private {
+namespace formatters {
+
+bool GenericOptionalSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+} // namespace formatters
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_GENERIC_H
diff --git a/lldb/source/Plugins/Language/CPlusPlus/GenericOptional.cpp b/lldb/source/Plugins/Language/CPlusPlus/GenericOptional.cpp
new file mode 100644
index 000000000000..74b3f711de35
--- /dev/null
+++ b/lldb/source/Plugins/Language/CPlusPlus/GenericOptional.cpp
@@ -0,0 +1,139 @@
+//===-- GenericOptional.cpp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===---------------------------------------------------------------------===//
+
+#include "Generic.h"
+#include "LibCxx.h"
+#include "LibStdcpp.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+bool lldb_private::formatters::GenericOptionalSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ stream.Printf(" Has Value=%s ",
+ valobj.GetNumChildren() == 0 ? "false" : "true");
+
+ return true;
+}
+
+// Synthetic Children Provider
+namespace {
+
+class GenericOptionalFrontend : public SyntheticChildrenFrontEnd {
+public:
+ enum class StdLib {
+ LibCxx,
+ LibStdcpp,
+ };
+
+ GenericOptionalFrontend(ValueObject &valobj, StdLib stdlib);
+
+ size_t GetIndexOfChildWithName(ConstString name) override {
+ return formatters::ExtractIndexFromString(name.GetCString());
+ }
+
+ bool MightHaveChildren() override { return true; }
+ size_t CalculateNumChildren() override { return m_has_value ? 1U : 0U; }
+
+ ValueObjectSP GetChildAtIndex(size_t idx) override;
+ bool Update() override;
+
+private:
+ bool m_has_value = false;
+ StdLib m_stdlib;
+};
+
+} // namespace
+
+GenericOptionalFrontend::GenericOptionalFrontend(ValueObject &valobj,
+ StdLib stdlib)
+ : SyntheticChildrenFrontEnd(valobj), m_stdlib(stdlib) {
+ if (auto target_sp = m_backend.GetTargetSP()) {
+ Update();
+ }
+}
+
+bool GenericOptionalFrontend::Update() {
+ ValueObjectSP engaged_sp;
+
+ if (m_stdlib == StdLib::LibCxx)
+ engaged_sp =
+ m_backend.GetChildMemberWithName(ConstString("__engaged_"), true);
+ else if (m_stdlib == StdLib::LibStdcpp)
+ engaged_sp =
+ m_backend.GetChildMemberWithName(ConstString("_M_payload"), true)
+ ->GetChildMemberWithName(ConstString("_M_engaged"), true);
+
+ if (!engaged_sp)
+ return false;
+
+ // _M_engaged/__engaged is a bool flag and is true if the optional contains a
+ // value. Converting it to unsigned gives us a size of 1 if it contains a
+ // value and 0 if not.
+ m_has_value = engaged_sp->GetValueAsUnsigned(0) != 0;
+
+ return false;
+}
+
+ValueObjectSP GenericOptionalFrontend::GetChildAtIndex(size_t _idx) {
+ if (!m_has_value)
+ return ValueObjectSP();
+
+ ValueObjectSP val_sp;
+
+ if (m_stdlib == StdLib::LibCxx)
+ // __val_ contains the underlying value of an optional if it has one.
+ // Currently because it is part of an anonymous union
+ // GetChildMemberWithName() does not peer through and find it unless we are
+ // at the parent itself. We can obtain the parent through __engaged_.
+ val_sp = m_backend.GetChildMemberWithName(ConstString("__engaged_"), true)
+ ->GetParent()
+ ->GetChildAtIndex(0, true)
+ ->GetChildMemberWithName(ConstString("__val_"), true);
+ else if (m_stdlib == StdLib::LibStdcpp) {
+ val_sp = m_backend.GetChildMemberWithName(ConstString("_M_payload"), true)
+ ->GetChildMemberWithName(ConstString("_M_payload"), true);
+
+ // In some implementations, _M_value contains the underlying value of an
+ // optional, and in other versions, it's in the payload member.
+ ValueObjectSP candidate =
+ val_sp->GetChildMemberWithName(ConstString("_M_value"), true);
+ if (candidate)
+ val_sp = candidate;
+ }
+
+ if (!val_sp)
+ return ValueObjectSP();
+
+ CompilerType holder_type = val_sp->GetCompilerType();
+
+ if (!holder_type)
+ return ValueObjectSP();
+
+ return val_sp->Clone(ConstString("Value"));
+}
+
+SyntheticChildrenFrontEnd *
+formatters::LibStdcppOptionalSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ if (valobj_sp)
+ return new GenericOptionalFrontend(
+ *valobj_sp, GenericOptionalFrontend::StdLib::LibStdcpp);
+ return nullptr;
+}
+
+SyntheticChildrenFrontEnd *formatters::LibcxxOptionalSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ if (valobj_sp)
+ return new GenericOptionalFrontend(*valobj_sp,
+ GenericOptionalFrontend::StdLib::LibCxx);
+ return nullptr;
+}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
index 99e206543197..80dc71787ceb 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -170,8 +170,8 @@ SyntheticChildrenFrontEnd *LibcxxTupleFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
SyntheticChildrenFrontEnd *
-LibcxxOptionalFrontEndCreator(CXXSyntheticChildren *,
- lldb::ValueObjectSP valobj_sp);
+LibcxxOptionalSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP valobj_sp);
SyntheticChildrenFrontEnd *
LibcxxVariantFrontEndCreator(CXXSyntheticChildren *,
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
deleted file mode 100644
index c1b40ba65e7d..000000000000
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-//===-- LibCxxOptional.cpp ------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "LibCxx.h"
-#include "lldb/DataFormatters/FormattersHelpers.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-
-class OptionalFrontEnd : public SyntheticChildrenFrontEnd {
-public:
- OptionalFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) {
- Update();
- }
-
- size_t GetIndexOfChildWithName(ConstString name) override {
- return formatters::ExtractIndexFromString(name.GetCString());
- }
-
- bool MightHaveChildren() override { return true; }
- bool Update() override;
- size_t CalculateNumChildren() override { return m_has_value ? 1U : 0U; }
- ValueObjectSP GetChildAtIndex(size_t idx) override;
-
-private:
- /// True iff the option contains a value.
- bool m_has_value = false;
-};
-} // namespace
-
-bool OptionalFrontEnd::Update() {
- ValueObjectSP engaged_sp(
- m_backend.GetChildMemberWithName(ConstString("__engaged_"), true));
-
- if (!engaged_sp)
- return false;
-
- // __engaged_ is a bool flag and is true if the optional contains a value.
- // Converting it to unsigned gives us a size of 1 if it contains a value
- // and 0 if not.
- m_has_value = engaged_sp->GetValueAsUnsigned(0) != 0;
-
- return false;
-}
-
-ValueObjectSP OptionalFrontEnd::GetChildAtIndex(size_t idx) {
- if (!m_has_value)
- return ValueObjectSP();
-
- // __val_ contains the underlying value of an optional if it has one.
- // Currently because it is part of an anonymous union GetChildMemberWithName()
- // does not peer through and find it unless we are at the parent itself.
- // We can obtain the parent through __engaged_.
- ValueObjectSP val_sp(
- m_backend.GetChildMemberWithName(ConstString("__engaged_"), true)
- ->GetParent()
- ->GetChildAtIndex(0, true)
- ->GetChildMemberWithName(ConstString("__val_"), true));
-
- if (!val_sp)
- return ValueObjectSP();
-
- CompilerType holder_type = val_sp->GetCompilerType();
-
- if (!holder_type)
- return ValueObjectSP();
-
- return val_sp->Clone(ConstString("Value"));
-}
-
-SyntheticChildrenFrontEnd *
-formatters::LibcxxOptionalFrontEndCreator(CXXSyntheticChildren *,
- lldb::ValueObjectSP valobj_sp) {
- if (valobj_sp)
- return new OptionalFrontEnd(*valobj_sp);
- return nullptr;
-}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h
index b6f9c469fedd..1c1c8fdb9ea4 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h
@@ -46,6 +46,10 @@ LibStdcppBitsetSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
SyntheticChildrenFrontEnd *
+LibStdcppOptionalSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *
LibStdcppVectorIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
index 9bc40c16e5d0..af11109ae45d 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
@@ -80,8 +80,6 @@ public:
LLDB_LOG(log, " AOEAS::CT Before:\n{1}", ClangUtil::DumpDecl(tag_decl));
LLDB_LOG(log, " AOEAS::CT After:{1}", ClangUtil::DumpDecl(tag_decl));
-
- return;
}
void CompleteType(clang::ObjCInterfaceDecl *interface_decl) override {
@@ -107,7 +105,6 @@ public:
LLDB_LOGF(log, " [CT] After:");
LLDB_LOG(log, " [CT] {0}", ClangUtil::DumpDecl(interface_decl));
}
- return;
}
bool layoutRecordType(
diff --git a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index 719109c863e7..1d989b268b74 100644
--- a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -589,6 +589,8 @@ PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx,
result_ptr->image_ptr = dlopen(name, RTLD_LAZY);
if (result_ptr->image_ptr)
result_ptr->error_str = nullptr;
+ else
+ result_ptr->error_str = dlerror();
return nullptr;
}
diff --git a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp
index 90c290b6fbc7..67c9484680a4 100644
--- a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp
+++ b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp
@@ -47,6 +47,27 @@ public:
return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr,
ePropertyEmulatorPath);
}
+
+ Args GetEmulatorArgs() {
+ Args result;
+ m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, ePropertyEmulatorArgs,
+ result);
+ return result;
+ }
+
+ Environment GetEmulatorEnvVars() {
+ Args args;
+ m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, ePropertyEmulatorEnvVars,
+ args);
+ return Environment(args);
+ }
+
+ Environment GetTargetEnvVars() {
+ Args args;
+ m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, ePropertyTargetEnvVars,
+ args);
+ return Environment(args);
+ }
};
static PluginProperties &GetGlobalProperties() {
@@ -98,6 +119,44 @@ static auto get_arg_range(const Args &args) {
args.GetArgumentArrayRef().end());
}
+// Returns the emulator environment which result in the desired environment
+// being presented to the emulated process. We want to be careful about
+// preserving the host environment, as it may contain entries (LD_LIBRARY_PATH,
+// for example) needed for the operation of the emulator itself.
+static Environment ComputeLaunchEnvironment(Environment target,
+ Environment host) {
+ std::vector<std::string> set_env;
+ for (const auto &KV : target) {
+ // If the host value differs from the target (or is unset), then set it
+ // through QEMU_SET_ENV. Identical entries will be forwarded automatically.
+ auto host_it = host.find(KV.first());
+ if (host_it == host.end() || host_it->second != KV.second)
+ set_env.push_back(Environment::compose(KV));
+ }
+ llvm::sort(set_env);
+
+ std::vector<llvm::StringRef> unset_env;
+ for (const auto &KV : host) {
+ // If the target is missing some host entries, then unset them through
+ // QEMU_UNSET_ENV.
+ if (target.count(KV.first()) == 0)
+ unset_env.push_back(KV.first());
+ }
+ llvm::sort(unset_env);
+
+ // The actual QEMU_(UN)SET_ENV variables should not be forwarded to the
+ // target.
+ if (!set_env.empty()) {
+ host["QEMU_SET_ENV"] = llvm::join(set_env, ",");
+ unset_env.push_back("QEMU_SET_ENV");
+ }
+ if (!unset_env.empty()) {
+ unset_env.push_back("QEMU_UNSET_ENV");
+ host["QEMU_UNSET_ENV"] = llvm::join(unset_env, ",");
+ }
+ return host;
+}
+
lldb::ProcessSP PlatformQemuUser::DebugProcess(ProcessLaunchInfo &launch_info,
Debugger &debugger,
Target &target, Status &error) {
@@ -112,8 +171,10 @@ lldb::ProcessSP PlatformQemuUser::DebugProcess(ProcessLaunchInfo &launch_info,
llvm::sys::fs::createUniquePath(socket_model, socket_path, false);
} while (FileSystem::Instance().Exists(socket_path));
- Args args(
- {qemu, "-g", socket_path, launch_info.GetExecutableFile().GetPath()});
+ Args args({qemu, "-g", socket_path});
+ args.AppendArguments(GetGlobalProperties().GetEmulatorArgs());
+ args.AppendArgument("--");
+ args.AppendArgument(launch_info.GetExecutableFile().GetPath());
for (size_t i = 1; i < launch_info.GetArguments().size(); ++i)
args.AppendArgument(launch_info.GetArguments()[i].ref());
@@ -121,11 +182,23 @@ lldb::ProcessSP PlatformQemuUser::DebugProcess(ProcessLaunchInfo &launch_info,
get_arg_range(args));
launch_info.SetArguments(args, true);
+
+ Environment emulator_env = Host::GetEnvironment();
+ for (const auto &KV : GetGlobalProperties().GetEmulatorEnvVars())
+ emulator_env[KV.first()] = KV.second;
+ launch_info.GetEnvironment() = ComputeLaunchEnvironment(
+ std::move(launch_info.GetEnvironment()), std::move(emulator_env));
+
launch_info.SetLaunchInSeparateProcessGroup(true);
launch_info.GetFlags().Clear(eLaunchFlagDebug);
launch_info.SetMonitorProcessCallback(ProcessLaunchInfo::NoOpMonitorCallback,
false);
+ // This is automatically done for host platform in
+ // Target::FinalizeFileActions, but we're not a host platform.
+ llvm::Error Err = launch_info.SetUpPtyRedirection();
+ LLDB_LOG_ERROR(log, std::move(Err), "SetUpPtyRedirection failed: {0}");
+
error = Host::LaunchProcess(launch_info);
if (error.Fail())
return nullptr;
@@ -134,6 +207,7 @@ lldb::ProcessSP PlatformQemuUser::DebugProcess(ProcessLaunchInfo &launch_info,
launch_info.GetListener(),
process_gdb_remote::ProcessGDBRemote::GetPluginNameStatic(), nullptr,
true);
+
ListenerSP listener_sp =
Listener::MakeListener("lldb.platform_qemu_user.debugprocess");
launch_info.SetHijackListener(listener_sp);
@@ -143,6 +217,18 @@ lldb::ProcessSP PlatformQemuUser::DebugProcess(ProcessLaunchInfo &launch_info,
if (error.Fail())
return nullptr;
+ if (launch_info.GetPTY().GetPrimaryFileDescriptor() !=
+ PseudoTerminal::invalid_fd)
+ process_sp->SetSTDIOFileDescriptor(
+ launch_info.GetPTY().ReleasePrimaryFileDescriptor());
+
process_sp->WaitForProcessToStop(llvm::None, nullptr, false, listener_sp);
return process_sp;
}
+
+Environment PlatformQemuUser::GetEnvironment() {
+ Environment env = Host::GetEnvironment();
+ for (const auto &KV : GetGlobalProperties().GetTargetEnvVars())
+ env[KV.first()] = KV.second;
+ return env;
+}
diff --git a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h
index f4f5d224a8cd..71df1b7b7811 100644
--- a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h
+++ b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h
@@ -45,7 +45,7 @@ public:
void CalculateTrapHandlerSymbolNames() override {}
- Environment GetEnvironment() override { return Host::GetEnvironment(); }
+ Environment GetEnvironment() override;
private:
static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
diff --git a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td
index abfab7f59de4..4e8fbcfd6760 100644
--- a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td
+++ b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td
@@ -9,4 +9,16 @@ let Definition = "platformqemuuser" in {
Global,
DefaultStringValue<"">,
Desc<"Path to the emulator binary.">;
+ def EmulatorArgs: Property<"emulator-args", "Args">,
+ Global,
+ DefaultStringValue<"">,
+ Desc<"Extra arguments to pass to the emulator.">;
+ def EmulatorEnvVars: Property<"emulator-env-vars", "Dictionary">,
+ Global,
+ ElementType<"String">,
+ Desc<"Extra variables to add to the emulator environment.">;
+ def TargetEnvVars: Property<"target-env-vars", "Dictionary">,
+ Global,
+ ElementType<"String">,
+ Desc<"Extra variables to add to emulated target environment.">;
}
diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 987f7c7f57e7..3535a5ad739d 100644
--- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -225,18 +225,12 @@ Status PlatformRemoteGDBServer::ConnectRemote(Args &args) {
m_platform_hostname = parsed_url->hostname.str();
m_gdb_client.SetConnection(std::make_unique<ConnectionFileDescriptor>());
- if (repro::Reproducer::Instance().IsReplaying()) {
- error = m_gdb_replay_server.Connect(m_gdb_client);
- if (error.Success())
- m_gdb_replay_server.StartAsyncThread();
- } else {
- if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
- repro::GDBRemoteProvider &provider =
- g->GetOrCreate<repro::GDBRemoteProvider>();
- m_gdb_client.SetPacketRecorder(provider.GetNewPacketRecorder());
- }
- m_gdb_client.Connect(url, &error);
+ if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
+ repro::GDBRemoteProvider &provider =
+ g->GetOrCreate<repro::GDBRemoteProvider>();
+ m_gdb_client.SetPacketRecorder(provider.GetNewPacketRecorder());
}
+ m_gdb_client.Connect(url, &error);
if (error.Fail())
return error;
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
new file mode 100644
index 000000000000..339d33d25110
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
@@ -0,0 +1,218 @@
+//===-- ProcessFreeBSDKernel.cpp ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Target/DynamicLoader.h"
+
+#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
+#include "ProcessFreeBSDKernel.h"
+#include "ThreadFreeBSDKernel.h"
+
+#if LLDB_ENABLE_FBSDVMCORE
+#include <fvc.h>
+#endif
+#if defined(__FreeBSD__)
+#include <kvm.h>
+#endif
+
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE(ProcessFreeBSDKernel)
+
+namespace {
+
+#if LLDB_ENABLE_FBSDVMCORE
+class ProcessFreeBSDKernelFVC : public ProcessFreeBSDKernel {
+public:
+ ProcessFreeBSDKernelFVC(lldb::TargetSP target_sp, lldb::ListenerSP listener,
+ fvc_t *fvc);
+
+ ~ProcessFreeBSDKernelFVC();
+
+ size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ lldb_private::Status &error) override;
+
+private:
+ fvc_t *m_fvc;
+
+ const char *GetError();
+};
+#endif // LLDB_ENABLE_FBSDVMCORE
+
+#if defined(__FreeBSD__)
+class ProcessFreeBSDKernelKVM : public ProcessFreeBSDKernel {
+public:
+ ProcessFreeBSDKernelKVM(lldb::TargetSP target_sp, lldb::ListenerSP listener,
+ kvm_t *fvc);
+
+ ~ProcessFreeBSDKernelKVM();
+
+ size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ lldb_private::Status &error) override;
+
+private:
+ kvm_t *m_kvm;
+
+ const char *GetError();
+};
+#endif // defined(__FreeBSD__)
+
+} // namespace
+
+ProcessFreeBSDKernel::ProcessFreeBSDKernel(lldb::TargetSP target_sp,
+ ListenerSP listener_sp)
+ : PostMortemProcess(target_sp, listener_sp) {}
+
+lldb::ProcessSP ProcessFreeBSDKernel::CreateInstance(lldb::TargetSP target_sp,
+ ListenerSP listener_sp,
+ const FileSpec *crash_file,
+ bool can_connect) {
+ ModuleSP executable = target_sp->GetExecutableModule();
+ if (crash_file && !can_connect && executable) {
+#if LLDB_ENABLE_FBSDVMCORE
+ fvc_t *fvc =
+ fvc_open(executable->GetFileSpec().GetPath().c_str(),
+ crash_file->GetPath().c_str(), nullptr, nullptr, nullptr);
+ if (fvc)
+ return std::make_shared<ProcessFreeBSDKernelFVC>(target_sp, listener_sp,
+ fvc);
+#endif
+
+#if defined(__FreeBSD__)
+ kvm_t *kvm =
+ kvm_open2(executable->GetFileSpec().GetPath().c_str(),
+ crash_file->GetPath().c_str(), O_RDONLY, nullptr, nullptr);
+ if (kvm)
+ return std::make_shared<ProcessFreeBSDKernelKVM>(target_sp, listener_sp,
+ kvm);
+#endif
+ }
+ return nullptr;
+}
+
+void ProcessFreeBSDKernel::Initialize() {
+ static llvm::once_flag g_once_flag;
+
+ llvm::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+ });
+}
+
+void ProcessFreeBSDKernel::Terminate() {
+ PluginManager::UnregisterPlugin(ProcessFreeBSDKernel::CreateInstance);
+}
+
+Status ProcessFreeBSDKernel::DoDestroy() { return Status(); }
+
+bool ProcessFreeBSDKernel::CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) {
+ return true;
+}
+
+void ProcessFreeBSDKernel::RefreshStateAfterStop() {}
+
+bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
+ if (old_thread_list.GetSize(false) == 0) {
+ // Make up the thread the first time this is called so we can set our one
+ // and only core thread state up.
+
+ // We cannot construct a thread without a register context as that crashes
+ // LLDB but we can construct a process without threads to provide minimal
+ // memory reading support.
+ switch (GetTarget().GetArchitecture().GetMachine()) {
+ case llvm::Triple::aarch64:
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ break;
+ default:
+ return false;
+ }
+
+ const Symbol *pcb_sym =
+ GetTarget().GetExecutableModule()->FindFirstSymbolWithNameAndType(
+ ConstString("dumppcb"));
+ ThreadSP thread_sp(new ThreadFreeBSDKernel(
+ *this, 1, pcb_sym ? pcb_sym->GetFileAddress() : LLDB_INVALID_ADDRESS));
+ new_thread_list.AddThread(thread_sp);
+ } else {
+ const uint32_t num_threads = old_thread_list.GetSize(false);
+ for (uint32_t i = 0; i < num_threads; ++i)
+ new_thread_list.AddThread(old_thread_list.GetThreadAtIndex(i, false));
+ }
+ return new_thread_list.GetSize(false) > 0;
+}
+
+Status ProcessFreeBSDKernel::DoLoadCore() {
+ // The core is already loaded by CreateInstance().
+ return Status();
+}
+
+DynamicLoader *ProcessFreeBSDKernel::GetDynamicLoader() {
+ if (m_dyld_up.get() == nullptr)
+ m_dyld_up.reset(DynamicLoader::FindPlugin(
+ this, DynamicLoaderStatic::GetPluginNameStatic()));
+ return m_dyld_up.get();
+}
+
+#if LLDB_ENABLE_FBSDVMCORE
+
+ProcessFreeBSDKernelFVC::ProcessFreeBSDKernelFVC(lldb::TargetSP target_sp,
+ ListenerSP listener_sp,
+ fvc_t *fvc)
+ : ProcessFreeBSDKernel(target_sp, listener_sp), m_fvc(fvc) {}
+
+ProcessFreeBSDKernelFVC::~ProcessFreeBSDKernelFVC() {
+ if (m_fvc)
+ fvc_close(m_fvc);
+}
+
+size_t ProcessFreeBSDKernelFVC::DoReadMemory(lldb::addr_t addr, void *buf,
+ size_t size, Status &error) {
+ ssize_t rd = 0;
+ rd = fvc_read(m_fvc, addr, buf, size);
+ if (rd < 0 || static_cast<size_t>(rd) != size) {
+ error.SetErrorStringWithFormat("Reading memory failed: %s", GetError());
+ return rd > 0 ? rd : 0;
+ }
+ return rd;
+}
+
+const char *ProcessFreeBSDKernelFVC::GetError() { return fvc_geterr(m_fvc); }
+
+#endif // LLDB_ENABLE_FBSDVMCORE
+
+#if defined(__FreeBSD__)
+
+ProcessFreeBSDKernelKVM::ProcessFreeBSDKernelKVM(lldb::TargetSP target_sp,
+ ListenerSP listener_sp,
+ kvm_t *fvc)
+ : ProcessFreeBSDKernel(target_sp, listener_sp), m_kvm(fvc) {}
+
+ProcessFreeBSDKernelKVM::~ProcessFreeBSDKernelKVM() {
+ if (m_kvm)
+ kvm_close(m_kvm);
+}
+
+size_t ProcessFreeBSDKernelKVM::DoReadMemory(lldb::addr_t addr, void *buf,
+ size_t size, Status &error) {
+ ssize_t rd = 0;
+ rd = kvm_read2(m_kvm, addr, buf, size);
+ if (rd < 0 || static_cast<size_t>(rd) != size) {
+ error.SetErrorStringWithFormat("Reading memory failed: %s", GetError());
+ return rd > 0 ? rd : 0;
+ }
+ return rd;
+}
+
+const char *ProcessFreeBSDKernelKVM::GetError() { return kvm_geterr(m_kvm); }
+
+#endif // defined(__FreeBSD__)
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
new file mode 100644
index 000000000000..558eec5403db
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
@@ -0,0 +1,51 @@
+//===-- ProcessFreeBSDKernel.h ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_PROCESSFREEBSDKERNEL_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_PROCESSFREEBSDKERNEL_H
+
+#include "lldb/Target/PostMortemProcess.h"
+
+class ProcessFreeBSDKernel : public lldb_private::PostMortemProcess {
+public:
+ ProcessFreeBSDKernel(lldb::TargetSP target_sp, lldb::ListenerSP listener);
+
+ static lldb::ProcessSP
+ CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener,
+ const lldb_private::FileSpec *crash_file_path,
+ bool can_connect);
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static llvm::StringRef GetPluginNameStatic() { return "freebsd-kernel"; }
+
+ static llvm::StringRef GetPluginDescriptionStatic() {
+ return "FreeBSD kernel vmcore debugging plug-in.";
+ }
+
+ llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+
+ lldb_private::Status DoDestroy() override;
+
+ bool CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) override;
+
+ void RefreshStateAfterStop() override;
+
+ lldb_private::Status DoLoadCore() override;
+
+ lldb_private::DynamicLoader *GetDynamicLoader() override;
+
+protected:
+ bool DoUpdateThreadList(lldb_private::ThreadList &old_thread_list,
+ lldb_private::ThreadList &new_thread_list) override;
+};
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_PROCESSFREEBSDKERNEL_H
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.cpp
new file mode 100644
index 000000000000..11843ddc82d9
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.cpp
@@ -0,0 +1,110 @@
+//===-- RegisterContextFreeBSDKernel_arm64.cpp ----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "RegisterContextFreeBSDKernel_arm64.h"
+#include "Plugins/Process/Utility/lldb-arm64-register-enums.h"
+
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "llvm/Support/Endian.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+RegisterContextFreeBSDKernel_arm64::RegisterContextFreeBSDKernel_arm64(
+ Thread &thread, std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up,
+ lldb::addr_t pcb_addr)
+ : RegisterContextPOSIX_arm64(thread, std::move(register_info_up)),
+ m_pcb_addr(pcb_addr) {}
+
+bool RegisterContextFreeBSDKernel_arm64::ReadGPR() { return true; }
+
+bool RegisterContextFreeBSDKernel_arm64::ReadFPR() { return true; }
+
+bool RegisterContextFreeBSDKernel_arm64::WriteGPR() {
+ assert(0);
+ return false;
+}
+
+bool RegisterContextFreeBSDKernel_arm64::WriteFPR() {
+ assert(0);
+ return false;
+}
+
+bool RegisterContextFreeBSDKernel_arm64::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ if (m_pcb_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ struct {
+ llvm::support::ulittle64_t x[30];
+ llvm::support::ulittle64_t lr;
+ llvm::support::ulittle64_t _reserved;
+ llvm::support::ulittle64_t sp;
+ } pcb;
+
+ Status error;
+ size_t rd =
+ m_thread.GetProcess()->ReadMemory(m_pcb_addr, &pcb, sizeof(pcb), error);
+ if (rd != sizeof(pcb))
+ return false;
+
+ uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ switch (reg) {
+ case gpr_x0_arm64:
+ case gpr_x1_arm64:
+ case gpr_x2_arm64:
+ case gpr_x3_arm64:
+ case gpr_x4_arm64:
+ case gpr_x5_arm64:
+ case gpr_x6_arm64:
+ case gpr_x7_arm64:
+ case gpr_x8_arm64:
+ case gpr_x9_arm64:
+ case gpr_x10_arm64:
+ case gpr_x11_arm64:
+ case gpr_x12_arm64:
+ case gpr_x13_arm64:
+ case gpr_x14_arm64:
+ case gpr_x15_arm64:
+ case gpr_x16_arm64:
+ case gpr_x17_arm64:
+ case gpr_x18_arm64:
+ case gpr_x19_arm64:
+ case gpr_x20_arm64:
+ case gpr_x21_arm64:
+ case gpr_x22_arm64:
+ case gpr_x23_arm64:
+ case gpr_x24_arm64:
+ case gpr_x25_arm64:
+ case gpr_x26_arm64:
+ case gpr_x27_arm64:
+ case gpr_x28_arm64:
+ case gpr_fp_arm64:
+ static_assert(gpr_fp_arm64 - gpr_x0_arm64 == 29,
+ "nonconsecutive arm64 register numbers");
+ value = pcb.x[reg - gpr_x0_arm64];
+ break;
+ case gpr_sp_arm64:
+ value = pcb.sp;
+ break;
+ case gpr_pc_arm64:
+ // The pc of crashing thread is stored in lr.
+ value = pcb.lr;
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+bool RegisterContextFreeBSDKernel_arm64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ return false;
+}
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.h b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.h
new file mode 100644
index 000000000000..155dda6e748f
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.h
@@ -0,0 +1,41 @@
+//===-- RegisterContextFreeBSDKernel_arm64.h --------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_ARM64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_ARM64_H
+
+#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
+
+class RegisterContextFreeBSDKernel_arm64 : public RegisterContextPOSIX_arm64 {
+public:
+ RegisterContextFreeBSDKernel_arm64(
+ lldb_private::Thread &thread,
+ std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up,
+ lldb::addr_t pcb_addr);
+
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
+
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
+
+protected:
+ bool ReadGPR() override;
+
+ bool ReadFPR() override;
+
+ bool WriteGPR() override;
+
+ bool WriteFPR() override;
+
+private:
+ lldb::addr_t m_pcb_addr;
+};
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_ARM64_H
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.cpp
new file mode 100644
index 000000000000..fde85c9c9f0d
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.cpp
@@ -0,0 +1,83 @@
+//===-- RegisterContextFreeBSDKernel_i386.cpp -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "RegisterContextFreeBSDKernel_i386.h"
+
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "llvm/Support/Endian.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+RegisterContextFreeBSDKernel_i386::RegisterContextFreeBSDKernel_i386(
+ Thread &thread, RegisterInfoInterface *register_info, lldb::addr_t pcb_addr)
+ : RegisterContextPOSIX_x86(thread, 0, register_info), m_pcb_addr(pcb_addr) {
+}
+
+bool RegisterContextFreeBSDKernel_i386::ReadGPR() { return true; }
+
+bool RegisterContextFreeBSDKernel_i386::ReadFPR() { return true; }
+
+bool RegisterContextFreeBSDKernel_i386::WriteGPR() {
+ assert(0);
+ return false;
+}
+
+bool RegisterContextFreeBSDKernel_i386::WriteFPR() {
+ assert(0);
+ return false;
+}
+
+bool RegisterContextFreeBSDKernel_i386::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ if (m_pcb_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ struct {
+ llvm::support::ulittle32_t edi;
+ llvm::support::ulittle32_t esi;
+ llvm::support::ulittle32_t ebp;
+ llvm::support::ulittle32_t esp;
+ llvm::support::ulittle32_t ebx;
+ llvm::support::ulittle32_t eip;
+ } pcb;
+
+ Status error;
+ size_t rd =
+ m_thread.GetProcess()->ReadMemory(m_pcb_addr, &pcb, sizeof(pcb), error);
+ if (rd != sizeof(pcb))
+ return false;
+
+ uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ switch (reg) {
+#define REG(x) \
+ case lldb_##x##_i386: \
+ value = pcb.x; \
+ break;
+
+ REG(edi);
+ REG(esi);
+ REG(ebp);
+ REG(esp);
+ REG(eip);
+
+#undef REG
+
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+bool RegisterContextFreeBSDKernel_i386::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ return false;
+}
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.h b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.h
new file mode 100644
index 000000000000..218e3374f8df
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.h
@@ -0,0 +1,41 @@
+//===-- RegisterContextFreeBSDKernel_i386.h ---------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_I386_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_I386_H
+
+#include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
+
+class RegisterContextFreeBSDKernel_i386 : public RegisterContextPOSIX_x86 {
+public:
+ RegisterContextFreeBSDKernel_i386(
+ lldb_private::Thread &thread,
+ lldb_private::RegisterInfoInterface *register_info,
+ lldb::addr_t pcb_addr);
+
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
+
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
+
+protected:
+ bool ReadGPR() override;
+
+ bool ReadFPR() override;
+
+ bool WriteGPR() override;
+
+ bool WriteFPR() override;
+
+private:
+ lldb::addr_t m_pcb_addr;
+};
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_I386_H
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.cpp
new file mode 100644
index 000000000000..ff57842e345c
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.cpp
@@ -0,0 +1,88 @@
+//===-- RegisterContextFreeBSDKernel_x86_64.cpp ---------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "RegisterContextFreeBSDKernel_x86_64.h"
+
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "llvm/Support/Endian.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+RegisterContextFreeBSDKernel_x86_64::RegisterContextFreeBSDKernel_x86_64(
+ Thread &thread, RegisterInfoInterface *register_info, lldb::addr_t pcb_addr)
+ : RegisterContextPOSIX_x86(thread, 0, register_info), m_pcb_addr(pcb_addr) {
+}
+
+bool RegisterContextFreeBSDKernel_x86_64::ReadGPR() { return true; }
+
+bool RegisterContextFreeBSDKernel_x86_64::ReadFPR() { return true; }
+
+bool RegisterContextFreeBSDKernel_x86_64::WriteGPR() {
+ assert(0);
+ return false;
+}
+
+bool RegisterContextFreeBSDKernel_x86_64::WriteFPR() {
+ assert(0);
+ return false;
+}
+
+bool RegisterContextFreeBSDKernel_x86_64::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ if (m_pcb_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ struct {
+ llvm::support::ulittle64_t r15;
+ llvm::support::ulittle64_t r14;
+ llvm::support::ulittle64_t r13;
+ llvm::support::ulittle64_t r12;
+ llvm::support::ulittle64_t rbp;
+ llvm::support::ulittle64_t rsp;
+ llvm::support::ulittle64_t rbx;
+ llvm::support::ulittle64_t rip;
+ } pcb;
+
+ Status error;
+ size_t rd =
+ m_thread.GetProcess()->ReadMemory(m_pcb_addr, &pcb, sizeof(pcb), error);
+ if (rd != sizeof(pcb))
+ return false;
+
+ uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ switch (reg) {
+#define REG(x) \
+ case lldb_##x##_x86_64: \
+ value = pcb.x; \
+ break;
+
+ REG(r15);
+ REG(r14);
+ REG(r13);
+ REG(r12);
+ REG(rbp);
+ REG(rsp);
+ REG(rbx);
+ REG(rip);
+
+#undef REG
+
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+bool RegisterContextFreeBSDKernel_x86_64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ return false;
+}
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.h b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.h
new file mode 100644
index 000000000000..9a2ac638dfea
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.h
@@ -0,0 +1,41 @@
+//===-- RegisterContextFreeBSDKernel_x86_64.h -------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_X86_64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_X86_64_H
+
+#include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
+
+class RegisterContextFreeBSDKernel_x86_64 : public RegisterContextPOSIX_x86 {
+public:
+ RegisterContextFreeBSDKernel_x86_64(
+ lldb_private::Thread &thread,
+ lldb_private::RegisterInfoInterface *register_info,
+ lldb::addr_t pcb_addr);
+
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
+
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
+
+protected:
+ bool ReadGPR() override;
+
+ bool ReadFPR() override;
+
+ bool WriteGPR() override;
+
+ bool WriteFPR() override;
+
+private:
+ lldb::addr_t m_pcb_addr;
+};
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_X86_64_H
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.cpp
new file mode 100644
index 000000000000..124c65d587ff
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.cpp
@@ -0,0 +1,85 @@
+//===-- ThreadFreeBSDKernel.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ThreadFreeBSDKernel.h"
+
+#include "lldb/Target/Unwind.h"
+#include "lldb/Utility/Log.h"
+
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
+#include "ProcessFreeBSDKernel.h"
+#include "RegisterContextFreeBSDKernel_arm64.h"
+#include "RegisterContextFreeBSDKernel_i386.h"
+#include "RegisterContextFreeBSDKernel_x86_64.h"
+#include "ThreadFreeBSDKernel.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+ThreadFreeBSDKernel::ThreadFreeBSDKernel(Process &process, lldb::tid_t tid,
+ lldb::addr_t pcb_addr)
+ : Thread(process, tid), m_pcb_addr(pcb_addr) {}
+
+ThreadFreeBSDKernel::~ThreadFreeBSDKernel() {}
+
+void ThreadFreeBSDKernel::RefreshStateAfterStop() {}
+
+lldb::RegisterContextSP ThreadFreeBSDKernel::GetRegisterContext() {
+ if (!m_reg_context_sp)
+ m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
+ return m_reg_context_sp;
+}
+
+lldb::RegisterContextSP
+ThreadFreeBSDKernel::CreateRegisterContextForFrame(StackFrame *frame) {
+ RegisterContextSP reg_ctx_sp;
+ uint32_t concrete_frame_idx = 0;
+
+ if (frame)
+ concrete_frame_idx = frame->GetConcreteFrameIndex();
+
+ if (concrete_frame_idx == 0) {
+ if (m_thread_reg_ctx_sp)
+ return m_thread_reg_ctx_sp;
+
+ ProcessFreeBSDKernel *process =
+ static_cast<ProcessFreeBSDKernel *>(GetProcess().get());
+ ArchSpec arch = process->GetTarget().GetArchitecture();
+
+ switch (arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ m_thread_reg_ctx_sp =
+ std::make_shared<RegisterContextFreeBSDKernel_arm64>(
+ *this, std::make_unique<RegisterInfoPOSIX_arm64>(arch, 0),
+ m_pcb_addr);
+ break;
+ case llvm::Triple::x86:
+ m_thread_reg_ctx_sp =
+ std::make_shared<RegisterContextFreeBSDKernel_i386>(
+ *this, new RegisterContextFreeBSD_i386(arch), m_pcb_addr);
+ break;
+ case llvm::Triple::x86_64:
+ m_thread_reg_ctx_sp =
+ std::make_shared<RegisterContextFreeBSDKernel_x86_64>(
+ *this, new RegisterContextFreeBSD_x86_64(arch), m_pcb_addr);
+ break;
+ default:
+ assert(false && "Unsupported architecture passed to ThreadFreeBSDKernel");
+ break;
+ }
+
+ reg_ctx_sp = m_thread_reg_ctx_sp;
+ } else {
+ reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame);
+ }
+ return reg_ctx_sp;
+}
+
+bool ThreadFreeBSDKernel::CalculateStopInfo() { return false; }
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.h b/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.h
new file mode 100644
index 000000000000..2842eba64e56
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.h
@@ -0,0 +1,36 @@
+//===-- ThreadFreeBSDKernel.h ------------------------------------- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_THREADFREEBSDKERNEL_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_THREADFREEBSDKERNEL_H
+
+#include "lldb/Target/Thread.h"
+
+class ThreadFreeBSDKernel : public lldb_private::Thread {
+public:
+ ThreadFreeBSDKernel(lldb_private::Process &process, lldb::tid_t tid,
+ lldb::addr_t pcb_addr);
+
+ ~ThreadFreeBSDKernel() override;
+
+ void RefreshStateAfterStop() override;
+
+ lldb::RegisterContextSP GetRegisterContext() override;
+
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
+
+protected:
+ bool CalculateStopInfo() override;
+
+private:
+ lldb::RegisterContextSP m_thread_reg_ctx_sp;
+ lldb::addr_t m_pcb_addr;
+};
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_THREADFREEBSDKERNEL_H
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index b852a0164375..65dbc8ea95b3 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -64,6 +64,10 @@ lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp,
DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
lldb::offset_t data_offset = 0;
if (elf_header.Parse(data, &data_offset)) {
+ // Check whether we're dealing with a raw FreeBSD "full memory dump"
+ // ELF vmcore that needs to be handled via FreeBSDKernel plugin instead.
+ if (elf_header.e_ident[7] == 0xFF && elf_header.e_version == 0)
+ return process_sp;
if (elf_header.e_type == llvm::ELF::ET_CORE)
process_sp = std::make_shared<ProcessElfCore>(target_sp, listener_sp,
*crash_file);
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 07dfa5e04ee5..b5b105351de5 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -1006,6 +1006,23 @@ GDBRemoteCommunicationClient::GetProcessArchitecture() {
return m_process_arch;
}
+bool GDBRemoteCommunicationClient::GetProcessStandaloneBinary(
+ UUID &uuid, addr_t &value, bool &value_is_offset) {
+ if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
+ GetCurrentProcessInfo();
+
+ // Return true if we have a UUID or an address/offset of the
+ // main standalone / firmware binary being used.
+ if (!m_process_standalone_uuid.IsValid() &&
+ m_process_standalone_value == LLDB_INVALID_ADDRESS)
+ return false;
+
+ uuid = m_process_standalone_uuid;
+ value = m_process_standalone_value;
+ value_is_offset = m_process_standalone_value_is_offset;
+ return true;
+}
+
bool GDBRemoteCommunicationClient::GetGDBServerVersion() {
if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate) {
m_gdb_server_name.clear();
@@ -2147,6 +2164,25 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
} else if (name.equals("elf_abi")) {
elf_abi = std::string(value);
++num_keys_decoded;
+ } else if (name.equals("main-binary-uuid")) {
+ m_process_standalone_uuid.SetFromStringRef(value);
+ ++num_keys_decoded;
+ } else if (name.equals("main-binary-slide")) {
+ StringExtractor extractor(value);
+ m_process_standalone_value =
+ extractor.GetU64(LLDB_INVALID_ADDRESS, 16);
+ if (m_process_standalone_value != LLDB_INVALID_ADDRESS) {
+ m_process_standalone_value_is_offset = true;
+ ++num_keys_decoded;
+ }
+ } else if (name.equals("main-binary-address")) {
+ StringExtractor extractor(value);
+ m_process_standalone_value =
+ extractor.GetU64(LLDB_INVALID_ADDRESS, 16);
+ if (m_process_standalone_value != LLDB_INVALID_ADDRESS) {
+ m_process_standalone_value_is_offset = false;
+ ++num_keys_decoded;
+ }
}
}
if (num_keys_decoded > 0)
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 6765372ce124..c69c33bb1c15 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -217,6 +217,9 @@ public:
const ArchSpec &GetProcessArchitecture();
+ bool GetProcessStandaloneBinary(UUID &uuid, lldb::addr_t &value,
+ bool &value_is_offset);
+
void GetRemoteQSupported();
bool GetVContSupported(char flavor);
@@ -584,6 +587,9 @@ protected:
ArchSpec m_host_arch;
ArchSpec m_process_arch;
+ UUID m_process_standalone_uuid;
+ lldb::addr_t m_process_standalone_value = LLDB_INVALID_ADDRESS;
+ bool m_process_standalone_value_is_offset = false;
llvm::VersionTuple m_os_version;
llvm::VersionTuple m_maccatalyst_version;
std::string m_os_build;
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 3ade8c815feb..93fe36c0d9d6 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -526,18 +526,15 @@ Status ProcessGDBRemote::WillAttachToProcessWithName(const char *process_name,
Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- Status error(WillLaunchOrAttach());
+ Status error(WillLaunchOrAttach());
if (error.Fail())
return error;
- if (repro::Reproducer::Instance().IsReplaying())
- error = ConnectToReplayServer();
- else
- error = ConnectToDebugserver(remote_url);
-
+ error = ConnectToDebugserver(remote_url);
if (error.Fail())
return error;
+
StartAsyncThread();
lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
@@ -564,6 +561,94 @@ Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) {
}
}
+ // The remote stub may know about the "main binary" in
+ // the context of a firmware debug session, and can
+ // give us a UUID and an address/slide of where the
+ // binary is loaded in memory.
+ UUID standalone_uuid;
+ addr_t standalone_value;
+ bool standalone_value_is_offset;
+ if (m_gdb_comm.GetProcessStandaloneBinary(
+ standalone_uuid, standalone_value, standalone_value_is_offset)) {
+ ModuleSP module_sp;
+
+ if (standalone_uuid.IsValid()) {
+ ModuleSpec module_spec;
+ module_spec.GetUUID() = standalone_uuid;
+
+ // Look up UUID in global module cache before attempting
+ // a more expensive search.
+ Status error = ModuleList::GetSharedModule(module_spec, module_sp,
+ nullptr, nullptr, nullptr);
+
+ if (!module_sp) {
+ // Force a an external lookup, if that tool is available.
+ if (!module_spec.GetSymbolFileSpec())
+ Symbols::DownloadObjectAndSymbolFile(module_spec, true);
+
+ if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
+ module_sp = std::make_shared<Module>(module_spec);
+ }
+ }
+
+ // If we couldn't find the binary anywhere else, as a last resort,
+ // read it out of memory.
+ if (!module_sp.get() && standalone_value != LLDB_INVALID_ADDRESS &&
+ !standalone_value_is_offset) {
+ char namebuf[80];
+ snprintf(namebuf, sizeof(namebuf), "mem-image-0x%" PRIx64,
+ standalone_value);
+ module_sp =
+ ReadModuleFromMemory(FileSpec(namebuf), standalone_value);
+ }
+
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(
+ LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (module_sp.get()) {
+ target.GetImages().AppendIfNeeded(module_sp, false);
+
+ bool changed = false;
+ if (module_sp->GetObjectFile()) {
+ if (standalone_value != LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("Loading binary UUID %s at %s 0x%" PRIx64,
+ standalone_uuid.GetAsString().c_str(),
+ standalone_value_is_offset ? "offset" : "address",
+ standalone_value);
+ module_sp->SetLoadAddress(target, standalone_value,
+ standalone_value_is_offset, changed);
+ } else {
+ // No address/offset/slide, load the binary at file address,
+ // offset 0.
+ if (log)
+ log->Printf("Loading binary UUID %s at file address",
+ standalone_uuid.GetAsString().c_str());
+ const bool value_is_slide = true;
+ module_sp->SetLoadAddress(target, 0, value_is_slide, changed);
+ }
+ } else {
+ // In-memory image, load at its true address, offset 0.
+ if (log)
+ log->Printf("Loading binary UUID %s from memory",
+ standalone_uuid.GetAsString().c_str());
+ const bool value_is_slide = true;
+ module_sp->SetLoadAddress(target, 0, value_is_slide, changed);
+ }
+
+ ModuleList added_module;
+ added_module.Append(module_sp, false);
+ target.ModulesDidLoad(added_module);
+ } else {
+ if (log)
+ log->Printf("Unable to find binary with UUID %s and load it at "
+ "%s 0x%" PRIx64,
+ standalone_uuid.GetAsString().c_str(),
+ standalone_value_is_offset ? "offset" : "address",
+ standalone_value);
+ }
+ }
+ }
+
const StateType state = SetThreadStopInfo(response);
if (state != eStateInvalid) {
SetPrivateState(state);
@@ -3259,9 +3344,6 @@ ProcessGDBRemote::EstablishConnectionIfNeeded(const ProcessInfo &process_info) {
if (platform_sp && !platform_sp->IsHost())
return Status("Lost debug server connection");
- if (repro::Reproducer::Instance().IsReplaying())
- return ConnectToReplayServer();
-
auto error = LaunchAndConnectToDebugserver(process_info);
if (error.Fail()) {
const char *error_string = error.AsCString();
@@ -3540,7 +3622,7 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
// So it is safer to simply ignore any remaining packets by
// explicitly checking for eStateExited before reentering the
// fetch loop.
-
+
bool done = false;
while (!done && process->GetPrivateState() != eStateExited) {
LLDB_LOGF(log,
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
index c1b7294a7f58..cb21a3e7e65f 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
+++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
@@ -311,6 +311,11 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list,
return GetInterface().ErrorWithMessage<bool>(LLVM_PRETTY_FUNCTION,
error.AsCString(), error);
+ RegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext();
+ if (!reg_ctx_sp)
+ return GetInterface().ErrorWithMessage<bool>(
+ LLVM_PRETTY_FUNCTION, "Invalid Register Context", error);
+
new_thread_list.AddThread(thread_sp);
return new_thread_list.GetSize(false) > 0;
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
index 1adbd4e7799d..959b8c581885 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
+++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
@@ -198,13 +198,17 @@ std::shared_ptr<DynamicRegisterInfo> ScriptedThread::GetDynamicRegisterInfo() {
if (!m_register_info_sp) {
StructuredData::DictionarySP reg_info = GetInterface()->GetRegisterInfo();
+
+ Status error;
if (!reg_info)
- return nullptr;
+ return GetInterface()
+ ->ErrorWithMessage<std::shared_ptr<DynamicRegisterInfo>>(
+ LLVM_PRETTY_FUNCTION,
+ "Failed to get scripted thread registers info.", error,
+ LIBLLDB_LOG_THREAD);
m_register_info_sp = std::make_shared<DynamicRegisterInfo>(
*reg_info, m_scripted_process.GetTarget().GetArchitecture());
- assert(m_register_info_sp->GetNumRegisters() > 0);
- assert(m_register_info_sp->GetNumRegisterSets() > 0);
}
return m_register_info_sp;
diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp b/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
index e99b7b88379a..b82a2647e9a0 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "Lua.h"
+#include "SWIGLuaBridge.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Utility/FileSpec.h"
#include "llvm/Support/Error.h"
@@ -15,30 +16,6 @@
using namespace lldb_private;
using namespace lldb;
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
-
-// Disable warning C4190: 'LLDBSwigPythonBreakpointCallbackFunction' has
-// C-linkage specified, but returns UDT 'llvm::Expected<bool>' which is
-// incompatible with C
-#if _MSC_VER
-#pragma warning (push)
-#pragma warning (disable : 4190)
-#endif
-
-extern "C" llvm::Expected<bool> LLDBSwigLuaBreakpointCallbackFunction(
- lua_State *L, lldb::StackFrameSP stop_frame_sp,
- lldb::BreakpointLocationSP bp_loc_sp, StructuredDataImpl *extra_args_impl);
-
-extern "C" llvm::Expected<bool> LLDBSwigLuaWatchpointCallbackFunction(
- lua_State *L, lldb::StackFrameSP stop_frame_sp, lldb::WatchpointSP wp_sp);
-
-#if _MSC_VER
-#pragma warning (pop)
-#endif
-
-#pragma clang diagnostic pop
-
static int lldb_print(lua_State *L) {
int n = lua_gettop(L);
lua_getglobal(L, "io");
@@ -105,13 +82,7 @@ Lua::CallBreakpointCallback(void *baton, lldb::StackFrameSP stop_frame_sp,
lua_pushlightuserdata(m_lua_state, baton);
lua_gettable(m_lua_state, LUA_REGISTRYINDEX);
- auto *extra_args_impl = [&]() -> StructuredDataImpl * {
- if (extra_args_sp == nullptr)
- return nullptr;
- auto *extra_args_impl = new StructuredDataImpl();
- extra_args_impl->SetObjectSP(extra_args_sp);
- return extra_args_impl;
- }();
+ StructuredDataImpl extra_args_impl(std::move(extra_args_sp));
return LLDBSwigLuaBreakpointCallbackFunction(m_lua_state, stop_frame_sp,
bp_loc_sp, extra_args_impl);
}
diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/SWIGLuaBridge.h b/lldb/source/Plugins/ScriptInterpreter/Lua/SWIGLuaBridge.h
new file mode 100644
index 000000000000..5fca18f2dd6d
--- /dev/null
+++ b/lldb/source/Plugins/ScriptInterpreter/Lua/SWIGLuaBridge.h
@@ -0,0 +1,28 @@
+//===-- SWIGLuaBridge.h -----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_LUA_SWIGLUABRIDGE_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_LUA_SWIGLUABRIDGE_H
+
+#include "lldb/lldb-forward.h"
+#include "lua.hpp"
+#include "llvm/Support/Error.h"
+
+namespace lldb_private {
+
+llvm::Expected<bool> LLDBSwigLuaBreakpointCallbackFunction(
+ lua_State *L, lldb::StackFrameSP stop_frame_sp,
+ lldb::BreakpointLocationSP bp_loc_sp,
+ const StructuredDataImpl &extra_args_impl);
+
+llvm::Expected<bool> LLDBSwigLuaWatchpointCallbackFunction(
+ lua_State *L, lldb::StackFrameSP stop_frame_sp, lldb::WatchpointSP wp_sp);
+
+} // namespace lldb_private
+
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_LUA_SWIGLUABRIDGE_H
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
index c7af13598843..2bb69dc47731 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
@@ -57,20 +57,20 @@ void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data);
void *LLDBSwigPythonCreateScriptedProcess(const char *python_class_name,
const char *session_dictionary_name,
const lldb::TargetSP &target_sp,
- StructuredDataImpl *args_impl,
+ const StructuredDataImpl &args_impl,
std::string &error_string);
void *LLDBSwigPythonCreateScriptedThread(const char *python_class_name,
const char *session_dictionary_name,
const lldb::ProcessSP &process_sp,
- StructuredDataImpl *args_impl,
+ const StructuredDataImpl &args_impl,
std::string &error_string);
llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction(
const char *python_function_name, const char *session_dictionary_name,
const lldb::StackFrameSP &sb_frame,
const lldb::BreakpointLocationSP &sb_bp_loc,
- lldb_private::StructuredDataImpl *args_impl);
+ const lldb_private::StructuredDataImpl &args_impl);
bool LLDBSwigPythonWatchpointCallbackFunction(
const char *python_function_name, const char *session_dictionary_name,
@@ -90,11 +90,11 @@ LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name,
void *LLDBSwigPythonCreateCommandObject(const char *python_class_name,
const char *session_dictionary_name,
- const lldb::DebuggerSP debugger_sp);
+ lldb::DebuggerSP debugger_sp);
void *LLDBSwigPythonCreateScriptedThreadPlan(
const char *python_class_name, const char *session_dictionary_name,
- lldb_private::StructuredDataImpl *args_data, std::string &error_string,
+ const StructuredDataImpl &args_data, std::string &error_string,
const lldb::ThreadPlanSP &thread_plan_sp);
bool LLDBSWIGPythonCallThreadPlan(void *implementor, const char *method_name,
@@ -103,16 +103,17 @@ bool LLDBSWIGPythonCallThreadPlan(void *implementor, const char *method_name,
void *LLDBSwigPythonCreateScriptedBreakpointResolver(
const char *python_class_name, const char *session_dictionary_name,
- lldb_private::StructuredDataImpl *args, const lldb::BreakpointSP &bkpt_sp);
+ const StructuredDataImpl &args, const lldb::BreakpointSP &bkpt_sp);
unsigned int
LLDBSwigPythonCallBreakpointResolver(void *implementor, const char *method_name,
lldb_private::SymbolContext *sym_ctx);
-void *LLDBSwigPythonCreateScriptedStopHook(
- lldb::TargetSP target_sp, const char *python_class_name,
- const char *session_dictionary_name, lldb_private::StructuredDataImpl *args,
- lldb_private::Status &error);
+void *LLDBSwigPythonCreateScriptedStopHook(lldb::TargetSP target_sp,
+ const char *python_class_name,
+ const char *session_dictionary_name,
+ const StructuredDataImpl &args,
+ lldb_private::Status &error);
bool LLDBSwigPythonStopHookCallHandleStop(void *implementor,
lldb::ExecutionContextRefSP exc_ctx,
@@ -136,18 +137,18 @@ PyObject *LLDBSwigPython_GetValueSynthProviderInstance(PyObject *implementor);
bool LLDBSwigPythonCallCommand(const char *python_function_name,
const char *session_dictionary_name,
- lldb::DebuggerSP &debugger, const char *args,
+ lldb::DebuggerSP debugger, const char *args,
lldb_private::CommandReturnObject &cmd_retobj,
lldb::ExecutionContextRefSP exe_ctx_ref_sp);
bool LLDBSwigPythonCallCommandObject(
- PyObject *implementor, lldb::DebuggerSP &debugger, const char *args,
+ PyObject *implementor, lldb::DebuggerSP debugger, const char *args,
lldb_private::CommandReturnObject &cmd_retobj,
lldb::ExecutionContextRefSP exe_ctx_ref_sp);
bool LLDBSwigPythonCallModuleInit(const char *python_module_name,
const char *session_dictionary_name,
- lldb::DebuggerSP &debugger);
+ lldb::DebuggerSP debugger);
void *LLDBSWIGPythonCreateOSPlugin(const char *python_class_name,
const char *session_dictionary_name,
@@ -165,20 +166,20 @@ bool LLDBSWIGPythonRunScriptKeywordProcess(const char *python_function_name,
const lldb::ProcessSP &process,
std::string &output);
-bool LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name,
- const char *session_dictionary_name,
- lldb::ThreadSP &thread,
- std::string &output);
+llvm::Optional<std::string>
+LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name,
+ const char *session_dictionary_name,
+ lldb::ThreadSP thread);
bool LLDBSWIGPythonRunScriptKeywordTarget(const char *python_function_name,
const char *session_dictionary_name,
const lldb::TargetSP &target,
std::string &output);
-bool LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name,
- const char *session_dictionary_name,
- lldb::StackFrameSP &frame,
- std::string &output);
+llvm::Optional<std::string>
+LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name,
+ const char *session_dictionary_name,
+ lldb::StackFrameSP frame);
bool LLDBSWIGPythonRunScriptKeywordValue(const char *python_function_name,
const char *session_dictionary_name,
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 5f282d74e364..6afa4742698b 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -1718,7 +1718,7 @@ StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_CreateThread(
}
StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan(
- const char *class_name, StructuredDataImpl *args_data,
+ const char *class_name, const StructuredDataImpl &args_data,
std::string &error_str, lldb::ThreadPlanSP thread_plan_sp) {
if (class_name == nullptr || class_name[0] == '\0')
return StructuredData::ObjectSP();
@@ -1820,7 +1820,7 @@ lldb::StateType ScriptInterpreterPythonImpl::ScriptedThreadPlanGetRunState(
StructuredData::GenericSP
ScriptInterpreterPythonImpl::CreateScriptedBreakpointResolver(
- const char *class_name, StructuredDataImpl *args_data,
+ const char *class_name, const StructuredDataImpl &args_data,
lldb::BreakpointSP &bkpt_sp) {
if (class_name == nullptr || class_name[0] == '\0')
@@ -1890,8 +1890,8 @@ ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchDepth(
}
StructuredData::GenericSP ScriptInterpreterPythonImpl::CreateScriptedStopHook(
- TargetSP target_sp, const char *class_name, StructuredDataImpl *args_data,
- Status &error) {
+ TargetSP target_sp, const char *class_name,
+ const StructuredDataImpl &args_data, Status &error) {
if (!target_sp) {
error.SetErrorString("No target for scripted stop-hook.");
@@ -2197,7 +2197,7 @@ bool ScriptInterpreterPythonImpl::BreakpointCallbackFunction(
LLDBSwigPythonBreakpointCallbackFunction(
python_function_name,
python_interpreter->m_dictionary_name.c_str(), stop_frame_sp,
- bp_loc_sp, bp_option_data->m_extra_args_up.get());
+ bp_loc_sp, bp_option_data->m_extra_args);
if (!maybe_ret_val) {
@@ -2521,7 +2521,6 @@ bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
const char *impl_function, Thread *thread, std::string &output,
Status &error) {
- bool ret_val;
if (!thread) {
error.SetErrorString("no thread");
return false;
@@ -2531,16 +2530,16 @@ bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
return false;
}
- {
- ThreadSP thread_sp(thread->shared_from_this());
- Locker py_lock(this,
- Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = LLDBSWIGPythonRunScriptKeywordThread(
- impl_function, m_dictionary_name.c_str(), thread_sp, output);
- if (!ret_val)
- error.SetErrorString("python script evaluation failed");
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ if (llvm::Optional<std::string> result = LLDBSWIGPythonRunScriptKeywordThread(
+ impl_function, m_dictionary_name.c_str(),
+ thread->shared_from_this())) {
+ output = std::move(*result);
+ return true;
}
- return ret_val;
+ error.SetErrorString("python script evaluation failed");
+ return false;
}
bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
@@ -2571,7 +2570,6 @@ bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
const char *impl_function, StackFrame *frame, std::string &output,
Status &error) {
- bool ret_val;
if (!frame) {
error.SetErrorString("no frame");
return false;
@@ -2581,16 +2579,16 @@ bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
return false;
}
- {
- StackFrameSP frame_sp(frame->shared_from_this());
- Locker py_lock(this,
- Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- ret_val = LLDBSWIGPythonRunScriptKeywordFrame(
- impl_function, m_dictionary_name.c_str(), frame_sp, output);
- if (!ret_val)
- error.SetErrorString("python script evaluation failed");
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ if (llvm::Optional<std::string> result = LLDBSWIGPythonRunScriptKeywordFrame(
+ impl_function, m_dictionary_name.c_str(),
+ frame->shared_from_this())) {
+ output = std::move(*result);
+ return true;
}
- return ret_val;
+ error.SetErrorString("python script evaluation failed");
+ return false;
}
bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
@@ -2655,7 +2653,6 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule(
}
ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
- lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this();
// Before executing Python code, lock the GIL.
Locker py_lock(this,
@@ -2792,7 +2789,8 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule(
// if we are here, everything worked
// call __lldb_init_module(debugger,dict)
if (!LLDBSwigPythonCallModuleInit(module_name.c_str(),
- m_dictionary_name.c_str(), debugger_sp)) {
+ m_dictionary_name.c_str(),
+ m_debugger.shared_from_this())) {
error.SetErrorString("calling __lldb_init_module failed");
return false;
}
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
index 8cfc24e71283..2e8301a85eb6 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
@@ -33,13 +33,12 @@ public:
CommandDataPython() : BreakpointOptions::CommandData() {
interpreter = lldb::eScriptLanguagePython;
}
- CommandDataPython(StructuredData::ObjectSP extra_args_sp) :
- BreakpointOptions::CommandData(),
- m_extra_args_up(new StructuredDataImpl()) {
- interpreter = lldb::eScriptLanguagePython;
- m_extra_args_up->SetObjectSP(extra_args_sp);
+ CommandDataPython(StructuredData::ObjectSP extra_args_sp)
+ : BreakpointOptions::CommandData(),
+ m_extra_args(std::move(extra_args_sp)) {
+ interpreter = lldb::eScriptLanguagePython;
}
- lldb::StructuredDataImplUP m_extra_args_up;
+ StructuredDataImpl m_extra_args;
};
ScriptInterpreterPython(Debugger &debugger)
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
index a3f83b696ed4..defc2acffcfa 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -79,7 +79,7 @@ public:
StructuredData::ObjectSP
CreateScriptedThreadPlan(const char *class_name,
- StructuredDataImpl *args_data,
+ const StructuredDataImpl &args_data,
std::string &error_str,
lldb::ThreadPlanSP thread_plan) override;
@@ -99,7 +99,7 @@ public:
StructuredData::GenericSP
CreateScriptedBreakpointResolver(const char *class_name,
- StructuredDataImpl *args_data,
+ const StructuredDataImpl &args_data,
lldb::BreakpointSP &bkpt_sp) override;
bool ScriptedBreakpointResolverSearchCallback(
StructuredData::GenericSP implementor_sp,
@@ -110,7 +110,8 @@ public:
StructuredData::GenericSP
CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name,
- StructuredDataImpl *args_data, Status &error) override;
+ const StructuredDataImpl &args_data,
+ Status &error) override;
bool ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp,
ExecutionContext &exc_ctx,
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
index 29680dab5a14..e3c1931a565a 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
@@ -37,11 +37,7 @@ StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject(
return {};
TargetSP target_sp = exe_ctx.GetTargetSP();
- StructuredDataImpl *args_impl = nullptr;
- if (args_sp) {
- args_impl = new StructuredDataImpl();
- args_impl->SetObjectSP(args_sp);
- }
+ StructuredDataImpl args_impl(args_sp);
std::string error_string;
Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
index d2c28bc426ee..6a881bfe625c 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
@@ -37,11 +37,7 @@ StructuredData::GenericSP ScriptedThreadPythonInterface::CreatePluginObject(
return {};
ProcessSP process_sp = exe_ctx.GetProcessSP();
- StructuredDataImpl *args_impl = nullptr;
- if (args_sp) {
- args_impl = new StructuredDataImpl();
- args_impl->SetObjectSP(args_sp);
- }
+ StructuredDataImpl args_impl(args_sp);
std::string error_string;
Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 4ac6e165dda3..b90f104c4d21 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -1530,7 +1530,6 @@ TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType(
return type_sp;
SymbolFileDWARF *dwarf = die.GetDWARF();
- TypeList &type_list = dwarf->GetTypeList();
DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
dw_tag_t sc_parent_tag = sc_parent_die.Tag();
@@ -1550,10 +1549,6 @@ TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType(
if (symbol_context_scope != nullptr)
type_sp->SetSymbolContextScope(symbol_context_scope);
- // We are ready to put this type into the uniqued list up at the module
- // level.
- type_list.Insert(type_sp);
-
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
return type_sp;
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index cece29dcf9ac..71d4c1e6c52f 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -153,7 +153,7 @@ public:
const DWARFAbbreviationDeclarationSet *GetAbbreviations() const;
dw_offset_t GetAbbrevOffset() const;
uint8_t GetAddressByteSize() const { return m_header.GetAddressByteSize(); }
- dw_addr_t GetAddrBase() const { return m_addr_base ? *m_addr_base : 0; }
+ dw_addr_t GetAddrBase() const { return m_addr_base.getValueOr(0); }
dw_addr_t GetBaseAddress() const { return m_base_addr; }
dw_offset_t GetLineTableOffset();
dw_addr_t GetRangesBase() const { return m_ranges_base; }
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 8c20244a6c44..8c995ef2eb2a 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1097,7 +1097,8 @@ bool SymbolFileDWARF::ParseImportedModules(
if (const char *include_path = module_die.GetAttributeValueAsString(
DW_AT_LLVM_include_path, nullptr)) {
FileSpec include_spec(include_path, dwarf_cu->GetPathStyle());
- MakeAbsoluteAndRemap(include_spec, *dwarf_cu, m_objfile_sp->GetModule());
+ MakeAbsoluteAndRemap(include_spec, *dwarf_cu,
+ m_objfile_sp->GetModule());
module.search_path = ConstString(include_spec.GetPath());
}
if (const char *sysroot = dwarf_cu->DIE().GetAttributeValueAsString(
@@ -1924,7 +1925,7 @@ void SymbolFileDWARF::ResolveFunctionAndBlock(lldb::addr_t file_vm_addr,
block_die = function_die.LookupDeepestBlock(file_vm_addr);
}
- if (!sc.function || ! lookup_block)
+ if (!sc.function || !lookup_block)
return;
Block &block = sc.function->GetBlock(true);
@@ -2319,7 +2320,8 @@ void SymbolFileDWARF::FindFunctions(ConstString name,
if (log) {
GetObjectFile()->GetModule()->LogMessage(
log,
- "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, sc_list)",
+ "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, "
+ "sc_list)",
name.GetCString(), name_type_mask);
}
@@ -2352,8 +2354,7 @@ void SymbolFileDWARF::FindFunctions(ConstString name,
log,
"SymbolFileDWARF::FindFunctions (name=\"%s\", "
"name_type_mask=0x%x, include_inlines=%d, sc_list) => %u",
- name.GetCString(), name_type_mask, include_inlines,
- num_matches);
+ name.GetCString(), name_type_mask, include_inlines, num_matches);
}
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 271ce7be1eea..e81ce28cb86e 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -253,8 +253,8 @@ public:
ExternalTypeModuleMap;
/// Return the list of Clang modules imported by this SymbolFile.
- const ExternalTypeModuleMap& getExternalTypeModules() const {
- return m_external_type_modules;
+ const ExternalTypeModuleMap &getExternalTypeModules() const {
+ return m_external_type_modules;
}
virtual DWARFDIE GetDIE(const DIERef &die_ref);
@@ -328,7 +328,6 @@ public:
return m_parse_time;
}
-
protected:
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *>
DIEToTypePtr;
@@ -428,9 +427,10 @@ protected:
virtual lldb::TypeSP
FindDefinitionTypeForDWARFDeclContext(const DWARFDeclContext &die_decl_ctx);
- virtual lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
- const DWARFDIE &die, lldb_private::ConstString type_name,
- bool must_be_implementation);
+ virtual lldb::TypeSP
+ FindCompleteObjCDefinitionTypeForDIE(const DWARFDIE &die,
+ lldb_private::ConstString type_name,
+ bool must_be_implementation);
lldb_private::Symbol *
GetObjCClassSymbol(lldb_private::ConstString objc_class_name);
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index c29fc2230a67..9473befa6cc3 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -30,6 +30,70 @@ using namespace lldb_private::npdb;
using namespace llvm::codeview;
using namespace llvm::pdb;
+namespace {
+struct CreateMethodDecl : public TypeVisitorCallbacks {
+ CreateMethodDecl(PdbIndex &m_index, TypeSystemClang &m_clang,
+ TypeIndex func_type_index,
+ clang::FunctionDecl *&function_decl,
+ lldb::opaque_compiler_type_t parent_ty,
+ llvm::StringRef proc_name, CompilerType func_ct)
+ : m_index(m_index), m_clang(m_clang), func_type_index(func_type_index),
+ function_decl(function_decl), parent_ty(parent_ty),
+ proc_name(proc_name), func_ct(func_ct) {}
+ PdbIndex &m_index;
+ TypeSystemClang &m_clang;
+ TypeIndex func_type_index;
+ clang::FunctionDecl *&function_decl;
+ lldb::opaque_compiler_type_t parent_ty;
+ llvm::StringRef proc_name;
+ CompilerType func_ct;
+
+ llvm::Error visitKnownMember(CVMemberRecord &cvr,
+ OverloadedMethodRecord &overloaded) override {
+ TypeIndex method_list_idx = overloaded.MethodList;
+
+ CVType method_list_type = m_index.tpi().getType(method_list_idx);
+ assert(method_list_type.kind() == LF_METHODLIST);
+
+ MethodOverloadListRecord method_list;
+ llvm::cantFail(TypeDeserializer::deserializeAs<MethodOverloadListRecord>(
+ method_list_type, method_list));
+
+ for (const OneMethodRecord &method : method_list.Methods) {
+ if (method.getType().getIndex() == func_type_index.getIndex())
+ AddMethod(overloaded.Name, method.getAccess(), method.getOptions(),
+ method.Attrs);
+ }
+
+ return llvm::Error::success();
+ }
+
+ llvm::Error visitKnownMember(CVMemberRecord &cvr,
+ OneMethodRecord &record) override {
+ AddMethod(record.getName(), record.getAccess(), record.getOptions(),
+ record.Attrs);
+ return llvm::Error::success();
+ }
+
+ void AddMethod(llvm::StringRef name, MemberAccess access,
+ MethodOptions options, MemberAttributes attrs) {
+ if (name != proc_name || function_decl)
+ return;
+ lldb::AccessType access_type = TranslateMemberAccess(access);
+ bool is_virtual = attrs.isVirtual();
+ bool is_static = attrs.isStatic();
+ bool is_artificial = (options & MethodOptions::CompilerGenerated) ==
+ MethodOptions::CompilerGenerated;
+ function_decl = m_clang.AddMethodToCXXRecordType(
+ parent_ty, proc_name,
+ /*mangled_name=*/nullptr, func_ct, /*access=*/access_type,
+ /*is_virtual=*/is_virtual, /*is_static=*/is_static,
+ /*is_inline=*/false, /*is_explicit=*/false,
+ /*is_attr_used=*/false, /*is_artificial=*/is_artificial);
+ }
+};
+} // namespace
+
static llvm::Optional<PdbCompilandSymId> FindSymbolScope(PdbIndex &index,
PdbCompilandSymId id) {
CVSymbol sym = index.ReadSymbolRecord(id);
@@ -681,7 +745,8 @@ bool PdbAstBuilder::CompleteTagDecl(clang::TagDecl &tag) {
// Visit all members of this class, then perform any finalization necessary
// to complete the class.
CompilerType ct = ToCompilerType(tag_qt);
- UdtRecordCompleter completer(best_ti, ct, tag, *this, m_index);
+ UdtRecordCompleter completer(best_ti, ct, tag, *this, m_index,
+ m_cxx_record_map);
auto error =
llvm::codeview::visitMemberRecordStream(field_list_cvt.data(), completer);
completer.complete();
@@ -1014,8 +1079,62 @@ PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) {
proc_name.consume_front(context_name);
proc_name.consume_front("::");
- clang::FunctionDecl *function_decl = m_clang.CreateFunctionDeclaration(
- parent, OptionalClangModuleID(), proc_name, func_ct, storage, false);
+ clang::FunctionDecl *function_decl = nullptr;
+ if (parent->isRecord()) {
+ clang::QualType parent_qt = llvm::dyn_cast<clang::TypeDecl>(parent)
+ ->getTypeForDecl()
+ ->getCanonicalTypeInternal();
+ lldb::opaque_compiler_type_t parent_opaque_ty =
+ ToCompilerType(parent_qt).GetOpaqueQualType();
+
+ auto iter = m_cxx_record_map.find(parent_opaque_ty);
+ if (iter != m_cxx_record_map.end()) {
+ if (iter->getSecond().contains({proc_name, func_ct})) {
+ return nullptr;
+ }
+ }
+
+ CVType cvt = m_index.tpi().getType(type_id.index);
+ MemberFunctionRecord func_record(static_cast<TypeRecordKind>(cvt.kind()));
+ llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>(
+ cvt, func_record));
+ TypeIndex class_index = func_record.getClassType();
+ CVType parent_cvt = m_index.tpi().getType(class_index);
+ ClassRecord class_record = CVTagRecord::create(parent_cvt).asClass();
+ // If it's a forward reference, try to get the real TypeIndex.
+ if (class_record.isForwardRef()) {
+ llvm::Expected<TypeIndex> eti =
+ m_index.tpi().findFullDeclForForwardRef(class_index);
+ if (eti) {
+ class_record =
+ CVTagRecord::create(m_index.tpi().getType(*eti)).asClass();
+ }
+ }
+ if (!class_record.FieldList.isSimple()) {
+ CVType field_list = m_index.tpi().getType(class_record.FieldList);
+ CreateMethodDecl process(m_index, m_clang, type_id.index, function_decl,
+ parent_opaque_ty, proc_name, func_ct);
+ if (llvm::Error err = visitMemberRecordStream(field_list.data(), process))
+ llvm::consumeError(std::move(err));
+ }
+
+ if (!function_decl) {
+ function_decl = m_clang.AddMethodToCXXRecordType(
+ parent_opaque_ty, proc_name,
+ /*mangled_name=*/nullptr, func_ct,
+ /*access=*/lldb::AccessType::eAccessPublic,
+ /*is_virtual=*/false, /*is_static=*/false,
+ /*is_inline=*/false, /*is_explicit=*/false,
+ /*is_attr_used=*/false, /*is_artificial=*/false);
+ }
+
+ m_cxx_record_map[parent_opaque_ty].insert({proc_name, func_ct});
+ } else {
+ function_decl = m_clang.CreateFunctionDeclaration(
+ parent, OptionalClangModuleID(), proc_name, func_ct, storage, false);
+ CreateFunctionParameters(func_id, *function_decl,
+ func_type->getNumParams());
+ }
lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0);
m_uid_to_decl[toOpaqueUid(func_id)] = function_decl;
@@ -1024,8 +1143,6 @@ PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) {
status.uid = toOpaqueUid(func_id);
m_decl_to_status.insert({function_decl, status});
- CreateFunctionParameters(func_id, *function_decl, func_type->getNumParams());
-
return function_decl;
}
@@ -1163,15 +1280,15 @@ clang::QualType PdbAstBuilder::CreateFunctionType(
}
static bool isTagDecl(clang::DeclContext &context) {
- return !!llvm::dyn_cast<clang::TagDecl>(&context);
+ return llvm::isa<clang::TagDecl>(&context);
}
static bool isFunctionDecl(clang::DeclContext &context) {
- return !!llvm::dyn_cast<clang::FunctionDecl>(&context);
+ return llvm::isa<clang::FunctionDecl>(&context);
}
static bool isBlockDecl(clang::DeclContext &context) {
- return !!llvm::dyn_cast<clang::BlockDecl>(&context);
+ return llvm::isa<clang::BlockDecl>(&context);
}
void PdbAstBuilder::ParseAllNamespacesPlusChildrenOf(
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
index 7bb2584d19a3..73accf5e5e68 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
@@ -137,6 +137,12 @@ private:
llvm::DenseMap<clang::Decl *, DeclStatus> m_decl_to_status;
llvm::DenseMap<lldb::user_id_t, clang::Decl *> m_uid_to_decl;
llvm::DenseMap<lldb::user_id_t, clang::QualType> m_uid_to_type;
+
+ // From class/struct's opaque_compiler_type_t to a set containing the pairs of
+ // method's name and CompilerType.
+ llvm::DenseMap<lldb::opaque_compiler_type_t,
+ llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>, 8>>
+ m_cxx_record_map;
};
} // namespace npdb
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index bf101ac1acf1..e859b1d5a86c 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -900,7 +900,7 @@ lldb::LanguageType SymbolFileNativePDB::ParseLanguage(CompileUnit &comp_unit) {
return TranslateLanguage(item->m_compile_opts->getLanguage());
}
-void SymbolFileNativePDB::AddSymbols(Symtab &symtab) { return; }
+void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {}
size_t SymbolFileNativePDB::ParseFunctions(CompileUnit &comp_unit) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
index c8fb46c75034..d0b27bc5bf79 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
@@ -28,13 +28,15 @@ using namespace lldb_private::npdb;
using Error = llvm::Error;
-UdtRecordCompleter::UdtRecordCompleter(PdbTypeSymId id,
- CompilerType &derived_ct,
- clang::TagDecl &tag_decl,
- PdbAstBuilder &ast_builder,
- PdbIndex &index)
+UdtRecordCompleter::UdtRecordCompleter(
+ PdbTypeSymId id, CompilerType &derived_ct, clang::TagDecl &tag_decl,
+ PdbAstBuilder &ast_builder, PdbIndex &index,
+ llvm::DenseMap<lldb::opaque_compiler_type_t,
+ llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>, 8>>
+ &cxx_record_map)
: m_id(id), m_derived_ct(derived_ct), m_tag_decl(tag_decl),
- m_ast_builder(ast_builder), m_index(index) {
+ m_ast_builder(ast_builder), m_index(index),
+ m_cxx_record_map(cxx_record_map) {
CVType cvt = m_index.tpi().getType(m_id.index);
switch (cvt.kind()) {
case LF_ENUM:
@@ -78,14 +80,24 @@ void UdtRecordCompleter::AddMethod(llvm::StringRef name, TypeIndex type_idx,
clang::QualType method_qt =
m_ast_builder.GetOrCreateType(PdbTypeSymId(type_idx));
m_ast_builder.CompleteType(method_qt);
+ CompilerType method_ct = m_ast_builder.ToCompilerType(method_qt);
+ lldb::opaque_compiler_type_t derived_opaque_ty = m_derived_ct.GetOpaqueQualType();
+ auto iter = m_cxx_record_map.find(derived_opaque_ty);
+ if (iter != m_cxx_record_map.end()) {
+ if (iter->getSecond().contains({name, method_ct})) {
+ return;
+ }
+ }
lldb::AccessType access_type = TranslateMemberAccess(access);
bool is_artificial = (options & MethodOptions::CompilerGenerated) ==
MethodOptions::CompilerGenerated;
m_ast_builder.clang().AddMethodToCXXRecordType(
- m_derived_ct.GetOpaqueQualType(), name.data(), nullptr,
- m_ast_builder.ToCompilerType(method_qt), access_type, attrs.isVirtual(),
- attrs.isStatic(), false, false, false, is_artificial);
+ derived_opaque_ty, name.data(), nullptr, method_ct,
+ access_type, attrs.isVirtual(), attrs.isStatic(), false, false, false,
+ is_artificial);
+
+ m_cxx_record_map[derived_opaque_ty].insert({name, method_ct});
}
Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
index ae7e47c82fe5..9c6b5ed28bc2 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
@@ -54,11 +54,17 @@ class UdtRecordCompleter : public llvm::codeview::TypeVisitorCallbacks {
PdbIndex &m_index;
std::vector<IndexedBase> m_bases;
ClangASTImporter::LayoutInfo m_layout;
+ llvm::DenseMap<lldb::opaque_compiler_type_t,
+ llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>, 8>>
+ &m_cxx_record_map;
public:
- UdtRecordCompleter(PdbTypeSymId id, CompilerType &derived_ct,
- clang::TagDecl &tag_decl, PdbAstBuilder &ast_builder,
- PdbIndex &index);
+ UdtRecordCompleter(
+ PdbTypeSymId id, CompilerType &derived_ct, clang::TagDecl &tag_decl,
+ PdbAstBuilder &ast_builder, PdbIndex &index,
+ llvm::DenseMap<lldb::opaque_compiler_type_t,
+ llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>,
+ 8>> &cxx_record_map);
#define MEMBER_RECORD(EnumName, EnumVal, Name) \
llvm::Error visitKnownMember(llvm::codeview::CVMemberRecord &CVR, \
diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index db0ae241be7e..a40b6ec9a635 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -239,7 +239,6 @@ void SymbolFilePDB::GetCompileUnitIndex(
}
}
index = UINT32_MAX;
- return;
}
std::unique_ptr<llvm::pdb::PDBSymbolCompiland>
@@ -402,7 +401,7 @@ static size_t ParseFunctionBlocksForPDBSymbol(
block = parent_block;
else
break;
- } else if (llvm::dyn_cast<PDBSymbolBlock>(pdb_symbol)) {
+ } else if (llvm::isa<PDBSymbolBlock>(pdb_symbol)) {
auto uid = pdb_symbol->getSymIndexId();
if (parent_block->FindBlockByID(uid))
break;
diff --git a/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp b/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp
index 919cdf46a5c0..a72e46a0b703 100644
--- a/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp
+++ b/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp
@@ -73,8 +73,7 @@ bool CommandObjectThreadTraceExportCTF::DoExecute(Args &command,
if (thread == nullptr) {
const uint32_t num_threads = process->GetThreadList().GetSize();
- size_t tid = m_options.m_thread_index ? *m_options.m_thread_index
- : LLDB_INVALID_THREAD_ID;
+ size_t tid = m_options.m_thread_index.getValueOr(LLDB_INVALID_THREAD_ID);
result.AppendErrorWithFormatv(
"Thread index {0} is out of range (valid values are 1 - {1}).\n", tid,
num_threads);
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index b1dbc382ff04..88c3aedb4c6b 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -2581,6 +2581,7 @@ RemoveWrappingTypes(QualType type, ArrayRef<clang::Type::TypeClass> mask = {}) {
case clang::Type::Typedef:
case clang::Type::TypeOf:
case clang::Type::TypeOfExpr:
+ case clang::Type::Using:
type = type->getLocallyUnqualifiedSingleStepDesugaredType();
break;
default:
@@ -4063,6 +4064,7 @@ TypeSystemClang::GetTypeClass(lldb::opaque_compiler_type_t type) {
case clang::Type::Paren:
case clang::Type::TypeOf:
case clang::Type::TypeOfExpr:
+ case clang::Type::Using:
llvm_unreachable("Handled in RemoveWrappingTypes!");
case clang::Type::UnaryTransform:
break;
@@ -4088,8 +4090,8 @@ TypeSystemClang::GetTypeClass(lldb::opaque_compiler_type_t type) {
return lldb::eTypeClassVector;
case clang::Type::Builtin:
// Ext-Int is just an integer type.
- case clang::Type::ExtInt:
- case clang::Type::DependentExtInt:
+ case clang::Type::BitInt:
+ case clang::Type::DependentBitInt:
return lldb::eTypeClassBuiltin;
case clang::Type::ObjCObjectPointer:
return lldb::eTypeClassObjCObjectPointer;
@@ -4722,6 +4724,7 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type,
case clang::Type::Typedef:
case clang::Type::TypeOf:
case clang::Type::TypeOfExpr:
+ case clang::Type::Using:
llvm_unreachable("Handled in RemoveWrappingTypes!");
case clang::Type::UnaryTransform:
@@ -4744,8 +4747,8 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type,
// TODO: Set this to more than one???
break;
- case clang::Type::ExtInt:
- case clang::Type::DependentExtInt:
+ case clang::Type::BitInt:
+ case clang::Type::DependentBitInt:
return qual_type->isUnsignedIntegerType() ? lldb::eEncodingUint
: lldb::eEncodingSint;
@@ -5104,6 +5107,7 @@ lldb::Format TypeSystemClang::GetFormat(lldb::opaque_compiler_type_t type) {
case clang::Type::Typedef:
case clang::Type::TypeOf:
case clang::Type::TypeOfExpr:
+ case clang::Type::Using:
llvm_unreachable("Handled in RemoveWrappingTypes!");
case clang::Type::UnaryTransform:
break;
@@ -5124,8 +5128,8 @@ lldb::Format TypeSystemClang::GetFormat(lldb::opaque_compiler_type_t type) {
case clang::Type::Vector:
break;
- case clang::Type::ExtInt:
- case clang::Type::DependentExtInt:
+ case clang::Type::BitInt:
+ case clang::Type::DependentBitInt:
return qual_type->isUnsignedIntegerType() ? lldb::eFormatUnsigned
: lldb::eFormatDecimal;
@@ -5145,6 +5149,8 @@ lldb::Format TypeSystemClang::GetFormat(lldb::opaque_compiler_type_t type) {
case clang::BuiltinType::UChar:
case clang::BuiltinType::WChar_U:
return lldb::eFormatChar;
+ case clang::BuiltinType::Char8:
+ return lldb::eFormatUnicode8;
case clang::BuiltinType::Char16:
return lldb::eFormatUnicode16;
case clang::BuiltinType::Char32:
@@ -8953,6 +8959,7 @@ bool TypeSystemClang::DumpTypeValue(
case eFormatCharPrintable:
case eFormatCharArray:
case eFormatBytes:
+ case eFormatUnicode8:
case eFormatBytesWithASCII:
item_count = byte_size;
byte_size = 1;
diff --git a/lldb/source/Symbol/ObjectFile.cpp b/lldb/source/Symbol/ObjectFile.cpp
index bfab741b0d66..e7b19f5e0c51 100644
--- a/lldb/source/Symbol/ObjectFile.cpp
+++ b/lldb/source/Symbol/ObjectFile.cpp
@@ -23,6 +23,8 @@
#include "lldb/Utility/Timer.h"
#include "lldb/lldb-private.h"
+#include "llvm/Support/DJB.h"
+
using namespace lldb;
using namespace lldb_private;
@@ -737,13 +739,24 @@ Symtab *ObjectFile::GetSymtab() {
// 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();
+ Symtab *symtab = new Symtab(this);
+ std::lock_guard<std::recursive_mutex> symtab_guard(symtab->GetMutex());
+ m_symtab_up.reset(symtab);
+ if (!m_symtab_up->LoadFromCache()) {
+ ElapsedTime elapsed(module_sp->GetSymtabParseTime());
+ ParseSymtab(*m_symtab_up);
+ m_symtab_up->Finalize();
+ }
});
}
return m_symtab_up.get();
}
+
+uint32_t ObjectFile::GetCacheHash() {
+ if (m_cache_hash)
+ return *m_cache_hash;
+ StreamString strm;
+ strm.Format("{0}-{1}-{2}", m_file, GetType(), GetStrata());
+ m_cache_hash = llvm::djbHash(strm.GetString());
+ return *m_cache_hash;
+}
diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp
index a8c81ee3082f..fa7226dfd046 100644
--- a/lldb/source/Symbol/Symbol.cpp
+++ b/lldb/source/Symbol/Symbol.cpp
@@ -17,6 +17,7 @@
#include "lldb/Symbol/Symtab.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/DataEncoder.h"
#include "lldb/Utility/Stream.h"
using namespace lldb;
@@ -595,3 +596,131 @@ void Symbol::SynthesizeNameIfNeeded() const {
m_mangled.SetDemangledName(ConstString(os.str()));
}
}
+
+bool Symbol::Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
+ const SectionList *section_list,
+ const StringTableReader &strtab) {
+ if (!data.ValidOffsetForDataOfSize(*offset_ptr, 8))
+ return false;
+ m_uid = data.GetU32(offset_ptr);
+ m_type_data = data.GetU16(offset_ptr);
+ const uint16_t bitfields = data.GetU16(offset_ptr);
+ m_type_data_resolved = (1u << 15 & bitfields) != 0;
+ m_is_synthetic = (1u << 14 & bitfields) != 0;
+ m_is_debug = (1u << 13 & bitfields) != 0;
+ m_is_external = (1u << 12 & bitfields) != 0;
+ m_size_is_sibling = (1u << 11 & bitfields) != 0;
+ m_size_is_synthesized = (1u << 10 & bitfields) != 0;
+ m_size_is_valid = (1u << 9 & bitfields) != 0;
+ m_demangled_is_synthesized = (1u << 8 & bitfields) != 0;
+ m_contains_linker_annotations = (1u << 7 & bitfields) != 0;
+ m_is_weak = (1u << 6 & bitfields) != 0;
+ m_type = bitfields & 0x003f;
+ if (!m_mangled.Decode(data, offset_ptr, strtab))
+ return false;
+ if (!data.ValidOffsetForDataOfSize(*offset_ptr, 20))
+ return false;
+ const bool is_addr = data.GetU8(offset_ptr) != 0;
+ const uint64_t value = data.GetU64(offset_ptr);
+ if (is_addr) {
+ m_addr_range.GetBaseAddress().ResolveAddressUsingFileSections(
+ value, section_list);
+ } else {
+ m_addr_range.GetBaseAddress().Clear();
+ m_addr_range.GetBaseAddress().SetOffset(value);
+ }
+ m_addr_range.SetByteSize(data.GetU64(offset_ptr));
+ m_flags = data.GetU32(offset_ptr);
+ return true;
+}
+
+/// The encoding format for the symbol is as follows:
+///
+/// uint32_t m_uid;
+/// uint16_t m_type_data;
+/// uint16_t bitfield_data;
+/// Mangled mangled;
+/// uint8_t is_addr;
+/// uint64_t file_addr_or_value;
+/// uint64_t size;
+/// uint32_t flags;
+///
+/// The only tricky thing in this encoding is encoding all of the bits in the
+/// bitfields. We use a trick to store all bitfields as a 16 bit value and we
+/// do the same thing when decoding the symbol. There are test that ensure this
+/// encoding works for each individual bit. Everything else is very easy to
+/// store.
+void Symbol::Encode(DataEncoder &file, ConstStringTable &strtab) const {
+ file.AppendU32(m_uid);
+ file.AppendU16(m_type_data);
+ uint16_t bitfields = m_type;
+ if (m_type_data_resolved)
+ bitfields |= 1u << 15;
+ if (m_is_synthetic)
+ bitfields |= 1u << 14;
+ if (m_is_debug)
+ bitfields |= 1u << 13;
+ if (m_is_external)
+ bitfields |= 1u << 12;
+ if (m_size_is_sibling)
+ bitfields |= 1u << 11;
+ if (m_size_is_synthesized)
+ bitfields |= 1u << 10;
+ if (m_size_is_valid)
+ bitfields |= 1u << 9;
+ if (m_demangled_is_synthesized)
+ bitfields |= 1u << 8;
+ if (m_contains_linker_annotations)
+ bitfields |= 1u << 7;
+ if (m_is_weak)
+ bitfields |= 1u << 6;
+ file.AppendU16(bitfields);
+ m_mangled.Encode(file, strtab);
+ // A symbol's value might be an address, or it might be a constant. If the
+ // symbol's base address doesn't have a section, then it is a constant value.
+ // If it does have a section, we will encode the file address and re-resolve
+ // the address when we decode it.
+ bool is_addr = m_addr_range.GetBaseAddress().GetSection().get() != NULL;
+ file.AppendU8(is_addr);
+ file.AppendU64(m_addr_range.GetBaseAddress().GetFileAddress());
+ file.AppendU64(m_addr_range.GetByteSize());
+ file.AppendU32(m_flags);
+}
+
+bool Symbol::operator==(const Symbol &rhs) const {
+ if (m_uid != rhs.m_uid)
+ return false;
+ if (m_type_data != rhs.m_type_data)
+ return false;
+ if (m_type_data_resolved != rhs.m_type_data_resolved)
+ return false;
+ if (m_is_synthetic != rhs.m_is_synthetic)
+ return false;
+ if (m_is_debug != rhs.m_is_debug)
+ return false;
+ if (m_is_external != rhs.m_is_external)
+ return false;
+ if (m_size_is_sibling != rhs.m_size_is_sibling)
+ return false;
+ if (m_size_is_synthesized != rhs.m_size_is_synthesized)
+ return false;
+ if (m_size_is_valid != rhs.m_size_is_valid)
+ return false;
+ if (m_demangled_is_synthesized != rhs.m_demangled_is_synthesized)
+ return false;
+ if (m_contains_linker_annotations != rhs.m_contains_linker_annotations)
+ return false;
+ if (m_is_weak != rhs.m_is_weak)
+ return false;
+ if (m_type != rhs.m_type)
+ return false;
+ if (m_mangled != rhs.m_mangled)
+ return false;
+ if (m_addr_range.GetBaseAddress() != rhs.m_addr_range.GetBaseAddress())
+ return false;
+ if (m_addr_range.GetByteSize() != rhs.m_addr_range.GetByteSize())
+ return false;
+ if (m_flags != rhs.m_flags)
+ return false;
+ return true;
+}
diff --git a/lldb/source/Symbol/SymbolFile.cpp b/lldb/source/Symbol/SymbolFile.cpp
index 53f8dd68c8b7..b85901af4d67 100644
--- a/lldb/source/Symbol/SymbolFile.cpp
+++ b/lldb/source/Symbol/SymbolFile.cpp
@@ -125,9 +125,7 @@ void SymbolFile::FindFunctions(const RegularExpression &regex,
void SymbolFile::GetMangledNamesForFunction(
const std::string &scope_qualified_name,
- std::vector<ConstString> &mangled_names) {
- return;
-}
+ std::vector<ConstString> &mangled_names) {}
void SymbolFile::FindTypes(
ConstString name, const CompilerDeclContext &parent_decl_ctx,
@@ -147,9 +145,11 @@ void SymbolFile::AssertModuleLock() {
// We assert that we have to module lock by trying to acquire the lock from a
// different thread. Note that we must abort if the result is true to
// guarantee correctness.
- assert(std::async(std::launch::async,
- [this] { return this->GetModuleMutex().try_lock(); })
- .get() == false &&
+ assert(std::async(
+ std::launch::async,
+ [this] {
+ return this->GetModuleMutex().try_lock();
+ }).get() == false &&
"Module is not locked");
#endif
}
diff --git a/lldb/source/Symbol/Symtab.cpp b/lldb/source/Symbol/Symtab.cpp
index c67955523bfb..75450a156c28 100644
--- a/lldb/source/Symbol/Symtab.cpp
+++ b/lldb/source/Symbol/Symtab.cpp
@@ -9,6 +9,7 @@
#include <map>
#include <set>
+#include "lldb/Core/DataFileCache.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/RichManglingContext.h"
#include "lldb/Core/Section.h"
@@ -17,11 +18,15 @@
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Symtab.h"
#include "lldb/Target/Language.h"
+#include "lldb/Utility/DataEncoder.h"
+#include "lldb/Utility/Endian.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/Timer.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DJB.h"
using namespace lldb;
using namespace lldb_private;
@@ -109,7 +114,8 @@ void Symtab::Dump(Stream *s, Target *target, SortOrder sort_order,
s->Indent();
pos->Dump(s, target, std::distance(begin, pos), name_preference);
}
- } break;
+ }
+ break;
case eSortOrderByName: {
// Although we maintain a lookup by exact name map, the table isn't
@@ -663,7 +669,6 @@ uint32_t Symtab::AppendSymbolIndexesWithName(ConstString symbol_name,
std::vector<uint32_t> &indexes) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
- LLDB_SCOPED_TIMER();
if (symbol_name) {
if (!m_name_indexes_computed)
InitNameIndexes();
@@ -808,7 +813,6 @@ Symtab::FindAllSymbolsWithNameAndType(ConstString name,
std::vector<uint32_t> &symbol_indexes) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
- LLDB_SCOPED_TIMER();
// Initialize all of the lookup by name indexes before converting NAME to a
// uniqued string NAME_STR below.
if (!m_name_indexes_computed)
@@ -1006,6 +1010,7 @@ void Symtab::Finalize() {
collection new_symbols(m_symbols.begin(), m_symbols.end());
m_symbols.swap(new_symbols);
}
+ SaveToCache();
}
Symbol *Symtab::FindSymbolAtFileAddress(addr_t file_addr) {
@@ -1152,3 +1157,191 @@ const Symbol *Symtab::GetParent(Symbol *child_symbol) const {
}
return nullptr;
}
+
+std::string Symtab::GetCacheKey() {
+ std::string key;
+ llvm::raw_string_ostream strm(key);
+ // Symbol table can come from different object files for the same module. A
+ // module can have one object file as the main executable and might have
+ // another object file in a separate symbol file.
+ strm << m_objfile->GetModule()->GetCacheKey() << "-symtab-"
+ << llvm::format_hex(m_objfile->GetCacheHash(), 10);
+ return strm.str();
+}
+
+void Symtab::SaveToCache() {
+ DataFileCache *cache = Module::GetIndexCache();
+ if (!cache)
+ return; // Caching is not enabled.
+ InitNameIndexes(); // Init the name indexes so we can cache them as well.
+ const auto byte_order = endian::InlHostByteOrder();
+ DataEncoder file(byte_order, /*addr_size=*/8);
+ // Encode will return false if the symbol table's object file doesn't have
+ // anything to make a signature from.
+ if (Encode(file))
+ cache->SetCachedData(GetCacheKey(), file.GetData());
+}
+
+constexpr llvm::StringLiteral kIdentifierCStrMap("CMAP");
+
+static void EncodeCStrMap(DataEncoder &encoder, ConstStringTable &strtab,
+ const UniqueCStringMap<uint32_t> &cstr_map) {
+ encoder.AppendData(kIdentifierCStrMap);
+ encoder.AppendU32(cstr_map.GetSize());
+ for (const auto &entry: cstr_map) {
+ // Make sure there are no empty strings.
+ assert((bool)entry.cstring);
+ encoder.AppendU32(strtab.Add(entry.cstring));
+ encoder.AppendU32(entry.value);
+ }
+}
+
+bool DecodeCStrMap(const DataExtractor &data, lldb::offset_t *offset_ptr,
+ const StringTableReader &strtab,
+ UniqueCStringMap<uint32_t> &cstr_map) {
+ llvm::StringRef identifier((const char *)data.GetData(offset_ptr, 4), 4);
+ if (identifier != kIdentifierCStrMap)
+ return false;
+ const uint32_t count = data.GetU32(offset_ptr);
+ for (uint32_t i=0; i<count; ++i)
+ {
+ llvm::StringRef str(strtab.Get(data.GetU32(offset_ptr)));
+ uint32_t value = data.GetU32(offset_ptr);
+ // No empty strings in the name indexes in Symtab
+ if (str.empty())
+ return false;
+ cstr_map.Append(ConstString(str), value);
+ }
+ return true;
+}
+
+constexpr llvm::StringLiteral kIdentifierSymbolTable("SYMB");
+constexpr uint32_t CURRENT_CACHE_VERSION = 1;
+
+/// The encoding format for the symbol table is as follows:
+///
+/// Signature signature;
+/// ConstStringTable strtab;
+/// Identifier four character code: 'SYMB'
+/// uint32_t version;
+/// uint32_t num_symbols;
+/// Symbol symbols[num_symbols];
+/// uint8_t num_cstr_maps;
+/// UniqueCStringMap<uint32_t> cstr_maps[num_cstr_maps]
+bool Symtab::Encode(DataEncoder &encoder) const {
+ // Name indexes must be computed before calling this function.
+ assert(m_name_indexes_computed);
+
+ // Encode the object file's signature
+ CacheSignature signature(m_objfile);
+ if (!signature.Encode(encoder))
+ return false;
+ ConstStringTable strtab;
+
+ // Encoder the symbol table into a separate encoder first. This allows us
+ // gather all of the strings we willl need in "strtab" as we will need to
+ // write the string table out before the symbol table.
+ DataEncoder symtab_encoder(encoder.GetByteOrder(),
+ encoder.GetAddressByteSize());
+ symtab_encoder.AppendData(kIdentifierSymbolTable);
+ // Encode the symtab data version.
+ symtab_encoder.AppendU32(CURRENT_CACHE_VERSION);
+ // Encode the number of symbols.
+ symtab_encoder.AppendU32(m_symbols.size());
+ // Encode the symbol data for all symbols.
+ for (const auto &symbol: m_symbols)
+ symbol.Encode(symtab_encoder, strtab);
+
+ // Emit a byte for how many C string maps we emit. We will fix this up after
+ // we emit the C string maps since we skip emitting C string maps if they are
+ // empty.
+ size_t num_cmaps_offset = symtab_encoder.GetByteSize();
+ uint8_t num_cmaps = 0;
+ symtab_encoder.AppendU8(0);
+ for (const auto &pair: m_name_to_symbol_indices) {
+ if (pair.second.IsEmpty())
+ continue;
+ ++num_cmaps;
+ symtab_encoder.AppendU8(pair.first);
+ EncodeCStrMap(symtab_encoder, strtab, pair.second);
+ }
+ if (num_cmaps > 0)
+ symtab_encoder.PutU8(num_cmaps_offset, num_cmaps);
+
+ // Now that all strings have been gathered, we will emit the string table.
+ strtab.Encode(encoder);
+ // Followed the the symbol table data.
+ encoder.AppendData(symtab_encoder.GetData());
+ return true;
+}
+
+bool Symtab::Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
+ bool &signature_mismatch) {
+ signature_mismatch = false;
+ CacheSignature signature;
+ StringTableReader strtab;
+ { // Scope for "elapsed" object below so it can measure the time parse.
+ ElapsedTime elapsed(m_objfile->GetModule()->GetSymtabParseTime());
+ if (!signature.Decode(data, offset_ptr))
+ return false;
+ if (CacheSignature(m_objfile) != signature) {
+ signature_mismatch = true;
+ return false;
+ }
+ // We now decode the string table for all strings in the data cache file.
+ if (!strtab.Decode(data, offset_ptr))
+ return false;
+
+ // And now we can decode the symbol table with string table we just decoded.
+ llvm::StringRef identifier((const char *)data.GetData(offset_ptr, 4), 4);
+ if (identifier != kIdentifierSymbolTable)
+ return false;
+ const uint32_t version = data.GetU32(offset_ptr);
+ if (version != CURRENT_CACHE_VERSION)
+ return false;
+ const uint32_t num_symbols = data.GetU32(offset_ptr);
+ if (num_symbols == 0)
+ return true;
+ m_symbols.resize(num_symbols);
+ SectionList *sections = m_objfile->GetModule()->GetSectionList();
+ for (uint32_t i=0; i<num_symbols; ++i) {
+ if (!m_symbols[i].Decode(data, offset_ptr, sections, strtab))
+ return false;
+ }
+ }
+
+ { // Scope for "elapsed" object below so it can measure the time to index.
+ ElapsedTime elapsed(m_objfile->GetModule()->GetSymtabIndexTime());
+ const uint8_t num_cstr_maps = data.GetU8(offset_ptr);
+ for (uint8_t i=0; i<num_cstr_maps; ++i) {
+ uint8_t type = data.GetU8(offset_ptr);
+ UniqueCStringMap<uint32_t> &cstr_map =
+ GetNameToSymbolIndexMap((lldb::FunctionNameType)type);
+ if (!DecodeCStrMap(data, offset_ptr, strtab, cstr_map))
+ return false;
+ }
+ m_name_indexes_computed = true;
+ }
+ return true;
+}
+
+bool Symtab::LoadFromCache() {
+ DataFileCache *cache = Module::GetIndexCache();
+ if (!cache)
+ return false;
+
+ std::unique_ptr<llvm::MemoryBuffer> mem_buffer_up =
+ cache->GetCachedData(GetCacheKey());
+ if (!mem_buffer_up)
+ return false;
+ DataExtractor data(mem_buffer_up->getBufferStart(),
+ mem_buffer_up->getBufferSize(),
+ m_objfile->GetByteOrder(),
+ m_objfile->GetAddressByteSize());
+ bool signature_mismatch = false;
+ lldb::offset_t offset = 0;
+ const bool result = Decode(data, &offset, signature_mismatch);
+ if (signature_mismatch)
+ cache->RemoveCacheFile(GetCacheKey());
+ return result;
+}
diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp
index 5b4169d256d2..d6c82ed1dd80 100644
--- a/lldb/source/Symbol/Type.cpp
+++ b/lldb/source/Symbol/Type.cpp
@@ -662,7 +662,7 @@ ConstString Type::GetQualifiedName() {
return GetForwardCompilerType().GetTypeName();
}
-bool Type::GetTypeScopeAndBasename(const llvm::StringRef& name,
+bool Type::GetTypeScopeAndBasename(llvm::StringRef name,
llvm::StringRef &scope,
llvm::StringRef &basename,
TypeClass &type_class) {
diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp
index cba51d266c5b..7b4295158425 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -1883,14 +1883,32 @@ bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source,
if (m_sc.comp_unit && m_sc.line_entry.IsValid()) {
have_debuginfo = true;
if (source_lines_before > 0 || source_lines_after > 0) {
+ uint32_t start_line = m_sc.line_entry.line;
+ if (!start_line && m_sc.function) {
+ FileSpec source_file;
+ m_sc.function->GetStartLineSourceInfo(source_file, start_line);
+ }
+
size_t num_lines =
target->GetSourceManager().DisplaySourceLinesWithLineNumbers(
- m_sc.line_entry.file, m_sc.line_entry.line,
- m_sc.line_entry.column, source_lines_before,
- source_lines_after, "->", &strm);
+ m_sc.line_entry.file, start_line, m_sc.line_entry.column,
+ source_lines_before, source_lines_after, "->", &strm);
if (num_lines != 0)
have_source = true;
// TODO: Give here a one time warning if source file is missing.
+ if (!m_sc.line_entry.line) {
+ ConstString fn_name = m_sc.GetFunctionName();
+
+ if (!fn_name.IsEmpty())
+ strm.Printf(
+ "Note: this address is compiler-generated code in function "
+ "%s that has no source code associated with it.",
+ fn_name.AsCString());
+ else
+ strm.Printf("Note: this address is compiler-generated code that "
+ "has no source code associated with it.");
+ strm.EOL();
+ }
}
}
switch (disasm_display) {
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 28575b50cf96..fa860399aca7 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -616,12 +616,8 @@ lldb::BreakpointSP Target::CreateScriptedBreakpoint(
shared_from_this());
}
- StructuredDataImpl *extra_args_impl = new StructuredDataImpl();
- if (extra_args_sp)
- extra_args_impl->SetObjectSP(extra_args_sp);
-
BreakpointResolverSP resolver_sp(new BreakpointResolverScripted(
- nullptr, class_name, depth, extra_args_impl));
+ nullptr, class_name, depth, StructuredDataImpl(extra_args_sp)));
return CreateBreakpoint(filter_sp, resolver_sp, internal, false, true);
}
@@ -3321,8 +3317,7 @@ void Target::FinalizeFileActions(ProcessLaunchInfo &info) {
err_file_spec);
}
- if (default_to_use_pty &&
- (!in_file_spec || !out_file_spec || !err_file_spec)) {
+ if (default_to_use_pty) {
llvm::Error Err = info.SetUpPtyRedirection();
LLDB_LOG_ERROR(log, std::move(Err), "SetUpPtyRedirection failed: {0}");
}
@@ -3485,11 +3480,7 @@ Status Target::StopHookScripted::SetScriptCallback(
}
m_class_name = class_name;
-
- m_extra_args = new StructuredDataImpl();
-
- if (extra_args_sp)
- m_extra_args->SetObjectSP(extra_args_sp);
+ m_extra_args.SetObjectSP(extra_args_sp);
m_implementation_sp = script_interp->CreateScriptedStopHook(
GetTarget(), m_class_name.c_str(), m_extra_args, error);
@@ -3527,9 +3518,9 @@ void Target::StopHookScripted::GetSubclassDescription(
// Now print the extra args:
// FIXME: We should use StructuredData.GetDescription on the m_extra_args
// but that seems to rely on some printing plugin that doesn't exist.
- if (!m_extra_args->IsValid())
+ if (!m_extra_args.IsValid())
return;
- StructuredData::ObjectSP object_sp = m_extra_args->GetObjectSP();
+ StructuredData::ObjectSP object_sp = m_extra_args.GetObjectSP();
if (!object_sp || !object_sp->IsValid())
return;
diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp
index 1b32331d98f7..481a39a576e9 100644
--- a/lldb/source/Target/Thread.cpp
+++ b/lldb/source/Target/Thread.cpp
@@ -1370,15 +1370,9 @@ lldb::ThreadPlanSP Thread::QueueThreadPlanForStepScripted(
bool abort_other_plans, const char *class_name,
StructuredData::ObjectSP extra_args_sp, bool stop_other_threads,
Status &status) {
-
- StructuredDataImpl *extra_args_impl = nullptr;
- if (extra_args_sp) {
- extra_args_impl = new StructuredDataImpl();
- extra_args_impl->SetObjectSP(extra_args_sp);
- }
- ThreadPlanSP thread_plan_sp(new ThreadPlanPython(*this, class_name,
- extra_args_impl));
+ ThreadPlanSP thread_plan_sp(new ThreadPlanPython(
+ *this, class_name, StructuredDataImpl(extra_args_sp)));
thread_plan_sp->SetStopOthers(stop_other_threads);
status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
return thread_plan_sp;
diff --git a/lldb/source/Target/ThreadPlanPython.cpp b/lldb/source/Target/ThreadPlanPython.cpp
index cd63d28a3934..a8a36ae65c46 100644
--- a/lldb/source/Target/ThreadPlanPython.cpp
+++ b/lldb/source/Target/ThreadPlanPython.cpp
@@ -26,7 +26,7 @@ using namespace lldb_private;
// ThreadPlanPython
ThreadPlanPython::ThreadPlanPython(Thread &thread, const char *class_name,
- StructuredDataImpl *args_data)
+ const StructuredDataImpl &args_data)
: ThreadPlan(ThreadPlan::eKindPython, "Python based Thread Plan", thread,
eVoteNoOpinion, eVoteNoOpinion),
m_class_name(class_name), m_args_data(args_data), m_did_push(false),
@@ -36,11 +36,6 @@ ThreadPlanPython::ThreadPlanPython(Thread &thread, const char *class_name,
SetPrivate(false);
}
-ThreadPlanPython::~ThreadPlanPython() {
- // FIXME, do I need to decrement the ref count on this implementation object
- // to make it go away?
-}
-
bool ThreadPlanPython::ValidatePlan(Stream *error) {
if (!m_did_push)
return true;
diff --git a/lldb/source/Target/ThreadPlanStack.cpp b/lldb/source/Target/ThreadPlanStack.cpp
index f09583cc50cc..80634647f9e0 100644
--- a/lldb/source/Target/ThreadPlanStack.cpp
+++ b/lldb/source/Target/ThreadPlanStack.cpp
@@ -210,7 +210,6 @@ void ThreadPlanStack::DiscardAllPlans() {
for (int i = stack_size - 1; i > 0; i--) {
DiscardPlan();
}
- return;
}
void ThreadPlanStack::DiscardConsultingControllingPlans() {
diff --git a/lldb/source/Target/UnwindLLDB.cpp b/lldb/source/Target/UnwindLLDB.cpp
index 047147112f3b..77dd19b04ebd 100644
--- a/lldb/source/Target/UnwindLLDB.cpp
+++ b/lldb/source/Target/UnwindLLDB.cpp
@@ -312,7 +312,6 @@ void UnwindLLDB::UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi) {
// Restore status after calling AddOneMoreFrame
m_unwind_complete = old_m_unwind_complete;
m_candidate_frame = old_m_candidate_frame;
- return;
}
bool UnwindLLDB::AddOneMoreFrame(ABI *abi) {
diff --git a/lldb/source/Utility/DataEncoder.cpp b/lldb/source/Utility/DataEncoder.cpp
index e88cd23c1d84..b21453977496 100644
--- a/lldb/source/Utility/DataEncoder.cpp
+++ b/lldb/source/Utility/DataEncoder.cpp
@@ -8,7 +8,7 @@
#include "lldb/Utility/DataEncoder.h"
-#include "lldb/Utility/DataBuffer.h"
+#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Endian.h"
#include "llvm/Support/Endian.h"
@@ -22,83 +22,26 @@ using namespace lldb;
using namespace lldb_private;
using namespace llvm::support::endian;
-// Default constructor.
DataEncoder::DataEncoder()
- : m_byte_order(endian::InlHostByteOrder()), m_addr_size(sizeof(void *)),
- m_data_sp() {}
+ : m_data_sp(new DataBufferHeap()), m_byte_order(endian::InlHostByteOrder()),
+ m_addr_size(sizeof(void *)) {}
-// This constructor allows us to use data that is owned by someone else. The
-// data must stay around as long as this object is valid.
-DataEncoder::DataEncoder(void *data, uint32_t length, ByteOrder endian,
+DataEncoder::DataEncoder(const void *data, uint32_t length, ByteOrder endian,
uint8_t addr_size)
- : m_start(static_cast<uint8_t *>(data)),
- m_end(static_cast<uint8_t *>(data) + length), m_byte_order(endian),
- m_addr_size(addr_size), m_data_sp() {}
+ : m_data_sp(new DataBufferHeap(data, length)), m_byte_order(endian),
+ m_addr_size(addr_size) {}
-// Make a shared pointer reference to the shared data in "data_sp" and set the
-// endian swapping setting to "swap", and the address size to "addr_size". The
-// shared data reference will ensure the data lives as long as any DataEncoder
-// objects exist that have a reference to this data.
-DataEncoder::DataEncoder(const DataBufferSP &data_sp, ByteOrder endian,
- uint8_t addr_size)
- : m_start(nullptr), m_end(nullptr), m_byte_order(endian),
- m_addr_size(addr_size), m_data_sp() {
- SetData(data_sp);
-}
+DataEncoder::DataEncoder(ByteOrder endian, uint8_t addr_size)
+ : m_data_sp(new DataBufferHeap()), m_byte_order(endian),
+ m_addr_size(addr_size) {}
DataEncoder::~DataEncoder() = default;
-// Clears the object contents back to a default invalid state, and release any
-// references to shared data that this object may contain.
-void DataEncoder::Clear() {
- m_start = nullptr;
- m_end = nullptr;
- m_byte_order = endian::InlHostByteOrder();
- m_addr_size = sizeof(void *);
- m_data_sp.reset();
+llvm::ArrayRef<uint8_t> DataEncoder::GetData() const {
+ return llvm::ArrayRef<uint8_t>(m_data_sp->GetBytes(), GetByteSize());
}
-// Assign the data for this object to be a subrange of the shared data in
-// "data_sp" starting "data_offset" bytes into "data_sp" and ending
-// "data_length" bytes later. If "data_offset" is not a valid offset into
-// "data_sp", then this object will contain no bytes. If "data_offset" is
-// within "data_sp" yet "data_length" is too large, the length will be capped
-// at the number of bytes remaining in "data_sp". A ref counted pointer to the
-// data in "data_sp" will be made in this object IF the number of bytes this
-// object refers to in greater than zero (if at least one byte was available
-// starting at "data_offset") to ensure the data stays around as long as it is
-// needed. The address size and endian swap settings will remain unchanged from
-// their current settings.
-uint32_t DataEncoder::SetData(const DataBufferSP &data_sp, uint32_t data_offset,
- uint32_t data_length) {
- m_start = m_end = nullptr;
-
- if (data_length > 0) {
- m_data_sp = data_sp;
- if (data_sp) {
- const size_t data_size = data_sp->GetByteSize();
- if (data_offset < data_size) {
- m_start = data_sp->GetBytes() + data_offset;
- const size_t bytes_left = data_size - data_offset;
- // Cap the length of we asked for too many
- if (data_length <= bytes_left)
- m_end = m_start + data_length; // We got all the bytes we wanted
- else
- m_end = m_start + bytes_left; // Not all the bytes requested were
- // available in the shared data
- }
- }
- }
-
- uint32_t new_size = GetByteSize();
-
- // Don't hold a shared pointer to the data buffer if we don't share any valid
- // bytes in the shared buffer.
- if (new_size == 0)
- m_data_sp.reset();
-
- return new_size;
-}
+size_t DataEncoder::GetByteSize() const { return m_data_sp->GetByteSize(); }
// Extract a single unsigned char from the binary data and update the offset
// pointed to by "offset_ptr".
@@ -106,7 +49,7 @@ uint32_t DataEncoder::SetData(const DataBufferSP &data_sp, uint32_t data_offset,
// RETURNS the byte that was extracted, or zero on failure.
uint32_t DataEncoder::PutU8(uint32_t offset, uint8_t value) {
if (ValidOffset(offset)) {
- m_start[offset] = value;
+ m_data_sp->GetBytes()[offset] = value;
return offset + 1;
}
return UINT32_MAX;
@@ -115,9 +58,9 @@ uint32_t DataEncoder::PutU8(uint32_t offset, uint8_t value) {
uint32_t DataEncoder::PutU16(uint32_t offset, uint16_t value) {
if (ValidOffsetForDataOfSize(offset, sizeof(value))) {
if (m_byte_order != endian::InlHostByteOrder())
- write16be(m_start + offset, value);
+ write16be(m_data_sp->GetBytes() + offset, value);
else
- write16le(m_start + offset, value);
+ write16le(m_data_sp->GetBytes() + offset, value);
return offset + sizeof(value);
}
@@ -127,9 +70,9 @@ uint32_t DataEncoder::PutU16(uint32_t offset, uint16_t value) {
uint32_t DataEncoder::PutU32(uint32_t offset, uint32_t value) {
if (ValidOffsetForDataOfSize(offset, sizeof(value))) {
if (m_byte_order != endian::InlHostByteOrder())
- write32be(m_start + offset, value);
+ write32be(m_data_sp->GetBytes() + offset, value);
else
- write32le(m_start + offset, value);
+ write32le(m_data_sp->GetBytes() + offset, value);
return offset + sizeof(value);
}
@@ -139,9 +82,9 @@ uint32_t DataEncoder::PutU32(uint32_t offset, uint32_t value) {
uint32_t DataEncoder::PutU64(uint32_t offset, uint64_t value) {
if (ValidOffsetForDataOfSize(offset, sizeof(value))) {
if (m_byte_order != endian::InlHostByteOrder())
- write64be(m_start + offset, value);
+ write64be(m_data_sp->GetBytes() + offset, value);
else
- write64le(m_start + offset, value);
+ write64le(m_data_sp->GetBytes() + offset, value);
return offset + sizeof(value);
}
@@ -171,7 +114,7 @@ uint32_t DataEncoder::PutData(uint32_t offset, const void *src,
return offset;
if (ValidOffsetForDataOfSize(offset, src_len)) {
- memcpy(m_start + offset, src, src_len);
+ memcpy(m_data_sp->GetBytes() + offset, src, src_len);
return offset + src_len;
}
return UINT32_MAX;
@@ -186,3 +129,63 @@ uint32_t DataEncoder::PutCString(uint32_t offset, const char *cstr) {
return PutData(offset, cstr, strlen(cstr) + 1);
return UINT32_MAX;
}
+
+void DataEncoder::AppendU8(uint8_t value) {
+ m_data_sp->AppendData(&value, sizeof(value));
+}
+
+void DataEncoder::AppendU16(uint16_t value) {
+ uint32_t offset = m_data_sp->GetByteSize();
+ m_data_sp->SetByteSize(m_data_sp->GetByteSize() + sizeof(value));
+ PutU16(offset, value);
+}
+
+void DataEncoder::AppendU32(uint32_t value) {
+ uint32_t offset = m_data_sp->GetByteSize();
+ m_data_sp->SetByteSize(m_data_sp->GetByteSize() + sizeof(value));
+ PutU32(offset, value);
+}
+
+void DataEncoder::AppendU64(uint64_t value) {
+ uint32_t offset = m_data_sp->GetByteSize();
+ m_data_sp->SetByteSize(m_data_sp->GetByteSize() + sizeof(value));
+ PutU64(offset, value);
+}
+
+void DataEncoder::AppendAddress(lldb::addr_t addr) {
+ switch (m_addr_size) {
+ case 4:
+ AppendU32(addr);
+ break;
+ case 8:
+ AppendU64(addr);
+ break;
+ default:
+ llvm_unreachable("AppendAddress unhandled case!");
+ }
+}
+
+void DataEncoder::AppendData(llvm::StringRef data) {
+ const char *bytes = data.data();
+ const size_t length = data.size();
+ if (bytes && length > 0)
+ m_data_sp->AppendData(bytes, length);
+}
+
+void DataEncoder::AppendData(llvm::ArrayRef<uint8_t> data) {
+ const uint8_t *bytes = data.data();
+ const size_t length = data.size();
+ if (bytes && length > 0)
+ m_data_sp->AppendData(bytes, length);
+}
+
+void DataEncoder::AppendCString(llvm::StringRef data) {
+ const char *bytes = data.data();
+ const size_t length = data.size();
+ if (bytes) {
+ if (length > 0)
+ m_data_sp->AppendData(bytes, length);
+ if (length == 0 || bytes[length - 1] != '\0')
+ AppendU8(0);
+ }
+}
diff --git a/lldb/source/Utility/FileSpec.cpp b/lldb/source/Utility/FileSpec.cpp
index 601edb86c1b0..24f8c2b1c23f 100644
--- a/lldb/source/Utility/FileSpec.cpp
+++ b/lldb/source/Utility/FileSpec.cpp
@@ -310,7 +310,7 @@ llvm::Optional<FileSpec::Style> FileSpec::GuessPathStyle(llvm::StringRef absolut
return Style::posix;
if (absolute_path.startswith(R"(\\)"))
return Style::windows;
- if (absolute_path.size() > 3 && llvm::isAlpha(absolute_path[0]) &&
+ if (absolute_path.size() >= 3 && llvm::isAlpha(absolute_path[0]) &&
absolute_path.substr(1, 2) == R"(:\)")
return Style::windows;
return llvm::None;
diff --git a/lldb/source/Utility/Reproducer.cpp b/lldb/source/Utility/Reproducer.cpp
index b63863c535fa..a306d6c1ef25 100644
--- a/lldb/source/Utility/Reproducer.cpp
+++ b/lldb/source/Utility/Reproducer.cpp
@@ -44,10 +44,6 @@ llvm::Error Reproducer::Initialize(ReproducerMode mode,
}
return Instance().SetCapture(root);
} break;
- case ReproducerMode::Replay:
- return Instance().SetReplay(root, /*passive*/ false);
- case ReproducerMode::PassiveReplay:
- return Instance().SetReplay(root, /*passive*/ true);
case ReproducerMode::Off:
break;
};
@@ -116,26 +112,6 @@ llvm::Error Reproducer::SetCapture(llvm::Optional<FileSpec> root) {
return Error::success();
}
-llvm::Error Reproducer::SetReplay(llvm::Optional<FileSpec> root, bool passive) {
- std::lock_guard<std::mutex> guard(m_mutex);
-
- if (root && m_generator)
- return make_error<StringError>(
- "cannot replay a reproducer when generating one",
- inconvertibleErrorCode());
-
- if (!root) {
- m_loader.reset();
- return Error::success();
- }
-
- m_loader.emplace(*root, passive);
- if (auto e = m_loader->LoadIndex())
- return e;
-
- return Error::success();
-}
-
FileSpec Reproducer::GetReproducerPath() const {
if (auto g = GetGenerator())
return g->GetRoot();
@@ -222,8 +198,7 @@ void Generator::AddProvidersToIndex() {
}
Loader::Loader(FileSpec root, bool passive)
- : m_root(MakeAbsolute(std::move(root))), m_loaded(false),
- m_passive_replay(passive) {}
+ : m_root(MakeAbsolute(std::move(root))), m_loaded(false) {}
llvm::Error Loader::LoadIndex() {
if (m_loaded)
diff --git a/lldb/source/lldb.cpp b/lldb/source/Version/Version.cpp
index 371902f6c1b5..b391fe1eacd8 100644
--- a/lldb/source/lldb.cpp
+++ b/lldb/source/Version/Version.cpp
@@ -1,4 +1,4 @@
-//===-- lldb.cpp ----------------------------------------------------------===//
+//===-- Version.cpp -------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,23 +6,16 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/Version/Version.h"
#include "VCSVersion.inc"
-#include "lldb/lldb-private.h"
+#include "lldb/Version/Version.inc"
#include "clang/Basic/Version.h"
-using namespace lldb;
-using namespace lldb_private;
-
-// LLDB_VERSION_STRING is set through a define so unlike the other defines
-// expanded with CMake, it lacks the double quotes.
-#define QUOTE(str) #str
-#define EXPAND_AND_QUOTE(str) QUOTE(str)
-
static const char *GetLLDBVersion() {
-#ifdef LLDB_VERSION_STRING
- return EXPAND_AND_QUOTE(LLDB_VERSION_STRING);
+#ifdef LLDB_FULL_VERSION_STRING
+ return LLDB_FULL_VERSION_STRING;
#else
- return "lldb version " CLANG_VERSION_STRING;
+ return "lldb version " LLDB_VERSION_STRING;
#endif
}
@@ -30,7 +23,7 @@ static const char *GetLLDBRevision() {
#ifdef LLDB_REVISION
return LLDB_REVISION;
#else
- return NULL;
+ return nullptr;
#endif
}
@@ -38,12 +31,13 @@ static const char *GetLLDBRepository() {
#ifdef LLDB_REPOSITORY
return LLDB_REPOSITORY;
#else
- return NULL;
+ return nullptr;
#endif
}
const char *lldb_private::GetVersion() {
static std::string g_version_str;
+
if (g_version_str.empty()) {
const char *lldb_version = GetLLDBVersion();
const char *lldb_repo = GetLLDBRepository();
@@ -67,11 +61,13 @@ const char *lldb_private::GetVersion() {
g_version_str += "\n clang revision ";
g_version_str += clang_rev;
}
+
std::string llvm_rev(clang::getLLVMRevision());
if (llvm_rev.length() > 0) {
g_version_str += "\n llvm revision ";
g_version_str += llvm_rev;
}
}
+
return g_version_str.c_str();
}
diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp
index 977cc306bb4e..2ed9958e51da 100644
--- a/lldb/tools/driver/Driver.cpp
+++ b/lldb/tools/driver/Driver.cpp
@@ -736,43 +736,6 @@ EXAMPLES:
static llvm::Optional<int> InitializeReproducer(llvm::StringRef argv0,
opt::InputArgList &input_args) {
- if (auto *finalize_path = input_args.getLastArg(OPT_reproducer_finalize)) {
- if (const char *error = SBReproducer::Finalize(finalize_path->getValue())) {
- WithColor::error() << "reproducer finalization failed: " << error << '\n';
- return 1;
- }
-
- llvm::outs() << "********************\n";
- llvm::outs() << "Crash reproducer for ";
- llvm::outs() << lldb::SBDebugger::GetVersionString() << '\n';
- llvm::outs() << '\n';
- llvm::outs() << "Reproducer written to '" << SBReproducer::GetPath()
- << "'\n";
- llvm::outs() << '\n';
- llvm::outs() << "Before attaching the reproducer to a bug report:\n";
- llvm::outs() << " - Look at the directory to ensure you're willing to "
- "share its content.\n";
- llvm::outs()
- << " - Make sure the reproducer works by replaying the reproducer.\n";
- llvm::outs() << '\n';
- llvm::outs() << "Replay the reproducer with the following command:\n";
- llvm::outs() << argv0 << " -replay " << finalize_path->getValue() << "\n";
- llvm::outs() << "********************\n";
- return 0;
- }
-
- if (auto *replay_path = input_args.getLastArg(OPT_replay)) {
- SBReplayOptions replay_options;
- replay_options.SetCheckVersion(!input_args.hasArg(OPT_no_version_check));
- replay_options.SetVerify(!input_args.hasArg(OPT_no_verification));
- if (const char *error =
- SBReproducer::Replay(replay_path->getValue(), replay_options)) {
- WithColor::error() << "reproducer replay failed: " << error << '\n';
- return 1;
- }
- return 0;
- }
-
bool capture = input_args.hasArg(OPT_capture);
bool generate_on_exit = input_args.hasArg(OPT_generate_on_exit);
auto *capture_path = input_args.getLastArg(OPT_capture_path);
@@ -799,18 +762,6 @@ static llvm::Optional<int> InitializeReproducer(llvm::StringRef argv0,
}
if (generate_on_exit)
SBReproducer::SetAutoGenerate(true);
-
- // Register the reproducer signal handler.
- if (!input_args.hasArg(OPT_no_generate_on_signal)) {
- if (const char *reproducer_path = SBReproducer::GetPath()) {
- static std::string *finalize_cmd = new std::string(argv0);
- finalize_cmd->append(" --reproducer-finalize '");
- finalize_cmd->append(reproducer_path);
- finalize_cmd->append("'");
- llvm::sys::AddSignalHandler(reproducer_handler,
- const_cast<char *>(finalize_cmd->c_str()));
- }
- }
}
return llvm::None;
diff --git a/lldb/tools/driver/Options.td b/lldb/tools/driver/Options.td
index d59ac314d594..9e6ee390eead 100644
--- a/lldb/tools/driver/Options.td
+++ b/lldb/tools/driver/Options.td
@@ -233,17 +233,6 @@ def capture: F<"capture">,
def capture_path: Separate<["--", "-"], "capture-path">,
MetaVarName<"<filename>">,
HelpText<"Tells the debugger to use the given filename for the reproducer.">;
-def replay: Separate<["--", "-"], "replay">,
- MetaVarName<"<filename>">,
- HelpText<"Tells the debugger to replay a reproducer from <filename>.">;
-def reproducer_finalize: Separate<["--", "-"], "reproducer-finalize">,
- MetaVarName<"<filename>">;
-def no_version_check: F<"reproducer-no-version-check">,
- HelpText<"Disable the reproducer version check.">;
-def no_verification: F<"reproducer-no-verify">,
- HelpText<"Disable the reproducer verification.">;
-def no_generate_on_signal: F<"reproducer-no-generate-on-signal">,
- HelpText<"Don't generate reproducer when a signal is received.">;
def generate_on_exit: F<"reproducer-generate-on-exit">,
HelpText<"Generate reproducer on exit.">;
diff --git a/lldb/tools/lldb-server/lldb-server.cpp b/lldb/tools/lldb-server/lldb-server.cpp
index 1e001ac7185b..1808ffc0c979 100644
--- a/lldb/tools/lldb-server/lldb-server.cpp
+++ b/lldb/tools/lldb-server/lldb-server.cpp
@@ -8,7 +8,7 @@
#include "SystemInitializerLLGS.h"
#include "lldb/Initialization/SystemLifetimeManager.h"
-#include "lldb/lldb-private.h"
+#include "lldb/Version/Version.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"