ckissane created this revision.
Herald added subscribers: hiraditya, arichardson, emaste.
Herald added a reviewer: alexander-shaposhnikov.
Herald added a reviewer: rupprecht.
Herald added a reviewer: jhenderson.
Herald added a reviewer: MaskRay.
Herald added a project: All.
ckissane requested review of this revision.
Herald added subscribers: llvm-commits, cfe-commits, StephenFan.
Herald added projects: clang, LLVM.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D128667
Files:
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Driver/ToolChains/CommonArgs.cpp
clang/lib/Driver/ToolChains/Gnu.cpp
lld/ELF/Driver.cpp
lld/ELF/InputSection.cpp
lld/ELF/InputSection.h
lld/ELF/OutputSections.h
llvm/include/llvm/BinaryFormat/ELF.h
llvm/include/llvm/MC/MCTargetOptions.h
llvm/include/llvm/Object/Decompressor.h
llvm/lib/MC/ELFObjectWriter.cpp
llvm/lib/ObjCopy/ELF/ELFObject.cpp
llvm/lib/ObjCopy/ELF/ELFObject.h
llvm/lib/Object/Decompressor.cpp
llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
Index: llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
===================================================================
--- llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -731,6 +731,7 @@
InputArgs.getLastArgValue(OBJCOPY_compress_debug_sections_eq))
.Case("zlib-gnu", DebugCompressionType::GNU)
.Case("zlib", DebugCompressionType::Z)
+ .Case("zstd", DebugCompressionType::Zstd)
.Default(DebugCompressionType::None);
if (Config.CompressionType == DebugCompressionType::None)
return createStringError(
@@ -740,10 +741,17 @@
.str()
.c_str());
}
- if (!compression::elf::isAvailable())
- return createStringError(
- errc::invalid_argument,
- "LLVM was not compiled with LLVM_ENABLE_ZLIB: can not compress");
+ if(Config.CompressionType == DebugCompressionType::Zstd) {
+ if (!compression::zstd::isAvailable())
+ return createStringError(
+ errc::invalid_argument,
+ "LLVM was not compiled with LLVM_ENABLE_ZSTD: can not compress");
+ } else {
+ if (!compression::zlib::isAvailable())
+ return createStringError(
+ errc::invalid_argument,
+ "LLVM was not compiled with LLVM_ENABLE_ZLIB: can not compress");
+ }
}
Config.AddGnuDebugLink = InputArgs.getLastArgValue(OBJCOPY_add_gnu_debuglink);
@@ -998,11 +1006,17 @@
"cannot specify both --compress-debug-sections and "
"--decompress-debug-sections");
}
-
- if (Config.DecompressDebugSections && !compression::elf::isAvailable())
+if(Config.CompressionType != DebugCompressionType::Zstd) {
+ if (Config.DecompressDebugSections && !compression::zlib::isAvailable())
return createStringError(
errc::invalid_argument,
"LLVM was not compiled with LLVM_ENABLE_ZLIB: cannot decompress");
+}else{
+ if (Config.DecompressDebugSections && !compression::zstd::isAvailable())
+ return createStringError(
+ errc::invalid_argument,
+ "LLVM was not compiled with LLVM_ENABLE_ZSTD: cannot decompress");
+}
if (Config.ExtractPartition && Config.ExtractMainPartition)
return createStringError(errc::invalid_argument,
Index: llvm/lib/Object/Decompressor.cpp
===================================================================
--- llvm/lib/Object/Decompressor.cpp
+++ llvm/lib/Object/Decompressor.cpp
@@ -8,6 +8,7 @@
#include "llvm/Object/Decompressor.h"
#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/MC/MCTargetOptions.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/DataExtractor.h"
@@ -19,19 +20,43 @@
Expected<Decompressor> Decompressor::create(StringRef Name, StringRef Data,
bool IsLE, bool Is64Bit) {
- if (!compression::elf::isAvailable())
+ DebugCompressionType CType = DebugCompressionType::Z;
+ if(isGnuStyle(Name)){
+ CType = DebugCompressionType::GNU;
+ }else{
+ if(Is64Bit){
+ auto *chdr = reinterpret_cast<const llvm::ELF::Elf64_Chdr *>(Data.bytes_begin());
+ if(chdr->ch_type == ELF::ELFCOMPRESS_ZLIB){
+ CType=DebugCompressionType::Z;
+ } else if(chdr->ch_type == ELF::ELFCOMPRESS_ZSTD){
+ CType = DebugCompressionType::Zstd;
+ } else {
+ return createError("unknown elf compress type in compressed section header");
+ }
+ } else {
+ auto *chdr = reinterpret_cast<const llvm::ELF::Elf32_Chdr *>(Data.bytes_begin());
+ if(chdr->ch_type == ELF::ELFCOMPRESS_ZLIB){
+ CType = DebugCompressionType::Z;
+ } else if(chdr->ch_type == ELF::ELFCOMPRESS_ZSTD){
+ CType = DebugCompressionType::Zstd;
+ } else {
+ return createError("unknown elf compress type in compressed section header");
+ }
+ }
+ }
+
+ if ((CType == DebugCompressionType::Z || CType==DebugCompressionType::GNU) && !compression::zlib::isAvailable())
return createError("zlib is not available");
-
- Decompressor D(Data);
- Error Err = isGnuStyle(Name) ? D.consumeCompressedGnuHeader()
- : D.consumeCompressedZLibHeader(Is64Bit, IsLE);
+ Decompressor D(Data, CType);
+ Error Err = CType == DebugCompressionType::GNU ? D.consumeCompressedGnuHeader()
+ : CType == DebugCompressionType::Z ? D.consumeCompressedZLibHeader(Is64Bit, IsLE) : D.consumeCompressedZStdHeader(Is64Bit, IsLE);
if (Err)
return std::move(Err);
return D;
}
-Decompressor::Decompressor(StringRef Data)
- : SectionData(Data), DecompressedSize(0) {}
+Decompressor::Decompressor(StringRef Data, DebugCompressionType CType)
+ : SectionData(Data), CType(CType), DecompressedSize(0) {}
Error Decompressor::consumeCompressedGnuHeader() {
if (!SectionData.startswith("ZLIB"))
@@ -72,6 +97,31 @@
return Error::success();
}
+
+Error Decompressor::consumeCompressedZStdHeader(bool Is64Bit,
+ bool IsLittleEndian) {
+ using namespace ELF;
+ uint64_t HdrSize = Is64Bit ? sizeof(Elf64_Chdr) : sizeof(Elf32_Chdr);
+ if (SectionData.size() < HdrSize)
+ return createError("corrupted compressed section header");
+
+ DataExtractor Extractor(SectionData, IsLittleEndian, 0);
+ uint64_t Offset = 0;
+ if (Extractor.getUnsigned(&Offset, Is64Bit ? sizeof(Elf64_Word)
+ : sizeof(Elf32_Word)) !=
+ ELFCOMPRESS_ZSTD)
+ return createError("unsupported compression type");
+
+ // Skip Elf64_Chdr::ch_reserved field.
+ if (Is64Bit)
+ Offset += sizeof(Elf64_Word);
+
+ DecompressedSize = Extractor.getUnsigned(
+ &Offset, Is64Bit ? sizeof(Elf64_Xword) : sizeof(Elf32_Word));
+ SectionData = SectionData.substr(HdrSize);
+ return Error::success();
+}
+
bool Decompressor::isGnuStyle(StringRef Name) {
return Name.startswith(".zdebug");
}
@@ -94,5 +144,5 @@
Error Decompressor::decompress(MutableArrayRef<char> Buffer) {
size_t Size = Buffer.size();
- return compression::elf::uncompress(SectionData, Buffer.data(), Size);
+ return CType == DebugCompressionType::Zstd ? compression::zstd::uncompress(SectionData, Buffer.data(), Size) : compression::zlib::uncompress(SectionData, Buffer.data(), Size);
}
Index: llvm/lib/ObjCopy/ELF/ELFObject.h
===================================================================
--- llvm/lib/ObjCopy/ELF/ELFObject.h
+++ llvm/lib/ObjCopy/ELF/ELFObject.h
@@ -536,12 +536,12 @@
class CompressedSection : public SectionBase {
MAKE_SEC_WRITER_FRIEND
- DebugCompressionType CompressionType;
uint64_t DecompressedSize;
uint64_t DecompressedAlign;
SmallVector<char, 128> CompressedData;
public:
+ DebugCompressionType CompressionType;
CompressedSection(const SectionBase &Sec,
DebugCompressionType CompressionType);
CompressedSection(ArrayRef<uint8_t> CompressedData, uint64_t DecompressedSize,
@@ -563,8 +563,10 @@
MAKE_SEC_WRITER_FRIEND
public:
+ DebugCompressionType OriginalCompressionType;
explicit DecompressedSection(const CompressedSection &Sec)
: SectionBase(Sec) {
+ OriginalCompressionType = Sec.CompressionType;
Size = Sec.getDecompressedSize();
Align = Sec.getDecompressedAlign();
Flags = OriginalFlags = (Flags & ~ELF::SHF_COMPRESSED);
Index: llvm/lib/ObjCopy/ELF/ELFObject.cpp
===================================================================
--- llvm/lib/ObjCopy/ELF/ELFObject.cpp
+++ llvm/lib/ObjCopy/ELF/ELFObject.cpp
@@ -468,10 +468,18 @@
Sec.OriginalData.size() - DataOffset);
SmallVector<char, 128> DecompressedContent;
- if (Error Err = compression::elf::uncompress(CompressedContent, DecompressedContent,
+ if(Sec.OriginalCompressionType==DebugCompressionType::Zstd){
+if (Error Err = compression::zstd::uncompress(CompressedContent, DecompressedContent,
static_cast<size_t>(Sec.Size)))
return createStringError(errc::invalid_argument,
"'" + Sec.Name + "': " + toString(std::move(Err)));
+ }
+ else{
+ if (Error Err = compression::zlib::uncompress(CompressedContent, DecompressedContent,
+ static_cast<size_t>(Sec.Size)))
+ return createStringError(errc::invalid_argument,
+ "'" + Sec.Name + "': " + toString(std::move(Err)));
+ }
uint8_t *Buf = reinterpret_cast<uint8_t *>(Out.getBufferStart()) + Sec.Offset;
std::copy(DecompressedContent.begin(), DecompressedContent.end(), Buf);
@@ -534,7 +542,7 @@
Buf += sizeof(DecompressedSize);
} else {
Elf_Chdr_Impl<ELFT> Chdr;
- Chdr.ch_type = ELF::ELFCOMPRESS_ZLIB;
+ Chdr.ch_type = Sec.CompressionType == DebugCompressionType::Zstd ? ELF::ELFCOMPRESS_ZSTD : ELF::ELFCOMPRESS_ZLIB;
Chdr.ch_size = Sec.DecompressedSize;
Chdr.ch_addralign = Sec.DecompressedAlign;
memcpy(Buf, &Chdr, sizeof(Chdr));
@@ -547,11 +555,19 @@
CompressedSection::CompressedSection(const SectionBase &Sec,
DebugCompressionType CompressionType)
- : SectionBase(Sec), CompressionType(CompressionType),
- DecompressedSize(Sec.OriginalData.size()), DecompressedAlign(Sec.Align) {
- compression::elf::compress(StringRef(reinterpret_cast<const char *>(OriginalData.data()),
- OriginalData.size()),
- CompressedData);
+ : SectionBase(Sec), DecompressedSize(Sec.OriginalData.size()),
+ DecompressedAlign(Sec.Align), CompressionType(CompressionType) {
+ if (CompressionType == DebugCompressionType::Zstd) {
+ compression::zstd::compress(
+ StringRef(reinterpret_cast<const char *>(OriginalData.data()),
+ OriginalData.size()),
+ CompressedData);
+ }else{
+ compression::zlib::compress(
+ StringRef(reinterpret_cast<const char *>(OriginalData.data()),
+ OriginalData.size()),
+ CompressedData);
+ }
size_t ChdrSize;
if (CompressionType == DebugCompressionType::GNU) {
@@ -572,8 +588,8 @@
CompressedSection::CompressedSection(ArrayRef<uint8_t> CompressedData,
uint64_t DecompressedSize,
uint64_t DecompressedAlign)
- : CompressionType(DebugCompressionType::None),
- DecompressedSize(DecompressedSize), DecompressedAlign(DecompressedAlign) {
+ : DecompressedSize(DecompressedSize),
+ DecompressedAlign(DecompressedAlign), CompressionType(DebugCompressionType::None) {
OriginalData = CompressedData;
}
Index: llvm/lib/MC/ELFObjectWriter.cpp
===================================================================
--- llvm/lib/MC/ELFObjectWriter.cpp
+++ llvm/lib/MC/ELFObjectWriter.cpp
@@ -146,7 +146,7 @@
bool maybeWriteCompression(uint64_t Size,
SmallVectorImpl<char> &CompressedContents,
- bool ZLibStyle, unsigned Alignment);
+ bool ZLibStyle, bool ZstdStyle, unsigned Alignment);
public:
ELFWriter(ELFObjectWriter &OWriter, raw_pwrite_stream &OS,
@@ -819,8 +819,9 @@
// Include the debug info compression header.
bool ELFWriter::maybeWriteCompression(
- uint64_t Size, SmallVectorImpl<char> &CompressedContents, bool ZLibStyle,
+ uint64_t Size, SmallVectorImpl<char> &CompressedContents, bool ZLibStyle,bool ZstdStyle,
unsigned Alignment) {
+ if(!ZstdStyle){
if (ZLibStyle) {
uint64_t HdrSize =
is64Bit() ? sizeof(ELF::Elf32_Chdr) : sizeof(ELF::Elf64_Chdr);
@@ -850,6 +851,27 @@
W.OS << Magic;
support::endian::write(W.OS, Size, support::big);
return true;
+ }else{
+ uint64_t HdrSize =
+ is64Bit() ? sizeof(ELF::Elf32_Chdr) : sizeof(ELF::Elf64_Chdr);
+ if (Size <= HdrSize + CompressedContents.size())
+ return false;
+ // Platform specific header is followed by compressed data.
+ if (is64Bit()) {
+ // Write Elf64_Chdr header.
+ write(static_cast<ELF::Elf64_Word>(ELF::ELFCOMPRESS_ZSTD));
+ write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field.
+ write(static_cast<ELF::Elf64_Xword>(Size));
+ write(static_cast<ELF::Elf64_Xword>(Alignment));
+ } else {
+ // Write Elf32_Chdr header otherwise.
+ write(static_cast<ELF::Elf32_Word>(ELF::ELFCOMPRESS_ZSTD));
+ write(static_cast<ELF::Elf32_Word>(Size));
+ write(static_cast<ELF::Elf32_Word>(Alignment));
+ }
+ return true;
+
+ }
}
void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
@@ -868,26 +890,34 @@
}
assert((MAI->compressDebugSections() == DebugCompressionType::Z ||
- MAI->compressDebugSections() == DebugCompressionType::GNU) &&
- "expected zlib or zlib-gnu style compression");
+ MAI->compressDebugSections() == DebugCompressionType::GNU ||
+ MAI->compressDebugSections() == DebugCompressionType::Zstd) &&
+ "expected zlib or zlib-gnu or zstd style compression");
SmallVector<char, 128> UncompressedData;
raw_svector_ostream VecOS(UncompressedData);
Asm.writeSectionData(VecOS, &Section, Layout);
SmallVector<char, 128> CompressedContents;
- compression::elf::compress(StringRef(UncompressedData.data(), UncompressedData.size()),
- CompressedContents);
+
bool ZlibStyle = MAI->compressDebugSections() == DebugCompressionType::Z;
+ bool ZstdStyle = MAI->compressDebugSections() == DebugCompressionType::Zstd;
+ if(ZstdStyle){
+ compression::zstd::compress(StringRef(UncompressedData.data(), UncompressedData.size()),
+ CompressedContents);
+ }else{
+ compression::zlib::compress(StringRef(UncompressedData.data(), UncompressedData.size()),
+ CompressedContents);
+ }
if (!maybeWriteCompression(UncompressedData.size(), CompressedContents,
- ZlibStyle, Sec.getAlignment())) {
+ ZlibStyle, ZstdStyle, Sec.getAlignment())) {
W.OS << UncompressedData;
return;
}
- if (ZlibStyle) {
- // Set the compressed flag. That is zlib style.
+ if (ZlibStyle || ZstdStyle) {
+ // Set the compressed flag. That is zlib or zstd style.
Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED);
// Alignment field should reflect the requirements of
// the compressed section header.
Index: llvm/include/llvm/Object/Decompressor.h
===================================================================
--- llvm/include/llvm/Object/Decompressor.h
+++ llvm/include/llvm/Object/Decompressor.h
@@ -11,6 +11,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCTargetOptions.h"
#include "llvm/Support/Error.h"
namespace llvm {
@@ -53,12 +54,14 @@
static bool isGnuStyle(StringRef Name);
private:
- Decompressor(StringRef Data);
+ Decompressor(StringRef Data, DebugCompressionType CType);
Error consumeCompressedGnuHeader();
Error consumeCompressedZLibHeader(bool Is64Bit, bool IsLittleEndian);
+ Error consumeCompressedZStdHeader(bool Is64Bit, bool IsLittleEndian);
StringRef SectionData;
+ DebugCompressionType CType;
uint64_t DecompressedSize;
};
Index: llvm/include/llvm/MC/MCTargetOptions.h
===================================================================
--- llvm/include/llvm/MC/MCTargetOptions.h
+++ llvm/include/llvm/MC/MCTargetOptions.h
@@ -29,6 +29,7 @@
None, ///< No compression
GNU, ///< zlib-gnu style compression
Z, ///< zlib style complession
+ Zstd, ///< Zstandard
};
enum class EmitDwarfUnwindType {
Index: llvm/include/llvm/BinaryFormat/ELF.h
===================================================================
--- llvm/include/llvm/BinaryFormat/ELF.h
+++ llvm/include/llvm/BinaryFormat/ELF.h
@@ -1061,6 +1061,9 @@
// Identifies a section containing compressed data.
SHF_COMPRESSED = 0x800U,
+ // SHF_COMPRESSED = 0x1800U,
+
+ // SHF_COMPRESSED_LOWEST = 0x800U,
// This section should not be garbage collected by the linker.
SHF_GNU_RETAIN = 0x200000,
@@ -1769,6 +1772,7 @@
// Legal values for ch_type field of compressed section header.
enum {
ELFCOMPRESS_ZLIB = 1, // ZLIB/DEFLATE algorithm.
+ ELFCOMPRESS_ZSTD = 2, // ZLIB/DEFLATE algorithm.
ELFCOMPRESS_LOOS = 0x60000000, // Start of OS-specific.
ELFCOMPRESS_HIOS = 0x6fffffff, // End of OS-specific.
ELFCOMPRESS_LOPROC = 0x70000000, // Start of processor-specific.
Index: lld/ELF/OutputSections.h
===================================================================
--- lld/ELF/OutputSections.h
+++ lld/ELF/OutputSections.h
@@ -12,6 +12,7 @@
#include "InputSection.h"
#include "LinkerScript.h"
#include "lld/Common/LLVM.h"
+#include "llvm/MC/MCTargetOptions.h"
#include <array>
@@ -25,6 +26,7 @@
uint32_t numShards = 0;
uint32_t checksum = 0;
uint64_t uncompressedSize;
+ llvm::DebugCompressionType CompressionType;
};
// This represents a section in an output file.
@@ -32,6 +34,7 @@
// The writer creates multiple OutputSections and assign them unique,
// non-overlapping file offsets and VAs.
class OutputSection final : public SectionBase {
+ llvm::DebugCompressionType CompressionType;
public:
OutputSection(StringRef name, uint32_t type, uint64_t flags);
Index: lld/ELF/InputSection.h
===================================================================
--- lld/ELF/InputSection.h
+++ lld/ELF/InputSection.h
@@ -14,6 +14,7 @@
#include "llvm/ADT/CachedHashString.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/TinyPtrVector.h"
+#include "llvm/MC/MCTargetOptions.h"
#include "llvm/Object/ELF.h"
namespace lld {
@@ -232,6 +233,8 @@
// compressed in the first place, or because we ended up uncompressing it).
// Since the feature is not used often, this is usually -1.
mutable int64_t uncompressedSize = -1;
+
+ llvm::DebugCompressionType CompressionType;
};
// SectionPiece represents a piece of splittable section contents.
@@ -383,7 +386,7 @@
template <class ELFT> void copyShtGroup(uint8_t *buf);
};
-static_assert(sizeof(InputSection) <= 160, "InputSection is too big");
+static_assert(sizeof(InputSection) <= 168, "InputSection is too big");
inline bool isDebugSection(const InputSectionBase &sec) {
return (sec.flags & llvm::ELF::SHF_ALLOC) == 0 &&
Index: lld/ELF/InputSection.cpp
===================================================================
--- lld/ELF/InputSection.cpp
+++ lld/ELF/InputSection.cpp
@@ -16,6 +16,8 @@
#include "SyntheticSections.h"
#include "Target.h"
#include "lld/Common/CommonLinkerContext.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/MC/MCTargetOptions.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/Endian.h"
@@ -73,10 +75,25 @@
// If SHF_COMPRESSED is set, parse the header. The legacy .zdebug format is no
// longer supported.
if (flags & SHF_COMPRESSED) {
- if (!compression::elf::isAvailable())
+ if (!compression::zlib::isAvailable() || !compression::zstd::isAvailable())
error(toString(file) + ": contains a compressed section, " +
- "but zlib is not available");
+ "but zlib or zstd is not available");
invokeELFT(parseCompressedHeader);
+ // uint64_t compressionFlags = (flags & SHF_COMPRESSED) / SHF_COMPRESSED_LOWEST;
+ // if(compressionFlags==1) {
+ // if (!compression::zlib::isAvailable())
+ // error(toString(file) + ": contains a zlib compressed section, " +
+ // "but zlib is not available");
+ // invokeELFT(parseCompressedHeader);
+ // } else if(compressionFlags==2) {
+ // if (!compression::zlib::isAvailable())
+ // error(toString(file) + ": contains a zstd compressed section, " +
+ // "but zstd is not available");
+ // invokeELFT(parseCompressedHeader);
+ // } else if(compressionFlags==3) {
+ // error(toString(file) + ": contains a compressed section, " +
+ // "but of unknown type");
+ // }
}
}
@@ -121,10 +138,23 @@
std::lock_guard<std::mutex> lock(mu);
uncompressedBuf = bAlloc().Allocate<char>(size);
}
-
- if (Error e = compression::elf::uncompress(toStringRef(rawData), uncompressedBuf, size))
+// TODO: COLE: this assumes that the CType has been extracted from header pre this func
+// // TODO: COLE: always cast elf32 chdr cause we only want type anyway which should be first :(?
+// auto *hdr = reinterpret_cast<const typename llvm::ELF::Elf32_Chdr *>(rawData.data());
+// if (hdr->ch_type != ELFCOMPRESS_ZLIB && hdr->ch_type != ELFCOMPRESS_ZSTD) {
+// error(toString(this) + ": unsupported compression type");
+// return;
+// }
+// DebugCompressionType CompressionType=hdr->ch_type == ELFCOMPRESS_ZSTD?DebugCompressionType::Zstd:DebugCompressionType::Z;
+if(CompressionType==DebugCompressionType::Zstd){
+ if (Error e = compression::zstd::uncompress(toStringRef(rawData), uncompressedBuf, size))
+ fatal(toString(this) +
+ ": uncompress failed: " + llvm::toString(std::move(e)));
+}else{
+ if (Error e = compression::zlib::uncompress(toStringRef(rawData), uncompressedBuf, size))
fatal(toString(this) +
": uncompress failed: " + llvm::toString(std::move(e)));
+}
rawData = makeArrayRef((uint8_t *)uncompressedBuf, size);
uncompressedSize = -1;
}
@@ -202,6 +232,7 @@
// by zlib-compressed data. This function parses a header to initialize
// `uncompressedSize` member and remove the header from `rawData`.
template <typename ELFT> void InputSectionBase::parseCompressedHeader() {
+ // uint64_t compressionFlags = (flags & SHF_COMPRESSED) / SHF_COMPRESSED_LOWEST;
flags &= ~(uint64_t)SHF_COMPRESSED;
// New-style header
@@ -211,11 +242,11 @@
}
auto *hdr = reinterpret_cast<const typename ELFT::Chdr *>(rawData.data());
- if (hdr->ch_type != ELFCOMPRESS_ZLIB) {
+ if (hdr->ch_type != ELFCOMPRESS_ZLIB && (hdr->ch_type != ELFCOMPRESS_ZSTD)) {
error(toString(this) + ": unsupported compression type");
return;
}
-
+ // CompressionType=hdr->ch_type == ELFCOMPRESS_ZSTD?DebugCompressionType::Zstd:DebugCompressionType::Z;
uncompressedSize = hdr->ch_size;
alignment = std::max<uint32_t>(hdr->ch_addralign, 1);
rawData = rawData.slice(sizeof(*hdr));
@@ -1213,9 +1244,15 @@
// to the buffer.
if (uncompressedSize >= 0) {
size_t size = uncompressedSize;
- if (Error e = compression::elf::uncompress(toStringRef(rawData), (char *)buf, size))
+ if(CompressionType==DebugCompressionType::Zstd){
+ if (Error e = compression::zstd::uncompress(toStringRef(rawData), (char *)buf, size))
+ fatal(toString(this) +
+ ": uncompress failed: " + llvm::toString(std::move(e)));
+ }else{
+ if (Error e = compression::zlib::uncompress(toStringRef(rawData), (char *)buf, size))
fatal(toString(this) +
": uncompress failed: " + llvm::toString(std::move(e)));
+ }
uint8_t *bufEnd = buf + size;
relocate<ELFT>(buf, bufEnd);
return;
Index: lld/ELF/Driver.cpp
===================================================================
--- lld/ELF/Driver.cpp
+++ lld/ELF/Driver.cpp
@@ -951,11 +951,25 @@
StringRef s = args.getLastArgValue(OPT_compress_debug_sections, "none");
if (s == "none")
return false;
- if (s != "zlib")
- error("unknown --compress-debug-sections value: " + s);
- if (!compression::elf::isAvailable())
+
+ if (s == "zlib"){
+ if (compression::zlib::isAvailable()) {
+ return true;
+ }
error("--compress-debug-sections: zlib is not available");
- return true;
+ return false;
+ }
+
+ if (s == "zstd"){
+ if (compression::zstd::isAvailable()) {
+ return true;
+ }
+ error("--compress-debug-sections: zstd is not available");
+ return false;
+ }
+
+ error("unknown --compress-debug-sections value: " + s);
+ return false;
}
static StringRef getAliasSpelling(opt::Arg *arg) {
Index: clang/lib/Driver/ToolChains/Gnu.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Gnu.cpp
+++ clang/lib/Driver/ToolChains/Gnu.cpp
@@ -716,7 +716,7 @@
CmdArgs.push_back("--compress-debug-sections");
} else {
StringRef Value = A->getValue();
- if (Value == "none" || Value == "zlib") {
+ if (Value == "none" || Value == "zlib" || Value == "zstd") {
CmdArgs.push_back(
Args.MakeArgString("--compress-debug-sections=" + Twine(Value)));
} else {
Index: clang/lib/Driver/ToolChains/CommonArgs.cpp
===================================================================
--- clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -284,7 +284,7 @@
// argument.
if (const Arg *A = Args.getLastArg(options::OPT_gz_EQ)) {
StringRef V = A->getValue();
- if (V == "none" || V == "zlib")
+ if (V == "none" || V == "zlib" || V == "zstd")
CmdArgs.push_back(Args.MakeArgString("--compress-debug-sections=" + V));
else
TC.getDriver().Diag(diag::err_drv_unsupported_option_argument)
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -1144,7 +1144,14 @@
if (Value == "none") {
CmdArgs.push_back("--compress-debug-sections=none");
} else if (Value == "zlib") {
- if (llvm::compression::elf::isAvailable()) {
+ if (llvm::compression::zlib::isAvailable()) {
+ CmdArgs.push_back(
+ Args.MakeArgString("--compress-debug-sections=" + Twine(Value)));
+ } else {
+ D.Diag(diag::warn_debug_compression_unavailable);
+ }
+ } else if (Value == "zstd") {
+ if (llvm::compression::zstd::isAvailable()) {
CmdArgs.push_back(
Args.MakeArgString("--compress-debug-sections=" + Twine(Value)));
} else {
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits