Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -250,6 +250,14 @@ }; case SortSectionPolicy::Priority: return [](InputSectionBase *A, InputSectionBase *B) { + // This is used for SORT_BY_INIT_PRIORITY. + // Which sorts sections by GCC priority attribute in ascending order. + // Compiler encodes priority value in section name. For .[cd]tors + // it is encoded as (65535 - Priority), and for .{fini,init}array it is + // Priority itself. So comparsion predicate is different. + if ((A->Name.startswith(".ctors.") || A->Name.startswith(".dtors.")) && + (B->Name.startswith(".ctors.") || B->Name.startswith(".dtors."))) + return getPriority(A->Name) > getPriority(B->Name); 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,22 @@ +# 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: 0301 +# CHECK: Contents of section .fini_array: +# CHECK-NEXT: 1311 + +.section .ctors.5, "aw", @progbits + .byte 0x1 +.section .ctors.100, "aw", @progbits + .byte 0x3 + +.section .dtors.5, "aw", @progbits + .byte 0x11 +.section .dtors.100, "aw", @progbits + .byte 0x13