blob: 73ef3151338258a1b3bdb8a6e6d377a92fbc0bd7 [file] [log] [blame]
Andrew MacPherson17220c12014-03-05 10:12:43 +00001//===-- JITLoaderGDB.cpp ----------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// C Includes
11
12#include "lldb/Breakpoint/Breakpoint.h"
13#include "lldb/Core/PluginManager.h"
14#include "lldb/Core/Log.h"
15#include "lldb/Core/Module.h"
16#include "lldb/Core/ModuleSpec.h"
17#include "lldb/Core/Section.h"
18#include "lldb/Core/StreamString.h"
19#include "lldb/Target/Process.h"
20#include "lldb/Target/SectionLoadList.h"
21#include "lldb/Target/Target.h"
22#include "lldb/Symbol/SymbolVendor.h"
23
24#include "JITLoaderGDB.h"
25
26using namespace lldb;
27using namespace lldb_private;
28
29//------------------------------------------------------------------
30// Debug Interface Structures
31//------------------------------------------------------------------
32typedef enum
33{
34 JIT_NOACTION = 0,
35 JIT_REGISTER_FN,
36 JIT_UNREGISTER_FN
37} jit_actions_t;
38
39struct jit_code_entry
40{
41 struct jit_code_entry *next_entry;
42 struct jit_code_entry *prev_entry;
43 const char *symfile_addr;
44 uint64_t symfile_size;
45};
46
47struct jit_descriptor
48{
49 uint32_t version;
50 uint32_t action_flag; // Values are jit_action_t
51 struct jit_code_entry *relevant_entry;
52 struct jit_code_entry *first_entry;
53};
54
55JITLoaderGDB::JITLoaderGDB (lldb_private::Process *process) :
56 JITLoader(process),
57 m_jit_objects(),
58 m_jit_break_id(LLDB_INVALID_BREAK_ID)
59{
60 m_notification_callbacks.baton = this;
61 m_notification_callbacks.initialize = nullptr;
62 m_notification_callbacks.process_state_changed =
63 ProcessStateChangedCallback;
64 m_process->RegisterNotificationCallbacks(m_notification_callbacks);
65}
66
67JITLoaderGDB::~JITLoaderGDB ()
68{
69 if (LLDB_BREAK_ID_IS_VALID(m_jit_break_id))
70 m_process->GetTarget().RemoveBreakpointByID (m_jit_break_id);
71 m_jit_break_id = LLDB_INVALID_BREAK_ID;
72}
73
74void JITLoaderGDB::DidAttach()
75{
76 SetJITBreakpoint();
77}
78
79void JITLoaderGDB::DidLaunch()
80{
81 SetJITBreakpoint();
82}
83
84//------------------------------------------------------------------
85// Setup the JIT Breakpoint
86//------------------------------------------------------------------
87void
88JITLoaderGDB::SetJITBreakpoint()
89{
90 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
91
92 if ( DidSetJITBreakpoint() )
93 return;
94
95 if (log)
96 log->Printf("JITLoaderGDB::%s looking for JIT register hook",
97 __FUNCTION__);
98
99 addr_t jit_addr = GetSymbolAddress(ConstString("__jit_debug_register_code"),
100 eSymbolTypeAny);
101 if (jit_addr == LLDB_INVALID_ADDRESS)
102 return;
103
104 if (log)
105 log->Printf("JITLoaderGDB::%s setting JIT breakpoint",
106 __FUNCTION__);
107
108 Breakpoint *bp =
109 m_process->GetTarget().CreateBreakpoint(jit_addr, true, false).get();
110 bp->SetCallback(JITDebugBreakpointHit, this, true);
111 bp->SetBreakpointKind("jit-debug-register");
112 m_jit_break_id = bp->GetID();
113
114 ReadJITDescriptor(true);
115}
116
117bool
118JITLoaderGDB::JITDebugBreakpointHit(void *baton,
119 StoppointCallbackContext *context,
120 user_id_t break_id, user_id_t break_loc_id)
121{
122 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
123 if (log)
124 log->Printf("JITLoaderGDB::%s hit JIT breakpoint",
125 __FUNCTION__);
126 JITLoaderGDB *instance = static_cast<JITLoaderGDB *>(baton);
127 return instance->ReadJITDescriptor(false);
128}
129
130bool
131JITLoaderGDB::ReadJITDescriptor(bool all_entries)
132{
133 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
134 Target &target = m_process->GetTarget();
135 ModuleList &images = target.GetImages();
136
137 addr_t jit_addr = GetSymbolAddress(ConstString("__jit_debug_descriptor"),
138 eSymbolTypeData);
139 if (jit_addr == LLDB_INVALID_ADDRESS)
140 {
141 if (log)
142 log->Printf(
143 "JITLoaderGDB::%s failed to find JIT descriptor address",
144 __FUNCTION__);
145 return false;
146 }
147
148 jit_descriptor jit_desc;
149 const size_t jit_desc_size = sizeof(jit_desc);
150 Error error;
151 size_t bytes_read =
152 m_process->DoReadMemory(jit_addr, &jit_desc, jit_desc_size, error);
153 if (bytes_read != jit_desc_size || !error.Success())
154 {
155 if (log)
156 log->Printf("JITLoaderGDB::%s failed to read JIT descriptor",
157 __FUNCTION__);
158 return false;
159 }
160
161 jit_actions_t jit_action = (jit_actions_t)jit_desc.action_flag;
162 addr_t jit_relevant_entry = (addr_t)jit_desc.relevant_entry;
163 if (all_entries)
164 {
165 jit_action = JIT_REGISTER_FN;
166 jit_relevant_entry = (addr_t)jit_desc.first_entry;
167 }
168
169 while (jit_relevant_entry != 0)
170 {
171 jit_code_entry jit_entry;
172 const size_t jit_entry_size = sizeof(jit_entry);
173 bytes_read = m_process->DoReadMemory(jit_relevant_entry, &jit_entry, jit_entry_size, error);
174 if (bytes_read != jit_entry_size || !error.Success())
175 {
176 if (log)
177 log->Printf(
178 "JITLoaderGDB::%s failed to read JIT entry at 0x%" PRIx64,
179 __FUNCTION__, jit_relevant_entry);
180 return false;
181 }
182
183 const addr_t &symbolfile_addr = (addr_t)jit_entry.symfile_addr;
184 const size_t &symbolfile_size = (size_t)jit_entry.symfile_size;
185 ModuleSP module_sp;
186
187 if (jit_action == JIT_REGISTER_FN)
188 {
189 if (log)
190 log->Printf(
191 "JITLoaderGDB::%s registering JIT entry at 0x%" PRIx64
192 " (%" PRIu64 " bytes)",
193 __FUNCTION__, symbolfile_addr, symbolfile_size);
194
195 char jit_name[64];
196 snprintf(jit_name, 64, "JIT(0x%" PRIx64 ")", symbolfile_addr);
197 module_sp = m_process->ReadModuleFromMemory(
198 FileSpec(jit_name, false), symbolfile_addr, symbolfile_size);
199
200 if (module_sp && module_sp->GetObjectFile())
201 {
202 bool changed;
203 m_jit_objects.insert(
204 std::pair<lldb::addr_t, const lldb::ModuleSP>(
205 symbolfile_addr, module_sp));
206 module_sp->SetLoadAddress(target, 0, true, changed);
207
208 // load the symbol table right away
209 module_sp->GetObjectFile()->GetSymtab();
210
211 images.AppendIfNeeded(module_sp);
212
213 ModuleList module_list;
214 module_list.Append(module_sp);
215 target.ModulesDidLoad(module_list);
216 }
217 else
218 {
219 if (log)
220 log->Printf("JITLoaderGDB::%s failed to load module for "
221 "JIT entry at 0x%" PRIx64,
222 __FUNCTION__, symbolfile_addr);
223 }
224 }
225 else if (jit_action == JIT_UNREGISTER_FN)
226 {
227 if (log)
228 log->Printf(
229 "JITLoaderGDB::%s unregistering JIT entry at 0x%" PRIx64,
230 __FUNCTION__, symbolfile_addr);
231
232 JITObjectMap::iterator it = m_jit_objects.find(symbolfile_addr);
233 if (it != m_jit_objects.end())
234 {
235 module_sp = it->second;
236 ObjectFile *image_object_file = module_sp->GetObjectFile();
237 if (image_object_file)
238 {
239 const SectionList *section_list = image_object_file->GetSectionList ();
240 if (section_list)
241 {
242 const uint32_t num_sections = section_list->GetSize();
243 for (uint32_t i = 0; i<num_sections; ++i)
244 {
245 SectionSP section_sp(section_list->GetSectionAtIndex(i));
246 if (section_sp)
247 {
248 target.GetSectionLoadList().SetSectionUnloaded (section_sp);
249 }
250 }
251 }
252 }
253 images.Remove(module_sp);
254 m_jit_objects.erase(it);
255 }
256 }
257 else if (jit_action == JIT_NOACTION)
258 {
259 // Nothing to do
260 }
261 else
262 {
263 assert(false && "Unknown jit action");
264 }
265
266 if (all_entries)
267 jit_relevant_entry = (addr_t)jit_entry.next_entry;
268 else
269 jit_relevant_entry = 0;
270 }
271
272 return false; // Continue Running.
273}
274
275//------------------------------------------------------------------
276// PluginInterface protocol
277//------------------------------------------------------------------
278lldb_private::ConstString
279JITLoaderGDB::GetPluginNameStatic()
280{
281 static ConstString g_name("gdb");
282 return g_name;
283}
284
285JITLoaderSP
286JITLoaderGDB::CreateInstance(Process *process, bool force)
287{
288 JITLoaderSP jit_loader_sp(new JITLoaderGDB(process));
289 return jit_loader_sp;
290}
291
292const char *
293JITLoaderGDB::GetPluginDescriptionStatic()
294{
295 return "JIT loader plug-in that watches for JIT events using the GDB interface.";
296}
297
298lldb_private::ConstString
299JITLoaderGDB::GetPluginName()
300{
301 return GetPluginNameStatic();
302}
303
304uint32_t
305JITLoaderGDB::GetPluginVersion()
306{
307 return 1;
308}
309
310void
311JITLoaderGDB::Initialize()
312{
313 PluginManager::RegisterPlugin (GetPluginNameStatic(),
314 GetPluginDescriptionStatic(),
315 CreateInstance);
316}
317
318void
319JITLoaderGDB::Terminate()
320{
321 PluginManager::UnregisterPlugin (CreateInstance);
322}
323
324bool
325JITLoaderGDB::DidSetJITBreakpoint() const
326{
327 return LLDB_BREAK_ID_IS_VALID(m_jit_break_id);
328}
329
330void
331JITLoaderGDB::ProcessStateChangedCallback(void *baton,
332 lldb_private::Process *process,
333 lldb::StateType state)
334{
335 JITLoaderGDB* instance = static_cast<JITLoaderGDB*>(baton);
336
337 switch (state)
338 {
339 case eStateConnected:
340 case eStateAttaching:
341 case eStateLaunching:
342 case eStateInvalid:
343 case eStateUnloaded:
344 case eStateExited:
345 case eStateDetached:
346 // instance->Clear(false);
347 break;
348
349 case eStateRunning:
350 case eStateStopped:
351 // Keep trying to set our JIT breakpoint each time we stop until we
352 // succeed
353 if (!instance->DidSetJITBreakpoint() && process->IsAlive())
354 instance->SetJITBreakpoint();
355 break;
356
357 case eStateStepping:
358 case eStateCrashed:
359 case eStateSuspended:
360 break;
361 }
362}
363
364addr_t
365JITLoaderGDB::GetSymbolAddress(const ConstString &name, SymbolType symbol_type) const
366{
367 SymbolContextList target_symbols;
368 Target &target = m_process->GetTarget();
369 ModuleList &images = target.GetImages();
370
371 if (!images.FindSymbolsWithNameAndType(name, symbol_type, target_symbols))
372 return LLDB_INVALID_ADDRESS;
373
374 SymbolContext sym_ctx;
375 target_symbols.GetContextAtIndex(0, sym_ctx);
376
377 const Address *jit_descriptor_addr = &sym_ctx.symbol->GetAddress();
378 if (!jit_descriptor_addr || !jit_descriptor_addr->IsValid())
379 return LLDB_INVALID_ADDRESS;
380
381 const addr_t jit_addr = jit_descriptor_addr->GetLoadAddress(&target);
382 return jit_addr;
383}