1 //===-- JITLoaderGDB.cpp ----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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"
24 #include "JITLoaderGDB.h"
27 using namespace lldb_private;
29 //------------------------------------------------------------------
30 // Debug Interface Structures
31 //------------------------------------------------------------------
41 struct jit_code_entry *next_entry;
42 struct jit_code_entry *prev_entry;
43 const char *symfile_addr;
44 uint64_t symfile_size;
50 uint32_t action_flag; // Values are jit_action_t
51 struct jit_code_entry *relevant_entry;
52 struct jit_code_entry *first_entry;
55 JITLoaderGDB::JITLoaderGDB (lldb_private::Process *process) :
58 m_jit_break_id(LLDB_INVALID_BREAK_ID),
59 m_jit_descriptor_addr(LLDB_INVALID_ADDRESS)
63 JITLoaderGDB::~JITLoaderGDB ()
65 if (LLDB_BREAK_ID_IS_VALID(m_jit_break_id))
66 m_process->GetTarget().RemoveBreakpointByID (m_jit_break_id);
69 void JITLoaderGDB::DidAttach()
71 Target &target = m_process->GetTarget();
72 ModuleList &module_list = target.GetImages();
73 SetJITBreakpoint(module_list);
76 void JITLoaderGDB::DidLaunch()
78 Target &target = m_process->GetTarget();
79 ModuleList &module_list = target.GetImages();
80 SetJITBreakpoint(module_list);
84 JITLoaderGDB::ModulesDidLoad(ModuleList &module_list)
86 if (!DidSetJITBreakpoint() && m_process->IsAlive())
87 SetJITBreakpoint(module_list);
90 //------------------------------------------------------------------
91 // Setup the JIT Breakpoint
92 //------------------------------------------------------------------
94 JITLoaderGDB::SetJITBreakpoint(lldb_private::ModuleList &module_list)
96 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
98 if ( DidSetJITBreakpoint() )
102 log->Printf("JITLoaderGDB::%s looking for JIT register hook",
105 addr_t jit_addr = GetSymbolAddress(module_list,
106 ConstString("__jit_debug_register_code"),
108 if (jit_addr == LLDB_INVALID_ADDRESS)
111 m_jit_descriptor_addr = GetSymbolAddress(module_list,
112 ConstString("__jit_debug_descriptor"),
114 if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS)
118 "JITLoaderGDB::%s failed to find JIT descriptor address",
124 log->Printf("JITLoaderGDB::%s setting JIT breakpoint",
128 m_process->GetTarget().CreateBreakpoint(jit_addr, true, false).get();
129 bp->SetCallback(JITDebugBreakpointHit, this, true);
130 bp->SetBreakpointKind("jit-debug-register");
131 m_jit_break_id = bp->GetID();
133 ReadJITDescriptor(true);
137 JITLoaderGDB::JITDebugBreakpointHit(void *baton,
138 StoppointCallbackContext *context,
139 user_id_t break_id, user_id_t break_loc_id)
141 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
143 log->Printf("JITLoaderGDB::%s hit JIT breakpoint",
145 JITLoaderGDB *instance = static_cast<JITLoaderGDB *>(baton);
146 return instance->ReadJITDescriptor(false);
149 static void updateSectionLoadAddress(const SectionList §ion_list,
151 uint64_t symbolfile_addr,
152 uint64_t symbolfile_size,
153 uint64_t &vmaddrheuristic,
157 const uint32_t num_sections = section_list.GetSize();
158 for (uint32_t i = 0; i<num_sections; ++i)
160 SectionSP section_sp(section_list.GetSectionAtIndex(i));
163 if(section_sp->IsFake()) {
164 uint64_t lower = (uint64_t)-1;
166 updateSectionLoadAddress(section_sp->GetChildren(), target, symbolfile_addr, symbolfile_size, vmaddrheuristic,
168 if (lower < min_addr)
170 if (upper > max_addr)
172 const lldb::addr_t slide_amount = lower - section_sp->GetFileAddress();
173 section_sp->Slide(slide_amount, false);
174 section_sp->GetChildren().Slide(-slide_amount, false);
175 section_sp->SetByteSize (upper - lower);
177 vmaddrheuristic += 2<<section_sp->GetLog2Align();
179 if (section_sp->GetFileAddress() > vmaddrheuristic)
180 lower = section_sp->GetFileAddress();
182 lower = symbolfile_addr+section_sp->GetFileOffset();
183 section_sp->SetFileAddress(symbolfile_addr+section_sp->GetFileOffset());
185 target.SetSectionLoadAddress(section_sp, lower, true);
186 uint64_t upper = lower + section_sp->GetByteSize();
187 if (lower < min_addr)
189 if (upper > max_addr)
191 // This is an upper bound, but a good enough heuristic
192 vmaddrheuristic += section_sp->GetByteSize();
199 JITLoaderGDB::ReadJITDescriptor(bool all_entries)
201 if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS)
204 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
205 Target &target = m_process->GetTarget();
206 ModuleList &module_list = target.GetImages();
208 jit_descriptor jit_desc;
209 const size_t jit_desc_size = sizeof(jit_desc);
211 size_t bytes_read = m_process->DoReadMemory(
212 m_jit_descriptor_addr, &jit_desc, jit_desc_size, error);
213 if (bytes_read != jit_desc_size || !error.Success())
216 log->Printf("JITLoaderGDB::%s failed to read JIT descriptor",
221 jit_actions_t jit_action = (jit_actions_t)jit_desc.action_flag;
222 addr_t jit_relevant_entry = (addr_t)jit_desc.relevant_entry;
225 jit_action = JIT_REGISTER_FN;
226 jit_relevant_entry = (addr_t)jit_desc.first_entry;
229 while (jit_relevant_entry != 0)
231 jit_code_entry jit_entry;
232 const size_t jit_entry_size = sizeof(jit_entry);
233 bytes_read = m_process->DoReadMemory(jit_relevant_entry, &jit_entry, jit_entry_size, error);
234 if (bytes_read != jit_entry_size || !error.Success())
238 "JITLoaderGDB::%s failed to read JIT entry at 0x%" PRIx64,
239 __FUNCTION__, jit_relevant_entry);
243 const addr_t &symbolfile_addr = (addr_t)jit_entry.symfile_addr;
244 const size_t &symbolfile_size = (size_t)jit_entry.symfile_size;
247 if (jit_action == JIT_REGISTER_FN)
251 "JITLoaderGDB::%s registering JIT entry at 0x%" PRIx64
252 " (%" PRIu64 " bytes)",
253 __FUNCTION__, symbolfile_addr, (uint64_t) symbolfile_size);
256 snprintf(jit_name, 64, "JIT(0x%" PRIx64 ")", symbolfile_addr);
257 module_sp = m_process->ReadModuleFromMemory(
258 FileSpec(jit_name, false), symbolfile_addr, symbolfile_size);
260 if (module_sp && module_sp->GetObjectFile())
263 m_jit_objects.insert(std::make_pair(symbolfile_addr, module_sp));
264 if (module_sp->GetObjectFile()->GetPluginName() == ConstString("mach-o"))
266 ObjectFile *image_object_file = module_sp->GetObjectFile();
267 if (image_object_file)
269 const SectionList *section_list = image_object_file->GetSectionList ();
272 uint64_t vmaddrheuristic = 0;
273 uint64_t lower = (uint64_t)-1;
275 updateSectionLoadAddress(*section_list, target, symbolfile_addr, symbolfile_size,
276 vmaddrheuristic, lower, upper);
282 module_sp->SetLoadAddress(target, 0, true, changed);
285 // load the symbol table right away
286 module_sp->GetObjectFile()->GetSymtab();
288 module_list.AppendIfNeeded(module_sp);
290 ModuleList module_list;
291 module_list.Append(module_sp);
292 target.ModulesDidLoad(module_list);
297 log->Printf("JITLoaderGDB::%s failed to load module for "
298 "JIT entry at 0x%" PRIx64,
299 __FUNCTION__, symbolfile_addr);
302 else if (jit_action == JIT_UNREGISTER_FN)
306 "JITLoaderGDB::%s unregistering JIT entry at 0x%" PRIx64,
307 __FUNCTION__, symbolfile_addr);
309 JITObjectMap::iterator it = m_jit_objects.find(symbolfile_addr);
310 if (it != m_jit_objects.end())
312 module_sp = it->second;
313 ObjectFile *image_object_file = module_sp->GetObjectFile();
314 if (image_object_file)
316 const SectionList *section_list = image_object_file->GetSectionList ();
319 const uint32_t num_sections = section_list->GetSize();
320 for (uint32_t i = 0; i<num_sections; ++i)
322 SectionSP section_sp(section_list->GetSectionAtIndex(i));
325 target.GetSectionLoadList().SetSectionUnloaded (section_sp);
330 module_list.Remove(module_sp);
331 m_jit_objects.erase(it);
334 else if (jit_action == JIT_NOACTION)
340 assert(false && "Unknown jit action");
344 jit_relevant_entry = (addr_t)jit_entry.next_entry;
346 jit_relevant_entry = 0;
349 return false; // Continue Running.
352 //------------------------------------------------------------------
353 // PluginInterface protocol
354 //------------------------------------------------------------------
355 lldb_private::ConstString
356 JITLoaderGDB::GetPluginNameStatic()
358 static ConstString g_name("gdb");
363 JITLoaderGDB::CreateInstance(Process *process, bool force)
365 JITLoaderSP jit_loader_sp;
366 ArchSpec arch (process->GetTarget().GetArchitecture());
367 if (arch.GetTriple().getVendor() != llvm::Triple::Apple)
368 jit_loader_sp.reset(new JITLoaderGDB(process));
369 return jit_loader_sp;
373 JITLoaderGDB::GetPluginDescriptionStatic()
375 return "JIT loader plug-in that watches for JIT events using the GDB interface.";
378 lldb_private::ConstString
379 JITLoaderGDB::GetPluginName()
381 return GetPluginNameStatic();
385 JITLoaderGDB::GetPluginVersion()
391 JITLoaderGDB::Initialize()
393 PluginManager::RegisterPlugin (GetPluginNameStatic(),
394 GetPluginDescriptionStatic(),
399 JITLoaderGDB::Terminate()
401 PluginManager::UnregisterPlugin (CreateInstance);
405 JITLoaderGDB::DidSetJITBreakpoint() const
407 return LLDB_BREAK_ID_IS_VALID(m_jit_break_id);
411 JITLoaderGDB::GetSymbolAddress(ModuleList &module_list, const ConstString &name,
412 SymbolType symbol_type) const
414 SymbolContextList target_symbols;
415 Target &target = m_process->GetTarget();
417 if (!module_list.FindSymbolsWithNameAndType(name, symbol_type,
419 return LLDB_INVALID_ADDRESS;
421 SymbolContext sym_ctx;
422 target_symbols.GetContextAtIndex(0, sym_ctx);
424 const Address *jit_descriptor_addr = &sym_ctx.symbol->GetAddress();
425 if (!jit_descriptor_addr || !jit_descriptor_addr->IsValid())
426 return LLDB_INVALID_ADDRESS;
428 const addr_t jit_addr = jit_descriptor_addr->GetLoadAddress(&target);