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