Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -233,6 +233,16 @@ return false; } +static bool compCtorsPriority(StringRef X, StringRef Y) { + if (X.empty() && Y.empty()) + return false; + uint64_t ValX, ValY; + if (to_integer(X.trim('0'), ValX, 10) && to_integer(Y.trim('0'), ValY, 10)) + if (ValX != ValY) + return ValX < ValY; + return X < Y; +} + // A helper function for the SORT() command. static std::function getComparator(SortSectionPolicy K) { @@ -250,6 +260,13 @@ }; case SortSectionPolicy::Priority: return [](InputSectionBase *A, InputSectionBase *B) { + // This is used for SORT_BY_INIT_PRIORITY. + // Which sorts section by GCC priority attribute. + // Manual says order is ascending, but in real life gnu + // linkers sort .[cd]tors differently from {.init,.fini}_array's. + if ((A->Name.startswith(".ctors.") || A->Name.startswith(".dtors.")) && + (B->Name.startswith(".ctors.") || B->Name.startswith(".dtors."))) + return compCtorsPriority(A->Name.substr(7), B->Name.substr(7)); return getPriority(A->Name) < getPriority(B->Name); }; default: Index: test/ELF/linkerscript/sort-init2.s =================================================================== --- test/ELF/linkerscript/sort-init2.s +++ test/ELF/linkerscript/sort-init2.s @@ -0,0 +1,26 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o +# RUN: echo "SECTIONS { \ +# RUN: .init_array : { *(SORT_BY_INIT_PRIORITY(.ctors.*)) } \ +# RUN: .fini_array : { *(SORT_BY_INIT_PRIORITY(.dtors.*)) } }" > %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: 030201 +# CHECK: Contents of section .fini_array: +# CHECK-NEXT: 131211 + +.section .ctors.5, "aw", @progbits + .byte 0x1 +.section .ctors.005, "aw", @progbits + .byte 0x2 +.section .ctors.100, "aw", @progbits + .byte 0x3 + +.section .dtors.5, "aw", @progbits + .byte 0x11 +.section .dtors.005, "aw", @progbits + .byte 0x12 +.section .dtors.100, "aw", @progbits + .byte 0x13