[PATCH] D31664: [LLD][ELF] Prefer placing ThunkSections before non ThunkSections

Peter Smith via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 4 04:40:50 PDT 2017


peter.smith created this revision.
Herald added subscribers: rengolin, aemerson.

When there is an inline thunks such as the Mips LA25 and a non inline thunk in the same OutputSection at the same OutSecOff we must make sure that we output the inline thunk last as control may drop through.

At present we haven't implemented any ARM inline thunks yet, and there aren't any non-inline thunks for Mips so this change may not be necessary just yet.


https://reviews.llvm.org/D31664

Files:
  ELF/Relocations.cpp


Index: ELF/Relocations.cpp
===================================================================
--- ELF/Relocations.cpp
+++ ELF/Relocations.cpp
@@ -949,6 +949,14 @@
 
     // Order Thunks in ascending OutSecOff
     auto ThunkCmp = [](const ThunkSection *A, const ThunkSection *B) {
+      if (A->OutSecOff == B->OutSecOff) {
+        // If we have two ThunkSections at the same address and one has a
+        // specific Target then the specific Target comes last as control may
+        // fall through from the Thunk to the Target
+        if (!A->getTargetInputSection() && B->getTargetInputSection())
+          return true;
+        return false;
+      }
       return A->OutSecOff < B->OutSecOff;
     };
     std::stable_sort(ThunkBegin, ThunkEnd, ThunkCmp);
@@ -960,12 +968,18 @@
       // std::merge requires a strict weak ordering.
       if (A->OutSecOff < B->OutSecOff)
         return true;
-      if (A->OutSecOff == B->OutSecOff)
+      if (A->OutSecOff == B->OutSecOff) {
+        auto *TA = dyn_cast<ThunkSection>(A);
+        auto *TB = dyn_cast<ThunkSection>(B);
         // Check if Thunk is immediately before any specific Target InputSection
         // for example Mips LA25 Thunks.
-        if (auto *TA = dyn_cast<ThunkSection>(A))
-          if (TA && TA->getTargetInputSection() == B)
-            return true;
+        if (TA && TA->getTargetInputSection() == B)
+          return true;
+        else if (TA && !TB && !TA->getTargetInputSection())
+          // In general place Thunk Sections without specific targets before
+          // non-Thunk Sections
+          return true;
+      }
       return false;
     };
     std::merge(OS->Sections.begin(), OS->Sections.end(), ThunkBegin, ThunkEnd,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D31664.94046.patch
Type: text/x-patch
Size: 1730 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170404/fa45f4cf/attachment.bin>


More information about the llvm-commits mailing list