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/Debugger.h"
14#include "lldb/Core/Module.h"
17#include "lldb/Core/Section.h"
23#include "lldb/Target/Target.h"
24#include "lldb/Target/Thread.h"
27#include "lldb/Utility/Log.h"
29#include "llvm/Support/ThreadPool.h"
30
31#include <memory>
32#include <optional>
33
34using namespace lldb;
35using namespace lldb_private;
36
38
43
45
47 return "Dynamic loader plug-in that watches for shared library "
48 "loads/unloads in POSIX processes.";
49}
50
52 bool force) {
53 bool create = force;
54 if (!create) {
55 const llvm::Triple &triple_ref =
56 process->GetTarget().GetArchitecture().GetTriple();
57 if (triple_ref.getOS() == llvm::Triple::FreeBSD ||
58 triple_ref.getOS() == llvm::Triple::Linux ||
59 triple_ref.getOS() == llvm::Triple::NetBSD ||
60 triple_ref.getOS() == llvm::Triple::OpenBSD)
61 create = true;
62 }
63
64 if (create)
65 return new DynamicLoaderPOSIXDYLD(process);
66 return nullptr;
67}
68
76
83
86 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64, __FUNCTION__,
88 m_auxv = std::make_unique<AuxVector>(m_process->GetAuxvData());
89
91 log, "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reloaded auxv data",
92 __FUNCTION__, m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
93
94 ModuleSP executable_sp = GetTargetExecutable();
95 ResolveExecutableModule(executable_sp);
96 m_rendezvous.UpdateExecutablePath();
97
98 // find the main process load offset
99 addr_t load_offset = ComputeLoadOffset();
100 LLDB_LOGF(log,
101 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
102 " executable '%s', load_offset 0x%" PRIx64,
103 __FUNCTION__,
105 executable_sp ? executable_sp->GetFileSpec().GetPath().c_str()
106 : "<null executable>",
107 load_offset);
108
110
111 // if we dont have a load address we cant re-base
112 bool rebase_exec = load_offset != LLDB_INVALID_ADDRESS;
113
114 // if the target executable should be re-based
115 if (rebase_exec) {
116 ModuleList module_list;
117
118 module_list.Append(executable_sp);
119 LLDB_LOGF(log,
120 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
121 " added executable '%s' to module load list",
122 __FUNCTION__,
124 executable_sp->GetFileSpec().GetPath().c_str());
125
126 UpdateLoadedSections(executable_sp, LLDB_INVALID_ADDRESS, load_offset,
127 true);
128
130
131 m_process->GetTarget().ModulesDidLoad(module_list);
132 if (log) {
133 LLDB_LOGF(log,
134 "DynamicLoaderPOSIXDYLD::%s told the target about the "
135 "modules that loaded:",
136 __FUNCTION__);
137 for (auto module_sp : module_list.Modules()) {
138 LLDB_LOGF(log, "-- [module] %s (pid %" PRIu64 ")",
139 module_sp ? module_sp->GetFileSpec().GetPath().c_str()
140 : "<null>",
142 }
143 }
144 }
145
146 if (executable_sp.get()) {
148 // If we cannot establish rendezvous breakpoint right now we'll try again
149 // at entry point.
150 ProbeEntry();
151 }
152 }
153}
154
157 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s()", __FUNCTION__);
158
159 ModuleSP executable;
160 addr_t load_offset;
161
162 m_auxv = std::make_unique<AuxVector>(m_process->GetAuxvData());
163
164 executable = GetTargetExecutable();
165 load_offset = ComputeLoadOffset();
167
168 if (executable.get() && load_offset != LLDB_INVALID_ADDRESS) {
169 ModuleList module_list;
170 module_list.Append(executable);
171 UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset, true);
172
173 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()",
174 __FUNCTION__);
175
177 // If we cannot establish rendezvous breakpoint right now we'll try again
178 // at entry point.
179 ProbeEntry();
180 }
181
182 LoadVDSO();
183 m_process->GetTarget().ModulesDidLoad(module_list);
184 }
185}
186
188
190 addr_t link_map_addr) {
191 llvm::sys::ScopedWriter lock(m_loaded_modules_rw_mutex);
192 m_loaded_modules[module_sp] = link_map_addr;
193}
194
196 llvm::sys::ScopedWriter lock(m_loaded_modules_rw_mutex);
197 m_loaded_modules.erase(module_sp);
198}
199
200std::optional<lldb::addr_t>
202 llvm::sys::ScopedReader lock(m_loaded_modules_rw_mutex);
203 auto it = m_loaded_modules.find(module_sp);
204 if (it != m_loaded_modules.end())
205 return it->second;
206 return std::nullopt;
207}
208
210 addr_t link_map_addr,
211 addr_t base_addr,
212 bool base_addr_is_offset) {
213 SetLoadedModule(module, link_map_addr);
214
215 UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset);
216}
217
219 UnloadModule(module);
220
221 UnloadSectionsCommon(module);
222}
223
226
227 // If we have a core file, we don't need any breakpoints.
228 if (IsCoreFile())
229 return;
230
231 const addr_t entry = GetEntryPoint();
232 if (entry == LLDB_INVALID_ADDRESS) {
233 LLDB_LOGF(
234 log,
235 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
236 " GetEntryPoint() returned no address, not setting entry breakpoint",
237 __FUNCTION__, m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
238 return;
239 }
240
241 LLDB_LOGF(log,
242 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
243 " GetEntryPoint() returned address 0x%" PRIx64
244 ", setting entry breakpoint",
245 __FUNCTION__,
246 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, entry);
247
248 if (m_process) {
249 Breakpoint *const entry_break =
250 m_process->GetTarget().CreateBreakpoint(entry, true, false).get();
251 entry_break->SetCallback(EntryBreakpointHit, this, true);
252 entry_break->SetBreakpointKind("shared-library-event");
253
254 // Shoudn't hit this more than once.
255 entry_break->SetOneShot(true);
256 }
257}
258
259// The runtime linker has run and initialized the rendezvous structure once the
260// process has hit its entry point. When we hit the corresponding breakpoint
261// we interrogate the rendezvous structure to get the load addresses of all
262// dependent modules for the process. Similarly, we can discover the runtime
263// linker function and setup a breakpoint to notify us of any dynamically
264// loaded modules (via dlopen).
266 void *baton, StoppointCallbackContext *context, user_id_t break_id,
267 user_id_t break_loc_id) {
268 assert(baton && "null baton");
269 if (!baton)
270 return false;
271
273 DynamicLoaderPOSIXDYLD *const dyld_instance =
274 static_cast<DynamicLoaderPOSIXDYLD *>(baton);
275 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
276 __FUNCTION__,
277 dyld_instance->m_process ? dyld_instance->m_process->GetID()
279
280 // Disable the breakpoint --- if a stop happens right after this, which we've
281 // seen on occasion, we don't want the breakpoint stepping thread-plan logic
282 // to show a breakpoint instruction at the disassembled entry point to the
283 // program. Disabling it prevents it. (One-shot is not enough - one-shot
284 // removal logic only happens after the breakpoint goes public, which wasn't
285 // happening in our scenario).
286 if (dyld_instance->m_process) {
287 BreakpointSP breakpoint_sp =
288 dyld_instance->m_process->GetTarget().GetBreakpointByID(break_id);
289 if (breakpoint_sp) {
290 LLDB_LOGF(log,
291 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
292 " disabling breakpoint id %" PRIu64,
293 __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
294 breakpoint_sp->SetEnabled(false);
295 } else {
296 LLDB_LOGF(log,
297 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
298 " failed to find breakpoint for breakpoint id %" PRIu64,
299 __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
300 }
301 } else {
302 LLDB_LOGF(log,
303 "DynamicLoaderPOSIXDYLD::%s breakpoint id %" PRIu64
304 " no Process instance! Cannot disable breakpoint",
305 __FUNCTION__, break_id);
306 }
307
308 dyld_instance->LoadAllCurrentModules();
309 dyld_instance->SetRendezvousBreakpoint();
310 return false; // Continue running.
311}
312
315
316 // If we have a core file, we don't need any breakpoints.
317 if (IsCoreFile())
318 return false;
319
321 LLDB_LOG(log,
322 "Rendezvous breakpoint breakpoint id {0} for pid {1}"
323 "is already set.",
326 return true;
327 }
328
329 addr_t break_addr;
330 Target &target = m_process->GetTarget();
331 BreakpointSP dyld_break;
332 if (m_rendezvous.IsValid() && m_rendezvous.GetBreakAddress() != 0) {
333 break_addr = m_rendezvous.GetBreakAddress();
334 LLDB_LOG(log, "Setting rendezvous break address for pid {0} at {1:x}",
336 break_addr);
337 dyld_break = target.CreateBreakpoint(break_addr, true, false);
338 } else {
339 LLDB_LOG(log, "Rendezvous structure is not set up yet. "
340 "Trying to locate rendezvous breakpoint in the interpreter "
341 "by symbol name.");
342 // Function names from different dynamic loaders that are known to be
343 // used 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 ModuleSP interpreter = LoadInterpreterModule();
350 FileSpecList containingModules;
351 if (interpreter)
352 containingModules.Append(interpreter->GetFileSpec());
353 else
354 containingModules.Append(
355 m_process->GetTarget().GetExecutableModulePointer()->GetFileSpec());
356
357 dyld_break = target.CreateBreakpoint(
358 &containingModules, /*containingSourceFiles=*/nullptr,
359 DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC,
360 /*m_offset=*/0,
361 /*skip_prologue=*/eLazyBoolNo,
362 /*internal=*/true,
363 /*request_hardware=*/false);
364 }
365
366 if (dyld_break->GetNumResolvedLocations() != 1) {
367 LLDB_LOG(
368 log,
369 "Rendezvous breakpoint has abnormal number of"
370 " resolved locations ({0}) in pid {1}. It's supposed to be exactly 1.",
371 dyld_break->GetNumResolvedLocations(),
373
374 target.RemoveBreakpointByID(dyld_break->GetID());
375 return false;
376 }
377
378 BreakpointLocationSP location = dyld_break->GetLocationAtIndex(0);
379 LLDB_LOG(log,
380 "Successfully set rendezvous breakpoint at address {0:x} "
381 "for pid {1}",
382 location->GetLoadAddress(),
384
385 dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
386 dyld_break->SetBreakpointKind("shared-library-event");
387 m_dyld_bid = dyld_break->GetID();
388 return true;
389}
390
392 void *baton, StoppointCallbackContext *context, user_id_t break_id,
393 user_id_t break_loc_id) {
394 assert(baton && "null baton");
395 if (!baton)
396 return false;
397
399 DynamicLoaderPOSIXDYLD *const dyld_instance =
400 static_cast<DynamicLoaderPOSIXDYLD *>(baton);
401 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
402 __FUNCTION__,
403 dyld_instance->m_process ? dyld_instance->m_process->GetID()
405
406 dyld_instance->RefreshModules();
407
408 // Return true to stop the target, false to just let the target run.
409 const bool stop_when_images_change = dyld_instance->GetStopWhenImagesChange();
410 LLDB_LOGF(log,
411 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
412 " stop_when_images_change=%s",
413 __FUNCTION__,
414 dyld_instance->m_process ? dyld_instance->m_process->GetID()
416 stop_when_images_change ? "true" : "false");
417 return stop_when_images_change;
418}
419
421 if (!m_rendezvous.Resolve())
422 return;
423
424 // The rendezvous class doesn't enumerate the main module, so track that
425 // ourselves here.
426 ModuleSP executable = GetTargetExecutable();
427 SetLoadedModule(executable, m_rendezvous.GetLinkMapAddress());
428
431
432 ModuleList &loaded_modules = m_process->GetTarget().GetImages();
433
434 if (m_rendezvous.ModulesDidLoad() || !m_initial_modules_added) {
435 ModuleList new_modules;
436
437 // If this is the first time rendezvous breakpoint fires, we need
438 // to take care of adding all the initial modules reported by
439 // the loader. This is necessary to list ld-linux.so on Linux,
440 // and all DT_NEEDED entries on *BSD.
442 I = m_rendezvous.loaded_begin();
443 E = m_rendezvous.loaded_end();
444 } else {
445 I = m_rendezvous.begin();
446 E = m_rendezvous.end();
448 }
449
450 // Synchronize reading and writing of `m_interpreter_module`.
451 std::mutex interpreter_module_mutex;
452 // We should be able to take SOEntry as reference since the data
453 // exists for the duration of this call in `m_rendezvous`.
454 auto load_module_fn =
455 [this, &loaded_modules, &new_modules,
456 &interpreter_module_mutex](const DYLDRendezvous::SOEntry &so_entry) {
457 // Don't load a duplicate copy of ld.so if we have already loaded it
458 // earlier in LoadInterpreterModule. If we instead loaded then
459 // unloaded it later, the section information for ld.so would be
460 // removed. That information is required for placing breakpoints on
461 // Arm/Thumb systems.
462 {
463 // `m_interpreter_module` may be modified by another thread at the
464 // same time, so we guard the access here.
465 std::lock_guard<std::mutex> lock(interpreter_module_mutex);
466 if ((m_interpreter_module.lock() != nullptr) &&
467 (so_entry.base_addr == m_interpreter_base))
468 return;
469 }
470
471 ModuleSP module_sp = LoadModuleAtAddress(
472 so_entry.file_spec, so_entry.link_addr, so_entry.base_addr,
473 /*base_addr_is_offset=*/true);
474 if (!module_sp.get())
475 return;
476
477 {
478 // `m_interpreter_module` may be modified by another thread at the
479 // same time, so we guard the access here.
480 std::lock_guard<std::mutex> lock(interpreter_module_mutex);
481 // Set the interpreter module, if this is the interpreter.
482 if (module_sp->GetObjectFile()->GetBaseAddress().GetLoadAddress(
483 &m_process->GetTarget()) == m_interpreter_base) {
484 ModuleSP interpreter_sp = m_interpreter_module.lock();
485 if (m_interpreter_module.lock() == nullptr) {
486 m_interpreter_module = module_sp;
487 } else if (module_sp == interpreter_sp) {
488 // Module already loaded.
489 return;
490 }
491 }
492 }
493
494 // Note: in a multi-threaded environment, these module lists may be
495 // appended to out-of-order. This is fine, since there's no
496 // expectation for `loaded_modules` or `new_modules` to be in any
497 // particular order, and appending to each module list is thread-safe.
498 // Also, `new_modules` is only used for the `ModulesDidLoad` call at
499 // the end of this function.
500 loaded_modules.AppendIfNeeded(module_sp);
501 new_modules.Append(module_sp);
502 };
503
504 if (m_process->GetTarget().GetParallelModuleLoad()) {
505 llvm::ThreadPoolTaskGroup task_group(Debugger::GetThreadPool());
506 for (; I != E; ++I)
507 task_group.async(load_module_fn, *I);
508 task_group.wait();
509 } else {
510 for (; I != E; ++I)
511 load_module_fn(*I);
512 }
513
514 m_process->GetTarget().ModulesDidLoad(new_modules);
515 }
516
517 if (m_rendezvous.ModulesDidUnload()) {
518 ModuleList old_modules;
519
520 E = m_rendezvous.unloaded_end();
521 for (I = m_rendezvous.unloaded_begin(); I != E; ++I) {
522 ModuleSpec module_spec{I->file_spec};
523 ModuleSP module_sp = loaded_modules.FindFirstModule(module_spec);
524
525 if (module_sp.get()) {
526 old_modules.Append(module_sp);
527 UnloadSections(module_sp);
528 }
529 }
530 loaded_modules.Remove(old_modules);
531 m_process->GetTarget().ModulesDidUnload(old_modules, false);
532 }
533}
534
537 bool stop) {
538 ThreadPlanSP thread_plan_sp;
539
540 StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
541 const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
542 Symbol *sym = context.symbol;
543
544 if (sym == nullptr || !sym->IsTrampoline())
545 return thread_plan_sp;
546
548 if (!sym_name)
549 return thread_plan_sp;
550
551 SymbolContextList target_symbols;
552 Target &target = thread.GetProcess()->GetTarget();
553 const ModuleList &images = target.GetImages();
554
555 llvm::StringRef target_name = sym_name.GetStringRef();
556 // On AArch64, the trampoline name has a prefix (__AArch64ADRPThunk_ or
557 // __AArch64AbsLongThunk_) added to the function name. If we detect a
558 // trampoline with the prefix, we need to remove the prefix to find the
559 // function symbol.
560 if (target_name.consume_front("__AArch64ADRPThunk_") ||
561 target_name.consume_front("__AArch64AbsLongThunk_")) {
562 // An empty target name can happen for trampolines generated for
563 // section-referencing relocations.
564 if (!target_name.empty()) {
565 sym_name = ConstString(target_name);
566 }
567 }
568 images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
569 if (!target_symbols.GetSize())
570 return thread_plan_sp;
571
572 typedef std::vector<lldb::addr_t> AddressVector;
573 AddressVector addrs;
574 for (const SymbolContext &context : target_symbols) {
575 addr_t addr = context.GetFunctionOrSymbolAddress().GetLoadAddress(&target);
576 if (addr != LLDB_INVALID_ADDRESS)
577 addrs.push_back(addr);
578 }
579
580 if (addrs.size() > 0) {
581 AddressVector::iterator start = addrs.begin();
582 AddressVector::iterator end = addrs.end();
583
584 llvm::sort(start, end);
585 addrs.erase(std::unique(start, end), end);
586 thread_plan_sp =
587 std::make_shared<ThreadPlanRunToAddress>(thread, addrs, stop);
588 }
589
590 return thread_plan_sp;
591}
592
595 return;
596
597 FileSpec file("[vdso]");
598
599 MemoryRegionInfo info;
600 Status status = m_process->GetMemoryRegionInfo(m_vdso_base, info);
601 if (status.Fail()) {
603 LLDB_LOG(log, "Failed to get vdso region info: {0}", status);
604 return;
605 }
606
607 if (ModuleSP module_sp = m_process->ReadModuleFromMemory(
608 file, m_vdso_base, info.GetRange().GetByteSize())) {
610 m_process->GetTarget().GetImages().AppendIfNeeded(module_sp);
611 }
612}
613
616 return nullptr;
617
618 MemoryRegionInfo info;
619 Target &target = m_process->GetTarget();
620 Status status = m_process->GetMemoryRegionInfo(m_interpreter_base, info);
621 if (status.Fail() || info.GetMapped() != MemoryRegionInfo::eYes ||
622 info.GetName().IsEmpty()) {
624 LLDB_LOG(log, "Failed to get interpreter region info: {0}", status);
625 return nullptr;
626 }
627
628 FileSpec file(info.GetName().GetCString());
629 ModuleSpec module_spec(file, target.GetArchitecture());
630
631 // Don't notify that module is added here because its loading section
632 // addresses are not updated yet. We manually notify it below.
633 if (ModuleSP module_sp =
634 target.GetOrCreateModule(module_spec, /*notify=*/false)) {
636 false);
637 // Manually notify that dynamic linker is loaded after updating load section
638 // addersses so that breakpoints can be resolved.
639 ModuleList module_list;
640 module_list.Append(module_sp);
641 target.ModulesDidLoad(module_list);
642 m_interpreter_module = module_sp;
643 return module_sp;
644 }
645 return nullptr;
646}
647
649 addr_t link_map_addr,
650 addr_t base_addr,
651 bool base_addr_is_offset) {
653 file, link_map_addr, base_addr, base_addr_is_offset))
654 return module_sp;
655
656 // This works around an dynamic linker "bug" on android <= 23, where the
657 // dynamic linker would report the application name
658 // (e.g. com.example.myapplication) instead of the main process binary
659 // (/system/bin/app_process(32)). The logic is not sound in general (it
660 // assumes base_addr is the real address, even though it actually is a load
661 // bias), but it happens to work on android because app_process has a file
662 // address of zero.
663 // This should be removed after we drop support for android-23.
664 if (m_process->GetTarget().GetArchitecture().GetTriple().isAndroid()) {
665 MemoryRegionInfo memory_info;
666 Status error = m_process->GetMemoryRegionInfo(base_addr, memory_info);
667 if (error.Success() && memory_info.GetMapped() &&
668 memory_info.GetRange().GetRangeBase() == base_addr &&
669 !(memory_info.GetName().IsEmpty())) {
671 FileSpec(memory_info.GetName().GetStringRef()), link_map_addr,
672 base_addr, base_addr_is_offset))
673 return module_sp;
674 }
675 }
676
677 return nullptr;
678}
679
683 ModuleList module_list;
685
686 LoadVDSO();
687
688 if (!m_rendezvous.Resolve()) {
689 LLDB_LOGF(log,
690 "DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD "
691 "rendezvous address",
692 __FUNCTION__);
693 return;
694 }
695
696 // The rendezvous class doesn't enumerate the main module, so track that
697 // ourselves here.
698 ModuleSP executable = GetTargetExecutable();
699 SetLoadedModule(executable, m_rendezvous.GetLinkMapAddress());
700
701 std::vector<FileSpec> module_names;
702 for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
703 module_names.push_back(I->file_spec);
704 m_process->PrefetchModuleSpecs(
705 module_names, m_process->GetTarget().GetArchitecture().GetTriple());
706
707 auto load_module_fn = [this, &module_list,
708 &log](const DYLDRendezvous::SOEntry &so_entry) {
709 ModuleSP module_sp = LoadModuleAtAddress(
710 so_entry.file_spec, so_entry.link_addr, so_entry.base_addr, true);
711 if (module_sp.get()) {
712 LLDB_LOG(log, "LoadAllCurrentModules loading module: {0}",
713 so_entry.file_spec.GetFilename());
714 module_list.Append(module_sp);
715 } else {
717 LLDB_LOGF(
718 log,
719 "DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64,
720 __FUNCTION__, so_entry.file_spec.GetPath().c_str(),
721 so_entry.base_addr);
722 }
723 };
724 if (m_process->GetTarget().GetParallelModuleLoad()) {
725 llvm::ThreadPoolTaskGroup task_group(Debugger::GetThreadPool());
726 for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
727 task_group.async(load_module_fn, *I);
728 task_group.wait();
729 } else {
730 for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
731 load_module_fn(*I);
732 }
733
734 m_process->GetTarget().ModulesDidLoad(module_list);
736}
737
739 addr_t virt_entry;
740
742 return m_load_offset;
743
744 if ((virt_entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS)
746
747 ModuleSP module = m_process->GetTarget().GetExecutableModule();
748 if (!module)
750
751 ObjectFile *exe = module->GetObjectFile();
752 if (!exe)
754
755 Address file_entry = exe->GetEntryPointAddress();
756
757 if (!file_entry.IsValid())
759
760 m_load_offset = virt_entry - file_entry.GetFileAddress();
761 return m_load_offset;
762}
763
765 if (std::optional<uint64_t> vdso_base =
767 m_vdso_base = *vdso_base;
768
769 if (std::optional<uint64_t> interpreter_base =
770 m_auxv->GetAuxValue(AuxVector::AUXV_AT_BASE))
771 m_interpreter_base = *interpreter_base;
772}
773
776 return m_entry_point;
777
778 if (m_auxv == nullptr)
780
781 std::optional<uint64_t> entry_point =
782 m_auxv->GetAuxValue(AuxVector::AUXV_AT_ENTRY);
783 if (!entry_point)
785
786 m_entry_point = static_cast<addr_t>(*entry_point);
787
788 const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
789
790 // On ppc64, the entry point is actually a descriptor. Dereference it.
791 if (arch.GetMachine() == llvm::Triple::ppc64)
793
794 return m_entry_point;
795}
796
799 const lldb::ThreadSP thread,
800 lldb::addr_t tls_file_addr) {
802 std::optional<addr_t> link_map_addr_opt = GetLoadedModuleLinkAddr(module_sp);
803 if (!link_map_addr_opt.has_value()) {
804 LLDB_LOGF(
805 log, "GetThreadLocalData error: module(%s) not found in loaded modules",
806 module_sp->GetObjectName().AsCString());
808 }
809
810 addr_t link_map = link_map_addr_opt.value();
811 if (link_map == LLDB_INVALID_ADDRESS || link_map == 0) {
812 LLDB_LOGF(log,
813 "GetThreadLocalData error: invalid link map address=0x%" PRIx64,
814 link_map);
816 }
817
818 const DYLDRendezvous::ThreadInfo &metadata = m_rendezvous.GetThreadInfo();
819 if (!metadata.valid) {
820 LLDB_LOGF(log,
821 "GetThreadLocalData error: fail to read thread info metadata");
823 }
824
825 LLDB_LOGF(log,
826 "GetThreadLocalData info: link_map=0x%" PRIx64
827 ", thread info metadata: "
828 "modid_offset=0x%" PRIx32 ", dtv_offset=0x%" PRIx32
829 ", tls_offset=0x%" PRIx32 ", dtv_slot_size=%" PRIx32 "\n",
830 link_map, metadata.modid_offset, metadata.dtv_offset,
831 metadata.tls_offset, metadata.dtv_slot_size);
832
833 // Get the thread pointer.
834 addr_t tp = thread->GetThreadPointer();
835 if (tp == LLDB_INVALID_ADDRESS) {
836 LLDB_LOGF(log, "GetThreadLocalData error: fail to read thread pointer");
838 }
839
840 // Find the module's modid.
841 int modid_size = 4; // FIXME(spucci): This isn't right for big-endian 64-bit
842 int64_t modid = ReadUnsignedIntWithSizeInBytes(
843 link_map + metadata.modid_offset, modid_size);
844 if (modid == -1) {
845 LLDB_LOGF(log, "GetThreadLocalData error: fail to read modid");
847 }
848
849 // Lookup the DTV structure for this thread.
850 addr_t dtv_ptr = tp + metadata.dtv_offset;
851 addr_t dtv = ReadPointer(dtv_ptr);
852 if (dtv == LLDB_INVALID_ADDRESS) {
853 LLDB_LOGF(log, "GetThreadLocalData error: fail to read dtv");
855 }
856
857 // Find the TLS block for this module.
858 addr_t dtv_slot = dtv + metadata.dtv_slot_size * modid;
859 addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset);
860
861 LLDB_LOGF(log,
862 "DynamicLoaderPOSIXDYLD::Performed TLS lookup: "
863 "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
864 ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n",
865 module_sp->GetObjectName().AsCString(""), link_map, tp,
866 (int64_t)modid, tls_block);
867
868 if (tls_block == LLDB_INVALID_ADDRESS) {
869 LLDB_LOGF(log, "GetThreadLocalData error: fail to read tls_block");
871 } else
872 return tls_block + tls_file_addr;
873}
874
876 lldb::ModuleSP &module_sp) {
878
879 if (m_process == nullptr)
880 return;
881
882 auto &target = m_process->GetTarget();
883 const auto platform_sp = target.GetPlatform();
884
885 ProcessInstanceInfo process_info;
886 if (!m_process->GetProcessInfo(process_info)) {
887 LLDB_LOGF(log,
888 "DynamicLoaderPOSIXDYLD::%s - failed to get process info for "
889 "pid %" PRIu64,
890 __FUNCTION__, m_process->GetID());
891 return;
892 }
893
894 LLDB_LOGF(
895 log, "DynamicLoaderPOSIXDYLD::%s - got executable by pid %" PRIu64 ": %s",
896 __FUNCTION__, m_process->GetID(),
897 process_info.GetExecutableFile().GetPath().c_str());
898
899 ModuleSpec module_spec(process_info.GetExecutableFile(),
900 process_info.GetArchitecture());
901 if (module_sp && module_sp->MatchesModuleSpec(module_spec))
902 return;
903
904 module_spec.SetTarget(target.shared_from_this());
905 const auto executable_search_paths(Target::GetDefaultExecutableSearchPaths());
906 auto error = platform_sp->ResolveExecutable(module_spec, module_sp);
907 if (error.Fail()) {
908 StreamString stream;
909 module_spec.Dump(stream);
910
911 LLDB_LOGF(log,
912 "DynamicLoaderPOSIXDYLD::%s - failed to resolve executable "
913 "with module spec \"%s\": %s",
914 __FUNCTION__, stream.GetData(), error.AsCString());
915 return;
916 }
917
918 target.SetExecutableModule(module_sp, eLoadDependentsNo);
919}
920
923 ModuleSP module_sp;
924 if (sym_ctx.symbol)
925 module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
926 if (!module_sp && sym_ctx.function)
927 module_sp = sym_ctx.function->GetAddress().GetModule();
928 if (!module_sp)
929 return false;
930
931 return module_sp->GetFileSpec().GetPath() == "[vdso]";
932}
933
935 return !m_process->IsLiveDebugSession();
936}
937
938// For our ELF/POSIX builds save off the fs_base/gs_base regions
939static void AddThreadLocalMemoryRegions(Process &process, ThreadSP &thread_sp,
940 std::vector<MemoryRegionInfo> &ranges) {
941 lldb::RegisterContextSP reg_ctx = thread_sp->GetRegisterContext();
942 if (!reg_ctx)
943 return;
944
945 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
947 if (!reg_info)
948 return;
949
950 lldb_private::RegisterValue thread_local_register_value;
951 bool success = reg_ctx->ReadRegister(reg_info, thread_local_register_value);
952 if (!success)
953 return;
954
955 const uint64_t fail_value = UINT64_MAX;
956 bool readSuccess = false;
957 const lldb::addr_t reg_value_addr =
958 thread_local_register_value.GetAsUInt64(fail_value, &readSuccess);
959 if (!readSuccess || reg_value_addr == fail_value)
960 return;
961
962 MemoryRegionInfo thread_local_region;
963 Status err = process.GetMemoryRegionInfo(reg_value_addr, thread_local_region);
964 if (err.Fail())
965 return;
966
967 ranges.push_back(thread_local_region);
968}
969
970// Save off the link map for core files.
971static void AddLinkMapSections(Process &process,
972 std::vector<MemoryRegionInfo> &ranges) {
973 ModuleList &module_list = process.GetTarget().GetImages();
974 Target *target = &process.GetTarget();
975 for (size_t idx = 0; idx < module_list.GetSize(); idx++) {
976 ModuleSP module_sp = module_list.GetModuleAtIndex(idx);
977 if (!module_sp)
978 continue;
979
980 ObjectFile *obj = module_sp->GetObjectFile();
981 if (!obj)
982 continue;
983 Address addr = obj->GetImageInfoAddress(target);
984 addr_t load_addr = addr.GetLoadAddress(target);
985 if (load_addr == LLDB_INVALID_ADDRESS)
986 continue;
987
988 MemoryRegionInfo link_map_section;
989 Status err = process.GetMemoryRegionInfo(load_addr, link_map_section);
990 if (err.Fail())
991 continue;
992
993 ranges.push_back(link_map_section);
994 }
995}
996
998 lldb_private::Process &process,
999 std::vector<lldb_private::MemoryRegionInfo> &ranges,
1000 llvm::function_ref<bool(const lldb_private::Thread &)>
1001 save_thread_predicate) {
1002 ThreadList &thread_list = process.GetThreadList();
1003 for (size_t idx = 0; idx < thread_list.GetSize(); idx++) {
1004 ThreadSP thread_sp = thread_list.GetThreadAtIndex(idx);
1005 if (!thread_sp)
1006 continue;
1007
1008 if (!save_thread_predicate(*thread_sp))
1009 continue;
1010
1011 AddThreadLocalMemoryRegions(process, thread_sp, ranges);
1012 }
1013
1014 AddLinkMapSections(process, ranges);
1015}
static llvm::raw_ostream & error(Stream &strm)
static void AddLinkMapSections(Process &process, std::vector< MemoryRegionInfo > &ranges)
static void AddThreadLocalMemoryRegions(Process &process, ThreadSP &thread_sp, std::vector< MemoryRegionInfo > &ranges)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:369
#define LLDB_LOGF(log,...)
Definition Log.h:376
#define LLDB_PLUGIN_DEFINE_ADV(ClassName, PluginName)
@ AUXV_AT_SYSINFO_EHDR
Definition AuxVector.h:64
@ AUXV_AT_ENTRY
Program entry point.
Definition AuxVector.h:36
@ AUXV_AT_BASE
Interpreter base address.
Definition AuxVector.h:34
SOEntryList::const_iterator iterator
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.
static lldb_private::DynamicLoader * CreateInstance(lldb_private::Process *process, bool force)
llvm::sys::RWMutex m_loaded_modules_rw_mutex
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...
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 SetLoadedModule(const lldb::ModuleSP &module_sp, lldb::addr_t link_map_addr)
void UnloadSections(const lldb::ModuleSP module) override
Removes the loaded sections from the target in module.
std::optional< lldb::addr_t > GetLoadedModuleLinkAddr(const lldb::ModuleSP &module_sp)
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.
static llvm::StringRef GetPluginNameStatic()
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)
void CalculateDynamicSaveCoreRanges(lldb_private::Process &process, std::vector< lldb_private::MemoryRegionInfo > &ranges, llvm::function_ref< bool(const lldb_private::Thread &)> save_thread_predicate) override
void UnloadModule(const lldb::ModuleSP &module_sp)
A section + offset based address class.
Definition Address.h:62
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition Address.cpp:301
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
Definition Address.cpp:273
lldb::addr_t GetFileAddress() const
Get the file address.
Definition Address.cpp:281
bool IsValid() const
Check if the object state is valid.
Definition Address.h:355
An architecture specification class.
Definition ArchSpec.h:31
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition ArchSpec.h:468
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition ArchSpec.cpp:677
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.
void SetBreakpointKind(const char *kind)
Set the "kind" description for a breakpoint.
Definition Breakpoint.h:482
void SetCallback(BreakpointHitCallback callback, void *baton, bool is_synchronous=false)
Set the callback action invoked when the breakpoint is hit.
A uniqued constant string class.
Definition ConstString.h:40
bool IsEmpty() const
Test for empty string.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
const char * GetCString() const
Get the string value as a C string.
static llvm::ThreadPoolInterface & GetThreadPool()
Shared thread pool. Use only with ThreadPoolTaskGroup.
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 ...
DynamicLoader(Process *process)
Construct with a process.
void UnloadSectionsCommon(const lldb::ModuleSP module)
A file collection class.
void Append(const FileSpec &file)
Append a FileSpec object to the list.
A file utility class.
Definition FileSpec.h:57
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:374
const Address & GetAddress() const
Return the address of the function (its entry point).
Definition Function.h:453
ConstString GetName(NamePreference preference=ePreferDemangled) const
Best name get accessor.
Definition Mangled.cpp:369
A collection class for Module objects.
Definition ModuleList.h:104
lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const
Finds the first module whose file specification matches module_spec.
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
bool Remove(const lldb::ModuleSP &module_sp, bool notify=true)
Remove a module from the module list.
lldb::ModuleSP GetModuleAtIndex(size_t idx) const
Get the module shared pointer for the module at index idx.
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
ModuleIterable Modules() const
Definition ModuleList.h:546
size_t GetSize() const
Gets the size of the module list.
void Dump(Stream &strm) const
Definition ModuleSpec.h:175
void SetTarget(std::shared_ptr< Target > target)
Set the target to be used when resolving a module.
Definition ModuleSpec.h:139
A plug-in interface definition class for object file parsers.
Definition ObjectFile.h:46
virtual lldb_private::Address GetImageInfoAddress(Target *target)
Similar to Process::GetImageInfoAddress().
Definition ObjectFile.h:467
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:477
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
FileSpec & GetExecutableFile()
Definition ProcessInfo.h:43
ArchSpec & GetArchitecture()
Definition ProcessInfo.h:62
A plug-in interface definition class for debugging a process.
Definition Process.h:354
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:553
ThreadList & GetThreadList()
Definition Process.h:2272
Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info)
Locate the memory region that contains load_addr.
Definition Process.cpp:6258
Target & GetTarget()
Get the target object pointer for this module.
Definition Process.h:1267
uint64_t GetAsUInt64(uint64_t fail_value=UINT64_MAX, bool *success_ptr=nullptr) const
This base class provides an interface to stack frames.
Definition StackFrame.h:44
virtual const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
An error handling class.
Definition Status.h:118
bool Fail() const
Test for error condition.
Definition Status.cpp:294
General Outline: When we hit a breakpoint we need to package up whatever information is needed to eva...
const char * GetData() const
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.
Function * function
The Function for a given query.
Symbol * symbol
The Symbol for a given query.
Address GetFunctionOrSymbolAddress() const
Get the address of the function or symbol represented by this symbol context.
Mangled & GetMangled()
Definition Symbol.h:147
bool IsTrampoline() const
Definition Symbol.cpp:221
Address & GetAddressRef()
Definition Symbol.h:73
void ModulesDidLoad(ModuleList &module_list)
This call may preload module symbols, and may do so in parallel depending on the following target set...
Definition Target.cpp:1858
lldb::BreakpointSP GetBreakpointByID(lldb::break_id_t break_id)
Definition Target.cpp:421
bool RemoveBreakpointByID(lldb::break_id_t break_id)
Definition Target.cpp:1106
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:2351
static FileSpecList GetDefaultExecutableSearchPaths()
Definition Target.cpp:2797
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:488
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition Target.h:1111
const ArchSpec & GetArchitecture() const
Definition Target.h:1153
uint32_t GetSize(bool can_update=true)
lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update=true)
#define UINT64_MAX
#define LLDB_INVALID_BREAK_ID
#define LLDB_INVALID_ADDRESS
#define LLDB_REGNUM_GENERIC_TP
#define LLDB_INVALID_PROCESS_ID
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:332
std::shared_ptr< lldb_private::ThreadPlan > ThreadPlanSP
std::shared_ptr< lldb_private::BreakpointLocation > BreakpointLocationSP
std::shared_ptr< lldb_private::Thread > ThreadSP
@ eLanguageTypeC
Non-standardized C, such as K&R.
std::shared_ptr< lldb_private::Breakpoint > BreakpointSP
uint64_t user_id_t
Definition lldb-types.h:82
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
std::shared_ptr< lldb_private::Module > ModuleSP
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
Structure representing the shared objects currently loaded into the inferior process.
BaseType GetRangeBase() const
Definition RangeMap.h:45
SizeType GetByteSize() const
Definition RangeMap.h:87
Every register is described in detail including its name, alternate name (optional),...