blob: 2aa284f2a5c9c3ca83c4be87d9b75b5bbaef90f1 [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
Pavel Labathe84f7842019-07-31 11:57:34 +00009#include "JITLoaderGDB.h"
10#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
Andrew MacPherson17220c12014-03-05 10:12:43 +000011#include "lldb/Breakpoint/Breakpoint.h"
Andrew MacPherson17220c12014-03-05 10:12:43 +000012#include "lldb/Core/Module.h"
13#include "lldb/Core/ModuleSpec.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000014#include "lldb/Core/PluginManager.h"
Andrew MacPherson17220c12014-03-05 10:12:43 +000015#include "lldb/Core/Section.h"
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +000016#include "lldb/Interpreter/OptionValueProperties.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000017#include "lldb/Symbol/ObjectFile.h"
18#include "lldb/Symbol/Symbol.h"
Zachary Turner32abc6e2015-03-03 19:23:09 +000019#include "lldb/Symbol/SymbolContext.h"
20#include "lldb/Symbol/SymbolVendor.h"
Andrew MacPherson17220c12014-03-05 10:12:43 +000021#include "lldb/Target/Process.h"
22#include "lldb/Target/SectionLoadList.h"
23#include "lldb/Target/Target.h"
Zachary Turner666cc0b2017-03-04 01:30:05 +000024#include "lldb/Utility/DataBufferHeap.h"
Siva Chandra02f593f2016-03-23 23:27:23 +000025#include "lldb/Utility/LLDBAssert.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000026#include "lldb/Utility/Log.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000027#include "lldb/Utility/StreamString.h"
Pavel Labathe84f7842019-07-31 11:57:34 +000028#include "llvm/Support/MathExtras.h"
Andrew MacPherson17220c12014-03-05 10:12:43 +000029
Jonas Devlieghere796ac802019-02-11 23:13:08 +000030#include <memory>
31
Andrew MacPherson17220c12014-03-05 10:12:43 +000032using namespace lldb;
33using namespace lldb_private;
34
Siva Chandra02f593f2016-03-23 23:27:23 +000035// Debug Interface Structures
Fangrui Songefe8e7e2019-05-14 08:55:50 +000036enum jit_actions_t { JIT_NOACTION = 0, JIT_REGISTER_FN, JIT_UNREGISTER_FN };
Siva Chandra02f593f2016-03-23 23:27:23 +000037
Kate Stoneb9c1b512016-09-06 20:57:50 +000038template <typename ptr_t> struct jit_code_entry {
39 ptr_t next_entry; // pointer
40 ptr_t prev_entry; // pointer
41 ptr_t symfile_addr; // pointer
42 uint64_t symfile_size;
Siva Chandra02f593f2016-03-23 23:27:23 +000043};
44
Kate Stoneb9c1b512016-09-06 20:57:50 +000045template <typename ptr_t> struct jit_descriptor {
46 uint32_t version;
47 uint32_t action_flag; // Values are jit_action_t
48 ptr_t relevant_entry; // pointer
49 ptr_t first_entry; // pointer
Siva Chandra02f593f2016-03-23 23:27:23 +000050};
51
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +000052namespace {
53
Yury Delendikbc6b2252019-03-05 14:23:53 +000054enum EnableJITLoaderGDB {
55 eEnableJITLoaderGDBDefault,
56 eEnableJITLoaderGDBOn,
57 eEnableJITLoaderGDBOff,
58};
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +000059
Yury Delendikbc6b2252019-03-05 14:23:53 +000060static constexpr OptionEnumValueElement g_enable_jit_loader_gdb_enumerators[] = {
61 {eEnableJITLoaderGDBDefault, "default", "Enable JIT compilation interface "
62 "for all platforms except macOS"},
63 {eEnableJITLoaderGDBOn, "on", "Enable JIT compilation interface"},
64 {eEnableJITLoaderGDBOff, "off", "Disable JIT compilation interface"}
65 };
66
Jonas Devlieghere971f9ca2019-07-25 21:36:37 +000067#define LLDB_PROPERTIES_jitloadergdb
Jordan Rupprecht6a253d32019-07-29 17:22:10 +000068#include "JITLoaderGDBProperties.inc"
Yury Delendikbc6b2252019-03-05 14:23:53 +000069
Jonas Devlieghere971f9ca2019-07-25 21:36:37 +000070enum {
71#define LLDB_PROPERTIES_jitloadergdb
Jordan Rupprecht6a253d32019-07-29 17:22:10 +000072#include "JITLoaderGDBPropertiesEnum.inc"
Jonas Devlieghere971f9ca2019-07-25 21:36:37 +000073 ePropertyEnableJITBreakpoint
74};
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +000075
Kate Stoneb9c1b512016-09-06 20:57:50 +000076class PluginProperties : public Properties {
77public:
78 static ConstString GetSettingName() {
79 return JITLoaderGDB::GetPluginNameStatic();
80 }
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +000081
Kate Stoneb9c1b512016-09-06 20:57:50 +000082 PluginProperties() {
Jonas Devlieghere796ac802019-02-11 23:13:08 +000083 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
Jonas Devliegherea8ea5952019-07-29 16:41:30 +000084 m_collection_sp->Initialize(g_jitloadergdb_properties);
Kate Stoneb9c1b512016-09-06 20:57:50 +000085 }
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +000086
Yury Delendikbc6b2252019-03-05 14:23:53 +000087 EnableJITLoaderGDB GetEnable() const {
88 return (EnableJITLoaderGDB)m_collection_sp->GetPropertyAtIndexAsEnumeration(
89 nullptr, ePropertyEnable,
Jonas Devliegherea8ea5952019-07-29 16:41:30 +000090 g_jitloadergdb_properties[ePropertyEnable].default_uint_value);
Kate Stoneb9c1b512016-09-06 20:57:50 +000091 }
92};
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +000093
Kate Stoneb9c1b512016-09-06 20:57:50 +000094typedef std::shared_ptr<PluginProperties> JITLoaderGDBPropertiesSP;
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +000095
Kate Stoneb9c1b512016-09-06 20:57:50 +000096static const JITLoaderGDBPropertiesSP &GetGlobalPluginProperties() {
97 static const auto g_settings_sp(std::make_shared<PluginProperties>());
98 return g_settings_sp;
Andrew MacPherson17220c12014-03-05 10:12:43 +000099}
100
Kate Stoneb9c1b512016-09-06 20:57:50 +0000101template <typename ptr_t>
102bool ReadJITEntry(const addr_t from_addr, Process *process,
103 jit_code_entry<ptr_t> *entry) {
104 lldbassert(from_addr % sizeof(ptr_t) == 0);
105
106 ArchSpec::Core core = process->GetTarget().GetArchitecture().GetCore();
107 bool i386_target = ArchSpec::kCore_x86_32_first <= core &&
108 core <= ArchSpec::kCore_x86_32_last;
109 uint8_t uint64_align_bytes = i386_target ? 4 : 8;
110 const size_t data_byte_size =
111 llvm::alignTo(sizeof(ptr_t) * 3, uint64_align_bytes) + sizeof(uint64_t);
112
Zachary Turner97206d52017-05-12 04:51:55 +0000113 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000114 DataBufferHeap data(data_byte_size, 0);
115 size_t bytes_read = process->ReadMemory(from_addr, data.GetBytes(),
116 data.GetByteSize(), error);
117 if (bytes_read != data_byte_size || !error.Success())
118 return false;
119
120 DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
121 process->GetByteOrder(), sizeof(ptr_t));
122 lldb::offset_t offset = 0;
123 entry->next_entry = extractor.GetPointer(&offset);
124 entry->prev_entry = extractor.GetPointer(&offset);
125 entry->symfile_addr = extractor.GetPointer(&offset);
126 offset = llvm::alignTo(offset, uint64_align_bytes);
127 entry->symfile_size = extractor.GetU64(&offset);
128
129 return true;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000130}
131
Kate Stoneb9c1b512016-09-06 20:57:50 +0000132} // anonymous namespace end
133
134JITLoaderGDB::JITLoaderGDB(lldb_private::Process *process)
135 : JITLoader(process), m_jit_objects(),
136 m_jit_break_id(LLDB_INVALID_BREAK_ID),
137 m_jit_descriptor_addr(LLDB_INVALID_ADDRESS) {}
138
139JITLoaderGDB::~JITLoaderGDB() {
140 if (LLDB_BREAK_ID_IS_VALID(m_jit_break_id))
141 m_process->GetTarget().RemoveBreakpointByID(m_jit_break_id);
Oleksiy Vyaloveff9ad22015-09-16 17:38:36 +0000142}
143
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144void JITLoaderGDB::DebuggerInitialize(Debugger &debugger) {
145 if (!PluginManager::GetSettingForJITLoaderPlugin(
146 debugger, PluginProperties::GetSettingName())) {
147 const bool is_global_setting = true;
148 PluginManager::CreateSettingForJITLoaderPlugin(
149 debugger, GetGlobalPluginProperties()->GetValueProperties(),
150 ConstString("Properties for the JIT LoaderGDB plug-in."),
151 is_global_setting);
152 }
153}
154
155void JITLoaderGDB::DidAttach() {
156 Target &target = m_process->GetTarget();
157 ModuleList &module_list = target.GetImages();
158 SetJITBreakpoint(module_list);
159}
160
161void JITLoaderGDB::DidLaunch() {
162 Target &target = m_process->GetTarget();
163 ModuleList &module_list = target.GetImages();
164 SetJITBreakpoint(module_list);
165}
166
167void JITLoaderGDB::ModulesDidLoad(ModuleList &module_list) {
168 if (!DidSetJITBreakpoint() && m_process->IsAlive())
Andrew MacPhersoneb4d0602014-03-13 09:37:02 +0000169 SetJITBreakpoint(module_list);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000170}
171
Andrew MacPherson17220c12014-03-05 10:12:43 +0000172// Setup the JIT Breakpoint
Kate Stoneb9c1b512016-09-06 20:57:50 +0000173void JITLoaderGDB::SetJITBreakpoint(lldb_private::ModuleList &module_list) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000174 if (DidSetJITBreakpoint())
175 return;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000176
Kate Stoneb9c1b512016-09-06 20:57:50 +0000177 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000178 LLDB_LOGF(log, "JITLoaderGDB::%s looking for JIT register hook",
179 __FUNCTION__);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000180
181 addr_t jit_addr = GetSymbolAddress(
182 module_list, ConstString("__jit_debug_register_code"), eSymbolTypeAny);
183 if (jit_addr == LLDB_INVALID_ADDRESS)
184 return;
185
186 m_jit_descriptor_addr = GetSymbolAddress(
187 module_list, ConstString("__jit_debug_descriptor"), eSymbolTypeData);
188 if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS) {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000189 LLDB_LOGF(log, "JITLoaderGDB::%s failed to find JIT descriptor address",
190 __FUNCTION__);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000191 return;
192 }
Andrew MacPherson17220c12014-03-05 10:12:43 +0000193
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000194 LLDB_LOGF(log, "JITLoaderGDB::%s setting JIT breakpoint", __FUNCTION__);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000195
Kate Stoneb9c1b512016-09-06 20:57:50 +0000196 Breakpoint *bp =
197 m_process->GetTarget().CreateBreakpoint(jit_addr, true, false).get();
198 bp->SetCallback(JITDebugBreakpointHit, this, true);
199 bp->SetBreakpointKind("jit-debug-register");
200 m_jit_break_id = bp->GetID();
Andrew MacPhersoneb4d0602014-03-13 09:37:02 +0000201
Kate Stoneb9c1b512016-09-06 20:57:50 +0000202 ReadJITDescriptor(true);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000203}
204
Kate Stoneb9c1b512016-09-06 20:57:50 +0000205bool JITLoaderGDB::JITDebugBreakpointHit(void *baton,
206 StoppointCallbackContext *context,
207 user_id_t break_id,
208 user_id_t break_loc_id) {
209 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000210 LLDB_LOGF(log, "JITLoaderGDB::%s hit JIT breakpoint", __FUNCTION__);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000211 JITLoaderGDB *instance = static_cast<JITLoaderGDB *>(baton);
212 return instance->ReadJITDescriptor(false);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000213}
214
Greg Clayton48672af2014-06-24 22:22:43 +0000215static void updateSectionLoadAddress(const SectionList &section_list,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000216 Target &target, uint64_t symbolfile_addr,
Greg Clayton48672af2014-06-24 22:22:43 +0000217 uint64_t symbolfile_size,
218 uint64_t &vmaddrheuristic,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000219 uint64_t &min_addr, uint64_t &max_addr) {
220 const uint32_t num_sections = section_list.GetSize();
221 for (uint32_t i = 0; i < num_sections; ++i) {
222 SectionSP section_sp(section_list.GetSectionAtIndex(i));
223 if (section_sp) {
224 if (section_sp->IsFake()) {
225 uint64_t lower = (uint64_t)-1;
226 uint64_t upper = 0;
227 updateSectionLoadAddress(section_sp->GetChildren(), target,
228 symbolfile_addr, symbolfile_size,
229 vmaddrheuristic, lower, upper);
230 if (lower < min_addr)
231 min_addr = lower;
232 if (upper > max_addr)
233 max_addr = upper;
234 const lldb::addr_t slide_amount = lower - section_sp->GetFileAddress();
235 section_sp->Slide(slide_amount, false);
236 section_sp->GetChildren().Slide(-slide_amount, false);
237 section_sp->SetByteSize(upper - lower);
238 } else {
239 vmaddrheuristic += 2 << section_sp->GetLog2Align();
240 uint64_t lower;
241 if (section_sp->GetFileAddress() > vmaddrheuristic)
242 lower = section_sp->GetFileAddress();
243 else {
244 lower = symbolfile_addr + section_sp->GetFileOffset();
245 section_sp->SetFileAddress(symbolfile_addr +
246 section_sp->GetFileOffset());
Greg Clayton48672af2014-06-24 22:22:43 +0000247 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000248 target.SetSectionLoadAddress(section_sp, lower, true);
249 uint64_t upper = lower + section_sp->GetByteSize();
250 if (lower < min_addr)
251 min_addr = lower;
252 if (upper > max_addr)
253 max_addr = upper;
254 // This is an upper bound, but a good enough heuristic
255 vmaddrheuristic += section_sp->GetByteSize();
256 }
Greg Clayton48672af2014-06-24 22:22:43 +0000257 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000258 }
Greg Clayton48672af2014-06-24 22:22:43 +0000259}
260
Kate Stoneb9c1b512016-09-06 20:57:50 +0000261bool JITLoaderGDB::ReadJITDescriptor(bool all_entries) {
262 if (m_process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
263 return ReadJITDescriptorImpl<uint64_t>(all_entries);
264 else
265 return ReadJITDescriptorImpl<uint32_t>(all_entries);
Todd Fiala49bc2d9d2014-09-15 19:55:27 +0000266}
267
Siva Chandra02f593f2016-03-23 23:27:23 +0000268template <typename ptr_t>
Kate Stoneb9c1b512016-09-06 20:57:50 +0000269bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) {
270 if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS)
271 return false;
Andrew MacPhersoneb4d0602014-03-13 09:37:02 +0000272
Kate Stoneb9c1b512016-09-06 20:57:50 +0000273 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
274 Target &target = m_process->GetTarget();
275 ModuleList &module_list = target.GetImages();
Andrew MacPherson17220c12014-03-05 10:12:43 +0000276
Kate Stoneb9c1b512016-09-06 20:57:50 +0000277 jit_descriptor<ptr_t> jit_desc;
278 const size_t jit_desc_size = sizeof(jit_desc);
Zachary Turner97206d52017-05-12 04:51:55 +0000279 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000280 size_t bytes_read = m_process->DoReadMemory(m_jit_descriptor_addr, &jit_desc,
281 jit_desc_size, error);
282 if (bytes_read != jit_desc_size || !error.Success()) {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000283 LLDB_LOGF(log, "JITLoaderGDB::%s failed to read JIT descriptor",
284 __FUNCTION__);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000285 return false;
286 }
Andrew MacPherson17220c12014-03-05 10:12:43 +0000287
Kate Stoneb9c1b512016-09-06 20:57:50 +0000288 jit_actions_t jit_action = (jit_actions_t)jit_desc.action_flag;
289 addr_t jit_relevant_entry = (addr_t)jit_desc.relevant_entry;
290 if (all_entries) {
291 jit_action = JIT_REGISTER_FN;
292 jit_relevant_entry = (addr_t)jit_desc.first_entry;
293 }
Andrew MacPherson17220c12014-03-05 10:12:43 +0000294
Kate Stoneb9c1b512016-09-06 20:57:50 +0000295 while (jit_relevant_entry != 0) {
296 jit_code_entry<ptr_t> jit_entry;
297 if (!ReadJITEntry(jit_relevant_entry, m_process, &jit_entry)) {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000298 LLDB_LOGF(log, "JITLoaderGDB::%s failed to read JIT entry at 0x%" PRIx64,
299 __FUNCTION__, jit_relevant_entry);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000300 return false;
301 }
Andrew MacPherson17220c12014-03-05 10:12:43 +0000302
Kate Stoneb9c1b512016-09-06 20:57:50 +0000303 const addr_t &symbolfile_addr = (addr_t)jit_entry.symfile_addr;
304 const size_t &symbolfile_size = (size_t)jit_entry.symfile_size;
305 ModuleSP module_sp;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000306
Kate Stoneb9c1b512016-09-06 20:57:50 +0000307 if (jit_action == JIT_REGISTER_FN) {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000308 LLDB_LOGF(log,
309 "JITLoaderGDB::%s registering JIT entry at 0x%" PRIx64
310 " (%" PRIu64 " bytes)",
311 __FUNCTION__, symbolfile_addr, (uint64_t)symbolfile_size);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000312
Kate Stoneb9c1b512016-09-06 20:57:50 +0000313 char jit_name[64];
314 snprintf(jit_name, 64, "JIT(0x%" PRIx64 ")", symbolfile_addr);
315 module_sp = m_process->ReadModuleFromMemory(
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +0000316 FileSpec(jit_name), symbolfile_addr, symbolfile_size);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000317
Kate Stoneb9c1b512016-09-06 20:57:50 +0000318 if (module_sp && module_sp->GetObjectFile()) {
Stefan Granitzf0ee69f2019-05-09 16:40:57 +0000319 // Object formats (like ELF) have no representation for a JIT type.
320 // We will get it wrong, if we deduce it from the header.
321 module_sp->GetObjectFile()->SetType(ObjectFile::eTypeJIT);
322
Kate Stoneb9c1b512016-09-06 20:57:50 +0000323 // load the symbol table right away
324 module_sp->GetObjectFile()->GetSymtab();
Tamas Berghammer31a2f8f2016-02-25 12:23:43 +0000325
Kate Stoneb9c1b512016-09-06 20:57:50 +0000326 m_jit_objects.insert(std::make_pair(symbolfile_addr, module_sp));
Pavel Labathe84f7842019-07-31 11:57:34 +0000327 if (auto image_object_file =
328 llvm::dyn_cast<ObjectFileMachO>(module_sp->GetObjectFile())) {
329 const SectionList *section_list = image_object_file->GetSectionList();
330 if (section_list) {
331 uint64_t vmaddrheuristic = 0;
332 uint64_t lower = (uint64_t)-1;
333 uint64_t upper = 0;
334 updateSectionLoadAddress(*section_list, target, symbolfile_addr,
335 symbolfile_size, vmaddrheuristic, lower,
336 upper);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000337 }
338 } else {
339 bool changed = false;
340 module_sp->SetLoadAddress(target, 0, true, changed);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000341 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000342
343 module_list.AppendIfNeeded(module_sp);
344
345 ModuleList module_list;
346 module_list.Append(module_sp);
347 target.ModulesDidLoad(module_list);
348 } else {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000349 LLDB_LOGF(log,
350 "JITLoaderGDB::%s failed to load module for "
351 "JIT entry at 0x%" PRIx64,
352 __FUNCTION__, symbolfile_addr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000353 }
354 } else if (jit_action == JIT_UNREGISTER_FN) {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000355 LLDB_LOGF(log, "JITLoaderGDB::%s unregistering JIT entry at 0x%" PRIx64,
356 __FUNCTION__, symbolfile_addr);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000357
Kate Stoneb9c1b512016-09-06 20:57:50 +0000358 JITObjectMap::iterator it = m_jit_objects.find(symbolfile_addr);
359 if (it != m_jit_objects.end()) {
360 module_sp = it->second;
361 ObjectFile *image_object_file = module_sp->GetObjectFile();
362 if (image_object_file) {
363 const SectionList *section_list = image_object_file->GetSectionList();
364 if (section_list) {
365 const uint32_t num_sections = section_list->GetSize();
366 for (uint32_t i = 0; i < num_sections; ++i) {
367 SectionSP section_sp(section_list->GetSectionAtIndex(i));
368 if (section_sp) {
369 target.GetSectionLoadList().SetSectionUnloaded(section_sp);
370 }
Andrew MacPherson17220c12014-03-05 10:12:43 +0000371 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000372 }
Andrew MacPherson17220c12014-03-05 10:12:43 +0000373 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000374 module_list.Remove(module_sp);
375 m_jit_objects.erase(it);
376 }
377 } else if (jit_action == JIT_NOACTION) {
378 // Nothing to do
379 } else {
380 assert(false && "Unknown jit action");
Andrew MacPherson17220c12014-03-05 10:12:43 +0000381 }
382
Kate Stoneb9c1b512016-09-06 20:57:50 +0000383 if (all_entries)
384 jit_relevant_entry = (addr_t)jit_entry.next_entry;
385 else
386 jit_relevant_entry = 0;
387 }
388
389 return false; // Continue Running.
Andrew MacPherson17220c12014-03-05 10:12:43 +0000390}
391
Andrew MacPherson17220c12014-03-05 10:12:43 +0000392// PluginInterface protocol
Kate Stoneb9c1b512016-09-06 20:57:50 +0000393lldb_private::ConstString JITLoaderGDB::GetPluginNameStatic() {
394 static ConstString g_name("gdb");
395 return g_name;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000396}
397
Kate Stoneb9c1b512016-09-06 20:57:50 +0000398JITLoaderSP JITLoaderGDB::CreateInstance(Process *process, bool force) {
399 JITLoaderSP jit_loader_sp;
Yury Delendikbc6b2252019-03-05 14:23:53 +0000400 bool enable;
401 switch (GetGlobalPluginProperties()->GetEnable()) {
402 case EnableJITLoaderGDB::eEnableJITLoaderGDBOn:
403 enable = true;
404 break;
405 case EnableJITLoaderGDB::eEnableJITLoaderGDBOff:
406 enable = false;
407 break;
408 case EnableJITLoaderGDB::eEnableJITLoaderGDBDefault:
409 ArchSpec arch(process->GetTarget().GetArchitecture());
410 enable = arch.GetTriple().getVendor() != llvm::Triple::Apple;
411 break;
412 }
413 if (enable)
Jonas Devlieghere796ac802019-02-11 23:13:08 +0000414 jit_loader_sp = std::make_shared<JITLoaderGDB>(process);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000415 return jit_loader_sp;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000416}
417
Kate Stoneb9c1b512016-09-06 20:57:50 +0000418const char *JITLoaderGDB::GetPluginDescriptionStatic() {
419 return "JIT loader plug-in that watches for JIT events using the GDB "
420 "interface.";
Andrew MacPherson17220c12014-03-05 10:12:43 +0000421}
422
Kate Stoneb9c1b512016-09-06 20:57:50 +0000423lldb_private::ConstString JITLoaderGDB::GetPluginName() {
424 return GetPluginNameStatic();
Andrew MacPherson17220c12014-03-05 10:12:43 +0000425}
426
Kate Stoneb9c1b512016-09-06 20:57:50 +0000427uint32_t JITLoaderGDB::GetPluginVersion() { return 1; }
428
429void JITLoaderGDB::Initialize() {
430 PluginManager::RegisterPlugin(GetPluginNameStatic(),
431 GetPluginDescriptionStatic(), CreateInstance,
432 DebuggerInitialize);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000433}
434
Kate Stoneb9c1b512016-09-06 20:57:50 +0000435void JITLoaderGDB::Terminate() {
436 PluginManager::UnregisterPlugin(CreateInstance);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000437}
438
Kate Stoneb9c1b512016-09-06 20:57:50 +0000439bool JITLoaderGDB::DidSetJITBreakpoint() const {
440 return LLDB_BREAK_ID_IS_VALID(m_jit_break_id);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000441}
442
Kate Stoneb9c1b512016-09-06 20:57:50 +0000443addr_t JITLoaderGDB::GetSymbolAddress(ModuleList &module_list,
Adrian Prantl0e4c4822019-03-06 21:22:25 +0000444 ConstString name,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000445 SymbolType symbol_type) const {
446 SymbolContextList target_symbols;
447 Target &target = m_process->GetTarget();
Andrew MacPherson17220c12014-03-05 10:12:43 +0000448
Kate Stoneb9c1b512016-09-06 20:57:50 +0000449 if (!module_list.FindSymbolsWithNameAndType(name, symbol_type,
450 target_symbols))
451 return LLDB_INVALID_ADDRESS;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000452
Kate Stoneb9c1b512016-09-06 20:57:50 +0000453 SymbolContext sym_ctx;
454 target_symbols.GetContextAtIndex(0, sym_ctx);
Andrew MacPherson17220c12014-03-05 10:12:43 +0000455
Kate Stoneb9c1b512016-09-06 20:57:50 +0000456 const Address jit_descriptor_addr = sym_ctx.symbol->GetAddress();
457 if (!jit_descriptor_addr.IsValid())
458 return LLDB_INVALID_ADDRESS;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000459
Kate Stoneb9c1b512016-09-06 20:57:50 +0000460 const addr_t jit_addr = jit_descriptor_addr.GetLoadAddress(&target);
461 return jit_addr;
Andrew MacPherson17220c12014-03-05 10:12:43 +0000462}