[lldb-dev] [PATCH] factor methods in DynamicLoaderPOSIXDYLD into base class

Steve Pucci spucci at google.com
Wed Feb 5 11:22:52 PST 2014


Oops, sorry.  Here it is...


On Wed, Feb 5, 2014 at 11:15 AM, Greg Clayton <gclayton at apple.com> wrote:

> Can you attach the update patch file?
>
> On Feb 5, 2014, at 10:23 AM, Steve Pucci <spucci at google.com> wrote:
>
> > OK, updated patch attached.  Responses to the questions inline below.
> >
> > Thanks,
> >    Steve
> >
> >
> > On Wed, Jan 29, 2014 at 4:16 PM, Greg Clayton <gclayton at apple.com>
> wrote:
> > So a few questions:
> >
> > 1 - Does anyone use the "link_map_addr" parameter that is being sent to
> many of the functions that were moved into DynamicLoader? I didn't see any.
> Please remove this argument if possible.
> >
> > It turns out this *is* used in
> DynamicLoaderPOSIXDYLD::UpdateLoadedSections(), so I left it in there and
> in the routine that calls it (LoadModuleAtAddress), but it was possible to
> remove it from UpdateLoadedSectionsCommon so I did that.
> >
> > 2 - ReadInt() isn't correct for all systems:
> >
> > static int ReadInt(Process *process, addr_t addr)
> > {
> >     Error error;
> >     int value = (int)process->ReadUnsignedIntegerFromMemory(addr,
> sizeof(uint32_t), 0, error);
> >
> > See the "sizeof(uint32_t)"? We will want to get the size of an "int" for
> the process that is being run if this function really does need to get a
> "int" from the debugger. So this sizeof() needs to be changed to get the
> actual size of a type "int" via:
> >
> > ClangASTContext *ast =
> m_process->GetTarget().GetScratchClangASTContext();
> > ClangASTType int_type = ast->GetBasicType (eBasicTypeInt);
> > uint64_t int_size = int_type.GetByteSize();
> >
> > Or this function might be more useful if we pass in the size of the
> integer we need?
> >
> > Investigating this revealed what appears to be a bug on big-endian
> 64-bit Linux platforms, but I'm decoupling that bug fix from this patch, as
> this patch is supposed to be functionally a no-op.  I've taken your
> suggestion that the size of the int should be passed in, but for now the
> caller passes in "4" as that's equivalent to the code that was there before.
> >
> > 3 - The DynamicLoader class has a m_process member variable so the
> "Process *process" argument doesn't need to be passed into the following
> functions:
> >         int DynamicLoader::ReadInt(Process *process, addr_t addr);
> >         addr_t DynamicLoader::ReadPointer(Process *process, addr_t addr);
> >
> > I made these methods non-static and removed the process parameter as you
> suggested.
> >
> > On Jan 29, 2014, at 1:45 PM, Steve Pucci <spucci at google.com> wrote:
> >
> > > OK, that seemed to work, at least on my simple shared-library testcase
> on Ubuntu, which invokes the new code in ObjectFileELF::SetLoadAddress().
> > >
> > > Updated full patch attached.
> > >
> > >
> > >
> > >
> > > On Tue, Jan 28, 2014 at 7:19 AM, Steve Pucci <spucci at google.com>
> wrote:
> > > OK, great, thanks Greg, I'll give it a go.
> > >
> > >  - Steve
> > >
> > >
> > > On Mon, Jan 27, 2014 at 4:31 PM, Greg Clayton <gclayton at apple.com>
> wrote:
> > > The first thing to do is just look at the section that has address of
> zero and see if it has any bits that the other don't or vice versa.
> > >
> > > I think the bit you are looking for is SHF_ALLOC.
> > >
> > > The "sh_flags" from the ELF section are indeed placed in the
> lldb_private::Section flags, so you should be able to do:
> > >
> > > for (section : sections)
> > > {
> > >     if (section->Test(SHF_ALLOC))
> > >     {
> > >         // Load this section
> > >     }
> > > }
> > >
> > >
> > >
> > >
> > >
> > > On Jan 27, 2014, at 4:23 PM, Steve Pucci <spucci at google.com> wrote:
> > >
> > > > OK, I understand, though I may need some help from someone with
> interpreting Section headers for Elf.  I'll let this group know if I have
> questions.
> > > >
> > > > Thanks again,
> > > >    Steve
> > > >
> > > >
> > > > On Mon, Jan 27, 2014 at 4:17 PM, Greg Clayton <gclayton at apple.com>
> wrote:
> > > >
> > > > On Jan 27, 2014, at 4:02 PM, Steve Pucci <spucci at google.com> wrote:
> > > >
> > > > > Thanks, Greg.
> > > > >
> > > > > I think it all makes sense, except for one bit:
> > > > >
> > > > > In ObjectFileELF::SetLoadAddress(), are you proposing I simply
> call Module::SetLoadAddress as it exists today?  That method walks through
> all sections and checks only section_sp->IsThreadSpecific() to decide
> whether to load the section, and there's no place to insert an ELF-specific
> check of the section to see if it's loadable.  Is that what you meant, or
> are you suggesting something else?
> > > >
> > > > Something else. When the ObjectFileELF parser parses the section
> headers, it places the flags (or it should if it isn't) into the flags
> field of the lldb_private::Section. So it should be able to use the flags
> from its sections to correctly in each lldb_private::Section, and correctly
> interpret them to know which sections need to be loaded and which don't. So
> let the ELF plugin that created the sections correctly interpret the flags
> it put into the sections.
> > > >
> > > > We then will need to change the Module::SetLoadAddress() to call
> this new ObjectFile function.
> > > >
> > > > >
> > > > > Instead of that I could have ObjectFileELF::SetLoadAddress iterate
> through the sections as UpdateLoadedSectionsCommon does below, OR I could
> somehow provide a callback to be called from Module::SetLoadAddress
> (perhaps by passing in the ObjectFile*).
> > > >
> > > > It should all be done in the ObjectFileELF::SetLoadAddress function.
> > > >
> > > > >
> > > > > Thanks,
> > > > >   Steve
> > > > >
> > > > >
> > > > >
> > > > > On Mon, Jan 27, 2014 at 3:14 PM, Greg Clayton <gclayton at apple.com>
> wrote:
> > > > >
> > > > > On Jan 27, 2014, at 3:05 PM, Greg Clayton <gclayton at apple.com>
> wrote:
> > > > >
> > > > > > Looks ok except for:
> > > > > >
> > > > > > This is ELF specific with the file address of zero, and it
> probably should more be done via flags and asking the section if it is
> loadable:
> > > > > >
> > > > > > +void
> > > > > > +DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module,
> addr_t link_map_addr, addr_t base_addr)
> > > > > > +{
> > > > > > +    Target &target = m_process->GetTarget();
> > > > > > +    const SectionList *sections =
> GetSectionListFromModule(module);
> > > > > > +
> > > > > > +    assert(sections && "SectionList missing from loaded
> module.");
> > > > > > +
> > > > > > +    const size_t num_sections = sections->GetSize();
> > > > > > +
> > > > > > +    for (unsigned i = 0; i < num_sections; ++i)
> > > > > > +    {
> > > > > > +        SectionSP section_sp (sections->GetSectionAtIndex(i));
> > > > > > +        lldb::addr_t new_load_addr =
> section_sp->GetFileAddress() + base_addr;
> > > > > > +
> > > > > > +        // If the file address of the section is zero then this
> is not an
> > > > > > +        // allocatable/loadable section (property of ELF
> sh_addr).  Skip it.
> > > > > > +        if (new_load_addr == base_addr)
> > > > > > +            continue;
> > > > > > +
> > > > > > +        target.SetSectionLoadAddress(section_sp, new_load_addr);
> > > > > > +    }
> > > > > > +}
> > > > > >
> > > > > >
> > > > > > There is also a module function that does something similar to
> this, without the looking for the zero address:
> > > > > >
> > > > > > bool
> > > > > > Module::SetLoadAddress (Target &target, lldb::addr_t offset,
> bool &changed);
> > > > > >
> > > > > > So I would propose the following:
> > > > > >
> > > > > > Update DynamicLoader::UpdateLoadedSectionsCommon() to call into
> a new function that is a virtual function in ObjectFile:
> > > > > >
> > > > > > virtual bool SetLoadAddress (addr_t base_addr)
> > > > > > {
> > > > > >    return false;
> > > > > > }
> > > > > >
> > > > > > Then each object file (ObjectFileELF in your case) can choose to
> do the loading correctly given a single "base_addr":
> > > > > >
> > > > > > bool
> > > > > > ObjectFileELF::SetLoadAddress (addr_t base_addr)
> > > > > > {
> > > > > > }
> > > > > >
> > > > > > Then in ObjectFileELF::SetLoadAddress() you can use the section
> flags that were saved in the lldb_private::Section to properly determine
> which sections are loadable and which aren't. This function is for a rigid
> slide of all loadable sections.
> > > > > >
> > > > > > Does that make sense?
> > > > >
> > > > > I forgot the SetLoadAddress needs a target, and each object file
> already knows its module, so that doesn't need to be passed, it can be
> retrieved via the getter function:
> > > > >
> > > > > virtual bool SetLoadAddress (Target &target, addr_t base_addr)
> > > > > {
> > > > >    return false;
> > > > > }
> > > > >
> > > > > Then each object file (ObjectFileELF in your case) can choose to
> do the loading correctly given a single "base_addr":
> > > > >
> > > > > bool
> > > > > ObjectFileELF::SetLoadAddress (Target &target, addr_t base_addr)
> > > > > {
> > > > >      ModuleSP module_sp = GetModule();
> > > > >      if (module_sp)
> > > > >      {
> > > > >          ....
> > > > >      }
> > > > > }
> > > > >
> > > > >
> > > > >
> > > > > > Greg
> > > > > >
> > > > > >
> > > > > >
> > > > > > On Jan 27, 2014, at 2:32 PM, Steve Pucci <spucci at google.com>
> wrote:
> > > > > >
> > > > > >> Hi,
> > > > > >>
> > > > > >> I'd like to have access to a number of methods in
> DynamicLoaderPOSIXDYLD from the new class I'm working on,
> DynamicLoaderGDBServer.  These methods have no dependency on
> DynamicLoaderPOSIXDYLD, with two exceptions noted below, so I'm proposing
> to move them into the base class DynamicLoader.
> > > > > >>
> > > > > >> The two exceptions are the methods UpdateLoadedSections and
> UnloadSections; in each case there is one line of code that is special to
> the derived class, and the rest of the code in the method is generic to the
> base class.  In each case I created a XXXCommon() method on the base class
> with the common code, and created a virtual method XXX() on the base class,
> which in DynamicLoaderPOSIXDYLD will call the common code and then execute
> its one line of specialized code.
> > > > > >>
> > > > > >> This patch is intended to have no functional difference
> whatsoever.  All 276 tests that are enabled for Ubuntu pass successfully.
> > > > > >>
> > > > > >> Thanks,
> > > > > >>   Steve
> > > > > >>
> > > > > >>
> > > > > >>
> <patch-FactorDynamicLibrary.txt>_______________________________________________
> > > > > >> lldb-dev mailing list
> > > > > >> lldb-dev at cs.uiuc.edu
> > > > > >> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
> > > > > >
> > > > > > _______________________________________________
> > > > > > lldb-dev mailing list
> > > > > > lldb-dev at cs.uiuc.edu
> > > > > > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
> > > > >
> > > > >
> > > >
> > > >
> > >
> > >
> > >
> > > <patch-FactorDynamicLibrary-2.txt>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20140205/c9ab623d/attachment.html>
-------------- next part --------------
Index: include/lldb/Symbol/ObjectFile.h
===================================================================
--- include/lldb/Symbol/ObjectFile.h	(revision 200851)
+++ include/lldb/Symbol/ObjectFile.h	(working copy)
@@ -451,6 +451,19 @@
     }
 
     //------------------------------------------------------------------
