diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -73,7 +73,14 @@ enum class OrphanHandlingPolicy { Place, Warn, Error }; // For --sort-section and linkerscript sorting rules. -enum class SortSectionPolicy { Default, None, Alignment, Name, Priority }; +enum class SortSectionPolicy { + Default, + None, + Alignment, + Name, + Priority, + Reverse, +}; // For --target2 enum class Target2Policy { Abs, Rel, GotRel }; diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -457,6 +457,8 @@ return llvm::stable_sort(vec, nameComparator); case SortSectionPolicy::Priority: return llvm::stable_sort(vec, priorityComparator); + case SortSectionPolicy::Reverse: + return std::reverse(vec.begin(), vec.end()); } } diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -660,6 +660,7 @@ SortSectionPolicy ScriptParser::peekSortKind() { return StringSwitch(peek()) + .Case("REVERSE", SortSectionPolicy::Reverse) .Cases("SORT", "SORT_BY_NAME", SortSectionPolicy::Name) .Case("SORT_BY_ALIGNMENT", SortSectionPolicy::Alignment) .Case("SORT_BY_INIT_PRIORITY", SortSectionPolicy::Priority) diff --git a/lld/test/ELF/linkerscript/sort-init.s b/lld/test/ELF/linkerscript/sort-init.s --- a/lld/test/ELF/linkerscript/sort-init.s +++ b/lld/test/ELF/linkerscript/sort-init.s @@ -9,6 +9,14 @@ # CHECK: Hex dump of section '.init_array': # CHECK-NEXT: 0x00000001 00010203 04050607 +## Test REVERSE can be used to reverse the order of .init_array and .ctors + +# RUN: ld.lld -T %t/reverse.lds %t.o -o %t2.out +# RUN: llvm-readelf -x .init_array %t2.out | FileCheck %s --check-prefix=CHECK2 + +# CHECK2: Hex dump of section '.init_array': +# CHECK2-NEXT: 0x00000001 04030201 00050706 + #--- asm .globl _start _start: @@ -41,3 +49,11 @@ *(.init_array .ctors) } } + +#--- reverse.lds +SECTIONS { + .init_array : { + *(REVERSE(SORT_BY_INIT_PRIORITY(.init_array.* .ctors.*)) SORT_BY_INIT_PRIORITY(foo*)) + *(REVERSE(.init_array .ctors)) + } +}