Apply upstream lld fix for compressed input sections on BE targets
Merge commit c6ebc651b6fa from llvm git (by Simon Atanasyan): [LLD] Support compressed input sections on big-endian targets This patch enables compressed input sections on big-endian targets by checking the target endianness and selecting an appropriate `Chdr` structure. Fixes PR51369 Differential Revision: https://reviews.llvm.org/D107635 Reported by: emaste MFC after: 3 days
This commit is contained in:
parent
b30e7cb7fa
commit
d69d07569e
@ -88,7 +88,22 @@ InputSectionBase::InputSectionBase(InputFile *file, uint64_t flags,
|
|||||||
if (!zlib::isAvailable())
|
if (!zlib::isAvailable())
|
||||||
error(toString(file) + ": contains a compressed section, " +
|
error(toString(file) + ": contains a compressed section, " +
|
||||||
"but zlib is not available");
|
"but zlib is not available");
|
||||||
parseCompressedHeader();
|
switch (config->ekind) {
|
||||||
|
case ELF32LEKind:
|
||||||
|
parseCompressedHeader<ELF32LE>();
|
||||||
|
break;
|
||||||
|
case ELF32BEKind:
|
||||||
|
parseCompressedHeader<ELF32BE>();
|
||||||
|
break;
|
||||||
|
case ELF64LEKind:
|
||||||
|
parseCompressedHeader<ELF64LE>();
|
||||||
|
break;
|
||||||
|
case ELF64BEKind:
|
||||||
|
parseCompressedHeader<ELF64BE>();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
llvm_unreachable("unknown ELFT");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,10 +225,7 @@ OutputSection *SectionBase::getOutputSection() {
|
|||||||
// When a section is compressed, `rawData` consists with a header followed
|
// When a section is compressed, `rawData` consists with a header followed
|
||||||
// by zlib-compressed data. This function parses a header to initialize
|
// by zlib-compressed data. This function parses a header to initialize
|
||||||
// `uncompressedSize` member and remove the header from `rawData`.
|
// `uncompressedSize` member and remove the header from `rawData`.
|
||||||
void InputSectionBase::parseCompressedHeader() {
|
template <typename ELFT> void InputSectionBase::parseCompressedHeader() {
|
||||||
using Chdr64 = typename ELF64LE::Chdr;
|
|
||||||
using Chdr32 = typename ELF32LE::Chdr;
|
|
||||||
|
|
||||||
// Old-style header
|
// Old-style header
|
||||||
if (name.startswith(".zdebug")) {
|
if (name.startswith(".zdebug")) {
|
||||||
if (!toStringRef(rawData).startswith("ZLIB")) {
|
if (!toStringRef(rawData).startswith("ZLIB")) {
|
||||||
@ -239,32 +251,13 @@ void InputSectionBase::parseCompressedHeader() {
|
|||||||
assert(flags & SHF_COMPRESSED);
|
assert(flags & SHF_COMPRESSED);
|
||||||
flags &= ~(uint64_t)SHF_COMPRESSED;
|
flags &= ~(uint64_t)SHF_COMPRESSED;
|
||||||
|
|
||||||
// New-style 64-bit header
|
// New-style header
|
||||||
if (config->is64) {
|
if (rawData.size() < sizeof(typename ELFT::Chdr)) {
|
||||||
if (rawData.size() < sizeof(Chdr64)) {
|
|
||||||
error(toString(this) + ": corrupted compressed section");
|
error(toString(this) + ": corrupted compressed section");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *hdr = reinterpret_cast<const Chdr64 *>(rawData.data());
|
auto *hdr = reinterpret_cast<const typename ELFT::Chdr *>(rawData.data());
|
||||||
if (hdr->ch_type != ELFCOMPRESS_ZLIB) {
|
|
||||||
error(toString(this) + ": unsupported compression type");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uncompressedSize = hdr->ch_size;
|
|
||||||
alignment = std::max<uint32_t>(hdr->ch_addralign, 1);
|
|
||||||
rawData = rawData.slice(sizeof(*hdr));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// New-style 32-bit header
|
|
||||||
if (rawData.size() < sizeof(Chdr32)) {
|
|
||||||
error(toString(this) + ": corrupted compressed section");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto *hdr = reinterpret_cast<const Chdr32 *>(rawData.data());
|
|
||||||
if (hdr->ch_type != ELFCOMPRESS_ZLIB) {
|
if (hdr->ch_type != ELFCOMPRESS_ZLIB) {
|
||||||
error(toString(this) + ": unsupported compression type");
|
error(toString(this) + ": unsupported compression type");
|
||||||
return;
|
return;
|
||||||
|
@ -238,6 +238,7 @@ class InputSectionBase : public SectionBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
template <typename ELFT>
|
||||||
void parseCompressedHeader();
|
void parseCompressedHeader();
|
||||||
void uncompress() const;
|
void uncompress() const;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user