[PATCH] D40408: [LLD] [COFF] Implement numerical sorting of constructors with priority

Martin Storsjö via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 24 00:56:43 PST 2017


mstorsjo created this revision.

All the sections in the form .ctors.<num> should be sorted numerically, not alphabetically, and should end up sorted before a sentinel that has the section name .ctors$zzz.


https://reviews.llvm.org/D40408

Files:
  COFF/Writer.cpp
  test/COFF/ctors_dtors_priority.s


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
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<StringRef, std::vector<Chunk *>> Map;
+  std::map<StringRef, std::vector<Chunk *>,
+           bool (*)(const StringRef &, const StringRef &)>
+      Map(orderSections);
   for (Chunk *C : Symtab->getChunks()) {
     auto *SC = dyn_cast<SectionChunk>(C);
     if (SC && !SC->isLive()) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D40408.124134.patch
Type: text/x-patch
Size: 2727 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171124/06eafd5f/attachment.bin>


More information about the llvm-commits mailing list