From: Peter Smith Date: Sun, 23 Feb 2020 10:49:51 +0000 (+0000) Subject: [MC][ELF][ARM] Add relocations for some pc-relative fixups X-Git-Tag: 2020.06-alpha~123^2~608 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2a92fc9b8e6a079acd53ec3675cfd9bb153ab1ea;p=platform%2Fupstream%2Fllvm.git [MC][ELF][ARM] Add relocations for some pc-relative fixups Add ELF relocations for the following fixups: fixup_thumb_adr_pcrel_10 -> R_ARM_THM_PC8 fixup_thumb_cp -> R_ARM_THM_PC8 fixup_t2_adr_pcrel_12 -> R_ARM_THM_PREL_11_0 fixup_t2_ldst_pcrel_12 -> R_ARM_THM_PC12 While these relocations are short-ranged there is support in the open source ELF linker's in binutils and soon to be in LLD. MC will no longer resolve pc-relative fixups to global symbols due to interpositioning concerns. We can handle these at link time by implementing the relocations. The R_ARM_THM_PC8 has some extra encoding rules for addends that llvm-mc sidesteps by not supporting addends for these instructions, using the wide Thumb 2 instruction if it is available. I think that this is a reasonable compromise given that these are rare. This partiall reverts D72892, the Thumb fixups no longer need to be evaluated at assembly time. Differential Revision: https://reviews.llvm.org/D75039 --- diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index 66ac2760a369..d118b4f9431a 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -64,7 +64,8 @@ const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { // Name Offset (bits) Size (bits) Flags {"fixup_arm_ldst_pcrel_12", 0, 32, IsPCRelConstant}, {"fixup_t2_ldst_pcrel_12", 0, 32, - IsPCRelConstant | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, + MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, {"fixup_arm_pcrel_10_unscaled", 0, 32, IsPCRelConstant}, {"fixup_arm_pcrel_10", 0, 32, IsPCRelConstant}, {"fixup_t2_pcrel_10", 0, 32, @@ -74,10 +75,12 @@ const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { {"fixup_t2_pcrel_9", 0, 32, IsPCRelConstant | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, {"fixup_thumb_adr_pcrel_10", 0, 8, - IsPCRelConstant | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, + MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, {"fixup_arm_adr_pcrel_12", 0, 32, IsPCRelConstant}, {"fixup_t2_adr_pcrel_12", 0, 32, - IsPCRelConstant | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, + MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, {"fixup_arm_condbranch", 0, 24, MCFixupKindInfo::FKF_IsPCRel}, {"fixup_arm_uncondbranch", 0, 24, MCFixupKindInfo::FKF_IsPCRel}, {"fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, @@ -109,8 +112,7 @@ const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { {"fixup_bfc_target", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, {"fixup_bfcsel_else_target", 0, 32, 0}, {"fixup_wls", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, - {"fixup_le", 0, 32, MCFixupKindInfo::FKF_IsPCRel} - }; + {"fixup_le", 0, 32, MCFixupKindInfo::FKF_IsPCRel}}; const static MCFixupKindInfo InfosBE[ARM::NumTargetFixupKinds] = { // This table *must* be in the order that the fixup_* kinds are defined in // ARMFixupKinds.h. diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp index 2c26dd388c05..1e2399c4be99 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp @@ -137,6 +137,13 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, default: return ELF::R_ARM_THM_CALL; } + case ARM::fixup_thumb_adr_pcrel_10: + case ARM::fixup_arm_thumb_cp: + return ELF::R_ARM_THM_PC8; + case ARM::fixup_t2_adr_pcrel_12: + return ELF::R_ARM_THM_ALU_PREL_11_0; + case ARM::fixup_t2_ldst_pcrel_12: + return ELF::R_ARM_THM_PC12; case ARM::fixup_bf_target: return ELF::R_ARM_THM_BF16; case ARM::fixup_bfc_target: diff --git a/llvm/test/MC/ARM/pcrel-global-rel.s b/llvm/test/MC/ARM/pcrel-global-rel.s new file mode 100644 index 000000000000..f1a71e6db773 --- /dev/null +++ b/llvm/test/MC/ARM/pcrel-global-rel.s @@ -0,0 +1,18 @@ +@ RUN: llvm-mc -filetype=obj -triple=armv7 %s -o %t +@ RUN: llvm-readobj -r %t + +@ Check that for ELF targets we generate a relocation for a within section +@ pc-relative reference to a global symbol as it may be interposed and we won't +@ know till link time whether this is possible. +.thumb +.thumb_func + +.globl bar +bar: +adr r0, bar @ thumb_adr_pcrel_10 +adr.w r0, bar @ t2_adr_pcrel_12 +ldr.w pc, bar @ t2_ldst_pcrel_12 + +@ CHECK: 0x0 R_ARM_THM_ALU_PREL_11_0 bar 0x0 +@ CHECK-NEXT: 0x4 R_ARM_THM_ALU_PREL_11_0 bar 0x0 +@ CHECK-NEXT: 0x8 R_ARM_THM_PC12 bar 0x0 diff --git a/llvm/test/MC/ARM/pcrel-global.s b/llvm/test/MC/ARM/pcrel-global.s index cec6c1cb52f3..c1ab43547532 100644 --- a/llvm/test/MC/ARM/pcrel-global.s +++ b/llvm/test/MC/ARM/pcrel-global.s @@ -11,11 +11,3 @@ vldr d0, foo @ arm_pcrel_10 adr r2, foo @ arm_adr_pcrel_12 ldr r0, foo @ arm_ldst_pcrel_12 -.thumb -.thumb_func - -.globl bar -bar: -adr r0, bar @ thumb_adr_pcrel_10 -adr.w r0, bar @ t2_adr_pcrel_12 -ldr.w pc, bar @ t2_ldst_pcrel_12 diff --git a/llvm/test/MC/ARM/thumb1-relax-adr.s b/llvm/test/MC/ARM/thumb1-relax-adr.s index 80b93ec8eae1..213c96822536 100644 --- a/llvm/test/MC/ARM/thumb1-relax-adr.s +++ b/llvm/test/MC/ARM/thumb1-relax-adr.s @@ -1,9 +1,11 @@ @ RUN: not llvm-mc -triple thumbv6m-none-macho -filetype=obj -o /dev/null %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s @ RUN: not llvm-mc -triple thumbv7m-none-macho -filetype=obj -o /dev/null %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s -@ RUN: not llvm-mc -triple thumbv7m-none-eabi -filetype=obj -o /dev/null %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s +@ RUN: llvm-mc -triple thumbv6m-none-eabi -filetype=obj %s -o - | llvm-readobj --relocs | FileCheck --check-prefix=CHECK-ELF-T1 %s +@ RUN: llvm-mc -triple thumbv7m-none-eabi -filetype=obj %s -o - | llvm-readobj --relocs | FileCheck --check-prefix=CHECK-ELF-T2 %s .global func1 _func1: adr r0, _func2 @ CHECK-ERROR: unsupported relocation on symbol - +@ CHECK-ELF-T1: 0x0 R_ARM_THM_PC8 _func2 0x0 +@ CHECK-ELF-T2: 0x0 R_ARM_THM_ALU_PREL_11_0 _func2 0x0 diff --git a/llvm/test/MC/ARM/thumb1-relax-ldrlit.s b/llvm/test/MC/ARM/thumb1-relax-ldrlit.s index 96c5aa036f28..e65ee52de7cb 100644 --- a/llvm/test/MC/ARM/thumb1-relax-ldrlit.s +++ b/llvm/test/MC/ARM/thumb1-relax-ldrlit.s @@ -1,9 +1,11 @@ @ RUN: not llvm-mc -triple thumbv6m-none-macho -filetype=obj -o /dev/null %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s @ RUN: not llvm-mc -triple thumbv7m-none-macho -filetype=obj -o /dev/null %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s -@ RUN: not llvm-mc -triple thumbv7m-none-eabi -filetype=obj -o /dev/null %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s +@ RUN: llvm-mc -triple thumbv6m-none-eabi -filetype=obj %s -o - | llvm-readobj --relocs | FileCheck --check-prefix=CHECK-ELF-T1 %s +@ RUN: llvm-mc -triple thumbv7m-none-eabi -filetype=obj %s -o - | llvm-readobj --relocs | FileCheck --check-prefix=CHECK-ELF-T2 %s .global func1 _func1: ldr r0, _func2 @ CHECK-ERROR: unsupported relocation on symbol - +@ CHECK-ELF-T1: 0x0 R_ARM_THM_PC8 _func2 0x0 +@ CHECK-ELF-T2: 0x0 R_ARM_THM_PC12 _func2 0x0