[lld] r273661 - [ELF] - Support of compressed input sections implemented.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 24 04:18:46 PDT 2016
Author: grimar
Date: Fri Jun 24 06:18:44 2016
New Revision: 273661
URL: http://llvm.org/viewvc/llvm-project?rev=273661&view=rev
Log:
[ELF] - Support of compressed input sections implemented.
Patch implements support of zlib style compressed sections.
SHF_COMPRESSED flag is used to recognize that decompression is required.
After that decompression is performed and flag is removed from output.
Differential revision: http://reviews.llvm.org/D20272
Added:
lld/trunk/test/ELF/compressed-debug-input.s
Modified:
lld/trunk/ELF/Driver.cpp
lld/trunk/ELF/InputSection.cpp
lld/trunk/ELF/InputSection.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=273661&r1=273660&r2=273661&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Fri Jun 24 06:18:44 2016
@@ -521,10 +521,14 @@ template <class ELFT> void LinkerDriver:
// any call of MergeInputSection::getOffset. Do that.
for (const std::unique_ptr<elf::ObjectFile<ELFT>> &F :
Symtab.getObjectFiles())
- for (InputSectionBase<ELFT> *S : F->getSections())
- if (S && S != &InputSection<ELFT>::Discarded && S->Live)
- if (auto *MS = dyn_cast<MergeInputSection<ELFT>>(S))
- MS->splitIntoPieces();
+ for (InputSectionBase<ELFT> *S : F->getSections()) {
+ if (!S || S == &InputSection<ELFT>::Discarded || !S->Live)
+ continue;
+ if (S->Compressed)
+ S->uncompress();
+ if (auto *MS = dyn_cast<MergeInputSection<ELFT>>(S))
+ MS->splitIntoPieces();
+ }
writeResult<ELFT>(&Symtab);
}
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=273661&r1=273660&r2=273661&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Fri Jun 24 06:18:44 2016
@@ -15,6 +15,7 @@
#include "OutputSections.h"
#include "Target.h"
+#include "llvm/Support/Compression.h"
#include "llvm/Support/Endian.h"
using namespace llvm;
@@ -29,7 +30,8 @@ template <class ELFT>
InputSectionBase<ELFT>::InputSectionBase(elf::ObjectFile<ELFT> *File,
const Elf_Shdr *Header,
Kind SectionKind)
- : Header(Header), File(File), SectionKind(SectionKind), Repl(this) {
+ : Header(Header), File(File), SectionKind(SectionKind), Repl(this),
+ Compressed(Header->sh_flags & SHF_COMPRESSED) {
// The garbage collector sets sections' Live bits.
// If GC is disabled, all sections are considered live by default.
Live = !Config->GcSections;
@@ -52,6 +54,9 @@ template <class ELFT> StringRef InputSec
template <class ELFT>
ArrayRef<uint8_t> InputSectionBase<ELFT>::getSectionData() const {
+ if (Compressed)
+ return ArrayRef<uint8_t>((const uint8_t *)Uncompressed.data(),
+ Uncompressed.size());
return check(this->File->getObj().getSectionContents(this->Header));
}
@@ -78,6 +83,27 @@ typename ELFT::uint InputSectionBase<ELF
llvm_unreachable("invalid section kind");
}
+template <class ELFT> void InputSectionBase<ELFT>::uncompress() {
+ typedef typename std::conditional<ELFT::Is64Bits, Elf64_Chdr,
+ Elf32_Chdr>::type Elf_Chdr;
+ const endianness E = ELFT::TargetEndianness;
+
+ if (!zlib::isAvailable())
+ fatal("build lld with zlib to enable compressed sections support");
+
+ ArrayRef<uint8_t> Data =
+ check(this->File->getObj().getSectionContents(this->Header));
+ if (read32<E>(Data.data()) != ELFCOMPRESS_ZLIB)
+ fatal("unsupported elf compression type");
+
+ size_t UncompressedSize =
+ reinterpret_cast<const Elf_Chdr *>(Data.data())->ch_size;
+ size_t HdrSize = sizeof(Elf_Chdr);
+ StringRef Buf((const char *)Data.data() + HdrSize, Data.size() - HdrSize);
+ if (zlib::uncompress(Buf, Uncompressed, UncompressedSize) != zlib::StatusOK)
+ fatal("error uncompressing section");
+}
+
template <class ELFT>
typename ELFT::uint
InputSectionBase<ELFT>::getOffset(const DefinedRegular<ELFT> &Sym) const {
Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=273661&r1=273660&r2=273661&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Fri Jun 24 06:18:44 2016
@@ -41,6 +41,9 @@ protected:
// The file this section is from.
ObjectFile<ELFT> *File;
+ // If a section is compressed, this vector has uncompressed section data.
+ SmallVector<char, 0> Uncompressed;
+
public:
enum Kind { Regular, EHFrame, Merge, MipsReginfo, MipsOptions };
Kind SectionKind;
@@ -78,8 +81,12 @@ public:
ArrayRef<uint8_t> getSectionData() const;
+ void uncompress();
+
void relocate(uint8_t *Buf, uint8_t *BufEnd);
std::vector<Relocation<ELFT>> Relocations;
+
+ bool Compressed;
};
template <class ELFT> InputSectionBase<ELFT> InputSectionBase<ELFT>::Discarded;
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=273661&r1=273660&r2=273661&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Jun 24 06:18:44 2016
@@ -623,7 +623,7 @@ SectionKey<ELFT::Is64Bits>
OutputSectionFactory<ELFT>::createKey(InputSectionBase<ELFT> *C,
StringRef OutsecName) {
const Elf_Shdr *H = C->getSectionHdr();
- uintX_t Flags = H->sh_flags & ~SHF_GROUP;
+ uintX_t Flags = H->sh_flags & ~SHF_GROUP & ~SHF_COMPRESSED;
// For SHF_MERGE we create different output sections for each alignment.
// This makes each output section simple and keeps a single level mapping from
Added: lld/trunk/test/ELF/compressed-debug-input.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/compressed-debug-input.s?rev=273661&view=auto
==============================================================================
--- lld/trunk/test/ELF/compressed-debug-input.s (added)
+++ lld/trunk/test/ELF/compressed-debug-input.s Fri Jun 24 06:18:44 2016
@@ -0,0 +1,55 @@
+# REQUIRES: zlib
+
+# RUN: llvm-mc -compress-debug-sections=zlib -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: llvm-readobj -sections %t | FileCheck -check-prefix=COMPRESSED %s
+
+# COMPRESSED: Section {
+# COMPRESSED: Index: 2
+# COMPRESSED: Name: .debug_str
+# COMPRESSED-NEXT: Type: SHT_PROGBITS
+# COMPRESSED-NEXT: Flags [
+# COMPRESSED-NEXT: SHF_COMPRESSED (0x800)
+# COMPRESSED-NEXT: SHF_MERGE (0x10)
+# COMPRESSED-NEXT: SHF_STRINGS (0x20)
+# COMPRESSED-NEXT: ]
+# COMPRESSED-NEXT: Address:
+# COMPRESSED-NEXT: Offset:
+# COMPRESSED-NEXT: Size: 66
+# COMPRESSED-NEXT: Link:
+# COMPRESSED-NEXT: Info:
+# COMPRESSED-NEXT: AddressAlignment: 1
+# COMPRESSED-NEXT: EntrySize: 1
+# COMPRESSED-NEXT: }
+
+# RUN: ld.lld %t -o %t.so -shared
+# RUN: llvm-readobj -sections %t.so | FileCheck -check-prefix=UNCOMPRESSED %s
+
+## Check that section is decompressed and compression flag is removed.
+# UNCOMPRESSED: Section {
+# UNCOMPRESSED: Index: 6
+# UNCOMPRESSED: Name: .debug_str
+# UNCOMPRESSED-NEXT: Type: SHT_PROGBITS
+# UNCOMPRESSED-NEXT: Flags [
+# UNCOMPRESSED-NEXT: SHF_MERGE (0x10)
+# UNCOMPRESSED-NEXT: SHF_STRINGS (0x20)
+# UNCOMPRESSED-NEXT: ]
+# UNCOMPRESSED-NEXT: Address: 0x0
+# UNCOMPRESSED-NEXT: Offset: 0x1060
+# UNCOMPRESSED-NEXT: Size: 69
+# UNCOMPRESSED-NEXT: Link: 0
+# UNCOMPRESSED-NEXT: Info: 0
+# UNCOMPRESSED-NEXT: AddressAlignment: 1
+# UNCOMPRESSED-NEXT: EntrySize: 1
+# UNCOMPRESSED-NEXT: }
+
+.section .debug_str,"MS", at progbits,1
+.LASF2:
+ .string "short unsigned int"
+.LASF3:
+ .string "unsigned int"
+.LASF0:
+ .string "long unsigned int"
+.LASF8:
+ .string "char"
+.LASF1:
+ .string "unsigned char"
More information about the llvm-commits
mailing list