[lld] r332688 - Mitigate relocation overflow [part 2 of 2]

Han Shen via llvm-commits llvm-commits at lists.llvm.org
Thu May 17 20:01:06 PDT 2018


Author: shenhan
Date: Thu May 17 20:01:06 2018
New Revision: 332688

URL: http://llvm.org/viewvc/llvm-project?rev=332688&view=rev
Log:
Mitigate relocation overflow [part 2 of 2]

_init_array_start/end are placed at 0 if no ".init_array" presents,
this causes .text relocation against them become more prone to overflow.
This CL sets ".init_array" address to that of ".text" to mitigate the situation.

Review: https://reviews.llvm.org/D46200


Modified:
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/ELF/pre_init_fini_array_missing.s

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=332688&r1=332687&r2=332688&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu May 17 20:01:06 2018
@@ -1702,17 +1702,29 @@ template <class ELFT> void Writer<ELFT>:
 // The linker is expected to define SECNAME_start and SECNAME_end
 // symbols for a few sections. This function defines them.
 template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
-  auto Define = [&](StringRef Start, StringRef End, OutputSection *OS) {
-    // These symbols resolve to the image base if the section does not exist.
-    // A special value -1 indicates end of the section.
+  // If a section does not exist, there's ambiguity as to how we
+  // define _start and _end symbols for an init/fini section. Since
+  // the loader assume that the symbols are always defined, we need to
+  // always define them. But what value? The loader iterates over all
+  // pointers between _start and _end to run global ctors/dtors, so if
+  // the section is empty, their symbol values don't actually matter
+  // as long as _start and _end point to the same location.
+  //
+  // That said, we don't want to set the symbols to 0 (which is
+  // probably the simplest value) because that could cause some
+  // program to fail to link due to relocation overflow, if their
+  // program text is above 2 GiB. We use the address of the .text
+  // section instead to prevent that failure.
+  OutputSection *Default = findSection(".text");
+  if (!Default)
+    Default = Out::ElfHeader;
+  auto Define = [=](StringRef Start, StringRef End, OutputSection *OS) {
     if (OS) {
       addOptionalRegular(Start, OS, 0);
       addOptionalRegular(End, OS, -1);
     } else {
-      if (Config->Pic)
-        OS = Out::ElfHeader;
-      addOptionalRegular(Start, OS, 0);
-      addOptionalRegular(End, OS, 0);
+      addOptionalRegular(Start, Default, 0);
+      addOptionalRegular(End, Default, 0);
     }
   };
 

Modified: lld/trunk/test/ELF/pre_init_fini_array_missing.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/pre_init_fini_array_missing.s?rev=332688&r1=332687&r2=332688&view=diff
==============================================================================
--- lld/trunk/test/ELF/pre_init_fini_array_missing.s (original)
+++ lld/trunk/test/ELF/pre_init_fini_array_missing.s Thu May 17 20:01:06 2018
@@ -14,30 +14,27 @@ _start:
   call __fini_array_start
   call __fini_array_end
 
-// With no .init_array section the symbols resolve to 0
-// 0 - (0x201000 + 5) = -2101253
-// 0 - (0x201005 + 5) = -2101258
-// 0 - (0x20100a + 5) = -2101263
-// 0 - (0x20100f + 5) = -2101268
-// 0 - (0x201014 + 5) = -2101273
-// 0 - (0x201019 + 5) = -2101278
+// With no .init_array section the symbols resolve to .text.
+// 0x201000 - (0x201000 + 5) = -5
+// 0x201000 - (0x201005 + 5) = -10
+// ...
 
 // CHECK: Disassembly of section .text:
 // CHECK-NEXT:  _start:
-// CHECK-NEXT:   201000:    e8 fb ef df ff     callq    -2101253
-// CHECK-NEXT:   201005:    e8 f6 ef df ff     callq    -2101258
-// CHECK-NEXT:   20100a:    e8 f1 ef df ff     callq    -2101263
-// CHECK-NEXT:   20100f:    e8 ec ef df ff     callq    -2101268
-// CHECK-NEXT:   201014:    e8 e7 ef df ff     callq    -2101273
-// CHECK-NEXT:   201019:    e8 e2 ef df ff     callq    -2101278
+// CHECK-NEXT:   201000:    e8 fb ff ff ff     callq    -5
+// CHECK-NEXT:   201005:    e8 f6 ff ff ff     callq    -10
+// CHECK-NEXT:   20100a:    e8 f1 ff ff ff     callq    -15
+// CHECK-NEXT:   20100f:    e8 ec ff ff ff     callq    -20
+// CHECK-NEXT:   201014:    e8 e7 ff ff ff     callq    -25
+// CHECK-NEXT:   201019:    e8 e2 ff ff ff     callq    -30
 
-// In position-independent binaries, they resolve to the image base.
+// In position-independent binaries, they resolve to .text too.
 
 // PIE:      Disassembly of section .text:
 // PIE-NEXT: _start:
-// PIE-NEXT:     1000:	e8 fb ef ff ff 	callq	-4101
-// PIE-NEXT:     1005:	e8 f6 ef ff ff 	callq	-4106
-// PIE-NEXT:     100a:	e8 f1 ef ff ff 	callq	-4111
-// PIE-NEXT:     100f:	e8 ec ef ff ff 	callq	-4116
-// PIE-NEXT:     1014:	e8 e7 ef ff ff 	callq	-4121
-// PIE-NEXT:     1019:	e8 e2 ef ff ff 	callq	-4126
+// PIE-NEXT:     1000:  e8 fb ff ff ff  callq   -5
+// PIE-NEXT:     1005:  e8 f6 ff ff ff  callq   -10
+// PIE-NEXT:     100a:  e8 f1 ff ff ff  callq   -15
+// PIE-NEXT:     100f:  e8 ec ff ff ff  callq   -20
+// PIE-NEXT:     1014:  e8 e7 ff ff ff  callq   -25
+// PIE-NEXT:     1019:  e8 e2 ff ff ff  callq   -30




More information about the llvm-commits mailing list