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