labath updated this revision to Diff 125110.
labath added a comment.

Rebase on master and update the test.


https://reviews.llvm.org/D40616

Files:
  lit/CMakeLists.txt
  lit/Modules/compressed-sections.yaml
  lit/Modules/lit.local.cfg
  lit/lit.cfg
  lit/lit.site.cfg.in
  source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
  source/Plugins/ObjectFile/ELF/ObjectFileELF.h
  tools/lldb-test/lldb-test.cpp
  unittests/ObjectFile/ELF/TestObjectFileELF.cpp

Index: unittests/ObjectFile/ELF/TestObjectFileELF.cpp
===================================================================
--- unittests/ObjectFile/ELF/TestObjectFileELF.cpp
+++ unittests/ObjectFile/ELF/TestObjectFileELF.cpp
@@ -10,12 +10,13 @@
 
 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
 #include "Plugins/SymbolVendor/ELF/SymbolVendorELF.h"
+#include "TestingSupport/TestUtilities.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Host/HostInfo.h"
-#include "TestingSupport/TestUtilities.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/Support/Compression.h"
 #include "llvm/Support/FileUtilities.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
Index: tools/lldb-test/lldb-test.cpp
===================================================================
--- tools/lldb-test/lldb-test.cpp
+++ tools/lldb-test/lldb-test.cpp
@@ -64,7 +64,8 @@
       assert(S);
       Printer.formatLine("Index: {0}", I);
       Printer.formatLine("Name: {0}", S->GetName().GetStringRef());
-      Printer.formatLine("Length: {0}", S->GetByteSize());
+      Printer.formatLine("VM size: {0}", S->GetByteSize());
+      Printer.formatLine("File size: {0}", S->GetFileSize());
 
       if (opts::module::SectionContents) {
         DataExtractor Data;
Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.h
===================================================================
--- source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -21,6 +21,7 @@
 #include "lldb/Utility/FileSpec.h"
 #include "lldb/Utility/UUID.h"
 #include "lldb/lldb-private.h"
+#include "llvm/Object/Decompressor.h"
 
 #include "ELFHeader.h"
 
@@ -140,6 +141,9 @@
 
   ObjectFile::Strata CalculateStrata() override;
 
+  size_t ReadSectionData(lldb_private::Section *section,
+                         lldb_private::DataExtractor &section_data) override;
+
   // Returns number of program headers found in the ELF file.
   size_t GetProgramHeaderCount();
 
@@ -244,6 +248,11 @@
   /// Returns the number of headers parsed.
   size_t ParseSectionHeaders();
 
+  llvm::Expected<llvm::object::Decompressor>
+  GetSectionDecompressor(const ELFSectionHeaderInfo &sect);
+
+  llvm::Expected<uint64_t> GetSectionFileSize(const ELFSectionHeaderInfo &sect);
+
   static void ParseARMAttributes(lldb_private::DataExtractor &data,
                                  uint64_t length,
                                  lldb_private::ArchSpec &arch_spec);
Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
===================================================================
--- source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -23,6 +23,7 @@
 #include "lldb/Target/SectionLoadList.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/DataBufferHeap.h"
 #include "lldb/Utility/DataBufferLLVM.h"
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/Status.h"
@@ -1814,7 +1815,38 @@
   return 0;
 }
 
+llvm::Expected<llvm::object::Decompressor>
+ObjectFileELF::GetSectionDecompressor(const ELFSectionHeaderInfo &sect) {
+  const uint8_t *start = m_data.PeekData(sect.sh_offset, sect.sh_size);
+  if (!start)
+    return llvm::make_error<llvm::StringError>(
+        "Invalid section file address or size.",
+        llvm::inconvertibleErrorCode());
+  llvm::StringRef data(reinterpret_cast<const char *>(start), sect.sh_size);
+
+  return llvm::object::Decompressor::create(
+      sect.section_name.GetStringRef(), data,
+      GetByteOrder() == eByteOrderLittle, GetAddressByteSize() == 8);
+}
+
+llvm::Expected<uint64_t>
+ObjectFileELF::GetSectionFileSize(const ELFSectionHeaderInfo &sect) {
+  if (sect.sh_type == SHT_NOBITS)
+    return 0;
+
+  if (!(sect.sh_flags & SHF_COMPRESSED))
+    return sect.sh_size;
+
+  auto Decompressor = GetSectionDecompressor(sect);
+  if (!Decompressor)
+    return Decompressor.takeError();
+
+  return Decompressor->getDecompressedSize();
+}
+
 void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
+  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES);
+
   if (!m_sections_ap.get() && ParseSectionHeaders()) {
     m_sections_ap.reset(new SectionList());
 
@@ -1829,8 +1861,12 @@
       const ELFSectionHeaderInfo &header = *I;
 
       ConstString &name = I->section_name;
-      const uint64_t file_size =
-          header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
+      auto file_size = GetSectionFileSize(header);
+      if (!file_size) {
+        LLDB_LOG(log, "Ignoring section {0}: {1}", name,
+                 llvm::toString(file_size.takeError()));
+        continue;
+      }
       const uint64_t vm_size = header.sh_flags & SHF_ALLOC ? header.sh_size : 0;
 
       static ConstString g_sect_name_text(".text");
@@ -2018,7 +2054,7 @@
           addr,                // VM address.
           vm_size,             // VM size in bytes of this section.
           header.sh_offset,    // Offset of this section in the file.
-          file_size,           // Size of the section as found in the file.
+          *file_size,          // Size of the section as found in the file.
           log2align,           // Alignment of the section
           header.sh_flags,     // Flags for this section.
           target_bytes_size)); // Number of host bytes per target byte
