1 //===-- DynamicLoaderPOSIX.h ------------------------------------*- 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 // Main header include
11 #include "DynamicLoaderPOSIXDYLD.h"
12 
13 // Project includes
14 #include "AuxVector.h"
15 
16 // Other libraries and framework includes
17 #include "lldb/Breakpoint/BreakpointLocation.h"
18 #include "lldb/Core/Log.h"
19 #include "lldb/Core/Module.h"
20 #include "lldb/Core/ModuleSpec.h"
21 #include "lldb/Core/PluginManager.h"
22 #include "lldb/Core/Section.h"
23 #include "lldb/Symbol/Function.h"
24 #include "lldb/Symbol/ObjectFile.h"
25 #include "lldb/Target/Platform.h"
26 #include "lldb/Target/Process.h"
27 #include "lldb/Target/Target.h"
28 #include "lldb/Target/Thread.h"
29 #include "lldb/Target/ThreadPlanRunToAddress.h"
30 
31 // C++ Includes
32 // C Includes
33 
34 using namespace lldb;
35 using namespace lldb_private;
36 
37 void DynamicLoaderPOSIXDYLD::Initialize() {
38   PluginManager::RegisterPlugin(GetPluginNameStatic(),
39                                 GetPluginDescriptionStatic(), CreateInstance);
40 }
41 
42 void DynamicLoaderPOSIXDYLD::Terminate() {}
43 
44 lldb_private::ConstString DynamicLoaderPOSIXDYLD::GetPluginName() {
45   return GetPluginNameStatic();
46 }
47 
48 lldb_private::ConstString DynamicLoaderPOSIXDYLD::GetPluginNameStatic() {
49   static ConstString g_name("linux-dyld");
50   return g_name;
51 }
52 
53 const char *DynamicLoaderPOSIXDYLD::GetPluginDescriptionStatic() {
54   return "Dynamic loader plug-in that watches for shared library "
55          "loads/unloads in POSIX processes.";
56 }
57 
58 uint32_t DynamicLoaderPOSIXDYLD::GetPluginVersion() { return 1; }
59 
60 DynamicLoader *DynamicLoaderPOSIXDYLD::CreateInstance(Process *process,
61                                                       bool force) {
62   bool create = force;
63   if (!create) {
64     const llvm::Triple &triple_ref =
65         process->GetTarget().GetArchitecture().GetTriple();
66     if (triple_ref.getOS() == llvm::Triple::Linux ||
67         triple_ref.getOS() == llvm::Triple::FreeBSD)
68       create = true;
69   }
70 
71   if (create)
72     return new DynamicLoaderPOSIXDYLD(process);
73   return NULL;
74 }
75 
76 DynamicLoaderPOSIXDYLD::DynamicLoaderPOSIXDYLD(Process *process)
77     : DynamicLoader(process), m_rendezvous(process),
78       m_load_offset(LLDB_INVALID_ADDRESS), m_entry_point(LLDB_INVALID_ADDRESS),
79       m_auxv(), m_dyld_bid(LLDB_INVALID_BREAK_ID),
80       m_vdso_base(LLDB_INVALID_ADDRESS) {}
81 
82 DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD() {
83   if (m_dyld_bid != LLDB_INVALID_BREAK_ID) {
84     m_process->GetTarget().RemoveBreakpointByID(m_dyld_bid);
85     m_dyld_bid = LLDB_INVALID_BREAK_ID;
86   }
87 }
88 
89 void DynamicLoaderPOSIXDYLD::DidAttach() {
90   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
91   if (log)
92     log->Printf("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64, __FUNCTION__,
93                 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
94 
95   m_auxv.reset(new AuxVector(m_process));
96   if (log)
97     log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reloaded auxv data",
98                 __FUNCTION__,
99                 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
100 
101   // ask the process if it can load any of its own modules
102   m_process->LoadModules();
103 
104   ModuleSP executable_sp = GetTargetExecutable();
105   ResolveExecutableModule(executable_sp);
106 
107   // find the main process load offset
108   addr_t load_offset = ComputeLoadOffset();
109   if (log)
110     log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
111                 " executable '%s', load_offset 0x%" PRIx64,
112                 __FUNCTION__,
113                 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
114                 executable_sp ? executable_sp->GetFileSpec().GetPath().c_str()
115                               : "<null executable>",
116                 load_offset);
117 
118   EvalVdsoStatus();
119 
120   // if we dont have a load address we cant re-base
121   bool rebase_exec = (load_offset == LLDB_INVALID_ADDRESS) ? false : true;
122 
123   // if we have a valid executable
124   if (executable_sp.get()) {
125     lldb_private::ObjectFile *obj = executable_sp->GetObjectFile();
126     if (obj) {
127       // don't rebase if the module already has a load address
128       Target &target = m_process->GetTarget();
129       Address addr = obj->GetImageInfoAddress(&target);
130       if (addr.GetLoadAddress(&target) != LLDB_INVALID_ADDRESS)
131         rebase_exec = false;
132     }
133   } else {
134     // no executable, nothing to re-base
135     rebase_exec = false;
136   }
137 
138   // if the target executable should be re-based
139   if (rebase_exec) {
140     ModuleList module_list;
141 
142     module_list.Append(executable_sp);
143     if (log)
144       log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
145                   " added executable '%s' to module load list",
146                   __FUNCTION__,
147                   m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
148                   executable_sp->GetFileSpec().GetPath().c_str());
149 
150     UpdateLoadedSections(executable_sp, LLDB_INVALID_ADDRESS, load_offset,
151                          true);
152 
153     // When attaching to a target, there are two possible states:
154     // (1) We already crossed the entry point and therefore the rendezvous
155     //     structure is ready to be used and we can load the list of modules
156     //     and place the rendezvous breakpoint.
157     // (2) We didn't cross the entry point yet, so these structures are not
158     //     ready; we should behave as if we just launched the target and
159     //     call ProbeEntry(). This will place a breakpoint on the entry
160     //     point which itself will be hit after the rendezvous structure is
161     //     set up and will perform actions described in (1).
162     if (m_rendezvous.Resolve()) {
163       if (log)
164         log->Printf("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64
165                     " rendezvous could resolve: attach assuming dynamic loader "
166                     "info is available now",
167                     __FUNCTION__,
168                     m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
169       LoadAllCurrentModules();
170       SetRendezvousBreakpoint();
171     } else {
172       if (log)
173         log->Printf("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64
174                     " rendezvous could not yet resolve: adding breakpoint to "
175                     "catch future rendezvous setup",
176                     __FUNCTION__,
177                     m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
178       ProbeEntry();
179     }
180 
181     m_process->GetTarget().ModulesDidLoad(module_list);
182     if (log) {
183       log->Printf("DynamicLoaderPOSIXDYLD::%s told the target about the "
184                   "modules that loaded:",
185                   __FUNCTION__);
186       for (auto module_sp : module_list.Modules()) {
187         log->Printf("-- [module] %s (pid %" PRIu64 ")",
188                     module_sp ? module_sp->GetFileSpec().GetPath().c_str()
189                               : "<null>",
190                     m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
191       }
192     }
193   }
194 }
195 
196 void DynamicLoaderPOSIXDYLD::DidLaunch() {
197   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
198   if (log)
199     log->Printf("DynamicLoaderPOSIXDYLD::%s()", __FUNCTION__);
200 
201   ModuleSP executable;
202   addr_t load_offset;
203 
204   m_auxv.reset(new AuxVector(m_process));
205 
206   executable = GetTargetExecutable();
207   load_offset = ComputeLoadOffset();
208   EvalVdsoStatus();
209 
210   if (executable.get() && load_offset != LLDB_INVALID_ADDRESS) {
211     ModuleList module_list;
212     module_list.Append(executable);
213     UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset, true);
214 
215     if (log)
216       log->Printf("DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()",
217                   __FUNCTION__);
218     ProbeEntry();
219 
220     m_process->GetTarget().ModulesDidLoad(module_list);
221   }
222 }
223 
224 Error DynamicLoaderPOSIXDYLD::CanLoadImage() { return Error(); }
225 
226 void DynamicLoaderPOSIXDYLD::UpdateLoadedSections(ModuleSP module,
227                                                   addr_t link_map_addr,
228                                                   addr_t base_addr,
229                                                   bool base_addr_is_offset) {
230   m_loaded_modules[module] = link_map_addr;
231   UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset);
232 }
233 
234 void DynamicLoaderPOSIXDYLD::UnloadSections(const ModuleSP module) {
235   m_loaded_modules.erase(module);
236 
237   UnloadSectionsCommon(module);
238 }
239 
240 void DynamicLoaderPOSIXDYLD::ProbeEntry() {
241   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
242 
243   const addr_t entry = GetEntryPoint();
244   if (entry == LLDB_INVALID_ADDRESS) {
245     if (log)
246       log->Printf(
247           "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
248           " GetEntryPoint() returned no address, not setting entry breakpoint",
249           __FUNCTION__,
250           m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
251     return;
252   }
253 
254   if (log)
255     log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
256                 " GetEntryPoint() returned address 0x%" PRIx64
257                 ", setting entry breakpoint",
258                 __FUNCTION__,
259                 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
260                 entry);
261 
262   if (m_process) {
263     Breakpoint *const entry_break =
264         m_process->GetTarget().CreateBreakpoint(entry, true, false).get();
265     entry_break->SetCallback(EntryBreakpointHit, this, true);
266     entry_break->SetBreakpointKind("shared-library-event");
267 
268     // Shoudn't hit this more than once.
269     entry_break->SetOneShot(true);
270   }
271 }
272 
273 // The runtime linker has run and initialized the rendezvous structure once the
274 // process has hit its entry point.  When we hit the corresponding breakpoint we
275 // interrogate the rendezvous structure to get the load addresses of all
276 // dependent modules for the process.  Similarly, we can discover the runtime
277 // linker function and setup a breakpoint to notify us of any dynamically loaded
278 // modules (via dlopen).
279 bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit(
280     void *baton, StoppointCallbackContext *context, user_id_t break_id,
281     user_id_t break_loc_id) {
282   assert(baton && "null baton");
283   if (!baton)
284     return false;
285 
286   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
287   DynamicLoaderPOSIXDYLD *const dyld_instance =
288       static_cast<DynamicLoaderPOSIXDYLD *>(baton);
289   if (log)
290     log->Printf("DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
291                 __FUNCTION__,
292                 dyld_instance->m_process ? dyld_instance->m_process->GetID()
293                                          : LLDB_INVALID_PROCESS_ID);
294 
295   // Disable the breakpoint --- if a stop happens right after this, which we've
296   // seen on occasion, we don't
297   // want the breakpoint stepping thread-plan logic to show a breakpoint
298   // instruction at the disassembled
299   // entry point to the program.  Disabling it prevents it.  (One-shot is not
300   // enough - one-shot removal logic
301   // only happens after the breakpoint goes public, which wasn't happening in
302   // our scenario).
303   if (dyld_instance->m_process) {
304     BreakpointSP breakpoint_sp =
305         dyld_instance->m_process->GetTarget().GetBreakpointByID(break_id);
306     if (breakpoint_sp) {
307       if (log)
308         log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
309                     " disabling breakpoint id %" PRIu64,
310                     __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
311       breakpoint_sp->SetEnabled(false);
312     } else {
313       if (log)
314         log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
315                     " failed to find breakpoint for breakpoint id %" PRIu64,
316                     __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
317     }
318   } else {
319     if (log)
320       log->Printf("DynamicLoaderPOSIXDYLD::%s breakpoint id %" PRIu64
321                   " no Process instance!  Cannot disable breakpoint",
322                   __FUNCTION__, break_id);
323   }
324 
325   dyld_instance->LoadAllCurrentModules();
326   dyld_instance->SetRendezvousBreakpoint();
327   return false; // Continue running.
328 }
329 
330 void DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() {
331   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
332 
333   addr_t break_addr = m_rendezvous.GetBreakAddress();
334   Target &target = m_process->GetTarget();
335 
336   if (m_dyld_bid == LLDB_INVALID_BREAK_ID) {
337     if (log)
338       log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
339                   " setting rendezvous break address at 0x%" PRIx64,
340                   __FUNCTION__,
341                   m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
342                   break_addr);
343     Breakpoint *dyld_break =
344         target.CreateBreakpoint(break_addr, true, false).get();
345     dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
346     dyld_break->SetBreakpointKind("shared-library-event");
347     m_dyld_bid = dyld_break->GetID();
348   } else {
349     if (log)
350       log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
351                   " reusing break id %" PRIu32 ", address at 0x%" PRIx64,
352                   __FUNCTION__,
353                   m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
354                   m_dyld_bid, break_addr);
355   }
356 
357   // Make sure our breakpoint is at the right address.
358   assert(target.GetBreakpointByID(m_dyld_bid)
359              ->FindLocationByAddress(break_addr)
360              ->GetBreakpoint()
361              .GetID() == m_dyld_bid);
362 }
363 
364 bool DynamicLoaderPOSIXDYLD::RendezvousBreakpointHit(
365     void *baton, StoppointCallbackContext *context, user_id_t break_id,
366     user_id_t break_loc_id) {
367   assert(baton && "null baton");
368   if (!baton)
369     return false;
370 
371   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
372   DynamicLoaderPOSIXDYLD *const dyld_instance =
373       static_cast<DynamicLoaderPOSIXDYLD *>(baton);
374   if (log)
375     log->Printf("DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
376                 __FUNCTION__,
377                 dyld_instance->m_process ? dyld_instance->m_process->GetID()
378                                          : LLDB_INVALID_PROCESS_ID);
379 
380   dyld_instance->RefreshModules();
381 
382   // Return true to stop the target, false to just let the target run.
383   const bool stop_when_images_change = dyld_instance->GetStopWhenImagesChange();
384   if (log)
385     log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
386                 " stop_when_images_change=%s",
387                 __FUNCTION__,
388                 dyld_instance->m_process ? dyld_instance->m_process->GetID()
389                                          : LLDB_INVALID_PROCESS_ID,
390                 stop_when_images_change ? "true" : "false");
391   return stop_when_images_change;
392 }
393 
394 void DynamicLoaderPOSIXDYLD::RefreshModules() {
395   if (!m_rendezvous.Resolve())
396     return;
397 
398   DYLDRendezvous::iterator I;
399   DYLDRendezvous::iterator E;
400 
401   ModuleList &loaded_modules = m_process->GetTarget().GetImages();
402 
403   if (m_rendezvous.ModulesDidLoad()) {
404     ModuleList new_modules;
405 
406     E = m_rendezvous.loaded_end();
407     for (I = m_rendezvous.loaded_begin(); I != E; ++I) {
408       ModuleSP module_sp =
409           LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
410       if (module_sp.get()) {
411         loaded_modules.AppendIfNeeded(module_sp);
412         new_modules.Append(module_sp);
413       }
414     }
415     m_process->GetTarget().ModulesDidLoad(new_modules);
416   }
417 
418   if (m_rendezvous.ModulesDidUnload()) {
419     ModuleList old_modules;
420 
421     E = m_rendezvous.unloaded_end();
422     for (I = m_rendezvous.unloaded_begin(); I != E; ++I) {
423       ModuleSpec module_spec{I->file_spec};
424       ModuleSP module_sp = loaded_modules.FindFirstModule(module_spec);
425 
426       if (module_sp.get()) {
427         old_modules.Append(module_sp);
428         UnloadSections(module_sp);
429       }
430     }
431     loaded_modules.Remove(old_modules);
432     m_process->GetTarget().ModulesDidUnload(old_modules, false);
433   }
434 }
435 
436 ThreadPlanSP
437 DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread,
438                                                      bool stop) {
439   ThreadPlanSP thread_plan_sp;
440 
441   StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
442   const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
443   Symbol *sym = context.symbol;
444 
445   if (sym == NULL || !sym->IsTrampoline())
446     return thread_plan_sp;
447 
448   ConstString sym_name = sym->GetName();
449   if (!sym_name)
450     return thread_plan_sp;
451 
452   SymbolContextList target_symbols;
453   Target &target = thread.GetProcess()->GetTarget();
454   const ModuleList &images = target.GetImages();
455 
456   images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
457   size_t num_targets = target_symbols.GetSize();
458   if (!num_targets)
459     return thread_plan_sp;
460 
461   typedef std::vector<lldb::addr_t> AddressVector;
462   AddressVector addrs;
463   for (size_t i = 0; i < num_targets; ++i) {
464     SymbolContext context;
465     AddressRange range;
466     if (target_symbols.GetContextAtIndex(i, context)) {
467       context.GetAddressRange(eSymbolContextEverything, 0, false, range);
468       lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target);
469       if (addr != LLDB_INVALID_ADDRESS)
470         addrs.push_back(addr);
471     }
472   }
473 
474   if (addrs.size() > 0) {
475     AddressVector::iterator start = addrs.begin();
476     AddressVector::iterator end = addrs.end();
477 
478     std::sort(start, end);
479     addrs.erase(std::unique(start, end), end);
480     thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop));
481   }
482 
483   return thread_plan_sp;
484 }
485 
486 void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() {
487   DYLDRendezvous::iterator I;
488   DYLDRendezvous::iterator E;
489   ModuleList module_list;
490 
491   if (!m_rendezvous.Resolve()) {
492     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
493     if (log)
494       log->Printf("DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD "
495                   "rendezvous address",
496                   __FUNCTION__);
497     return;
498   }
499 
500   // The rendezvous class doesn't enumerate the main module, so track
501   // that ourselves here.
502   ModuleSP executable = GetTargetExecutable();
503   m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress();
504   if (m_vdso_base != LLDB_INVALID_ADDRESS) {
505     FileSpec file_spec("[vdso]", false);
506     ModuleSP module_sp = LoadModuleAtAddress(file_spec, LLDB_INVALID_ADDRESS,
507                                              m_vdso_base, false);
508     if (module_sp.get()) {
509       module_list.Append(module_sp);
510     }
511   }
512 
513   std::vector<FileSpec> module_names;
514   for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
515     module_names.push_back(I->file_spec);
516   m_process->PrefetchModuleSpecs(
517       module_names, m_process->GetTarget().GetArchitecture().GetTriple());
518 
519   for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) {
520     ModuleSP module_sp =
521         LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
522     if (module_sp.get()) {
523       module_list.Append(module_sp);
524     } else {
525       Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
526       if (log)
527         log->Printf(
528             "DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64,
529             __FUNCTION__, I->file_spec.GetCString(), I->base_addr);
530     }
531   }
532 
533   m_process->GetTarget().ModulesDidLoad(module_list);
534 }
535 
536 addr_t DynamicLoaderPOSIXDYLD::ComputeLoadOffset() {
537   addr_t virt_entry;
538 
539   if (m_load_offset != LLDB_INVALID_ADDRESS)
540     return m_load_offset;
541 
542   if ((virt_entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS)
543     return LLDB_INVALID_ADDRESS;
544 
545   ModuleSP module = m_process->GetTarget().GetExecutableModule();
546   if (!module)
547     return LLDB_INVALID_ADDRESS;
548 
549   ObjectFile *exe = module->GetObjectFile();
550   if (!exe)
551     return LLDB_INVALID_ADDRESS;
552 
553   Address file_entry = exe->GetEntryPointAddress();
554 
555   if (!file_entry.IsValid())
556     return LLDB_INVALID_ADDRESS;
557 
558   m_load_offset = virt_entry - file_entry.GetFileAddress();
559   return m_load_offset;
560 }
561 
562 void DynamicLoaderPOSIXDYLD::EvalVdsoStatus() {
563   AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AT_SYSINFO_EHDR);
564 
565   if (I != m_auxv->end())
566     m_vdso_base = I->value;
567 }
568 
569 addr_t DynamicLoaderPOSIXDYLD::GetEntryPoint() {
570   if (m_entry_point != LLDB_INVALID_ADDRESS)
571     return m_entry_point;
572 
573   if (m_auxv.get() == NULL)
574     return LLDB_INVALID_ADDRESS;
575 
576   AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AT_ENTRY);
577 
578   if (I == m_auxv->end())
579     return LLDB_INVALID_ADDRESS;
580 
581   m_entry_point = static_cast<addr_t>(I->value);
582 
583   const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
584 
585   // On ppc64, the entry point is actually a descriptor.  Dereference it.
586   if (arch.GetMachine() == llvm::Triple::ppc64)
587     m_entry_point = ReadUnsignedIntWithSizeInBytes(m_entry_point, 8);
588 
589   return m_entry_point;
590 }
591 
592 lldb::addr_t
593 DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp,
594                                            const lldb::ThreadSP thread,
595                                            lldb::addr_t tls_file_addr) {
596   auto it = m_loaded_modules.find(module_sp);
597   if (it == m_loaded_modules.end())
598     return LLDB_INVALID_ADDRESS;
599 
600   addr_t link_map = it->second;
601   if (link_map == LLDB_INVALID_ADDRESS)
602     return LLDB_INVALID_ADDRESS;
603 
604   const DYLDRendezvous::ThreadInfo &metadata = m_rendezvous.GetThreadInfo();
605   if (!metadata.valid)
606     return LLDB_INVALID_ADDRESS;
607 
608   // Get the thread pointer.
609   addr_t tp = thread->GetThreadPointer();
610   if (tp == LLDB_INVALID_ADDRESS)
611     return LLDB_INVALID_ADDRESS;
612 
613   // Find the module's modid.
614   int modid_size = 4; // FIXME(spucci): This isn't right for big-endian 64-bit
615   int64_t modid = ReadUnsignedIntWithSizeInBytes(
616       link_map + metadata.modid_offset, modid_size);
617   if (modid == -1)
618     return LLDB_INVALID_ADDRESS;
619 
620   // Lookup the DTV structure for this thread.
621   addr_t dtv_ptr = tp + metadata.dtv_offset;
622   addr_t dtv = ReadPointer(dtv_ptr);
623   if (dtv == LLDB_INVALID_ADDRESS)
624     return LLDB_INVALID_ADDRESS;
625 
626   // Find the TLS block for this module.
627   addr_t dtv_slot = dtv + metadata.dtv_slot_size * modid;
628   addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset);
629 
630   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
631   if (log)
632     log->Printf("DynamicLoaderPOSIXDYLD::Performed TLS lookup: "
633                 "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
634                 ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n",
635                 module_sp->GetObjectName().AsCString(""), link_map, tp,
636                 (int64_t)modid, tls_block);
637 
638   if (tls_block == LLDB_INVALID_ADDRESS)
639     return LLDB_INVALID_ADDRESS;
640   else
641     return tls_block + tls_file_addr;
642 }
643 
644 void DynamicLoaderPOSIXDYLD::ResolveExecutableModule(
645     lldb::ModuleSP &module_sp) {
646   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
647 
648   if (m_process == nullptr)
649     return;
650 
651   auto &target = m_process->GetTarget();
652   const auto platform_sp = target.GetPlatform();
653 
654   ProcessInstanceInfo process_info;
655   if (!m_process->GetProcessInfo(process_info)) {
656     if (log)
657       log->Printf("DynamicLoaderPOSIXDYLD::%s - failed to get process info for "
658                   "pid %" PRIu64,
659                   __FUNCTION__, m_process->GetID());
660     return;
661   }
662 
663   if (log)
664     log->Printf("DynamicLoaderPOSIXDYLD::%s - got executable by pid %" PRIu64
665                 ": %s",
666                 __FUNCTION__, m_process->GetID(),
667                 process_info.GetExecutableFile().GetPath().c_str());
668 
669   ModuleSpec module_spec(process_info.GetExecutableFile(),
670                          process_info.GetArchitecture());
671   if (module_sp && module_sp->MatchesModuleSpec(module_spec))
672     return;
673 
674   const auto executable_search_paths(Target::GetDefaultExecutableSearchPaths());
675   auto error = platform_sp->ResolveExecutable(
676       module_spec, module_sp,
677       !executable_search_paths.IsEmpty() ? &executable_search_paths : nullptr);
678   if (error.Fail()) {
679     StreamString stream;
680     module_spec.Dump(stream);
681 
682     if (log)
683       log->Printf("DynamicLoaderPOSIXDYLD::%s - failed to resolve executable "
684                   "with module spec \"%s\": %s",
685                   __FUNCTION__, stream.GetString().c_str(), error.AsCString());
686     return;
687   }
688 
689   target.SetExecutableModule(module_sp, false);
690 }
691 
692 bool DynamicLoaderPOSIXDYLD::AlwaysRelyOnEHUnwindInfo(
693     lldb_private::SymbolContext &sym_ctx) {
694   ModuleSP module_sp;
695   if (sym_ctx.symbol)
696     module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
697   if (!module_sp && sym_ctx.function)
698     module_sp =
699         sym_ctx.function->GetAddressRange().GetBaseAddress().GetModule();
700   if (!module_sp)
701     return false;
702 
703   return module_sp->GetFileSpec().GetPath() == "[vdso]";
704 }
705