Modified ObjectFile::SetLoadAddress() to now be:

ObjectFile::SetLoadAddress (Target &target,
                            lldb::addr_t value,
                            bool value_is_offset);

Now "value" is a slide if "value_is_offset" is true, and "value" is an image base address otherwise. All previous usage of this API was using slides.

Updated the ObjectFileELF and ObjectFileMachO SetLoadAddress methods to do the right thing.

Also updated the ObjectFileMachO::SetLoadAddress() function to not load __LINKEDIT when it isn't needed and to only load sections that belong to the executable object file.

llvm-svn: 201003
This commit is contained in:
Greg Clayton
2014-02-07 22:54:47 +00:00
parent c7fb225cdc
commit 751caf65c2
12 changed files with 139 additions and 50 deletions

View File

@@ -4706,7 +4706,9 @@ ObjectFileMachO::GetPluginVersion()
bool
ObjectFileMachO::SetLoadAddress(Target &target, addr_t base_addr)
ObjectFileMachO::SetLoadAddress (Target &target,
lldb::addr_t value,
bool value_is_offset)
{
bool changed = false;
ModuleSP module_sp = GetModule();
@@ -4719,39 +4721,98 @@ ObjectFileMachO::SetLoadAddress(Target &target, addr_t base_addr)
lldb::addr_t mach_base_file_addr = LLDB_INVALID_ADDRESS;
const size_t num_sections = section_list->GetSize();
// First find the address of the mach header which is the first non-zero
// file sized section whose file offset is zero as this will be subtracted
// from each other valid section's vmaddr and then get "base_addr" added to
// it when loading the module in the target
for (size_t sect_idx = 0;
sect_idx < num_sections && mach_base_file_addr == LLDB_INVALID_ADDRESS;
++sect_idx)
{
// Iterate through the object file sections to find all
// of the sections that size on disk (to avoid __PAGEZERO)
// and load them
Section *section = section_list->GetSectionAtIndex (sect_idx).get();
if (section && section->GetFileSize() > 0 && section->GetFileOffset() == 0)
{
mach_base_file_addr = section->GetFileAddress();
}
}
if (mach_base_file_addr != LLDB_INVALID_ADDRESS)
const bool is_memory_image = (bool)m_process_wp.lock();
const Strata strata = GetStrata();
static ConstString g_linkedit_segname ("__LINKEDIT");
if (value_is_offset)
{
// "value" is an offset to apply to each top level segment
for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
{
// Iterate through the object file sections to find all
// of the sections that size on disk (to avoid __PAGEZERO)
// and load them
SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
if (section_sp && section_sp->GetFileSize() > 0 && !section_sp->IsThreadSpecific())
if (section_sp &&
section_sp->GetFileSize() > 0 &&
section_sp->IsThreadSpecific() == false &&
module_sp.get() == section_sp->GetModule().get())
{
if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() - mach_base_file_addr + base_addr))
// Ignore __LINKEDIT and __DWARF segments
if (section_sp->GetName() == g_linkedit_segname)
{
// Only map __LINKEDIT if we have an in memory image and this isn't
// a kernel binary like a kext or mach_kernel.
if (is_memory_image == false || strata == eStrataKernel)
continue;
}
if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + value))
++num_loaded_sections;
}
}
}
else
{
// "value" is the new base address of the mach_header, adjust each
// section accordingly
// First find the address of the mach header which is the first non-zero
// file sized section whose file offset is zero as this will be subtracted
// from each other valid section's vmaddr and then get "base_addr" added to
// it when loading the module in the target
for (size_t sect_idx = 0;
sect_idx < num_sections && mach_base_file_addr == LLDB_INVALID_ADDRESS;
++sect_idx)
{
// Iterate through the object file sections to find all
// of the sections that size on disk (to avoid __PAGEZERO)
// and load them
Section *section = section_list->GetSectionAtIndex (sect_idx).get();
if (section &&
section->GetFileSize() > 0 &&
section->GetFileOffset() == 0 &&
section->IsThreadSpecific() == false &&
module_sp.get() == section->GetModule().get())
{
// Ignore __LINKEDIT and __DWARF segments
if (section->GetName() == g_linkedit_segname)
{
// Only map __LINKEDIT if we have an in memory image and this isn't
// a kernel binary like a kext or mach_kernel.
if (is_memory_image == false || strata == eStrataKernel)
continue;
}
mach_base_file_addr = section->GetFileAddress();
}
}
if (mach_base_file_addr != LLDB_INVALID_ADDRESS)
{
for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
{
// Iterate through the object file sections to find all
// of the sections that size on disk (to avoid __PAGEZERO)
// and load them
SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
if (section_sp &&
section_sp->GetFileSize() > 0 &&
section_sp->IsThreadSpecific() == false &&
module_sp.get() == section_sp->GetModule().get())
{
// Ignore __LINKEDIT and __DWARF segments
if (section_sp->GetName() == g_linkedit_segname)
{
// Only map __LINKEDIT if we have an in memory image and this isn't
// a kernel binary like a kext or mach_kernel.
if (is_memory_image == false || strata == eStrataKernel)
continue;
}
if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() - mach_base_file_addr + value))
++num_loaded_sections;
}
}
}
}
}
changed = num_loaded_sections > 0;
return num_loaded_sections > 0;