+    /// Sets the load address for an entire module, assuming a rigid
+    /// slide of sections, if possible in the implementation.
+    ///
+    /// @return
+    ///     Returns true iff any section's load address changed.
+    //------------------------------------------------------------------
+    virtual bool
+    SetLoadAddress(Target &target, lldb::addr_t base_addr)
+    {
+        return false;
+    }
+
+    //------------------------------------------------------------------
     /// Gets whether endian swapping should occur when extracting data
     /// from this object file.
     ///
Index: include/lldb/Target/DynamicLoader.h
===================================================================
--- include/lldb/Target/DynamicLoader.h	(revision 200851)
+++ include/lldb/Target/DynamicLoader.h	(working copy)
@@ -246,6 +246,60 @@
 
 protected:
     //------------------------------------------------------------------
+    // Utility methods for derived classes
+    //------------------------------------------------------------------
+
+    /// Checks to see if the target module has changed, updates the target
+    /// accordingly and returns the target executable module.
+    lldb::ModuleSP
+    GetTargetExecutable();
+
+    /// Updates the load address of every allocatable section in @p module.
+    ///
+    /// @param module The module to traverse.
+    ///
+    /// @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
+    UpdateLoadedSections(lldb::ModuleSP module,
+                         lldb::addr_t link_map_addr,
+                         lldb::addr_t base_addr);
+
+    // Utility method so base classes can share implementation of UpdateLoadedSections
+    void
+    UpdateLoadedSectionsCommon(lldb::ModuleSP module,
+                               lldb::addr_t base_addr);
+
+    /// Removes the loaded sections from the target in @p module.
+    ///
+    /// @param module The module to traverse.
+    virtual void
+    UnloadSections(const lldb::ModuleSP module);
+
+    // Utility method so base classes can share implementation of UnloadSections
+    void
+    UnloadSectionsCommon(const lldb::ModuleSP module);
+
+    /// 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);
+
+    const lldb_private::SectionList *
+    GetSectionListFromModule(const lldb::ModuleSP module) const;
+
+    // Read an unsigned int of the given size from memory at the given addr.
+    // Return -1 if the read fails, otherwise return the result as an int64_t.
+    int64_t
+    ReadUnsignedIntWithSizeInBytes(lldb::addr_t addr, int size_in_bytes);
+
+    // Read a pointer from memory at the given addr.
+    // Return LLDB_INVALID_ADDRESS if the read fails.
+    lldb::addr_t
+    ReadPointer(lldb::addr_t addr);
+
+    //------------------------------------------------------------------
     // Member variables.
     //------------------------------------------------------------------
     Process* m_process; ///< The process that this dynamic loader plug-in is tracking.