@@ -3452,3 +3488,32 @@
   }
   return eStrataUnknown;
 }
+
+size_t ObjectFileELF::ReadSectionData(Section *section,
+                                      DataExtractor &section_data) {
+  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES);
+
+  if (section->GetObjectFile() != this)
+    return section->GetObjectFile()->ReadSectionData(section, section_data);
+  if (section->GetFileSize() == 0)
+    return 0;
+  if (!section->Test(SHF_COMPRESSED))
+    return ObjectFile::ReadSectionData(section, section_data);
+
+  const ELFSectionHeaderInfo *info = GetSectionHeaderByIndex(section->GetID());
+  // Decompressor construction checked in GetSectionFileSize. Only valid
+  // sections are created.
+  auto Decompressor = llvm::cantFail(GetSectionDecompressor(*info));
+  auto buffer_sp =
+      std::make_shared<DataBufferHeap>(Decompressor.getDecompressedSize(), 0);
+  if (auto Error = Decompressor.decompress(
+          {reinterpret_cast<char *>(buffer_sp->GetBytes()),
+           buffer_sp->GetByteSize()})) {
+    LLDB_LOG(log, "Decompression of section {0} failed: {1}",
+             section->GetName(), llvm::toString(std::move(Error)));
+    return 0;
+  }
+
+  section_data.SetData(buffer_sp);
+  return buffer_sp->GetByteSize();
+}
Index: lit/lit.site.cfg.in
===================================================================
--- lit/lit.site.cfg.in
+++ lit/lit.site.cfg.in
@@ -12,6 +12,7 @@
 config.python_executable = "@PYTHON_EXECUTABLE@"
 config.cc = "@LLDB_TEST_C_COMPILER@"
 config.cxx = "@LLDB_TEST_CXX_COMPILER@"
+config.have_zlib = @HAVE_LIBZ@
 
 # Support substitution of the tools and libs dirs with user parameters. This is
 # used when we can't determine the tool dir at configuration time.
Index: lit/lit.cfg
===================================================================
--- lit/lit.cfg
+++ lit/lit.cfg
@@ -9,6 +9,9 @@
 import lit.formats
 import lit.util
 
+def binary_feature(on, feature, off_prefix):
+  return feature if on else off_prefix + feature
+
 # Configuration file for the 'lit' test runner.
 
 # name: The name of this test suite.
@@ -81,6 +84,8 @@
     config.substitutions.append(('%debugserver', debugserver))
 
 for pattern in [r"\bFileCheck\b",
+                r"\blldb-test\b",
+                r"\byaml2obj\b",
                 r"\| \bnot\b"]:
     tool_match = re.match(r"^(\\)?((\| )?)\W+b([0-9A-Za-z-_]+)\\b\W*$",
                           pattern)
@@ -125,6 +130,8 @@
 elif re.match(r'cl', config.cc):
     config.available_features.add("compiler-msvc")
 
+config.available_features.add(binary_feature(config.have_zlib, "zlib", "no"))
+
 # llvm-config knows whether it is compiled with asserts (and)
 # whether we are operating in release/debug mode.
 import subprocess
Index: lit/Modules/lit.local.cfg
===================================================================
--- /dev/null
+++ lit/Modules/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.yaml']
Index: lit/Modules/compressed-sections.yaml
===================================================================
--- /dev/null
+++ lit/Modules/compressed-sections.yaml
@@ -0,0 +1,28 @@
+# REQUIRES: zlib
+# RUN: yaml2obj %s > %t.elf
+# RUN: lldb-test module-sections --contents %t.elf > %t.dump
+# RUN: FileCheck %s <%t.dump
+# RUN: FileCheck --check-prefix CHECK2 %s <%t.dump
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_386
+Sections:
+  - Name:            .hello_elf
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_COMPRESSED ]
+    Content:         010000000800000001000000789c5330700848286898000009c802c1
+  - Name:            .bogus
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_COMPRESSED ]
+    Content:         deadbeefbaadf00d
+
+# CHECK: Name: .hello_elf
+# CHECK-NEXT: VM size: 0
+# CHECK-NEXT: File size: 8
+# CHECK-NEXT: Data:
+# CHECK-NEXT: 20304050 60708090
+
+# CHECK2-NOT: Name: .bogus
Index: lit/CMakeLists.txt
===================================================================
--- lit/CMakeLists.txt
+++ lit/CMakeLists.txt
@@ -22,10 +22,11 @@
 set(LLDB_TEST_DEPS
   LLDBUnitTests
   lldb
+  lldb-test
   )
 
 if(NOT LLDB_BUILT_STANDALONE)
-  list(APPEND LLDB_TEST_DEPS FileCheck not)
+  list(APPEND LLDB_TEST_DEPS FileCheck not yaml2obj)
 endif()
   
 # lldb-server is not built on every platform.
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to