Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -1346,23 +1346,21 @@ if (!OS || !SS->empty()) continue; - std::vector::iterator Empty = OS->SectionCommands.end(); - for (auto I = OS->SectionCommands.begin(), E = OS->SectionCommands.end(); - I != E; ++I) { - BaseCommand *B = *I; - if (auto *ISD = dyn_cast(B)) { + // If we reach here, then SS is an unused synthetic section and we want to + // remove it from corresponding input section description of output section. + for (BaseCommand *B : OS->SectionCommands) + if (auto *ISD = dyn_cast(B)) llvm::erase_if(ISD->Sections, [=](InputSection *IS) { return IS == SS; }); - if (ISD->Sections.empty()) - Empty = I; - } - } - if (Empty != OS->SectionCommands.end()) - OS->SectionCommands.erase(Empty); - // If there are no other sections in the output section, remove it from the - // output. - if (OS->SectionCommands.empty()) + // If there are no other alive sections or commands left in the output + // section description, we remove it from the output. + bool IsEmpty = llvm::all_of(OS->SectionCommands, [](BaseCommand *B) { + if (auto *ISD = dyn_cast(B)) + return ISD->Sections.empty(); + return false; + }); + if (IsEmpty) OS->Live = false; } } Index: test/ELF/linkerscript/unused-synthetic.s =================================================================== --- test/ELF/linkerscript/unused-synthetic.s +++ test/ELF/linkerscript/unused-synthetic.s @@ -1,7 +1,7 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o # RUN: echo "SECTIONS { \ -# RUN: .got : { *(.got) } \ +# RUN: .got : { *(.got) *(.got) } \ # RUN: .plt : { *(.plt) } \ # RUN: .text : { *(.text) } \ # RUN: }" > %t.script Index: test/ELF/linkerscript/unused-synthetic2.s =================================================================== --- test/ELF/linkerscript/unused-synthetic2.s +++ test/ELF/linkerscript/unused-synthetic2.s @@ -0,0 +1,9 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=armv7-unknown-linux-gnueabi %s -o %t.o +# RUN: echo "SECTIONS { .trap : { *(.ARM.exidx) *(.dummy) } }" > %t.script + +## We incorrectly removed unused synthetic sections and crashed before. +## Check we do not crash and do not produce .trap output section. +# RUN: ld.lld -shared -o %t.so --script %t.script %t.o +# RUN: llvm-objdump -section-headers %t.so | FileCheck %s +# CHECK-NOT: .trap