Fix a bug for packed relocations.
authorRui Ueyama <ruiu@google.com>
Mon, 9 Jul 2018 23:54:24 +0000 (23:54 +0000)
committerRui Ueyama <ruiu@google.com>
Mon, 9 Jul 2018 23:54:24 +0000 (23:54 +0000)
Previously, we didn't create multiple consecutive bitmaps.
Added a test to catch this bug too.

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

llvm-svn: 336620

lld/ELF/SyntheticSections.cpp
lld/test/ELF/pack-dyn-relocs2.s [new file with mode: 0644]

index f15102f..3b87d5c 100644 (file)
@@ -1764,28 +1764,34 @@ template <class ELFT> bool RelrSection<ELFT>::updateAllocSize() {
   for (size_t I = 0, E = Offsets.size(); I < E;) {
     // Add a leading relocation.
     RelrRelocs.push_back(Elf_Relr(Offsets[I]));
+    uint64_t Base = Offsets[I] + Wordsize;
     ++I;
 
-    // Find foldable relocations to create a bitmap.
-    uint64_t Bitmap = 0;
-    for (size_t J = I; J < E; ++J) {
-      uint64_t Delta = Offsets[J] - Offsets[I];
+    // Find foldable relocations to construct bitmaps.
+    while (I < E) {
+      uint64_t Bitmap = 0;
 
-      // If it is too far, it cannot be folded.
-      if (Delta >= NBits * Wordsize)
-        break;
+      while (I < E) {
+        uint64_t Delta = Offsets[I] - Base;
 
-      // If it is not a multiple of wordsize away, it cannot be folded.
-      if (Delta % Wordsize)
-        break;
+        // If it is too far, it cannot be folded.
+        if (Delta >= NBits * Wordsize)
+          break;
 
-      // Fold it.
-      Bitmap |= 1ULL << (Delta / Wordsize);
-    }
+        // If it is not a multiple of wordsize away, it cannot be folded.
+        if (Delta % Wordsize)
+          break;
+
+        // Fold it.
+        Bitmap |= 1ULL << (Delta / Wordsize);
+        ++I;
+      }
+
+      if (!Bitmap)
+        break;
 
-    if (Bitmap) {
       RelrRelocs.push_back(Elf_Relr((Bitmap << 1) | 1));
-      I += NBits;
+      Base += NBits * Wordsize;
     }
   }
 
diff --git a/lld/test/ELF/pack-dyn-relocs2.s b/lld/test/ELF/pack-dyn-relocs2.s
new file mode 100644 (file)
index 0000000..20c7176
--- /dev/null
@@ -0,0 +1,85 @@
+// REQUIRES: arm, aarch64
+
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-shared.s -o %t.so.o
+// RUN: ld.lld -shared %t.so.o -o %t.so
+
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
+// RUN: ld.lld -pie --pack-dyn-relocs=relr %t.o %t.so -o %t.exe
+// RUN: llvm-readobj -relocations %t.exe | FileCheck %s
+
+// CHECK:      Section (5) .relr.dyn {
+// CHECK-NEXT:   0x1000 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1004 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1008 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x100C R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1010 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1014 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1018 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x101C R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1020 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1024 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1028 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x102C R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1030 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1034 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1038 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x103C R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1040 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1044 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1048 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x104C R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1050 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1054 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1058 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x105C R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1060 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1064 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1068 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x106C R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1070 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1074 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1078 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x107C R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1080 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT:   0x1084 R_ARM_RELATIVE - 0x0
+// CHECK-NEXT: }
+
+// RUN: llvm-readobj -s -dynamic-table %t.exe | FileCheck --check-prefix=HEADER %s
+// HEADER: 0x00000023 RELRSZ 0xC
+
+.data
+.align 2
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start
+.dc.a __ehdr_start