Index: ELF/InputFiles.cpp =================================================================== --- ELF/InputFiles.cpp +++ ELF/InputFiles.cpp @@ -537,9 +537,6 @@ return &InputSection::Discarded; } - if (Config->Strip != StripPolicy::None && Name.startswith(".debug")) - return &InputSection::Discarded; - // The linkonce feature is a sort of proto-comdat. Some glibc i386 object // files contain definitions of symbol "__x86.get_pc_thunk.bx" in linkonce // sections. Drop those sections to avoid duplicate symbol errors. Index: ELF/MarkLive.cpp =================================================================== --- ELF/MarkLive.cpp +++ ELF/MarkLive.cpp @@ -255,14 +255,22 @@ forEachSuccessor(*Q.pop_back_val(), Enqueue); } +// Returns true if debug section should be removed from output. Used for +// implementation of --strip-debug/--strip-all. We can't just discard such +// sections earlier because may want to use their content for error reporting. +static bool shouldStrip(InputSectionBase *Sec) { + return (Config->Strip != StripPolicy::None) && Sec->Name.startswith(".debug"); +} + // Before calling this function, Live bits are off for all // input sections. This function make some or all of them on // so that they are emitted to the output file. template void elf::markLive() { - // If -gc-sections is missing, no sections are removed. + // If -gc-sections is missing, no sections are garbage collected, but we + // want to mark debug sections as dead if --strip-debug/--strip-all was used. if (!Config->GcSections) { for (InputSectionBase *Sec : InputSections) - Sec->Live = true; + Sec->Live = !shouldStrip(Sec); return; } @@ -283,7 +291,7 @@ for (InputSectionBase *Sec : InputSections) { bool IsAlloc = (Sec->Flags & SHF_ALLOC); bool IsRel = (Sec->Type == SHT_REL || Sec->Type == SHT_RELA); - if (!IsAlloc && !IsRel) + if (!IsAlloc && !IsRel && !shouldStrip(Sec)) Sec->Live = true; } Index: test/ELF/conflict-debug-variable.s =================================================================== --- test/ELF/conflict-debug-variable.s +++ test/ELF/conflict-debug-variable.s @@ -30,6 +30,9 @@ # CHECK-NEXT: >>> defined at 1.c:1 # CHECK-NEXT: >>> {{.*}}:(.bss+0x0) +## Check that stripping debug sections does not break error reporting. +# RUN: not ld.lld --strip-debug %t.o %t.o -o %t 2>&1 | FileCheck %s + # Used reduced output from following code and gcc 7.1.0 # to produce this input file: # Source (1.c):