LLDB mainline
DynamicLoaderPOSIXDYLD.cpp
Go to the documentation of this file.
1//===-- DynamicLoaderPOSIXDYLD.cpp ----------------------------------------===//
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
11
13#include "lldb/Core/Module.h"
16#include "lldb/Core/Section.h"
21#include "lldb/Target/Target.h"
22#include "lldb/Target/Thread.h"
25#include "lldb/Utility/Log.h"
27
28#include <memory>
29#include <optional>
30
31using namespace lldb;
32using namespace lldb_private;
33
35
36void DynamicLoaderPOSIXDYLD::Initialize() {
37 PluginManager::RegisterPlugin(GetPluginNameStatic(),
38 GetPluginDescriptionStatic(), CreateInstance);
39}
40
42
44 return "Dynamic loader plug-in that watches for shared library "
45 "loads/unloads in POSIX processes.";
46}
47
49 bool force) {
50 bool create = force;
51 if (!create) {
52 const llvm::Triple &triple_ref =
53 process->GetTarget().GetArchitecture().GetTriple();
54 if (triple_ref.getOS() == llvm::Triple::FreeBSD ||
55 triple_ref.getOS() == llvm::Triple::Linux ||
56 triple_ref.getOS() == llvm::Triple::NetBSD)
57 create = true;
58 }
59
60 if (create)
61 return new DynamicLoaderPOSIXDYLD(process);
62 return nullptr;
63}
64
66 : DynamicLoader(process), m_rendezvous(process),
67 m_load_offset(LLDB_INVALID_ADDRESS), m_entry_point(LLDB_INVALID_ADDRESS),
68 m_auxv(), m_dyld_bid(LLDB_INVALID_BREAK_ID),
69 m_vdso_base(LLDB_INVALID_ADDRESS),
70 m_interpreter_base(LLDB_INVALID_ADDRESS), m_initial_modules_added(false) {
71}
72
77 }
78}
79
81 Log *log = GetLog(LLDBLog::DynamicLoader);
82 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64, __FUNCTION__,
84 m_auxv = std::make_unique<AuxVector>(m_process->GetAuxvData());
85
87 log, "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reloaded auxv data",
89
90 ModuleSP executable_sp = GetTargetExecutable();
91 ResolveExecutableModule(executable_sp);
93
94 // find the main process load offset
95 addr_t load_offset = ComputeLoadOffset();
96 LLDB_LOGF(log,
97 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
98 " executable '%s', load_offset 0x%" PRIx64,
99 __FUNCTION__,
101 executable_sp ? executable_sp->GetFileSpec().GetPath().c_str()
102 : "<null executable>",
103 load_offset);
104
106
107 // if we dont have a load address we cant re-base
108 bool rebase_exec = load_offset != LLDB_INVALID_ADDRESS;
109
110 // if we have a valid executable
111 if (executable_sp.get()) {
112 lldb_private::ObjectFile *obj = executable_sp->GetObjectFile();
113 if (obj) {
114 // don't rebase if the module already has a load address
115 Target &target = m_process->GetTarget();
116 Address addr = obj->GetImageInfoAddress(&target);
117 if (addr.GetLoadAddress(&target) != LLDB_INVALID_ADDRESS)
118 rebase_exec = false;
119 }
120 } else {
121 // no executable, nothing to re-base
122 rebase_exec = false;
123 }
124
125 // if the target executable should be re-based
126 if (rebase_exec) {
127 ModuleList module_list;
128
129 module_list.Append(executable_sp);
130 LLDB_LOGF(log,
131 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
132 " added executable '%s' to module load list",
133 __FUNCTION__,
135 executable_sp->GetFileSpec().GetPath().c_str());
136
137 UpdateLoadedSections(executable_sp, LLDB_INVALID_ADDRESS, load_offset,
138 true);
139
141
142 m_process->GetTarget().ModulesDidLoad(module_list);
143 if (log) {
144 LLDB_LOGF(log,
145 "DynamicLoaderPOSIXDYLD::%s told the target about the "
146 "modules that loaded:",
147 __FUNCTION__);
148 for (auto module_sp : module_list.Modules()) {
149 LLDB_LOGF(log, "-- [module] %s (pid %" PRIu64 ")",
150 module_sp ? module_sp->GetFileSpec().GetPath().c_str()
151 : "<null>",
153 }
154 }
155 }
156
157 if (executable_sp.get()) {
159 // If we cannot establish rendezvous breakpoint right now we'll try again
160 // at entry point.
161 ProbeEntry();
162 }
163 }
164}
165
167 Log *log = GetLog(LLDBLog::DynamicLoader);
168 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s()", __FUNCTION__);
169
170 ModuleSP executable;
171 addr_t load_offset;
172
173 m_auxv = std::make_unique<AuxVector>(m_process->GetAuxvData());
174
175 executable = GetTargetExecutable();
176 load_offset = ComputeLoadOffset();
178
179 if (executable.get() && load_offset != LLDB_INVALID_ADDRESS) {
180 ModuleList module_list;
181 module_list.Append(executable);
182 UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset, true);
183
184 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()",
185 __FUNCTION__);
186
188 // If we cannot establish rendezvous breakpoint right now we'll try again
189 // at entry point.
190 ProbeEntry();
191 }
192
193 LoadVDSO();
194 m_process->GetTarget().ModulesDidLoad(module_list);
195 }
196}
197
199
201 addr_t link_map_addr,
202 addr_t base_addr,
203 bool base_addr_is_offset) {
204 m_loaded_modules[module] = link_map_addr;
205 UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset);
206}
207
209 m_loaded_modules.erase(module);
210
211 UnloadSectionsCommon(module);
212}
213
215 Log *log = GetLog(LLDBLog::DynamicLoader);
216
217 // If we have a core file, we don't need any breakpoints.
218 if (IsCoreFile())
219 return;
220
221 const addr_t entry = GetEntryPoint();
222 if (entry == LLDB_INVALID_ADDRESS) {
223 LLDB_LOGF(
224 log,
225 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
226 " GetEntryPoint() returned no address, not setting entry breakpoint",
227 __FUNCTION__, m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
228 return;
229 }
230
231 LLDB_LOGF(log,
232 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
233 " GetEntryPoint() returned address 0x%" PRIx64
234 ", setting entry breakpoint",
235 __FUNCTION__,
237
238 if (m_process) {
239 Breakpoint *const entry_break =
240 m_process->GetTarget().CreateBreakpoint(entry, true, false).get();
241 entry_break->SetCallback(EntryBreakpointHit, this, true);
242 entry_break->SetBreakpointKind("shared-library-event");
243
244 // Shoudn't hit this more than once.
245 entry_break->SetOneShot(true);
246 }
247}
248
249// The runtime linker has run and initialized the rendezvous structure once the
250// process has hit its entry point. When we hit the corresponding breakpoint
251// we interrogate the rendezvous structure to get the load addresses of all
252// dependent modules for the process. Similarly, we can discover the runtime
253// linker function and setup a breakpoint to notify us of any dynamically
254// loaded modules (via dlopen).
256 void *baton, StoppointCallbackContext *context, user_id_t break_id,
257 user_id_t break_loc_id) {
258 assert(baton && "null baton");
259 if (!baton)
260 return false;
261
262 Log *log = GetLog(LLDBLog::DynamicLoader);
263 DynamicLoaderPOSIXDYLD *const dyld_instance =
264 static_cast<DynamicLoaderPOSIXDYLD *>(baton);
265 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
266 __FUNCTION__,
267 dyld_instance->m_process ? dyld_instance->m_process->GetID()
269
270 // Disable the breakpoint --- if a stop happens right after this, which we've
271 // seen on occasion, we don't want the breakpoint stepping thread-plan logic
272 // to show a breakpoint instruction at the disassembled entry point to the
273 // program. Disabling it prevents it. (One-shot is not enough - one-shot
274 // removal logic only happens after the breakpoint goes public, which wasn't
275 // happening in our scenario).
276 if (dyld_instance->m_process) {
277 BreakpointSP breakpoint_sp =
278 dyld_instance->m_process->GetTarget().GetBreakpointByID(break_id);
279 if (breakpoint_sp) {
280 LLDB_LOGF(log,
281 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
282 " disabling breakpoint id %" PRIu64,
283 __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
284 breakpoint_sp->SetEnabled(false);
285 } else {
286 LLDB_LOGF(log,
287 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
288 " failed to find breakpoint for breakpoint id %" PRIu64,
289 __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
290 }
291 } else {
292 LLDB_LOGF(log,
293 "DynamicLoaderPOSIXDYLD::%s breakpoint id %" PRIu64
294 " no Process instance! Cannot disable breakpoint",
295 __FUNCTION__, break_id);
296 }
297
298 dyld_instance->LoadAllCurrentModules();
299 dyld_instance->SetRendezvousBreakpoint();
300 return false; // Continue running.
301}
302
304 Log *log = GetLog(LLDBLog::DynamicLoader);
305
306 // If we have a core file, we don't need any breakpoints.
307 if (IsCoreFile())
308 return false;
309
311 LLDB_LOG(log,
312 "Rendezvous breakpoint breakpoint id {0} for pid {1}"
313 "is already set.",
316 return true;
317 }
318
319 addr_t break_addr;
320 Target &target = m_process->GetTarget();
321 BreakpointSP dyld_break;
323 break_addr = m_rendezvous.GetBreakAddress();
324 LLDB_LOG(log, "Setting rendezvous break address for pid {0} at {1:x}",
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 // Function names from different dynamic loaders that are known to be
333 // used as rendezvous between the loader and debuggers.
334 static std::vector<std::string> DebugStateCandidates{
335 "_dl_debug_state", "rtld_db_dlactivity", "__dl_rtld_db_dlactivity",
336 "r_debug_state", "_r_debug_state", "_rtld_debug_state",
337 };
338
339 ModuleSP interpreter = LoadInterpreterModule();
340 if (!interpreter) {
341 FileSpecList containingModules;
342 containingModules.Append(
344
345 dyld_break = target.CreateBreakpoint(
346 &containingModules, /*containingSourceFiles=*/nullptr,
347 DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC,
348 /*m_offset=*/0,
349 /*skip_prologue=*/eLazyBoolNo,
350 /*internal=*/true,
351 /*request_hardware=*/false);
352 } else {
353 FileSpecList containingModules;
354 containingModules.Append(interpreter->GetFileSpec());
355 dyld_break = target.CreateBreakpoint(
356 &containingModules, /*containingSourceFiles=*/nullptr,
357 DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC,
358 /*m_offset=*/0,
359 /*skip_prologue=*/eLazyBoolNo,
360 /*internal=*/true,
361 /*request_hardware=*/false);
362 }
363 }
364
365 if (dyld_break->GetNumResolvedLocations() != 1) {
366 LLDB_LOG(
367 log,
368 "Rendezvous breakpoint has abnormal number of"
369 " resolved locations ({0}) in pid {1}. It's supposed to be exactly 1.",
370 dyld_break->GetNumResolvedLocations(),
372
373 target.RemoveBreakpointByID(dyld_break->GetID());
374 return false;
375 }
376
377 BreakpointLocationSP location = dyld_break->GetLocationAtIndex(0);
378 LLDB_LOG(log,
379 "Successfully set rendezvous breakpoint at address {0:x} "
380 "for pid {1}",
381 location->GetLoadAddress(),
383
384 dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
385 dyld_break->SetBreakpointKind("shared-library-event");
386 m_dyld_bid = dyld_break->GetID();
387 return true;
388}
389
391 void *baton, StoppointCallbackContext *context, user_id_t break_id,
392 user_id_t break_loc_id) {
393 assert(baton && "null baton");
394 if (!baton)
395 return false;
396
397 Log *log = GetLog(LLDBLog::DynamicLoader);
398 DynamicLoaderPOSIXDYLD *const dyld_instance =
399 static_cast<DynamicLoaderPOSIXDYLD *>(baton);
400 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
401 __FUNCTION__,
402 dyld_instance->m_process ? dyld_instance->m_process->GetID()
404
405 dyld_instance->RefreshModules();
406
407 // Return true to stop the target, false to just let the target run.
408 const bool stop_when_images_change = dyld_instance->GetStopWhenImagesChange();
409 LLDB_LOGF(log,
410 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
411 " stop_when_images_change=%s",
412 __FUNCTION__,
413 dyld_instance->m_process ? dyld_instance->m_process->GetID()
415 stop_when_images_change ? "true" : "false");
416 return stop_when_images_change;
417}
418
420 if (!m_rendezvous.Resolve())
421 return;
422
425
426 ModuleList &loaded_modules = m_process->GetTarget().GetImages();
427
429 ModuleList new_modules;
430
431 // If this is the first time rendezvous breakpoint fires, we need
432 // to take care of adding all the initial modules reported by
433 // the loader. This is necessary to list ld-linux.so on Linux,
434 // and all DT_NEEDED entries on *BSD.
438 } else {
439 I = m_rendezvous.begin();
440 E = m_rendezvous.end();
442 }
443 for (; I != E; ++I) {
444 ModuleSP module_sp =
445 LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
446 if (!module_sp.get())
447 continue;
448
449 if (module_sp->GetObjectFile()->GetBaseAddress().GetLoadAddress(
451 ModuleSP interpreter_sp = m_interpreter_module.lock();
452 if (m_interpreter_module.lock() == nullptr) {
453 m_interpreter_module = module_sp;
454 } else if (module_sp == interpreter_sp) {
455 // Module already loaded.
456 continue;
457 } else {
458 // If this is a duplicate instance of ld.so, unload it. We may end
459 // up with it if we load it via a different path than before
460 // (symlink vs real path).
461 // TODO: remove this once we either fix library matching or avoid
462 // loading the interpreter when setting the rendezvous breakpoint.
463 UnloadSections(module_sp);
464 loaded_modules.Remove(module_sp);
465 continue;
466 }
467 }
468
469 loaded_modules.AppendIfNeeded(module_sp);
470 new_modules.Append(module_sp);
471 }
472 m_process->GetTarget().ModulesDidLoad(new_modules);
473 }
474
476 ModuleList old_modules;
477
479 for (I = m_rendezvous.unloaded_begin(); I != E; ++I) {
480 ModuleSpec module_spec{I->file_spec};
481 ModuleSP module_sp = loaded_modules.FindFirstModule(module_spec);
482
483 if (module_sp.get()) {
484 old_modules.Append(module_sp);
485 UnloadSections(module_sp);
486 }
487 }
488 loaded_modules.Remove(old_modules);
489 m_process->GetTarget().ModulesDidUnload(old_modules, false);
490 }
491}
492
495 bool stop) {
496 ThreadPlanSP thread_plan_sp;
497
498 StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
499 const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
500 Symbol *sym = context.symbol;
501
502 if (sym == nullptr || !sym->IsTrampoline())
503 return thread_plan_sp;
504
506 if (!sym_name)
507 return thread_plan_sp;
508
509 SymbolContextList target_symbols;
510 Target &target = thread.GetProcess()->GetTarget();
511 const ModuleList &images = target.GetImages();
512
513 images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
514 if (!target_symbols.GetSize())
515 return thread_plan_sp;
516
517 typedef std::vector<lldb::addr_t> AddressVector;
518 AddressVector addrs;
519 for (const SymbolContext &context : target_symbols) {
520 AddressRange range;
521 context.GetAddressRange(eSymbolContextEverything, 0, false, range);
522 lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target);
523 if (addr != LLDB_INVALID_ADDRESS)
524 addrs.push_back(addr);
525 }
526
527 if (addrs.size() > 0) {
528 AddressVector::iterator start = addrs.begin();
529 AddressVector::iterator end = addrs.end();
530
531 llvm::sort(start, end);
532 addrs.erase(std::unique(start, end), end);
533 thread_plan_sp =
534 std::make_shared<ThreadPlanRunToAddress>(thread, addrs, stop);
535 }
536
537 return thread_plan_sp;
538}
539
542 return;
543
544 FileSpec file("[vdso]");
545
546 MemoryRegionInfo info;
548 if (status.Fail()) {
549 Log *log = GetLog(LLDBLog::DynamicLoader);
550 LLDB_LOG(log, "Failed to get vdso region info: {0}", status);
551 return;
552 }
553
554 if (ModuleSP module_sp = m_process->ReadModuleFromMemory(
555 file, m_vdso_base, info.GetRange().GetByteSize())) {
558 }
559}
560
563 return nullptr;
564
565 MemoryRegionInfo info;
566 Target &target = m_process->GetTarget();
568 if (status.Fail() || info.GetMapped() != MemoryRegionInfo::eYes ||
569 info.GetName().IsEmpty()) {
570 Log *log = GetLog(LLDBLog::DynamicLoader);
571 LLDB_LOG(log, "Failed to get interpreter region info: {0}", status);
572 return nullptr;
573 }
574
575 FileSpec file(info.GetName().GetCString());
576 ModuleSpec module_spec(file, target.GetArchitecture());
577
578 if (ModuleSP module_sp = target.GetOrCreateModule(module_spec,
579 true /* notify */)) {
581 false);
582 m_interpreter_module = module_sp;
583 return module_sp;
584 }
585 return nullptr;
586}
587
589 addr_t link_map_addr,
590 addr_t base_addr,
591 bool base_addr_is_offset) {
593 file, link_map_addr, base_addr, base_addr_is_offset))
594 return module_sp;
595
596 // This works around an dynamic linker "bug" on android <= 23, where the
597 // dynamic linker would report the application name
598 // (e.g. com.example.myapplication) instead of the main process binary
599 // (/system/bin/app_process(32)). The logic is not sound in general (it
600 // assumes base_addr is the real address, even though it actually is a load
601 // bias), but it happens to work on android because app_process has a file
602 // address of zero.
603 // This should be removed after we drop support for android-23.
604 if (m_process->GetTarget().GetArchitecture().GetTriple().isAndroid()) {
605 MemoryRegionInfo memory_info;
606 Status error = m_process->GetMemoryRegionInfo(base_addr, memory_info);
607 if (error.Success() && memory_info.GetMapped() &&
608 memory_info.GetRange().GetRangeBase() == base_addr &&
609 !(memory_info.GetName().IsEmpty())) {
611 FileSpec(memory_info.GetName().GetStringRef()), link_map_addr,
612 base_addr, base_addr_is_offset))
613 return module_sp;
614 }
615 }
616
617 return nullptr;
618}
619
623 ModuleList module_list;
624 Log *log = GetLog(LLDBLog::DynamicLoader);
625
626 LoadVDSO();
627
628 if (!m_rendezvous.Resolve()) {
629 LLDB_LOGF(log,
630 "DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD "
631 "rendezvous address",
632 __FUNCTION__);
633 return;
634 }
635
636 // The rendezvous class doesn't enumerate the main module, so track that
637 // ourselves here.
638 ModuleSP executable = GetTargetExecutable();
640
641 std::vector<FileSpec> module_names;
642 for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
643 module_names.push_back(I->file_spec);
645 module_names, m_process->GetTarget().GetArchitecture().GetTriple());
646
647 for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) {
648 ModuleSP module_sp =
649 LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
650 if (module_sp.get()) {
651 LLDB_LOG(log, "LoadAllCurrentModules loading module: {0}",
652 I->file_spec.GetFilename());
653 module_list.Append(module_sp);
654 } else {
655 Log *log = GetLog(LLDBLog::DynamicLoader);
656 LLDB_LOGF(
657 log,
658 "DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64,
659 __FUNCTION__, I->file_spec.GetPath().c_str(), I->base_addr);
660 }
661 }
662
663 m_process->GetTarget().ModulesDidLoad(module_list);
665}
666
668 addr_t virt_entry;
669
671 return m_load_offset;
672
673 if ((virt_entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS)
675
677 if (!module)
679
680 ObjectFile *exe = module->GetObjectFile();
681 if (!exe)
683
684 Address file_entry = exe->GetEntryPointAddress();
685
686 if (!file_entry.IsValid())
688
689 m_load_offset = virt_entry - file_entry.GetFileAddress();
690 return m_load_offset;
691}
692
694 if (std::optional<uint64_t> vdso_base =
696 m_vdso_base = *vdso_base;
697
698 if (std::optional<uint64_t> interpreter_base =
699 m_auxv->GetAuxValue(AuxVector::AUXV_AT_BASE))
700 m_interpreter_base = *interpreter_base;
701}
702
705 return m_entry_point;
706
707 if (m_auxv == nullptr)
709
710 std::optional<uint64_t> entry_point =
711 m_auxv->GetAuxValue(AuxVector::AUXV_AT_ENTRY);
712 if (!entry_point)
714
715 m_entry_point = static_cast<addr_t>(*entry_point);
716
717 const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
718
719 // On ppc64, the entry point is actually a descriptor. Dereference it.
720 if (arch.GetMachine() == llvm::Triple::ppc64)
722
723 return m_entry_point;
724}
725
728 const lldb::ThreadSP thread,
729 lldb::addr_t tls_file_addr) {
730 auto it = m_loaded_modules.find(module_sp);
731 if (it == m_loaded_modules.end())
733
734 addr_t link_map = it->second;
735 if (link_map == LLDB_INVALID_ADDRESS)
737
739 if (!metadata.valid)
741
742 // Get the thread pointer.
743 addr_t tp = thread->GetThreadPointer();
744 if (tp == LLDB_INVALID_ADDRESS)
746
747 // Find the module's modid.
748 int modid_size = 4; // FIXME(spucci): This isn't right for big-endian 64-bit
749 int64_t modid = ReadUnsignedIntWithSizeInBytes(
750 link_map + metadata.modid_offset, modid_size);
751 if (modid == -1)
753
754 // Lookup the DTV structure for this thread.
755 addr_t dtv_ptr = tp + metadata.dtv_offset;
756 addr_t dtv = ReadPointer(dtv_ptr);
757 if (dtv == LLDB_INVALID_ADDRESS)
759
760 // Find the TLS block for this module.
761 addr_t dtv_slot = dtv + metadata.dtv_slot_size * modid;
762 addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset);
763
764 Log *log = GetLog(LLDBLog::DynamicLoader);
765 LLDB_LOGF(log,
766 "DynamicLoaderPOSIXDYLD::Performed TLS lookup: "
767 "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
768 ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n",
769 module_sp->GetObjectName().AsCString(""), link_map, tp,
770 (int64_t)modid, tls_block);
771
772 if (tls_block == LLDB_INVALID_ADDRESS)
774 else
775 return tls_block + tls_file_addr;
776}
777
779 lldb::ModuleSP &module_sp) {
780 Log *log = GetLog(LLDBLog::DynamicLoader);
781
782 if (m_process == nullptr)
783 return;
784
785 auto &target = m_process->GetTarget();
786 const auto platform_sp = target.GetPlatform();
787
788 ProcessInstanceInfo process_info;
789 if (!m_process->GetProcessInfo(process_info)) {
790 LLDB_LOGF(log,
791 "DynamicLoaderPOSIXDYLD::%s - failed to get process info for "
792 "pid %" PRIu64,
793 __FUNCTION__, m_process->GetID());
794 return;
795 }
796
797 LLDB_LOGF(
798 log, "DynamicLoaderPOSIXDYLD::%s - got executable by pid %" PRIu64 ": %s",
799 __FUNCTION__, m_process->GetID(),
800 process_info.GetExecutableFile().GetPath().c_str());
801
802 ModuleSpec module_spec(process_info.GetExecutableFile(),
803 process_info.GetArchitecture());
804 if (module_sp && module_sp->MatchesModuleSpec(module_spec))
805 return;
806
807 const auto executable_search_paths(Target::GetDefaultExecutableSearchPaths());
808 auto error = platform_sp->ResolveExecutable(
809 module_spec, module_sp,
810 !executable_search_paths.IsEmpty() ? &executable_search_paths : nullptr);
811 if (error.Fail()) {
812 StreamString stream;
813 module_spec.Dump(stream);
814
815 LLDB_LOGF(log,
816 "DynamicLoaderPOSIXDYLD::%s - failed to resolve executable "
817 "with module spec \"%s\": %s",
818 __FUNCTION__, stream.GetData(), error.AsCString());
819 return;
820 }
821
822 target.SetExecutableModule(module_sp, eLoadDependentsNo);
823}
824
827 ModuleSP module_sp;
828 if (sym_ctx.symbol)
829 module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
830 if (!module_sp && sym_ctx.function)
831 module_sp =
833 if (!module_sp)
834 return false;
835
836 return module_sp->GetFileSpec().GetPath() == "[vdso]";
837}
838
840 return !m_process->IsLiveDebugSession();
841}
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition: Log.h:342
#define LLDB_LOGF(log,...)
Definition: Log.h:349
#define LLDB_PLUGIN_DEFINE_ADV(ClassName, PluginName)
Definition: PluginManager.h:25
@ AUXV_AT_SYSINFO_EHDR
Definition: AuxVector.h:58
@ AUXV_AT_ENTRY
Program entry point.
Definition: AuxVector.h:36
@ AUXV_AT_BASE
Interpreter base address.
Definition: AuxVector.h:34
bool ModulesDidUnload() const
bool ModulesDidLoad() const
lldb::addr_t GetBreakAddress() const
A breakpoint should be set at this address and Resolve called on each hit.
void UpdateExecutablePath()
Update the cached executable path.
iterator loaded_begin() const
Iterators over all modules loaded into the inferior since the last call to Resolve().
lldb::addr_t GetLinkMapAddress() const
bool Resolve()
Update the internal snapshot of runtime linker rendezvous and recompute the currently loaded modules.
iterator unloaded_begin() const
Iterators over all modules unloaded from the inferior since the last call to Resolve().
iterator begin() const
Iterators over all currently loaded modules.
iterator unloaded_end() const
const ThreadInfo & GetThreadInfo()
iterator loaded_end() const
SOEntryList::const_iterator iterator
iterator end() const
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...
std::map< lldb::ModuleWP, lldb::addr_t, std::owner_less< lldb::ModuleWP > > m_loaded_modules
Loaded module list. (link map for each module)
static lldb_private::DynamicLoader * CreateInstance(lldb_private::Process *process, bool force)
bool m_initial_modules_added
Indicates whether the initial set of modules was reported added.
lldb::addr_t m_load_offset
Virtual load address of the inferior process.
lldb::break_id_t m_dyld_bid
Rendezvous breakpoint.
lldb::addr_t GetEntryPoint()
Computes a value for m_entry_point returning the computed address on success and LLDB_INVALID_ADDRESS...
std::unique_ptr< AuxVector > m_auxv
Auxiliary vector of the inferior process.
static llvm::StringRef GetPluginDescriptionStatic()
void EvalSpecialModulesStatus()
Evaluate if Aux vectors contain vDSO and LD information in case they do, read and assign the address ...
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::ModuleSP LoadInterpreterModule()
void RefreshModules()
Helper method for RendezvousBreakpointHit.
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's the fi...
lldb::addr_t m_interpreter_base
Contains AT_BASE, which means a dynamic loader has been mapped to the address space.
void ProbeEntry()
Resolves the entry point for the current inferior process and sets a breakpoint at that address.
lldb_private::Status CanLoadImage() override
Ask if it is ok to try and load or unload an shared library (image).
lldb::addr_t m_vdso_base
Contains AT_SYSINFO_EHDR, which means a vDSO has been mapped to the address space.
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...
void UnloadSections(const lldb::ModuleSP module) override
Removes the loaded sections from the target in module.
DYLDRendezvous m_rendezvous
Runtime linker rendezvous structure.
void DidLaunch() override
Called after launching a process.
lldb::ModuleSP LoadModuleAtAddress(const lldb_private::FileSpec &file, lldb::addr_t link_map_addr, lldb::addr_t base_addr, bool base_addr_is_offset) override
Locates or creates a module given by file and updates/loads the resulting module at the virtual base ...
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.
void DidAttach() override
Called after attaching a process.
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.
void ResolveExecutableModule(lldb::ModuleSP &module_sp)
Loads Module from inferior process.
lldb::addr_t m_entry_point
Virtual entry address of the inferior process.
virtual void LoadAllCurrentModules()
Helper for the entry breakpoint callback.
std::weak_ptr< lldb_private::Module > m_interpreter_module
Contains the pointer to the interpret module, if loaded.
bool IsCoreFile() const
Returns true if the process is for a core file.
DynamicLoaderPOSIXDYLD(lldb_private::Process *process)
A section + offset based address range class.
Definition: AddressRange.h:25
Address & GetBaseAddress()
Get accessor for the base address of the range.
Definition: AddressRange.h:209
A section + offset based address class.
Definition: Address.h:59
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition: Address.cpp:311
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
Definition: Address.cpp:283
lldb::addr_t GetFileAddress() const
Get the file address.
Definition: Address.cpp:291
bool IsValid() const
Check if the object state is valid.
Definition: Address.h:345
An architecture specification class.
Definition: ArchSpec.h:31
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:450
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition: ArchSpec.cpp:683
General Outline: A breakpoint has four main parts, a filter, a resolver, the list of breakpoint locat...
Definition: Breakpoint.h:81
void SetOneShot(bool one_shot)
If one_shot is true, breakpoint will be deleted on first hit.
Definition: Breakpoint.cpp:333
void SetBreakpointKind(const char *kind)
Set the "kind" description for a breakpoint.
Definition: Breakpoint.h:452
void SetCallback(BreakpointHitCallback callback, void *baton, bool is_synchronous=false)
Set the callback action invoked when the breakpoint is hit.
Definition: Breakpoint.cpp:413
A uniqued constant string class.
Definition: ConstString.h:40
bool IsEmpty() const
Test for empty string.
Definition: ConstString.h:293
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:191
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:205
A plug-in interface definition class for dynamic loaders.
Definition: DynamicLoader.h:52
int64_t ReadUnsignedIntWithSizeInBytes(lldb::addr_t addr, int size_in_bytes)
lldb::addr_t ReadPointer(lldb::addr_t addr)
Process * m_process
The process that this dynamic loader plug-in is tracking.
void UpdateLoadedSectionsCommon(lldb::ModuleSP module, lldb::addr_t base_addr, bool base_addr_is_offset)
lldb::ModuleSP GetTargetExecutable()
Checks to see if the target module has changed, updates the target accordingly and returns the target...
bool GetStopWhenImagesChange() const
Get whether the process should stop when images change.
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 ...
void UnloadSectionsCommon(const lldb::ModuleSP module)
A file collection class.
Definition: FileSpecList.h:24
void Append(const FileSpec &file)
Append a FileSpec object to the list.
A file utility class.
Definition: FileSpec.h:56
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:367
const AddressRange & GetAddressRange()
Definition: Function.h:447
ConstString GetName(NamePreference preference=ePreferDemangled) const
Best name get accessor.
Definition: Mangled.cpp:323
OptionalBool GetMapped() const
A collection class for Module objects.
Definition: ModuleList.h:82
lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const
Definition: ModuleList.cpp:614
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
Definition: ModuleList.cpp:253
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
Definition: ModuleList.cpp:500
bool Remove(const lldb::ModuleSP &module_sp, bool notify=true)
Remove a module from the module list.
Definition: ModuleList.cpp:307
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
Definition: ModuleList.cpp:220
ModuleIterable Modules() const
Definition: ModuleList.h:510
void Dump(Stream &strm) const
Definition: ModuleSpec.h:162
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
Definition: Module.h:497
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:44
virtual lldb_private::Address GetImageInfoAddress(Target *target)
Similar to Process::GetImageInfoAddress().
Definition: ObjectFile.h:459
virtual lldb_private::Address GetEntryPointAddress()
Returns the address of the Entry Point in this object file - if the object file doesn't have an entry...
Definition: ObjectFile.h:469
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
FileSpec & GetExecutableFile()
Definition: ProcessInfo.h:42
ArchSpec & GetArchitecture()
Definition: ProcessInfo.h:61
A plug-in interface definition class for debugging a process.
Definition: Process.h:336
lldb::pid_t GetID() const
Returns the pid of the process or LLDB_INVALID_PROCESS_ID if there is no known pid.
Definition: Process.h:535
virtual DataExtractor GetAuxvData()
Definition: Process.cpp:2687
virtual void PrefetchModuleSpecs(llvm::ArrayRef< FileSpec > module_file_specs, const llvm::Triple &triple)
Definition: Process.h:2479
virtual bool GetProcessInfo(ProcessInstanceInfo &info)
Definition: Process.cpp:5864
virtual bool IsLiveDebugSession() const
Definition: Process.h:1470
Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info)
Locate the memory region that contains load_addr.
Definition: Process.cpp:5971
lldb::ModuleSP ReadModuleFromMemory(const FileSpec &file_spec, lldb::addr_t header_addr, size_t size_to_read=512)
Definition: Process.cpp:2375
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1242
This base class provides an interface to stack frames.
Definition: StackFrame.h:41
const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
Definition: StackFrame.cpp:300
An error handling class.
Definition: Status.h:44
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
General Outline: When we hit a breakpoint we need to package up whatever information is needed to eva...
const char * GetData() const
Definition: StreamString.h:43
Defines a list of symbol context objects.
uint32_t GetSize() const
Get accessor for a symbol context list size.
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
Function * function
The Function for a given query.
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.
Symbol * symbol
The Symbol for a given query.
Mangled & GetMangled()
Definition: Symbol.h:145
bool IsTrampoline() const
Definition: Symbol.cpp:223
Address & GetAddressRef()
Definition: Symbol.h:71
void ModulesDidLoad(ModuleList &module_list)
Definition: Target.cpp:1649
Module * GetExecutableModulePointer()
Definition: Target.cpp:1389
lldb::BreakpointSP GetBreakpointByID(lldb::break_id_t break_id)
Definition: Target.cpp:327
bool RemoveBreakpointByID(lldb::break_id_t break_id)
Definition: Target.cpp:957
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:2114
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
Definition: Target.cpp:1375
void ModulesDidUnload(ModuleList &module_list, bool delete_locations)
Definition: Target.cpp:1681
static FileSpecList GetDefaultExecutableSearchPaths()
Definition: Target.cpp:2557
lldb::PlatformSP GetPlatform()
Definition: Target.h:1428
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:355
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:967
const ArchSpec & GetArchitecture() const
Definition: Target.h:1009
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
Definition: Thread.h:397
lldb::ProcessSP GetProcess() const
Definition: Thread.h:153
#define LLDB_INVALID_BREAK_ID
Definition: lldb-defines.h:37
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:76
#define LLDB_INVALID_PROCESS_ID
Definition: lldb-defines.h:83
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:314
Definition: SBAddress.h:15
std::shared_ptr< lldb_private::ThreadPlan > ThreadPlanSP
Definition: lldb-forward.h:428
std::shared_ptr< lldb_private::BreakpointLocation > BreakpointLocationSP
Definition: lldb-forward.h:306
std::shared_ptr< lldb_private::Thread > ThreadSP
Definition: lldb-forward.h:425
@ eLanguageTypeC
Non-standardized C, such as K&R.
std::shared_ptr< lldb_private::Breakpoint > BreakpointSP
Definition: lldb-forward.h:303
uint64_t user_id_t
Definition: lldb-types.h:80
uint64_t addr_t
Definition: lldb-types.h:79
std::shared_ptr< lldb_private::Module > ModuleSP
Definition: lldb-forward.h:354
BaseType GetRangeBase() const
Definition: RangeMap.h:45
SizeType GetByteSize() const
Definition: RangeMap.h:87