Index: source/Core/DynamicLoader.cpp
===================================================================
--- source/Core/DynamicLoader.cpp	(revision 200851)
+++ source/Core/DynamicLoader.cpp	(working copy)
@@ -10,7 +10,11 @@
 #include "lldb/lldb-private.h"
 #include "lldb/Target/DynamicLoader.h"
 #include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/Section.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -74,3 +78,136 @@
     m_process->SetStopOnSharedLibraryEvents (stop);
 }
 
+ModuleSP
+DynamicLoader::GetTargetExecutable()
+{
+    Target &target = m_process->GetTarget();
+    ModuleSP executable = target.GetExecutableModule();
+
+    if (executable.get())
+    {
+        if (executable->GetFileSpec().Exists())
+        {
+            ModuleSpec module_spec (executable->GetFileSpec(), executable->GetArchitecture());
+            ModuleSP module_sp (new Module (module_spec));
+
+            // Check if the executable has changed and set it to the target executable if they differ.
+            if (module_sp.get() && module_sp->GetUUID().IsValid() && executable->GetUUID().IsValid())
+            {
+                if (module_sp->GetUUID() != executable->GetUUID())
+                    executable.reset();
+            }
+            else if (executable->FileHasChanged())
+            {
+                executable.reset();
+            }
+
+            if (!executable.get())
+            {
+                executable = target.GetSharedModule(module_spec);
+                if (executable.get() != target.GetExecutableModulePointer())
+                {
+                    // Don't load dependent images since we are in dyld where we will know
+                    // and find out about all images that are loaded
+                    const bool get_dependent_images = false;
+                    target.SetExecutableModule(executable, get_dependent_images);
+                }
+            }
+        }
+    }
+    return executable;
+}
+
+void
+DynamicLoader::UpdateLoadedSections(ModuleSP module, addr_t link_map_addr, addr_t base_addr)
+{
+    UpdateLoadedSectionsCommon(module, base_addr);
+}
+
+void
+DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module, addr_t base_addr)
+{
+    bool changed;
+    module->SetLoadAddress(m_process->GetTarget(), base_addr, changed);
+}
+
+void
+DynamicLoader::UnloadSections(const ModuleSP module)
+{
+    UnloadSectionsCommon(module);
+}
+
+void
+DynamicLoader::UnloadSectionsCommon(const ModuleSP module)
+{
+    Target &target = m_process->GetTarget();
+    const SectionList *sections = GetSectionListFromModule(module);
+
+    assert(sections && "SectionList missing from unloaded module.");
+
+    const size_t num_sections = sections->GetSize();
+    for (size_t i = 0; i < num_sections; ++i)
+    {
+        SectionSP section_sp (sections->GetSectionAtIndex(i));
+        target.SetSectionUnloaded(section_sp);
+    }
+}
+
+
+const SectionList *
+DynamicLoader::GetSectionListFromModule(const ModuleSP module) const
+{
+    SectionList *sections = nullptr;
+    if (module.get())
+    {
+        ObjectFile *obj_file = module->GetObjectFile();
+        if (obj_file)
+        {
+            sections = obj_file->GetSectionList();
+        }
+    }
+    return sections;
+}
+
+ModuleSP
+DynamicLoader::LoadModuleAtAddress(const FileSpec &file, addr_t link_map_addr, addr_t base_addr)
+{
+    Target &target = m_process->GetTarget();
+    ModuleList &modules = target.GetImages();
+    ModuleSP module_sp;
+
+    ModuleSpec module_spec (file, target.GetArchitecture());
+    if ((module_sp = modules.FindFirstModule (module_spec)))
+    {
+        UpdateLoadedSections(module_sp, link_map_addr, base_addr);
+    }
+    else if ((module_sp = target.GetSharedModule(module_spec)))
+    {
+        UpdateLoadedSections(module_sp, link_map_addr, base_addr);
+    }
+
+    return module_sp;
+}
+
+int64_t
+DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr, int size_in_bytes)
+{
+    Error error;
+
+    uint64_t value = m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error);
+    if (error.Fail())
+        return -1;
+    else
+        return (int64_t)value;
+}
+
+addr_t
+DynamicLoader::ReadPointer(addr_t addr)
+{
+    Error error;
+    addr_t value = m_process->ReadPointerFromMemory(addr, error);
+    if (error.Fail())
+        return LLDB_INVALID_ADDRESS;
+    else
+        return value;
+}
Index: source/Core/Module.cpp
===================================================================
--- source/Core/Module.cpp	(revision 200851)
+++ source/Core/Module.cpp	(working copy)
@@ -1502,28 +1502,12 @@
 bool 
 Module::SetLoadAddress (Target &target, lldb::addr_t offset, bool &changed)
 {
-    size_t num_loaded_sections = 0;
-    SectionList *section_list = GetSectionList ();
-    if (section_list)
+    ObjectFile *object_file = GetObjectFile();
+    if (object_file)
     {
-        const size_t num_sections = section_list->GetSize();
-        size_t sect_idx = 0;
-        for (sect_idx = 0; sect_idx < num_sections; ++sect_idx)
-        {
-            // Iterate through the object file sections to find the
-            // first section that starts of file offset zero and that
-            // has bytes in the file...
-            SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
-            // Only load non-thread specific sections when given a slide
-            if (section_sp && !section_sp->IsThreadSpecific())
-            {
-                if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + offset))
-                    ++num_loaded_sections;
-            }
-        }
+        return object_file->SetLoadAddress(target, offset);
     }
