Index: ELF/GdbIndex.cpp =================================================================== --- ELF/GdbIndex.cpp +++ ELF/GdbIndex.cpp @@ -17,6 +17,7 @@ #include "GdbIndex.h" #include "Memory.h" #include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h" +#include "llvm/Object/Decompressor.h" #include "llvm/Object/ELFObjectFile.h" using namespace llvm; @@ -33,6 +34,7 @@ .Case(".debug_ranges", &RangeSection) .Case(".debug_line", &LineSection) .Default(nullptr)) { + Sec->maybeUncompress(); M->Data = toStringRef(Sec->Data); M->Sec = Sec; continue; Index: ELF/InputSection.h =================================================================== --- ELF/InputSection.h +++ ELF/InputSection.h @@ -165,7 +165,7 @@ InputSection *getLinkOrderDep() const; - void uncompress(); + void maybeUncompress(); // Returns a source location string. Used to construct an error message. template std::string getLocation(uint64_t Offset); Index: ELF/InputSection.cpp =================================================================== --- ELF/InputSection.cpp +++ ELF/InputSection.cpp @@ -210,9 +210,15 @@ return Sec ? Sec->getParent() : nullptr; } -// Uncompress section contents. Note that this function is called -// from parallelForEach, so it must be thread-safe. -void InputSectionBase::uncompress() { +// Uncompress section contents if required. Note that this function +// is called from parallelForEach, so it must be thread-safe. +void InputSectionBase::maybeUncompress() { + if (UncompressBuf) + return; + + if (!Decompressor::isCompressedELFSection(Flags, Name)) + return; + Decompressor Dec = check(Decompressor::create(Name, toStringRef(Data), Config->IsLE, Config->Is64)); Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -2300,8 +2300,7 @@ parallelForEach(InputSections, [](InputSectionBase *S) { if (!S->Live) return; - if (Decompressor::isCompressedELFSection(S->Flags, S->Name)) - S->uncompress(); + S->maybeUncompress(); if (auto *MS = dyn_cast(S)) MS->splitIntoPieces(); }); Index: test/ELF/compressed-debug-conflict.s =================================================================== --- /dev/null +++ test/ELF/compressed-debug-conflict.s @@ -0,0 +1,29 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple i686-linux-gnu -compress-debug-sections=zlib %s -o %t.o +# RUN: llvm-readobj -sections %t.o | FileCheck -check-prefix=OBJ %s +# RUN: not ld.lld %t.o %t.o -o %tout 2>&1 | FileCheck -check-prefix=ERROR %s + +# OBJ: Sections [ +# OBJ: Section { +# OBJ: Index: 3 +# OBJ-NEXT: Name: .debug_line (16) +# OBJ-NEXT: Type: SHT_PROGBITS (0x1) +# OBJ-NEXT: Flags [ (0x800) +# OBJ-NEXT: SHF_COMPRESSED (0x800) +# OBJ-NEXT: ] + +# ERROR: error: duplicate symbol: main +# ERROR-NEXT: >>> defined at reduced.c:2 (/tmp/reduced.c:2) +# ERROR-NEXT: >>> +# ERROR-NEXT: >>> defined at reduced.c:2 (/tmp/reduced.c:2) +# ERROR-NEXT: >>> + + .text + .file "reduced.c" + .globl main +main: + .file 1 "/tmp" "reduced.c" + .loc 1 2 0 + xorl %eax, %eax + retl + .file 2 "/tmp/repeat/repeat/repeat/repeat" "repeat.h"