[Lldb-commits] [lldb] r305780 - [linux] Change the way we load vdso pseudo-module

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Tue Jun 20 01:11:47 PDT 2017


Author: labath
Date: Tue Jun 20 03:11:47 2017
New Revision: 305780

URL: http://llvm.org/viewvc/llvm-project?rev=305780&view=rev
Log:
[linux] Change the way we load vdso pseudo-module

Summary:
This is basically a revert of D16107 and parts of D10800, which were
trying to get vdso loading working. They did this by implementing a
generic load-an-elf-file from memory approach, which is not correct,
since we cannot assume that an elf file is loaded in memory in full (it
usually isn't, as there's no need to load section headers for example).
This meant that we would read garbage instead of section sizes, and if
that garbage happened to be a large number, we would crash while trying
to allocate a buffer to accomodate the hypothetical section.

Instead of this, I add a bit of custom code to load the vdso to
DynamicLoaderPOSIXDYLD (which already needed to handle the vdso
specially). I determine the size of the memory to read using
Process::GetMemoryRegionInfo, which is information coming from the OS,
and cannot be forged by a malicious/misbehaving application.

Reviewers: eugene, clayborg

Subscribers: lldb-commits, ravitheja, tberghammer, emaste

Differential Revision: https://reviews.llvm.org/D34352

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

Modified: lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp?rev=305780&r1=305779&r2=305780&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp Tue Jun 20 03:11:47 2017
@@ -21,6 +21,7 @@
 #include "lldb/Core/Section.h"
 #include "lldb/Symbol/Function.h"
 #include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/MemoryRegionInfo.h"
 #include "lldb/Target/Platform.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
@@ -484,6 +485,27 @@ DynamicLoaderPOSIXDYLD::GetStepThroughTr
   return thread_plan_sp;
 }
 
+void DynamicLoaderPOSIXDYLD::LoadVDSO(ModuleList &modules) {
+  if (m_vdso_base == LLDB_INVALID_ADDRESS)
+    return;
+
+  FileSpec file("[vdso]", false);
+
+  MemoryRegionInfo info;
+  Status status = m_process->GetMemoryRegionInfo(m_vdso_base, info);
+  if (status.Fail()) {
+    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+    LLDB_LOG(log, "Failed to get vdso region info: {0}", status);
+    return;
+  }
+
+  if (ModuleSP module_sp = m_process->ReadModuleFromMemory(
+          file, m_vdso_base, info.GetRange().GetByteSize())) {
+    UpdateLoadedSections(module_sp, LLDB_INVALID_ADDRESS, m_vdso_base, false);
+    m_process->GetTarget().GetImages().AppendIfNeeded(module_sp);
+  }
+}
+
 void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() {
   DYLDRendezvous::iterator I;
   DYLDRendezvous::iterator E;
@@ -502,14 +524,7 @@ void DynamicLoaderPOSIXDYLD::LoadAllCurr
   // that ourselves here.
   ModuleSP executable = GetTargetExecutable();
   m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress();
-  if (m_vdso_base != LLDB_INVALID_ADDRESS) {
-    FileSpec file_spec("[vdso]", false);
-    ModuleSP module_sp = LoadModuleAtAddress(file_spec, LLDB_INVALID_ADDRESS,
-                                             m_vdso_base, false);
-    if (module_sp.get()) {
-      module_list.Append(module_sp);
-    }
-  }
+  LoadVDSO(module_list);
 
   std::vector<FileSpec> module_names;
   for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)

Modified: lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h?rev=305780&r1=305779&r2=305780&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h Tue Jun 20 03:11:47 2017
@@ -17,11 +17,11 @@
 
 // Other libraries and framework includes
 // Project includes
+#include "DYLDRendezvous.h"
 #include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Core/ModuleList.h"
 #include "lldb/Target/DynamicLoader.h"
 
