Fix endianness issue.

Previously, ch_size was read in host byte order, so if a host and
a target are different in byte order, we would produce a corrupted
output.

llvm-svn: 274729
This commit is contained in:
Rui Ueyama 2016-07-07 03:55:55 +00:00
parent 830c078d8b
commit 1d12ac1d11
3 changed files with 21 additions and 13 deletions

View File

@ -84,23 +84,24 @@ typename ELFT::uint InputSectionBase<ELFT>::getOffset(uintX_t Offset) const {
}
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");
// A compressed section consists of a header of Elf_Chdr type
// followed by compressed data.
ArrayRef<uint8_t> Data =
check(this->File->getObj().getSectionContents(this->Header));
if (read32<E>(Data.data()) != ELFCOMPRESS_ZLIB)
fatal("unsupported elf compression type");
if (Data.size() < sizeof(Elf_Chdr))
fatal("corrupt compressed section");
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)
auto *Hdr = reinterpret_cast<const Elf_Chdr *>(Data.data());
Data = Data.slice(sizeof(Elf_Chdr));
if (Hdr->ch_type != ELFCOMPRESS_ZLIB)
fatal("unsupported compression type");
StringRef Buf((const char *)Data.data(), Data.size());
if (zlib::uncompress(Buf, Uncompressed, Hdr->ch_size) != zlib::StatusOK)
fatal("error uncompressing section");
}

View File

@ -31,6 +31,7 @@ template <class ELFT> class OutputSectionBase;
// This corresponds to a section of an input file.
template <class ELFT> class InputSectionBase {
protected:
typedef typename ELFT::Chdr Elf_Chdr;
typedef typename ELFT::Rel Elf_Rel;
typedef typename ELFT::Rela Elf_Rela;
typedef typename ELFT::Shdr Elf_Shdr;

View File

@ -22,9 +22,8 @@
# COMPRESSED-NEXT: }
# RUN: ld.lld %t -o %t.so -shared
# RUN: llvm-readobj -sections %t.so | FileCheck -check-prefix=UNCOMPRESSED %s
# RUN: llvm-readobj -sections -section-data %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
@ -40,6 +39,13 @@
# UNCOMPRESSED-NEXT: Info: 0
# UNCOMPRESSED-NEXT: AddressAlignment: 1
# UNCOMPRESSED-NEXT: EntrySize: 1
# UNCOMPRESSED-NEXT: SectionData (
# UNCOMPRESSED-NEXT: 0000: 73686F72 7420756E 7369676E 65642069 |short unsigned i|
# UNCOMPRESSED-NEXT: 0010: 6E740075 6E736967 6E656420 696E7400 |nt.unsigned int.|
# UNCOMPRESSED-NEXT: 0020: 6C6F6E67 20756E73 69676E65 6420696E |long unsigned in|
# UNCOMPRESSED-NEXT: 0030: 74006368 61720075 6E736967 6E656420 |t.char.unsigned |
# UNCOMPRESSED-NEXT: 0040: 63686172 00 |char.|
# UNCOMPRESSED-NEXT: )
# UNCOMPRESSED-NEXT: }
.section .debug_str,"MS",@progbits,1