LLDB  mainline
DynamicLoaderPOSIXDYLD.cpp
Go to the documentation of this file.
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 "AuxVector.h"
13 
15 #include "lldb/Core/Module.h"
16 #include "lldb/Core/ModuleSpec.h"
18 #include "lldb/Core/Section.h"
19 #include "lldb/Symbol/Function.h"
20 #include "lldb/Symbol/ObjectFile.h"
22 #include "lldb/Target/Platform.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Target/Thread.h"
26 #include "lldb/Utility/Log.h"
28 
29 #include <memory>
30 
31 using namespace lldb;
32 using namespace lldb_private;
33 
35  PluginManager::RegisterPlugin(GetPluginNameStatic(),
36  GetPluginDescriptionStatic(), CreateInstance);
37 }
38 
40 
42  return GetPluginNameStatic();
43 }
44 
46  static ConstString g_name("linux-dyld");
47  return g_name;
48 }
49 
51  return "Dynamic loader plug-in that watches for shared library "
52  "loads/unloads in POSIX processes.";
53 }
54 
56 
58  bool force) {
59  bool create = force;
60  if (!create) {
61  const llvm::Triple &triple_ref =
62  process->GetTarget().GetArchitecture().GetTriple();
63  if (triple_ref.getOS() == llvm::Triple::FreeBSD ||
64  triple_ref.getOS() == llvm::Triple::Linux ||
65  triple_ref.getOS() == llvm::Triple::NetBSD)
66  create = true;
67  }
68 
69  if (create)
70  return new DynamicLoaderPOSIXDYLD(process);
71  return NULL;
72 }
73 
75  : DynamicLoader(process), m_rendezvous(process),
76  m_load_offset(LLDB_INVALID_ADDRESS), m_entry_point(LLDB_INVALID_ADDRESS),
77  m_auxv(), m_dyld_bid(LLDB_INVALID_BREAK_ID),
78  m_vdso_base(LLDB_INVALID_ADDRESS),
79  m_interpreter_base(LLDB_INVALID_ADDRESS) {}
80 
85  }
86 }
87 
90  if (log)
91  log->Printf("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64, __FUNCTION__,
93 
94  m_auxv.reset(new AuxVector(m_process));
95  if (log)
96  log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reloaded auxv data",
97  __FUNCTION__,
99 
100  // ask the process if it can load any of its own modules
102 
103  ModuleSP executable_sp = GetTargetExecutable();
104  ResolveExecutableModule(executable_sp);
105 
106  // find the main process load offset
107  addr_t load_offset = ComputeLoadOffset();
108  if (log)
109  log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
110  " executable '%s', load_offset 0x%" PRIx64,
111  __FUNCTION__,
113  executable_sp ? executable_sp->GetFileSpec().GetPath().c_str()
114  : "<null executable>",
115  load_offset);
116 
118 
119  // if we dont have a load address we cant re-base
120  bool rebase_exec = load_offset != LLDB_INVALID_ADDRESS;
121 
122  // if we have a valid executable
123  if (executable_sp.get()) {
124  lldb_private::ObjectFile *obj = executable_sp->GetObjectFile();
125  if (obj) {
126  // don't rebase if the module already has a load address
127  Target &target = m_process->GetTarget();
128  Address addr = obj->GetImageInfoAddress(&target);
129  if (addr.GetLoadAddress(&target) != LLDB_INVALID_ADDRESS)
130  rebase_exec = false;
131  }
132  } else {
133  // no executable, nothing to re-base
134  rebase_exec = false;
135  }
136 
137  // if the target executable should be re-based
138  if (rebase_exec) {
139  ModuleList module_list;
140 
141  module_list.Append(executable_sp);
142  if (log)
143  log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
144  " added executable '%s' to module load list",
145  __FUNCTION__,
147  executable_sp->GetFileSpec().GetPath().c_str());
148 
149  UpdateLoadedSections(executable_sp, LLDB_INVALID_ADDRESS, load_offset,
150  true);
151 
153  if (!SetRendezvousBreakpoint()) {
154  // If we cannot establish rendezvous breakpoint right now we'll try again
155  // at entry point.
156  ProbeEntry();
157  }
158 
159  m_process->GetTarget().ModulesDidLoad(module_list);
160  if (log) {
161  log->Printf("DynamicLoaderPOSIXDYLD::%s told the target about the "
162  "modules that loaded:",
163  __FUNCTION__);
164  for (auto module_sp : module_list.Modules()) {
165  log->Printf("-- [module] %s (pid %" PRIu64 ")",
166  module_sp ? module_sp->GetFileSpec().GetPath().c_str()
167  : "<null>",
169  }
170  }
171  }
172 }
173 
176  if (log)
177  log->Printf("DynamicLoaderPOSIXDYLD::%s()", __FUNCTION__);
178 
179  ModuleSP executable;
180  addr_t load_offset;
181 
182  m_auxv.reset(new AuxVector(m_process));
183 
184  executable = GetTargetExecutable();
185  load_offset = ComputeLoadOffset();
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  if (log)
194  log->Printf("DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()",
195  __FUNCTION__);
196 
197  if (!SetRendezvousBreakpoint()) {
198  // If we cannot establish rendezvous breakpoint right now we'll try again
199  // at entry point.
200  ProbeEntry();
201  }
202 
203  LoadVDSO();
204  m_process->GetTarget().ModulesDidLoad(module_list);
205  }
206 }
207 
209 
211  addr_t link_map_addr,
212  addr_t base_addr,
213  bool base_addr_is_offset) {
214  m_loaded_modules[module] = link_map_addr;
215  UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset);
216 }
217 
218 void DynamicLoaderPOSIXDYLD::UnloadSections(const ModuleSP module) {
219  m_loaded_modules.erase(module);
220 
221  UnloadSectionsCommon(module);
222 }
223 
226 
227  const addr_t entry = GetEntryPoint();
228  if (entry == LLDB_INVALID_ADDRESS) {
229  if (log)
230  log->Printf(
231  "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
232  " GetEntryPoint() returned no address, not setting entry breakpoint",
233  __FUNCTION__,
235  return;
236  }
237 
238  if (log)
239  log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
240  " GetEntryPoint() returned address 0x%" PRIx64
241  ", setting entry breakpoint",
242  __FUNCTION__,
244  entry);
245 
246  if (m_process) {
247  Breakpoint *const entry_break =
248  m_process->GetTarget().CreateBreakpoint(entry, true, false).get();
249  entry_break->SetCallback(EntryBreakpointHit, this, true);
250  entry_break->SetBreakpointKind("shared-library-event");
251 
252  // Shoudn't hit this more than once.
253  entry_break->SetOneShot(true);
254  }
255 }
256 
257 // The runtime linker has run and initialized the rendezvous structure once the
258 // process has hit its entry point. When we hit the corresponding breakpoint
259 // we interrogate the rendezvous structure to get the load addresses of all
260 // dependent modules for the process. Similarly, we can discover the runtime
261 // linker function and setup a breakpoint to notify us of any dynamically
262 // loaded modules (via dlopen).
264  void *baton, StoppointCallbackContext *context, user_id_t break_id,
265  user_id_t break_loc_id) {
266  assert(baton && "null baton");
267  if (!baton)
268  return false;
269 
271  DynamicLoaderPOSIXDYLD *const dyld_instance =
272  static_cast<DynamicLoaderPOSIXDYLD *>(baton);
273  if (log)
274  log->Printf("DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
275  __FUNCTION__,
276  dyld_instance->m_process ? dyld_instance->m_process->GetID()
278 
279  // Disable the breakpoint --- if a stop happens right after this, which we've
280  // seen on occasion, we don't want the breakpoint stepping thread-plan logic
281  // to show a breakpoint instruction at the disassembled entry point to the
282  // program. Disabling it prevents it. (One-shot is not enough - one-shot
283  // removal logic only happens after the breakpoint goes public, which wasn't
284  // happening in our scenario).
285  if (dyld_instance->m_process) {
286  BreakpointSP breakpoint_sp =
287  dyld_instance->m_process->GetTarget().GetBreakpointByID(break_id);
288  if (breakpoint_sp) {
289  if (log)
290  log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
291  " disabling breakpoint id %" PRIu64,
292  __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
293  breakpoint_sp->SetEnabled(false);
294  } else {
295  if (log)
296  log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
297  " failed to find breakpoint for breakpoint id %" PRIu64,
298  __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
299  }
300  } else {
301  if (log)
302  log->Printf("DynamicLoaderPOSIXDYLD::%s breakpoint id %" PRIu64
303  " no Process instance! Cannot disable breakpoint",
304  __FUNCTION__, break_id);
305  }
306 
307  dyld_instance->LoadAllCurrentModules();
308  dyld_instance->SetRendezvousBreakpoint();
309  return false; // Continue running.
310 }
311 
315  LLDB_LOG(log,
316  "Rendezvous breakpoint breakpoint id {0} for pid {1}"
317  "is already set.",
318  m_dyld_bid,
320  return true;
321  }
322 
323  addr_t break_addr;
324  Target &target = m_process->GetTarget();
325  BreakpointSP dyld_break;
326  if (m_rendezvous.IsValid()) {
327  break_addr = m_rendezvous.GetBreakAddress();
328  LLDB_LOG(log, "Setting rendezvous break address for pid {0} at {1:x}",
330  break_addr);
331  dyld_break = target.CreateBreakpoint(break_addr, true, false);
332  } else {
333  LLDB_LOG(log, "Rendezvous structure is not set up yet. "
334  "Trying to locate rendezvous breakpoint in the interpreter "
335  "by symbol name.");
336  ModuleSP interpreter = LoadInterpreterModule();
337  if (!interpreter) {
338  LLDB_LOG(log, "Can't find interpreter, rendezvous breakpoint isn't set.");
339  return false;
340  }
341 
342  // Function names from different dynamic loaders that are known to be used
343  // as rendezvous between the loader and debuggers.
344  static std::vector<std::string> DebugStateCandidates{
345  "_dl_debug_state", "rtld_db_dlactivity", "__dl_rtld_db_dlactivity",
346  "r_debug_state", "_r_debug_state", "_rtld_debug_state",
347  };
348 
349  FileSpecList containingModules;
350  containingModules.Append(interpreter->GetFileSpec());
351  dyld_break = target.CreateBreakpoint(
352  &containingModules, nullptr /* containingSourceFiles */,
353  DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC,
354  0, /* offset */
355  eLazyBoolNo, /* skip_prologue */
356  true, /* internal */
357  false /* request_hardware */);
358  }
359 
360  if (dyld_break->GetNumResolvedLocations() != 1) {
361  LLDB_LOG(
362  log,
363  "Rendezvous breakpoint has abnormal number of"
364  " resolved locations ({0}) in pid {1}. It's supposed to be exactly 1.",
365  dyld_break->GetNumResolvedLocations(),
367 
368  target.RemoveBreakpointByID(dyld_break->GetID());
369  return false;
370  }
371 
372  BreakpointLocationSP location = dyld_break->GetLocationAtIndex(0);
373  LLDB_LOG(log,
374  "Successfully set rendezvous breakpoint at address {0:x} "
375  "for pid {1}",
376  location->GetLoadAddress(),
378 
379  dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
380  dyld_break->SetBreakpointKind("shared-library-event");
381  m_dyld_bid = dyld_break->GetID();
382  return true;
383 }
384 
386  void *baton, StoppointCallbackContext *context, user_id_t break_id,
387  user_id_t break_loc_id) {
388  assert(baton && "null baton");
389  if (!baton)
390  return false;
391 
393  DynamicLoaderPOSIXDYLD *const dyld_instance =
394  static_cast<DynamicLoaderPOSIXDYLD *>(baton);
395  if (log)
396  log->Printf("DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
397  __FUNCTION__,
398  dyld_instance->m_process ? dyld_instance->m_process->GetID()
400 
401  dyld_instance->RefreshModules();
402 
403  // Return true to stop the target, false to just let the target run.
404  const bool stop_when_images_change = dyld_instance->GetStopWhenImagesChange();
405  if (log)
406  log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
407  " stop_when_images_change=%s",
408  __FUNCTION__,
409  dyld_instance->m_process ? dyld_instance->m_process->GetID()
411  stop_when_images_change ? "true" : "false");
412  return stop_when_images_change;
413 }
414 
416  if (!m_rendezvous.Resolve())
417  return;
418 
421 
422  ModuleList &loaded_modules = m_process->GetTarget().GetImages();
423 
425  ModuleList new_modules;
426 
427  E = m_rendezvous.loaded_end();
428  for (I = m_rendezvous.loaded_begin(); I != E; ++I) {
429  ModuleSP module_sp =
430  LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
431  if (module_sp.get()) {
432  loaded_modules.AppendIfNeeded(module_sp);
433  new_modules.Append(module_sp);
434  }
435  }
436  m_process->GetTarget().ModulesDidLoad(new_modules);
437  }
438 
440  ModuleList old_modules;
441 
443  for (I = m_rendezvous.unloaded_begin(); I != E; ++I) {
444  ModuleSpec module_spec{I->file_spec};
445  ModuleSP module_sp = loaded_modules.FindFirstModule(module_spec);
446 
447  if (module_sp.get()) {
448  old_modules.Append(module_sp);
449  UnloadSections(module_sp);
450  }
451  }
452  loaded_modules.Remove(old_modules);
453  m_process->GetTarget().ModulesDidUnload(old_modules, false);
454  }
455 }
456 
457 ThreadPlanSP
459  bool stop) {
460  ThreadPlanSP thread_plan_sp;
461 
462  StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
463  const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
464  Symbol *sym = context.symbol;
465 
466  if (sym == NULL || !sym->IsTrampoline())
467  return thread_plan_sp;
468 
469  ConstString sym_name = sym->GetName();
470  if (!sym_name)
471  return thread_plan_sp;
472 
473  SymbolContextList target_symbols;
474  Target &target = thread.GetProcess()->GetTarget();
475  const ModuleList &images = target.GetImages();
476 
477  images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
478  size_t num_targets = target_symbols.GetSize();
479  if (!num_targets)
480  return thread_plan_sp;
481 
482  typedef std::vector<lldb::addr_t> AddressVector;
483  AddressVector addrs;
484  for (size_t i = 0; i < num_targets; ++i) {
485  SymbolContext context;
486  AddressRange range;
487  if (target_symbols.GetContextAtIndex(i, context)) {
488  context.GetAddressRange(eSymbolContextEverything, 0, false, range);
489  lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target);
490  if (addr != LLDB_INVALID_ADDRESS)
491  addrs.push_back(addr);
492  }
493  }
494 
495  if (addrs.size() > 0) {
496  AddressVector::iterator start = addrs.begin();
497  AddressVector::iterator end = addrs.end();
498 
499  llvm::sort(start, end);
500  addrs.erase(std::unique(start, end), end);
501  thread_plan_sp =
502  std::make_shared<ThreadPlanRunToAddress>(thread, addrs, stop);
503  }
504 
505  return thread_plan_sp;
506 }
507 
510  return;
511 
512  FileSpec file("[vdso]");
513 
514  MemoryRegionInfo info;
516  if (status.Fail()) {
518  LLDB_LOG(log, "Failed to get vdso region info: {0}", status);
519  return;
520  }
521 
522  if (ModuleSP module_sp = m_process->ReadModuleFromMemory(
523  file, m_vdso_base, info.GetRange().GetByteSize())) {
526  }
527 }
528 
531  return nullptr;
532 
533  MemoryRegionInfo info;
534  Target &target = m_process->GetTarget();
536  if (status.Fail() || info.GetMapped() != MemoryRegionInfo::eYes ||
537  info.GetName().IsEmpty()) {
539  LLDB_LOG(log, "Failed to get interpreter region info: {0}", status);
540  return nullptr;
541  }
542 
543  FileSpec file(info.GetName().GetCString());
544  ModuleSpec module_spec(file, target.GetArchitecture());
545 
546  if (ModuleSP module_sp = target.GetOrCreateModule(module_spec,
547  true /* notify */)) {
549  false);
550  return module_sp;
551  }
552  return nullptr;
553 }
554 
558  ModuleList module_list;
560 
561  LoadVDSO();
562 
563  if (!m_rendezvous.Resolve()) {
564  if (log)
565  log->Printf("DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD "
566  "rendezvous address",
567  __FUNCTION__);
568  return;
569  }
570 
571  // The rendezvous class doesn't enumerate the main module, so track that
572  // ourselves here.
573  ModuleSP executable = GetTargetExecutable();
575 
576  std::vector<FileSpec> module_names;
577  for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
578  module_names.push_back(I->file_spec);
580  module_names, m_process->GetTarget().GetArchitecture().GetTriple());
581 
582  for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) {
583  ModuleSP module_sp =
584  LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
585  if (module_sp.get()) {
586  LLDB_LOG(log, "LoadAllCurrentModules loading module: {0}",
587  I->file_spec.GetFilename());
588  module_list.Append(module_sp);
589  } else {
591  if (log)
592  log->Printf(
593  "DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64,
594  __FUNCTION__, I->file_spec.GetCString(), I->base_addr);
595  }
596  }
597 
598  m_process->GetTarget().ModulesDidLoad(module_list);
599 }
600 
602  addr_t virt_entry;
603 
605  return m_load_offset;
606 
607  if ((virt_entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS)
608  return LLDB_INVALID_ADDRESS;
609 
610  ModuleSP module = m_process->GetTarget().GetExecutableModule();
611  if (!module)
612  return LLDB_INVALID_ADDRESS;
613 
614  ObjectFile *exe = module->GetObjectFile();
615  if (!exe)
616  return LLDB_INVALID_ADDRESS;
617 
618  Address file_entry = exe->GetEntryPointAddress();
619 
620  if (!file_entry.IsValid())
621  return LLDB_INVALID_ADDRESS;
622 
623  m_load_offset = virt_entry - file_entry.GetFileAddress();
624  return m_load_offset;
625 }
626 
628  auto I = m_auxv->FindEntry(AuxVector::AUXV_AT_SYSINFO_EHDR);
629  if (I != m_auxv->end() && I->value != 0)
630  m_vdso_base = I->value;
631 
632  I = m_auxv->FindEntry(AuxVector::AUXV_AT_BASE);
633  if (I != m_auxv->end() && I->value != 0)
634  m_interpreter_base = I->value;
635 }
636 
639  return m_entry_point;
640 
641  if (m_auxv == NULL)
642  return LLDB_INVALID_ADDRESS;
643 
645 
646  if (I == m_auxv->end())
647  return LLDB_INVALID_ADDRESS;
648 
649  m_entry_point = static_cast<addr_t>(I->value);
650 
651  const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
652 
653  // On ppc64, the entry point is actually a descriptor. Dereference it.
654  if (arch.GetMachine() == llvm::Triple::ppc64)
656 
657  return m_entry_point;
658 }
659 
661 DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp,
662  const lldb::ThreadSP thread,
663  lldb::addr_t tls_file_addr) {
664  auto it = m_loaded_modules.find(module_sp);
665  if (it == m_loaded_modules.end())
666  return LLDB_INVALID_ADDRESS;
667 
668  addr_t link_map = it->second;
669  if (link_map == LLDB_INVALID_ADDRESS)
670  return LLDB_INVALID_ADDRESS;
671 
673  if (!metadata.valid)
674  return LLDB_INVALID_ADDRESS;
675 
676  // Get the thread pointer.
677  addr_t tp = thread->GetThreadPointer();
678  if (tp == LLDB_INVALID_ADDRESS)
679  return LLDB_INVALID_ADDRESS;
680 
681  // Find the module's modid.
682  int modid_size = 4; // FIXME(spucci): This isn't right for big-endian 64-bit
683  int64_t modid = ReadUnsignedIntWithSizeInBytes(
684  link_map + metadata.modid_offset, modid_size);
685  if (modid == -1)
686  return LLDB_INVALID_ADDRESS;
687 
688  // Lookup the DTV structure for this thread.
689  addr_t dtv_ptr = tp + metadata.dtv_offset;
690  addr_t dtv = ReadPointer(dtv_ptr);
691  if (dtv == LLDB_INVALID_ADDRESS)
692  return LLDB_INVALID_ADDRESS;
693 
694  // Find the TLS block for this module.
695  addr_t dtv_slot = dtv + metadata.dtv_slot_size * modid;
696  addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset);
697 
699  if (log)
700  log->Printf("DynamicLoaderPOSIXDYLD::Performed TLS lookup: "
701  "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
702  ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n",
703  module_sp->GetObjectName().AsCString(""), link_map, tp,
704  (int64_t)modid, tls_block);
705 
706  if (tls_block == LLDB_INVALID_ADDRESS)
707  return LLDB_INVALID_ADDRESS;
708  else
709  return tls_block + tls_file_addr;
710 }
711 
713  lldb::ModuleSP &module_sp) {
715 
716  if (m_process == nullptr)
717  return;
718 
719  auto &target = m_process->GetTarget();
720  const auto platform_sp = target.GetPlatform();
721 
722  ProcessInstanceInfo process_info;
723  if (!m_process->GetProcessInfo(process_info)) {
724  if (log)
725  log->Printf("DynamicLoaderPOSIXDYLD::%s - failed to get process info for "
726  "pid %" PRIu64,
727  __FUNCTION__, m_process->GetID());
728  return;
729  }
730 
731  if (log)
732  log->Printf("DynamicLoaderPOSIXDYLD::%s - got executable by pid %" PRIu64
733  ": %s",
734  __FUNCTION__, m_process->GetID(),
735  process_info.GetExecutableFile().GetPath().c_str());
736 
737  ModuleSpec module_spec(process_info.GetExecutableFile(),
738  process_info.GetArchitecture());
739  if (module_sp && module_sp->MatchesModuleSpec(module_spec))
740  return;
741 
742  const auto executable_search_paths(Target::GetDefaultExecutableSearchPaths());
743  auto error = platform_sp->ResolveExecutable(
744  module_spec, module_sp,
745  !executable_search_paths.IsEmpty() ? &executable_search_paths : nullptr);
746  if (error.Fail()) {
747  StreamString stream;
748  module_spec.Dump(stream);
749 
750  if (log)
751  log->Printf("DynamicLoaderPOSIXDYLD::%s - failed to resolve executable "
752  "with module spec \"%s\": %s",
753  __FUNCTION__, stream.GetData(), error.AsCString());
754  return;
755  }
756 
757  target.SetExecutableModule(module_sp, eLoadDependentsNo);
758 }
759 
761  lldb_private::SymbolContext &sym_ctx) {
762  ModuleSP module_sp;
763  if (sym_ctx.symbol)
764  module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
765  if (!module_sp && sym_ctx.function)
766  module_sp =
768  if (!module_sp)
769  return false;
770 
771  return module_sp->GetFileSpec().GetPath() == "[vdso]";
772 }
lldb_private::ConstString GetPluginName() override
Address & GetAddressRef()
Definition: Symbol.h:56
OptionalBool GetMapped() const
static lldb_private::DynamicLoader * CreateInstance(lldb_private::Process *process, bool force)
virtual lldb_private::Address GetImageInfoAddress(Target *target)
Similar to Process::GetImageInfoAddress().
Definition: ObjectFile.h:458
bool AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override
Ask if the eh_frame information for the given SymbolContext should be relied on even when it&#39;s the fi...
bool RemoveBreakpointByID(lldb::break_id_t break_id)
Definition: Target.cpp:940
Defines a list of symbol context objects.
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
const ArchSpec & GetArchitecture() const
Definition: Target.h:941
Program entry point.
Definition: AuxVector.h:53
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
bool IsTrampoline() const
Definition: Symbol.cpp:170
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition: Address.cpp:292
#define LLDB_INVALID_PROCESS_ID
Definition: lldb-defines.h:92
virtual lldb::ModuleSP LoadModuleAtAddress(const lldb_private::FileSpec &file, lldb::addr_t link_map_addr, lldb::addr_t base_addr, bool base_addr_is_offset)
Locates or creates a module given by file and updates/loads the resulting module at the virtual base ...
General Outline: A breakpoint has four main parts, a filter, a resolver, the list of breakpoint locat...
Definition: Breakpoint.h:78
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition: UserID.h:49
lldb::addr_t GetBreakAddress() const
A breakpoint should be set at this address and Resolve called on each hit.
A file utility class.
Definition: FileSpec.h:55
lldb_private::Status CanLoadImage() override
Ask if it is ok to try and load or unload an shared library (image).
An architecture specification class.
Definition: ArchSpec.h:32
bool GetStopWhenImagesChange() const
Get whether the process should stop when images change.
void DidAttach() override
Called after attaching a process.
lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread, lldb::addr_t tls_file_addr) override
Retrieves the per-module TLS block for a given thread.
bool SetRendezvousBreakpoint()
If possible sets a breakpoint on a function called by the runtime linker each time a module is loaded...
lldb::addr_t GetFileAddress() const
Get the file address.
Definition: Address.cpp:272
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:58
void SetBreakpointKind(const char *kind)
Set the "kind" description for a breakpoint.
Definition: Breakpoint.h:456
virtual void PrefetchModuleSpecs(llvm::ArrayRef< FileSpec > module_file_specs, const llvm::Triple &triple)
Definition: Process.h:2296
const char * GetData() const
Definition: StreamString.h:43
#define LLDB_LOG(log,...)
Definition: Log.h:209
void UnloadSections(const lldb::ModuleSP module) override
Removes the loaded sections from the target in module.
Symbol * symbol
The Symbol for a given query.
void ResolveExecutableModule(lldb::ModuleSP &module_sp)
Loads Module from inferior process.
DynamicLoaderPOSIXDYLD(lldb_private::Process *process)
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:431
lldb::break_id_t m_dyld_bid
Rendezvous breakpoint.
uint32_t GetSize() const
Get accessor for a symbol context list size.
const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame&#39;s current pc value.
Definition: StackFrame.cpp:267
Function * function
The Function for a given query.
void SetCallback(BreakpointHitCallback callback, void *baton, bool is_synchronous=false)
Set the callback action invoked when the breakpoint is hit.
Definition: Breakpoint.cpp:421
bool Remove(const lldb::ModuleSP &module_sp, bool notify=true)
Remove a module from the module list.
lldb::ModuleSP LoadInterpreterModule()
virtual lldb_private::Address GetEntryPointAddress()
Returns the address of the Entry Point in this object file - if the object file doesn&#39;t have an entry...
Definition: ObjectFile.h:468
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
uint64_t user_id_t
Definition: lldb-types.h:84
lldb::addr_t ReadPointer(lldb::addr_t addr)
lldb::BreakpointSP GetBreakpointByID(lldb::break_id_t break_id)
Definition: Target.cpp:297
DYLDRendezvous m_rendezvous
Runtime linker rendezvous structure.
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
lldb::ModuleSP ReadModuleFromMemory(const FileSpec &file_spec, lldb::addr_t header_addr, size_t size_to_read=512)
Definition: Process.cpp:2435
void ProbeEntry()
Resolves the entry point for the current inferior process and sets a breakpoint at that address...
static bool RendezvousBreakpointHit(void *baton, lldb_private::StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
Callback routine which updates the current list of loaded modules based on the information supplied b...
A collection class for Module objects.
Definition: ModuleList.h:91
Process * m_process
The process that this dynamic loader plug-in is tracking.
iterator loaded_begin() const
Iterators over all modules loaded into the inferior since the last call to Resolve().
int64_t ReadUnsignedIntWithSizeInBytes(lldb::addr_t addr, int size_in_bytes)
iterator unloaded_end() const
lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const
Definition: ModuleList.cpp:599
void DidLaunch() override
Called after launching a process.
lldb::addr_t m_load_offset
Virtual load address of the inferior process.
size_t FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list, bool append=false) const
Definition: ModuleList.cpp:457
lldb::addr_t m_entry_point
Virtual entry address of the inferior process.
lldb::ModuleSP GetOrCreateModule(const ModuleSpec &module_spec, bool notify, Status *error_ptr=nullptr)
Find a binary on the system and return its Module, or return an existing Module that is already in th...
Definition: Target.cpp:1999
const ThreadInfo & GetThreadInfo()
lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread, bool stop_others) override
Provides a plan to step through the dynamic loader trampoline for the current state of thread...
lldb::ModuleSP GetTargetExecutable()
Checks to see if the target module has changed, updates the target accordingly and returns the target...
A plug-in interface definition class for debugging a process.
Definition: Process.h:353
Represents a processes auxiliary vector.
Definition: AuxVector.h:27
FileSpec & GetExecutableFile()
Definition: ProcessInfo.h:43
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
Definition: Target.cpp:1380
bool Resolve()
Update the internal snapshot of runtime linker rendezvous and recompute the currently loaded modules...
virtual void LoadAllCurrentModules()
Helper for the entry breakpoint callback.
ArchSpec & GetArchitecture()
Definition: ProcessInfo.h:62
bool ModulesDidLoad() const
virtual size_t LoadModules()
Sometimes processes know how to retrieve and load shared libraries.
Definition: Process.h:684
lldb::addr_t GetEntryPoint()
Computes a value for m_entry_point returning the computed address on success and LLDB_INVALID_ADDRESS...
bool IsValid() const
Check if the object state is valid.
Definition: Address.h:343
A section + offset based address class.
Definition: Address.h:80
lldb::addr_t GetLinkMapAddress() const
void ModulesDidLoad(ModuleList &module_list)
Definition: Target.cpp:1651
lldb::ProcessSP GetProcess() const
Definition: Thread.h:154
static bool EntryBreakpointHit(void *baton, lldb_private::StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
Callback routine invoked when we hit the breakpoint on process entry.
A plug-in interface definition class for dynamic loaders.
Definition: DynamicLoader.h:64
ModuleIterable Modules()
Definition: ModuleList.h:559
bool GetContextAtIndex(size_t idx, SymbolContext &sc) const
Get accessor for a symbol context at index idx.
iterator end() const
Interpreter base address.
Definition: AuxVector.h:51
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:899
#define LIBLLDB_LOG_DYNAMIC_LOADER
Definition: Logging.h:17
iterator loaded_end() const
std::map< lldb::ModuleWP, lldb::addr_t, std::owner_less< lldb::ModuleWP > > m_loaded_modules
Loaded module list. (link map for each module)
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1194
uint64_t addr_t
Definition: lldb-types.h:83
lldb::addr_t m_interpreter_base
Contains AT_BASE, which means a dynamic loader has been mapped to the address space.
lldb::PlatformSP GetPlatform()
Definition: Target.h:1214
A uniqued constant string class.
Definition: ConstString.h:38
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
Definition: Address.cpp:264
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:247
bool ModulesDidUnload() const
virtual Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info)
Locate the memory region that contains load_addr.
Definition: Process.h:1759
void UnloadSectionsCommon(const lldb::ModuleSP module)
Non-standardized C, such as K&R.
Log * GetLogIfAnyCategoriesSet(uint32_t mask)
Definition: Logging.cpp:61
EntryVector::const_iterator iterator
Definition: AuxVector.h:84
Definition: SBAddress.h:15
ConstString GetName() const
Definition: Symbol.cpp:494
void ModulesDidUnload(ModuleList &module_list, bool delete_locations)
Definition: Target.cpp:1686
SOEntryList::const_iterator iterator
lldb::addr_t m_vdso_base
Contains AT_SYSINFO_EHDR, which means a vDSO has been mapped to the address space.
bool GetAddressRange(uint32_t scope, uint32_t range_idx, bool use_inline_block_range, AddressRange &range) const
Get the address range contained within a symbol context.
void SetOneShot(bool one_shot)
If one_shot is true, breakpoint will be deleted on first hit.
Definition: Breakpoint.cpp:337
Address & GetBaseAddress()
Get accessor for the base address of the range.
Definition: AddressRange.h:220
#define LLDB_INVALID_BREAK_ID
Definition: lldb-defines.h:49
iterator unloaded_begin() const
Iterators over all modules unloaded from the inferior since the last call to Resolve().
static const char * GetPluginDescriptionStatic()
void EvalSpecialModulesStatus()
Evaluate if Aux vectors contain vDSO and LD information in case they do, read and assign the address ...
void UpdateLoadedSectionsCommon(lldb::ModuleSP module, lldb::addr_t base_addr, bool base_addr_is_offset)
General Outline: When we hit a breakpoint we need to package up whatever information is needed to eva...
std::unique_ptr< AuxVector > m_auxv
Auxiliary vector of the inferior process.
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
Definition: Thread.h:395
const AddressRange & GetAddressRange()
Definition: Function.h:371
SizeType GetByteSize() const
Definition: RangeMap.h:71
static lldb_private::ConstString GetPluginNameStatic()
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:376
bool AppendIfNeeded(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list, if it is not already there.
void Printf(const char *format,...) __attribute__((format(printf
Definition: Log.cpp:113
A section + offset based address range class.
Definition: AddressRange.h:32
bool IsEmpty() const
Test for empty string.
Definition: ConstString.h:340
iterator begin() const
Iterators over all currently loaded modules.
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition: ArchSpec.cpp:726
uint32_t GetPluginVersion() override
This base class provides an interface to stack frames.
Definition: StackFrame.h:40
lldb::BreakpointSP CreateBreakpoint(const FileSpecList *containingModules, const FileSpec &file, uint32_t line_no, uint32_t column, lldb::addr_t offset, LazyBool check_inlines, LazyBool skip_prologue, bool internal, bool request_hardware, LazyBool move_to_nearest_code)
Definition: Target.cpp:325
virtual bool GetProcessInfo(ProcessInstanceInfo &info)
Definition: Process.cpp:5742
void RefreshModules()
Helper method for RendezvousBreakpointHit.
An error handling class.
Definition: Status.h:44
void UpdateLoadedSections(lldb::ModuleSP module, lldb::addr_t link_map_addr, lldb::addr_t base_addr, bool base_addr_is_offset) override
Updates the load address of every allocatable section in module.
lldb::addr_t ComputeLoadOffset()
Computes a value for m_load_offset returning the computed address on success and LLDB_INVALID_ADDRESS...