xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1dda28197Spatrick //===-- JITLoaderGDB.cpp --------------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9061da546Spatrick #include "JITLoaderGDB.h"
10061da546Spatrick #include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
11061da546Spatrick #include "lldb/Breakpoint/Breakpoint.h"
12061da546Spatrick #include "lldb/Core/Module.h"
13061da546Spatrick #include "lldb/Core/ModuleSpec.h"
14061da546Spatrick #include "lldb/Core/PluginManager.h"
15061da546Spatrick #include "lldb/Core/Section.h"
16061da546Spatrick #include "lldb/Interpreter/OptionValueProperties.h"
17061da546Spatrick #include "lldb/Symbol/ObjectFile.h"
18061da546Spatrick #include "lldb/Symbol/Symbol.h"
19061da546Spatrick #include "lldb/Symbol/SymbolContext.h"
20061da546Spatrick #include "lldb/Symbol/SymbolVendor.h"
21061da546Spatrick #include "lldb/Target/Process.h"
22061da546Spatrick #include "lldb/Target/SectionLoadList.h"
23061da546Spatrick #include "lldb/Target/Target.h"
24061da546Spatrick #include "lldb/Utility/DataBufferHeap.h"
25061da546Spatrick #include "lldb/Utility/LLDBAssert.h"
26*f6aab3d8Srobert #include "lldb/Utility/LLDBLog.h"
27061da546Spatrick #include "lldb/Utility/Log.h"
28061da546Spatrick #include "lldb/Utility/StreamString.h"
29061da546Spatrick #include "llvm/Support/MathExtras.h"
30061da546Spatrick 
31061da546Spatrick #include <memory>
32061da546Spatrick 
33061da546Spatrick using namespace lldb;
34061da546Spatrick using namespace lldb_private;
35061da546Spatrick 
36dda28197Spatrick LLDB_PLUGIN_DEFINE(JITLoaderGDB)
37dda28197Spatrick 
38061da546Spatrick // Debug Interface Structures
39061da546Spatrick enum jit_actions_t { JIT_NOACTION = 0, JIT_REGISTER_FN, JIT_UNREGISTER_FN };
40061da546Spatrick 
41061da546Spatrick template <typename ptr_t> struct jit_code_entry {
42061da546Spatrick   ptr_t next_entry;   // pointer
43061da546Spatrick   ptr_t prev_entry;   // pointer
44061da546Spatrick   ptr_t symfile_addr; // pointer
45061da546Spatrick   uint64_t symfile_size;
46061da546Spatrick };
47061da546Spatrick 
48061da546Spatrick template <typename ptr_t> struct jit_descriptor {
49061da546Spatrick   uint32_t version;
50061da546Spatrick   uint32_t action_flag; // Values are jit_action_t
51061da546Spatrick   ptr_t relevant_entry; // pointer
52061da546Spatrick   ptr_t first_entry;    // pointer
53061da546Spatrick };
54061da546Spatrick 
55061da546Spatrick namespace {
56061da546Spatrick enum EnableJITLoaderGDB {
57061da546Spatrick   eEnableJITLoaderGDBDefault,
58061da546Spatrick   eEnableJITLoaderGDBOn,
59061da546Spatrick   eEnableJITLoaderGDBOff,
60061da546Spatrick };
61061da546Spatrick 
62061da546Spatrick static constexpr OptionEnumValueElement g_enable_jit_loader_gdb_enumerators[] =
63061da546Spatrick     {
64061da546Spatrick         {
65061da546Spatrick             eEnableJITLoaderGDBDefault,
66061da546Spatrick             "default",
67061da546Spatrick             "Enable JIT compilation interface for all platforms except macOS",
68061da546Spatrick         },
69061da546Spatrick         {
70061da546Spatrick             eEnableJITLoaderGDBOn,
71061da546Spatrick             "on",
72061da546Spatrick             "Enable JIT compilation interface",
73061da546Spatrick         },
74061da546Spatrick         {
75061da546Spatrick             eEnableJITLoaderGDBOff,
76061da546Spatrick             "off",
77061da546Spatrick             "Disable JIT compilation interface",
78061da546Spatrick         },
79061da546Spatrick };
80061da546Spatrick 
81061da546Spatrick #define LLDB_PROPERTIES_jitloadergdb
82061da546Spatrick #include "JITLoaderGDBProperties.inc"
83061da546Spatrick 
84061da546Spatrick enum {
85061da546Spatrick #define LLDB_PROPERTIES_jitloadergdb
86061da546Spatrick #include "JITLoaderGDBPropertiesEnum.inc"
87061da546Spatrick   ePropertyEnableJITBreakpoint
88061da546Spatrick };
89061da546Spatrick 
90061da546Spatrick class PluginProperties : public Properties {
91061da546Spatrick public:
GetSettingName()92061da546Spatrick   static ConstString GetSettingName() {
93*f6aab3d8Srobert     return ConstString(JITLoaderGDB::GetPluginNameStatic());
94061da546Spatrick   }
95061da546Spatrick 
PluginProperties()96061da546Spatrick   PluginProperties() {
97061da546Spatrick     m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
98061da546Spatrick     m_collection_sp->Initialize(g_jitloadergdb_properties);
99061da546Spatrick   }
100061da546Spatrick 
GetEnable() const101061da546Spatrick   EnableJITLoaderGDB GetEnable() const {
102061da546Spatrick     return (EnableJITLoaderGDB)m_collection_sp->GetPropertyAtIndexAsEnumeration(
103061da546Spatrick         nullptr, ePropertyEnable,
104061da546Spatrick         g_jitloadergdb_properties[ePropertyEnable].default_uint_value);
105061da546Spatrick   }
106061da546Spatrick };
107*f6aab3d8Srobert } // namespace
108061da546Spatrick 
GetGlobalPluginProperties()109*f6aab3d8Srobert static PluginProperties &GetGlobalPluginProperties() {
110*f6aab3d8Srobert   static PluginProperties g_settings;
111*f6aab3d8Srobert   return g_settings;
112061da546Spatrick }
113061da546Spatrick 
114061da546Spatrick template <typename ptr_t>
ReadJITEntry(const addr_t from_addr,Process * process,jit_code_entry<ptr_t> * entry)115*f6aab3d8Srobert static bool ReadJITEntry(const addr_t from_addr, Process *process,
116061da546Spatrick                          jit_code_entry<ptr_t> *entry) {
117061da546Spatrick   lldbassert(from_addr % sizeof(ptr_t) == 0);
118061da546Spatrick 
119061da546Spatrick   ArchSpec::Core core = process->GetTarget().GetArchitecture().GetCore();
120061da546Spatrick   bool i386_target = ArchSpec::kCore_x86_32_first <= core &&
121061da546Spatrick                      core <= ArchSpec::kCore_x86_32_last;
122061da546Spatrick   uint8_t uint64_align_bytes = i386_target ? 4 : 8;
123061da546Spatrick   const size_t data_byte_size =
124061da546Spatrick       llvm::alignTo(sizeof(ptr_t) * 3, uint64_align_bytes) + sizeof(uint64_t);
125061da546Spatrick 
126061da546Spatrick   Status error;
127061da546Spatrick   DataBufferHeap data(data_byte_size, 0);
128061da546Spatrick   size_t bytes_read = process->ReadMemory(from_addr, data.GetBytes(),
129061da546Spatrick                                           data.GetByteSize(), error);
130061da546Spatrick   if (bytes_read != data_byte_size || !error.Success())
131061da546Spatrick     return false;
132061da546Spatrick 
133061da546Spatrick   DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
134061da546Spatrick                           process->GetByteOrder(), sizeof(ptr_t));
135061da546Spatrick   lldb::offset_t offset = 0;
136dda28197Spatrick   entry->next_entry = extractor.GetAddress(&offset);
137dda28197Spatrick   entry->prev_entry = extractor.GetAddress(&offset);
138dda28197Spatrick   entry->symfile_addr = extractor.GetAddress(&offset);
139061da546Spatrick   offset = llvm::alignTo(offset, uint64_align_bytes);
140061da546Spatrick   entry->symfile_size = extractor.GetU64(&offset);
141061da546Spatrick 
142061da546Spatrick   return true;
143061da546Spatrick }
144061da546Spatrick 
JITLoaderGDB(lldb_private::Process * process)145061da546Spatrick JITLoaderGDB::JITLoaderGDB(lldb_private::Process *process)
146061da546Spatrick     : JITLoader(process), m_jit_objects(),
147061da546Spatrick       m_jit_break_id(LLDB_INVALID_BREAK_ID),
148061da546Spatrick       m_jit_descriptor_addr(LLDB_INVALID_ADDRESS) {}
149061da546Spatrick 
~JITLoaderGDB()150061da546Spatrick JITLoaderGDB::~JITLoaderGDB() {
151061da546Spatrick   if (LLDB_BREAK_ID_IS_VALID(m_jit_break_id))
152061da546Spatrick     m_process->GetTarget().RemoveBreakpointByID(m_jit_break_id);
153061da546Spatrick }
154061da546Spatrick 
DebuggerInitialize(Debugger & debugger)155061da546Spatrick void JITLoaderGDB::DebuggerInitialize(Debugger &debugger) {
156061da546Spatrick   if (!PluginManager::GetSettingForJITLoaderPlugin(
157061da546Spatrick           debugger, PluginProperties::GetSettingName())) {
158061da546Spatrick     const bool is_global_setting = true;
159061da546Spatrick     PluginManager::CreateSettingForJITLoaderPlugin(
160*f6aab3d8Srobert         debugger, GetGlobalPluginProperties().GetValueProperties(),
161061da546Spatrick         ConstString("Properties for the JIT LoaderGDB plug-in."),
162061da546Spatrick         is_global_setting);
163061da546Spatrick   }
164061da546Spatrick }
165061da546Spatrick 
DidAttach()166061da546Spatrick void JITLoaderGDB::DidAttach() {
167061da546Spatrick   Target &target = m_process->GetTarget();
168061da546Spatrick   ModuleList &module_list = target.GetImages();
169061da546Spatrick   SetJITBreakpoint(module_list);
170061da546Spatrick }
171061da546Spatrick 
DidLaunch()172061da546Spatrick void JITLoaderGDB::DidLaunch() {
173061da546Spatrick   Target &target = m_process->GetTarget();
174061da546Spatrick   ModuleList &module_list = target.GetImages();
175061da546Spatrick   SetJITBreakpoint(module_list);
176061da546Spatrick }
177061da546Spatrick 
ModulesDidLoad(ModuleList & module_list)178061da546Spatrick void JITLoaderGDB::ModulesDidLoad(ModuleList &module_list) {
179061da546Spatrick   if (!DidSetJITBreakpoint() && m_process->IsAlive())
180061da546Spatrick     SetJITBreakpoint(module_list);
181061da546Spatrick }
182061da546Spatrick 
183061da546Spatrick // Setup the JIT Breakpoint
SetJITBreakpoint(lldb_private::ModuleList & module_list)184061da546Spatrick void JITLoaderGDB::SetJITBreakpoint(lldb_private::ModuleList &module_list) {
185061da546Spatrick   if (DidSetJITBreakpoint())
186061da546Spatrick     return;
187061da546Spatrick 
188*f6aab3d8Srobert   Log *log = GetLog(LLDBLog::JITLoader);
189061da546Spatrick   LLDB_LOGF(log, "JITLoaderGDB::%s looking for JIT register hook",
190061da546Spatrick             __FUNCTION__);
191061da546Spatrick 
192061da546Spatrick   addr_t jit_addr = GetSymbolAddress(
193*f6aab3d8Srobert       module_list, ConstString("__jit_debug_register_code"), eSymbolTypeCode);
194061da546Spatrick   if (jit_addr == LLDB_INVALID_ADDRESS)
195061da546Spatrick     return;
196061da546Spatrick 
197061da546Spatrick   m_jit_descriptor_addr = GetSymbolAddress(
198061da546Spatrick       module_list, ConstString("__jit_debug_descriptor"), eSymbolTypeData);
199061da546Spatrick   if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS) {
200061da546Spatrick     LLDB_LOGF(log, "JITLoaderGDB::%s failed to find JIT descriptor address",
201061da546Spatrick               __FUNCTION__);
202061da546Spatrick     return;
203061da546Spatrick   }
204061da546Spatrick 
205061da546Spatrick   LLDB_LOGF(log, "JITLoaderGDB::%s setting JIT breakpoint", __FUNCTION__);
206061da546Spatrick 
207061da546Spatrick   Breakpoint *bp =
208061da546Spatrick       m_process->GetTarget().CreateBreakpoint(jit_addr, true, false).get();
209061da546Spatrick   bp->SetCallback(JITDebugBreakpointHit, this, true);
210061da546Spatrick   bp->SetBreakpointKind("jit-debug-register");
211061da546Spatrick   m_jit_break_id = bp->GetID();
212061da546Spatrick 
213061da546Spatrick   ReadJITDescriptor(true);
214061da546Spatrick }
215061da546Spatrick 
JITDebugBreakpointHit(void * baton,StoppointCallbackContext * context,user_id_t break_id,user_id_t break_loc_id)216061da546Spatrick bool JITLoaderGDB::JITDebugBreakpointHit(void *baton,
217061da546Spatrick                                          StoppointCallbackContext *context,
218061da546Spatrick                                          user_id_t break_id,
219061da546Spatrick                                          user_id_t break_loc_id) {
220*f6aab3d8Srobert   Log *log = GetLog(LLDBLog::JITLoader);
221061da546Spatrick   LLDB_LOGF(log, "JITLoaderGDB::%s hit JIT breakpoint", __FUNCTION__);
222061da546Spatrick   JITLoaderGDB *instance = static_cast<JITLoaderGDB *>(baton);
223061da546Spatrick   return instance->ReadJITDescriptor(false);
224061da546Spatrick }
225061da546Spatrick 
updateSectionLoadAddress(const SectionList & section_list,Target & target,uint64_t symbolfile_addr,uint64_t symbolfile_size,uint64_t & vmaddrheuristic,uint64_t & min_addr,uint64_t & max_addr)226061da546Spatrick static void updateSectionLoadAddress(const SectionList &section_list,
227061da546Spatrick                                      Target &target, uint64_t symbolfile_addr,
228061da546Spatrick                                      uint64_t symbolfile_size,
229061da546Spatrick                                      uint64_t &vmaddrheuristic,
230061da546Spatrick                                      uint64_t &min_addr, uint64_t &max_addr) {
231061da546Spatrick   const uint32_t num_sections = section_list.GetSize();
232061da546Spatrick   for (uint32_t i = 0; i < num_sections; ++i) {
233061da546Spatrick     SectionSP section_sp(section_list.GetSectionAtIndex(i));
234061da546Spatrick     if (section_sp) {
235061da546Spatrick       if (section_sp->IsFake()) {
236061da546Spatrick         uint64_t lower = (uint64_t)-1;
237061da546Spatrick         uint64_t upper = 0;
238061da546Spatrick         updateSectionLoadAddress(section_sp->GetChildren(), target,
239061da546Spatrick                                  symbolfile_addr, symbolfile_size,
240061da546Spatrick                                  vmaddrheuristic, lower, upper);
241061da546Spatrick         if (lower < min_addr)
242061da546Spatrick           min_addr = lower;
243061da546Spatrick         if (upper > max_addr)
244061da546Spatrick           max_addr = upper;
245061da546Spatrick         const lldb::addr_t slide_amount = lower - section_sp->GetFileAddress();
246061da546Spatrick         section_sp->Slide(slide_amount, false);
247061da546Spatrick         section_sp->GetChildren().Slide(-slide_amount, false);
248061da546Spatrick         section_sp->SetByteSize(upper - lower);
249061da546Spatrick       } else {
250061da546Spatrick         vmaddrheuristic += 2 << section_sp->GetLog2Align();
251061da546Spatrick         uint64_t lower;
252061da546Spatrick         if (section_sp->GetFileAddress() > vmaddrheuristic)
253061da546Spatrick           lower = section_sp->GetFileAddress();
254061da546Spatrick         else {
255061da546Spatrick           lower = symbolfile_addr + section_sp->GetFileOffset();
256061da546Spatrick           section_sp->SetFileAddress(symbolfile_addr +
257061da546Spatrick                                      section_sp->GetFileOffset());
258061da546Spatrick         }
259061da546Spatrick         target.SetSectionLoadAddress(section_sp, lower, true);
260061da546Spatrick         uint64_t upper = lower + section_sp->GetByteSize();
261061da546Spatrick         if (lower < min_addr)
262061da546Spatrick           min_addr = lower;
263061da546Spatrick         if (upper > max_addr)
264061da546Spatrick           max_addr = upper;
265061da546Spatrick         // This is an upper bound, but a good enough heuristic
266061da546Spatrick         vmaddrheuristic += section_sp->GetByteSize();
267061da546Spatrick       }
268061da546Spatrick     }
269061da546Spatrick   }
270061da546Spatrick }
271061da546Spatrick 
ReadJITDescriptor(bool all_entries)272061da546Spatrick bool JITLoaderGDB::ReadJITDescriptor(bool all_entries) {
273061da546Spatrick   if (m_process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
274061da546Spatrick     return ReadJITDescriptorImpl<uint64_t>(all_entries);
275061da546Spatrick   else
276061da546Spatrick     return ReadJITDescriptorImpl<uint32_t>(all_entries);
277061da546Spatrick }
278061da546Spatrick 
279061da546Spatrick template <typename ptr_t>
ReadJITDescriptorImpl(bool all_entries)280061da546Spatrick bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) {
281061da546Spatrick   if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS)
282061da546Spatrick     return false;
283061da546Spatrick 
284*f6aab3d8Srobert   Log *log = GetLog(LLDBLog::JITLoader);
285061da546Spatrick   Target &target = m_process->GetTarget();
286061da546Spatrick   ModuleList &module_list = target.GetImages();
287061da546Spatrick 
288061da546Spatrick   jit_descriptor<ptr_t> jit_desc;
289061da546Spatrick   const size_t jit_desc_size = sizeof(jit_desc);
290061da546Spatrick   Status error;
291be691f3bSpatrick   size_t bytes_read = m_process->ReadMemory(m_jit_descriptor_addr, &jit_desc,
292061da546Spatrick                                             jit_desc_size, error);
293061da546Spatrick   if (bytes_read != jit_desc_size || !error.Success()) {
294061da546Spatrick     LLDB_LOGF(log, "JITLoaderGDB::%s failed to read JIT descriptor",
295061da546Spatrick               __FUNCTION__);
296061da546Spatrick     return false;
297061da546Spatrick   }
298061da546Spatrick 
299061da546Spatrick   jit_actions_t jit_action = (jit_actions_t)jit_desc.action_flag;
300061da546Spatrick   addr_t jit_relevant_entry = (addr_t)jit_desc.relevant_entry;
301061da546Spatrick   if (all_entries) {
302061da546Spatrick     jit_action = JIT_REGISTER_FN;
303061da546Spatrick     jit_relevant_entry = (addr_t)jit_desc.first_entry;
304061da546Spatrick   }
305061da546Spatrick 
306061da546Spatrick   while (jit_relevant_entry != 0) {
307061da546Spatrick     jit_code_entry<ptr_t> jit_entry;
308061da546Spatrick     if (!ReadJITEntry(jit_relevant_entry, m_process, &jit_entry)) {
309061da546Spatrick       LLDB_LOGF(log, "JITLoaderGDB::%s failed to read JIT entry at 0x%" PRIx64,
310061da546Spatrick                 __FUNCTION__, jit_relevant_entry);
311061da546Spatrick       return false;
312061da546Spatrick     }
313061da546Spatrick 
314061da546Spatrick     const addr_t &symbolfile_addr = (addr_t)jit_entry.symfile_addr;
315061da546Spatrick     const size_t &symbolfile_size = (size_t)jit_entry.symfile_size;
316061da546Spatrick     ModuleSP module_sp;
317061da546Spatrick 
318061da546Spatrick     if (jit_action == JIT_REGISTER_FN) {
319061da546Spatrick       LLDB_LOGF(log,
320061da546Spatrick                 "JITLoaderGDB::%s registering JIT entry at 0x%" PRIx64
321061da546Spatrick                 " (%" PRIu64 " bytes)",
322061da546Spatrick                 __FUNCTION__, symbolfile_addr, (uint64_t)symbolfile_size);
323061da546Spatrick 
324061da546Spatrick       char jit_name[64];
325061da546Spatrick       snprintf(jit_name, 64, "JIT(0x%" PRIx64 ")", symbolfile_addr);
326061da546Spatrick       module_sp = m_process->ReadModuleFromMemory(
327061da546Spatrick           FileSpec(jit_name), symbolfile_addr, symbolfile_size);
328061da546Spatrick 
329061da546Spatrick       if (module_sp && module_sp->GetObjectFile()) {
330061da546Spatrick         // Object formats (like ELF) have no representation for a JIT type.
331061da546Spatrick         // We will get it wrong, if we deduce it from the header.
332061da546Spatrick         module_sp->GetObjectFile()->SetType(ObjectFile::eTypeJIT);
333061da546Spatrick 
334061da546Spatrick         // load the symbol table right away
335061da546Spatrick         module_sp->GetObjectFile()->GetSymtab();
336061da546Spatrick 
337061da546Spatrick         m_jit_objects.insert(std::make_pair(symbolfile_addr, module_sp));
338061da546Spatrick         if (auto image_object_file =
339061da546Spatrick                 llvm::dyn_cast<ObjectFileMachO>(module_sp->GetObjectFile())) {
340061da546Spatrick           const SectionList *section_list = image_object_file->GetSectionList();
341061da546Spatrick           if (section_list) {
342061da546Spatrick             uint64_t vmaddrheuristic = 0;
343061da546Spatrick             uint64_t lower = (uint64_t)-1;
344061da546Spatrick             uint64_t upper = 0;
345061da546Spatrick             updateSectionLoadAddress(*section_list, target, symbolfile_addr,
346061da546Spatrick                                      symbolfile_size, vmaddrheuristic, lower,
347061da546Spatrick                                      upper);
348061da546Spatrick           }
349061da546Spatrick         } else {
350061da546Spatrick           bool changed = false;
351061da546Spatrick           module_sp->SetLoadAddress(target, 0, true, changed);
352061da546Spatrick         }
353061da546Spatrick 
354061da546Spatrick         module_list.AppendIfNeeded(module_sp);
355061da546Spatrick 
356061da546Spatrick         ModuleList module_list;
357061da546Spatrick         module_list.Append(module_sp);
358061da546Spatrick         target.ModulesDidLoad(module_list);
359061da546Spatrick       } else {
360061da546Spatrick         LLDB_LOGF(log,
361061da546Spatrick                   "JITLoaderGDB::%s failed to load module for "
362061da546Spatrick                   "JIT entry at 0x%" PRIx64,
363061da546Spatrick                   __FUNCTION__, symbolfile_addr);
364061da546Spatrick       }
365061da546Spatrick     } else if (jit_action == JIT_UNREGISTER_FN) {
366061da546Spatrick       LLDB_LOGF(log, "JITLoaderGDB::%s unregistering JIT entry at 0x%" PRIx64,
367061da546Spatrick                 __FUNCTION__, symbolfile_addr);
368061da546Spatrick 
369061da546Spatrick       JITObjectMap::iterator it = m_jit_objects.find(symbolfile_addr);
370061da546Spatrick       if (it != m_jit_objects.end()) {
371061da546Spatrick         module_sp = it->second;
372061da546Spatrick         ObjectFile *image_object_file = module_sp->GetObjectFile();
373061da546Spatrick         if (image_object_file) {
374061da546Spatrick           const SectionList *section_list = image_object_file->GetSectionList();
375061da546Spatrick           if (section_list) {
376061da546Spatrick             const uint32_t num_sections = section_list->GetSize();
377061da546Spatrick             for (uint32_t i = 0; i < num_sections; ++i) {
378061da546Spatrick               SectionSP section_sp(section_list->GetSectionAtIndex(i));
379061da546Spatrick               if (section_sp) {
380061da546Spatrick                 target.GetSectionLoadList().SetSectionUnloaded(section_sp);
381061da546Spatrick               }
382061da546Spatrick             }
383061da546Spatrick           }
384061da546Spatrick         }
385061da546Spatrick         module_list.Remove(module_sp);
386061da546Spatrick         m_jit_objects.erase(it);
387061da546Spatrick       }
388061da546Spatrick     } else if (jit_action == JIT_NOACTION) {
389061da546Spatrick       // Nothing to do
390061da546Spatrick     } else {
391061da546Spatrick       assert(false && "Unknown jit action");
392061da546Spatrick     }
393061da546Spatrick 
394061da546Spatrick     if (all_entries)
395061da546Spatrick       jit_relevant_entry = (addr_t)jit_entry.next_entry;
396061da546Spatrick     else
397061da546Spatrick       jit_relevant_entry = 0;
398061da546Spatrick   }
399061da546Spatrick 
400061da546Spatrick   return false; // Continue Running.
401061da546Spatrick }
402061da546Spatrick 
403061da546Spatrick // PluginInterface protocol
CreateInstance(Process * process,bool force)404061da546Spatrick JITLoaderSP JITLoaderGDB::CreateInstance(Process *process, bool force) {
405061da546Spatrick   JITLoaderSP jit_loader_sp;
406061da546Spatrick   bool enable;
407*f6aab3d8Srobert   switch (GetGlobalPluginProperties().GetEnable()) {
408061da546Spatrick     case EnableJITLoaderGDB::eEnableJITLoaderGDBOn:
409061da546Spatrick       enable = true;
410061da546Spatrick       break;
411061da546Spatrick     case EnableJITLoaderGDB::eEnableJITLoaderGDBOff:
412061da546Spatrick       enable = false;
413061da546Spatrick       break;
414061da546Spatrick     case EnableJITLoaderGDB::eEnableJITLoaderGDBDefault:
415061da546Spatrick       ArchSpec arch(process->GetTarget().GetArchitecture());
416061da546Spatrick       enable = arch.GetTriple().getVendor() != llvm::Triple::Apple;
417061da546Spatrick       break;
418061da546Spatrick   }
419061da546Spatrick   if (enable)
420061da546Spatrick     jit_loader_sp = std::make_shared<JITLoaderGDB>(process);
421061da546Spatrick   return jit_loader_sp;
422061da546Spatrick }
423061da546Spatrick 
GetPluginDescriptionStatic()424*f6aab3d8Srobert llvm::StringRef JITLoaderGDB::GetPluginDescriptionStatic() {
425061da546Spatrick   return "JIT loader plug-in that watches for JIT events using the GDB "
426061da546Spatrick          "interface.";
427061da546Spatrick }
428061da546Spatrick 
Initialize()429061da546Spatrick void JITLoaderGDB::Initialize() {
430061da546Spatrick   PluginManager::RegisterPlugin(GetPluginNameStatic(),
431061da546Spatrick                                 GetPluginDescriptionStatic(), CreateInstance,
432061da546Spatrick                                 DebuggerInitialize);
433061da546Spatrick }
434061da546Spatrick 
Terminate()435061da546Spatrick void JITLoaderGDB::Terminate() {
436061da546Spatrick   PluginManager::UnregisterPlugin(CreateInstance);
437061da546Spatrick }
438061da546Spatrick 
DidSetJITBreakpoint() const439061da546Spatrick bool JITLoaderGDB::DidSetJITBreakpoint() const {
440061da546Spatrick   return LLDB_BREAK_ID_IS_VALID(m_jit_break_id);
441061da546Spatrick }
442061da546Spatrick 
GetSymbolAddress(ModuleList & module_list,ConstString name,SymbolType symbol_type) const443061da546Spatrick addr_t JITLoaderGDB::GetSymbolAddress(ModuleList &module_list,
444061da546Spatrick                                       ConstString name,
445061da546Spatrick                                       SymbolType symbol_type) const {
446061da546Spatrick   SymbolContextList target_symbols;
447061da546Spatrick   Target &target = m_process->GetTarget();
448061da546Spatrick 
449061da546Spatrick   module_list.FindSymbolsWithNameAndType(name, symbol_type, target_symbols);
450061da546Spatrick   if (target_symbols.IsEmpty())
451061da546Spatrick     return LLDB_INVALID_ADDRESS;
452061da546Spatrick 
453061da546Spatrick   SymbolContext sym_ctx;
454061da546Spatrick   target_symbols.GetContextAtIndex(0, sym_ctx);
455061da546Spatrick 
456061da546Spatrick   const Address jit_descriptor_addr = sym_ctx.symbol->GetAddress();
457061da546Spatrick   if (!jit_descriptor_addr.IsValid())
458061da546Spatrick     return LLDB_INVALID_ADDRESS;
459061da546Spatrick 
460061da546Spatrick   const addr_t jit_addr = jit_descriptor_addr.GetLoadAddress(&target);
461061da546Spatrick   return jit_addr;
462061da546Spatrick }
463