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