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/RegisterContext.h" 22 #include "lldb/Target/Target.h" 23 #include "lldb/Target/Thread.h" 24 #include "lldb/Target/ThreadPlanRunToAddress.h" 25 #include "lldb/Utility/LLDBLog.h" 26 #include "lldb/Utility/Log.h" 27 #include "lldb/Utility/ProcessInfo.h" 28 29 #include <memory> 30 #include <optional> 31 32 using namespace lldb; 33 using namespace lldb_private; 34 35 LLDB_PLUGIN_DEFINE_ADV(DynamicLoaderPOSIXDYLD, DynamicLoaderPosixDYLD) 36 37 void DynamicLoaderPOSIXDYLD::Initialize() { 38 PluginManager::RegisterPlugin(GetPluginNameStatic(), 39 GetPluginDescriptionStatic(), CreateInstance); 40 } 41 42 void DynamicLoaderPOSIXDYLD::Terminate() {} 43 44 llvm::StringRef DynamicLoaderPOSIXDYLD::GetPluginDescriptionStatic() { 45 return "Dynamic loader plug-in that watches for shared library " 46 "loads/unloads in POSIX processes."; 47 } 48 49 DynamicLoader *DynamicLoaderPOSIXDYLD::CreateInstance(Process *process, 50 bool force) { 51 bool create = force; 52 if (!create) { 53 const llvm::Triple &triple_ref = 54 process->GetTarget().GetArchitecture().GetTriple(); 55 if (triple_ref.getOS() == llvm::Triple::FreeBSD || 56 triple_ref.getOS() == llvm::Triple::Linux || 57 triple_ref.getOS() == llvm::Triple::NetBSD || 58 triple_ref.getOS() == llvm::Triple::OpenBSD) 59 create = true; 60 } 61 62 if (create) 63 return new DynamicLoaderPOSIXDYLD(process); 64 return nullptr; 65 } 66 67 DynamicLoaderPOSIXDYLD::DynamicLoaderPOSIXDYLD(Process *process) 68 : DynamicLoader(process), m_rendezvous(process), 69 m_load_offset(LLDB_INVALID_ADDRESS), m_entry_point(LLDB_INVALID_ADDRESS), 70 m_auxv(), m_dyld_bid(LLDB_INVALID_BREAK_ID), 71 m_vdso_base(LLDB_INVALID_ADDRESS), 72 m_interpreter_base(LLDB_INVALID_ADDRESS), m_initial_modules_added(false) { 73 } 74 75 DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD() { 76 if (m_dyld_bid != LLDB_INVALID_BREAK_ID) { 77 m_process->GetTarget().RemoveBreakpointByID(m_dyld_bid); 78 m_dyld_bid = LLDB_INVALID_BREAK_ID; 79 } 80 } 81 82 void DynamicLoaderPOSIXDYLD::DidAttach() { 83 Log *log = GetLog(LLDBLog::DynamicLoader); 84 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64, __FUNCTION__, 85 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); 86 m_auxv = std::make_unique<AuxVector>(m_process->GetAuxvData()); 87 88 LLDB_LOGF( 89 log, "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reloaded auxv data", 90 __FUNCTION__, m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); 91 92 ModuleSP executable_sp = GetTargetExecutable(); 93 ResolveExecutableModule(executable_sp); 94 m_rendezvous.UpdateExecutablePath(); 95 96 // find the main process load offset 97 addr_t load_offset = ComputeLoadOffset(); 98 LLDB_LOGF(log, 99 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 100 " executable '%s', load_offset 0x%" PRIx64, 101 __FUNCTION__, 102 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, 103 executable_sp ? executable_sp->GetFileSpec().GetPath().c_str() 104 : "<null executable>", 105 load_offset); 106 107 EvalSpecialModulesStatus(); 108 109 // if we dont have a load address we cant re-base 110 bool rebase_exec = load_offset != LLDB_INVALID_ADDRESS; 111 112 // if the target executable should be re-based 113 if (rebase_exec) { 114 ModuleList module_list; 115 116 module_list.Append(executable_sp); 117 LLDB_LOGF(log, 118 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 119 " added executable '%s' to module load list", 120 __FUNCTION__, 121 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, 122 executable_sp->GetFileSpec().GetPath().c_str()); 123 124 UpdateLoadedSections(executable_sp, LLDB_INVALID_ADDRESS, load_offset, 125 true); 126 127 LoadAllCurrentModules(); 128 129 m_process->GetTarget().ModulesDidLoad(module_list); 130 if (log) { 131 LLDB_LOGF(log, 132 "DynamicLoaderPOSIXDYLD::%s told the target about the " 133 "modules that loaded:", 134 __FUNCTION__); 135 for (auto module_sp : module_list.Modules()) { 136 LLDB_LOGF(log, "-- [module] %s (pid %" PRIu64 ")", 137 module_sp ? module_sp->GetFileSpec().GetPath().c_str() 138 : "<null>", 139 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); 140 } 141 } 142 } 143 144 if (executable_sp.get()) { 145 if (!SetRendezvousBreakpoint()) { 146 // If we cannot establish rendezvous breakpoint right now we'll try again 147 // at entry point. 148 ProbeEntry(); 149 } 150 } 151 } 152 153 void DynamicLoaderPOSIXDYLD::DidLaunch() { 154 Log *log = GetLog(LLDBLog::DynamicLoader); 155 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s()", __FUNCTION__); 156 157 ModuleSP executable; 158 addr_t load_offset; 159 160 m_auxv = std::make_unique<AuxVector>(m_process->GetAuxvData()); 161 162 executable = GetTargetExecutable(); 163 load_offset = ComputeLoadOffset(); 164 EvalSpecialModulesStatus(); 165 166 if (executable.get() && load_offset != LLDB_INVALID_ADDRESS) { 167 ModuleList module_list; 168 module_list.Append(executable); 169 UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset, true); 170 171 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()", 172 __FUNCTION__); 173 174 if (!SetRendezvousBreakpoint()) { 175 // If we cannot establish rendezvous breakpoint right now we'll try again 176 // at entry point. 177 ProbeEntry(); 178 } 179 180 LoadVDSO(); 181 m_process->GetTarget().ModulesDidLoad(module_list); 182 } 183 } 184 185 Status DynamicLoaderPOSIXDYLD::CanLoadImage() { return Status(); } 186 187 void DynamicLoaderPOSIXDYLD::UpdateLoadedSections(ModuleSP module, 188 addr_t link_map_addr, 189 addr_t base_addr, 190 bool base_addr_is_offset) { 191 m_loaded_modules[module] = link_map_addr; 192 UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset); 193 } 194 195 void DynamicLoaderPOSIXDYLD::UnloadSections(const ModuleSP module) { 196 m_loaded_modules.erase(module); 197 198 UnloadSectionsCommon(module); 199 } 200 201 void DynamicLoaderPOSIXDYLD::ProbeEntry() { 202 Log *log = GetLog(LLDBLog::DynamicLoader); 203 204 // If we have a core file, we don't need any breakpoints. 205 if (IsCoreFile()) 206 return; 207 208 const addr_t entry = GetEntryPoint(); 209 if (entry == LLDB_INVALID_ADDRESS) { 210 LLDB_LOGF( 211 log, 212 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 213 " GetEntryPoint() returned no address, not setting entry breakpoint", 214 __FUNCTION__, m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); 215 return; 216 } 217 218 LLDB_LOGF(log, 219 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 220 " GetEntryPoint() returned address 0x%" PRIx64 221 ", setting entry breakpoint", 222 __FUNCTION__, 223 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, entry); 224 225 if (m_process) { 226 Breakpoint *const entry_break = 227 m_process->GetTarget().CreateBreakpoint(entry, true, false).get(); 228 entry_break->SetCallback(EntryBreakpointHit, this, true); 229 entry_break->SetBreakpointKind("shared-library-event"); 230 231 // Shoudn't hit this more than once. 232 entry_break->SetOneShot(true); 233 } 234 } 235 236 // The runtime linker has run and initialized the rendezvous structure once the 237 // process has hit its entry point. When we hit the corresponding breakpoint 238 // we interrogate the rendezvous structure to get the load addresses of all 239 // dependent modules for the process. Similarly, we can discover the runtime 240 // linker function and setup a breakpoint to notify us of any dynamically 241 // loaded modules (via dlopen). 242 bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit( 243 void *baton, StoppointCallbackContext *context, user_id_t break_id, 244 user_id_t break_loc_id) { 245 assert(baton && "null baton"); 246 if (!baton) 247 return false; 248 249 Log *log = GetLog(LLDBLog::DynamicLoader); 250 DynamicLoaderPOSIXDYLD *const dyld_instance = 251 static_cast<DynamicLoaderPOSIXDYLD *>(baton); 252 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64, 253 __FUNCTION__, 254 dyld_instance->m_process ? dyld_instance->m_process->GetID() 255 : LLDB_INVALID_PROCESS_ID); 256 257 // Disable the breakpoint --- if a stop happens right after this, which we've 258 // seen on occasion, we don't want the breakpoint stepping thread-plan logic 259 // to show a breakpoint instruction at the disassembled entry point to the 260 // program. Disabling it prevents it. (One-shot is not enough - one-shot 261 // removal logic only happens after the breakpoint goes public, which wasn't 262 // happening in our scenario). 263 if (dyld_instance->m_process) { 264 BreakpointSP breakpoint_sp = 265 dyld_instance->m_process->GetTarget().GetBreakpointByID(break_id); 266 if (breakpoint_sp) { 267 LLDB_LOGF(log, 268 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 269 " disabling breakpoint id %" PRIu64, 270 __FUNCTION__, dyld_instance->m_process->GetID(), break_id); 271 breakpoint_sp->SetEnabled(false); 272 } else { 273 LLDB_LOGF(log, 274 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 275 " failed to find breakpoint for breakpoint id %" PRIu64, 276 __FUNCTION__, dyld_instance->m_process->GetID(), break_id); 277 } 278 } else { 279 LLDB_LOGF(log, 280 "DynamicLoaderPOSIXDYLD::%s breakpoint id %" PRIu64 281 " no Process instance! Cannot disable breakpoint", 282 __FUNCTION__, break_id); 283 } 284 285 dyld_instance->LoadAllCurrentModules(); 286 dyld_instance->SetRendezvousBreakpoint(); 287 return false; // Continue running. 288 } 289 290 bool DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() { 291 Log *log = GetLog(LLDBLog::DynamicLoader); 292 293 // If we have a core file, we don't need any breakpoints. 294 if (IsCoreFile()) 295 return false; 296 297 if (m_dyld_bid != LLDB_INVALID_BREAK_ID) { 298 LLDB_LOG(log, 299 "Rendezvous breakpoint breakpoint id {0} for pid {1}" 300 "is already set.", 301 m_dyld_bid, 302 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); 303 return true; 304 } 305 306 addr_t break_addr; 307 Target &target = m_process->GetTarget(); 308 BreakpointSP dyld_break; 309 if (m_rendezvous.IsValid() && m_rendezvous.GetBreakAddress() != 0) { 310 break_addr = m_rendezvous.GetBreakAddress(); 311 LLDB_LOG(log, "Setting rendezvous break address for pid {0} at {1:x}", 312 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, 313 break_addr); 314 dyld_break = target.CreateBreakpoint(break_addr, true, false); 315 } else { 316 LLDB_LOG(log, "Rendezvous structure is not set up yet. " 317 "Trying to locate rendezvous breakpoint in the interpreter " 318 "by symbol name."); 319 // Function names from different dynamic loaders that are known to be 320 // used as rendezvous between the loader and debuggers. 321 static std::vector<std::string> DebugStateCandidates{ 322 "_dl_debug_state", "rtld_db_dlactivity", "__dl_rtld_db_dlactivity", 323 "r_debug_state", "_r_debug_state", "_rtld_debug_state", 324 }; 325 326 ModuleSP interpreter = LoadInterpreterModule(); 327 FileSpecList containingModules; 328 if (interpreter) 329 containingModules.Append(interpreter->GetFileSpec()); 330 else 331 containingModules.Append( 332 m_process->GetTarget().GetExecutableModulePointer()->GetFileSpec()); 333 334 dyld_break = target.CreateBreakpoint( 335 &containingModules, /*containingSourceFiles=*/nullptr, 336 DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC, 337 /*m_offset=*/0, 338 /*skip_prologue=*/eLazyBoolNo, 339 /*internal=*/true, 340 /*request_hardware=*/false); 341 } 342 343 if (dyld_break->GetNumResolvedLocations() != 1) { 344 LLDB_LOG( 345 log, 346 "Rendezvous breakpoint has abnormal number of" 347 " resolved locations ({0}) in pid {1}. It's supposed to be exactly 1.", 348 dyld_break->GetNumResolvedLocations(), 349 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); 350 351 target.RemoveBreakpointByID(dyld_break->GetID()); 352 return false; 353 } 354 355 BreakpointLocationSP location = dyld_break->GetLocationAtIndex(0); 356 LLDB_LOG(log, 357 "Successfully set rendezvous breakpoint at address {0:x} " 358 "for pid {1}", 359 location->GetLoadAddress(), 360 m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); 361 362 dyld_break->SetCallback(RendezvousBreakpointHit, this, true); 363 dyld_break->SetBreakpointKind("shared-library-event"); 364 m_dyld_bid = dyld_break->GetID(); 365 return true; 366 } 367 368 bool DynamicLoaderPOSIXDYLD::RendezvousBreakpointHit( 369 void *baton, StoppointCallbackContext *context, user_id_t break_id, 370 user_id_t break_loc_id) { 371 assert(baton && "null baton"); 372 if (!baton) 373 return false; 374 375 Log *log = GetLog(LLDBLog::DynamicLoader); 376 DynamicLoaderPOSIXDYLD *const dyld_instance = 377 static_cast<DynamicLoaderPOSIXDYLD *>(baton); 378 LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64, 379 __FUNCTION__, 380 dyld_instance->m_process ? dyld_instance->m_process->GetID() 381 : LLDB_INVALID_PROCESS_ID); 382 383 dyld_instance->RefreshModules(); 384 385 // Return true to stop the target, false to just let the target run. 386 const bool stop_when_images_change = dyld_instance->GetStopWhenImagesChange(); 387 LLDB_LOGF(log, 388 "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 389 " stop_when_images_change=%s", 390 __FUNCTION__, 391 dyld_instance->m_process ? dyld_instance->m_process->GetID() 392 : LLDB_INVALID_PROCESS_ID, 393 stop_when_images_change ? "true" : "false"); 394 return stop_when_images_change; 395 } 396 397 void DynamicLoaderPOSIXDYLD::RefreshModules() { 398 if (!m_rendezvous.Resolve()) 399 return; 400 401 // The rendezvous class doesn't enumerate the main module, so track that 402 // ourselves here. 403 ModuleSP executable = GetTargetExecutable(); 404 m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress(); 405 406 DYLDRendezvous::iterator I; 407 DYLDRendezvous::iterator E; 408 409 ModuleList &loaded_modules = m_process->GetTarget().GetImages(); 410 411 if (m_rendezvous.ModulesDidLoad() || !m_initial_modules_added) { 412 ModuleList new_modules; 413 414 // If this is the first time rendezvous breakpoint fires, we need 415 // to take care of adding all the initial modules reported by 416 // the loader. This is necessary to list ld-linux.so on Linux, 417 // and all DT_NEEDED entries on *BSD. 418 if (m_initial_modules_added) { 419 I = m_rendezvous.loaded_begin(); 420 E = m_rendezvous.loaded_end(); 421 } else { 422 I = m_rendezvous.begin(); 423 E = m_rendezvous.end(); 424 m_initial_modules_added = true; 425 } 426 for (; I != E; ++I) { 427 // Don't load a duplicate copy of ld.so if we have already loaded it 428 // earlier in LoadInterpreterModule. If we instead loaded then unloaded it 429 // later, the section information for ld.so would be removed. That 430 // information is required for placing breakpoints on Arm/Thumb systems. 431 if ((m_interpreter_module.lock() != nullptr) && 432 (I->base_addr == m_interpreter_base)) 433 continue; 434 435 ModuleSP module_sp = 436 LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true); 437 if (!module_sp.get()) 438 continue; 439 440 if (module_sp->GetObjectFile()->GetBaseAddress().GetLoadAddress( 441 &m_process->GetTarget()) == m_interpreter_base) { 442 ModuleSP interpreter_sp = m_interpreter_module.lock(); 443 if (m_interpreter_module.lock() == nullptr) { 444 m_interpreter_module = module_sp; 445 } else if (module_sp == interpreter_sp) { 446 // Module already loaded. 447 continue; 448 } 449 } 450 451 loaded_modules.AppendIfNeeded(module_sp); 452 new_modules.Append(module_sp); 453 } 454 m_process->GetTarget().ModulesDidLoad(new_modules); 455 } 456 457 if (m_rendezvous.ModulesDidUnload()) { 458 ModuleList old_modules; 459 460 E = m_rendezvous.unloaded_end(); 461 for (I = m_rendezvous.unloaded_begin(); I != E; ++I) { 462 ModuleSpec module_spec{I->file_spec}; 463 ModuleSP module_sp = loaded_modules.FindFirstModule(module_spec); 464 465 if (module_sp.get()) { 466 old_modules.Append(module_sp); 467 UnloadSections(module_sp); 468 } 469 } 470 loaded_modules.Remove(old_modules); 471 m_process->GetTarget().ModulesDidUnload(old_modules, false); 472 } 473 } 474 475 ThreadPlanSP 476 DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread, 477 bool stop) { 478 ThreadPlanSP thread_plan_sp; 479 480 StackFrame *frame = thread.GetStackFrameAtIndex(0).get(); 481 const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol); 482 Symbol *sym = context.symbol; 483 484 if (sym == nullptr || !sym->IsTrampoline()) 485 return thread_plan_sp; 486 487 ConstString sym_name = sym->GetMangled().GetName(Mangled::ePreferMangled); 488 if (!sym_name) 489 return thread_plan_sp; 490 491 SymbolContextList target_symbols; 492 Target &target = thread.GetProcess()->GetTarget(); 493 const ModuleList &images = target.GetImages(); 494 495 llvm::StringRef target_name = sym_name.GetStringRef(); 496 // On AArch64, the trampoline name has a prefix (__AArch64ADRPThunk_ or 497 // __AArch64AbsLongThunk_) added to the function name. If we detect a 498 // trampoline with the prefix, we need to remove the prefix to find the 499 // function symbol. 500 if (target_name.consume_front("__AArch64ADRPThunk_") || 501 target_name.consume_front("__AArch64AbsLongThunk_")) { 502 // An empty target name can happen for trampolines generated for 503 // section-referencing relocations. 504 if (!target_name.empty()) { 505 sym_name = ConstString(target_name); 506 } 507 } 508 images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols); 509 if (!target_symbols.GetSize()) 510 return thread_plan_sp; 511 512 typedef std::vector<lldb::addr_t> AddressVector; 513 AddressVector addrs; 514 for (const SymbolContext &context : target_symbols) { 515 AddressRange range; 516 context.GetAddressRange(eSymbolContextEverything, 0, false, range); 517 lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target); 518 if (addr != LLDB_INVALID_ADDRESS) 519 addrs.push_back(addr); 520 } 521 522 if (addrs.size() > 0) { 523 AddressVector::iterator start = addrs.begin(); 524 AddressVector::iterator end = addrs.end(); 525 526 llvm::sort(start, end); 527 addrs.erase(std::unique(start, end), end); 528 thread_plan_sp = 529 std::make_shared<ThreadPlanRunToAddress>(thread, addrs, stop); 530 } 531 532 return thread_plan_sp; 533 } 534 535 void DynamicLoaderPOSIXDYLD::LoadVDSO() { 536 if (m_vdso_base == LLDB_INVALID_ADDRESS) 537 return; 538 539 FileSpec file("[vdso]"); 540 541 MemoryRegionInfo info; 542 Status status = m_process->GetMemoryRegionInfo(m_vdso_base, info); 543 if (status.Fail()) { 544 Log *log = GetLog(LLDBLog::DynamicLoader); 545 LLDB_LOG(log, "Failed to get vdso region info: {0}", status); 546 return; 547 } 548 549 if (ModuleSP module_sp = m_process->ReadModuleFromMemory( 550 file, m_vdso_base, info.GetRange().GetByteSize())) { 551 UpdateLoadedSections(module_sp, LLDB_INVALID_ADDRESS, m_vdso_base, false); 552 m_process->GetTarget().GetImages().AppendIfNeeded(module_sp); 553 } 554 } 555 556 ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() { 557 if (m_interpreter_base == LLDB_INVALID_ADDRESS) 558 return nullptr; 559 560 MemoryRegionInfo info; 561 Target &target = m_process->GetTarget(); 562 Status status = m_process->GetMemoryRegionInfo(m_interpreter_base, info); 563 if (status.Fail() || info.GetMapped() != MemoryRegionInfo::eYes || 564 info.GetName().IsEmpty()) { 565 Log *log = GetLog(LLDBLog::DynamicLoader); 566 LLDB_LOG(log, "Failed to get interpreter region info: {0}", status); 567 return nullptr; 568 } 569 570 FileSpec file(info.GetName().GetCString()); 571 ModuleSpec module_spec(file, target.GetArchitecture()); 572 573 // Don't notify that module is added here because its loading section 574 // addresses are not updated yet. We manually notify it below. 575 if (ModuleSP module_sp = 576 target.GetOrCreateModule(module_spec, /*notify=*/false)) { 577 UpdateLoadedSections(module_sp, LLDB_INVALID_ADDRESS, m_interpreter_base, 578 false); 579 // Manually notify that dynamic linker is loaded after updating load section 580 // addersses so that breakpoints can be resolved. 581 ModuleList module_list; 582 module_list.Append(module_sp); 583 target.ModulesDidLoad(module_list); 584 m_interpreter_module = module_sp; 585 return module_sp; 586 } 587 return nullptr; 588 } 589 590 ModuleSP DynamicLoaderPOSIXDYLD::LoadModuleAtAddress(const FileSpec &file, 591 addr_t link_map_addr, 592 addr_t base_addr, 593 bool base_addr_is_offset) { 594 if (ModuleSP module_sp = DynamicLoader::LoadModuleAtAddress( 595 file, link_map_addr, base_addr, base_addr_is_offset)) 596 return module_sp; 597 598 // This works around an dynamic linker "bug" on android <= 23, where the 599 // dynamic linker would report the application name 600 // (e.g. com.example.myapplication) instead of the main process binary 601 // (/system/bin/app_process(32)). The logic is not sound in general (it 602 // assumes base_addr is the real address, even though it actually is a load 603 // bias), but it happens to work on android because app_process has a file 604 // address of zero. 605 // This should be removed after we drop support for android-23. 606 if (m_process->GetTarget().GetArchitecture().GetTriple().isAndroid()) { 607 MemoryRegionInfo memory_info; 608 Status error = m_process->GetMemoryRegionInfo(base_addr, memory_info); 609 if (error.Success() && memory_info.GetMapped() && 610 memory_info.GetRange().GetRangeBase() == base_addr && 611 !(memory_info.GetName().IsEmpty())) { 612 if (ModuleSP module_sp = DynamicLoader::LoadModuleAtAddress( 613 FileSpec(memory_info.GetName().GetStringRef()), link_map_addr, 614 base_addr, base_addr_is_offset)) 615 return module_sp; 616 } 617 } 618 619 return nullptr; 620 } 621 622 void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() { 623 DYLDRendezvous::iterator I; 624 DYLDRendezvous::iterator E; 625 ModuleList module_list; 626 Log *log = GetLog(LLDBLog::DynamicLoader); 627 628 LoadVDSO(); 629 630 if (!m_rendezvous.Resolve()) { 631 LLDB_LOGF(log, 632 "DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD " 633 "rendezvous address", 634 __FUNCTION__); 635 return; 636 } 637 638 // The rendezvous class doesn't enumerate the main module, so track that 639 // ourselves here. 640 ModuleSP executable = GetTargetExecutable(); 641 m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress(); 642 643 std::vector<FileSpec> module_names; 644 for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) 645 module_names.push_back(I->file_spec); 646 m_process->PrefetchModuleSpecs( 647 module_names, m_process->GetTarget().GetArchitecture().GetTriple()); 648 649 for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) { 650 ModuleSP module_sp = 651 LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true); 652 if (module_sp.get()) { 653 LLDB_LOG(log, "LoadAllCurrentModules loading module: {0}", 654 I->file_spec.GetFilename()); 655 module_list.Append(module_sp); 656 } else { 657 Log *log = GetLog(LLDBLog::DynamicLoader); 658 LLDB_LOGF( 659 log, 660 "DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64, 661 __FUNCTION__, I->file_spec.GetPath().c_str(), I->base_addr); 662 } 663 } 664 665 m_process->GetTarget().ModulesDidLoad(module_list); 666 m_initial_modules_added = true; 667 } 668 669 addr_t DynamicLoaderPOSIXDYLD::ComputeLoadOffset() { 670 addr_t virt_entry; 671 672 if (m_load_offset != LLDB_INVALID_ADDRESS) 673 return m_load_offset; 674 675 if ((virt_entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS) 676 return LLDB_INVALID_ADDRESS; 677 678 ModuleSP module = m_process->GetTarget().GetExecutableModule(); 679 if (!module) 680 return LLDB_INVALID_ADDRESS; 681 682 ObjectFile *exe = module->GetObjectFile(); 683 if (!exe) 684 return LLDB_INVALID_ADDRESS; 685 686 Address file_entry = exe->GetEntryPointAddress(); 687 688 if (!file_entry.IsValid()) 689 return LLDB_INVALID_ADDRESS; 690 691 m_load_offset = virt_entry - file_entry.GetFileAddress(); 692 return m_load_offset; 693 } 694 695 void DynamicLoaderPOSIXDYLD::EvalSpecialModulesStatus() { 696 if (std::optional<uint64_t> vdso_base = 697 m_auxv->GetAuxValue(AuxVector::AUXV_AT_SYSINFO_EHDR)) 698 m_vdso_base = *vdso_base; 699 700 if (std::optional<uint64_t> interpreter_base = 701 m_auxv->GetAuxValue(AuxVector::AUXV_AT_BASE)) 702 m_interpreter_base = *interpreter_base; 703 } 704 705 addr_t DynamicLoaderPOSIXDYLD::GetEntryPoint() { 706 if (m_entry_point != LLDB_INVALID_ADDRESS) 707 return m_entry_point; 708 709 if (m_auxv == nullptr) 710 return LLDB_INVALID_ADDRESS; 711 712 std::optional<uint64_t> entry_point = 713 m_auxv->GetAuxValue(AuxVector::AUXV_AT_ENTRY); 714 if (!entry_point) 715 return LLDB_INVALID_ADDRESS; 716 717 m_entry_point = static_cast<addr_t>(*entry_point); 718 719 const ArchSpec &arch = m_process->GetTarget().GetArchitecture(); 720 721 // On ppc64, the entry point is actually a descriptor. Dereference it. 722 if (arch.GetMachine() == llvm::Triple::ppc64) 723 m_entry_point = ReadUnsignedIntWithSizeInBytes(m_entry_point, 8); 724 725 return m_entry_point; 726 } 727 728 lldb::addr_t 729 DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp, 730 const lldb::ThreadSP thread, 731 lldb::addr_t tls_file_addr) { 732 Log *log = GetLog(LLDBLog::DynamicLoader); 733 auto it = m_loaded_modules.find(module_sp); 734 if (it == m_loaded_modules.end()) { 735 LLDB_LOGF( 736 log, "GetThreadLocalData error: module(%s) not found in loaded modules", 737 module_sp->GetObjectName().AsCString()); 738 return LLDB_INVALID_ADDRESS; 739 } 740 741 addr_t link_map = it->second; 742 if (link_map == LLDB_INVALID_ADDRESS || link_map == 0) { 743 LLDB_LOGF(log, 744 "GetThreadLocalData error: invalid link map address=0x%" PRIx64, 745 link_map); 746 return LLDB_INVALID_ADDRESS; 747 } 748 749 const DYLDRendezvous::ThreadInfo &metadata = m_rendezvous.GetThreadInfo(); 750 if (!metadata.valid) { 751 LLDB_LOGF(log, 752 "GetThreadLocalData error: fail to read thread info metadata"); 753 return LLDB_INVALID_ADDRESS; 754 } 755 756 LLDB_LOGF(log, 757 "GetThreadLocalData info: link_map=0x%" PRIx64 758 ", thread info metadata: " 759 "modid_offset=0x%" PRIx32 ", dtv_offset=0x%" PRIx32 760 ", tls_offset=0x%" PRIx32 ", dtv_slot_size=%" PRIx32 "\n", 761 link_map, metadata.modid_offset, metadata.dtv_offset, 762 metadata.tls_offset, metadata.dtv_slot_size); 763 764 // Get the thread pointer. 765 addr_t tp = thread->GetThreadPointer(); 766 if (tp == LLDB_INVALID_ADDRESS) { 767 LLDB_LOGF(log, "GetThreadLocalData error: fail to read thread pointer"); 768 return LLDB_INVALID_ADDRESS; 769 } 770 771 // Find the module's modid. 772 int modid_size = 4; // FIXME(spucci): This isn't right for big-endian 64-bit 773 int64_t modid = ReadUnsignedIntWithSizeInBytes( 774 link_map + metadata.modid_offset, modid_size); 775 if (modid == -1) { 776 LLDB_LOGF(log, "GetThreadLocalData error: fail to read modid"); 777 return LLDB_INVALID_ADDRESS; 778 } 779 780 // Lookup the DTV structure for this thread. 781 addr_t dtv_ptr = tp + metadata.dtv_offset; 782 addr_t dtv = ReadPointer(dtv_ptr); 783 if (dtv == LLDB_INVALID_ADDRESS) { 784 LLDB_LOGF(log, "GetThreadLocalData error: fail to read dtv"); 785 return LLDB_INVALID_ADDRESS; 786 } 787 788 // Find the TLS block for this module. 789 addr_t dtv_slot = dtv + metadata.dtv_slot_size * modid; 790 addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset); 791 792 LLDB_LOGF(log, 793 "DynamicLoaderPOSIXDYLD::Performed TLS lookup: " 794 "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64 795 ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n", 796 module_sp->GetObjectName().AsCString(""), link_map, tp, 797 (int64_t)modid, tls_block); 798 799 if (tls_block == LLDB_INVALID_ADDRESS) { 800 LLDB_LOGF(log, "GetThreadLocalData error: fail to read tls_block"); 801 return LLDB_INVALID_ADDRESS; 802 } else 803 return tls_block + tls_file_addr; 804 } 805 806 void DynamicLoaderPOSIXDYLD::ResolveExecutableModule( 807 lldb::ModuleSP &module_sp) { 808 Log *log = GetLog(LLDBLog::DynamicLoader); 809 810 if (m_process == nullptr) 811 return; 812 813 auto &target = m_process->GetTarget(); 814 const auto platform_sp = target.GetPlatform(); 815 816 ProcessInstanceInfo process_info; 817 if (!m_process->GetProcessInfo(process_info)) { 818 LLDB_LOGF(log, 819 "DynamicLoaderPOSIXDYLD::%s - failed to get process info for " 820 "pid %" PRIu64, 821 __FUNCTION__, m_process->GetID()); 822 return; 823 } 824 825 LLDB_LOGF( 826 log, "DynamicLoaderPOSIXDYLD::%s - got executable by pid %" PRIu64 ": %s", 827 __FUNCTION__, m_process->GetID(), 828 process_info.GetExecutableFile().GetPath().c_str()); 829 830 ModuleSpec module_spec(process_info.GetExecutableFile(), 831 process_info.GetArchitecture()); 832 if (module_sp && module_sp->MatchesModuleSpec(module_spec)) 833 return; 834 835 const auto executable_search_paths(Target::GetDefaultExecutableSearchPaths()); 836 auto error = platform_sp->ResolveExecutable( 837 module_spec, module_sp, 838 !executable_search_paths.IsEmpty() ? &executable_search_paths : nullptr); 839 if (error.Fail()) { 840 StreamString stream; 841 module_spec.Dump(stream); 842 843 LLDB_LOGF(log, 844 "DynamicLoaderPOSIXDYLD::%s - failed to resolve executable " 845 "with module spec \"%s\": %s", 846 __FUNCTION__, stream.GetData(), error.AsCString()); 847 return; 848 } 849 850 target.SetExecutableModule(module_sp, eLoadDependentsNo); 851 } 852 853 bool DynamicLoaderPOSIXDYLD::AlwaysRelyOnEHUnwindInfo( 854 lldb_private::SymbolContext &sym_ctx) { 855 ModuleSP module_sp; 856 if (sym_ctx.symbol) 857 module_sp = sym_ctx.symbol->GetAddressRef().GetModule(); 858 if (!module_sp && sym_ctx.function) 859 module_sp = sym_ctx.function->GetAddress().GetModule(); 860 if (!module_sp) 861 return false; 862 863 return module_sp->GetFileSpec().GetPath() == "[vdso]"; 864 } 865 866 bool DynamicLoaderPOSIXDYLD::IsCoreFile() const { 867 return !m_process->IsLiveDebugSession(); 868 } 869 870 // For our ELF/POSIX builds save off the fs_base/gs_base regions 871 static void AddThreadLocalMemoryRegions(Process &process, ThreadSP &thread_sp, 872 std::vector<MemoryRegionInfo> &ranges) { 873 lldb::RegisterContextSP reg_ctx = thread_sp->GetRegisterContext(); 874 if (!reg_ctx) 875 return; 876 877 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo( 878 lldb::RegisterKind::eRegisterKindGeneric, LLDB_REGNUM_GENERIC_TP); 879 if (!reg_info) 880 return; 881 882 lldb_private::RegisterValue thread_local_register_value; 883 bool success = reg_ctx->ReadRegister(reg_info, thread_local_register_value); 884 if (!success) 885 return; 886 887 const uint64_t fail_value = UINT64_MAX; 888 bool readSuccess = false; 889 const lldb::addr_t reg_value_addr = 890 thread_local_register_value.GetAsUInt64(fail_value, &readSuccess); 891 if (!readSuccess || reg_value_addr == fail_value) 892 return; 893 894 MemoryRegionInfo thread_local_region; 895 Status err = process.GetMemoryRegionInfo(reg_value_addr, thread_local_region); 896 if (err.Fail()) 897 return; 898 899 ranges.push_back(thread_local_region); 900 } 901 902 // Save off the link map for core files. 903 static void AddLinkMapSections(Process &process, 904 std::vector<MemoryRegionInfo> &ranges) { 905 ModuleList &module_list = process.GetTarget().GetImages(); 906 Target *target = &process.GetTarget(); 907 for (size_t idx = 0; idx < module_list.GetSize(); idx++) { 908 ModuleSP module_sp = module_list.GetModuleAtIndex(idx); 909 if (!module_sp) 910 continue; 911 912 ObjectFile *obj = module_sp->GetObjectFile(); 913 if (!obj) 914 continue; 915 Address addr = obj->GetImageInfoAddress(target); 916 addr_t load_addr = addr.GetLoadAddress(target); 917 if (load_addr == LLDB_INVALID_ADDRESS) 918 continue; 919 920 MemoryRegionInfo link_map_section; 921 Status err = process.GetMemoryRegionInfo(load_addr, link_map_section); 922 if (err.Fail()) 923 continue; 924 925 ranges.push_back(link_map_section); 926 } 927 } 928 929 void DynamicLoaderPOSIXDYLD::CalculateDynamicSaveCoreRanges( 930 lldb_private::Process &process, 931 std::vector<lldb_private::MemoryRegionInfo> &ranges, 932 llvm::function_ref<bool(const lldb_private::Thread &)> 933 save_thread_predicate) { 934 ThreadList &thread_list = process.GetThreadList(); 935 for (size_t idx = 0; idx < thread_list.GetSize(); idx++) { 936 ThreadSP thread_sp = thread_list.GetThreadAtIndex(idx); 937 if (!thread_sp) 938 continue; 939 940 if (!save_thread_predicate(*thread_sp)) 941 continue; 942 943 AddThreadLocalMemoryRegions(process, thread_sp, ranges); 944 } 945 946 AddLinkMapSections(process, ranges); 947 } 948