Index: lld/ELF/Config.h =================================================================== --- lld/ELF/Config.h +++ lld/ELF/Config.h @@ -61,6 +61,9 @@ // For tracking ARM Float Argument PCS enum class ARMVFPArgKind { Default, Base, VFP, ToolChain }; +// For --compress-debug-sections. +enum class CompressDebugSectionsPolicy { None, Zlib, ZlibGnu }; + struct SymbolVersion { llvm::StringRef Name; bool IsExternCpp; @@ -130,7 +133,7 @@ bool BsymbolicFunctions; bool CallGraphProfileSort; bool CheckSections; - bool CompressDebugSections; + CompressDebugSectionsPolicy CompressDebugSections; bool Cref; bool DefineCommon; bool Demangle = true; Index: lld/ELF/Driver.cpp =================================================================== --- lld/ELF/Driver.cpp +++ lld/ELF/Driver.cpp @@ -700,15 +700,19 @@ } } -static bool getCompressDebugSections(opt::InputArgList &Args) { +static CompressDebugSectionsPolicy getCompressDebugSections(opt::InputArgList &Args) { StringRef S = Args.getLastArgValue(OPT_compress_debug_sections, "none"); - if (S == "none") - return false; - if (S != "zlib") + if (S == "zlib" || S == "zlib-gnu") { + if (!zlib::isAvailable()) + error("--compress-debug-sections: zlib is not available"); + if (S == "zlib") + return CompressDebugSectionsPolicy::Zlib; + if (S == "zlib-gnu") + return CompressDebugSectionsPolicy::ZlibGnu; + } else if (S != "none") { error("unknown --compress-debug-sections value: " + S); - if (!zlib::isAvailable()) - error("--compress-debug-sections: zlib is not available"); - return true; + } + return CompressDebugSectionsPolicy::None; } static std::pair getOldNewOptions(opt::InputArgList &Args, Index: lld/ELF/OutputSections.h =================================================================== --- lld/ELF/OutputSections.h +++ lld/ELF/OutputSections.h @@ -108,6 +108,8 @@ template void writeTo(uint8_t *Buf); template void maybeCompress(); + StringRef finalName(); + void sort(llvm::function_ref Order); void sortInitFini(); void sortCtorsDtors(); Index: lld/ELF/OutputSections.cpp =================================================================== --- lld/ELF/OutputSections.cpp +++ lld/ELF/OutputSections.cpp @@ -183,8 +183,8 @@ typedef typename ELFT::Chdr Elf_Chdr; // Compress only DWARF debug sections. - if (!Config->CompressDebugSections || (Flags & SHF_ALLOC) || - !Name.startswith(".debug_")) + if (Config->CompressDebugSections == CompressDebugSectionsPolicy::None || + (Flags & SHF_ALLOC) || !Name.startswith(".debug_")) return; // Create a section header. @@ -205,6 +205,13 @@ Flags |= SHF_COMPRESSED; } +StringRef OutputSection::finalName() { + if (Config->CompressDebugSections == CompressDebugSectionsPolicy::ZlibGnu && + !(Flags & SHF_ALLOC) && Name.startswith(".debug_")) + return Saver.save(".z" + Name.substr(1)); + return Name; +} + static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) { if (Size == 1) *Buf = Data; Index: lld/ELF/Writer.cpp =================================================================== --- lld/ELF/Writer.cpp +++ lld/ELF/Writer.cpp @@ -1751,7 +1751,7 @@ for (size_t I = 0, E = OutputSections.size(); I != E; ++I) { OutputSection *Sec = OutputSections[I]; Sec->SectionIndex = I + 1; - Sec->ShName = In.ShStrTab->addString(Sec->Name); + Sec->ShName = In.ShStrTab->addString(Sec->finalName()); } // Binary and relocatable output does not have PHDRS. Index: lld/test/ELF/compress-debug-sections.s =================================================================== --- lld/test/ELF/compress-debug-sections.s +++ lld/test/ELF/compress-debug-sections.s @@ -30,6 +30,21 @@ # RUN: FileCheck -check-prefix=ERR %s # ERR: unknown --compress-debug-sections value: zlib-gabi +## Test GNU version. +# RUN: ld.lld %t.o -o %t3 --compress-debug-sections=zlib-gnu + +# RUN: llvm-objdump -s %t3 | FileCheck %s --check-prefix=ZLIBGNUCONTENT +# ZLIBGNUCONTENT: Contents of section .zdebug_str: +# ZLIBGNUCONTENT-NOT: AAAAAAAAA + +# RUN: llvm-readobj -s %t3 | FileCheck %s --check-prefix=ZLIBGNUFLAGS +# ZLIBGNUFLAGS: Section { +# ZLIBGNUFLAGS: Index: +# ZLIBGNUFLAGS: Name: .zdebug_str +# ZLIBGNUFLAGS-NEXT: Type: SHT_PROGBITS +# ZLIBGNUFLAGS-NEXT: Flags [ +# ZLIBGNUFLAGS-NEXT: SHF_COMPRESSED + .section .debug_str,"MS",@progbits,1 .Linfo_string0: .asciz "AAAAAAAAAAAAAAAAAAAAAAAAAAA"