-    changed = num_loaded_sections > 0;
-    return num_loaded_sections > 0;
+    return false;
 }
 
 
Index: source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
===================================================================
--- source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp	(revision 200851)
+++ source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp	(working copy)
@@ -150,46 +150,6 @@
     }
 }
 
-ModuleSP
-DynamicLoaderPOSIXDYLD::GetTargetExecutable()
-{
-    Target &target = m_process->GetTarget();
-    ModuleSP executable = target.GetExecutableModule();
-
-    if (executable.get())
-    {
-        if (executable->GetFileSpec().Exists())
-        {
-            ModuleSpec module_spec (executable->GetFileSpec(), executable->GetArchitecture());
-            ModuleSP module_sp (new Module (module_spec));
-
-            // Check if the executable has changed and set it to the target executable if they differ.
-            if (module_sp.get() && module_sp->GetUUID().IsValid() && executable->GetUUID().IsValid())
-            {
-                if (module_sp->GetUUID() != executable->GetUUID())
-                    executable.reset();
-            }
-            else if (executable->FileHasChanged())
-            {
-                executable.reset();
-            }
-
-            if (!executable.get())
-            {
-                executable = target.GetSharedModule(module_spec);
-                if (executable.get() != target.GetExecutableModulePointer())
-                {
-                    // Don't load dependent images since we are in dyld where we will know
-                    // and find out about all images that are loaded
-                    const bool get_dependent_images = false;
-                    target.SetExecutableModule(executable, get_dependent_images);
-                }
-            }
-        }
-    }
-    return executable;
-}
-
 Error
 DynamicLoaderPOSIXDYLD::ExecutePluginCommand(Args &command, Stream *strm)
 {
@@ -211,45 +171,17 @@
 void
 DynamicLoaderPOSIXDYLD::UpdateLoadedSections(ModuleSP module, addr_t link_map_addr, addr_t base_addr)
 {
-    Target &target = m_process->GetTarget();
-    const SectionList *sections = GetSectionListFromModule(module);
-
-    assert(sections && "SectionList missing from loaded module.");
-
     m_loaded_modules[module] = link_map_addr;
 
-    const size_t num_sections = sections->GetSize();
-
-    for (unsigned i = 0; i < num_sections; ++i)
-    {
-        SectionSP section_sp (sections->GetSectionAtIndex(i));
-        lldb::addr_t new_load_addr = section_sp->GetFileAddress() + base_addr;
-
-        // If the file address of the section is zero then this is not an
-        // allocatable/loadable section (property of ELF sh_addr).  Skip it.
-        if (new_load_addr == base_addr)
-            continue;
-
-        target.SetSectionLoadAddress(section_sp, new_load_addr);
-    }
+    UpdateLoadedSectionsCommon(module, base_addr);
 }
 
 void
 DynamicLoaderPOSIXDYLD::UnloadSections(const ModuleSP module)
 {
-    Target &target = m_process->GetTarget();
-    const SectionList *sections = GetSectionListFromModule(module);
-
-    assert(sections && "SectionList missing from unloaded module.");
-
     m_loaded_modules.erase(module);
 
-    const size_t num_sections = sections->GetSize();
-    for (size_t i = 0; i < num_sections; ++i)
-    {
-        SectionSP section_sp (sections->GetSectionAtIndex(i));
-        target.SetSectionUnloaded(section_sp);
-    }
+    UnloadSectionsCommon(module);
 }
 
 void
@@ -467,26 +399,6 @@
     m_process->GetTarget().ModulesDidLoad(module_list);
 }
 
