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