Index: lld/trunk/ELF/LinkerScript.h =================================================================== --- lld/trunk/ELF/LinkerScript.h +++ lld/trunk/ELF/LinkerScript.h @@ -95,7 +95,7 @@ ConstraintKind Constraint = ConstraintKind::NoConstraint; }; -enum SortKind { SortNone, SortByName, SortByAlignment }; +enum SortKind { SortNone, SortByPriority, SortByName, SortByAlignment }; struct InputSectionDescription : BaseCommand { InputSectionDescription(StringRef FilePattern) Index: lld/trunk/ELF/LinkerScript.cpp =================================================================== --- lld/trunk/ELF/LinkerScript.cpp +++ lld/trunk/ELF/LinkerScript.cpp @@ -110,6 +110,10 @@ !const_cast(Desc->ExcludedFileRe).match(Filename); } +static bool comparePriority(InputSectionData *A, InputSectionData *B) { + return getPriority(A->Name) < getPriority(B->Name); +} + static bool compareName(InputSectionData *A, InputSectionData *B) { return A->Name < B->Name; } @@ -123,6 +127,8 @@ static std::function getComparator(SortKind K) { + if (K == SortByPriority) + return comparePriority; if (K == SortByName) return compareName; return compareAlignment; @@ -967,6 +973,8 @@ return SortByName; if (skip("SORT_BY_ALIGNMENT")) return SortByAlignment; + if (skip("SORT_BY_INIT_PRIORITY")) + return SortByPriority; return SortNone; } Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -895,19 +895,6 @@ this->updateAlignment(S->Alignment); } -// If an input string is in the form of "foo.N" where N is a number, -// return N. Otherwise, returns 65536, which is one greater than the -// lowest priority. -static int getPriority(StringRef S) { - size_t Pos = S.rfind('.'); - if (Pos == StringRef::npos) - return 65536; - int V; - if (S.substr(Pos + 1).getAsInteger(10, V)) - return 65536; - return V; -} - // This function is called after we sort input sections // and scan relocations to setup sections' offsets. template void OutputSection::assignOffsets() { Index: lld/trunk/ELF/Strings.h =================================================================== --- lld/trunk/ELF/Strings.h +++ lld/trunk/ELF/Strings.h @@ -17,6 +17,7 @@ namespace lld { namespace elf { llvm::Regex compileGlobPatterns(ArrayRef V); +int getPriority(StringRef S); bool hasWildcard(StringRef S); std::vector parseHex(StringRef S); bool isValidCIdentifier(StringRef S); Index: lld/trunk/ELF/Strings.cpp =================================================================== --- lld/trunk/ELF/Strings.cpp +++ lld/trunk/ELF/Strings.cpp @@ -20,6 +20,19 @@ using namespace lld; using namespace lld::elf; +// If an input string is in the form of "foo.N" where N is a number, +// return N. Otherwise, returns 65536, which is one greater than the +// lowest priority. +int elf::getPriority(StringRef S) { + size_t Pos = S.rfind('.'); + if (Pos == StringRef::npos) + return 65536; + int V; + if (S.substr(Pos + 1).getAsInteger(10, V)) + return 65536; + return V; +} + bool elf::hasWildcard(StringRef S) { return S.find_first_of("?*[") != StringRef::npos; } Index: lld/trunk/test/ELF/linkerscript/sort-init.s =================================================================== --- lld/trunk/test/ELF/linkerscript/sort-init.s +++ lld/trunk/test/ELF/linkerscript/sort-init.s @@ -0,0 +1,24 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o +# RUN: echo "SECTIONS { .init_array : { *(SORT_BY_INIT_PRIORITY(.init_array.*)) } }" > %t1.script +# RUN: ld.lld --script %t1.script %t1.o -o %t2 +# RUN: llvm-objdump -s %t2 | FileCheck %s + +# CHECK: Contents of section .init_array: +# CHECK-NEXT: 03020000 00000000 010405 + +.globl _start +_start: + nop + +.section .init_array, "aw", @init_array + .align 8 + .byte 1 +.section .init_array.100, "aw", @init_array + .long 2 +.section .init_array.5, "aw", @init_array + .byte 3 +.section .init_array, "aw", @init_array + .byte 4 +.section .init_array, "aw", @init_array + .byte 5