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
208void DynamicLoaderPOSIXDYLD::UnloadSections(const ModuleSP module) {
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
493ThreadPlanSP
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
505 ConstString sym_name = sym->GetMangled().GetName(Mangled::ePreferMangled);
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 size_t num_targets = target_symbols.GetSize();
515 if (!num_targets)
516 return thread_plan_sp;
517
518 typedef std::vector<lldb::addr_t> AddressVector;
519 AddressVector addrs;
520 for (size_t i = 0; i < num_targets; ++i) {
521 SymbolContext context;
522 AddressRange range;
523 if (target_symbols.GetContextAtIndex(i, context)) {
524 context.GetAddressRange(eSymbolContextEverything, 0, false, range);
525 lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target);
526 if (addr != LLDB_INVALID_ADDRESS)
527 addrs.push_back(addr);
528 }
529 }
530
531 if (addrs.size() > 0) {
532 AddressVector::iterator start = addrs.begin();
533 AddressVector::iterator end = addrs.end();
534
535 llvm::sort(start, end);
536 addrs.erase(std::unique(start, end), end);
537 thread_plan_sp =
538 std::make_shared<ThreadPlanRunToAddress>(thread, addrs, stop);
539 }
540
541 return thread_plan_sp;
542}
543
546 return;
547
548 FileSpec file("[vdso]");
549
550 MemoryRegionInfo info;
552 if (status.Fail()) {
553 Log *log = GetLog(LLDBLog::DynamicLoader);
554 LLDB_LOG(log, "Failed to get vdso region info: {0}", status);
555 return;
556 }
557
558 if (ModuleSP module_sp = m_process->ReadModuleFromMemory(
559 file, m_vdso_base, info.GetRange().GetByteSize())) {
562 }
563}
564
567 return nullptr;
568
569 MemoryRegionInfo info;
570 Target &target = m_process->GetTarget();
572 if (status.Fail() || info.GetMapped() != MemoryRegionInfo::eYes ||
573 info.GetName().IsEmpty()) {
574 Log *log = GetLog(LLDBLog::DynamicLoader);
575 LLDB_LOG(log, "Failed to get interpreter region info: {0}", status);
576 return nullptr;
577 }
578
579 FileSpec file(info.GetName().GetCString());
580 ModuleSpec module_spec(file, target.GetArchitecture());
581
582 if (ModuleSP module_sp = target.GetOrCreateModule(module_spec,
583 true /* notify */)) {
585 false);
586 m_interpreter_module = module_sp;
587 return module_sp;
588 }
589 return nullptr;
590}
591
593 addr_t link_map_addr,
594 addr_t base_addr,
595 bool base_addr_is_offset) {
596 if (ModuleSP module_sp = DynamicLoader::LoadModuleAtAddress(
597 file, link_map_addr, base_addr, base_addr_is_offset))
598 return module_sp;
599
600 // This works around an dynamic linker "bug" on android <= 23, where the
601 // dynamic linker would report the application name
602 // (e.g. com.example.myapplication) instead of the main process binary
603 // (/system/bin/app_process(32)). The logic is not sound in general (it
604 // assumes base_addr is the real address, even though it actually is a load
605 // bias), but it happens to work on android because app_process has a file
606 // address of zero.
607 // This should be removed after we drop support for android-23.
608 if (m_process->GetTarget().GetArchitecture().GetTriple().isAndroid()) {
609 MemoryRegionInfo memory_info;
610 Status error = m_process->GetMemoryRegionInfo(base_addr, memory_info);
611 if (error.Success() && memory_info.GetMapped() &&
612 memory_info.GetRange().GetRangeBase() == base_addr &&
613 !(memory_info.GetName().IsEmpty())) {
614 if (ModuleSP module_sp = DynamicLoader::LoadModuleAtAddress(
615 FileSpec(memory_info.GetName().GetStringRef()), link_map_addr,
616 base_addr, base_addr_is_offset))
617 return module_sp;
618 }
619 }
620
621 return nullptr;
622}
623
627 ModuleList module_list;
628 Log *log = GetLog(LLDBLog::DynamicLoader);
629
630 LoadVDSO();
631
632 if (!m_rendezvous.Resolve()) {
633 LLDB_LOGF(log,
634 "DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD "
635 "rendezvous address",
636 __FUNCTION__);
637 return;
638 }
639
640 // The rendezvous class doesn't enumerate the main module, so track that
641 // ourselves here.
642 ModuleSP executable = GetTargetExecutable();
644
645 std::vector<FileSpec> module_names;
646 for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
647 module_names.push_back(I->file_spec);
649 module_names, m_process->GetTarget().GetArchitecture().GetTriple());
650
651 for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) {
652 ModuleSP module_sp =
653 LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
654 if (module_sp.get()) {
655 LLDB_LOG(log, "LoadAllCurrentModules loading module: {0}",
656 I->file_spec.GetFilename());
657 module_list.Append(module_sp);
658 } else {
659 Log *log = GetLog(LLDBLog::DynamicLoader);
660 LLDB_LOGF(
661 log,
662 "DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64,
663 __FUNCTION__, I->file_spec.GetPath().c_str(), I->base_addr);
664 }
665 }
666
667 m_process->GetTarget().ModulesDidLoad(module_list);
669}
670
672 addr_t virt_entry;
673
675 return m_load_offset;
676
677 if ((virt_entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS)
679
680 ModuleSP module = m_process->GetTarget().GetExecutableModule();
681 if (!module)
683
684 ObjectFile *exe = module->GetObjectFile();
685 if (!exe)
687
688 Address file_entry = exe->GetEntryPointAddress();
689
690 if (!file_entry.IsValid())
692
693 m_load_offset = virt_entry - file_entry.GetFileAddress();
694 return m_load_offset;
695}
696
698 if (std::optional<uint64_t> vdso_base =
700 m_vdso_base = *vdso_base;
701
702 if (std::optional<uint64_t> interpreter_base =
703 m_auxv->GetAuxValue(AuxVector::AUXV_AT_BASE))
704 m_interpreter_base = *interpreter_base;
705}
706
709 return m_entry_point;
710
711 if (m_auxv == nullptr)
713
714 std::optional<uint64_t> entry_point =
715 m_auxv->GetAuxValue(AuxVector::AUXV_AT_ENTRY);
716 if (!entry_point)
718
719 m_entry_point = static_cast<addr_t>(*entry_point);
720
721 const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
722
723 // On ppc64, the entry point is actually a descriptor. Dereference it.
724 if (arch.GetMachine() == llvm::Triple::ppc64)
726
727 return m_entry_point;
728}
729
731DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp,
732 const lldb::ThreadSP thread,
733 lldb::addr_t tls_file_addr) {
734 auto it = m_loaded_modules.find(module_sp);
735 if (it == m_loaded_modules.end())
737
738 addr_t link_map = it->second;
739 if (link_map == LLDB_INVALID_ADDRESS)
741
743 if (!metadata.valid)
745
746 // Get the thread pointer.
747 addr_t tp = thread->GetThreadPointer();
748 if (tp == LLDB_INVALID_ADDRESS)
750
751 // Find the module's modid.
752 int modid_size = 4; // FIXME(spucci): This isn't right for big-endian 64-bit
753 int64_t modid = ReadUnsignedIntWithSizeInBytes(
754 link_map + metadata.modid_offset, modid_size);
755 if (modid == -1)
757
758 // Lookup the DTV structure for this thread.
759 addr_t dtv_ptr = tp + metadata.dtv_offset;
760 addr_t dtv = ReadPointer(dtv_ptr);
761 if (dtv == LLDB_INVALID_ADDRESS)
763
764 // Find the TLS block for this module.
765 addr_t dtv_slot = dtv + metadata.dtv_slot_size * modid;
766 addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset);
767
768 Log *log = GetLog(LLDBLog::DynamicLoader);
769 LLDB_LOGF(log,
770 "DynamicLoaderPOSIXDYLD::Performed TLS lookup: "
771 "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
772 ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n",
773 module_sp->GetObjectName().AsCString(""), link_map, tp,
774 (int64_t)modid, tls_block);
775
776 if (tls_block == LLDB_INVALID_ADDRESS)
778 else
779 return tls_block + tls_file_addr;
780}
781
783 lldb::ModuleSP &module_sp) {
784 Log *log = GetLog(LLDBLog::DynamicLoader);
785
786 if (m_process == nullptr)
787 return;
788
789 auto &target = m_process->GetTarget();
790 const auto platform_sp = target.GetPlatform();
791
792 ProcessInstanceInfo process_info;
793 if (!m_process->GetProcessInfo(process_info)) {
794 LLDB_LOGF(log,
795 "DynamicLoaderPOSIXDYLD::%s - failed to get process info for "
796 "pid %" PRIu64,
797 __FUNCTION__, m_process->GetID());
798 return;
799 }
800
801 LLDB_LOGF(
802 log, "DynamicLoaderPOSIXDYLD::%s - got executable by pid %" PRIu64 ": %s",
803 __FUNCTION__, m_process->GetID(),
804 process_info.GetExecutableFile().GetPath().c_str());
805
806 ModuleSpec module_spec(process_info.GetExecutableFile(),
807 process_info.GetArchitecture());
808 if (module_sp && module_sp->MatchesModuleSpec(module_spec))
809 return;
810
811 const auto executable_search_paths(Target::GetDefaultExecutableSearchPaths());
812 auto error = platform_sp->ResolveExecutable(
813 module_spec, module_sp,
814 !executable_search_paths.IsEmpty() ? &executable_search_paths : nullptr);
815 if (error.Fail()) {
816 StreamString stream;
817 module_spec.Dump(stream);
818
819 LLDB_LOGF(log,
820 "DynamicLoaderPOSIXDYLD::%s - failed to resolve executable "
821 "with module spec \"%s\": %s",
822 __FUNCTION__, stream.GetData(), error.AsCString());
823 return;
824 }
825
826 target.SetExecutableModule(module_sp, eLoadDependentsNo);
827}
828
831 ModuleSP module_sp;
832 if (sym_ctx.symbol)
833 module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
834 if (!module_sp && sym_ctx.function)
835 module_sp =
837 if (!module_sp)
838 return false;
839
840 return module_sp->GetFileSpec().GetPath() == "[vdso]";
841}
842
844 return !m_process->IsLiveDebugSession();
845}
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:337
#define LLDB_LOGF(log,...)
Definition: Log.h:344
#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:32
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:463
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition: ArchSpec.cpp:678
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:338
void SetBreakpointKind(const char *kind)
Set the "kind" description for a breakpoint.
Definition: Breakpoint.h:453
void SetCallback(BreakpointHitCallback callback, void *baton, bool is_synchronous=false)
Set the callback action invoked when the breakpoint is hit.
Definition: Breakpoint.cpp:418
A uniqued constant string class.
Definition: ConstString.h:39
bool IsEmpty() const
Test for empty string.
Definition: ConstString.h:303
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:201
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:215
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 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:366
const AddressRange & GetAddressRange()
Definition: Function.h:457
OptionalBool GetMapped() const
A collection class for Module objects.
Definition: ModuleList.h:82
lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const
Definition: ModuleList.cpp:623
bool Remove(const lldb::ModuleSP &module_sp, bool notify=true)
Remove a module from the module list.
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
Definition: ModuleList.cpp:509
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
ModuleIterable Modules() const
Definition: ModuleList.h:507
void Dump(Stream &strm) const
Definition: ModuleSpec.h:162
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
Definition: Module.h:498
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:62
virtual lldb_private::Address GetImageInfoAddress(Target *target)
Similar to Process::GetImageInfoAddress().
Definition: ObjectFile.h:477
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:487
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
FileSpec & GetExecutableFile()
Definition: ProcessInfo.h:41
ArchSpec & GetArchitecture()
Definition: ProcessInfo.h:60
A plug-in interface definition class for debugging a process.
Definition: Process.h:342
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:526
virtual DataExtractor GetAuxvData()
Definition: Process.cpp:2664
virtual void PrefetchModuleSpecs(llvm::ArrayRef< FileSpec > module_file_specs, const llvm::Triple &triple)
Definition: Process.h:2413
virtual bool GetProcessInfo(ProcessInstanceInfo &info)
Definition: Process.cpp:5770
virtual bool IsLiveDebugSession() const
Definition: Process.h:1425
Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info)
Locate the memory region that contains load_addr.
Definition: Process.cpp:5877
lldb::ModuleSP ReadModuleFromMemory(const FileSpec &file_spec, lldb::addr_t header_addr, size_t size_to_read=512)
Definition: Process.cpp:2358
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1219
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.
bool GetContextAtIndex(size_t idx, SymbolContext &sc) const
Get accessor for a symbol context at index idx.
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:131
bool IsTrampoline() const
Definition: Symbol.cpp:173
Address & GetAddressRef()
Definition: Symbol.h:57
void ModulesDidLoad(ModuleList &module_list)
Definition: Target.cpp:1646
Module * GetExecutableModulePointer()
Definition: Target.cpp:1386
lldb::BreakpointSP GetBreakpointByID(lldb::break_id_t break_id)
Definition: Target.cpp:324
bool RemoveBreakpointByID(lldb::break_id_t break_id)
Definition: Target.cpp:954
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:2111
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
Definition: Target.cpp:1372
void ModulesDidUnload(ModuleList &module_list, bool delete_locations)
Definition: Target.cpp:1678
static FileSpecList GetDefaultExecutableSearchPaths()
Definition: Target.cpp:2511
lldb::PlatformSP GetPlatform()
Definition: Target.h:1403
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:352
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:946
const ArchSpec & GetArchitecture() const
Definition: Target.h:988
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
Definition: Thread.h:399
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:74
#define LLDB_INVALID_PROCESS_ID
Definition: lldb-defines.h:81
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:309
Definition: SBAddress.h:15
@ eLanguageTypeC
Non-standardized C, such as K&R.
uint64_t user_id_t
Definition: lldb-types.h:84
uint64_t addr_t
Definition: lldb-types.h:83
BaseType GetRangeBase() const
Definition: RangeMap.h:46
SizeType GetByteSize() const
Definition: RangeMap.h:87