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