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 §ion_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 §);
+
+ llvm::Expected<uint64_t> GetSectionFileSize(const ELFSectionHeaderInfo §);
+
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 §) {
+ 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 §) {
+ 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 §ion_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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits