Author: tberghammer Date: Mon Aug 24 05:21:55 2015 New Revision: 245834 URL: http://llvm.org/viewvc/llvm-project?rev=245834&view=rev Log: Add absolute load address support for the DynamicLoader plugins
The POSIX linker generally reports the load bias for the loaded libraries but in some case it is useful to handle a library based on absolute load address. Example usecases: * Windows linker uses absolute addresses * Library list came from different source (e.g. /proc/<pid>/maps) Differential revision: http://reviews.llvm.org/D12233 Modified: lldb/trunk/include/lldb/Target/DynamicLoader.h lldb/trunk/source/Core/DynamicLoader.cpp lldb/trunk/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp lldb/trunk/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Modified: lldb/trunk/include/lldb/Target/DynamicLoader.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/DynamicLoader.h?rev=245834&r1=245833&r2=245834&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/DynamicLoader.h (original) +++ lldb/trunk/include/lldb/Target/DynamicLoader.h Mon Aug 24 05:21:55 2015 @@ -263,12 +263,14 @@ protected: virtual void UpdateLoadedSections(lldb::ModuleSP module, lldb::addr_t link_map_addr, - lldb::addr_t base_addr); + lldb::addr_t base_addr, + bool base_addr_is_offset); // Utility method so base classes can share implementation of UpdateLoadedSections void UpdateLoadedSectionsCommon(lldb::ModuleSP module, - lldb::addr_t base_addr); + lldb::addr_t base_addr, + bool base_addr_is_offset); /// Removes the loaded sections from the target in @p module. /// @@ -282,8 +284,11 @@ protected: /// Locates or creates a module given by @p file and updates/loads the /// resulting module at the virtual base address @p base_addr. - lldb::ModuleSP - LoadModuleAtAddress(const lldb_private::FileSpec &file, lldb::addr_t link_map_addr, lldb::addr_t base_addr); + virtual lldb::ModuleSP + LoadModuleAtAddress(const lldb_private::FileSpec &file, + lldb::addr_t link_map_addr, + lldb::addr_t base_addr, + bool base_addr_is_offset); const lldb_private::SectionList * GetSectionListFromModule(const lldb::ModuleSP module) const; Modified: lldb/trunk/source/Core/DynamicLoader.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/DynamicLoader.cpp?rev=245834&r1=245833&r2=245834&view=diff ============================================================================== --- lldb/trunk/source/Core/DynamicLoader.cpp (original) +++ lldb/trunk/source/Core/DynamicLoader.cpp Mon Aug 24 05:21:55 2015 @@ -119,16 +119,20 @@ DynamicLoader::GetTargetExecutable() } void -DynamicLoader::UpdateLoadedSections(ModuleSP module, addr_t link_map_addr, addr_t base_addr) +DynamicLoader::UpdateLoadedSections(ModuleSP module, + addr_t link_map_addr, + addr_t base_addr, + bool base_addr_is_offset) { - UpdateLoadedSectionsCommon(module, base_addr); + UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset); } void -DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module, addr_t base_addr) +DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module, + addr_t base_addr, + bool base_addr_is_offset) { bool changed; - const bool base_addr_is_offset = true; module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset, changed); } @@ -171,7 +175,10 @@ DynamicLoader::GetSectionListFromModule( } ModuleSP -DynamicLoader::LoadModuleAtAddress(const FileSpec &file, addr_t link_map_addr, addr_t base_addr) +DynamicLoader::LoadModuleAtAddress(const FileSpec &file, + addr_t link_map_addr, + addr_t base_addr, + bool base_addr_is_offset) { Target &target = m_process->GetTarget(); ModuleList &modules = target.GetImages(); @@ -180,27 +187,28 @@ DynamicLoader::LoadModuleAtAddress(const ModuleSpec module_spec (file, target.GetArchitecture()); if ((module_sp = modules.FindFirstModule (module_spec))) { - UpdateLoadedSections(module_sp, link_map_addr, base_addr); + UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset); } else if ((module_sp = target.GetSharedModule(module_spec))) { - UpdateLoadedSections(module_sp, link_map_addr, base_addr); + UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset); } else { - // Try to fetch the load address of the file from the process. It can be different from the - // address reported by the linker in case of a file with fixed load address because the - // linker reports the bias between the load address specified in the file and the actual - // load address it loaded the file. - bool is_loaded; - lldb::addr_t load_addr; - Error error = m_process->GetFileLoadAddress(file, is_loaded, load_addr); - if (error.Fail() || !is_loaded) - load_addr = base_addr; + if (base_addr_is_offset) + { + // Try to fetch the load address of the file from the process as we need absolute load + // address to read the file out of the memory instead of a load bias. + bool is_loaded; + lldb::addr_t load_addr; + Error error = m_process->GetFileLoadAddress(file, is_loaded, load_addr); + if (error.Success() && is_loaded) + base_addr = load_addr; + } - if ((module_sp = m_process->ReadModuleFromMemory(file, load_addr))) + if ((module_sp = m_process->ReadModuleFromMemory(file, base_addr))) { - UpdateLoadedSections(module_sp, link_map_addr, base_addr); + UpdateLoadedSections(module_sp, link_map_addr, base_addr, false); target.GetImages().AppendIfNeeded(module_sp); } } Modified: lldb/trunk/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp?rev=245834&r1=245833&r2=245834&view=diff ============================================================================== --- lldb/trunk/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp (original) +++ lldb/trunk/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp Mon Aug 24 05:21:55 2015 @@ -177,7 +177,7 @@ DynamicLoaderHexagonDYLD::DidAttach() // Map the loaded sections of this executable if ( load_offset != LLDB_INVALID_ADDRESS ) - UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset); + UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset, true); // AD: confirm this? // Load into LLDB all of the currently loaded executables in the stub @@ -268,7 +268,10 @@ DynamicLoaderHexagonDYLD::CanLoadImage() } void -DynamicLoaderHexagonDYLD::UpdateLoadedSections(ModuleSP module, addr_t link_map_addr, addr_t base_addr) +DynamicLoaderHexagonDYLD::UpdateLoadedSections(ModuleSP module, + addr_t link_map_addr, + addr_t base_addr, + bool base_addr_is_offset) { Target &target = m_process->GetTarget(); const SectionList *sections = GetSectionListFromModule(module); @@ -442,7 +445,7 @@ DynamicLoaderHexagonDYLD::RefreshModules for (I = m_rendezvous.loaded_begin(); I != E; ++I) { FileSpec file(I->path.c_str(), true); - ModuleSP module_sp = LoadModuleAtAddress(file, I->link_addr, I->base_addr); + ModuleSP module_sp = LoadModuleAtAddress(file, I->link_addr, I->base_addr, true); if (module_sp.get()) { loaded_modules.AppendIfNeeded( module_sp ); @@ -571,7 +574,7 @@ DynamicLoaderHexagonDYLD::LoadAllCurrent { const char *module_path = I->path.c_str(); FileSpec file(module_path, false); - ModuleSP module_sp = LoadModuleAtAddress(file, I->link_addr, I->base_addr); + ModuleSP module_sp = LoadModuleAtAddress(file, I->link_addr, I->base_addr, true); if (module_sp.get()) { module_list.Append(module_sp); @@ -591,7 +594,10 @@ DynamicLoaderHexagonDYLD::LoadAllCurrent /// Helper for the entry breakpoint callback. Resolves the load addresses /// of all dependent modules. ModuleSP -DynamicLoaderHexagonDYLD::LoadModuleAtAddress(const FileSpec &file, addr_t link_map_addr, addr_t base_addr) +DynamicLoaderHexagonDYLD::LoadModuleAtAddress(const FileSpec &file, + addr_t link_map_addr, + addr_t base_addr, + bool base_addr_is_offset) { Target &target = m_process->GetTarget(); ModuleList &modules = target.GetImages(); @@ -602,12 +608,12 @@ DynamicLoaderHexagonDYLD::LoadModuleAtAd // check if module is currently loaded if ((module_sp = modules.FindFirstModule (module_spec))) { - UpdateLoadedSections(module_sp, link_map_addr, base_addr); + UpdateLoadedSections(module_sp, link_map_addr, base_addr, true); } // try to load this module from disk else if ((module_sp = target.GetSharedModule(module_spec))) { - UpdateLoadedSections(module_sp, link_map_addr, base_addr); + UpdateLoadedSections(module_sp, link_map_addr, base_addr, true); } return module_sp; Modified: lldb/trunk/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h?rev=245834&r1=245833&r2=245834&view=diff ============================================================================== --- lldb/trunk/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h (original) +++ lldb/trunk/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h Mon Aug 24 05:21:55 2015 @@ -124,7 +124,8 @@ protected: void UpdateLoadedSections(lldb::ModuleSP module, lldb::addr_t link_map_addr, - lldb::addr_t base_addr); + lldb::addr_t base_addr, + bool base_addr_is_offset) override; /// Removes the loaded sections from the target in @p module. /// @@ -135,7 +136,10 @@ protected: /// Locates or creates a module given by @p file and updates/loads the /// resulting module at the virtual base address @p base_addr. lldb::ModuleSP - LoadModuleAtAddress(const lldb_private::FileSpec &file, lldb::addr_t link_map_addr, lldb::addr_t base_addr); + LoadModuleAtAddress(const lldb_private::FileSpec &file, + lldb::addr_t link_map_addr, + lldb::addr_t base_addr, + bool base_addr_is_offset) override; /// Callback routine invoked when we hit the breakpoint on process entry. /// Modified: lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp?rev=245834&r1=245833&r2=245834&view=diff ============================================================================== --- lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp (original) +++ lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp Mon Aug 24 05:21:55 2015 @@ -165,7 +165,7 @@ DynamicLoaderPOSIXDYLD::DidAttach() m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID, executable_sp->GetFileSpec().GetPath().c_str ()); - UpdateLoadedSections(executable_sp, LLDB_INVALID_ADDRESS, load_offset); + UpdateLoadedSections(executable_sp, LLDB_INVALID_ADDRESS, load_offset, true); // When attaching to a target, there are two possible states: // (1) We already crossed the entry point and therefore the rendezvous @@ -223,7 +223,7 @@ DynamicLoaderPOSIXDYLD::DidLaunch() { ModuleList module_list; module_list.Append(executable); - UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset); + UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset, true); if (log) log->Printf ("DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()", __FUNCTION__); @@ -252,11 +252,13 @@ DynamicLoaderPOSIXDYLD::CanLoadImage() } void -DynamicLoaderPOSIXDYLD::UpdateLoadedSections(ModuleSP module, addr_t link_map_addr, addr_t base_addr) +DynamicLoaderPOSIXDYLD::UpdateLoadedSections(ModuleSP module, + addr_t link_map_addr, + addr_t base_addr, + bool base_addr_is_offset) { m_loaded_modules[module] = link_map_addr; - - UpdateLoadedSectionsCommon(module, base_addr); + UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset); } void @@ -414,7 +416,7 @@ DynamicLoaderPOSIXDYLD::RefreshModules() E = m_rendezvous.loaded_end(); for (I = m_rendezvous.loaded_begin(); I != E; ++I) { - ModuleSP module_sp = LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr); + ModuleSP module_sp = LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true); if (module_sp.get()) { loaded_modules.AppendIfNeeded(module_sp); @@ -432,8 +434,7 @@ DynamicLoaderPOSIXDYLD::RefreshModules() for (I = m_rendezvous.unloaded_begin(); I != E; ++I) { ModuleSpec module_spec{I->file_spec}; - ModuleSP module_sp = - loaded_modules.FindFirstModule (module_spec); + ModuleSP module_sp = loaded_modules.FindFirstModule (module_spec); if (module_sp.get()) { @@ -520,10 +521,9 @@ DynamicLoaderPOSIXDYLD::LoadAllCurrentMo ModuleSP executable = GetTargetExecutable(); m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress(); - for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) { - ModuleSP module_sp = LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr); + ModuleSP module_sp = LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true); if (module_sp.get()) { module_list.Append(module_sp); Modified: lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h?rev=245834&r1=245833&r2=245834&view=diff ============================================================================== --- lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h (original) +++ lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h Mon Aug 24 05:21:55 2015 @@ -103,7 +103,7 @@ protected: /// Enables a breakpoint on a function called by the runtime /// linker each time a module is loaded or unloaded. - void + virtual void SetRendezvousBreakpoint(); /// Callback routine which updates the current list of loaded modules based @@ -126,16 +126,17 @@ protected: /// @param link_map_addr The virtual address of the link map for the @p module. /// /// @param base_addr The virtual base address @p module is loaded at. - virtual void + void UpdateLoadedSections(lldb::ModuleSP module, lldb::addr_t link_map_addr, - lldb::addr_t base_addr); + lldb::addr_t base_addr, + bool base_addr_is_offset) override; /// Removes the loaded sections from the target in @p module. /// /// @param module The module to traverse. - virtual void - UnloadSections(const lldb::ModuleSP module); + void + UnloadSections(const lldb::ModuleSP module) override; /// Resolves the entry point for the current inferior process and sets a /// breakpoint at that address. @@ -155,7 +156,7 @@ protected: /// Helper for the entry breakpoint callback. Resolves the load addresses /// of all dependent modules. - void + virtual void LoadAllCurrentModules(); /// Computes a value for m_load_offset returning the computed address on Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=245834&r1=245833&r2=245834&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original) +++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Mon Aug 24 05:21:55 2015 @@ -847,40 +847,52 @@ ObjectFileELF::SetLoadAddress (Target &t SectionList *section_list = GetSectionList (); if (section_list) { - if (value_is_offset) + if (!value_is_offset) { - const size_t num_sections = section_list->GetSize(); - size_t sect_idx = 0; - - for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) + bool found_offset = false; + for (size_t i = 0, count = GetProgramHeaderCount(); i < count; ++i) { - // Iterate through the object file sections to find all - // of the sections that have SHF_ALLOC in their flag bits. - SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx)); - // if (section_sp && !section_sp->IsThreadSpecific()) - if (section_sp && section_sp->Test(SHF_ALLOC)) - { - lldb::addr_t load_addr = section_sp->GetFileAddress() + value; - - // On 32-bit systems the load address have to fit into 4 bytes. The rest of - // the bytes are the overflow from the addition. - if (GetAddressByteSize() == 4) - load_addr &= 0xFFFFFFFF; - - if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, load_addr)) - ++num_loaded_sections; - } + const elf::ELFProgramHeader* header = GetProgramHeaderByIndex(i); + if (header == nullptr) + continue; + + if (header->p_type != PT_LOAD || header->p_offset != 0) + continue; + + value = value - header->p_vaddr; + found_offset = true; + break; } - return num_loaded_sections > 0; + if (!found_offset) + return false; } - else + + const size_t num_sections = section_list->GetSize(); + size_t sect_idx = 0; + + for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) { - // Not sure how to slide an ELF file given the base address - // of the ELF file in memory + // Iterate through the object file sections to find all + // of the sections that have SHF_ALLOC in their flag bits. + SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx)); + // if (section_sp && !section_sp->IsThreadSpecific()) + if (section_sp && section_sp->Test(SHF_ALLOC)) + { + lldb::addr_t load_addr = section_sp->GetFileAddress() + value; + + // On 32-bit systems the load address have to fit into 4 bytes. The rest of + // the bytes are the overflow from the addition. + if (GetAddressByteSize() == 4) + load_addr &= 0xFFFFFFFF; + + if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, load_addr)) + ++num_loaded_sections; + } } + return num_loaded_sections > 0; } } - return false; // If it changed + return false; } ByteOrder _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits