diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/Makefile --- a/lldb/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/Makefile +++ b/lldb/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/Makefile @@ -2,4 +2,12 @@ C_SOURCES := main.c +all: a.out simple + include $(LEVEL)/Makefile.rules + +simple: + $(MAKE) VPATH=$(VPATH) -f $(SRCDIR)/simple.mk + +clean:: + $(MAKE) -f $(SRCDIR)/simple.mk clean \ No newline at end of file diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/TestJITLoaderGDB.py b/lldb/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/TestJITLoaderGDB.py --- a/lldb/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/TestJITLoaderGDB.py +++ b/lldb/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/TestJITLoaderGDB.py @@ -10,6 +10,7 @@ from lldbsuite.test.lldbtest import * import re +file_index = 0 class JITLoaderGDBTestCase(TestBase): @@ -38,3 +39,80 @@ self.assertEqual(process.GetState(), lldb.eStateExited) self.assertEqual(process.GetExitStatus(), 0) + + def gen_log_file(self): + global file_index + ++file_index + logfile = os.path.join( + self.getBuildDir(), + "jitintgdb-" + self.getArchitecture() + "-" + + str(file_index) + ".txt") + + def cleanup(): + if os.path.exists(logfile): + os.unlink(logfile) + self.addTearDownHook(cleanup) + return logfile + + def test_jit_int_default(self): + self.expect("settings show plugin.jit-loader.gdb.enable", + substrs=["plugin.jit-loader.gdb.enable (enum) = default"]) + + def test_jit_int_on(self): + """Tests interface with 'enable' settings 'on'""" + self.build() + exe = self.getBuildArtifact("simple") + + logfile = self.gen_log_file() + self.runCmd("log enable -f %s lldb jit" % (logfile)) + self.runCmd("settings set plugin.jit-loader.gdb.enable on") + def cleanup(): + self.runCmd("log disable lldb") + self.runCmd("settings set plugin.jit-loader.gdb.enable default") + self.addTearDownHook(cleanup) + + # launch the process + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + self.assertEqual(process.GetState(), lldb.eStateExited) + self.assertEqual(process.GetExitStatus(), 0) + + logcontent = "" + if os.path.exists(logfile): + logcontent = open(logfile).read() + self.assertIn( + "SetJITBreakpoint setting JIT breakpoint", logcontent) + + def test_jit_int_off(self): + """Tests interface with 'enable' settings 'off'""" + self.build() + exe = self.getBuildArtifact("simple") + + logfile = self.gen_log_file() + self.runCmd("log enable -f %s lldb jit" % (logfile)) + self.runCmd("settings set plugin.jit-loader.gdb.enable off") + def cleanup(): + self.runCmd("log disable lldb") + self.runCmd("settings set plugin.jit-loader.gdb.enable default") + self.addTearDownHook(cleanup) + + # launch the process + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + self.assertEqual(process.GetState(), lldb.eStateExited) + self.assertEqual(process.GetExitStatus(), 0) + + if os.path.exists(logfile): + logcontent = open(logfile).read() + self.assertNotIn( + "SetJITBreakpoint setting JIT breakpoint", logcontent) + else: + self.assertTrue(false) diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/simple.c b/lldb/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/simple.c new file mode 100644 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/simple.c @@ -0,0 +1,20 @@ +#include + +// GDB JIT interface stub +struct +{ + uint32_t version; + uint32_t action_flag; + void* relevant_entry; + void* first_entry; +} __jit_debug_descriptor = { 1, 0, 0, 0 }; + +void __jit_debug_register_code() +{ +} +// end GDB JIT interface stub + +int main() +{ + return 0; +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/simple.mk copy from lldb/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/Makefile copy to lldb/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/simple.mk --- a/lldb/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/Makefile +++ b/lldb/packages/Python/lldbsuite/test/functionalities/jitloader_gdb/simple.mk @@ -1,5 +1,6 @@ LEVEL = ../../make -C_SOURCES := main.c +C_SOURCES := simple.c +EXE = simple include $(LEVEL)/Makefile.rules diff --git a/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp b/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp --- a/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp +++ b/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp @@ -57,11 +57,27 @@ namespace { +enum EnableJITLoaderGDB { + eEnableJITLoaderGDBDefault, + eEnableJITLoaderGDBOn, + eEnableJITLoaderGDBOff, +}; + +static constexpr OptionEnumValueElement g_enable_jit_loader_gdb_enumerators[] = { + {eEnableJITLoaderGDBDefault, "default", "Enable JIT compilation interface " + "for all platforms except macOS"}, + {eEnableJITLoaderGDBOn, "on", "Enable JIT compilation interface"}, + {eEnableJITLoaderGDBOff, "off", "Disable JIT compilation interface"} + }; + static constexpr PropertyDefinition g_properties[] = { - {"enable-jit-breakpoint", OptionValue::eTypeBoolean, true, true, nullptr, - {}, "Enable breakpoint on __jit_debug_register_code."}}; + {"enable", OptionValue::eTypeEnum, true, + eEnableJITLoaderGDBDefault, nullptr, + OptionEnumValues(g_enable_jit_loader_gdb_enumerators), + "Enable GDB's JIT compilation interface (default: enabled on " + "all platforms except macOS)"}}; -enum { ePropertyEnableJITBreakpoint }; +enum { ePropertyEnable, ePropertyEnableJITBreakpoint }; class PluginProperties : public Properties { public: @@ -74,10 +90,10 @@ m_collection_sp->Initialize(g_properties); } - bool GetEnableJITBreakpoint() const { - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, ePropertyEnableJITBreakpoint, - g_properties[ePropertyEnableJITBreakpoint].default_uint_value != 0); + EnableJITLoaderGDB GetEnable() const { + return (EnableJITLoaderGDB)m_collection_sp->GetPropertyAtIndexAsEnumeration( + nullptr, ePropertyEnable, + g_properties[ePropertyEnable].default_uint_value); } }; @@ -163,9 +179,6 @@ // Setup the JIT Breakpoint //------------------------------------------------------------------ void JITLoaderGDB::SetJITBreakpoint(lldb_private::ModuleList &module_list) { - if (!GetGlobalPluginProperties()->GetEnableJITBreakpoint()) - return; - if (DidSetJITBreakpoint()) return; @@ -400,8 +413,20 @@ JITLoaderSP JITLoaderGDB::CreateInstance(Process *process, bool force) { JITLoaderSP jit_loader_sp; - ArchSpec arch(process->GetTarget().GetArchitecture()); - if (arch.GetTriple().getVendor() != llvm::Triple::Apple) + bool enable; + switch (GetGlobalPluginProperties()->GetEnable()) { + case EnableJITLoaderGDB::eEnableJITLoaderGDBOn: + enable = true; + break; + case EnableJITLoaderGDB::eEnableJITLoaderGDBOff: + enable = false; + break; + case EnableJITLoaderGDB::eEnableJITLoaderGDBDefault: + ArchSpec arch(process->GetTarget().GetArchitecture()); + enable = arch.GetTriple().getVendor() != llvm::Triple::Apple; + break; + } + if (enable) jit_loader_sp.reset(new JITLoaderGDB(process)); return jit_loader_sp; }