DynamicLoaderPOSIXDYLD.cpp revision 360784
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
29using namespace lldb;
30using namespace lldb_private;
31
32void DynamicLoaderPOSIXDYLD::Initialize() {
33  PluginManager::RegisterPlugin(GetPluginNameStatic(),
34                                GetPluginDescriptionStatic(), CreateInstance);
35}
36
37void DynamicLoaderPOSIXDYLD::Terminate() {}
38
39lldb_private::ConstString DynamicLoaderPOSIXDYLD::GetPluginName() {
40  return GetPluginNameStatic();
41}
42
43lldb_private::ConstString DynamicLoaderPOSIXDYLD::GetPluginNameStatic() {
44  static ConstString g_name("linux-dyld");
45  return g_name;
46}
47
48const char *DynamicLoaderPOSIXDYLD::GetPluginDescriptionStatic() {
49  return "Dynamic loader plug-in that watches for shared library "
50         "loads/unloads in POSIX processes.";
51}
52
53uint32_t DynamicLoaderPOSIXDYLD::GetPluginVersion() { return 1; }
54
55DynamicLoader *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
72DynamicLoaderPOSIXDYLD::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
79DynamicLoaderPOSIXDYLD::~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
86void 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
175void 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
207Status DynamicLoaderPOSIXDYLD::CanLoadImage() { return Status(); }
208
209void 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
217void DynamicLoaderPOSIXDYLD::UnloadSections(const ModuleSP module) {
218  m_loaded_modules.erase(module);
219
220  UnloadSectionsCommon(module);
221}
222
223void 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).
260bool 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
308bool 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
381bool 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
410void 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
452ThreadPlanSP
453DynamicLoaderPOSIXDYLD::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
503void 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
524ModuleSP 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
550void 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
596addr_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
622void 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
632addr_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
655lldb::addr_t
656DynamicLoaderPOSIXDYLD::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
707void 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
754bool 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