-ModuleSP
-DynamicLoaderPOSIXDYLD::LoadModuleAtAddress(const FileSpec &file, addr_t link_map_addr, addr_t base_addr)
-{
-    Target &target = m_process->GetTarget();
-    ModuleList &modules = target.GetImages();
-    ModuleSP module_sp;
-
-    ModuleSpec module_spec (file, target.GetArchitecture());
-    if ((module_sp = modules.FindFirstModule (module_spec))) 
-    {
-        UpdateLoadedSections(module_sp, link_map_addr, base_addr);
-    }
-    else if ((module_sp = target.GetSharedModule(module_spec))) 
-    {
-        UpdateLoadedSections(module_sp, link_map_addr, base_addr);
-    }
-
-    return module_sp;
-}
-
 addr_t
 DynamicLoaderPOSIXDYLD::ComputeLoadOffset()
 {
@@ -530,41 +442,6 @@
     return m_entry_point;
 }
 
-const SectionList *
-DynamicLoaderPOSIXDYLD::GetSectionListFromModule(const ModuleSP module) const
-{
-    SectionList *sections = nullptr;
-    if (module.get())
-    {
-        ObjectFile *obj_file = module->GetObjectFile();
-        if (obj_file)
-        {
-            sections = obj_file->GetSectionList();
-        }
-    }
-    return sections;
-}
-
-static int ReadInt(Process *process, addr_t addr)
-{
-    Error error;
-    int value = (int)process->ReadUnsignedIntegerFromMemory(addr, sizeof(uint32_t), 0, error);
-    if (error.Fail())
-        return -1;
-    else
-        return value;
-}
-
-static addr_t ReadPointer(Process *process, addr_t addr)
-{
-    Error error;
-    addr_t value = process->ReadPointerFromMemory(addr, error);
-    if (error.Fail())
-        return LLDB_INVALID_ADDRESS;
-    else
-        return value;
-}
-
 lldb::addr_t
 DynamicLoaderPOSIXDYLD::GetThreadLocalData (const lldb::ModuleSP module, const lldb::ThreadSP thread)
 {
@@ -586,26 +463,27 @@
         return LLDB_INVALID_ADDRESS;
 
     // Find the module's modid.
-    int modid = ReadInt (m_process, link_map + metadata.modid_offset);
+    int modid_size = 4;  // FIXME(spucci): This isn't right for big-endian 64-bit
+    int64_t modid = ReadUnsignedIntWithSizeInBytes (link_map + metadata.modid_offset, modid_size);
     if (modid == -1)
         return LLDB_INVALID_ADDRESS;
 
     // Lookup the DTV stucture for this thread.
     addr_t dtv_ptr = tp + metadata.dtv_offset;
-    addr_t dtv = ReadPointer (m_process, dtv_ptr);
+    addr_t dtv = ReadPointer (dtv_ptr);
     if (dtv == LLDB_INVALID_ADDRESS)
         return LLDB_INVALID_ADDRESS;
 
     // Find the TLS block for this module.
     addr_t dtv_slot = dtv + metadata.dtv_slot_size*modid;
-    addr_t tls_block = ReadPointer (m_process, dtv_slot + metadata.tls_offset);
+    addr_t tls_block = ReadPointer (dtv_slot + metadata.tls_offset);
 
     Module *mod = module.get();
     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
     if (log)
         log->Printf("DynamicLoaderPOSIXDYLD::Performed TLS lookup: "
-                    "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64 ", modid=%i, tls_block=0x%" PRIx64 "\n",
-                    mod->GetObjectName().AsCString(""), link_map, tp, modid, tls_block);
+                    "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64 ", modid=%ld, tls_block=0x%" PRIx64 "\n",
+                    mod->GetObjectName().AsCString(""), link_map, tp, (int64_t)modid, tls_block);
 
     return tls_block;
 }
