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, true);
473 if (!module_sp.get())
474 return;
475
476 {
477 // `m_interpreter_module` may be modified by another thread at the
478 // same time, so we guard the access here.
479 std::lock_guard<std::mutex> lock(interpreter_module_mutex);
480 // Set the interpreter module, if this is the interpreter.
481 if (module_sp->GetObjectFile()->GetBaseAddress().GetLoadAddress(
482 &m_process->GetTarget()) == m_interpreter_base) {
483 ModuleSP interpreter_sp = m_interpreter_module.lock();
484 if (m_interpreter_module.lock() == nullptr) {
485 m_interpreter_module = module_sp;
486 } else if (module_sp == interpreter_sp) {
487 // Module already loaded.
488 return;
489 }
490 }
491 }
492
493 // Note: in a multi-threaded environment, these module lists may be
494 // appended to out-of-order. This is fine, since there's no
495 // expectation for `loaded_modules` or `new_modules` to be in any
496 // particular order, and appending to each module list is thread-safe.
497 // Also, `new_modules` is only used for the `ModulesDidLoad` call at
498 // the end of this function.
499 loaded_modules.AppendIfNeeded(module_sp);
500 new_modules.Append(module_sp);
501 };
502
503 if (m_process->GetTarget().GetParallelModuleLoad()) {
504 llvm::ThreadPoolTaskGroup task_group(Debugger::GetThreadPool());
505 for (; I != E; ++I)
506 task_group.async(load_module_fn, *I);
507 task_group.wait();
508 } else {
509 for (; I != E; ++I)
510 load_module_fn(*I);
511 }
512
513 m_process->GetTarget().ModulesDidLoad(new_modules);
514 }
515
516 if (m_rendezvous.ModulesDidUnload()) {
517 ModuleList old_modules;
518
519 E = m_rendezvous.unloaded_end();
520 for (I = m_rendezvous.unloaded_begin(); I != E; ++I) {
521 ModuleSpec module_spec{I->file_spec};
522 ModuleSP module_sp = loaded_modules.FindFirstModule(module_spec);
523
524 if (module_sp.get()) {
525 old_modules.Append(module_sp);
526 UnloadSections(module_sp);
527 }
528 }
529 loaded_modules.Remove(old_modules);
530 m_process->GetTarget().ModulesDidUnload(old_modules, false);
531 }
532}
533
536 bool stop) {
537 ThreadPlanSP thread_plan_sp;
538
539 StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
540 const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
541 Symbol *sym = context.symbol;
542
543 if (sym == nullptr || !sym->IsTrampoline())
544 return thread_plan_sp;
545
547 if (!sym_name)
548 return thread_plan_sp;
549
550 SymbolContextList target_symbols;
551 Target &target = thread.GetProcess()->GetTarget();
552 const ModuleList &images = target.GetImages();
553
554 llvm::StringRef target_name = sym_name.GetStringRef();
555 // On AArch64, the trampoline name has a prefix (__AArch64ADRPThunk_ or
556 // __AArch64AbsLongThunk_) added to the function name. If we detect a
557 // trampoline with the prefix, we need to remove the prefix to find the
558 // function symbol.
559 if (target_name.consume_front("__AArch64ADRPThunk_") ||
560 target_name.consume_front("__AArch64AbsLongThunk_")) {
561 // An empty target name can happen for trampolines generated for
562 // section-referencing relocations.
563 if (!target_name.empty()) {
564 sym_name = ConstString(target_name);
565 }
566 }
567 images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
568 if (!target_symbols.GetSize())
569 return thread_plan_sp;
570
571 typedef std::vector<lldb::addr_t> AddressVector;
572 AddressVector addrs;
573 for (const SymbolContext &context : target_symbols) {
574 addr_t addr = context.GetFunctionOrSymbolAddress().GetLoadAddress(&target);
575 if (addr != LLDB_INVALID_ADDRESS)
576 addrs.push_back(addr);
577 }
578
579 if (addrs.size() > 0) {
580 AddressVector::iterator start = addrs.begin();
581 AddressVector::iterator end = addrs.end();
582
583 llvm::sort(start, end);
584 addrs.erase(std::unique(start, end), end);
585 thread_plan_sp =
586 std::make_shared<ThreadPlanRunToAddress>(thread, addrs, stop);
587 }
588
589 return thread_plan_sp;
590}
591
594 return;
595
596 FileSpec file("[vdso]");
597
598 MemoryRegionInfo info;
599 Status status = m_process->GetMemoryRegionInfo(m_vdso_base, info);
600 if (status.Fail()) {
602 LLDB_LOG(log, "Failed to get vdso region info: {0}", status);
603 return;
604 }
605
606 if (ModuleSP module_sp = m_process->ReadModuleFromMemory(
607 file, m_vdso_base, info.GetRange().GetByteSize())) {
609 m_process->GetTarget().GetImages().AppendIfNeeded(module_sp);
610 }
611}
612
615 return nullptr;
616
617 MemoryRegionInfo info;
618 Target &target = m_process->GetTarget();
619 Status status = m_process->GetMemoryRegionInfo(m_interpreter_base, info);
620 if (status.Fail() || info.GetMapped() != MemoryRegionInfo::eYes ||
621 info.GetName().IsEmpty()) {
623 LLDB_LOG(log, "Failed to get interpreter region info: {0}", status);
624 return nullptr;
625 }
626
627 FileSpec file(info.GetName().GetCString());
628 ModuleSpec module_spec(file, target.GetArchitecture());
629
630 // Don't notify that module is added here because its loading section
631 // addresses are not updated yet. We manually notify it below.
632 if (ModuleSP module_sp =
633 target.GetOrCreateModule(module_spec, /*notify=*/false)) {
635 false);
636 // Manually notify that dynamic linker is loaded after updating load section
637 // addersses so that breakpoints can be resolved.
638 ModuleList module_list;
639 module_list.Append(module_sp);
640 target.ModulesDidLoad(module_list);
641 m_interpreter_module = module_sp;
642 return module_sp;
643 }
644 return nullptr;
645}
646
648 addr_t link_map_addr,
649 addr_t base_addr,
650 bool base_addr_is_offset) {
652 file, link_map_addr, base_addr, base_addr_is_offset))
653 return module_sp;
654
655 // This works around an dynamic linker "bug" on android <= 23, where the
656 // dynamic linker would report the application name
657 // (e.g. com.example.myapplication) instead of the main process binary
658 // (/system/bin/app_process(32)). The logic is not sound in general (it
659 // assumes base_addr is the real address, even though it actually is a load
660 // bias), but it happens to work on android because app_process has a file
661 // address of zero.
662 // This should be removed after we drop support for android-23.
663 if (m_process->GetTarget().GetArchitecture().GetTriple().isAndroid()) {
664 MemoryRegionInfo memory_info;
665 Status error = m_process->GetMemoryRegionInfo(base_addr, memory_info);
666 if (error.Success() && memory_info.GetMapped() &&
667 memory_info.GetRange().GetRangeBase() == base_addr &&
668 !(memory_info.GetName().IsEmpty())) {
670 FileSpec(memory_info.GetName().GetStringRef()), link_map_addr,
671 base_addr, base_addr_is_offset))
672 return module_sp;
673 }
674 }
675
676 return nullptr;
677}
678
682 ModuleList module_list;
684
685 LoadVDSO();
686
687 if (!m_rendezvous.Resolve()) {
688 LLDB_LOGF(log,
689 "DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD "
690 "rendezvous address",
691 __FUNCTION__);
692 return;
693 }
694
695 // The rendezvous class doesn't enumerate the main module, so track that
696 // ourselves here.
697 ModuleSP executable = GetTargetExecutable();
698 SetLoadedModule(executable, m_rendezvous.GetLinkMapAddress());
699
700 std::vector<FileSpec> module_names;
701 for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
702 module_names.push_back(I->file_spec);
703 m_process->PrefetchModuleSpecs(
704 module_names, m_process->GetTarget().GetArchitecture().GetTriple());
705
706 auto load_module_fn = [this, &module_list,
707 &log](const DYLDRendezvous::SOEntry &so_entry) {
708 ModuleSP module_sp = LoadModuleAtAddress(
709 so_entry.file_spec, so_entry.link_addr, so_entry.base_addr, true);
710 if (module_sp.get()) {
711 LLDB_LOG(log, "LoadAllCurrentModules loading module: {0}",
712 so_entry.file_spec.GetFilename());
713 module_list.Append(module_sp);
714 } else {
716 LLDB_LOGF(
717 log,
718 "DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64,
719 __FUNCTION__, so_entry.file_spec.GetPath().c_str(),
720 so_entry.base_addr);
721 }
722 };
723 if (m_process->GetTarget().GetParallelModuleLoad()) {
724 llvm::ThreadPoolTaskGroup task_group(Debugger::GetThreadPool());
725 for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
726 task_group.async(load_module_fn, *I);
727 task_group.wait();
728 } else {
729 for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) {
730 load_module_fn(*I);
731 }
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 const auto executable_search_paths(Target::GetDefaultExecutableSearchPaths());
905 auto error = platform_sp->ResolveExecutable(
906 module_spec, module_sp,
907 !executable_search_paths.IsEmpty() ? &executable_search_paths : nullptr);
908 if (error.Fail()) {
909 StreamString stream;
910 module_spec.Dump(stream);
911
912 LLDB_LOGF(log,
913 "DynamicLoaderPOSIXDYLD::%s - failed to resolve executable "
914 "with module spec \"%s\": %s",
915 __FUNCTION__, stream.GetData(), error.AsCString());
916 return;
917 }
918
919 target.SetExecutableModule(module_sp, eLoadDependentsNo);
920}
921
924 ModuleSP module_sp;
925 if (sym_ctx.symbol)
926 module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
927 if (!module_sp && sym_ctx.function)
928 module_sp = sym_ctx.function->GetAddress().GetModule();
929 if (!module_sp)
930 return false;
931
932 return module_sp->GetFileSpec().GetPath() == "[vdso]";
933}
934
936 return !m_process->IsLiveDebugSession();
937}
938
939// For our ELF/POSIX builds save off the fs_base/gs_base regions
940static void AddThreadLocalMemoryRegions(Process &process, ThreadSP &thread_sp,
941 std::vector<MemoryRegionInfo> &ranges) {
942 lldb::RegisterContextSP reg_ctx = thread_sp->GetRegisterContext();
943 if (!reg_ctx)
944 return;
945
946 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
948 if (!reg_info)
949 return;
950
951 lldb_private::RegisterValue thread_local_register_value;
952 bool success = reg_ctx->ReadRegister(reg_info, thread_local_register_value);
953 if (!success)
954 return;
955
956 const uint64_t fail_value = UINT64_MAX;
957 bool readSuccess = false;
958 const lldb::addr_t reg_value_addr =
959 thread_local_register_value.GetAsUInt64(fail_value, &readSuccess);
960 if (!readSuccess || reg_value_addr == fail_value)
961 return;
962
963 MemoryRegionInfo thread_local_region;
964 Status err = process.GetMemoryRegionInfo(reg_value_addr, thread_local_region);
965 if (err.Fail())
966 return;
967
968 ranges.push_back(thread_local_region);
969}
970
971// Save off the link map for core files.
972static void AddLinkMapSections(Process &process,
973 std::vector<MemoryRegionInfo> &ranges) {
974 ModuleList &module_list = process.GetTarget().GetImages();
975 Target *target = &process.GetTarget();
976 for (size_t idx = 0; idx < module_list.GetSize(); idx++) {
977 ModuleSP module_sp = module_list.GetModuleAtIndex(idx);
978 if (!module_sp)
979 continue;
980
981 ObjectFile *obj = module_sp->GetObjectFile();
982 if (!obj)
983 continue;
984 Address addr = obj->GetImageInfoAddress(target);
985 addr_t load_addr = addr.GetLoadAddress(target);
986 if (load_addr == LLDB_INVALID_ADDRESS)
987 continue;
988
989 MemoryRegionInfo link_map_section;
990 Status err = process.GetMemoryRegionInfo(load_addr, link_map_section);
991 if (err.Fail())
992 continue;
993
994 ranges.push_back(link_map_section);
995 }
996}
997
999 lldb_private::Process &process,
1000 std::vector<lldb_private::MemoryRegionInfo> &ranges,
1001 llvm::function_ref<bool(const lldb_private::Thread &)>
1002 save_thread_predicate) {
1003 ThreadList &thread_list = process.GetThreadList();
1004 for (size_t idx = 0; idx < thread_list.GetSize(); idx++) {
1005 ThreadSP thread_sp = thread_list.GetThreadAtIndex(idx);
1006 if (!thread_sp)
1007 continue;
1008
1009 if (!save_thread_predicate(*thread_sp))
1010 continue;
1011
1012 AddThreadLocalMemoryRegions(process, thread_sp, ranges);
1013 }
1014
1015 AddLinkMapSections(process, ranges);
1016}
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:448
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:537
size_t GetSize() const
Gets the size of the module list.
void Dump(Stream &strm) const
Definition ModuleSpec.h:162
A plug-in interface definition class for object file parsers.
Definition ObjectFile.h:45
virtual lldb_private::Address GetImageInfoAddress(Target *target)
Similar to Process::GetImageInfoAddress().
Definition ObjectFile.h:466
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:476
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:357
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:556
ThreadList & GetThreadList()
Definition Process.h:2253
Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info)
Locate the memory region that contains load_addr.
Definition Process.cpp:6214
Target & GetTarget()
Get the target object pointer for this module.
Definition Process.h:1270
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
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)
Definition Target.cpp:1851
lldb::BreakpointSP GetBreakpointByID(lldb::break_id_t break_id)
Definition Target.cpp:414
bool RemoveBreakpointByID(lldb::break_id_t break_id)
Definition Target.cpp:1099
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:2339
static FileSpecList GetDefaultExecutableSearchPaths()
Definition Target.cpp:2789
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:481
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition Target.h:1014
const ArchSpec & GetArchitecture() const
Definition Target.h:1056
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),...