diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index f92e63cc45f42a..31c6d27240b389 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -219,7 +219,7 @@ enum ScriptLanguage { eScriptLanguagePython, eScriptLanguageLua, eScriptLanguageUnknown, - eScriptLanguageDefault = eScriptLanguagePython + eScriptLanguageDefault = eScriptLanguageLua }; /// Register numbering types. diff --git a/lldb/source/API/CMakeLists.txt b/lldb/source/API/CMakeLists.txt index 3e189f387f1ca0..de37097f33cec7 100644 --- a/lldb/source/API/CMakeLists.txt +++ b/lldb/source/API/CMakeLists.txt @@ -15,7 +15,7 @@ if(LLDB_ENABLE_LUA) set(lldb_lua_wrapper ${lua_bindings_dir}/LLDBWrapLua.cpp) endif() -add_lldb_library(liblldb SHARED ${option_framework} +add_lldb_library(liblldb STATIC ${option_framework} SBAddress.cpp SBAttachInfo.cpp SBBlock.cpp diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/CMakeLists.txt b/lldb/source/Plugins/ScriptInterpreter/Lua/CMakeLists.txt index 498bd97839510a..ed14fb34e30dbd 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Lua/CMakeLists.txt +++ b/lldb/source/Plugins/ScriptInterpreter/Lua/CMakeLists.txt @@ -1,5 +1,6 @@ add_lldb_library(lldbPluginScriptInterpreterLua PLUGIN Lua.cpp + LuaBuiltin.cpp ScriptInterpreterLua.cpp LINK_LIBS diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp b/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp index b82a2647e9a082..a9d7d84d73decd 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp @@ -37,6 +37,8 @@ Lua::Lua() : m_lua_state(luaL_newstate()) { luaopen_lldb(m_lua_state); lua_pushcfunction(m_lua_state, lldb_print); lua_setglobal(m_lua_state, "print"); + + luaL_dostring(m_lua_state, m_builtin); } Lua::~Lua() { diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h b/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h index 5daedf835b9b52..f9c3de684a5519 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h +++ b/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h @@ -47,6 +47,7 @@ class Lua { private: lua_State *m_lua_state; + static const char m_builtin[]; }; } // namespace lldb_private diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/LuaBuiltin.cpp b/lldb/source/Plugins/ScriptInterpreter/Lua/LuaBuiltin.cpp new file mode 100644 index 00000000000000..2ef796771b06ce --- /dev/null +++ b/lldb/source/Plugins/ScriptInterpreter/Lua/LuaBuiltin.cpp @@ -0,0 +1,103 @@ +#include "Lua.h" + +namespace lldb_private { + +const char Lua::m_builtin[] = u8R"Lua( +local function prepare() + lldb.debugger = lldb.SBDebugger.FindDebuggerWithID(1) + lldb.target = lldb.debugger:GetSelectedTarget() + lldb.process = lldb.target:GetProcess() + lldb.thread = lldb.process:GetSelectedThread() + lldb.frame = lldb.thread:GetSelectedFrame() +end + +local function printf(s, ...) + print(string.format(s, ...)) +end + +local function cmdf(s, ...) + local cmd = string.format(s, ...) + local ret = lldb.SBCommandReturnObject() + local interpreter = lldb.debugger:GetCommandInterpreter() + interpreter:HandleCommand(cmd, ret) + if not ret:Succeeded() then + lldb.debugger:GetErrorFile():Flush() + local err = string.gsub(ret:GetError(), "\n$", "") + error(err) + end + lldb.debugger:GetOutputFile():Flush() + local out = string.gsub(ret:GetOutput(), "\n$", "") + return out +end + +local function evalf(ctx, s, ...) + local expr = string.format(s, ...) + local value = ctx:EvaluateExpression(expr) + if not value:IsValid() then + error("failed evaluating: " .. expr) + end + return value:GetValue() +end + +local function read_string(ctx, expr, len) + local value = ctx:EvaluateExpression(expr) + local err = lldb.SBError() + local process = value:GetProcess() + local buf = process:ReadCStringFromMemory(tonumber(value:GetValue()), len + 1, err) + if not err:Success() then + error(err:GetCString()) + end + -- printf("read_string: [%d] %q", len, buf) + return buf +end + +unreal = {} + +function unreal.pname(index) + pcall(prepare) + local ctx = lldb.target + local shift = tonumber(evalf(ctx, "FNameDebugVisualizer::OffsetBits")) + local mask = tonumber(evalf(ctx, "FNameDebugVisualizer::OffsetMask")) + local stride = tonumber(evalf(ctx, "FNameDebugVisualizer::EntryStride")) + local i = index >> shift + local j = (index & mask) * stride + local entry = evalf(ctx, "&GNameBlocksDebug[%d][%d]", i, j) + -- printf("entry = %q", entry) + local len = tonumber(evalf(ctx, "((FNameEntry*)%s)->Header.Len", entry)) + -- printf("len = %d", len) + local name = read_string(ctx, string.format("&((FNameEntry*)%s)->AnsiName", entry), len) + printf("FName(%d) = %q", index, name) +end + +function unreal.pweak(index) + pcall(prepare) + local chunk = 65536 + local i = index // chunk + local j = index % chunk + print(cmdf("print GUObjectArray.ObjObjects.Objects[%d][%d]", i, j)) +end + +function unreal.ptype(ptr) + pcall(prepare) + local vtable = tonumber(evalf(lldb.target, string.format("*(void**)0x%x", ptr))) + printf("vtable: 0x%x", vtable) + print(cmdf("target modules lookup -a 0x%x", vtable)) +end + +function unreal.vtable(vtable) + pcall(prepare) + local size = tonumber(evalf(lldb.target, "sizeof(void*)")) + for i = 0, 999 do + local vfunc = vtable + (i * size) + local line = cmdf("memory read -c 1 -f A 0x%x", vfunc) + local ptr = select(3, string.find(line, "^%s*%w+:%s+(%w+)")) + if tonumber(ptr) == 0 then + break + end + print(line) + end +end + +)Lua"; + +} // namespace lldb_private diff --git a/lldb/tools/driver/CMakeLists.txt b/lldb/tools/driver/CMakeLists.txt index c93cd171b92b47..92e3a7045869c2 100644 --- a/lldb/tools/driver/CMakeLists.txt +++ b/lldb/tools/driver/CMakeLists.txt @@ -17,6 +17,8 @@ add_lldb_tool(lldb LINK_LIBS liblldb + lldbPluginScriptInterpreterLua # hack for GNU ld + liblldb LINK_COMPONENTS Option diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp index d463267aeef353..958d0605c39424 100644 --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -266,6 +266,8 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) { if (auto *arg = args.getLastArg(OPT_script_language)) { auto arg_value = arg->getValue(); m_debugger.SetScriptLanguage(m_debugger.GetScriptingLanguage(arg_value)); + } else { + m_debugger.SetScriptLanguage(lldb::ScriptLanguage::eScriptLanguageDefault); } if (args.hasArg(OPT_source_quietly)) {