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
10 #include "DynamicLoaderPOSIXDYLD.h"
11
12 #include "lldb/Breakpoint/BreakpointLocation.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/ModuleSpec.h"
15 #include "lldb/Core/PluginManager.h"
16 #include "lldb/Core/Section.h"
17 #include "lldb/Symbol/Function.h"
18 #include "lldb/Symbol/ObjectFile.h"
19 #include "lldb/Target/MemoryRegionInfo.h"
20 #include "lldb/Target/Platform.h"
21 #include "lldb/Target/Target.h"
22 #include "lldb/Target/Thread.h"
23 #include "lldb/Target/ThreadPlanRunToAddress.h"
24 #include "lldb/Utility/Log.h"
25 #include "lldb/Utility/ProcessInfo.h"
26
27 #include <memory>
28
29 using namespace lldb;
30 using namespace lldb_private;
31
LLDB_PLUGIN_DEFINE_ADV(DynamicLoaderPOSIXDYLD,DynamicLoaderPosixDYLD)32 LLDB_PLUGIN_DEFINE_ADV(DynamicLoaderPOSIXDYLD, DynamicLoaderPosixDYLD)
33
34 void DynamicLoaderPOSIXDYLD::Initialize() {
35 PluginManager::RegisterPlugin(GetPluginNameStatic(),
36 GetPluginDescriptionStatic(), CreateInstance);
37 }
38
Terminate()39 void DynamicLoaderPOSIXDYLD::Terminate() {}
40
GetPluginName()41 lldb_private::ConstString DynamicLoaderPOSIXDYLD::GetPluginName() {
42 return GetPluginNameStatic();
43 }
44
GetPluginNameStatic()45 lldb_private::ConstString DynamicLoaderPOSIXDYLD::GetPluginNameStatic() {
46 static ConstString g_name("linux-dyld");
47 return g_name;
48 }
49
GetPluginDescriptionStatic()50 const char *DynamicLoaderPOSIXDYLD::GetPluginDescriptionStatic() {
51 return "Dynamic loader plug-in that watches for shared library "
52 "loads/unloads in POSIX processes.";
53 }
54
GetPluginVersion()55 uint32_t DynamicLoaderPOSIXDYLD::GetPluginVersion() { return 1; }
56
CreateInstance(Process * process,bool force)57 DynamicLoader *DynamicLoaderPOSIXDYLD::CreateInstance(Process *process,
58 bool force) {
59 bool create = force;
60 if (!create) {
61 const llvm::Triple &triple_ref =
62 process->GetTarget().GetArchitecture().GetTriple();
63 if (triple_ref.getOS() == llvm::Triple::FreeBSD ||
64 triple_ref.getOS() == llvm::Triple::Linux ||
65 triple_ref.getOS() == llvm::Triple::NetBSD)
66 create = true;
67 }
68
69 if (create)
70 return new DynamicLoaderPOSIXDYLD(process);
71 return nullptr;
72 }
73
DynamicLoaderPOSIXDYLD(Process * process)74 DynamicLoaderPOSIXDYLD::DynamicLoaderPOSIXDYLD(Process *process)
75 : DynamicLoader(process), m_rendezvous(process),
76 m_load_offset(LLDB_INVALID_ADDRESS), m_entry_point(LLDB_INVALID_ADDRESS),
77 m_auxv(), m_dyld_bid(LLDB_INVALID_BREAK_ID),
78 m_vdso_base(LLDB_INVALID_ADDRESS),
79 m_interpreter_base(LLDB_INVALID_ADDRESS) {}
80
~DynamicLoaderPOSIXDYLD()81 DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD() {
82 if (m_dyld_bid != LLDB_INVALID_BREAK_ID) {
83 m_process->GetTarget().RemoveBreakpointByID(m_dyld_bid);
84 m_dyld_bid = LLDB_INVALID_BREAK_ID;
85 }
86 }
87
DidAttach()88 void DynamicLoaderPOSIXDYLD::DidAttach() {
89 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
90 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64, __FUNCTION__,
91 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
92 m_auxv = std::make_unique<AuxVector>(m_process->GetAuxvData());
93
94 LLDB_LOGF(
95 log, "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reloaded auxv data",
96 __FUNCTION__, m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
97
98 // ask the process if it can load any of its own modules
99 auto error = m_process->LoadModules();
100 LLDB_LOG_ERROR(log, std::move(error), "Couldn't load modules: {0}");
101
102 ModuleSP executable_sp = GetTargetExecutable();
103 ResolveExecutableModule(executable_sp);
104
105 // find the main process load offset
106 addr_t load_offset = ComputeLoadOffset();
107 LLDB_LOGF(log,
108 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
109 " executable '%s', load_offset 0x%" PRIx64,
110 __FUNCTION__,
111 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
112 executable_sp ? executable_sp->GetFileSpec().GetPath().c_str()
113 : "<null executable>",
114 load_offset);
115
116 EvalSpecialModulesStatus();
117
118 // if we dont have a load address we cant re-base
119 bool rebase_exec = load_offset != LLDB_INVALID_ADDRESS;
120
121 // if we have a valid executable
122 if (executable_sp.get()) {
123 lldb_private::ObjectFile *obj = executable_sp->GetObjectFile();
124 if (obj) {
125 // don't rebase if the module already has a load address
126 Target &target = m_process->GetTarget();
127 Address addr = obj->GetImageInfoAddress(&target);
128 if (addr.GetLoadAddress(&target) != LLDB_INVALID_ADDRESS)
129 rebase_exec = false;
130 }
131 } else {
132 // no executable, nothing to re-base
133 rebase_exec = false;
134 }
135
136 // if the target executable should be re-based
137 if (rebase_exec) {
138 ModuleList module_list;
139
140 module_list.Append(executable_sp);
141 LLDB_LOGF(log,
142 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
143 " added executable '%s' to module load list",
144 __FUNCTION__,
145 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
146 executable_sp->GetFileSpec().GetPath().c_str());
147
148 UpdateLoadedSections(executable_sp, LLDB_INVALID_ADDRESS, load_offset,
149 true);
150
151 LoadAllCurrentModules();
152
153 m_process->GetTarget().ModulesDidLoad(module_list);
154 if (log) {
155 LLDB_LOGF(log,
156 "DynamicLoaderPOSIXDYLD::%s told the target about the "
157 "modules that loaded:",
158 __FUNCTION__);
159 for (auto module_sp : module_list.Modules()) {
160 LLDB_LOGF(log, "-- [module] %s (pid %" PRIu64 ")",
161 module_sp ? module_sp->GetFileSpec().GetPath().c_str()
162 : "<null>",
163 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
164 }
165 }
166 }
167
168 if (executable_sp.get()) {
169 if (!SetRendezvousBreakpoint()) {
170 // If we cannot establish rendezvous breakpoint right now we'll try again
171 // at entry point.
172 ProbeEntry();
173 }
174 }
175 }
176
DidLaunch()177 void DynamicLoaderPOSIXDYLD::DidLaunch() {
178 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
179 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s()", __FUNCTION__);
180
181 ModuleSP executable;
182 addr_t load_offset;
183
184 m_auxv = std::make_unique<AuxVector>(m_process->GetAuxvData());
185
186 executable = GetTargetExecutable();
187 load_offset = ComputeLoadOffset();
188 EvalSpecialModulesStatus();
189
190 if (executable.get() && load_offset != LLDB_INVALID_ADDRESS) {
191 ModuleList module_list;
192 module_list.Append(executable);
193 UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset, true);
194
195 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()",
196 __FUNCTION__);
197
198 if (!SetRendezvousBreakpoint()) {
199 // If we cannot establish rendezvous breakpoint right now we'll try again
200 // at entry point.
201 ProbeEntry();
202 }
203
204 LoadVDSO();
205 m_process->GetTarget().ModulesDidLoad(module_list);
206 }
207 }
208
CanLoadImage()209 Status DynamicLoaderPOSIXDYLD::CanLoadImage() { return Status(); }
210
UpdateLoadedSections(ModuleSP module,addr_t link_map_addr,addr_t base_addr,bool base_addr_is_offset)211 void DynamicLoaderPOSIXDYLD::UpdateLoadedSections(ModuleSP module,
212 addr_t link_map_addr,
213 addr_t base_addr,
214 bool base_addr_is_offset) {
215 m_loaded_modules[module] = link_map_addr;
216 UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset);
217 }
218
UnloadSections(const ModuleSP module)219 void DynamicLoaderPOSIXDYLD::UnloadSections(const ModuleSP module) {
220 m_loaded_modules.erase(module);
221
222 UnloadSectionsCommon(module);
223 }
224
ProbeEntry()225 void DynamicLoaderPOSIXDYLD::ProbeEntry() {
226 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
227
228 const addr_t entry = GetEntryPoint();
229 if (entry == LLDB_INVALID_ADDRESS) {
230 LLDB_LOGF(
231 log,
232 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
233 " GetEntryPoint() returned no address, not setting entry breakpoint",
234 __FUNCTION__, m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
235 return;
236 }
237
238 LLDB_LOGF(log,
239 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
240 " GetEntryPoint() returned address 0x%" PRIx64
241 ", setting entry breakpoint",
242 __FUNCTION__,
243 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, entry);
244
245 if (m_process) {
246 Breakpoint *const entry_break =
247 m_process->GetTarget().CreateBreakpoint(entry, true, false).get();
248 entry_break->SetCallback(EntryBreakpointHit, this, true);
249 entry_break->SetBreakpointKind("shared-library-event");
250
251 // Shoudn't hit this more than once.
252 entry_break->SetOneShot(true);
253 }
254 }
255
256 // The runtime linker has run and initialized the rendezvous structure once the
257 // process has hit its entry point. When we hit the corresponding breakpoint
258 // we interrogate the rendezvous structure to get the load addresses of all
259 // dependent modules for the process. Similarly, we can discover the runtime
260 // linker function and setup a breakpoint to notify us of any dynamically
261 // loaded modules (via dlopen).
EntryBreakpointHit(void * baton,StoppointCallbackContext * context,user_id_t break_id,user_id_t break_loc_id)262 bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit(
263 void *baton, StoppointCallbackContext *context, user_id_t break_id,
264 user_id_t break_loc_id) {
265 assert(baton && "null baton");
266 if (!baton)
267 return false;
268
269 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
270 DynamicLoaderPOSIXDYLD *const dyld_instance =
271 static_cast<DynamicLoaderPOSIXDYLD *>(baton);
272 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
273 __FUNCTION__,
274 dyld_instance->m_process ? dyld_instance->m_process->GetID()
275 : LLDB_INVALID_PROCESS_ID);
276
277 // Disable the breakpoint --- if a stop happens right after this, which we've
278 // seen on occasion, we don't want the breakpoint stepping thread-plan logic
279 // to show a breakpoint instruction at the disassembled entry point to the
280 // program. Disabling it prevents it. (One-shot is not enough - one-shot
281 // removal logic only happens after the breakpoint goes public, which wasn't
282 // happening in our scenario).
283 if (dyld_instance->m_process) {
284 BreakpointSP breakpoint_sp =
285 dyld_instance->m_process->GetTarget().GetBreakpointByID(break_id);
286 if (breakpoint_sp) {
287 LLDB_LOGF(log,
288 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
289 " disabling breakpoint id %" PRIu64,
290 __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
291 breakpoint_sp->SetEnabled(false);
292 } else {
293 LLDB_LOGF(log,
294 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
295 " failed to find breakpoint for breakpoint id %" PRIu64,
296 __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
297 }
298 } else {
299 LLDB_LOGF(log,
300 "DynamicLoaderPOSIXDYLD::%s breakpoint id %" PRIu64
301 " no Process instance! Cannot disable breakpoint",
302 __FUNCTION__, break_id);
303 }
304
305 dyld_instance->LoadAllCurrentModules();
306 dyld_instance->SetRendezvousBreakpoint();
307 return false; // Continue running.
308 }
309
SetRendezvousBreakpoint()310 bool DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() {
311 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
312 if (m_dyld_bid != LLDB_INVALID_BREAK_ID) {
313 LLDB_LOG(log,
314 "Rendezvous breakpoint breakpoint id {0} for pid {1}"
315 "is already set.",
316 m_dyld_bid,
317 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
318 return true;
319 }
320
321 addr_t break_addr;
322 Target &target = m_process->GetTarget();
323 BreakpointSP dyld_break;
324 if (m_rendezvous.IsValid()) {
325 break_addr = m_rendezvous.GetBreakAddress();
326 LLDB_LOG(log, "Setting rendezvous break address for pid {0} at {1:x}",
327 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
328 break_addr);
329 dyld_break = target.CreateBreakpoint(break_addr, true, false);
330 } else {
331 LLDB_LOG(log, "Rendezvous structure is not set up yet. "
332 "Trying to locate rendezvous breakpoint in the interpreter "
333 "by symbol name.");
334 ModuleSP interpreter = LoadInterpreterModule();
335 if (!interpreter) {
336 LLDB_LOG(log, "Can't find interpreter, rendezvous breakpoint isn't set.");
337 return false;
338 }
339
340 // Function names from different dynamic loaders that are known to be used
341 // as rendezvous between the loader and debuggers.
342 static std::vector<std::string> DebugStateCandidates{
343 "_dl_debug_state", "rtld_db_dlactivity", "__dl_rtld_db_dlactivity",
344 "r_debug_state", "_r_debug_state", "_rtld_debug_state",
345 };
346
347 FileSpecList containingModules;
348 containingModules.Append(interpreter->GetFileSpec());
349 dyld_break = target.CreateBreakpoint(
350 &containingModules, nullptr /* containingSourceFiles */,
351 DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC,
352 0, /* offset */
353 eLazyBoolNo, /* skip_prologue */
354 true, /* internal */
355 false /* request_hardware */);
356 }
357
358 if (dyld_break->GetNumResolvedLocations() != 1) {
359 LLDB_LOG(
360 log,
361 "Rendezvous breakpoint has abnormal number of"
362 " resolved locations ({0}) in pid {1}. It's supposed to be exactly 1.",
363 dyld_break->GetNumResolvedLocations(),
364 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
365
366 target.RemoveBreakpointByID(dyld_break->GetID());
367 return false;
368 }
369
370 BreakpointLocationSP location = dyld_break->GetLocationAtIndex(0);
371 LLDB_LOG(log,
372 "Successfully set rendezvous breakpoint at address {0:x} "
373 "for pid {1}",
374 location->GetLoadAddress(),
375 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
376
377 dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
378 dyld_break->SetBreakpointKind("shared-library-event");
379 m_dyld_bid = dyld_break->GetID();
380 return true;
381 }
382
RendezvousBreakpointHit(void * baton,StoppointCallbackContext * context,user_id_t break_id,user_id_t break_loc_id)383 bool DynamicLoaderPOSIXDYLD::RendezvousBreakpointHit(
384 void *baton, StoppointCallbackContext *context, user_id_t break_id,
385 user_id_t break_loc_id) {
386 assert(baton && "null baton");
387 if (!baton)
388 return false;
389
390 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
391 DynamicLoaderPOSIXDYLD *const dyld_instance =
392 static_cast<DynamicLoaderPOSIXDYLD *>(baton);
393 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
394 __FUNCTION__,
395 dyld_instance->m_process ? dyld_instance->m_process->GetID()
396 : LLDB_INVALID_PROCESS_ID);
397
398 dyld_instance->RefreshModules();
399
400 // Return true to stop the target, false to just let the target run.
401 const bool stop_when_images_change = dyld_instance->GetStopWhenImagesChange();
402 LLDB_LOGF(log,
403 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
404 " stop_when_images_change=%s",
405 __FUNCTION__,
406 dyld_instance->m_process ? dyld_instance->m_process->GetID()
407 : LLDB_INVALID_PROCESS_ID,
408 stop_when_images_change ? "true" : "false");
409 return stop_when_images_change;
410 }
411
RefreshModules()412 void DynamicLoaderPOSIXDYLD::RefreshModules() {
413 if (!m_rendezvous.Resolve())
414 return;
415
416 DYLDRendezvous::iterator I;
417 DYLDRendezvous::iterator E;
418
419 ModuleList &loaded_modules = m_process->GetTarget().GetImages();
420
421 if (m_rendezvous.ModulesDidLoad()) {
422 ModuleList new_modules;
423
424 E = m_rendezvous.loaded_end();
425 for (I = m_rendezvous.loaded_begin(); I != E; ++I) {
426 ModuleSP module_sp =
427 LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
428 if (module_sp.get()) {
429 loaded_modules.AppendIfNeeded(module_sp);
430 new_modules.Append(module_sp);
431 }
432 }
433 m_process->GetTarget().ModulesDidLoad(new_modules);
434 }
435
436 if (m_rendezvous.ModulesDidUnload()) {
437 ModuleList old_modules;
438
439 E = m_rendezvous.unloaded_end();
440 for (I = m_rendezvous.unloaded_begin(); I != E; ++I) {
441 ModuleSpec module_spec{I->file_spec};
442 ModuleSP module_sp = loaded_modules.FindFirstModule(module_spec);
443
444 if (module_sp.get()) {
445 old_modules.Append(module_sp);
446 UnloadSections(module_sp);
447 }
448 }
449 loaded_modules.Remove(old_modules);
450 m_process->GetTarget().ModulesDidUnload(old_modules, false);
451 }
452 }
453
454 ThreadPlanSP
GetStepThroughTrampolinePlan(Thread & thread,bool stop)455 DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread,
456 bool stop) {
457 ThreadPlanSP thread_plan_sp;
458
459 StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
460 const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
461 Symbol *sym = context.symbol;
462
463 if (sym == nullptr || !sym->IsTrampoline())
464 return thread_plan_sp;
465
466 ConstString sym_name = sym->GetName();
467 if (!sym_name)
468 return thread_plan_sp;
469
470 SymbolContextList target_symbols;
471 Target &target = thread.GetProcess()->GetTarget();
472 const ModuleList &images = target.GetImages();
473
474 images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
475 size_t num_targets = target_symbols.GetSize();
476 if (!num_targets)
477 return thread_plan_sp;
478
479 typedef std::vector<lldb::addr_t> AddressVector;
480 AddressVector addrs;
481 for (size_t i = 0; i < num_targets; ++i) {
482 SymbolContext context;
483 AddressRange range;
484 if (target_symbols.GetContextAtIndex(i, context)) {
485 context.GetAddressRange(eSymbolContextEverything, 0, false, range);
486 lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target);
487 if (addr != LLDB_INVALID_ADDRESS)
488 addrs.push_back(addr);
489 }
490 }
491
492 if (addrs.size() > 0) {
493 AddressVector::iterator start = addrs.begin();
494 AddressVector::iterator end = addrs.end();
495
496 llvm::sort(start, end);
497 addrs.erase(std::unique(start, end), end);
498 thread_plan_sp =
499 std::make_shared<ThreadPlanRunToAddress>(thread, addrs, stop);
500 }
501
502 return thread_plan_sp;
503 }
504
LoadVDSO()505 void DynamicLoaderPOSIXDYLD::LoadVDSO() {
506 if (m_vdso_base == LLDB_INVALID_ADDRESS)
507 return;
508
509 FileSpec file("[vdso]");
510
511 MemoryRegionInfo info;
512 Status status = m_process->GetMemoryRegionInfo(m_vdso_base, info);
513 if (status.Fail()) {
514 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
515 LLDB_LOG(log, "Failed to get vdso region info: {0}", status);
516 return;
517 }
518
519 if (ModuleSP module_sp = m_process->ReadModuleFromMemory(
520 file, m_vdso_base, info.GetRange().GetByteSize())) {
521 UpdateLoadedSections(module_sp, LLDB_INVALID_ADDRESS, m_vdso_base, false);
522 m_process->GetTarget().GetImages().AppendIfNeeded(module_sp);
523 }
524 }
525
LoadInterpreterModule()526 ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() {
527 if (m_interpreter_base == LLDB_INVALID_ADDRESS)
528 return nullptr;
529
530 MemoryRegionInfo info;
531 Target &target = m_process->GetTarget();
532 Status status = m_process->GetMemoryRegionInfo(m_interpreter_base, info);
533 if (status.Fail() || info.GetMapped() != MemoryRegionInfo::eYes ||
534 info.GetName().IsEmpty()) {
535 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
536 LLDB_LOG(log, "Failed to get interpreter region info: {0}", status);
537 return nullptr;
538 }
539
540 FileSpec file(info.GetName().GetCString());
541 ModuleSpec module_spec(file, target.GetArchitecture());
542
543 if (ModuleSP module_sp = target.GetOrCreateModule(module_spec,
544 true /* notify */)) {
545 UpdateLoadedSections(module_sp, LLDB_INVALID_ADDRESS, m_interpreter_base,
546 false);
547 return module_sp;
548 }
549 return nullptr;
550 }
551
LoadAllCurrentModules()552 void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() {
553 DYLDRendezvous::iterator I;
554 DYLDRendezvous::iterator E;
555 ModuleList module_list;
556 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
557
558 LoadVDSO();
559
560 if (!m_rendezvous.Resolve()) {
561 LLDB_LOGF(log,
562 "DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD "
563 "rendezvous address",
564 __FUNCTION__);
565 return;
566 }
567
568 // The rendezvous class doesn't enumerate the main module, so track that
569 // ourselves here.
570 ModuleSP executable = GetTargetExecutable();
571 m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress();
572
573 std::vector<FileSpec> module_names;
574 for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
575 module_names.push_back(I->file_spec);
576 m_process->PrefetchModuleSpecs(
577 module_names, m_process->GetTarget().GetArchitecture().GetTriple());
578
579 for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) {
580 ModuleSP module_sp =
581 LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
582 if (module_sp.get()) {
583 LLDB_LOG(log, "LoadAllCurrentModules loading module: {0}",
584 I->file_spec.GetFilename());
585 module_list.Append(module_sp);
586 } else {
587 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
588 LLDB_LOGF(
589 log,
590 "DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64,
591 __FUNCTION__, I->file_spec.GetCString(), I->base_addr);
592 }
593 }
594
595 m_process->GetTarget().ModulesDidLoad(module_list);
596 }
597
ComputeLoadOffset()598 addr_t DynamicLoaderPOSIXDYLD::ComputeLoadOffset() {
599 addr_t virt_entry;
600
601 if (m_load_offset != LLDB_INVALID_ADDRESS)
602 return m_load_offset;
603
604 if ((virt_entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS)
605 return LLDB_INVALID_ADDRESS;
606
607 ModuleSP module = m_process->GetTarget().GetExecutableModule();
608 if (!module)
609 return LLDB_INVALID_ADDRESS;
610
611 ObjectFile *exe = module->GetObjectFile();
612 if (!exe)
613 return LLDB_INVALID_ADDRESS;
614
615 Address file_entry = exe->GetEntryPointAddress();
616
617 if (!file_entry.IsValid())
618 return LLDB_INVALID_ADDRESS;
619
620 m_load_offset = virt_entry - file_entry.GetFileAddress();
621 return m_load_offset;
622 }
623
EvalSpecialModulesStatus()624 void DynamicLoaderPOSIXDYLD::EvalSpecialModulesStatus() {
625 if (llvm::Optional<uint64_t> vdso_base =
626 m_auxv->GetAuxValue(AuxVector::AUXV_AT_SYSINFO_EHDR))
627 m_vdso_base = *vdso_base;
628
629 if (llvm::Optional<uint64_t> interpreter_base =
630 m_auxv->GetAuxValue(AuxVector::AUXV_AT_BASE))
631 m_interpreter_base = *interpreter_base;
632 }
633
GetEntryPoint()634 addr_t DynamicLoaderPOSIXDYLD::GetEntryPoint() {
635 if (m_entry_point != LLDB_INVALID_ADDRESS)
636 return m_entry_point;
637
638 if (m_auxv == nullptr)
639 return LLDB_INVALID_ADDRESS;
640
641 llvm::Optional<uint64_t> entry_point =
642 m_auxv->GetAuxValue(AuxVector::AUXV_AT_ENTRY);
643 if (!entry_point)
644 return LLDB_INVALID_ADDRESS;
645
646 m_entry_point = static_cast<addr_t>(*entry_point);
647
648 const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
649
650 // On ppc64, the entry point is actually a descriptor. Dereference it.
651 if (arch.GetMachine() == llvm::Triple::ppc64)
652 m_entry_point = ReadUnsignedIntWithSizeInBytes(m_entry_point, 8);
653
654 return m_entry_point;
655 }
656
657 lldb::addr_t
GetThreadLocalData(const lldb::ModuleSP module_sp,const lldb::ThreadSP thread,lldb::addr_t tls_file_addr)658 DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp,
659 const lldb::ThreadSP thread,
660 lldb::addr_t tls_file_addr) {
661 auto it = m_loaded_modules.find(module_sp);
662 if (it == m_loaded_modules.end())
663 return LLDB_INVALID_ADDRESS;
664
665 addr_t link_map = it->second;
666 if (link_map == LLDB_INVALID_ADDRESS)
667 return LLDB_INVALID_ADDRESS;
668
669 const DYLDRendezvous::ThreadInfo &metadata = m_rendezvous.GetThreadInfo();
670 if (!metadata.valid)
671 return LLDB_INVALID_ADDRESS;
672
673 // Get the thread pointer.
674 addr_t tp = thread->GetThreadPointer();
675 if (tp == LLDB_INVALID_ADDRESS)
676 return LLDB_INVALID_ADDRESS;
677
678 // Find the module's modid.
679 int modid_size = 4; // FIXME(spucci): This isn't right for big-endian 64-bit
680 int64_t modid = ReadUnsignedIntWithSizeInBytes(
681 link_map + metadata.modid_offset, modid_size);
682 if (modid == -1)
683 return LLDB_INVALID_ADDRESS;
684
685 // Lookup the DTV structure for this thread.
686 addr_t dtv_ptr = tp + metadata.dtv_offset;
687 addr_t dtv = ReadPointer(dtv_ptr);
688 if (dtv == LLDB_INVALID_ADDRESS)
689 return LLDB_INVALID_ADDRESS;
690
691 // Find the TLS block for this module.
692 addr_t dtv_slot = dtv + metadata.dtv_slot_size * modid;
693 addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset);
694
695 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
696 LLDB_LOGF(log,
697 "DynamicLoaderPOSIXDYLD::Performed TLS lookup: "
698 "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
699 ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n",
700 module_sp->GetObjectName().AsCString(""), link_map, tp,
701 (int64_t)modid, tls_block);
702
703 if (tls_block == LLDB_INVALID_ADDRESS)
704 return LLDB_INVALID_ADDRESS;
705 else
706 return tls_block + tls_file_addr;
707 }
708
ResolveExecutableModule(lldb::ModuleSP & module_sp)709 void DynamicLoaderPOSIXDYLD::ResolveExecutableModule(
710 lldb::ModuleSP &module_sp) {
711 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
712
713 if (m_process == nullptr)
714 return;
715
716 auto &target = m_process->GetTarget();
717 const auto platform_sp = target.GetPlatform();
718
719 ProcessInstanceInfo process_info;
720 if (!m_process->GetProcessInfo(process_info)) {
721 LLDB_LOGF(log,
722 "DynamicLoaderPOSIXDYLD::%s - failed to get process info for "
723 "pid %" PRIu64,
724 __FUNCTION__, m_process->GetID());
725 return;
726 }
727
728 LLDB_LOGF(
729 log, "DynamicLoaderPOSIXDYLD::%s - got executable by pid %" PRIu64 ": %s",
730 __FUNCTION__, m_process->GetID(),
731 process_info.GetExecutableFile().GetPath().c_str());
732
733 ModuleSpec module_spec(process_info.GetExecutableFile(),
734 process_info.GetArchitecture());
735 if (module_sp && module_sp->MatchesModuleSpec(module_spec))
736 return;
737
738 const auto executable_search_paths(Target::GetDefaultExecutableSearchPaths());
739 auto error = platform_sp->ResolveExecutable(
740 module_spec, module_sp,
741 !executable_search_paths.IsEmpty() ? &executable_search_paths : nullptr);
742 if (error.Fail()) {
743 StreamString stream;
744 module_spec.Dump(stream);
745
746 LLDB_LOGF(log,
747 "DynamicLoaderPOSIXDYLD::%s - failed to resolve executable "
748 "with module spec \"%s\": %s",
749 __FUNCTION__, stream.GetData(), error.AsCString());
750 return;
751 }
752
753 target.SetExecutableModule(module_sp, eLoadDependentsNo);
754 }
755
AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext & sym_ctx)756 bool DynamicLoaderPOSIXDYLD::AlwaysRelyOnEHUnwindInfo(
757 lldb_private::SymbolContext &sym_ctx) {
758 ModuleSP module_sp;
759 if (sym_ctx.symbol)
760 module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
761 if (!module_sp && sym_ctx.function)
762 module_sp =
763 sym_ctx.function->GetAddressRange().GetBaseAddress().GetModule();
764 if (!module_sp)
765 return false;
766
767 return module_sp->GetFileSpec().GetPath() == "[vdso]";
768 }
769