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