diff options
-rw-r--r-- | lldb/source/Core/DynamicLoader.cpp | 18 | ||||
-rw-r--r-- | lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp | 14 | ||||
-rw-r--r-- | lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 36 | ||||
-rw-r--r-- | lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h | 2 |
4 files changed, 59 insertions, 11 deletions
diff --git a/lldb/source/Core/DynamicLoader.cpp b/lldb/source/Core/DynamicLoader.cpp index 1f545b727a1..ffd7425f523 100644 --- a/lldb/source/Core/DynamicLoader.cpp +++ b/lldb/source/Core/DynamicLoader.cpp @@ -186,6 +186,24 @@ DynamicLoader::LoadModuleAtAddress(const FileSpec &file, addr_t link_map_addr, a { UpdateLoadedSections(module_sp, link_map_addr, base_addr); } + else + { + // Try to fetch the load address of the file from the process. It can be different from the + // address reported by the linker in case of a file with fixed load address because the + // linker reports the bias between the load address specified in the file and the actual + // load address it loaded the file. + bool is_loaded; + lldb::addr_t load_addr; + Error error = m_process->GetFileLoadAddress(file, is_loaded, load_addr); + if (error.Fail() || !is_loaded) + load_addr = base_addr; + + if ((module_sp = m_process->ReadModuleFromMemory(file, load_addr))) + { + UpdateLoadedSections(module_sp, link_map_addr, base_addr); + target.GetImages().AppendIfNeeded(module_sp); + } + } return module_sp; } diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp index 08feda52f5c..8b1dd283394 100644 --- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp +++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp @@ -410,12 +410,14 @@ DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry) if (!(addr = ReadPointer(addr, &entry.prev))) return false; - entry.file_spec.SetFile(ReadStringFromMemory(entry.path_addr), false); - - // The base_addr is not filled in for some case. - // Try to figure it out based on the load address of the object file. - // The issue observed for '/system/bin/linker' on Android L (5.0, 5.1) - if (entry.base_addr == 0) + std::string file_path = ReadStringFromMemory(entry.path_addr); + entry.file_spec.SetFile(file_path, false); + + // On Android L (5.0, 5.1) the load address of the "/system/bin/linker" isn't filled in + // correctly. To get the correct load address we fetch the load address of the file from the + // proc file system. + if (arch.GetTriple().getEnvironment() == llvm::Triple::Android && entry.base_addr == 0 && + (file_path == "/system/bin/linker" || file_path == "/system/bin/linker64")) { lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; bool is_loaded = false; diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 1ceaa2c3761..f9cec241538 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -807,10 +807,10 @@ ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp, } ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp, - DataBufferSP& data_sp, + DataBufferSP& header_data_sp, const lldb::ProcessSP &process_sp, addr_t header_addr) : - ObjectFile(module_sp, process_sp, LLDB_INVALID_ADDRESS, data_sp), + ObjectFile(module_sp, process_sp, header_addr, header_data_sp), m_header(), m_uuid(), m_gnu_debuglink_file(), @@ -860,7 +860,14 @@ ObjectFileELF::SetLoadAddress (Target &target, // if (section_sp && !section_sp->IsThreadSpecific()) if (section_sp && section_sp->Test(SHF_ALLOC)) { - if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + value)) + 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; } } @@ -933,7 +940,28 @@ bool ObjectFileELF::ParseHeader() { lldb::offset_t offset = 0; - return m_header.Parse(m_data, &offset); + if (!m_header.Parse(m_data, &offset)) + return false; + + if (!IsInMemory()) + return true; + + // For in memory object files m_data might not contain the full object file. Try to load it + // until the end of the "Section header table" what is at the end of the ELF file. + addr_t file_size = m_header.e_shoff + m_header.e_shnum * m_header.e_shentsize; + if (m_data.GetByteSize() < file_size) + { + ProcessSP process_sp (m_process_wp.lock()); + if (!process_sp) + return false; + + DataBufferSP data_sp = ReadMemory(process_sp, m_memory_addr, file_size); + if (!data_sp) + return false; + m_data.SetData(data_sp, 0, file_size); + } + + return true; } bool diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h index 8ea3daba327..99088d166b1 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -199,7 +199,7 @@ private: lldb::offset_t length); ObjectFileELF (const lldb::ModuleSP &module_sp, - lldb::DataBufferSP& data_sp, + lldb::DataBufferSP& header_data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); |