Index: lld/trunk/ELF/LinkerScript.h =================================================================== --- lld/trunk/ELF/LinkerScript.h +++ lld/trunk/ELF/LinkerScript.h @@ -61,9 +61,6 @@ // SECTIONS commands. std::vector Sections; - // Output sections are sorted by this order. - std::vector SectionOrder; - // Section fill attribute for each section. llvm::StringMap> Filler; @@ -86,6 +83,7 @@ bool shouldKeep(InputSectionBase *S); void assignAddresses(std::vector *> &S); int compareSections(StringRef A, StringRef B); + uint32_t getSectionOrder(StringRef Name); private: SectionRule *find(InputSectionBase *S); Index: lld/trunk/ELF/LinkerScript.cpp =================================================================== --- lld/trunk/ELF/LinkerScript.cpp +++ lld/trunk/ELF/LinkerScript.cpp @@ -204,8 +204,7 @@ // https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections. for (OutputSectionBase *Sec : Sections) { StringRef Name = Sec->getName(); - auto I = std::find(Opt.SectionOrder.begin(), Opt.SectionOrder.end(), Name); - if (I == Opt.SectionOrder.end()) + if (getSectionOrder(Name) == (uint32_t)-1) Opt.Commands.push_back({SectionKind, {}, Name}); } @@ -249,15 +248,23 @@ return I->second; } -// A compartor to sort output sections. Returns -1 or 1 if both -// A and B are mentioned in linker scripts. Otherwise, returns 0 -// to use the default rule which is implemented in Writer.cpp. +template +uint32_t LinkerScript::getSectionOrder(StringRef Name) { + auto Begin = Opt.Commands.begin(); + auto End = Opt.Commands.end(); + auto I = std::find_if(Begin, End, [&](SectionsCommand &N) { + return N.Kind == SectionKind && N.SectionName == Name; + }); + return I == End ? (uint32_t)-1 : (I - Begin); +} + +// A compartor to sort output sections. Returns -1 or 1 if +// A or B are mentioned in linker script. Otherwise, returns 0. template int LinkerScript::compareSections(StringRef A, StringRef B) { - auto E = Opt.SectionOrder.end(); - auto I = std::find(Opt.SectionOrder.begin(), E, A); - auto J = std::find(Opt.SectionOrder.begin(), E, B); - if (I == E || J == E) + uint32_t I = getSectionOrder(A); + uint32_t J = getSectionOrder(B); + if (I == (uint32_t)-1 && J == (uint32_t)-1) return 0; return I < J ? -1 : 1; } @@ -509,7 +516,6 @@ void ScriptParser::readOutputSectionDescription() { StringRef OutSec = next(); - Opt.SectionOrder.push_back(OutSec); Opt.Commands.push_back({SectionKind, {}, OutSec}); expect(":"); expect("{"); Index: lld/trunk/test/ELF/linkerscript-orphans.s =================================================================== --- lld/trunk/test/ELF/linkerscript-orphans.s +++ lld/trunk/test/ELF/linkerscript-orphans.s @@ -0,0 +1,31 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +# RUN: echo "SECTIONS { .writable : { *(.writable) } }" > %t.script +# RUN: ld.lld -o %t.out --script %t.script %t +# RUN: llvm-objdump -section-headers %t.out | \ +# RUN: FileCheck -check-prefix=TEXTORPHAN %s + +# RUN: echo "SECTIONS { .text : { *(.text) } }" > %t.script +# RUN: ld.lld -o %t.out --script %t.script %t +# RUN: llvm-objdump -section-headers %t.out | \ +# RUN: FileCheck -check-prefix=WRITABLEORPHAN %s + +# TEXTORPHAN: Sections: +# TEXTORPHAN-NEXT: Idx Name +# TEXTORPHAN-NEXT: 0 +# TEXTORPHAN-NEXT: 1 .writable +# TEXTORPHAN-NEXT: 2 .text + +# WRITABLEORPHAN: Sections: +# WRITABLEORPHAN-NEXT: Idx Name +# WRITABLEORPHAN-NEXT: 0 +# WRITABLEORPHAN-NEXT: 1 .text +# WRITABLEORPHAN-NEXT: 2 .writable + +.global _start +_start: + nop + +.section .writable,"aw" + .zero 4