Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -1149,8 +1149,17 @@ SS->Live = false; // If there are no other sections in the output section, remove it from the // output. - if (OS->Sections.empty()) + if (OS->Sections.empty()) { V.erase(std::find(V.begin(), V.end(), OS)); + // Also remove script commands matching the output section. + auto &Cmds = Script->Opt.Commands; + auto I = std::remove_if(Cmds.begin(), Cmds.end(), [&](BaseCommand *Cmd) { + if (auto *OSCmd = dyn_cast(Cmd)) + return OSCmd->Sec == OS; + return false; + }); + Cmds.erase(I, Cmds.end()); + } } } Index: test/ELF/linkerscript/unused-synthetic.s =================================================================== --- /dev/null +++ test/ELF/linkerscript/unused-synthetic.s @@ -0,0 +1,18 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "SECTIONS { \ +# RUN: .got : { *(.got) } \ +# RUN: .plt : { *(.plt) } \ +# RUN: .text : { *(.text) } \ +# RUN: }" > %t.script +# RUN: ld.lld -shared -o %t.so --script %t.script %t.o + +# RUN: llvm-objdump -section-headers %t.so | FileCheck %s +# CHECK-NOT: .got +# CHECK-NOT: .plt +# CHECK: .text +# CHECK-NEXT: .dynsym + +.global _start +_start: + nop