diff options
-rw-r--r-- | lld/ELF/LinkerScript.cpp | 9 | ||||
-rw-r--r-- | lld/ELF/OutputSections.h | 1 | ||||
-rw-r--r-- | lld/ELF/ScriptParser.cpp | 4 | ||||
-rw-r--r-- | lld/test/ELF/linkerscript/empty-sections-expressions.s | 18 |
4 files changed, 27 insertions, 5 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 69a35be858c..6aae9e6975d 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -778,11 +778,10 @@ static bool isDiscardable(OutputSection &Sec) { 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) diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index 35a873488f2..ce6bff32228 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -101,6 +101,7 @@ public: std::string LMARegionName; bool NonAlloc = false; bool Noload = false; + bool ExpressionsUseSymbols = false; template <class ELFT> void finalize(); template <class ELFT> void writeTo(uint8_t *Buf); diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index 6073820ff69..d2f12a10cfa 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -671,6 +671,8 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) { OutputSection *Cmd = Script->createOutputSection(OutSec, getCurrentLocation()); + size_t SymbolsReferenced = Script->ReferencedSymbols.size(); + if (peek() != ":") readSectionAddressType(Cmd); expect(":"); @@ -737,6 +739,8 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) { // Consume optional comma following output section command. consume(","); + if (Script->ReferencedSymbols.size() > SymbolsReferenced) + Cmd->ExpressionsUseSymbols = true; return Cmd; } diff --git a/lld/test/ELF/linkerscript/empty-sections-expressions.s b/lld/test/ELF/linkerscript/empty-sections-expressions.s new file mode 100644 index 00000000000..3c9a9edf578 --- /dev/null +++ b/lld/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: |