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