[PATCH] D45788: Mitigate relocation overflow

Han Shen via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 18 15:22:39 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 ".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.

So here is the way this CL proposes:
to fix 1) - group similar PROGBITS together, thus .dynstr no longer stands in between
to fix 2) - set _init_array_start/end to ".text" if no ".init_array" presents

With this Cl, we could fix 16 out of 17 such errors for huge binaries.


Repository:
  rLLD LLVM Linker

https://reviews.llvm.org/D45788

Files:
  ELF/Writer.cpp


Index: ELF/Writer.cpp
===================================================================
--- ELF/Writer.cpp
+++ ELF/Writer.cpp
@@ -681,8 +681,9 @@
   RF_NOT_INTERP = 1 << 17,
   RF_NOT_ALLOC = 1 << 16,
   RF_WRITE = 1 << 15,
-  RF_EXEC_WRITE = 1 << 13,
-  RF_EXEC = 1 << 12,
+  RF_EXEC_WRITE = 1 << 14,
+  RF_EXEC = 1 << 13,
+  RF_PROGBITS = 1 << 12,
   RF_NON_TLS_BSS = 1 << 11,
   RF_NON_TLS_BSS_RO = 1 << 10,
   RF_NOT_TLS = 1 << 9,
@@ -717,6 +718,10 @@
   if (!(Sec->Flags & SHF_ALLOC))
     return Rank | RF_NOT_ALLOC;
 
+  // Place sections with PROGBITS closer.
+  if (Sec->Type == SHT_PROGBITS && !isRelroSection(Sec))
+    Rank |= RF_PROGBITS;
+
   // Sort sections based on their access permission in the following
   // order: R, RX, RWX, RW.  This order is based on the following
   // considerations:
@@ -1675,14 +1680,18 @@
 // 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.
+    // 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.
     if (OS) {
       addOptionalRegular(Start, OS, 0);
       addOptionalRegular(End, OS, -1);
     } else {
       if (Config->Pic)
         OS = Out::ElfHeader;
+      OutputSection* p = findSection(".text");
+      if (p) OS = p;
       addOptionalRegular(Start, OS, 0);
       addOptionalRegular(End, OS, 0);
     }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D45788.143010.patch
Type: text/x-patch
Size: 1723 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180418/68e4d73f/attachment.bin>


More information about the llvm-commits mailing list