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"
22#include "lldb/Target/Target.h"
23#include "lldb/Target/Thread.h"
26#include "lldb/Utility/Log.h"
28
29#include <memory>
30#include <optional>
31
32using namespace lldb;
33using namespace lldb_private;
34
36
37void DynamicLoaderPOSIXDYLD::Initialize() {
38 PluginManager::RegisterPlugin(GetPluginNameStatic(),
39 GetPluginDescriptionStatic(), CreateInstance);
40}
41
43
45 return "Dynamic loader plug-in that watches for shared library "
46 "loads/unloads in POSIX processes.";
47}
48
50 bool force) {
51 bool create = force;
52 if (!create) {
53 const llvm::Triple &triple_ref =
54 process->GetTarget().GetArchitecture().GetTriple();
55 if (triple_ref.getOS() == llvm::Triple::FreeBSD ||
56 triple_ref.getOS() == llvm::Triple::Linux ||
57 triple_ref.getOS() == llvm::Triple::NetBSD ||
58 triple_ref.getOS() == llvm::Triple::OpenBSD)
59 create = true;
60 }
61
62 if (create)
63 return new DynamicLoaderPOSIXDYLD(process);
64 return nullptr;
65}
66
68 : DynamicLoader(process), m_rendezvous(process),
69 m_load_offset(LLDB_INVALID_ADDRESS), m_entry_point(LLDB_INVALID_ADDRESS),
70 m_auxv(), m_dyld_bid(LLDB_INVALID_BREAK_ID),
71 m_vdso_base(LLDB_INVALID_ADDRESS),
72 m_interpreter_base(LLDB_INVALID_ADDRESS), m_initial_modules_added(false) {
73}
74
79 }
80}
81
83 Log *log = GetLog(LLDBLog::DynamicLoader);
84 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64, __FUNCTION__,
86 m_auxv = std::make_unique<AuxVector>(m_process->GetAuxvData());
87
89 log, "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reloaded auxv data",
91
92 ModuleSP executable_sp = GetTargetExecutable();
93 ResolveExecutableModule(executable_sp);
95
96 // find the main process load offset
97 addr_t load_offset = ComputeLoadOffset();
98 LLDB_LOGF(log,
99 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
100 " executable '%s', load_offset 0x%" PRIx64,
101 __FUNCTION__,
103 executable_sp ? executable_sp->GetFileSpec().GetPath().c_str()
104 : "<null executable>",
105 load_offset);
106
108
109 // if we dont have a load address we cant re-base
110 bool rebase_exec = load_offset != LLDB_INVALID_ADDRESS;
111
112 // if the target executable should be re-based
113 if (rebase_exec) {
114 ModuleList module_list;
115
116 module_list.Append(executable_sp);
117 LLDB_LOGF(log,
118 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
119 " added executable '%s' to module load list",
120 __FUNCTION__,
122 executable_sp->GetFileSpec().GetPath().c_str());
123
124 UpdateLoadedSections(executable_sp, LLDB_INVALID_ADDRESS, load_offset,
125 true);
126
128
129 m_process->GetTarget().ModulesDidLoad(module_list);
130 if (log) {
131 LLDB_LOGF(log,
132 "DynamicLoaderPOSIXDYLD::%s told the target about the "
133 "modules that loaded:",
134 __FUNCTION__);
135 for (auto module_sp : module_list.Modules()) {
136 LLDB_LOGF(log, "-- [module] %s (pid %" PRIu64 ")",
137 module_sp ? module_sp->GetFileSpec().GetPath().c_str()
138 : "<null>",
140 }
141 }
142 }
143
144 if (executable_sp.get()) {
146 // If we cannot establish rendezvous breakpoint right now we'll try again
147 // at entry point.
148 ProbeEntry();
149 }
150 }
151}
152
154 Log *log = GetLog(LLDBLog::DynamicLoader);
155 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s()", __FUNCTION__);
156
157 ModuleSP executable;
158 addr_t load_offset;
159
160 m_auxv = std::make_unique<AuxVector>(m_process->GetAuxvData());
161
162 executable = GetTargetExecutable();
163 load_offset = ComputeLoadOffset();
165
166 if (executable.get() && load_offset != LLDB_INVALID_ADDRESS) {
167 ModuleList module_list;
168 module_list.Append(executable);
169 UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset, true);
170
171 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()",
172 __FUNCTION__);
173
175 // If we cannot establish rendezvous breakpoint right now we'll try again
176 // at entry point.
177 ProbeEntry();
178 }
179
180 LoadVDSO();
181 m_process->GetTarget().ModulesDidLoad(module_list);
182 }
183}
184
186
188 addr_t link_map_addr,
189 addr_t base_addr,
190 bool base_addr_is_offset) {
191 m_loaded_modules[module] = link_map_addr;
192 UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset);
193}
194
196 m_loaded_modules.erase(module);
197
198 UnloadSectionsCommon(module);
199}
200
202 Log *log = GetLog(LLDBLog::DynamicLoader);
203
204 // If we have a core file, we don't need any breakpoints.
205 if (IsCoreFile())
206 return;
207
208 const addr_t entry = GetEntryPoint();
209 if (entry == LLDB_INVALID_ADDRESS) {
210 LLDB_LOGF(
211 log,
212 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
213 " GetEntryPoint() returned no address, not setting entry breakpoint",
214 __FUNCTION__, m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
215 return;
216 }
217
218 LLDB_LOGF(log,
219 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
220 " GetEntryPoint() returned address 0x%" PRIx64
221 ", setting entry breakpoint",
222 __FUNCTION__,
224
225 if (m_process) {
226 Breakpoint *const entry_break =
227 m_process->GetTarget().CreateBreakpoint(entry, true, false).get();
228 entry_break->SetCallback(EntryBreakpointHit, this, true);
229 entry_break->SetBreakpointKind("shared-library-event");
230
231 // Shoudn't hit this more than once.
232 entry_break->SetOneShot(true);
233 }
234}
235
236// The runtime linker has run and initialized the rendezvous structure once the
237// process has hit its entry point. When we hit the corresponding breakpoint
238// we interrogate the rendezvous structure to get the load addresses of all
239// dependent modules for the process. Similarly, we can discover the runtime
240// linker function and setup a breakpoint to notify us of any dynamically
241// loaded modules (via dlopen).
243 void *baton, StoppointCallbackContext *context, user_id_t break_id,
244 user_id_t break_loc_id) {
245 assert(baton && "null baton");
246 if (!baton)
247 return false;
248
249 Log *log = GetLog(LLDBLog::DynamicLoader);
250 DynamicLoaderPOSIXDYLD *const dyld_instance =
251 static_cast<DynamicLoaderPOSIXDYLD *>(baton);
252 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
253 __FUNCTION__,
254 dyld_instance->m_process ? dyld_instance->m_process->GetID()
256
257 // Disable the breakpoint --- if a stop happens right after this, which we've
258 // seen on occasion, we don't want the breakpoint stepping thread-plan logic
259 // to show a breakpoint instruction at the disassembled entry point to the
260 // program. Disabling it prevents it. (One-shot is not enough - one-shot
261 // removal logic only happens after the breakpoint goes public, which wasn't
262 // happening in our scenario).
263 if (dyld_instance->m_process) {
264 BreakpointSP breakpoint_sp =
265 dyld_instance->m_process->GetTarget().GetBreakpointByID(break_id);
266 if (breakpoint_sp) {
267 LLDB_LOGF(log,
268 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
269 " disabling breakpoint id %" PRIu64,
270 __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
271 breakpoint_sp->SetEnabled(false);
272 } else {
273 LLDB_LOGF(log,
274 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
275 " failed to find breakpoint for breakpoint id %" PRIu64,
276 __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
277 }
278 } else {
279 LLDB_LOGF(log,
280 "DynamicLoaderPOSIXDYLD::%s breakpoint id %" PRIu64
281 " no Process instance! Cannot disable breakpoint",
282 __FUNCTION__, break_id);
283 }
284
285 dyld_instance->LoadAllCurrentModules();
286 dyld_instance->SetRendezvousBreakpoint();
287 return false; // Continue running.
288}
289
291 Log *log = GetLog(LLDBLog::DynamicLoader);
292
293 // If we have a core file, we don't need any breakpoints.
294 if (IsCoreFile())
295 return false;
296
298 LLDB_LOG(log,
299 "Rendezvous breakpoint breakpoint id {0} for pid {1}"
300 "is already set.",
303 return true;
304 }
305
306 addr_t break_addr;
307 Target &target = m_process->GetTarget();
308 BreakpointSP dyld_break;
310 break_addr = m_rendezvous.GetBreakAddress();
311 LLDB_LOG(log, "Setting rendezvous break address for pid {0} at {1:x}",
313 break_addr);
314 dyld_break = target.CreateBreakpoint(break_addr, true, false);
315 } else {
316 LLDB_LOG(log, "Rendezvous structure is not set up yet. "
317 "Trying to locate rendezvous breakpoint in the interpreter "
318 "by symbol name.");
319 // Function names from different dynamic loaders that are known to be
320 // used as rendezvous between the loader and debuggers.
321 static std::vector<std::string> DebugStateCandidates{
322 "_dl_debug_state", "rtld_db_dlactivity", "__dl_rtld_db_dlactivity",
323 "r_debug_state", "_r_debug_state", "_rtld_debug_state",
324 };
325
326 ModuleSP interpreter = LoadInterpreterModule();
327 FileSpecList containingModules;
328 if (interpreter)
329 containingModules.Append(interpreter->GetFileSpec());
330 else
331 containingModules.Append(
333
334 dyld_break = target.CreateBreakpoint(
335 &containingModules, /*containingSourceFiles=*/nullptr,
336 DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC,
337 /*m_offset=*/0,
338 /*skip_prologue=*/eLazyBoolNo,
339 /*internal=*/true,
340 /*request_hardware=*/false);
341 }
342
343 if (dyld_break->GetNumResolvedLocations() != 1) {
344 LLDB_LOG(
345 log,
346 "Rendezvous breakpoint has abnormal number of"
347 " resolved locations ({0}) in pid {1}. It's supposed to be exactly 1.",
348 dyld_break->GetNumResolvedLocations(),
350
351 target.RemoveBreakpointByID(dyld_break->GetID());
352 return false;
353 }
354
355 BreakpointLocationSP location = dyld_break->GetLocationAtIndex(0);
356 LLDB_LOG(log,
357 "Successfully set rendezvous breakpoint at address {0:x} "
358 "for pid {1}",
359 location->GetLoadAddress(),
361
362 dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
363 dyld_break->SetBreakpointKind("shared-library-event");
364 m_dyld_bid = dyld_break->GetID();
365 return true;
366}
367
369 void *baton, StoppointCallbackContext *context, user_id_t break_id,
370 user_id_t break_loc_id) {
371 assert(baton && "null baton");
372 if (!baton)
373 return false;
374
375 Log *log = GetLog(LLDBLog::DynamicLoader);
376 DynamicLoaderPOSIXDYLD *const dyld_instance =
377 static_cast<DynamicLoaderPOSIXDYLD *>(baton);
378 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
379 __FUNCTION__,
380 dyld_instance->m_process ? dyld_instance->m_process->GetID()
382
383 dyld_instance->RefreshModules();
384
385 // Return true to stop the target, false to just let the target run.
386 const bool stop_when_images_change = dyld_instance->GetStopWhenImagesChange();
387 LLDB_LOGF(log,
388 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
389 " stop_when_images_change=%s",
390 __FUNCTION__,
391 dyld_instance->m_process ? dyld_instance->m_process->GetID()
393 stop_when_images_change ? "true" : "false");
394 return stop_when_images_change;
395}
396
398 if (!m_rendezvous.Resolve())
399 return;
400
401 // The rendezvous class doesn't enumerate the main module, so track that
402 // ourselves here.
403 ModuleSP executable = GetTargetExecutable();
405
408
409 ModuleList &loaded_modules = m_process->GetTarget().GetImages();
410
412 ModuleList new_modules;
413
414 // If this is the first time rendezvous breakpoint fires, we need
415 // to take care of adding all the initial modules reported by
416 // the loader. This is necessary to list ld-linux.so on Linux,
417 // and all DT_NEEDED entries on *BSD.
421 } else {
422 I = m_rendezvous.begin();
423 E = m_rendezvous.end();
425 }
426 for (; I != E; ++I) {
427 // Don't load a duplicate copy of ld.so if we have already loaded it
428 // earlier in LoadInterpreterModule. If we instead loaded then unloaded it
429 // later, the section information for ld.so would be removed. That
430 // information is required for placing breakpoints on Arm/Thumb systems.
431 if ((m_interpreter_module.lock() != nullptr) &&
432 (I->base_addr == m_interpreter_base))
433 continue;
434
435 ModuleSP module_sp =
436 LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
437 if (!module_sp.get())
438 continue;
439
440 if (module_sp->GetObjectFile()->GetBaseAddress().GetLoadAddress(
442 ModuleSP interpreter_sp = m_interpreter_module.lock();
443 if (m_interpreter_module.lock() == nullptr) {
444 m_interpreter_module = module_sp;
445 } else if (module_sp == interpreter_sp) {
446 // Module already loaded.
447 continue;
448 }
449 }
450
451 loaded_modules.AppendIfNeeded(module_sp);
452 new_modules.Append(module_sp);
453 }
454 m_process->GetTarget().ModulesDidLoad(new_modules);
455 }
456
458 ModuleList old_modules;
459
461 for (I = m_rendezvous.unloaded_begin(); I != E; ++I) {
462 ModuleSpec module_spec{I->file_spec};
463 ModuleSP module_sp = loaded_modules.FindFirstModule(module_spec);
464
465 if (module_sp.get()) {
466 old_modules.Append(module_sp);
467 UnloadSections(module_sp);
468 }
469 }
470 loaded_modules.Remove(old_modules);
471 m_process->GetTarget().ModulesDidUnload(old_modules, false);
472 }
473}
474
477 bool stop) {
478 ThreadPlanSP thread_plan_sp;
479
480 StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
481 const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
482 Symbol *sym = context.symbol;
483
484 if (sym == nullptr || !sym->IsTrampoline())
485 return thread_plan_sp;
486
488 if (!sym_name)
489 return thread_plan_sp;
490
491 SymbolContextList target_symbols;
492 Target &target = thread.GetProcess()->GetTarget();
493 const ModuleList &images = target.GetImages();
494
495 llvm::StringRef target_name = sym_name.GetStringRef();
496 // On AArch64, the trampoline name has a prefix (__AArch64ADRPThunk_ or
497 // __AArch64AbsLongThunk_) added to the function name. If we detect a
498 // trampoline with the prefix, we need to remove the prefix to find the
499 // function symbol.
500 if (target_name.consume_front("__AArch64ADRPThunk_") ||
501 target_name.consume_front("__AArch64AbsLongThunk_")) {
502 // An empty target name can happen for trampolines generated for
503 // section-referencing relocations.
504 if (!target_name.empty()) {
505 sym_name = ConstString(target_name);
506 }
507 }
508 images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
509 if (!target_symbols.GetSize())
510 return thread_plan_sp;
511
512 typedef std::vector<lldb::addr_t> AddressVector;
513 AddressVector addrs;
514 for (const SymbolContext &context : target_symbols) {
515 AddressRange range;
516 context.GetAddressRange(eSymbolContextEverything, 0, false, range);
517 lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target);
518 if (addr != LLDB_INVALID_ADDRESS)
519 addrs.push_back(addr);
520 }
521
522 if (addrs.size() > 0) {
523 AddressVector::iterator start = addrs.begin();
524 AddressVector::iterator end = addrs.end();
525
526 llvm::sort(start, end);
527 addrs.erase(std::unique(start, end), end);
528 thread_plan_sp =
529 std::make_shared<ThreadPlanRunToAddress>(thread, addrs, stop);
530 }
531
532 return thread_plan_sp;
533}
534
537 return;
538
539 FileSpec file("[vdso]");
540
541 MemoryRegionInfo info;
543 if (status.Fail()) {
544 Log *log = GetLog(LLDBLog::DynamicLoader);
545 LLDB_LOG(log, "Failed to get vdso region info: {0}", status);
546 return;
547 }
548
549 if (ModuleSP module_sp = m_process->ReadModuleFromMemory(
550 file, m_vdso_base, info.GetRange().GetByteSize())) {
553 }
554}
555
558 return nullptr;
559
560 MemoryRegionInfo info;
561 Target &target = m_process->GetTarget();
563 if (status.Fail() || info.GetMapped() != MemoryRegionInfo::eYes ||
564 info.GetName().IsEmpty()) {
565 Log *log = GetLog(LLDBLog::DynamicLoader);
566 LLDB_LOG(log, "Failed to get interpreter region info: {0}", status);
567 return nullptr;
568 }
569
570 FileSpec file(info.GetName().GetCString());
571 ModuleSpec module_spec(file, target.GetArchitecture());
572
573 // Don't notify that module is added here because its loading section
574 // addresses are not updated yet. We manually notify it below.
575 if (ModuleSP module_sp =
576 target.GetOrCreateModule(module_spec, /*notify=*/false)) {
578 false);
579 // Manually notify that dynamic linker is loaded after updating load section
580 // addersses so that breakpoints can be resolved.
581 ModuleList module_list;
582 module_list.Append(module_sp);
583 target.ModulesDidLoad(module_list);
584 m_interpreter_module = module_sp;
585 return module_sp;
586 }
587 return nullptr;
588}
589
591 addr_t link_map_addr,
592 addr_t base_addr,
593 bool base_addr_is_offset) {
595 file, link_map_addr, base_addr, base_addr_is_offset))
596 return module_sp;
597
598 // This works around an dynamic linker "bug" on android <= 23, where the
599 // dynamic linker would report the application name
600 // (e.g. com.example.myapplication) instead of the main process binary
601 // (/system/bin/app_process(32)). The logic is not sound in general (it
602 // assumes base_addr is the real address, even though it actually is a load
603 // bias), but it happens to work on android because app_process has a file
604 // address of zero.
605 // This should be removed after we drop support for android-23.
606 if (m_process->GetTarget().GetArchitecture().GetTriple().isAndroid()) {
607 MemoryRegionInfo memory_info;
608 Status error = m_process->GetMemoryRegionInfo(base_addr, memory_info);
609 if (error.Success() && memory_info.GetMapped() &&
610 memory_info.GetRange().GetRangeBase() == base_addr &&
611 !(memory_info.GetName().IsEmpty())) {
613 FileSpec(memory_info.GetName().GetStringRef()), link_map_addr,
614 base_addr, base_addr_is_offset))
615 return module_sp;
616 }
617 }
618
619 return nullptr;
620}
621
625 ModuleList module_list;
626 Log *log = GetLog(LLDBLog::DynamicLoader);
627
628 LoadVDSO();
629
630 if (!m_rendezvous.Resolve()) {
631 LLDB_LOGF(log,
632 "DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD "
633 "rendezvous address",
634 __FUNCTION__);
635 return;
636 }
637
638 // The rendezvous class doesn't enumerate the main module, so track that
639 // ourselves here.
640 ModuleSP executable = GetTargetExecutable();
642
643 std::vector<FileSpec> module_names;
644 for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
645 module_names.push_back(I->file_spec);
647 module_names, m_process->GetTarget().GetArchitecture().GetTriple());
648
649 for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) {
650 ModuleSP module_sp =
651 LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
652 if (module_sp.get()) {
653 LLDB_LOG(log, "LoadAllCurrentModules loading module: {0}",
654 I->file_spec.GetFilename());
655 module_list.Append(module_sp);
656 } else {
657 Log *log = GetLog(LLDBLog::DynamicLoader);
658 LLDB_LOGF(
659 log,
660 "DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64,
661 __FUNCTION__, I->file_spec.GetPath().c_str(), I->base_addr);
662 }
663 }
664
665 m_process->GetTarget().ModulesDidLoad(module_list);
667}
668
670 addr_t virt_entry;
671
673 return m_load_offset;
674
675 if ((virt_entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS)
677
679 if (!module)
681
682 ObjectFile *exe = module->GetObjectFile();
683 if (!exe)
685
686 Address file_entry = exe->GetEntryPointAddress();
687
688 if (!file_entry.IsValid())
690
691 m_load_offset = virt_entry - file_entry.GetFileAddress();
692 return m_load_offset;
693}
694
696 if (std::optional<uint64_t> vdso_base =
698 m_vdso_base = *vdso_base;
699
700 if (std::optional<uint64_t> interpreter_base =
701 m_auxv->GetAuxValue(AuxVector::AUXV_AT_BASE))
702 m_interpreter_base = *interpreter_base;
703}
704
707 return m_entry_point;
708
709 if (m_auxv == nullptr)
711
712 std::optional<uint64_t> entry_point =
713 m_auxv->GetAuxValue(AuxVector::AUXV_AT_ENTRY);
714 if (!entry_point)
716
717 m_entry_point = static_cast<addr_t>(*entry_point);
718
719 const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
720
721 // On ppc64, the entry point is actually a descriptor. Dereference it.
722 if (arch.GetMachine() == llvm::Triple::ppc64)
724
725 return m_entry_point;
726}
727
730 const lldb::ThreadSP thread,
731 lldb::addr_t tls_file_addr) {
732 Log *log = GetLog(LLDBLog::DynamicLoader);
733 auto it = m_loaded_modules.find(module_sp);
734 if (it == m_loaded_modules.end()) {
735 LLDB_LOGF(
736 log, "GetThreadLocalData error: module(%s) not found in loaded modules",
737 module_sp->GetObjectName().AsCString());
739 }
740
741 addr_t link_map = it->second;
742 if (link_map == LLDB_INVALID_ADDRESS || link_map == 0) {
743 LLDB_LOGF(log,
744 "GetThreadLocalData error: invalid link map address=0x%" PRIx64,
745 link_map);
747 }
748
750 if (!metadata.valid) {
751 LLDB_LOGF(log,
752 "GetThreadLocalData error: fail to read thread info metadata");
754 }
755
756 LLDB_LOGF(log,
757 "GetThreadLocalData info: link_map=0x%" PRIx64
758 ", thread info metadata: "
759 "modid_offset=0x%" PRIx32 ", dtv_offset=0x%" PRIx32
760 ", tls_offset=0x%" PRIx32 ", dtv_slot_size=%" PRIx32 "\n",
761 link_map, metadata.modid_offset, metadata.dtv_offset,
762 metadata.tls_offset, metadata.dtv_slot_size);
763
764 // Get the thread pointer.
765 addr_t tp = thread->GetThreadPointer();
766 if (tp == LLDB_INVALID_ADDRESS) {
767 LLDB_LOGF(log, "GetThreadLocalData error: fail to read thread pointer");
769 }
770
771 // Find the module's modid.
772 int modid_size = 4; // FIXME(spucci): This isn't right for big-endian 64-bit
773 int64_t modid = ReadUnsignedIntWithSizeInBytes(
774 link_map + metadata.modid_offset, modid_size);
775 if (modid == -1) {
776 LLDB_LOGF(log, "GetThreadLocalData error: fail to read modid");
778 }
779
780 // Lookup the DTV structure for this thread.
781 addr_t dtv_ptr = tp + metadata.dtv_offset;
782 addr_t dtv = ReadPointer(dtv_ptr);
783 if (dtv == LLDB_INVALID_ADDRESS) {
784 LLDB_LOGF(log, "GetThreadLocalData error: fail to read dtv");
786 }
787
788 // Find the TLS block for this module.
789 addr_t dtv_slot = dtv + metadata.dtv_slot_size * modid;
790 addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset);
791
792 LLDB_LOGF(log,
793 "DynamicLoaderPOSIXDYLD::Performed TLS lookup: "
794 "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
795 ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n",
796 module_sp->GetObjectName().AsCString(""), link_map, tp,
797 (int64_t)modid, tls_block);
798
799 if (tls_block == LLDB_INVALID_ADDRESS) {
800 LLDB_LOGF(log, "GetThreadLocalData error: fail to read tls_block");
802 } else
803 return tls_block + tls_file_addr;
804}
805
807 lldb::ModuleSP &module_sp) {
808 Log *log = GetLog(LLDBLog::DynamicLoader);
809
810 if (m_process == nullptr)
811 return;
812
813 auto &target = m_process->GetTarget();
814 const auto platform_sp = target.GetPlatform();
815
816 ProcessInstanceInfo process_info;
817 if (!m_process->GetProcessInfo(process_info)) {
818 LLDB_LOGF(log,
819 "DynamicLoaderPOSIXDYLD::%s - failed to get process info for "
820 "pid %" PRIu64,
821 __FUNCTION__, m_process->GetID());
822 return;
823 }
824
825 LLDB_LOGF(
826 log, "DynamicLoaderPOSIXDYLD::%s - got executable by pid %" PRIu64 ": %s",
827 __FUNCTION__, m_process->GetID(),
828 process_info.GetExecutableFile().GetPath().c_str());
829
830 ModuleSpec module_spec(process_info.GetExecutableFile(),
831 process_info.GetArchitecture());
832 if (module_sp && module_sp->MatchesModuleSpec(module_spec))
833 return;
834
835 const auto executable_search_paths(Target::GetDefaultExecutableSearchPaths());
836 auto error = platform_sp->ResolveExecutable(
837 module_spec, module_sp,
838 !executable_search_paths.IsEmpty() ? &executable_search_paths : nullptr);
839 if (error.Fail()) {
840 StreamString stream;
841 module_spec.Dump(stream);
842
843 LLDB_LOGF(log,
844 "DynamicLoaderPOSIXDYLD::%s - failed to resolve executable "
845 "with module spec \"%s\": %s",
846 __FUNCTION__, stream.GetData(), error.AsCString());
847 return;
848 }
849
850 target.SetExecutableModule(module_sp, eLoadDependentsNo);
851}
852
855 ModuleSP module_sp;
856 if (sym_ctx.symbol)
857 module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
858 if (!module_sp && sym_ctx.function)
859 module_sp =
861 if (!module_sp)
862 return false;
863
864 return module_sp->GetFileSpec().GetPath() == "[vdso]";
865}
866
868 return !m_process->IsLiveDebugSession();
869}
870
871// For our ELF/POSIX builds save off the fs_base/gs_base regions
872static void AddThreadLocalMemoryRegions(Process &process, ThreadSP &thread_sp,
873 std::vector<MemoryRegionInfo> &ranges) {
874 lldb::RegisterContextSP reg_ctx = thread_sp->GetRegisterContext();
875 if (!reg_ctx)
876 return;
877
878 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
880 if (!reg_info)
881 return;
882
883 lldb_private::RegisterValue thread_local_register_value;
884 bool success = reg_ctx->ReadRegister(reg_info, thread_local_register_value);
885 if (!success)
886 return;
887
888 const uint64_t fail_value = UINT64_MAX;
889 bool readSuccess = false;
890 const lldb::addr_t reg_value_addr =
891 thread_local_register_value.GetAsUInt64(fail_value, &readSuccess);
892 if (!readSuccess || reg_value_addr == fail_value)
893 return;
894
895 MemoryRegionInfo thread_local_region;
896 Status err = process.GetMemoryRegionInfo(reg_value_addr, thread_local_region);
897 if (err.Fail())
898 return;
899
900 ranges.push_back(thread_local_region);
901}
902
903// Save off the link map for core files.
904static void AddLinkMapSections(Process &process,
905 std::vector<MemoryRegionInfo> &ranges) {
906 ModuleList &module_list = process.GetTarget().GetImages();
907 Target *target = &process.GetTarget();
908 for (size_t idx = 0; idx < module_list.GetSize(); idx++) {
909 ModuleSP module_sp = module_list.GetModuleAtIndex(idx);
910 if (!module_sp)
911 continue;
912
913 ObjectFile *obj = module_sp->GetObjectFile();
914 if (!obj)
915 continue;
916 Address addr = obj->GetImageInfoAddress(target);
917 addr_t load_addr = addr.GetLoadAddress(target);
918 if (load_addr == LLDB_INVALID_ADDRESS)
919 continue;
920
921 MemoryRegionInfo link_map_section;
922 Status err = process.GetMemoryRegionInfo(load_addr, link_map_section);
923 if (err.Fail())
924 continue;
925
926 ranges.push_back(link_map_section);
927 }
928}
929
931 lldb_private::Process &process,
932 std::vector<lldb_private::MemoryRegionInfo> &ranges,
933 llvm::function_ref<bool(const lldb_private::Thread &)>
934 save_thread_predicate) {
935 ThreadList &thread_list = process.GetThreadList();
936 for (size_t idx = 0; idx < thread_list.GetSize(); idx++) {
937 ThreadSP thread_sp = thread_list.GetThreadAtIndex(idx);
938 if (!thread_sp)
939 continue;
940
941 if (!save_thread_predicate(*thread_sp))
942 continue;
943
944 AddThreadLocalMemoryRegions(process, thread_sp, ranges);
945 }
946
947 AddLinkMapSections(process, ranges);
948}
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)
Definition: PluginManager.h:26
@ AUXV_AT_SYSINFO_EHDR
Definition: AuxVector.h:63
@ 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)
void CalculateDynamicSaveCoreRanges(lldb_private::Process &process, std::vector< lldb_private::MemoryRegionInfo > &ranges, llvm::function_ref< bool(const lldb_private::Thread &)> save_thread_predicate) override
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:211
A section + offset based address class.
Definition: Address.h:62
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition: Address.cpp:313
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
Definition: Address.cpp:285
lldb::addr_t GetFileAddress() const
Get the file address.
Definition: Address.cpp:293
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:461
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition: ArchSpec.cpp:701
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:329
void SetBreakpointKind(const char *kind)
Set the "kind" description for a breakpoint.
Definition: Breakpoint.h:452
void SetCallback(BreakpointHitCallback callback, void *baton, bool is_synchronous=false)
Set the callback action invoked when the breakpoint is hit.
Definition: Breakpoint.cpp:409
A uniqued constant string class.
Definition: ConstString.h:40
bool IsEmpty() const
Test for empty string.
Definition: ConstString.h:304
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:197
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:216
A plug-in interface definition class for dynamic loaders.
Definition: DynamicLoader.h:54
int64_t ReadUnsignedIntWithSizeInBytes(lldb::addr_t addr, int size_in_bytes)
lldb::addr_t ReadPointer(lldb::addr_t addr)
Process * m_process
The process that this dynamic loader plug-in is tracking.
void UpdateLoadedSectionsCommon(lldb::ModuleSP module, lldb::addr_t base_addr, bool base_addr_is_offset)
lldb::ModuleSP GetTargetExecutable()
Checks to see if the target module has changed, updates the target accordingly and returns the target...
bool GetStopWhenImagesChange() const
Get whether the process should stop when images change.
virtual lldb::ModuleSP LoadModuleAtAddress(const lldb_private::FileSpec &file, lldb::addr_t link_map_addr, lldb::addr_t base_addr, bool base_addr_is_offset)
Locates or creates a module given by file and updates/loads the resulting module at the virtual base ...
void UnloadSectionsCommon(const lldb::ModuleSP module)
A file collection class.
Definition: FileSpecList.h:91
void Append(const FileSpec &file)
Append a FileSpec object to the list.
A file utility class.
Definition: FileSpec.h:56
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:367
const AddressRange & GetAddressRange()
DEPRECATED: Use GetAddressRanges instead.
Definition: Function.h:448
ConstString GetName(NamePreference preference=ePreferDemangled) const
Best name get accessor.
Definition: Mangled.cpp:335
OptionalBool GetMapped() const
A collection class for Module objects.
Definition: ModuleList.h:103
lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const
Definition: ModuleList.cpp:626
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
Definition: ModuleList.cpp:280
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
Definition: ModuleList.cpp:527
bool Remove(const lldb::ModuleSP &module_sp, bool notify=true)
Remove a module from the module list.
Definition: ModuleList.cpp:334
lldb::ModuleSP GetModuleAtIndex(size_t idx) const
Get the module shared pointer for the module at index idx.
Definition: ModuleList.cpp:429
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
Definition: ModuleList.cpp:247
ModuleIterable Modules() const
Definition: ModuleList.h:527
size_t GetSize() const
Gets the size of the module list.
Definition: ModuleList.cpp:638
void Dump(Stream &strm) const
Definition: ModuleSpec.h:162
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
Definition: Module.h:453
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:44
virtual lldb_private::Address GetImageInfoAddress(Target *target)
Similar to Process::GetImageInfoAddress().
Definition: ObjectFile.h:460
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:470
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:343
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:542
ThreadList & GetThreadList()
Definition: Process.h:2182
virtual DataExtractor GetAuxvData()
Definition: Process.cpp:2840
virtual void PrefetchModuleSpecs(llvm::ArrayRef< FileSpec > module_file_specs, const llvm::Triple &triple)
Definition: Process.h:2511
virtual bool GetProcessInfo(ProcessInstanceInfo &info)
Definition: Process.cpp:6074
virtual bool IsLiveDebugSession() const
Definition: Process.h:1494
Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info)
Locate the memory region that contains load_addr.
Definition: Process.cpp:6188
lldb::ModuleSP ReadModuleFromMemory(const FileSpec &file_spec, lldb::addr_t header_addr, size_t size_to_read=512)
Definition: Process.cpp:2527
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1246
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.
Definition: StackFrame.cpp:301
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
Definition: StreamString.h:45
Defines a list of symbol context objects.
uint32_t GetSize() const
Get accessor for a symbol context list size.
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:34
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:146
bool IsTrampoline() const
Definition: Symbol.cpp:221
Address & GetAddressRef()
Definition: Symbol.h:72
void ModulesDidLoad(ModuleList &module_list)
Definition: Target.cpp:1814
Module * GetExecutableModulePointer()
Definition: Target.cpp:1518
lldb::BreakpointSP GetBreakpointByID(lldb::break_id_t break_id)
Definition: Target.cpp:405
bool RemoveBreakpointByID(lldb::break_id_t break_id)
Definition: Target.cpp:1086
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:2286
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
Definition: Target.cpp:1504
void ModulesDidUnload(ModuleList &module_list, bool delete_locations)
Definition: Target.cpp:1850
static FileSpecList GetDefaultExecutableSearchPaths()
Definition: Target.cpp:2737
lldb::PlatformSP GetPlatform()
Definition: Target.h:1463
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:472
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:997
const ArchSpec & GetArchitecture() const
Definition: Target.h:1039
uint32_t GetSize(bool can_update=true)
Definition: ThreadList.cpp:82
lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update=true)
Definition: ThreadList.cpp:90
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
Definition: Thread.h:408
lldb::ProcessSP GetProcess() const
Definition: Thread.h:157
#define UINT64_MAX
Definition: lldb-defines.h:23
#define LLDB_INVALID_BREAK_ID
Definition: lldb-defines.h:37
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:82
#define LLDB_REGNUM_GENERIC_TP
Definition: lldb-defines.h:77
#define LLDB_INVALID_PROCESS_ID
Definition: lldb-defines.h:89
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
Definition: SBAddress.h:15
std::shared_ptr< lldb_private::ThreadPlan > ThreadPlanSP
Definition: lldb-forward.h:453
std::shared_ptr< lldb_private::BreakpointLocation > BreakpointLocationSP
Definition: lldb-forward.h:324
std::shared_ptr< lldb_private::Thread > ThreadSP
Definition: lldb-forward.h:450
@ eLanguageTypeC
Non-standardized C, such as K&R.
std::shared_ptr< lldb_private::Breakpoint > BreakpointSP
Definition: lldb-forward.h:321
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
Definition: lldb-forward.h:394
std::shared_ptr< lldb_private::Module > ModuleSP
Definition: lldb-forward.h:373
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
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),...