Index: COFF/Writer.cpp =================================================================== --- COFF/Writer.cpp +++ COFF/Writer.cpp @@ -319,16 +319,50 @@ static StringRef getOutputSection(StringRef Name) { StringRef S = Name.split('$').first; + S = S.substr(0, S.find('.', 1)); auto It = Config->Merge.find(S); if (It == Config->Merge.end()) return S; return It->second; } +static bool orderSections(const StringRef& FullA, const StringRef& FullB) { + StringRef A = FullA; + StringRef B = FullB; + StringRef SectA = A.split('$').first; + StringRef SectB = B.split('$').first; + SectA = SectA.substr(0, SectA.find('.', 1)); + SectB = SectB.substr(0, SectB.find('.', 1)); + if (SectA != SectB) + return A < B; + A = A.substr(SectA.size()); + B = B.substr(SectB.size()); + if (A.empty() || B.empty()) + return A < B; + bool DollarA = A[0] == '$'; + bool DollarB = B[0] == '$'; + if (DollarA && DollarB) + return A < B; + if (DollarA != DollarB) + return DollarB; + bool PeriodA = A[0] == '.'; + bool PeriodB = B[0] == '.'; + if (!PeriodA || !PeriodB) + return A < B; + A = A.substr(1); + B = B.substr(1); + int NumA, NumB; + if (!A.getAsInteger(10, NumA) && !B.getAsInteger(10, NumB)) + return NumA < NumB; + return A < B; +} + // Create output section objects and add them to OutputSections. void Writer::createSections() { // First, bin chunks by name. - std::map> Map; + std::map, + bool (*)(const StringRef &, const StringRef &)> + Map(orderSections); for (Chunk *C : Symtab->getChunks()) { auto *SC = dyn_cast(C); if (SC && !SC->isLive()) { Index: test/COFF/ctors_dtors_priority.s =================================================================== --- /dev/null +++ test/COFF/ctors_dtors_priority.s @@ -0,0 +1,34 @@ +# REQUIRES: x86 +# RUN: llvm-mc -triple=x86_64-windows-gnu -filetype=obj -o %t.obj %s +# RUN: lld-link -entry:main %t.obj -out:%t.exe +# RUN: llvm-objdump -s %t.exe | FileCheck %s + +.globl main +main: + nop + +.section .ctors$zzz, "w" + .quad 4 +.section .ctors.5, "w" + .quad 2 +.section .ctors, "w" + .quad 1 +.section .ctors.100, "w" + .quad 3 + +.section .dtors, "w" + .quad 1 +.section .dtors$zzz, "w" + .quad 4 +.section .dtors.100, "w" + .quad 3 +.section .dtors.5, "w" + .quad 2 + +# CHECK: Contents of section .ctors: +# CHECK-NEXT: 140001000 01000000 00000000 02000000 00000000 +# CHECK-NEXT: 140001010 03000000 00000000 04000000 00000000 + +# CHECK: Contents of section .dtors: +# CHECK-NEXT: 140002000 01000000 00000000 02000000 00000000 +# CHECK-NEXT: 140002010 03000000 00000000 04000000 00000000