diff options
author | Tamas Berghammer <tberghammer@google.com> | 2015-08-24 10:21:55 +0000 |
---|---|---|
committer | Tamas Berghammer <tberghammer@google.com> | 2015-08-24 10:21:55 +0000 |
commit | 42ecef3b15e9b74fe6bf8dca6bae76650e095726 (patch) | |
tree | a4592ace7d88f818a589866232d7b724ece2c053 /lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | |
parent | 71ad47f81fb33bbbf0a0713006691ed0c0550b3f (diff) | |
download | bcm5719-llvm-42ecef3b15e9b74fe6bf8dca6bae76650e095726.tar.gz bcm5719-llvm-42ecef3b15e9b74fe6bf8dca6bae76650e095726.zip |
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/<pid>/maps)
Differential revision: http://reviews.llvm.org/D12233
llvm-svn: 245834
Diffstat (limited to 'lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp')
-rw-r--r-- | lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 64 |
1 files changed, 38 insertions, 26 deletions
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 6cfc23a30b9..c5930b48a86 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 |