[Lldb-commits] [lldb] r245834 - Add absolute load address support for the DynamicLoader plugins

Tamas Berghammer via lldb-commits lldb-commits at lists.llvm.org
Mon Aug 24 03:21:55 PDT 2015


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




More information about the lldb-commits mailing list