xref: /freebsd/contrib/llvm-project/lldb/source/API/SystemInitializerFull.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- SystemInitializerFull.cpp -----------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "SystemInitializerFull.h"
10 #include "lldb/API/SBCommandInterpreter.h"
11 #include "lldb/API/SBDebugger.h"
12 #include "lldb/Core/Debugger.h"
13 #include "lldb/Core/PluginManager.h"
14 #include "lldb/Core/Progress.h"
15 #include "lldb/Host/Config.h"
16 #include "lldb/Host/Host.h"
17 #include "lldb/Initialization/SystemInitializerCommon.h"
18 #include "lldb/Interpreter/CommandInterpreter.h"
19 #include "lldb/Target/ProcessTrace.h"
20 #include "lldb/Utility/Timer.h"
21 #include "lldb/Version/Version.h"
22 #include "llvm/Support/CommandLine.h"
23 #include "llvm/Support/TargetSelect.h"
24 
25 #pragma clang diagnostic push
26 #pragma clang diagnostic ignored "-Wglobal-constructors"
27 #include "llvm/ExecutionEngine/MCJIT.h"
28 #pragma clang diagnostic pop
29 
30 #include <string>
31 
32 #define LLDB_PLUGIN(p) LLDB_PLUGIN_DECLARE(p)
33 #include "Plugins/Plugins.def"
34 
35 #if LLDB_ENABLE_PYTHON
36 #include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h"
37 
38 constexpr lldb_private::HostInfo::SharedLibraryDirectoryHelper
39     *g_shlib_dir_helper =
40         lldb_private::ScriptInterpreterPython::SharedLibraryDirectoryHelper;
41 
42 #else
43 constexpr lldb_private::HostInfo::SharedLibraryDirectoryHelper
44     *g_shlib_dir_helper = nullptr;
45 #endif
46 
47 using namespace lldb_private;
48 
SystemInitializerFull()49 SystemInitializerFull::SystemInitializerFull()
50     : SystemInitializerCommon(g_shlib_dir_helper) {}
51 SystemInitializerFull::~SystemInitializerFull() = default;
52 
Initialize()53 llvm::Error SystemInitializerFull::Initialize() {
54   llvm::Error error = SystemInitializerCommon::Initialize();
55   if (error)
56     return error;
57 
58   // Initialize LLVM and Clang
59   llvm::InitializeAllTargets();
60   llvm::InitializeAllAsmPrinters();
61   llvm::InitializeAllTargetMCs();
62   llvm::InitializeAllDisassemblers();
63 
64   // Initialize the command line parser in LLVM. This usually isn't necessary
65   // as we aren't dealing with command line options here, but otherwise some
66   // other code in Clang/LLVM might be tempted to call this function from a
67   // different thread later on which won't work (as the function isn't
68   // thread-safe).
69   const char *arg0 = "lldb";
70   llvm::cl::ParseCommandLineOptions(1, &arg0);
71 
72 #define LLDB_PLUGIN(p) LLDB_PLUGIN_INITIALIZE(p);
73 #include "Plugins/Plugins.def"
74 
75   // Scan for any system or user LLDB plug-ins.
76   PluginManager::Initialize();
77 
78   // The process settings need to know about installed plug-ins, so the
79   // Settings must be initialized AFTER PluginManager::Initialize is called.
80   Debugger::SettingsInitialize();
81 
82   // Use the Debugger's LLDBAssert callback.
83   SetLLDBAssertCallback(Debugger::AssertCallback);
84 
85   // Use the system log to report errors that would otherwise get dropped.
86   SetLLDBErrorLog(GetLog(SystemLog::System));
87 
88   LLDB_LOG(GetLog(SystemLog::System), "{0}", GetVersion());
89 
90   auto LoadPlugin = [](const lldb::DebuggerSP &debugger_sp,
91                        const FileSpec &spec,
92                        Status &error) -> llvm::sys::DynamicLibrary {
93     llvm::sys::DynamicLibrary dynlib =
94         llvm::sys::DynamicLibrary::getPermanentLibrary(spec.GetPath().c_str());
95     if (dynlib.isValid()) {
96       typedef bool (*LLDBCommandPluginInit)(lldb::SBDebugger debugger);
97 
98       lldb::SBDebugger debugger_sb(debugger_sp);
99       // This calls the bool lldb::PluginInitialize(lldb::SBDebugger debugger)
100       // function.
101       // TODO: mangle this differently for your system - on OSX, the first
102       // underscore needs to be removed and the second one stays
103       LLDBCommandPluginInit init_func =
104           (LLDBCommandPluginInit)(uintptr_t)dynlib.getAddressOfSymbol(
105               "_ZN4lldb16PluginInitializeENS_10SBDebuggerE");
106       if (init_func) {
107         if (init_func(debugger_sb))
108           return dynlib;
109         else
110           error = Status::FromErrorString(
111               "plug-in refused to load "
112               "(lldb::PluginInitialize(lldb::SBDebugger) "
113               "returned false)");
114       } else {
115         error = Status::FromErrorString(
116             "plug-in is missing the required initialization: "
117             "lldb::PluginInitialize(lldb::SBDebugger)");
118       }
119     } else {
120       if (FileSystem::Instance().Exists(spec))
121         error = Status::FromErrorString(
122             "this file does not represent a loadable dylib");
123       else
124         error = Status::FromErrorString("no such file");
125     }
126     return llvm::sys::DynamicLibrary();
127   };
128 
129   Debugger::Initialize(LoadPlugin);
130 
131   return llvm::Error::success();
132 }
133 
Terminate()134 void SystemInitializerFull::Terminate() {
135   Debugger::Terminate();
136 
137   Debugger::SettingsTerminate();
138 
139   // Terminate plug-ins in core LLDB.
140   ProcessTrace::Terminate();
141 
142   // Terminate and unload and loaded system or user LLDB plug-ins.
143   PluginManager::Terminate();
144 
145 #define LLDB_PLUGIN(p) LLDB_PLUGIN_TERMINATE(p);
146 #include "Plugins/Plugins.def"
147 
148   // Now shutdown the common parts, in reverse order.
149   SystemInitializerCommon::Terminate();
150 }
151