1 //===-- DynamicLoaderHexagonDYLD.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 #include "lldb/Breakpoint/BreakpointLocation.h" 10 #include "lldb/Core/Module.h" 11 #include "lldb/Core/ModuleSpec.h" 12 #include "lldb/Core/PluginManager.h" 13 #include "lldb/Core/Section.h" 14 #include "lldb/Symbol/ObjectFile.h" 15 #include "lldb/Target/Process.h" 16 #include "lldb/Target/Target.h" 17 #include "lldb/Target/Thread.h" 18 #include "lldb/Target/ThreadPlanRunToAddress.h" 19 #include "lldb/Utility/Log.h" 20 21 #include "DynamicLoaderHexagonDYLD.h" 22 23 #include <memory> 24 25 using namespace lldb; 26 using namespace lldb_private; 27 28 LLDB_PLUGIN_DEFINE(DynamicLoaderHexagonDYLD) 29 30 // Aidan 21/05/2014 31 // 32 // Notes about hexagon dynamic loading: 33 // 34 // When we connect to a target we find the dyld breakpoint address. We put 35 // a 36 // breakpoint there with a callback 'RendezvousBreakpointHit()'. 37 // 38 // It is possible to find the dyld structure address from the ELF symbol 39 // table, 40 // but in the case of the simulator it has not been initialized before the 41 // target calls dlinit(). 42 // 43 // We can only safely parse the dyld structure after we hit the dyld 44 // breakpoint 45 // since at that time we know dlinit() must have been called. 46 // 47 48 // Find the load address of a symbol 49 static lldb::addr_t findSymbolAddress(Process *proc, ConstString findName) { 50 assert(proc != nullptr); 51 52 ModuleSP module = proc->GetTarget().GetExecutableModule(); 53 assert(module.get() != nullptr); 54 55 ObjectFile *exe = module->GetObjectFile(); 56 assert(exe != nullptr); 57 58 lldb_private::Symtab *symtab = exe->GetSymtab(); 59 assert(symtab != nullptr); 60 61 for (size_t i = 0; i < symtab->GetNumSymbols(); i++) { 62 const Symbol *sym = symtab->SymbolAtIndex(i); 63 assert(sym != nullptr); 64 ConstString symName = sym->GetName(); 65 66 if (ConstString::Compare(findName, symName) == 0) { 67 Address addr = sym->GetAddress(); 68 return addr.GetLoadAddress(&proc->GetTarget()); 69 } 70 } 71 return LLDB_INVALID_ADDRESS; 72 } 73 74 void DynamicLoaderHexagonDYLD::Initialize() { 75 PluginManager::RegisterPlugin(GetPluginNameStatic(), 76 GetPluginDescriptionStatic(), CreateInstance); 77 } 78 79 void DynamicLoaderHexagonDYLD::Terminate() {} 80 81 llvm::StringRef DynamicLoaderHexagonDYLD::GetPluginDescriptionStatic() { 82 return "Dynamic loader plug-in that watches for shared library " 83 "loads/unloads in Hexagon processes."; 84 } 85 86 DynamicLoader *DynamicLoaderHexagonDYLD::CreateInstance(Process *process, 87 bool force) { 88 bool create = force; 89 if (!create) { 90 const llvm::Triple &triple_ref = 91 process->GetTarget().GetArchitecture().GetTriple(); 92 if (triple_ref.getArch() == llvm::Triple::hexagon) 93 create = true; 94 } 95 96 if (create) 97 return new DynamicLoaderHexagonDYLD(process); 98 return nullptr; 99 } 100 101 DynamicLoaderHexagonDYLD::DynamicLoaderHexagonDYLD(Process *process) 102 : DynamicLoader(process), m_rendezvous(process), 103 m_load_offset(LLDB_INVALID_ADDRESS), m_entry_point(LLDB_INVALID_ADDRESS), 104 m_dyld_bid(LLDB_INVALID_BREAK_ID) {} 105 106 DynamicLoaderHexagonDYLD::~DynamicLoaderHexagonDYLD() { 107 if (m_dyld_bid != LLDB_INVALID_BREAK_ID) { 108 m_process->GetTarget().RemoveBreakpointByID(m_dyld_bid); 109 m_dyld_bid = LLDB_INVALID_BREAK_ID; 110 } 111 } 112 113 void DynamicLoaderHexagonDYLD::DidAttach() { 114 ModuleSP executable; 115 addr_t load_offset; 116 117 executable = GetTargetExecutable(); 118 119 // Find the difference between the desired load address in the elf file and 120 // the real load address in memory 121 load_offset = ComputeLoadOffset(); 122 123 // Check that there is a valid executable 124 if (executable.get() == nullptr) 125 return; 126 127 // Disable JIT for hexagon targets because its not supported 128 m_process->SetCanJIT(false); 129 130 // Enable Interpreting of function call expressions 131 m_process->SetCanInterpretFunctionCalls(true); 132 133 // Add the current executable to the module list 134 ModuleList module_list; 135 module_list.Append(executable); 136 137 // Map the loaded sections of this executable 138 if (load_offset != LLDB_INVALID_ADDRESS) 139 UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset, true); 140 141 // AD: confirm this? 142 // Load into LLDB all of the currently loaded executables in the stub 143 LoadAllCurrentModules(); 144 145 // AD: confirm this? 146 // Callback for the target to give it the loaded module list 147 m_process->GetTarget().ModulesDidLoad(module_list); 148 149 // Try to set a breakpoint at the rendezvous breakpoint. DidLaunch uses 150 // ProbeEntry() instead. That sets a breakpoint, at the dyld breakpoint 151 // address, with a callback so that when hit, the dyld structure can be 152 // parsed. 153 if (!SetRendezvousBreakpoint()) { 154 // fail 155 } 156 } 157 158 void DynamicLoaderHexagonDYLD::DidLaunch() {} 159 160 /// Checks to see if the target module has changed, updates the target 161 /// accordingly and returns the target executable module. 162 ModuleSP DynamicLoaderHexagonDYLD::GetTargetExecutable() { 163 Target &target = m_process->GetTarget(); 164 ModuleSP executable = target.GetExecutableModule(); 165 166 // There is no executable 167 if (!executable.get()) 168 return executable; 169 170 // The target executable file does not exits 171 if (!FileSystem::Instance().Exists(executable->GetFileSpec())) 172 return executable; 173 174 // Prep module for loading 175 ModuleSpec module_spec(executable->GetFileSpec(), 176 executable->GetArchitecture()); 177 ModuleSP module_sp(new Module(module_spec)); 178 179 // Check if the executable has changed and set it to the target executable if 180 // they differ. 181 if (module_sp.get() && module_sp->GetUUID().IsValid() && 182 executable->GetUUID().IsValid()) { 183 // if the executable has changed ?? 184 if (module_sp->GetUUID() != executable->GetUUID()) 185 executable.reset(); 186 } else if (executable->FileHasChanged()) 187 executable.reset(); 188 189 if (executable.get()) 190 return executable; 191 192 // TODO: What case is this code used? 193 executable = target.GetOrCreateModule(module_spec, true /* notify */); 194 if (executable.get() != target.GetExecutableModulePointer()) { 195 // Don't load dependent images since we are in dyld where we will know and 196 // find out about all images that are loaded 197 target.SetExecutableModule(executable, eLoadDependentsNo); 198 } 199 200 return executable; 201 } 202 203 // AD: Needs to be updated? 204 Status DynamicLoaderHexagonDYLD::CanLoadImage() { return Status(); } 205 206 void DynamicLoaderHexagonDYLD::UpdateLoadedSections(ModuleSP module, 207 addr_t link_map_addr, 208 addr_t base_addr, 209 bool base_addr_is_offset) { 210 Target &target = m_process->GetTarget(); 211 const SectionList *sections = GetSectionListFromModule(module); 212 213 assert(sections && "SectionList missing from loaded module."); 214 215 m_loaded_modules[module] = link_map_addr; 216 217 const size_t num_sections = sections->GetSize(); 218 219 for (unsigned i = 0; i < num_sections; ++i) { 220 SectionSP section_sp(sections->GetSectionAtIndex(i)); 221 lldb::addr_t new_load_addr = section_sp->GetFileAddress() + base_addr; 222 223 // AD: 02/05/14 224 // since our memory map starts from address 0, we must not ignore 225 // sections that load to address 0. This violates the reference 226 // ELF spec, however is used for Hexagon. 227 228 // If the file address of the section is zero then this is not an 229 // allocatable/loadable section (property of ELF sh_addr). Skip it. 230 // if (new_load_addr == base_addr) 231 // continue; 232 233 target.SetSectionLoadAddress(section_sp, new_load_addr); 234 } 235 } 236 237 /// Removes the loaded sections from the target in \p module. 238 /// 239 /// \param module The module to traverse. 240 void DynamicLoaderHexagonDYLD::UnloadSections(const ModuleSP module) { 241 Target &target = m_process->GetTarget(); 242 const SectionList *sections = GetSectionListFromModule(module); 243 244 assert(sections && "SectionList missing from unloaded module."); 245 246 m_loaded_modules.erase(module); 247 248 const size_t num_sections = sections->GetSize(); 249 for (size_t i = 0; i < num_sections; ++i) { 250 SectionSP section_sp(sections->GetSectionAtIndex(i)); 251 target.SetSectionUnloaded(section_sp); 252 } 253 } 254 255 // Place a breakpoint on <_rtld_debug_state> 256 bool DynamicLoaderHexagonDYLD::SetRendezvousBreakpoint() { 257 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); 258 259 // This is the original code, which want to look in the rendezvous structure 260 // to find the breakpoint address. Its backwards for us, since we can easily 261 // find the breakpoint address, since it is exported in our executable. We 262 // however know that we cant read the Rendezvous structure until we have hit 263 // the breakpoint once. 264 const ConstString dyldBpName("_rtld_debug_state"); 265 addr_t break_addr = findSymbolAddress(m_process, dyldBpName); 266 267 Target &target = m_process->GetTarget(); 268 269 // Do not try to set the breakpoint if we don't know where to put it 270 if (break_addr == LLDB_INVALID_ADDRESS) { 271 LLDB_LOGF(log, "Unable to locate _rtld_debug_state breakpoint address"); 272 273 return false; 274 } 275 276 // Save the address of the rendezvous structure 277 m_rendezvous.SetBreakAddress(break_addr); 278 279 // If we haven't set the breakpoint before then set it 280 if (m_dyld_bid == LLDB_INVALID_BREAK_ID) { 281 Breakpoint *dyld_break = 282 target.CreateBreakpoint(break_addr, true, false).get(); 283 dyld_break->SetCallback(RendezvousBreakpointHit, this, true); 284 dyld_break->SetBreakpointKind("shared-library-event"); 285 m_dyld_bid = dyld_break->GetID(); 286 287 // Make sure our breakpoint is at the right address. 288 assert(target.GetBreakpointByID(m_dyld_bid) 289 ->FindLocationByAddress(break_addr) 290 ->GetBreakpoint() 291 .GetID() == m_dyld_bid); 292 293 if (log && dyld_break == nullptr) 294 LLDB_LOGF(log, "Failed to create _rtld_debug_state breakpoint"); 295 296 // check we have successfully set bp 297 return (dyld_break != nullptr); 298 } else 299 // rendezvous already set 300 return true; 301 } 302 303 // We have just hit our breakpoint at <_rtld_debug_state> 304 bool DynamicLoaderHexagonDYLD::RendezvousBreakpointHit( 305 void *baton, StoppointCallbackContext *context, user_id_t break_id, 306 user_id_t break_loc_id) { 307 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); 308 309 LLDB_LOGF(log, "Rendezvous breakpoint hit!"); 310 311 DynamicLoaderHexagonDYLD *dyld_instance = nullptr; 312 dyld_instance = static_cast<DynamicLoaderHexagonDYLD *>(baton); 313 314 // if the dyld_instance is still not valid then try to locate it on the 315 // symbol table 316 if (!dyld_instance->m_rendezvous.IsValid()) { 317 Process *proc = dyld_instance->m_process; 318 319 const ConstString dyldStructName("_rtld_debug"); 320 addr_t structAddr = findSymbolAddress(proc, dyldStructName); 321 322 if (structAddr != LLDB_INVALID_ADDRESS) { 323 dyld_instance->m_rendezvous.SetRendezvousAddress(structAddr); 324 325 LLDB_LOGF(log, "Found _rtld_debug structure @ 0x%08" PRIx64, structAddr); 326 } else { 327 LLDB_LOGF(log, "Unable to resolve the _rtld_debug structure"); 328 } 329 } 330 331 dyld_instance->RefreshModules(); 332 333 // Return true to stop the target, false to just let the target run. 334 return dyld_instance->GetStopWhenImagesChange(); 335 } 336 337 /// Helper method for RendezvousBreakpointHit. Updates LLDB's current set 338 /// of loaded modules. 339 void DynamicLoaderHexagonDYLD::RefreshModules() { 340 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); 341 342 if (!m_rendezvous.Resolve()) 343 return; 344 345 HexagonDYLDRendezvous::iterator I; 346 HexagonDYLDRendezvous::iterator E; 347 348 ModuleList &loaded_modules = m_process->GetTarget().GetImages(); 349 350 if (m_rendezvous.ModulesDidLoad()) { 351 ModuleList new_modules; 352 353 E = m_rendezvous.loaded_end(); 354 for (I = m_rendezvous.loaded_begin(); I != E; ++I) { 355 FileSpec file(I->path); 356 FileSystem::Instance().Resolve(file); 357 ModuleSP module_sp = 358 LoadModuleAtAddress(file, I->link_addr, I->base_addr, true); 359 if (module_sp.get()) { 360 loaded_modules.AppendIfNeeded(module_sp); 361 new_modules.Append(module_sp); 362 } 363 364 if (log) { 365 LLDB_LOGF(log, "Target is loading '%s'", I->path.c_str()); 366 if (!module_sp.get()) 367 LLDB_LOGF(log, "LLDB failed to load '%s'", I->path.c_str()); 368 else 369 LLDB_LOGF(log, "LLDB successfully loaded '%s'", I->path.c_str()); 370 } 371 } 372 m_process->GetTarget().ModulesDidLoad(new_modules); 373 } 374 375 if (m_rendezvous.ModulesDidUnload()) { 376 ModuleList old_modules; 377 378 E = m_rendezvous.unloaded_end(); 379 for (I = m_rendezvous.unloaded_begin(); I != E; ++I) { 380 FileSpec file(I->path); 381 FileSystem::Instance().Resolve(file); 382 ModuleSpec module_spec(file); 383 ModuleSP module_sp = loaded_modules.FindFirstModule(module_spec); 384 385 if (module_sp.get()) { 386 old_modules.Append(module_sp); 387 UnloadSections(module_sp); 388 } 389 390 LLDB_LOGF(log, "Target is unloading '%s'", I->path.c_str()); 391 } 392 loaded_modules.Remove(old_modules); 393 m_process->GetTarget().ModulesDidUnload(old_modules, false); 394 } 395 } 396 397 // AD: This is very different to the Static Loader code. 398 // It may be wise to look over this and its relation to stack 399 // unwinding. 400 ThreadPlanSP 401 DynamicLoaderHexagonDYLD::GetStepThroughTrampolinePlan(Thread &thread, 402 bool stop) { 403 ThreadPlanSP thread_plan_sp; 404 405 StackFrame *frame = thread.GetStackFrameAtIndex(0).get(); 406 const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol); 407 Symbol *sym = context.symbol; 408 409 if (sym == nullptr || !sym->IsTrampoline()) 410 return thread_plan_sp; 411 412 const ConstString sym_name = 413 sym->GetMangled().GetName(Mangled::ePreferMangled); 414 if (!sym_name) 415 return thread_plan_sp; 416 417 SymbolContextList target_symbols; 418 Target &target = thread.GetProcess()->GetTarget(); 419 const ModuleList &images = target.GetImages(); 420 421 images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols); 422 size_t num_targets = target_symbols.GetSize(); 423 if (!num_targets) 424 return thread_plan_sp; 425 426 typedef std::vector<lldb::addr_t> AddressVector; 427 AddressVector addrs; 428 for (size_t i = 0; i < num_targets; ++i) { 429 SymbolContext context; 430 AddressRange range; 431 if (target_symbols.GetContextAtIndex(i, context)) { 432 context.GetAddressRange(eSymbolContextEverything, 0, false, range); 433 lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target); 434 if (addr != LLDB_INVALID_ADDRESS) 435 addrs.push_back(addr); 436 } 437 } 438 439 if (addrs.size() > 0) { 440 AddressVector::iterator start = addrs.begin(); 441 AddressVector::iterator end = addrs.end(); 442 443 llvm::sort(start, end); 444 addrs.erase(std::unique(start, end), end); 445 thread_plan_sp = 446 std::make_shared<ThreadPlanRunToAddress>(thread, addrs, stop); 447 } 448 449 return thread_plan_sp; 450 } 451 452 /// Helper for the entry breakpoint callback. Resolves the load addresses 453 /// of all dependent modules. 454 void DynamicLoaderHexagonDYLD::LoadAllCurrentModules() { 455 HexagonDYLDRendezvous::iterator I; 456 HexagonDYLDRendezvous::iterator E; 457 ModuleList module_list; 458 459 if (!m_rendezvous.Resolve()) { 460 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); 461 LLDB_LOGF( 462 log, 463 "DynamicLoaderHexagonDYLD::%s unable to resolve rendezvous address", 464 __FUNCTION__); 465 return; 466 } 467 468 // The rendezvous class doesn't enumerate the main module, so track that 469 // ourselves here. 470 ModuleSP executable = GetTargetExecutable(); 471 m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress(); 472 473 for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) { 474 const char *module_path = I->path.c_str(); 475 FileSpec file(module_path); 476 ModuleSP module_sp = 477 LoadModuleAtAddress(file, I->link_addr, I->base_addr, true); 478 if (module_sp.get()) { 479 module_list.Append(module_sp); 480 } else { 481 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); 482 LLDB_LOGF(log, 483 "DynamicLoaderHexagonDYLD::%s failed loading module %s at " 484 "0x%" PRIx64, 485 __FUNCTION__, module_path, I->base_addr); 486 } 487 } 488 489 m_process->GetTarget().ModulesDidLoad(module_list); 490 } 491 492 /// Computes a value for m_load_offset returning the computed address on 493 /// success and LLDB_INVALID_ADDRESS on failure. 494 addr_t DynamicLoaderHexagonDYLD::ComputeLoadOffset() { 495 // Here we could send a GDB packet to know the load offset 496 // 497 // send: $qOffsets#4b 498 // get: Text=0;Data=0;Bss=0 499 // 500 // Currently qOffsets is not supported by pluginProcessGDBRemote 501 // 502 return 0; 503 } 504 505 // Here we must try to read the entry point directly from the elf header. This 506 // is possible if the process is not relocatable or dynamically linked. 507 // 508 // an alternative is to look at the PC if we can be sure that we have connected 509 // when the process is at the entry point. 510 // I dont think that is reliable for us. 511 addr_t DynamicLoaderHexagonDYLD::GetEntryPoint() { 512 if (m_entry_point != LLDB_INVALID_ADDRESS) 513 return m_entry_point; 514 // check we have a valid process 515 if (m_process == nullptr) 516 return LLDB_INVALID_ADDRESS; 517 // Get the current executable module 518 Module &module = *(m_process->GetTarget().GetExecutableModule().get()); 519 // Get the object file (elf file) for this module 520 lldb_private::ObjectFile &object = *(module.GetObjectFile()); 521 // Check if the file is executable (ie, not shared object or relocatable) 522 if (object.IsExecutable()) { 523 // Get the entry point address for this object 524 lldb_private::Address entry = object.GetEntryPointAddress(); 525 // Return the entry point address 526 return entry.GetFileAddress(); 527 } 528 // No idea so back out 529 return LLDB_INVALID_ADDRESS; 530 } 531 532 const SectionList *DynamicLoaderHexagonDYLD::GetSectionListFromModule( 533 const ModuleSP module) const { 534 SectionList *sections = nullptr; 535 if (module.get()) { 536 ObjectFile *obj_file = module->GetObjectFile(); 537 if (obj_file) { 538 sections = obj_file->GetSectionList(); 539 } 540 } 541 return sections; 542 } 543 544 static int ReadInt(Process *process, addr_t addr) { 545 Status error; 546 int value = (int)process->ReadUnsignedIntegerFromMemory( 547 addr, sizeof(uint32_t), 0, error); 548 if (error.Fail()) 549 return -1; 550 else 551 return value; 552 } 553 554 lldb::addr_t 555 DynamicLoaderHexagonDYLD::GetThreadLocalData(const lldb::ModuleSP module, 556 const lldb::ThreadSP thread, 557 lldb::addr_t tls_file_addr) { 558 auto it = m_loaded_modules.find(module); 559 if (it == m_loaded_modules.end()) 560 return LLDB_INVALID_ADDRESS; 561 562 addr_t link_map = it->second; 563 if (link_map == LLDB_INVALID_ADDRESS) 564 return LLDB_INVALID_ADDRESS; 565 566 const HexagonDYLDRendezvous::ThreadInfo &metadata = 567 m_rendezvous.GetThreadInfo(); 568 if (!metadata.valid) 569 return LLDB_INVALID_ADDRESS; 570 571 // Get the thread pointer. 572 addr_t tp = thread->GetThreadPointer(); 573 if (tp == LLDB_INVALID_ADDRESS) 574 return LLDB_INVALID_ADDRESS; 575 576 // Find the module's modid. 577 int modid = ReadInt(m_process, link_map + metadata.modid_offset); 578 if (modid == -1) 579 return LLDB_INVALID_ADDRESS; 580 581 // Lookup the DTV structure for this thread. 582 addr_t dtv_ptr = tp + metadata.dtv_offset; 583 addr_t dtv = ReadPointer(dtv_ptr); 584 if (dtv == LLDB_INVALID_ADDRESS) 585 return LLDB_INVALID_ADDRESS; 586 587 // Find the TLS block for this module. 588 addr_t dtv_slot = dtv + metadata.dtv_slot_size * modid; 589 addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset); 590 591 Module *mod = module.get(); 592 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); 593 LLDB_LOGF(log, 594 "DynamicLoaderHexagonDYLD::Performed TLS lookup: " 595 "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64 596 ", modid=%i, tls_block=0x%" PRIx64, 597 mod->GetObjectName().AsCString(""), link_map, tp, modid, tls_block); 598 599 if (tls_block == LLDB_INVALID_ADDRESS) 600 return LLDB_INVALID_ADDRESS; 601 else 602 return tls_block + tls_file_addr; 603 } 604