Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -813,7 +813,7 @@ for (BaseCommand *Base : Sec.SectionCommands) if (!isa(*Base)) return false; - return getInputSections(&Sec).empty(); + return true; } void LinkerScript::adjustSectionsBeforeSorting() { @@ -839,23 +839,23 @@ // the previous sections. Only a few flags are needed to keep the impact low. uint64_t Flags = SHF_ALLOC; - for (BaseCommand *&Cmd : SectionCommands) { + for (BaseCommand *Cmd : SectionCommands) { auto *Sec = dyn_cast(Cmd); if (!Sec) continue; // A live output section means that some input section was added to it. It - // might have been removed (gc, or empty synthetic section), but we at least + // might have been removed (if it was empty synthetic section), but we at least // know the flags. if (Sec->Live) - Flags = Sec->Flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR); - else - Sec->Flags = Flags; - - if (isDiscardable(*Sec)) { - Sec->Live = false; - Cmd = nullptr; - } + Flags = Sec->Flags; + + // We do not want to keep any special flags for output section in case it is empty. + bool IsEmpty = getInputSections(Sec).empty(); + if (IsEmpty) + Sec->Flags = Flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR); + + Sec->Live = !IsEmpty || !isDiscardable(*Sec); } // It is common practice to use very generic linker scripts. So for any @@ -864,7 +864,9 @@ // clutter the output. // We instead remove trivially empty sections. The bfd linker seems even // more aggressive at removing them. - llvm::erase_if(SectionCommands, [&](BaseCommand *Base) { return !Base; }); + llvm::erase_if(SectionCommands, [&](BaseCommand *Base) { + return isa(Base) && !cast(Base)->Live; + }); } void LinkerScript::adjustSectionsAfterSorting() { Index: test/ELF/linkerscript/empty-link-order.test =================================================================== --- test/ELF/linkerscript/empty-link-order.test +++ test/ELF/linkerscript/empty-link-order.test @@ -0,0 +1,10 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=arm-arm-none-eabi -o %t.o < /dev/null + +SECTIONS { + .foo : { + bar = .; + *(.ARM.exidx*) + } +} +# RUN: ld.lld %t.o -o %t --script %s