diff options
Diffstat (limited to 'lldb/source/Plugins/ObjectFile')
4 files changed, 112 insertions, 36 deletions
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 2f3cd8b78cf..02db05b3c6b 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -464,7 +464,9 @@ ObjectFileELF::IsExecutable() const } bool -ObjectFileELF::SetLoadAddress(Target &target, addr_t base_addr) +ObjectFileELF::SetLoadAddress (Target &target, + lldb::addr_t value, + bool value_is_offset) { bool changed = false; ModuleSP module_sp = GetModule(); @@ -474,23 +476,32 @@ ObjectFileELF::SetLoadAddress(Target &target, addr_t base_addr) 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) + if (value_is_offset) { - // 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)) + const size_t num_sections = section_list->GetSize(); + size_t sect_idx = 0; + + for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) { - if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + base_addr)) - ++num_loaded_sections; + // 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)) + { + if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + value)) + ++num_loaded_sections; + } } + changed = num_loaded_sections > 0; + return num_loaded_sections > 0; + } + else + { + // Not sure how to slide an ELF file given the base address + // of the ELF file in memory } } - changed = num_loaded_sections > 0; - return num_loaded_sections > 0; } return changed; } diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h index 4fb0250108a..9b7c073d902 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -119,7 +119,9 @@ public: ParseHeader(); virtual bool - SetLoadAddress(lldb_private::Target &target, lldb::addr_t base_addr); + SetLoadAddress (lldb_private::Target &target, + lldb::addr_t value, + bool value_is_offset); virtual lldb::ByteOrder GetByteOrder() const; diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index 5cbb31ef5b2..a4bfc5caec5 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -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,36 +4721,95 @@ 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) + const bool is_memory_image = (bool)m_process_wp.lock(); + const Strata strata = GetStrata(); + static ConstString g_linkedit_segname ("__LINKEDIT"); + if (value_is_offset) { - // 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) + // "value" is an offset to apply to each top level segment + for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) { - mach_base_file_addr = section->GetFileAddress(); + // 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() + value)) + ++num_loaded_sections; + } } } - - if (mach_base_file_addr != LLDB_INVALID_ADDRESS) + else { - for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) + // "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 - SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx)); - if (section_sp && section_sp->GetFileSize() > 0 && !section_sp->IsThreadSpecific()) + 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()) { - if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() - mach_base_file_addr + base_addr)) - ++num_loaded_sections; + // 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; + } } } } diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h index e1ab99959b5..f6b0e3a89cc 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h @@ -90,7 +90,9 @@ public: ParseHeader (); virtual bool - SetLoadAddress(lldb_private::Target &target, lldb::addr_t base_addr); + SetLoadAddress(lldb_private::Target &target, + lldb::addr_t value, + bool value_is_offset); virtual lldb::ByteOrder GetByteOrder () const; |