AArch64: work around ld64 bug more aggressively.
authorTim Northover <tnorthover@apple.com>
Mon, 18 May 2015 22:07:20 +0000 (22:07 +0000)
committerTim Northover <tnorthover@apple.com>
Mon, 18 May 2015 22:07:20 +0000 (22:07 +0000)
ld64 currently mishandles internal pointer relocations (i.e.
ARM64_RELOC_UNSIGNED referred to by section & offset rather than symbol). The
existing __cfstring clause was an early discovery and workaround for this, but
the problem is wider and we should avoid such relocations wherever possible for
now.

This code should be reverted to allowing internal relocations as soon as
possible.

PR23437.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237621 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp
test/MC/MachO/AArch64/cfstring.s [deleted file]
test/MC/MachO/AArch64/ld64-workaround.s [new file with mode: 0644]
test/MC/MachO/AArch64/mergeable.s

index 253432448902fdb894ac5c04339b86db1c52443b..99f30bcac7e2da5542a98cff5cfa9d4d836b5470 100644 (file)
@@ -130,15 +130,14 @@ static bool canUseLocalRelocation(const MCSectionMachO &Section,
   if (RefSec.getType() == MachO::S_CSTRING_LITERALS)
     return false;
 
-  if (RefSec.getSegmentName() == "__DATA" &&
-      RefSec.getSectionName() == "__cfstring")
-    return false;
-
   if (RefSec.getSegmentName() == "__DATA" &&
       RefSec.getSectionName() == "__objc_classrefs")
     return false;
 
-  return true;
+  // FIXME: ld64 currently handles internal pointer-sized relocations
+  // incorrectly (applying the addend twice). We should be able to return true
+  // unconditionally by this point when that's fixed.
+  return false;
 }
 
 void AArch64MachObjectWriter::RecordRelocation(
diff --git a/test/MC/MachO/AArch64/cfstring.s b/test/MC/MachO/AArch64/cfstring.s
deleted file mode 100644 (file)
index 19b5067..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-; RUN: llvm-mc -triple arm64-apple-darwin10 %s -filetype=obj -o - | llvm-readobj -r --expand-relocs | FileCheck %s
-
-; Test that we produce an external relocation. There is no apparent need for it, but
-; ld64 (241.9) produces a corrupt output if we don't.
-
-// CHECK:      Relocations [
-// CHECK-NEXT:   Section __data {
-// CHECK-NEXT:     Relocation {
-// CHECK-NEXT:       Offset: 0x0
-// CHECK-NEXT:       PCRel: 0
-// CHECK-NEXT:       Length: 3
-// CHECK-NEXT:       Extern: 1
-// CHECK-NEXT:       Type: ARM64_RELOC_UNSIGNED (0)
-// CHECK-NEXT:       Symbol: Lfoo
-// CHECK-NEXT:       Scattered: 0
-// CHECK-NEXT:     }
-// CHECK-NEXT:   }
-// CHECK-NEXT: ]
-
-        .section        __DATA,__cfstring
-Lfoo:
-
-        .section        __DATA,__data
-        .quad   Lfoo
diff --git a/test/MC/MachO/AArch64/ld64-workaround.s b/test/MC/MachO/AArch64/ld64-workaround.s
new file mode 100644 (file)
index 0000000..a33cacc
--- /dev/null
@@ -0,0 +1,68 @@
+; RUN: llvm-mc -triple arm64-apple-darwin10 %s -filetype=obj -o - | llvm-readobj -r --expand-relocs | FileCheck %s
+
+; Test that we produce an external relocation. This is a known and temporary bug
+; in ld64, where it mishandles pointer-sized internal relocations. We should be
+; able to remove this entirely soon.
+
+// CHECK:      Relocations [
+// CHECK-NEXT:   Section __data {
+// CHECK-NEXT:     Relocation {
+// CHECK-NEXT:       Offset: 0x18
+// CHECK-NEXT:       PCRel: 0
+// CHECK-NEXT:       Length: 3
+// CHECK-NEXT:       Extern: 1
+// CHECK-NEXT:       Type: ARM64_RELOC_UNSIGNED (0)
+// CHECK-NEXT:       Symbol: Llit16
+// CHECK-NEXT:       Scattered: 0
+// CHECK-NEXT:     }
+// CHECK-NEXT:     Relocation {
+// CHECK-NEXT:       Offset: 0x10
+// CHECK-NEXT:       PCRel: 0
+// CHECK-NEXT:       Length: 3
+// CHECK-NEXT:       Extern: 1
+// CHECK-NEXT:       Type: ARM64_RELOC_UNSIGNED (0)
+// CHECK-NEXT:       Symbol: Llit8
+// CHECK-NEXT:       Scattered: 0
+// CHECK-NEXT:     }
+// CHECK-NEXT:     Relocation {
+// CHECK-NEXT:       Offset: 0x8
+// CHECK-NEXT:       PCRel: 0
+// CHECK-NEXT:       Length: 3
+// CHECK-NEXT:       Extern: 1
+// CHECK-NEXT:       Type: ARM64_RELOC_UNSIGNED (0)
+// CHECK-NEXT:       Symbol: Llit4
+// CHECK-NEXT:       Scattered: 0
+// CHECK-NEXT:     }
+// CHECK-NEXT:     Relocation {
+// CHECK-NEXT:       Offset: 0x0
+// CHECK-NEXT:       PCRel: 0
+// CHECK-NEXT:       Length: 3
+// CHECK-NEXT:       Extern: 1
+// CHECK-NEXT:       Type: ARM64_RELOC_UNSIGNED (0)
+// CHECK-NEXT:       Symbol: Lcfstring
+// CHECK-NEXT:       Scattered: 0
+// CHECK-NEXT:     }
+// CHECK-NEXT:   }
+// CHECK-NEXT: ]
+
+        .section        __DATA,__cfstring
+Lcfstring:
+
+        .section        __DATA,__literal4,4byte_literals
+Llit4:
+        .word 42
+
+        .section        __DATA,__literal8,8byte_literals
+Llit8:
+        .quad 42
+
+        .section        __DATA,__literal16,16byte_literals
+Llit16:
+        .quad 42
+        .quad 42
+
+        .section        __DATA,__data
+        .quad   Lcfstring
+        .quad   Llit4
+        .quad   Llit8
+        .quad   Llit16
index fc6ec04f37bf044d163ddaf3e6dfec489425a2f1..fcd8395275680dfc4b929ad3b61fe4f612d5660f 100644 (file)
@@ -1,4 +1,6 @@
 // RUN: llvm-mc -triple aarch64-apple-darwin14 %s -filetype=obj -o - | llvm-readobj -r --expand-relocs | FileCheck %s
+// FIXME: the final relocation should be internal, but the linker doesn't
+// currently handle the it correctly.
 
 // Test that we "S + K" produce a relocation with a symbol, but just S produces
 // a relocation with the section.
@@ -50,9 +52,9 @@ L1:
 // CHECK-NEXT:       Offset: 0x0
 // CHECK-NEXT:       PCRel: 0
 // CHECK-NEXT:       Length: 3
-// CHECK-NEXT:       Extern: 0
+// CHECK-NEXT:       Extern: 1
 // CHECK-NEXT:       Type: ARM64_RELOC_UNSIGNED (0)
-// CHECK-NEXT:       Symbol: 0x2
+// CHECK-NEXT:       Symbol: L0
 // CHECK-NEXT:       Scattered: 0
 // CHECK-NEXT:     }
 // CHECK-NEXT:   }