From 6b57892624f1ff7dcdb6e5291bedfe7929c6d96f Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Mon, 18 May 2015 22:07:20 +0000 Subject: [PATCH] AArch64: work around ld64 bug more aggressively. 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 --- .../MCTargetDesc/AArch64MachObjectWriter.cpp | 9 ++- test/MC/MachO/AArch64/cfstring.s | 24 ------- test/MC/MachO/AArch64/ld64-workaround.s | 68 +++++++++++++++++++ test/MC/MachO/AArch64/mergeable.s | 6 +- 4 files changed, 76 insertions(+), 31 deletions(-) delete mode 100644 test/MC/MachO/AArch64/cfstring.s create mode 100644 test/MC/MachO/AArch64/ld64-workaround.s diff --git a/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp b/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp index 25343244890..99f30bcac7e 100644 --- a/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp +++ b/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp @@ -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 index 19b50678877..00000000000 --- a/test/MC/MachO/AArch64/cfstring.s +++ /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 index 00000000000..a33cacc075b --- /dev/null +++ b/test/MC/MachO/AArch64/ld64-workaround.s @@ -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 diff --git a/test/MC/MachO/AArch64/mergeable.s b/test/MC/MachO/AArch64/mergeable.s index fc6ec04f37b..fcd83952756 100644 --- a/test/MC/MachO/AArch64/mergeable.s +++ b/test/MC/MachO/AArch64/mergeable.s @@ -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: }