Index: source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
===================================================================
--- source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h	(revision 200851)
+++ source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h	(working copy)
@@ -126,7 +126,7 @@
     /// @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.
-    void
+    virtual void
     UpdateLoadedSections(lldb::ModuleSP module,
                          lldb::addr_t link_map_addr,
                          lldb::addr_t base_addr);
@@ -134,14 +134,9 @@
     /// Removes the loaded sections from the target in @p module.
     ///
     /// @param module The module to traverse.
-    void
+    virtual void
     UnloadSections(const lldb::ModuleSP module);
 
-    /// 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);
-
     /// Resolves the entry point for the current inferior process and sets a
     /// breakpoint at that address.
     void
@@ -173,16 +168,8 @@
     lldb::addr_t
     GetEntryPoint();
 
-    /// Checks to see if the target module has changed, updates the target
-    /// accordingly and returns the target executable module.
-    lldb::ModuleSP
-    GetTargetExecutable();
-
 private:
     DISALLOW_COPY_AND_ASSIGN(DynamicLoaderPOSIXDYLD);
-
-    const lldb_private::SectionList *
-    GetSectionListFromModule(const lldb::ModuleSP module) const;
 };
 
 #endif  // liblldb_DynamicLoaderPOSIXDYLD_H_
Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
===================================================================
--- source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp	(revision 200851)
+++ source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp	(working copy)
@@ -24,6 +24,7 @@
 #include "lldb/Core/Stream.h"
 #include "lldb/Symbol/DWARFCallFrameInfo.h"
 #include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/SectionLoadList.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Host/Host.h"
 
