[lld] r370923 - [ELF] Don't shrink RelrSection

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 4 09:27:35 PDT 2019


Author: maskray
Date: Wed Sep  4 09:27:35 2019
New Revision: 370923

URL: http://llvm.org/viewvc/llvm-project?rev=370923&view=rev
Log:
[ELF] Don't shrink RelrSection

Fixes PR43214.

The size of SHT_RELR may oscillate between 2 numbers (see D53003 for a
similar --pack-dyn-relocs=android issue). This can happen if the shrink
of SHT_RELR causes it to take more words to encode relocation offsets
(this can happen with thunks or segments with overlapping p_offset
ranges), and the expansion of SHT_RELR causes it to take fewer words to
encode relocation offsets.

To avoid the issue, add padding 1s to the end of the relocation section
if its size would decrease. Trailing 1s do not decode to more relocations.

Reviewed By: peter.smith

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

Added:
    lld/trunk/test/ELF/pack-dyn-relocs-relr-loop.s
Modified:
    lld/trunk/ELF/SyntheticSections.cpp

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=370923&r1=370922&r2=370923&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Wed Sep  4 09:27:35 2019
@@ -1957,6 +1957,14 @@ template <class ELFT> bool RelrSection<E
     }
   }
 
+  // Don't allow the section to shrink; otherwise the size of the section can
+  // oscillate infinitely. Trailing 1s do not decode to more relocations.
+  if (relrRelocs.size() < oldSize) {
+    log(".relr.dyn needs " + Twine(oldSize - relrRelocs.size()) +
+        " padding word(s)");
+    relrRelocs.resize(oldSize, Elf_Relr(1));
+  }
+
   return relrRelocs.size() != oldSize;
 }
 

Added: lld/trunk/test/ELF/pack-dyn-relocs-relr-loop.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/pack-dyn-relocs-relr-loop.s?rev=370923&view=auto
==============================================================================
--- lld/trunk/test/ELF/pack-dyn-relocs-relr-loop.s (added)
+++ lld/trunk/test/ELF/pack-dyn-relocs-relr-loop.s Wed Sep  4 09:27:35 2019
@@ -0,0 +1,36 @@
+# REQUIRES: aarch64
+# RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
+# RUN: ld.lld -pie --pack-dyn-relocs=relr -z max-page-size=4096 --verbose %t.o -o %t 2>&1 | FileCheck %s
+# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELR %s
+
+## This test makes sure we don't shrink .relr.dyn, otherwise its size may
+## oscillate between 2 words and 3 words.
+
+## The test is very sensitive to the exact section sizes and offsets,
+## make sure .data is located at a page boundary.
+
+# CHECK: .relr.dyn needs 1 padding word(s)
+
+# RELR:      .relr.dyn {
+# RELR-NEXT:   0x2F40 R_AARCH64_RELATIVE - 0x0
+# RELR-NEXT:   0x2F48 R_AARCH64_RELATIVE - 0x0
+# RELR-NEXT:   0x3000 R_AARCH64_RELATIVE - 0x0
+# RELR-NEXT: }
+
+.section .data.rel.ro
+.align 3
+.space 0xce0
+foo:
+## Encoded by the first word of .relr.dyn
+.quad foo
+
+## Encoded by the second word of .relr.dyn
+.quad foo
+
+.section .data
+.align 3
+## If .data is at 0x3000, the relocation will be encoded by the second word.
+## If we shrink .relr.dyn, the end of .dynamic will be at 0x2ff8 and .data
+## will be at 0x3ff8, we will need the third word to encode this relocation,
+## which will cause .relr.dyn to expand again.
+.quad foo




More information about the llvm-commits mailing list