summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/source/Core/DynamicLoader.cpp18
-rw-r--r--lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp14
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp36
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h2
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);
OpenPOWER on IntegriCloud