blob: a6db810ac77ff6a0d2e86141297bd216d9563770 [file] [log] [blame]
Andrew MacPherson17220c12014-03-05 10:12:43 +00001//===-- JITLoaderGDB.cpp ----------------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Andrew MacPherson17220c12014-03-05 10:12:43 +00006//
7//===----------------------------------------------------------------------===//
8
Andrew MacPherson17220c12014-03-05 10:12:43 +00009
Siva Chandra02f593f2016-03-23 23:27:23 +000010#include "llvm/Support/MathExtras.h"
11
Andrew MacPherson17220c12014-03-05 10:12:43 +000012#include "lldb/Breakpoint/Breakpoint.h"
Andrew MacPherson17220c12014-03-05 10:12:43 +000013#include "lldb/Core/Module.h"
14#include "lldb/Core/ModuleSpec.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000015#include "lldb/Core/PluginManager.h"
Andrew MacPherson17220c12014-03-05 10:12:43 +000016#include "lldb/Core/Section.h"
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +000017#include "lldb/Interpreter/OptionValueProperties.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000018#include "lldb/Symbol/ObjectFile.h"
19#include "lldb/Symbol/Symbol.h"
Zachary Turner32abc6e2015-03-03 19:23:09 +000020#include "lldb/Symbol/SymbolContext.h"
21#include "lldb/Symbol/SymbolVendor.h"
Andrew MacPherson17220c12014-03-05 10:12:43 +000022#include "lldb/Target/Process.h"
23#include "lldb/Target/SectionLoadList.h"
24#include "lldb/Target/Target.h"
Zachary Turner666cc0b2017-03-04 01:30:05 +000025#include "lldb/Utility/DataBufferHeap.h"
Siva Chandra02f593f2016-03-23 23:27:23 +000026#include "lldb/Utility/LLDBAssert.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000027#include "lldb/Utility/Log.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000028#include "lldb/Utility/StreamString.h"
Andrew MacPherson17220c12014-03-05 10:12:43 +000029
30#include "JITLoaderGDB.h"
31
Jonas Devlieghere796ac802019-02-11 23:13:08 +000032#include <memory>
33
Andrew MacPherson17220c12014-03-05 10:12:43 +000034using namespace lldb;
35using namespace lldb_private;
36
Siva Chandra02f593f2016-03-23 23:27:23 +000037// Debug Interface Structures
Fangrui Songefe8e7e2019-05-14 08:55:50 +000038enum jit_actions_t { JIT_NOACTION = 0, JIT_REGISTER_FN, JIT_UNREGISTER_FN };
Siva Chandra02f593f2016-03-23 23:27:23 +000039
Kate Stoneb9c1b512016-09-06 20:57:50 +000040template <typename ptr_t> struct jit_code_entry {
41 ptr_t next_entry; // pointer
42 ptr_t prev_entry; // pointer
43 ptr_t symfile_addr; // pointer
44 uint64_t symfile_size;
Siva Chandra02f593f2016-03-23 23:27:23 +000045};
46
Kate Stoneb9c1b512016-09-06 20:57:50 +000047template <typename ptr_t> struct jit_descriptor {
48 uint32_t version;
49 uint32_t action_flag; // Values are jit_action_t
50 ptr_t relevant_entry; // pointer
51 ptr_t first_entry; // pointer
Siva Chandra02f593f2016-03-23 23:27:23 +000052};
53
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +000054namespace {
55
Yury Delendikbc6b2252019-03-05 14:23:53 +000056enum EnableJITLoaderGDB {
57 eEnableJITLoaderGDBDefault,
58 eEnableJITLoaderGDBOn,
59 eEnableJITLoaderGDBOff,
60};
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +000061
Yury Delendikbc6b2252019-03-05 14:23:53 +000062static constexpr OptionEnumValueElement g_enable_jit_loader_gdb_enumerators[] = {
63 {eEnableJITLoaderGDBDefault, "default", "Enable JIT compilation interface "
64 "for all platforms except macOS"},
65 {eEnableJITLoaderGDBOn, "on", "Enable JIT compilation interface"},
66 {eEnableJITLoaderGDBOff, "off", "Disable JIT compilation interface"}
67 };
68
69static constexpr PropertyDefinition g_properties[] = {
Jonas Devlieghere971f9ca2019-07-25 21:36:37 +000070#define LLDB_PROPERTIES_jitloadergdb
71#include "Properties.inc"
72};
Yury Delendikbc6b2252019-03-05 14:23:53 +000073
Jonas Devlieghere971f9ca2019-07-25 21:36:37 +000074enum {
75#define LLDB_PROPERTIES_jitloadergdb
76#include "PropertiesEnum.inc"
77 ePropertyEnableJITBreakpoint
78};
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +000079
Kate Stoneb9c1b512016-09-06 20:57:50 +000080class PluginProperties : public Properties {
81public:
82 static ConstString GetSettingName() {
83 return JITLoaderGDB::GetPluginNameStatic();
84 }
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +000085
Kate Stoneb9c1b512016-09-06 20:57:50 +000086 PluginProperties() {
Jonas Devlieghere796ac802019-02-11 23:13:08 +000087 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
Kate Stoneb9c1b512016-09-06 20:57:50 +000088 m_collection_sp->Initialize(g_properties);
89 }
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +000090
Yury Delendikbc6b2252019-03-05 14:23:53 +000091 EnableJITLoaderGDB GetEnable() const {
92 return (EnableJITLoaderGDB)m_collection_sp->GetPropertyAtIndexAsEnumeration(
93 nullptr, ePropertyEnable,
94 g_properties[ePropertyEnable].default_uint_value);
Kate Stoneb9c1b512016-09-06 20:57:50 +000095 }
96};
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +000097
Kate Stoneb9c1b512016-09-06 20:57:50 +000098typedef std::shared_ptr<PluginProperties> JITLoaderGDBPropertiesSP;
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +000099
Kate Stoneb9c1b512016-09-06 20:57:50 +0000100static const JITLoaderGDBPropertiesSP &GetGlobalPluginProperties() {
101 static const auto g_settings_sp(std::make_shared<PluginProperties>());
102 return g_settings_sp;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000103}
104
Kate Stoneb9c1b512016-09-06 20:57:50 +0000105template <typename ptr_t>
106bool ReadJITEntry(const addr_t from_addr, Process *process,
107 jit_code_entry<ptr_t> *entry) {
108 lldbassert(from_addr % sizeof(ptr_t) == 0);
109
110 ArchSpec::Core core = process->GetTarget().GetArchitecture().GetCore();
111 bool i386_target = ArchSpec::kCore_x86_32_first <= core &&
112 core <= ArchSpec::kCore_x86_32_last;
113 uint8_t uint64_align_bytes = i386_target ? 4 : 8;
114 const size_t data_byte_size =
115 llvm::alignTo(sizeof(ptr_t) * 3, uint64_align_bytes) + sizeof(uint64_t);
116
Zachary Turner97206d52017-05-12 04:51:55 +0000117 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000118 DataBufferHeap data(data_byte_size, 0);
119 size_t bytes_read = process->ReadMemory(from_addr, data.GetBytes(),
120 data.GetByteSize(), error);
121 if (bytes_read != data_byte_size || !error.Success())
122 return false;
123
124 DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
125 process->GetByteOrder(), sizeof(ptr_t));
126 lldb::offset_t offset = 0;
127 entry->next_entry = extractor.GetPointer(&offset);
128 entry->prev_entry = extractor.GetPointer(&offset);
129 entry->symfile_addr = extractor.GetPointer(&offset);
130 offset = llvm::alignTo(offset, uint64_align_bytes);
131 entry->symfile_size = extractor.GetU64(&offset);
132
133 return true;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000134}
135
Kate Stoneb9c1b512016-09-06 20:57:50 +0000136} // anonymous namespace end
137
138JITLoaderGDB::JITLoaderGDB(lldb_private::Process *process)
139 : JITLoader(process), m_jit_objects(),
140 m_jit_break_id(LLDB_INVALID_BREAK_ID),
141 m_jit_descriptor_addr(LLDB_INVALID_ADDRESS) {}
142
143JITLoaderGDB::~JITLoaderGDB() {
144 if (LLDB_BREAK_ID_IS_VALID(m_jit_break_id))
145 m_process->GetTarget().RemoveBreakpointByID(m_jit_break_id);
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +0000146}
147
Kate Stoneb9c1b512016-09-06 20:57:50 +0000148void JITLoaderGDB::DebuggerInitialize(Debugger &debugger) {
149 if (!PluginManager::GetSettingForJITLoaderPlugin(
150 debugger, PluginProperties::GetSettingName())) {
151 const bool is_global_setting = true;
152 PluginManager::CreateSettingForJITLoaderPlugin(
153 debugger, GetGlobalPluginProperties()->GetValueProperties(),
154 ConstString("Properties for the JIT LoaderGDB plug-in."),
155 is_global_setting);
156 }
157}
158
159void JITLoaderGDB::DidAttach() {
160 Target &target = m_process->GetTarget();
161 ModuleList &module_list = target.GetImages();
162 SetJITBreakpoint(module_list);
163}
164
165void JITLoaderGDB::DidLaunch() {
166 Target &target = m_process->GetTarget();
167 ModuleList &module_list = target.GetImages();
168 SetJITBreakpoint(module_list);
169}
170
171void JITLoaderGDB::ModulesDidLoad(ModuleList &module_list) {
172 if (!DidSetJITBreakpoint() && m_process->IsAlive())
Andrew MacPhersoneb4d0602014-03-13 09:37:02 +0000173 SetJITBreakpoint(module_list);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000174}
175
Andrew MacPherson17220c12014-03-05 10:12:43 +0000176// Setup the JIT Breakpoint
Kate Stoneb9c1b512016-09-06 20:57:50 +0000177void JITLoaderGDB::SetJITBreakpoint(lldb_private::ModuleList &module_list) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000178 if (DidSetJITBreakpoint())
179 return;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000180
Kate Stoneb9c1b512016-09-06 20:57:50 +0000181 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000182 LLDB_LOGF(log, "JITLoaderGDB::%s looking for JIT register hook",
183 __FUNCTION__);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000184
185 addr_t jit_addr = GetSymbolAddress(
186 module_list, ConstString("__jit_debug_register_code"), eSymbolTypeAny);
187 if (jit_addr == LLDB_INVALID_ADDRESS)
188 return;
189
190 m_jit_descriptor_addr = GetSymbolAddress(
191 module_list, ConstString("__jit_debug_descriptor"), eSymbolTypeData);
192 if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS) {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000193 LLDB_LOGF(log, "JITLoaderGDB::%s failed to find JIT descriptor address",
194 __FUNCTION__);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000195 return;
196 }
Andrew MacPherson17220c12014-03-05 10:12:43 +0000197
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000198 LLDB_LOGF(log, "JITLoaderGDB::%s setting JIT breakpoint", __FUNCTION__);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000199
Kate Stoneb9c1b512016-09-06 20:57:50 +0000200 Breakpoint *bp =
201 m_process->GetTarget().CreateBreakpoint(jit_addr, true, false).get();
202 bp->SetCallback(JITDebugBreakpointHit, this, true);
203 bp->SetBreakpointKind("jit-debug-register");
204 m_jit_break_id = bp->GetID();
Andrew MacPhersoneb4d0602014-03-13 09:37:02 +0000205
Kate Stoneb9c1b512016-09-06 20:57:50 +0000206 ReadJITDescriptor(true);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000207}
208
Kate Stoneb9c1b512016-09-06 20:57:50 +0000209bool JITLoaderGDB::JITDebugBreakpointHit(void *baton,
210 StoppointCallbackContext *context,
211 user_id_t break_id,
212 user_id_t break_loc_id) {
213 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000214 LLDB_LOGF(log, "JITLoaderGDB::%s hit JIT breakpoint", __FUNCTION__);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000215 JITLoaderGDB *instance = static_cast<JITLoaderGDB *>(baton);
216 return instance->ReadJITDescriptor(false);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000217}
218
Greg Clayton48672af2014-06-24 22:22:43 +0000219static void updateSectionLoadAddress(const SectionList &section_list,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000220 Target &target, uint64_t symbolfile_addr,
Greg Clayton48672af2014-06-24 22:22:43 +0000221 uint64_t symbolfile_size,
222 uint64_t &vmaddrheuristic,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000223 uint64_t &min_addr, uint64_t &max_addr) {
224 const uint32_t num_sections = section_list.GetSize();
225 for (uint32_t i = 0; i < num_sections; ++i) {
226 SectionSP section_sp(section_list.GetSectionAtIndex(i));
227 if (section_sp) {
228 if (section_sp->IsFake()) {
229 uint64_t lower = (uint64_t)-1;
230 uint64_t upper = 0;
231 updateSectionLoadAddress(section_sp->GetChildren(), target,
232 symbolfile_addr, symbolfile_size,
233 vmaddrheuristic, lower, upper);
234 if (lower < min_addr)
235 min_addr = lower;
236 if (upper > max_addr)
237 max_addr = upper;
238 const lldb::addr_t slide_amount = lower - section_sp->GetFileAddress();
239 section_sp->Slide(slide_amount, false);
240 section_sp->GetChildren().Slide(-slide_amount, false);
241 section_sp->SetByteSize(upper - lower);
242 } else {
243 vmaddrheuristic += 2 << section_sp->GetLog2Align();
244 uint64_t lower;
245 if (section_sp->GetFileAddress() > vmaddrheuristic)
246 lower = section_sp->GetFileAddress();
247 else {
248 lower = symbolfile_addr + section_sp->GetFileOffset();
249 section_sp->SetFileAddress(symbolfile_addr +
250 section_sp->GetFileOffset());
Greg Clayton48672af2014-06-24 22:22:43 +0000251 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000252 target.SetSectionLoadAddress(section_sp, lower, true);
253 uint64_t upper = lower + section_sp->GetByteSize();
254 if (lower < min_addr)
255 min_addr = lower;
256 if (upper > max_addr)
257 max_addr = upper;
258 // This is an upper bound, but a good enough heuristic
259 vmaddrheuristic += section_sp->GetByteSize();
260 }
Greg Clayton48672af2014-06-24 22:22:43 +0000261 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000262 }
Greg Clayton48672af2014-06-24 22:22:43 +0000263}
264
Kate Stoneb9c1b512016-09-06 20:57:50 +0000265bool JITLoaderGDB::ReadJITDescriptor(bool all_entries) {
266 if (m_process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
267 return ReadJITDescriptorImpl<uint64_t>(all_entries);
268 else
269 return ReadJITDescriptorImpl<uint32_t>(all_entries);
Todd Fiala49bc2d9d2014-09-15 19:55:27 +0000270}
271
Siva Chandra02f593f2016-03-23 23:27:23 +0000272template <typename ptr_t>
Kate Stoneb9c1b512016-09-06 20:57:50 +0000273bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) {
274 if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS)
275 return false;
Andrew MacPhersoneb4d0602014-03-13 09:37:02 +0000276
Kate Stoneb9c1b512016-09-06 20:57:50 +0000277 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
278 Target &target = m_process->GetTarget();
279 ModuleList &module_list = target.GetImages();
Andrew MacPherson17220c12014-03-05 10:12:43 +0000280
Kate Stoneb9c1b512016-09-06 20:57:50 +0000281 jit_descriptor<ptr_t> jit_desc;
282 const size_t jit_desc_size = sizeof(jit_desc);
Zachary Turner97206d52017-05-12 04:51:55 +0000283 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000284 size_t bytes_read = m_process->DoReadMemory(m_jit_descriptor_addr, &jit_desc,
285 jit_desc_size, error);
286 if (bytes_read != jit_desc_size || !error.Success()) {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000287 LLDB_LOGF(log, "JITLoaderGDB::%s failed to read JIT descriptor",
288 __FUNCTION__);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000289 return false;
290 }
Andrew MacPherson17220c12014-03-05 10:12:43 +0000291
Kate Stoneb9c1b512016-09-06 20:57:50 +0000292 jit_actions_t jit_action = (jit_actions_t)jit_desc.action_flag;
293 addr_t jit_relevant_entry = (addr_t)jit_desc.relevant_entry;
294 if (all_entries) {
295 jit_action = JIT_REGISTER_FN;
296 jit_relevant_entry = (addr_t)jit_desc.first_entry;
297 }
Andrew MacPherson17220c12014-03-05 10:12:43 +0000298
Kate Stoneb9c1b512016-09-06 20:57:50 +0000299 while (jit_relevant_entry != 0) {
300 jit_code_entry<ptr_t> jit_entry;
301 if (!ReadJITEntry(jit_relevant_entry, m_process, &jit_entry)) {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000302 LLDB_LOGF(log, "JITLoaderGDB::%s failed to read JIT entry at 0x%" PRIx64,
303 __FUNCTION__, jit_relevant_entry);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000304 return false;
305 }
Andrew MacPherson17220c12014-03-05 10:12:43 +0000306
Kate Stoneb9c1b512016-09-06 20:57:50 +0000307 const addr_t &symbolfile_addr = (addr_t)jit_entry.symfile_addr;
308 const size_t &symbolfile_size = (size_t)jit_entry.symfile_size;
309 ModuleSP module_sp;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000310
Kate Stoneb9c1b512016-09-06 20:57:50 +0000311 if (jit_action == JIT_REGISTER_FN) {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000312 LLDB_LOGF(log,
313 "JITLoaderGDB::%s registering JIT entry at 0x%" PRIx64
314 " (%" PRIu64 " bytes)",
315 __FUNCTION__, symbolfile_addr, (uint64_t)symbolfile_size);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000316
Kate Stoneb9c1b512016-09-06 20:57:50 +0000317 char jit_name[64];
318 snprintf(jit_name, 64, "JIT(0x%" PRIx64 ")", symbolfile_addr);
319 module_sp = m_process->ReadModuleFromMemory(
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +0000320 FileSpec(jit_name), symbolfile_addr, symbolfile_size);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000321
Kate Stoneb9c1b512016-09-06 20:57:50 +0000322 if (module_sp && module_sp->GetObjectFile()) {
Stefan Granitzf0ee69f2019-05-09 16:40:57 +0000323 // Object formats (like ELF) have no representation for a JIT type.
324 // We will get it wrong, if we deduce it from the header.
325 module_sp->GetObjectFile()->SetType(ObjectFile::eTypeJIT);
326
Kate Stoneb9c1b512016-09-06 20:57:50 +0000327 // load the symbol table right away
328 module_sp->GetObjectFile()->GetSymtab();
Tamas Berghammer31a2f8f2016-02-25 12:23:43 +0000329
Kate Stoneb9c1b512016-09-06 20:57:50 +0000330 m_jit_objects.insert(std::make_pair(symbolfile_addr, module_sp));
331 if (module_sp->GetObjectFile()->GetPluginName() ==
332 ConstString("mach-o")) {
333 ObjectFile *image_object_file = module_sp->GetObjectFile();
334 if (image_object_file) {
335 const SectionList *section_list =
336 image_object_file->GetSectionList();
337 if (section_list) {
338 uint64_t vmaddrheuristic = 0;
339 uint64_t lower = (uint64_t)-1;
340 uint64_t upper = 0;
341 updateSectionLoadAddress(*section_list, target, symbolfile_addr,
342 symbolfile_size, vmaddrheuristic, lower,
343 upper);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000344 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000345 }
346 } else {
347 bool changed = false;
348 module_sp->SetLoadAddress(target, 0, true, changed);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000349 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000350
351 module_list.AppendIfNeeded(module_sp);
352
353 ModuleList module_list;
354 module_list.Append(module_sp);
355 target.ModulesDidLoad(module_list);
356 } else {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000357 LLDB_LOGF(log,
358 "JITLoaderGDB::%s failed to load module for "
359 "JIT entry at 0x%" PRIx64,
360 __FUNCTION__, symbolfile_addr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000361 }
362 } else if (jit_action == JIT_UNREGISTER_FN) {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000363 LLDB_LOGF(log, "JITLoaderGDB::%s unregistering JIT entry at 0x%" PRIx64,
364 __FUNCTION__, symbolfile_addr);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000365
Kate Stoneb9c1b512016-09-06 20:57:50 +0000366 JITObjectMap::iterator it = m_jit_objects.find(symbolfile_addr);
367 if (it != m_jit_objects.end()) {
368 module_sp = it->second;
369 ObjectFile *image_object_file = module_sp->GetObjectFile();
370 if (image_object_file) {
371 const SectionList *section_list = image_object_file->GetSectionList();
372 if (section_list) {
373 const uint32_t num_sections = section_list->GetSize();
374 for (uint32_t i = 0; i < num_sections; ++i) {
375 SectionSP section_sp(section_list->GetSectionAtIndex(i));
376 if (section_sp) {
377 target.GetSectionLoadList().SetSectionUnloaded(section_sp);
378 }
Andrew MacPherson17220c12014-03-05 10:12:43 +0000379 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000380 }
Andrew MacPherson17220c12014-03-05 10:12:43 +0000381 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000382 module_list.Remove(module_sp);
383 m_jit_objects.erase(it);
384 }
385 } else if (jit_action == JIT_NOACTION) {
386 // Nothing to do
387 } else {
388 assert(false && "Unknown jit action");
Andrew MacPherson17220c12014-03-05 10:12:43 +0000389 }
390
Kate Stoneb9c1b512016-09-06 20:57:50 +0000391 if (all_entries)
392 jit_relevant_entry = (addr_t)jit_entry.next_entry;
393 else
394 jit_relevant_entry = 0;
395 }
396
397 return false; // Continue Running.
Andrew MacPherson17220c12014-03-05 10:12:43 +0000398}
399
Andrew MacPherson17220c12014-03-05 10:12:43 +0000400// PluginInterface protocol
Kate Stoneb9c1b512016-09-06 20:57:50 +0000401lldb_private::ConstString JITLoaderGDB::GetPluginNameStatic() {
402 static ConstString g_name("gdb");
403 return g_name;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000404}
405
Kate Stoneb9c1b512016-09-06 20:57:50 +0000406JITLoaderSP JITLoaderGDB::CreateInstance(Process *process, bool force) {
407 JITLoaderSP jit_loader_sp;
Yury Delendikbc6b2252019-03-05 14:23:53 +0000408 bool enable;
409 switch (GetGlobalPluginProperties()->GetEnable()) {
410 case EnableJITLoaderGDB::eEnableJITLoaderGDBOn:
411 enable = true;
412 break;
413 case EnableJITLoaderGDB::eEnableJITLoaderGDBOff:
414 enable = false;
415 break;
416 case EnableJITLoaderGDB::eEnableJITLoaderGDBDefault:
417 ArchSpec arch(process->GetTarget().GetArchitecture());
418 enable = arch.GetTriple().getVendor() != llvm::Triple::Apple;
419 break;
420 }
421 if (enable)
Jonas Devlieghere796ac802019-02-11 23:13:08 +0000422 jit_loader_sp = std::make_shared<JITLoaderGDB>(process);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000423 return jit_loader_sp;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000424}
425
Kate Stoneb9c1b512016-09-06 20:57:50 +0000426const char *JITLoaderGDB::GetPluginDescriptionStatic() {
427 return "JIT loader plug-in that watches for JIT events using the GDB "
428 "interface.";
Andrew MacPherson17220c12014-03-05 10:12:43 +0000429}
430
Kate Stoneb9c1b512016-09-06 20:57:50 +0000431lldb_private::ConstString JITLoaderGDB::GetPluginName() {
432 return GetPluginNameStatic();
Andrew MacPherson17220c12014-03-05 10:12:43 +0000433}
434
Kate Stoneb9c1b512016-09-06 20:57:50 +0000435uint32_t JITLoaderGDB::GetPluginVersion() { return 1; }
436
437void JITLoaderGDB::Initialize() {
438 PluginManager::RegisterPlugin(GetPluginNameStatic(),
439 GetPluginDescriptionStatic(), CreateInstance,
440 DebuggerInitialize);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000441}
442
Kate Stoneb9c1b512016-09-06 20:57:50 +0000443void JITLoaderGDB::Terminate() {
444 PluginManager::UnregisterPlugin(CreateInstance);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000445}
446
Kate Stoneb9c1b512016-09-06 20:57:50 +0000447bool JITLoaderGDB::DidSetJITBreakpoint() const {
448 return LLDB_BREAK_ID_IS_VALID(m_jit_break_id);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000449}
450
Kate Stoneb9c1b512016-09-06 20:57:50 +0000451addr_t JITLoaderGDB::GetSymbolAddress(ModuleList &module_list,
Adrian Prantl0e4c4822019-03-06 21:22:25 +0000452 ConstString name,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000453 SymbolType symbol_type) const {
454 SymbolContextList target_symbols;
455 Target &target = m_process->GetTarget();
Andrew MacPherson17220c12014-03-05 10:12:43 +0000456
Kate Stoneb9c1b512016-09-06 20:57:50 +0000457 if (!module_list.FindSymbolsWithNameAndType(name, symbol_type,
458 target_symbols))
459 return LLDB_INVALID_ADDRESS;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000460
Kate Stoneb9c1b512016-09-06 20:57:50 +0000461 SymbolContext sym_ctx;
462 target_symbols.GetContextAtIndex(0, sym_ctx);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000463
Kate Stoneb9c1b512016-09-06 20:57:50 +0000464 const Address jit_descriptor_addr = sym_ctx.symbol->GetAddress();
465 if (!jit_descriptor_addr.IsValid())
466 return LLDB_INVALID_ADDRESS;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000467
Kate Stoneb9c1b512016-09-06 20:57:50 +0000468 const addr_t jit_addr = jit_descriptor_addr.GetLoadAddress(&target);
469 return jit_addr;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000470}