[PATCH] D46200: Mitigate relocation overflow [part 2 of 2]

Han Shen via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 27 10:32:03 PDT 2018


shenhan created this revision.
shenhan added reviewers: ruiu, echristo.
Herald added subscribers: llvm-commits, arichardson, emaste.
Herald added a reviewer: espindola.

This CL is to mitigate R_X86_64_PC32 relocation overflow problems for huge binaries that has near 4G allocated sections.

By examining those binaries, I found these 2 issues contributes to the problem:
1). huge ".dynsym" and ".dynstr" stands in the way between .rodata and .text
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 is to address 2). 
( 1) is addressed in https://reviews.llvm.org/D45788 )


Repository:
  rLLD LLVM Linker

https://reviews.llvm.org/D46200

Files:
  ELF/Writer.cpp
  test/ELF/preinit_init_finit_placement.s


Index: test/ELF/preinit_init_finit_placement.s
===================================================================
--- /dev/null
+++ test/ELF/preinit_init_finit_placement.s
@@ -0,0 +1,24 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+// RUN: ld.lld %t -o %t2
+// RUN: llvm-objdump -d %t2 | FileCheck %s
+// REQUIRES: x86
+
+.globl _start
+_start:
+  call __preinit_array_start
+  call __preinit_array_end
+  call __init_array_start
+  call __init_array_end
+  call __fini_array_start
+  call __fini_array_end
+
+// With no .init_array section the symbols resolve to ".text".
+
+// CHECK: Disassembly of section .text:
+// CHECK-NEXT:  _start:
+// 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
Index: ELF/Writer.cpp
===================================================================
--- ELF/Writer.cpp
+++ ELF/Writer.cpp
@@ -1688,17 +1688,20 @@
 // 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.
+  // These symbols resolve to the image base or ".text" if the section
+  // does not exist. Set symbol value to ".text" mitigates the possibilities
+  // that an relocation from .text section to these symbols overflows.
+  // A special value -1 indicates end of the section.
+  OutputSection *DefaultOutSec = findSection(".text");
+  if (!DefaultOutSec && Config->Pic)
+    DefaultOutSec = 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, DefaultOutSec, 0);
+      addOptionalRegular(End, DefaultOutSec, 0);
     }
   };
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D46200.144366.patch
Type: text/x-patch
Size: 2431 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180427/8bf8610a/attachment.bin>


More information about the llvm-commits mailing list