Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -778,11 +778,10 @@ if (!Sec.Phdrs.empty()) return false; - // We do not want to remove sections that have custom address or align - // expressions set even if them are empty. We keep them because we - // want to be sure that any expressions can be evaluated and report - // an error otherwise. - if (Sec.AddrExpr || Sec.AlignExpr || Sec.LMAExpr) + // We do not want to remove sections that reference symbols in address and + // other expressions. We add script symbols as undefined, and want to ensure + // all of them are defined in the output, hence have to keep them. + if (Sec.ExpressionsUseSymbols) return false; for (BaseCommand *Base : Sec.SectionCommands) Index: ELF/OutputSections.h =================================================================== --- ELF/OutputSections.h +++ ELF/OutputSections.h @@ -101,6 +101,7 @@ std::string LMARegionName; bool NonAlloc = false; bool Noload = false; + bool ExpressionsUseSymbols = false; template void finalize(); template void writeTo(uint8_t *Buf); Index: ELF/ScriptParser.cpp =================================================================== --- ELF/ScriptParser.cpp +++ ELF/ScriptParser.cpp @@ -671,6 +671,8 @@ OutputSection *Cmd = Script->createOutputSection(OutSec, getCurrentLocation()); + size_t SymbolsReferenced = Script->ReferencedSymbols.size(); + if (peek() != ":") readSectionAddressType(Cmd); expect(":"); @@ -737,6 +739,8 @@ // Consume optional comma following output section command. consume(","); + if (Script->ReferencedSymbols.size() > SymbolsReferenced) + Cmd->ExpressionsUseSymbols = true; return Cmd; } Index: test/ELF/linkerscript/empty-sections-expressions.s =================================================================== --- test/ELF/linkerscript/empty-sections-expressions.s +++ test/ELF/linkerscript/empty-sections-expressions.s @@ -0,0 +1,18 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o + +## We remove empty sections that do not reference symbols in address, +## LMA, align and subalign expressions. Here we check that. + +# RUN: echo "SECTIONS { .debug_info 0 : { *(.debug_info) } }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-objdump -section-headers %t | FileCheck %s +# CHECK-NOT: .debug_info + +# RUN: echo "SECTIONS { .debug_info foo : { *(.debug_info) } }" > %t2.script +# RUN: ld.lld -o %t2 --script %t2.script %t.o +# RUN: llvm-objdump -section-headers %t2 | FileCheck %s --check-prefix=SEC +# SEC: .debug_info + +.globl foo +foo: