Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -834,9 +834,16 @@ if (Sec.ExpressionsUseSymbols) return false; - for (BaseCommand *Base : Sec.SectionCommands) + for (BaseCommand *Base : Sec.SectionCommands) { + if (auto Cmd = dyn_cast(Base)) + // Don't create empty output sections just for unreferenced PROVIDE + // symbols. + if (Cmd->Provide) + continue; + if (!isa(*Base)) return false; + } return true; } Index: test/ELF/linkerscript/Inputs/provide-empty-section.s =================================================================== --- test/ELF/linkerscript/Inputs/provide-empty-section.s +++ test/ELF/linkerscript/Inputs/provide-empty-section.s @@ -0,0 +1,2 @@ +baz: + call foo Index: test/ELF/linkerscript/provide-empty-section.s =================================================================== --- test/ELF/linkerscript/provide-empty-section.s +++ test/ELF/linkerscript/provide-empty-section.s @@ -0,0 +1,34 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tundefined.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tdefined.o -defsym="foo=42" +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/provide-empty-section.s -o %treference.o + +# RUN: echo "SECTIONS { " > %t.script +# RUN: echo " .bar : {" >> %t.script +# RUN: echo " PROVIDE(foo = .);" >> %t.script +# RUN: echo " }" >> %t.script +# RUN: echo "}" >> %t.script + +# Case 1: Provided symbol is undefined and not referenced - empty section should be removed. +# RUN: ld.lld %tundefined.o -T %t.script -o %t1.elf +# RUN: llvm-readobj -sections %t1.elf | FileCheck %s --check-prefix=NOSECTION + +# Case 2: Provided symbol is undefined and referenced - empty section should not be removed. +# RUN: ld.lld %tundefined.o %treference.o -T %t.script -o %t2.elf +# RUN: llvm-readobj -sections %t2.elf | FileCheck %s --check-prefix=SECTION + +# Case 3: Provided symbol is defined and not referenced - empty section should be removed. +# RUN: ld.lld %tdefined.o -T %t.script -o %t3.elf +# RUN: llvm-readobj -sections %t3.elf | FileCheck %s --check-prefix=NOSECTION + +# Case 4: Provided symbol is defined and referenced - empty section should not be removed. +# RUN: ld.lld %tdefined.o %treference.o -T %t.script -o %t4.elf +# RUN: llvm-readobj -sections %t4.elf | FileCheck %s --check-prefix=SECTION + +.global _start +_start: + ret + +# SECTION: .bar +# NOSECTION-NOT: .bar