[Lldb-commits] [lldb] r241057 - Fix [vdso] handling on Android (x86 and aarch64)

Tamas Berghammer tberghammer at google.com
Tue Jun 30 03:41:24 PDT 2015


Author: tberghammer
Date: Tue Jun 30 05:41:23 2015
New Revision: 241057

URL: http://llvm.org/viewvc/llvm-project?rev=241057&view=rev
Log:
Fix [vdso] handling on Android (x86 and aarch64)

* Add in-memory object file handling to the core dynamic loader
* Fix in memory object file handling in ObjectFileELF (previously
  only part of the file was loaded before parsing)
* Fix load address setting in ObjectFileELF for 32-bit targets
  when the load bias is negative
* Change hack in DYLDRendezvous.cpp to be more specific and not to
  interfere with object files with fixed load address

Differential revision: http://reviews.llvm.org/D10800

Modified:
    lldb/trunk/source/Core/DynamicLoader.cpp
    lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
    lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
    lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h

Modified: lldb/trunk/source/Core/DynamicLoader.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/DynamicLoader.cpp?rev=241057&r1=241056&r2=241057&view=diff
==============================================================================
--- lldb/trunk/source/Core/DynamicLoader.cpp (original)
+++ lldb/trunk/source/Core/DynamicLoader.cpp Tue Jun 30 05:41:23 2015
@@ -186,6 +186,24 @@ DynamicLoader::LoadModuleAtAddress(const
     {
         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;
 }

Modified: lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp?rev=241057&r1=241056&r2=241057&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp Tue Jun 30 05:41:23 2015
@@ -410,12 +410,14 @@ DYLDRendezvous::ReadSOEntryFromMemory(ll
     if (!(addr = ReadPointer(addr, &entry.prev)))
         return false;
 
-    entry.file_spec.SetFile(ReadStringFromMemory(entry.path_addr), false);
+    std::string file_path = ReadStringFromMemory(entry.path_addr);
+    entry.file_spec.SetFile(file_path, 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)
+    // 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;

Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=241057&r1=241056&r2=241057&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Tue Jun 30 05:41:23 2015
@@ -807,10 +807,10 @@ ObjectFileELF::ObjectFileELF (const lldb
 }
 
 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 &t
                     // 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

Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h?rev=241057&r1=241056&r2=241057&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h Tue Jun 30 05:41:23 2015
@@ -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);
 





More information about the lldb-commits mailing list