Index: ELF/OutputSections.h =================================================================== --- ELF/OutputSections.h +++ ELF/OutputSections.h @@ -103,6 +103,7 @@ std::string LMARegionName; bool NonAlloc = false; bool Noload = false; + bool ExpressionsUseSymbols = false; template void finalize(); template void writeTo(uint8_t *Buf); Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -84,11 +84,10 @@ if (!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 (AddrExpr || AlignExpr || 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 output, hence have to keep them. + if (ExpressionsUseSymbols) return false; for (BaseCommand *Base : SectionCommands) Index: ELF/ScriptParser.cpp =================================================================== --- ELF/ScriptParser.cpp +++ ELF/ScriptParser.cpp @@ -668,6 +668,8 @@ OutputSection *Cmd = Script->createOutputSection(OutSec, getCurrentLocation()); + size_t SymbolsReferenced = Script->ReferencedSymbols.size(); + if (peek() != ":") readSectionAddressType(Cmd); expect(":"); @@ -734,6 +736,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,19 @@ +# 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: not ld.lld -o %t --script %t2.script %t.o 2>&1 | FileCheck %s --check-prefix=ERR +# ERR: symbol not found: foo + +.text +.globl _start +_start: + nop