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