[lld] 3834385 - [ELF] Move SHF_LINK_ORDER till OutputSection addresses are known

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Mon May 4 06:26:33 PDT 2020


Author: Peter Smith
Date: 2020-05-04T14:25:25+01:00
New Revision: 3834385f27aeb4cafe1f5f957bff36bdbececf81

URL: https://github.com/llvm/llvm-project/commit/3834385f27aeb4cafe1f5f957bff36bdbececf81
DIFF: https://github.com/llvm/llvm-project/commit/3834385f27aeb4cafe1f5f957bff36bdbececf81.diff

LOG: [ELF] Move SHF_LINK_ORDER till OutputSection addresses are known

Sections with the SHF_LINK_ORDER flag must be ordered in the same relative
order as the Sections they have a link to. When using a linker script an
arbitrary expression may be used for the virtual address of the
OutputSection. In some cases the virtual address does not monotonically
increase as the OutputSection index increases, so if we base the ordering
of the SHF_LINK_ORDER sections on the index then we can get the order
wrong. We fix this by moving SHF_LINK_ORDER resolution till after we have
created OutputSection virtual addresses.

Differential Revision: https://reviews.llvm.org/D79286

Added: 
    lld/test/ELF/linkorder-script.s

Modified: 
    lld/ELF/Writer.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 3c197391a91a..b5a8c33ddd8d 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -1596,7 +1596,7 @@ static bool compareByFilePosition(InputSection *a, InputSection *b) {
   OutputSection *bOut = lb->getParent();
 
   if (aOut != bOut)
-    return aOut->sectionIndex < bOut->sectionIndex;
+    return aOut->addr < bOut->addr;
   return la->outSecOff < lb->outSecOff;
 }
 
@@ -1666,11 +1666,13 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
   AArch64Err843419Patcher a64p;
   ARMErr657417Patcher a32p;
   script->assignAddresses();
-  // .ARM.exidx does not require precise addresses, but it does require the
-  // relative addresses of OutputSections because linker scripts can assign
-  // Virtual Addresses to OutputSections that are not monotonically increasing.
+  // .ARM.exidx and SHF_LINK_ORDER do not require precise addresses, but they
+  // do require the relative addresses of OutputSections because linker scripts
+  // can assign Virtual Addresses to OutputSections that are not monotonically
+  // increasing.
   for (Partition &part : partitions)
     finalizeSynthetic(part.armExidx);
+  resolveShfLinkOrder();
 
   // Converts call x at GDPLT to call __tls_get_addr
   if (config->emachine == EM_HEXAGON)
@@ -2104,12 +2106,6 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
   if (!script->hasSectionsCommand && !config->relocatable)
     fixSectionAlignments();
 
-  // SHFLinkOrder processing must be processed after relative section placements are
-  // known but before addresses are allocated.
-  resolveShfLinkOrder();
-  if (errorCount())
-    return;
-
   // This is used to:
   // 1) Create "thunks":
   //    Jump instructions in many ISAs have small displacements, and therefore
@@ -2132,6 +2128,8 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
   //    sometimes using forward symbol declarations. We want to set the correct
   //    values. They also might change after adding the thunks.
   finalizeAddressDependentContent();
+  if (errorCount())
+    return;
 
   // finalizeAddressDependentContent may have added local symbols to the static symbol table.
   finalizeSynthetic(in.symTab);

diff  --git a/lld/test/ELF/linkorder-script.s b/lld/test/ELF/linkorder-script.s
new file mode 100644
index 000000000000..6bf2887abb2a
--- /dev/null
+++ b/lld/test/ELF/linkorder-script.s
@@ -0,0 +1,32 @@
+// REQUIRES: x86
+// RUN: llvm-mc --triple=x86_64 -filetype=obj %s -o %t.o
+// RUN: echo "SECTIONS { \
+// RUN:         . = 0x80000000; \
+// RUN:         .linkorder : { *(.linkorder.*) } \
+// RUN:         .text : { *(.text) } \
+// RUN:         .text.1 0x80000200 : AT(0x1000) { *(.text.1) } \
+// RUN:         .text.2 0x80000100 : AT(0x2000) { *(.text.2) } \
+// RUN: } " > %t.script
+// RUN: ld.lld --script %t.script %t.o -o %t
+// RUN: llvm-readobj -x .linkorder  %t | FileCheck %s
+
+/// When a linker script does not have monotonically increasing addresses
+/// the SHF_LINK_ORDER sections should still be in monotonically increasing
+/// order.
+
+// CHECK: Hex dump of section '.linkorder':
+// CHECK-NEXT: 0x80000000 0201
+
+.section .text.1, "ax", %progbits
+.global _start
+_start:
+nop
+
+.section .text.2, "ax", %progbits
+.byte 0
+
+.section .linkorder.1, "ao", %progbits, .text.1
+.byte 1
+
+.section .linkorder.2, "ao", %progbits, .text.2
+.byte 2


        


More information about the llvm-commits mailing list