-#include "DYLDRendezvous.h"
-
 class AuxVector;
 
 class DynamicLoaderPOSIXDYLD : public lldb_private::DynamicLoader {
@@ -138,6 +138,8 @@ protected:
   /// of all dependent modules.
   virtual void LoadAllCurrentModules();
 
+  void LoadVDSO(lldb_private::ModuleList &modules);
+
   /// Computes a value for m_load_offset returning the computed address on
   /// success and LLDB_INVALID_ADDRESS on failure.
   lldb::addr_t ComputeLoadOffset();

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=305780&r1=305779&r2=305780&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Tue Jun 20 03:11:47 2017
@@ -707,10 +707,7 @@ size_t ObjectFileELF::GetModuleSpecifica
           SectionHeaderColl section_headers;
           lldb_private::UUID &uuid = spec.GetUUID();
 
-          using namespace std::placeholders;
-          const SetDataFunction set_data =
-              std::bind(&ObjectFileELF::SetData, std::cref(data), _1, _2, _3);
-          GetSectionHeaderInfo(section_headers, set_data, header, uuid,
+          GetSectionHeaderInfo(section_headers, data, header, uuid,
                                gnu_debuglink_file, gnu_debuglink_crc,
                                spec.GetArchitecture());
 
@@ -748,7 +745,7 @@ size_t ObjectFileELF::GetModuleSpecifica
                     data.SetData(data_sp);
                 }
                 ProgramHeaderColl program_headers;
-                GetProgramHeaderInfo(program_headers, set_data, header);
+                GetProgramHeaderInfo(program_headers, data, header);
 
                 size_t segment_data_end = 0;
                 for (ProgramHeaderCollConstIter I = program_headers.begin();
@@ -950,29 +947,7 @@ size_t ObjectFileELF::SectionIndex(const
 
 bool ObjectFileELF::ParseHeader() {
   lldb::offset_t offset = 0;
-  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;
+  return m_header.Parse(m_data, &offset);
 }
 
 bool ObjectFileELF::GetUUID(lldb_private::UUID *uuid) {
@@ -1188,7 +1163,7 @@ size_t ObjectFileELF::ParseDependentModu
 // GetProgramHeaderInfo
 //----------------------------------------------------------------------
 size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
-                                           const SetDataFunction &set_data,
+                                           DataExtractor &object_data,
                                            const ELFHeader &header) {
   // We have already parsed the program headers
   if (!program_headers.empty())
@@ -1205,7 +1180,7 @@ size_t ObjectFileELF::GetProgramHeaderIn
   const size_t ph_size = header.e_phnum * header.e_phentsize;
   const elf_off ph_offset = header.e_phoff;
   DataExtractor data;
-  if (set_data(data, ph_offset, ph_size) != ph_size)
+  if (data.SetData(object_data, ph_offset, ph_size) != ph_size)
     return 0;
 
   uint32_t idx;
@@ -1225,12 +1200,7 @@ size_t ObjectFileELF::GetProgramHeaderIn
 // ParseProgramHeaders
 //----------------------------------------------------------------------
 size_t ObjectFileELF::ParseProgramHeaders() {
-  using namespace std::placeholders;
-  return GetProgramHeaderInfo(
-      m_program_headers,
-      std::bind(&ObjectFileELF::SetDataWithReadMemoryFallback, this, _1, _2,
-                _3),
-      m_header);
+  return GetProgramHeaderInfo(m_program_headers, m_data, m_header);
 }
 
 lldb_private::Status
@@ -1562,7 +1532,7 @@ void ObjectFileELF::ParseARMAttributes(D
 // GetSectionHeaderInfo
 //----------------------------------------------------------------------
 size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
-                                           const SetDataFunction &set_data,
+                                           DataExtractor &object_data,
                                            const elf::ELFHeader &header,
                                            lldb_private::UUID &uuid,
                                            std::string &gnu_debuglink_file,
@@ -1634,7 +1604,7 @@ size_t ObjectFileELF::GetSectionHeaderIn
   const size_t sh_size = header.e_shnum * header.e_shentsize;
   const elf_off sh_offset = header.e_shoff;
   DataExtractor sh_data;
-  if (set_data(sh_data, sh_offset, sh_size) != sh_size)
+  if (sh_data.SetData(object_data, sh_offset, sh_size) != sh_size)
     return 0;
 
   uint32_t idx;
@@ -1653,7 +1623,7 @@ size_t ObjectFileELF::GetSectionHeaderIn
     const Elf64_Off offset = sheader.sh_offset;
     lldb_private::DataExtractor shstr_data;
 
-    if (set_data(shstr_data, offset, byte_size) == byte_size) {
+    if (shstr_data.SetData(object_data, offset, byte_size) == byte_size) {
       for (SectionHeaderCollIter I = section_headers.begin();
            I != section_headers.end(); ++I) {
         static ConstString g_sect_name_gnu_debuglink(".gnu_debuglink");
@@ -1669,8 +1639,8 @@ size_t ObjectFileELF::GetSectionHeaderIn
           DataExtractor data;
           if (sheader.sh_type == SHT_MIPS_ABIFLAGS) {
 
-            if (section_size && (set_data(data, sheader.sh_offset,
-                                          section_size) == section_size)) {
+            if (section_size && (data.SetData(object_data, sheader.sh_offset,
+                                              section_size) == section_size)) {
               // MIPS ASE Mask is at offset 12 in MIPS.abiflags section
               lldb::offset_t offset = 12; // MIPS ABI Flags Version: 0
               arch_flags |= data.GetU32(&offset);
@@ -1735,14 +1705,14 @@ size_t ObjectFileELF::GetSectionHeaderIn
           DataExtractor data;
 
           if (sheader.sh_type == SHT_ARM_ATTRIBUTES && section_size != 0 &&
-              set_data(data, sheader.sh_offset, section_size) == section_size)
+              data.SetData(object_data, sheader.sh_offset, section_size) == section_size)
             ParseARMAttributes(data, section_size, arch_spec);
         }
 
         if (name == g_sect_name_gnu_debuglink) {
           DataExtractor data;
-          if (section_size && (set_data(data, sheader.sh_offset,
-                                        section_size) == section_size)) {
+          if (section_size && (data.SetData(object_data, sheader.sh_offset,
+                                            section_size) == section_size)) {
             lldb::offset_t gnu_debuglink_offset = 0;
             gnu_debuglink_file = data.GetCStr(&gnu_debuglink_offset);
             gnu_debuglink_offset = llvm::alignTo(gnu_debuglink_offset, 4);
@@ -1762,8 +1732,8 @@ size_t ObjectFileELF::GetSectionHeaderIn
         if (is_note_header) {
           // Allow notes to refine module info.
           DataExtractor data;
-          if (section_size && (set_data(data, sheader.sh_offset,
-                                        section_size) == section_size)) {
+          if (section_size && (data.SetData(object_data, sheader.sh_offset,
+                                            section_size) == section_size)) {
             Status error = RefineModuleDetailsFromNote(data, arch_spec, uuid);
             if (error.Fail()) {
               if (log)
@@ -1819,40 +1789,9 @@ ObjectFileELF::StripLinkerSymbolAnnotati
 // ParseSectionHeaders
 //----------------------------------------------------------------------
 size_t ObjectFileELF::ParseSectionHeaders() {
-  using namespace std::placeholders;
-
-  return GetSectionHeaderInfo(
-      m_section_headers,
-      std::bind(&ObjectFileELF::SetDataWithReadMemoryFallback, this, _1, _2,
-                _3),
-      m_header, m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc, m_arch_spec);
-}
-
-lldb::offset_t ObjectFileELF::SetData(const lldb_private::DataExtractor &src,
-                                      lldb_private::DataExtractor &dst,
-                                      lldb::offset_t offset,
-                                      lldb::offset_t length) {
-  return dst.SetData(src, offset, length);
-}
-
-lldb::offset_t
-ObjectFileELF::SetDataWithReadMemoryFallback(lldb_private::DataExtractor &dst,
-                                             lldb::offset_t offset,
-                                             lldb::offset_t length) {
-  if (offset + length <= m_data.GetByteSize())
-    return dst.SetData(m_data, offset, length);
-
-  const auto process_sp = m_process_wp.lock();
-  if (process_sp != nullptr) {
-    addr_t file_size = offset + length;
-
-    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 dst.SetData(m_data, offset, length);
+  return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid,
+                              m_gnu_debuglink_file, m_gnu_debuglink_crc,
+                              m_arch_spec);
 }
 
 const ObjectFileELF::ELFSectionHeaderInfo *

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=305780&r1=305779&r2=305780&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h Tue Jun 20 03:11:47 2017
@@ -14,7 +14,6 @@
 #include <stdint.h>
 
 // C++ Includes
-#include <functional>
 #include <vector>
 
 // Other libraries and framework includes
@@ -182,9 +181,6 @@ private:
 
   typedef std::map<lldb::addr_t, lldb::AddressClass>
       FileAddressToAddressClassMap;
-  typedef std::function<lldb::offset_t(lldb_private::DataExtractor &,
-                                       lldb::offset_t, lldb::offset_t)>
-      SetDataFunction;
 
   /// Version of this reader common to all plugins based on this class.
   static const uint32_t m_plugin_version = 1;
@@ -230,7 +226,7 @@ private:
 
   // Parses the ELF program headers.
   static size_t GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
-                                     const SetDataFunction &set_data,
+                                     lldb_private::DataExtractor &object_data,
                                      const elf::ELFHeader &header);
 
   // Finds PT_NOTE segments and calculates their crc sum.
@@ -255,7 +251,7 @@ private:
   /// Parses the elf section headers and returns the uuid, debug link name, crc,
   /// archspec.
   static size_t GetSectionHeaderInfo(SectionHeaderColl &section_headers,
-                                     const SetDataFunction &set_data,
+                                     lldb_private::DataExtractor &object_data,
                                      const elf::ELFHeader &header,
                                      lldb_private::UUID &uuid,
                                      std::string &gnu_debuglink_file,
@@ -379,14 +375,6 @@ private:
   RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
                               lldb_private::ArchSpec &arch_spec,
                               lldb_private::UUID &uuid);
-
-  static lldb::offset_t SetData(const lldb_private::DataExtractor &src,
-                                lldb_private::DataExtractor &dst,
-                                lldb::offset_t offset, lldb::offset_t length);
-
-  lldb::offset_t SetDataWithReadMemoryFallback(lldb_private::DataExtractor &dst,
-                                               lldb::offset_t offset,
-                                               lldb::offset_t length);
 };
 
 #endif // liblldb_ObjectFileELF_h_




More information about the lldb-commits mailing list