From 42ecef3b15e9b74fe6bf8dca6bae76650e095726 Mon Sep 17 00:00:00 2001 From: Tamas Berghammer Date: Mon, 24 Aug 2015 10:21:55 +0000 Subject: 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//maps) Differential revision: http://reviews.llvm.org/D12233 llvm-svn: 245834 --- .../Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 64 +++++++++++++--------- 1 file changed, 38 insertions(+), 26 deletions(-) (limited to 'lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp') diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 6cfc23a30b9c..c5930b48a86e 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -847,40 +847,52 @@ ObjectFileELF::SetLoadAddress (Target &target, 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 -- cgit v1.2.3