@@ -462,6 +463,39 @@
     return m_header.e_entry != 0;
 }
 
+bool
+ObjectFileELF::SetLoadAddress(Target &target, addr_t base_addr)
+{
+    bool changed = false;
+    ModuleSP module_sp = GetModule();
+    if (module_sp)
+    {
+        size_t num_loaded_sections = 0;
+        SectionList *section_list = GetSectionList ();
+        if (section_list)
+        {
+            const size_t num_sections = section_list->GetSize();
+            size_t sect_idx = 0;
+            for (sect_idx = 0; sect_idx < num_sections; ++sect_idx)
+            {
+                // Iterate through the object file sections to find the
+                // first section that starts of file offset zero and that
+                // has bytes in the file...
+                SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
+                // if (section_sp && !section_sp->IsThreadSpecific())
+                if (section_sp && section_sp->Test(SHF_ALLOC))
+                {
+                    if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + base_addr))
+                        ++num_loaded_sections;
+                }
+            }
+        }
+        changed = num_loaded_sections > 0;
+        return num_loaded_sections > 0;
+    }
+    return changed;
+}
+
 ByteOrder
 ObjectFileELF::GetByteOrder() const
 {
Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.h
===================================================================
--- source/Plugins/ObjectFile/ELF/ObjectFileELF.h	(revision 200851)
+++ source/Plugins/ObjectFile/ELF/ObjectFileELF.h	(working copy)
@@ -118,6 +118,9 @@
     virtual bool
     ParseHeader();
 
+    virtual bool
+    SetLoadAddress(lldb_private::Target &target, lldb::addr_t base_addr);
+
     virtual lldb::ByteOrder
     GetByteOrder() const;
 


More information about the lldb-dev mailing list