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