]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
Merge ^/head r275387 through r275477.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / JITLoader / GDB / JITLoaderGDB.cpp
1 //===-- 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
26 using namespace lldb;
27 using namespace lldb_private;
28
29 //------------------------------------------------------------------
30 // Debug Interface Structures
31 //------------------------------------------------------------------
32 typedef enum
33 {
34     JIT_NOACTION = 0,
35     JIT_REGISTER_FN,
36     JIT_UNREGISTER_FN
37 } jit_actions_t;
38
39 struct 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
47 struct 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
55 JITLoaderGDB::JITLoaderGDB (lldb_private::Process *process) :
56     JITLoader(process),
57     m_jit_objects(),
58     m_jit_break_id(LLDB_INVALID_BREAK_ID),
59     m_jit_descriptor_addr(LLDB_INVALID_ADDRESS)
60 {
61 }
62
63 JITLoaderGDB::~JITLoaderGDB ()
64 {
65     if (LLDB_BREAK_ID_IS_VALID(m_jit_break_id))
66         m_process->GetTarget().RemoveBreakpointByID (m_jit_break_id);
67 }
68
69 void JITLoaderGDB::DidAttach()
70 {
71     Target &target = m_process->GetTarget();
72     ModuleList &module_list = target.GetImages();
73     SetJITBreakpoint(module_list);
74 }
75
76 void JITLoaderGDB::DidLaunch()
77 {
78     Target &target = m_process->GetTarget();
79     ModuleList &module_list = target.GetImages();
80     SetJITBreakpoint(module_list);
81 }
82
83 void
84 JITLoaderGDB::ModulesDidLoad(ModuleList &module_list)
85 {
86     if (!DidSetJITBreakpoint() && m_process->IsAlive())
87         SetJITBreakpoint(module_list);
88 }
89
90 //------------------------------------------------------------------
91 // Setup the JIT Breakpoint
92 //------------------------------------------------------------------
93 void
94 JITLoaderGDB::SetJITBreakpoint(lldb_private::ModuleList &module_list)
95 {
96     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
97
98     if ( DidSetJITBreakpoint() )
99         return;
100
101     if (log)
102         log->Printf("JITLoaderGDB::%s looking for JIT register hook",
103                     __FUNCTION__);
104
105     addr_t jit_addr = GetSymbolAddress(module_list,
106                                        ConstString("__jit_debug_register_code"),
107                                        eSymbolTypeAny);
108     if (jit_addr == LLDB_INVALID_ADDRESS)
109         return;
110
111     m_jit_descriptor_addr = GetSymbolAddress(module_list,
112                                              ConstString("__jit_debug_descriptor"),
113                                              eSymbolTypeData);
114     if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS)
115     {
116         if (log)
117             log->Printf(
118                 "JITLoaderGDB::%s failed to find JIT descriptor address",
119                 __FUNCTION__);
120         return;
121     }
122
123     if (log)
124         log->Printf("JITLoaderGDB::%s setting JIT breakpoint",
125                     __FUNCTION__);
126
127     Breakpoint *bp =
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();
132
133     ReadJITDescriptor(true);
134 }
135
136 bool
137 JITLoaderGDB::JITDebugBreakpointHit(void *baton,
138                                     StoppointCallbackContext *context,
139                                     user_id_t break_id, user_id_t break_loc_id)
140 {
141     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
142     if (log)
143         log->Printf("JITLoaderGDB::%s hit JIT breakpoint",
144                     __FUNCTION__);
145     JITLoaderGDB *instance = static_cast<JITLoaderGDB *>(baton);
146     return instance->ReadJITDescriptor(false);
147 }
148
149 static void updateSectionLoadAddress(const SectionList &section_list,
150                                      Target &target,
151                                      uint64_t symbolfile_addr,
152                                      uint64_t symbolfile_size,
153                                      uint64_t &vmaddrheuristic,
154                                      uint64_t &min_addr,
155                                      uint64_t &max_addr)
156 {
157     const uint32_t num_sections = section_list.GetSize();
158     for (uint32_t i = 0; i<num_sections; ++i)
159     {
160         SectionSP section_sp(section_list.GetSectionAtIndex(i));
161         if (section_sp)
162         {
163             if(section_sp->IsFake()) {
164                 uint64_t lower = (uint64_t)-1;
165                 uint64_t upper = 0;
166                 updateSectionLoadAddress(section_sp->GetChildren(), target, symbolfile_addr, symbolfile_size, vmaddrheuristic,
167                     lower, upper);
168                 if (lower < min_addr)
169                     min_addr = lower;
170                 if (upper > max_addr)
171                     max_addr = upper;
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);
176             } else {
177                 vmaddrheuristic += 2<<section_sp->GetLog2Align();
178                 uint64_t lower;
179                 if (section_sp->GetFileAddress() > vmaddrheuristic)
180                     lower = section_sp->GetFileAddress();
181                 else {
182                     lower = symbolfile_addr+section_sp->GetFileOffset();
183                     section_sp->SetFileAddress(symbolfile_addr+section_sp->GetFileOffset());
184                 }
185                 target.SetSectionLoadAddress(section_sp, lower, true);
186                 uint64_t upper = lower + section_sp->GetByteSize();
187                 if (lower < min_addr)
188                     min_addr = lower;
189                 if (upper > max_addr)
190                     max_addr = upper;
191                 // This is an upper bound, but a good enough heuristic
192                 vmaddrheuristic += section_sp->GetByteSize();
193             }
194         }
195     }
196 }
197
198 bool
199 JITLoaderGDB::ReadJITDescriptor(bool all_entries)
200 {
201     if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS)
202         return false;
203
204     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
205     Target &target = m_process->GetTarget();
206     ModuleList &module_list = target.GetImages();
207
208     jit_descriptor jit_desc;
209     const size_t jit_desc_size = sizeof(jit_desc);
210     Error error;
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())
214     {
215         if (log)
216             log->Printf("JITLoaderGDB::%s failed to read JIT descriptor",
217                         __FUNCTION__);
218         return false;
219     }
220
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;
223     if (all_entries)
224     {
225         jit_action = JIT_REGISTER_FN;
226         jit_relevant_entry = (addr_t)jit_desc.first_entry;
227     }
228
229     while (jit_relevant_entry != 0)
230     {
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())
235         {
236             if (log)
237                 log->Printf(
238                     "JITLoaderGDB::%s failed to read JIT entry at 0x%" PRIx64,
239                     __FUNCTION__, jit_relevant_entry);
240             return false;
241         }
242
243         const addr_t &symbolfile_addr = (addr_t)jit_entry.symfile_addr;
244         const size_t &symbolfile_size = (size_t)jit_entry.symfile_size;
245         ModuleSP module_sp;
246
247         if (jit_action == JIT_REGISTER_FN)
248         {
249             if (log)
250                 log->Printf(
251                     "JITLoaderGDB::%s registering JIT entry at 0x%" PRIx64
252                     " (%" PRIu64 " bytes)",
253                     __FUNCTION__, symbolfile_addr, (uint64_t) symbolfile_size);
254
255             char jit_name[64];
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);
259
260             if (module_sp && module_sp->GetObjectFile())
261             {
262                 bool changed;
263                 m_jit_objects.insert(std::make_pair(symbolfile_addr, module_sp));
264                 if (module_sp->GetObjectFile()->GetPluginName() == ConstString("mach-o"))
265                 {
266                     ObjectFile *image_object_file = module_sp->GetObjectFile();
267                     if (image_object_file)
268                     {
269                         const SectionList *section_list = image_object_file->GetSectionList ();
270                         if (section_list)
271                         {
272                             uint64_t vmaddrheuristic = 0;
273                             uint64_t lower = (uint64_t)-1;
274                             uint64_t upper = 0;
275                             updateSectionLoadAddress(*section_list, target, symbolfile_addr, symbolfile_size,
276                                 vmaddrheuristic, lower, upper);
277                         }
278                     }
279                 }
280                 else
281                 {
282                     module_sp->SetLoadAddress(target, 0, true, changed);
283                 }
284
285                 // load the symbol table right away
286                 module_sp->GetObjectFile()->GetSymtab();
287
288                 module_list.AppendIfNeeded(module_sp);
289
290                 ModuleList module_list;
291                 module_list.Append(module_sp);
292                 target.ModulesDidLoad(module_list);
293             }
294             else
295             {
296                 if (log)
297                     log->Printf("JITLoaderGDB::%s failed to load module for "
298                                 "JIT entry at 0x%" PRIx64,
299                                 __FUNCTION__, symbolfile_addr);
300             }
301         }
302         else if (jit_action == JIT_UNREGISTER_FN)
303         {
304             if (log)
305                 log->Printf(
306                     "JITLoaderGDB::%s unregistering JIT entry at 0x%" PRIx64,
307                     __FUNCTION__, symbolfile_addr);
308
309             JITObjectMap::iterator it = m_jit_objects.find(symbolfile_addr);
310             if (it != m_jit_objects.end())
311             {
312                 module_sp = it->second;
313                 ObjectFile *image_object_file = module_sp->GetObjectFile();
314                 if (image_object_file)
315                 {
316                     const SectionList *section_list = image_object_file->GetSectionList ();
317                     if (section_list)
318                     {
319                         const uint32_t num_sections = section_list->GetSize();
320                         for (uint32_t i = 0; i<num_sections; ++i)
321                         {
322                             SectionSP section_sp(section_list->GetSectionAtIndex(i));
323                             if (section_sp)
324                             {
325                                 target.GetSectionLoadList().SetSectionUnloaded (section_sp);
326                             }
327                         }
328                     }
329                 }
330                 module_list.Remove(module_sp);
331                 m_jit_objects.erase(it);
332             }
333         }
334         else if (jit_action == JIT_NOACTION)
335         {
336             // Nothing to do
337         }
338         else
339         {
340             assert(false && "Unknown jit action");
341         }
342
343         if (all_entries)
344             jit_relevant_entry = (addr_t)jit_entry.next_entry;
345         else
346             jit_relevant_entry = 0;
347     }
348
349     return false; // Continue Running.
350 }
351
352 //------------------------------------------------------------------
353 // PluginInterface protocol
354 //------------------------------------------------------------------
355 lldb_private::ConstString
356 JITLoaderGDB::GetPluginNameStatic()
357 {
358     static ConstString g_name("gdb");
359     return g_name;
360 }
361
362 JITLoaderSP
363 JITLoaderGDB::CreateInstance(Process *process, bool force)
364 {
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;
370 }
371
372 const char *
373 JITLoaderGDB::GetPluginDescriptionStatic()
374 {
375     return "JIT loader plug-in that watches for JIT events using the GDB interface.";
376 }
377
378 lldb_private::ConstString
379 JITLoaderGDB::GetPluginName()
380 {
381     return GetPluginNameStatic();
382 }
383
384 uint32_t
385 JITLoaderGDB::GetPluginVersion()
386 {
387     return 1;
388 }
389
390 void
391 JITLoaderGDB::Initialize()
392 {
393     PluginManager::RegisterPlugin (GetPluginNameStatic(),
394                                    GetPluginDescriptionStatic(),
395                                    CreateInstance);
396 }
397
398 void
399 JITLoaderGDB::Terminate()
400 {
401     PluginManager::UnregisterPlugin (CreateInstance);
402 }
403
404 bool
405 JITLoaderGDB::DidSetJITBreakpoint() const
406 {
407     return LLDB_BREAK_ID_IS_VALID(m_jit_break_id);
408 }
409
410 addr_t
411 JITLoaderGDB::GetSymbolAddress(ModuleList &module_list, const ConstString &name,
412                                SymbolType symbol_type) const
413 {
414     SymbolContextList target_symbols;
415     Target &target = m_process->GetTarget();
416
417     if (!module_list.FindSymbolsWithNameAndType(name, symbol_type,
418                                                 target_symbols))
419         return LLDB_INVALID_ADDRESS;
420
421     SymbolContext sym_ctx;
422     target_symbols.GetContextAtIndex(0, sym_ctx);
423
424     const Address *jit_descriptor_addr = &sym_ctx.symbol->GetAddress();
425     if (!jit_descriptor_addr || !jit_descriptor_addr->IsValid())
426         return LLDB_INVALID_ADDRESS;
427
428     const addr_t jit_addr = jit_descriptor_addr->GetLoadAddress(&target);
429     return jit_addr;
430 }