[lldb-dev] [PATCH] factor methods in DynamicLoaderPOSIXDYLD into base class
Steve Pucci
spucci at google.com
Wed Jan 29 13:45:09 PST 2014
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
>> > >
>> > >
>> >
>> >
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20140129/b1fe26eb/attachment.html>
-------------- next part --------------
Index: include/lldb/Symbol/ObjectFile.h
===================================================================
--- include/lldb/Symbol/ObjectFile.h (revision 200416)
+++ 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 200416)
+++ include/lldb/Target/DynamicLoader.h (working copy)
@@ -246,6 +246,59 @@
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 link_map_addr,
+ 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 int from the given process from memory at the given addr
+ static int
+ ReadInt(Process *process, lldb::addr_t addr);
+
+ // Read a pointer from the given process from memory at the given addr
+ static lldb::addr_t
+ ReadPointer(Process *process, 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 200416)
+++ 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,135 @@
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, link_map_addr, base_addr);
+}
+
+void
+DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module, addr_t link_map_addr, 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;
+}
+
+int
+DynamicLoader::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;
+}
+
+addr_t
+DynamicLoader::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;
+}
Index: source/Core/Module.cpp
===================================================================
--- source/Core/Module.cpp (revision 200416)
+++ 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 200416)
+++ 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, link_map_addr, 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)
{
Index: source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
===================================================================
--- source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h (revision 200416)
+++ 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 200416)
+++ 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 200416)
+++ 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