1 //===-- DynamicLoaderHexagonDYLD.cpp --------------------------------------===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/Breakpoint/BreakpointLocation.h"
10 #include "lldb/Core/Module.h"
11 #include "lldb/Core/ModuleSpec.h"
12 #include "lldb/Core/PluginManager.h"
13 #include "lldb/Core/Section.h"
14 #include "lldb/Symbol/ObjectFile.h"
15 #include "lldb/Target/Process.h"
16 #include "lldb/Target/Target.h"
17 #include "lldb/Target/Thread.h"
18 #include "lldb/Target/ThreadPlanRunToAddress.h"
19 #include "lldb/Utility/LLDBLog.h"
20 #include "lldb/Utility/Log.h"
21 
22 #include "DynamicLoaderHexagonDYLD.h"
23 
24 #include <memory>
25 
26 using namespace lldb;
27 using namespace lldb_private;
28 
29 LLDB_PLUGIN_DEFINE(DynamicLoaderHexagonDYLD)
30 
31 // Aidan 21/05/2014
32 //
33 // Notes about hexagon dynamic loading:
34 //
35 //      When we connect to a target we find the dyld breakpoint address.  We put
36 //      a
37 //      breakpoint there with a callback 'RendezvousBreakpointHit()'.
38 //
39 //      It is possible to find the dyld structure address from the ELF symbol
40 //      table,
41 //      but in the case of the simulator it has not been initialized before the
42 //      target calls dlinit().
43 //
44 //      We can only safely parse the dyld structure after we hit the dyld
45 //      breakpoint
46 //      since at that time we know dlinit() must have been called.
47 //
48 
49 // Find the load address of a symbol
50 static lldb::addr_t findSymbolAddress(Process *proc, ConstString findName) {
51   assert(proc != nullptr);
52 
53   ModuleSP module = proc->GetTarget().GetExecutableModule();
54   assert(module.get() != nullptr);
55 
56   ObjectFile *exe = module->GetObjectFile();
57   assert(exe != nullptr);
58 
59   lldb_private::Symtab *symtab = exe->GetSymtab();
60   assert(symtab != nullptr);
61 
62   for (size_t i = 0; i < symtab->GetNumSymbols(); i++) {
63     const Symbol *sym = symtab->SymbolAtIndex(i);
64     assert(sym != nullptr);
65     ConstString symName = sym->GetName();
66 
67     if (ConstString::Compare(findName, symName) == 0) {
68       Address addr = sym->GetAddress();
69       return addr.GetLoadAddress(&proc->GetTarget());
70     }
71   }
72   return LLDB_INVALID_ADDRESS;
73 }
74 
75 void DynamicLoaderHexagonDYLD::Initialize() {
76   PluginManager::RegisterPlugin(GetPluginNameStatic(),
77                                 GetPluginDescriptionStatic(), CreateInstance);
78 }
79 
80 void DynamicLoaderHexagonDYLD::Terminate() {}
81 
82 llvm::StringRef DynamicLoaderHexagonDYLD::GetPluginDescriptionStatic() {
83   return "Dynamic loader plug-in that watches for shared library "
84          "loads/unloads in Hexagon processes.";
85 }
86 
87 DynamicLoader *DynamicLoaderHexagonDYLD::CreateInstance(Process *process,
88                                                         bool force) {
89   bool create = force;
90   if (!create) {
91     const llvm::Triple &triple_ref =
92         process->GetTarget().GetArchitecture().GetTriple();
93     if (triple_ref.getArch() == llvm::Triple::hexagon)
94       create = true;
95   }
96 
97   if (create)
98     return new DynamicLoaderHexagonDYLD(process);
99   return nullptr;
100 }
101 
102 DynamicLoaderHexagonDYLD::DynamicLoaderHexagonDYLD(Process *process)
103     : DynamicLoader(process), m_rendezvous(process),
104       m_load_offset(LLDB_INVALID_ADDRESS), m_entry_point(LLDB_INVALID_ADDRESS),
105       m_dyld_bid(LLDB_INVALID_BREAK_ID) {}
106 
107 DynamicLoaderHexagonDYLD::~DynamicLoaderHexagonDYLD() {
108   if (m_dyld_bid != LLDB_INVALID_BREAK_ID) {
109     m_process->GetTarget().RemoveBreakpointByID(m_dyld_bid);
110     m_dyld_bid = LLDB_INVALID_BREAK_ID;
111   }
112 }
113 
114 void DynamicLoaderHexagonDYLD::DidAttach() {
115   ModuleSP executable;
116   addr_t load_offset;
117 
118   executable = GetTargetExecutable();
119 
120   // Find the difference between the desired load address in the elf file and
121   // the real load address in memory
122   load_offset = ComputeLoadOffset();
123 
124   // Check that there is a valid executable
125   if (executable.get() == nullptr)
126     return;
127 
128   // Disable JIT for hexagon targets because its not supported
129   m_process->SetCanJIT(false);
130 
131   // Enable Interpreting of function call expressions
132   m_process->SetCanInterpretFunctionCalls(true);
133 
134   // Add the current executable to the module list
135   ModuleList module_list;
136   module_list.Append(executable);
137 
138   // Map the loaded sections of this executable
139   if (load_offset != LLDB_INVALID_ADDRESS)
140     UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset, true);
141 
142   // AD: confirm this?
143   // Load into LLDB all of the currently loaded executables in the stub
144   LoadAllCurrentModules();
145 
146   // AD: confirm this?
147   // Callback for the target to give it the loaded module list
148   m_process->GetTarget().ModulesDidLoad(module_list);
149 
150   // Try to set a breakpoint at the rendezvous breakpoint. DidLaunch uses
151   // ProbeEntry() instead.  That sets a breakpoint, at the dyld breakpoint
152   // address, with a callback so that when hit, the dyld structure can be
153   // parsed.
154   if (!SetRendezvousBreakpoint()) {
155     // fail
156   }
157 }
158 
159 void DynamicLoaderHexagonDYLD::DidLaunch() {}
160 
161 /// Checks to see if the target module has changed, updates the target
162 /// accordingly and returns the target executable module.
163 ModuleSP DynamicLoaderHexagonDYLD::GetTargetExecutable() {
164   Target &target = m_process->GetTarget();
165   ModuleSP executable = target.GetExecutableModule();
166 
167   // There is no executable
168   if (!executable.get())
169     return executable;
170 
171   // The target executable file does not exits
172   if (!FileSystem::Instance().Exists(executable->GetFileSpec()))
173     return executable;
174 
175   // Prep module for loading
176   ModuleSpec module_spec(executable->GetFileSpec(),
177                          executable->GetArchitecture());
178   ModuleSP module_sp(new Module(module_spec));
179 
180   // Check if the executable has changed and set it to the target executable if
181   // they differ.
182   if (module_sp.get() && module_sp->GetUUID().IsValid() &&
183       executable->GetUUID().IsValid()) {
184     // if the executable has changed ??
185     if (module_sp->GetUUID() != executable->GetUUID())
186       executable.reset();
187   } else if (executable->FileHasChanged())
188     executable.reset();
189 
190   if (executable.get())
191     return executable;
192 
193   // TODO: What case is this code used?
194   executable = target.GetOrCreateModule(module_spec, true /* notify */);
195   if (executable.get() != target.GetExecutableModulePointer()) {
196     // Don't load dependent images since we are in dyld where we will know and
197     // find out about all images that are loaded
198     target.SetExecutableModule(executable, eLoadDependentsNo);
199   }
200 
201   return executable;
202 }
203 
204 // AD: Needs to be updated?
205 Status DynamicLoaderHexagonDYLD::CanLoadImage() { return Status(); }
206 
207 void DynamicLoaderHexagonDYLD::UpdateLoadedSections(ModuleSP module,
208                                                     addr_t link_map_addr,
209                                                     addr_t base_addr,
210                                                     bool base_addr_is_offset) {
211   Target &target = m_process->GetTarget();
212   const SectionList *sections = GetSectionListFromModule(module);
213 
214   assert(sections && "SectionList missing from loaded module.");
215 
216   m_loaded_modules[module] = link_map_addr;
217 
218   const size_t num_sections = sections->GetSize();
219 
220   for (unsigned i = 0; i < num_sections; ++i) {
221     SectionSP section_sp(sections->GetSectionAtIndex(i));
222     lldb::addr_t new_load_addr = section_sp->GetFileAddress() + base_addr;
223 
224     // AD: 02/05/14
225     //   since our memory map starts from address 0, we must not ignore
226     //   sections that load to address 0.  This violates the reference
227     //   ELF spec, however is used for Hexagon.
228 
229     // If the file address of the section is zero then this is not an
230     // allocatable/loadable section (property of ELF sh_addr).  Skip it.
231     //      if (new_load_addr == base_addr)
232     //          continue;
233 
234     target.SetSectionLoadAddress(section_sp, new_load_addr);
235   }
236 }
237 
238 /// Removes the loaded sections from the target in \p module.
239 ///
240 /// \param module The module to traverse.
241 void DynamicLoaderHexagonDYLD::UnloadSections(const ModuleSP module) {
242   Target &target = m_process->GetTarget();
243   const SectionList *sections = GetSectionListFromModule(module);
244 
245   assert(sections && "SectionList missing from unloaded module.");
246 
247   m_loaded_modules.erase(module);
248 
249   const size_t num_sections = sections->GetSize();
250   for (size_t i = 0; i < num_sections; ++i) {
251     SectionSP section_sp(sections->GetSectionAtIndex(i));
252     target.SetSectionUnloaded(section_sp);
253   }
254 }
255 
256 // Place a breakpoint on <_rtld_debug_state>
257 bool DynamicLoaderHexagonDYLD::SetRendezvousBreakpoint() {
258   Log *log = GetLog(LLDBLog::DynamicLoader);
259 
260   // This is the original code, which want to look in the rendezvous structure
261   // to find the breakpoint address.  Its backwards for us, since we can easily
262   // find the breakpoint address, since it is exported in our executable. We
263   // however know that we cant read the Rendezvous structure until we have hit
264   // the breakpoint once.
265   const ConstString dyldBpName("_rtld_debug_state");
266   addr_t break_addr = findSymbolAddress(m_process, dyldBpName);
267 
268   Target &target = m_process->GetTarget();
269 
270   // Do not try to set the breakpoint if we don't know where to put it
271   if (break_addr == LLDB_INVALID_ADDRESS) {
272     LLDB_LOGF(log, "Unable to locate _rtld_debug_state breakpoint address");
273 
274     return false;
275   }
276 
277   // Save the address of the rendezvous structure
278   m_rendezvous.SetBreakAddress(break_addr);
279 
280   // If we haven't set the breakpoint before then set it
281   if (m_dyld_bid == LLDB_INVALID_BREAK_ID) {
282     Breakpoint *dyld_break =
283         target.CreateBreakpoint(break_addr, true, false).get();
284     dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
285     dyld_break->SetBreakpointKind("shared-library-event");
286     m_dyld_bid = dyld_break->GetID();
287 
288     // Make sure our breakpoint is at the right address.
289     assert(target.GetBreakpointByID(m_dyld_bid)
290                ->FindLocationByAddress(break_addr)
291                ->GetBreakpoint()
292                .GetID() == m_dyld_bid);
293 
294     if (log && dyld_break == nullptr)
295       LLDB_LOGF(log, "Failed to create _rtld_debug_state breakpoint");
296 
297     // check we have successfully set bp
298     return (dyld_break != nullptr);
299   } else
300     // rendezvous already set
301     return true;
302 }
303 
304 // We have just hit our breakpoint at <_rtld_debug_state>
305 bool DynamicLoaderHexagonDYLD::RendezvousBreakpointHit(
306     void *baton, StoppointCallbackContext *context, user_id_t break_id,
307     user_id_t break_loc_id) {
308   Log *log = GetLog(LLDBLog::DynamicLoader);
309 
310   LLDB_LOGF(log, "Rendezvous breakpoint hit!");
311 
312   DynamicLoaderHexagonDYLD *dyld_instance = nullptr;
313   dyld_instance = static_cast<DynamicLoaderHexagonDYLD *>(baton);
314 
315   // if the dyld_instance is still not valid then try to locate it on the
316   // symbol table
317   if (!dyld_instance->m_rendezvous.IsValid()) {
318     Process *proc = dyld_instance->m_process;
319 
320     const ConstString dyldStructName("_rtld_debug");
321     addr_t structAddr = findSymbolAddress(proc, dyldStructName);
322 
323     if (structAddr != LLDB_INVALID_ADDRESS) {
324       dyld_instance->m_rendezvous.SetRendezvousAddress(structAddr);
325 
326       LLDB_LOGF(log, "Found _rtld_debug structure @ 0x%08" PRIx64, structAddr);
327     } else {
328       LLDB_LOGF(log, "Unable to resolve the _rtld_debug structure");
329     }
330   }
331 
332   dyld_instance->RefreshModules();
333 
334   // Return true to stop the target, false to just let the target run.
335   return dyld_instance->GetStopWhenImagesChange();
336 }
337 
338 /// Helper method for RendezvousBreakpointHit.  Updates LLDB's current set
339 /// of loaded modules.
340 void DynamicLoaderHexagonDYLD::RefreshModules() {
341   Log *log = GetLog(LLDBLog::DynamicLoader);
342 
343   if (!m_rendezvous.Resolve())
344     return;
345 
346   HexagonDYLDRendezvous::iterator I;
347   HexagonDYLDRendezvous::iterator E;
348 
349   ModuleList &loaded_modules = m_process->GetTarget().GetImages();
350 
351   if (m_rendezvous.ModulesDidLoad()) {
352     ModuleList new_modules;
353 
354     E = m_rendezvous.loaded_end();
355     for (I = m_rendezvous.loaded_begin(); I != E; ++I) {
356       FileSpec file(I->path);
357       FileSystem::Instance().Resolve(file);
358       ModuleSP module_sp =
359           LoadModuleAtAddress(file, I->link_addr, I->base_addr, true);
360       if (module_sp.get()) {
361         loaded_modules.AppendIfNeeded(module_sp);
362         new_modules.Append(module_sp);
363       }
364 
365       if (log) {
366         LLDB_LOGF(log, "Target is loading '%s'", I->path.c_str());
367         if (!module_sp.get())
368           LLDB_LOGF(log, "LLDB failed to load '%s'", I->path.c_str());
369         else
370           LLDB_LOGF(log, "LLDB successfully loaded '%s'", I->path.c_str());
371       }
372     }
373     m_process->GetTarget().ModulesDidLoad(new_modules);
374   }
375 
376   if (m_rendezvous.ModulesDidUnload()) {
377     ModuleList old_modules;
378 
379     E = m_rendezvous.unloaded_end();
380     for (I = m_rendezvous.unloaded_begin(); I != E; ++I) {
381       FileSpec file(I->path);
382       FileSystem::Instance().Resolve(file);
383       ModuleSpec module_spec(file);
384       ModuleSP module_sp = loaded_modules.FindFirstModule(module_spec);
385 
386       if (module_sp.get()) {
387         old_modules.Append(module_sp);
388         UnloadSections(module_sp);
389       }
390 
391       LLDB_LOGF(log, "Target is unloading '%s'", I->path.c_str());
392     }
393     loaded_modules.Remove(old_modules);
394     m_process->GetTarget().ModulesDidUnload(old_modules, false);
395   }
396 }
397 
398 // AD:	This is very different to the Static Loader code.
399 //		It may be wise to look over this and its relation to stack
400 //		unwinding.
401 ThreadPlanSP
402 DynamicLoaderHexagonDYLD::GetStepThroughTrampolinePlan(Thread &thread,
403                                                        bool stop) {
404   ThreadPlanSP thread_plan_sp;
405 
406   StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
407   const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
408   Symbol *sym = context.symbol;
409 
410   if (sym == nullptr || !sym->IsTrampoline())
411     return thread_plan_sp;
412 
413   const ConstString sym_name =
414       sym->GetMangled().GetName(Mangled::ePreferMangled);
415   if (!sym_name)
416     return thread_plan_sp;
417 
418   SymbolContextList target_symbols;
419   Target &target = thread.GetProcess()->GetTarget();
420   const ModuleList &images = target.GetImages();
421 
422   images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
423   size_t num_targets = target_symbols.GetSize();
424   if (!num_targets)
425     return thread_plan_sp;
426 
427   typedef std::vector<lldb::addr_t> AddressVector;
428   AddressVector addrs;
429   for (size_t i = 0; i < num_targets; ++i) {
430     SymbolContext context;
431     AddressRange range;
432     if (target_symbols.GetContextAtIndex(i, context)) {
433       context.GetAddressRange(eSymbolContextEverything, 0, false, range);
434       lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target);
435       if (addr != LLDB_INVALID_ADDRESS)
436         addrs.push_back(addr);
437     }
438   }
439 
440   if (addrs.size() > 0) {
441     AddressVector::iterator start = addrs.begin();
442     AddressVector::iterator end = addrs.end();
443 
444     llvm::sort(start, end);
445     addrs.erase(std::unique(start, end), end);
446     thread_plan_sp =
447         std::make_shared<ThreadPlanRunToAddress>(thread, addrs, stop);
448   }
449 
450   return thread_plan_sp;
451 }
452 
453 /// Helper for the entry breakpoint callback.  Resolves the load addresses
454 /// of all dependent modules.
455 void DynamicLoaderHexagonDYLD::LoadAllCurrentModules() {
456   HexagonDYLDRendezvous::iterator I;
457   HexagonDYLDRendezvous::iterator E;
458   ModuleList module_list;
459 
460   if (!m_rendezvous.Resolve()) {
461     Log *log = GetLog(LLDBLog::DynamicLoader);
462     LLDB_LOGF(
463         log,
464         "DynamicLoaderHexagonDYLD::%s unable to resolve rendezvous address",
465         __FUNCTION__);
466     return;
467   }
468 
469   // The rendezvous class doesn't enumerate the main module, so track that
470   // ourselves here.
471   ModuleSP executable = GetTargetExecutable();
472   m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress();
473 
474   for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) {
475     const char *module_path = I->path.c_str();
476     FileSpec file(module_path);
477     ModuleSP module_sp =
478         LoadModuleAtAddress(file, I->link_addr, I->base_addr, true);
479     if (module_sp.get()) {
480       module_list.Append(module_sp);
481     } else {
482       Log *log = GetLog(LLDBLog::DynamicLoader);
483       LLDB_LOGF(log,
484                 "DynamicLoaderHexagonDYLD::%s failed loading module %s at "
485                 "0x%" PRIx64,
486                 __FUNCTION__, module_path, I->base_addr);
487     }
488   }
489 
490   m_process->GetTarget().ModulesDidLoad(module_list);
491 }
492 
493 /// Computes a value for m_load_offset returning the computed address on
494 /// success and LLDB_INVALID_ADDRESS on failure.
495 addr_t DynamicLoaderHexagonDYLD::ComputeLoadOffset() {
496   // Here we could send a GDB packet to know the load offset
497   //
498   // send:    $qOffsets#4b
499   // get:     Text=0;Data=0;Bss=0
500   //
501   // Currently qOffsets is not supported by pluginProcessGDBRemote
502   //
503   return 0;
504 }
505 
506 // Here we must try to read the entry point directly from the elf header.  This
507 // is possible if the process is not relocatable or dynamically linked.
508 //
509 // an alternative is to look at the PC if we can be sure that we have connected
510 // when the process is at the entry point.
511 // I dont think that is reliable for us.
512 addr_t DynamicLoaderHexagonDYLD::GetEntryPoint() {
513   if (m_entry_point != LLDB_INVALID_ADDRESS)
514     return m_entry_point;
515   // check we have a valid process
516   if (m_process == nullptr)
517     return LLDB_INVALID_ADDRESS;
518   // Get the current executable module
519   Module &module = *(m_process->GetTarget().GetExecutableModule().get());
520   // Get the object file (elf file) for this module
521   lldb_private::ObjectFile &object = *(module.GetObjectFile());
522   // Check if the file is executable (ie, not shared object or relocatable)
523   if (object.IsExecutable()) {
524     // Get the entry point address for this object
525     lldb_private::Address entry = object.GetEntryPointAddress();
526     // Return the entry point address
527     return entry.GetFileAddress();
528   }
529   // No idea so back out
530   return LLDB_INVALID_ADDRESS;
531 }
532 
533 const SectionList *DynamicLoaderHexagonDYLD::GetSectionListFromModule(
534     const ModuleSP module) const {
535   SectionList *sections = nullptr;
536   if (module.get()) {
537     ObjectFile *obj_file = module->GetObjectFile();
538     if (obj_file) {
539       sections = obj_file->GetSectionList();
540     }
541   }
542   return sections;
543 }
544 
545 static int ReadInt(Process *process, addr_t addr) {
546   Status error;
547   int value = (int)process->ReadUnsignedIntegerFromMemory(
548       addr, sizeof(uint32_t), 0, error);
549   if (error.Fail())
550     return -1;
551   else
552     return value;
553 }
554 
555 lldb::addr_t
556 DynamicLoaderHexagonDYLD::GetThreadLocalData(const lldb::ModuleSP module,
557                                              const lldb::ThreadSP thread,
558                                              lldb::addr_t tls_file_addr) {
559   auto it = m_loaded_modules.find(module);
560   if (it == m_loaded_modules.end())
561     return LLDB_INVALID_ADDRESS;
562 
563   addr_t link_map = it->second;
564   if (link_map == LLDB_INVALID_ADDRESS)
565     return LLDB_INVALID_ADDRESS;
566 
567   const HexagonDYLDRendezvous::ThreadInfo &metadata =
568       m_rendezvous.GetThreadInfo();
569   if (!metadata.valid)
570     return LLDB_INVALID_ADDRESS;
571 
572   // Get the thread pointer.
573   addr_t tp = thread->GetThreadPointer();
574   if (tp == LLDB_INVALID_ADDRESS)
575     return LLDB_INVALID_ADDRESS;
576 
577   // Find the module's modid.
578   int modid = ReadInt(m_process, link_map + metadata.modid_offset);
579   if (modid == -1)
580     return LLDB_INVALID_ADDRESS;
581 
582   // Lookup the DTV structure for this thread.
583   addr_t dtv_ptr = tp + metadata.dtv_offset;
584   addr_t dtv = ReadPointer(dtv_ptr);
585   if (dtv == LLDB_INVALID_ADDRESS)
586     return LLDB_INVALID_ADDRESS;
587 
588   // Find the TLS block for this module.
589   addr_t dtv_slot = dtv + metadata.dtv_slot_size * modid;
590   addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset);
591 
592   Module *mod = module.get();
593   Log *log = GetLog(LLDBLog::DynamicLoader);
594   LLDB_LOGF(log,
595             "DynamicLoaderHexagonDYLD::Performed TLS lookup: "
596             "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
597             ", modid=%i, tls_block=0x%" PRIx64,
598             mod->GetObjectName().AsCString(""), link_map, tp, modid, tls_block);
599 
600   if (tls_block == LLDB_INVALID_ADDRESS)
601     return LLDB_INVALID_ADDRESS;
602   else
603     return tls_block + tls_file_addr;
604 }
605