Skip to content

Commit b2e9fcf

Browse files
committed
[AArch64] Force relocations for all ADRP instructions
This generalizes an existing fix from ELF to MachO and COFF. Test that an ADRP to a local symbol whose offset is known at assembly time still produces relocations, both for MachO and COFF. Test that an ADRP without a @page modifier on MachO fails (previously it didn't). Differential Revision: https://reviews.llvm.org/D35544 llvm-svn: 308518
1 parent 2ff5f5d commit b2e9fcf

File tree

4 files changed

+42
-26
lines changed

4 files changed

+42
-26
lines changed

llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ class AArch64AsmBackend : public MCAsmBackend {
8888
unsigned getPointerSize() const { return 8; }
8989

9090
unsigned getFixupKindContainereSizeInBytes(unsigned Kind) const;
91+
92+
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
93+
const MCValue &Target) override;
9194
};
9295

9396
} // end anonymous namespace
@@ -338,6 +341,26 @@ bool AArch64AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
338341
return true;
339342
}
340343

344+
bool AArch64AsmBackend::shouldForceRelocation(const MCAssembler &Asm,
345+
const MCFixup &Fixup,
346+
const MCValue &Target) {
347+
// The ADRP instruction adds some multiple of 0x1000 to the current PC &
348+
// ~0xfff. This means that the required offset to reach a symbol can vary by
349+
// up to one step depending on where the ADRP is in memory. For example:
350+
//
351+
// ADRP x0, there
352+
// there:
353+
//
354+
// If the ADRP occurs at address 0xffc then "there" will be at 0x1000 and
355+
// we'll need that as an offset. At any other address "there" will be in the
356+
// same page as the ADRP and the instruction should encode 0x0. Assuming the
357+
// section isn't 0x1000-aligned, we therefore need to delegate this decision
358+
// to the linker -- a relocation!
359+
if ((uint32_t)Fixup.getKind() == AArch64::fixup_aarch64_pcrel_adrp_imm21)
360+
return true;
361+
return false;
362+
}
363+
341364
namespace {
342365

343366
namespace CU {
@@ -544,31 +567,8 @@ class ELFAArch64AsmBackend : public AArch64AsmBackend {
544567
MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override {
545568
return createAArch64ELFObjectWriter(OS, OSABI, IsLittleEndian, IsILP32);
546569
}
547-
548-
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
549-
const MCValue &Target) override;
550570
};
551571

552-
bool ELFAArch64AsmBackend::shouldForceRelocation(const MCAssembler &Asm,
553-
const MCFixup &Fixup,
554-
const MCValue &Target) {
555-
// The ADRP instruction adds some multiple of 0x1000 to the current PC &
556-
// ~0xfff. This means that the required offset to reach a symbol can vary by
557-
// up to one step depending on where the ADRP is in memory. For example:
558-
//
559-
// ADRP x0, there
560-
// there:
561-
//
562-
// If the ADRP occurs at address 0xffc then "there" will be at 0x1000 and
563-
// we'll need that as an offset. At any other address "there" will be in the
564-
// same page as the ADRP and the instruction should encode 0x0. Assuming the
565-
// section isn't 0x1000-aligned, we therefore need to delegate this decision
566-
// to the linker -- a relocation!
567-
if ((uint32_t)Fixup.getKind() == AArch64::fixup_aarch64_pcrel_adrp_imm21)
568-
return true;
569-
return false;
570-
}
571-
572572
}
573573

574574
namespace {

llvm/test/MC/AArch64/coff-relocations.s

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,17 @@ add x0, x0, :lo12:foo
2626
; IMAGE_REL_ARM64_PAGEOFFSET_12L
2727
ldr x0, [x0, :lo12:foo]
2828

29+
; IMAGE_REL_ARM64_PAGEBASE_REL21, even if the symbol offset is known
30+
adrp x0, bar
31+
bar:
32+
2933
; IMAGE_REL_ARM64_SECREL
3034
.secrel32 .Linfo_bar
3135
.Linfo_bar:
3236

3337
; IMAGE_REL_ARM64_SECTION
3438
.secidx func
3539

36-
3740
; CHECK: Format: COFF-ARM64
3841
; CHECK: Arch: aarch64
3942
; CHECK: AddressSize: 64bit
@@ -46,7 +49,8 @@ ldr x0, [x0, :lo12:foo]
4649
; CHECK: 0x18 IMAGE_REL_ARM64_PAGEBASE_REL21 foo
4750
; CHECK: 0x1C IMAGE_REL_ARM64_PAGEOFFSET_12A foo
4851
; CHECK: 0x20 IMAGE_REL_ARM64_PAGEOFFSET_12L foo
49-
; CHECK: 0x24 IMAGE_REL_ARM64_SECREL .text
50-
; CHECK: 0x28 IMAGE_REL_ARM64_SECTION func
52+
; CHECK: 0x24 IMAGE_REL_ARM64_PAGEBASE_REL21 bar
53+
; CHECK: 0x28 IMAGE_REL_ARM64_SECREL .text
54+
; CHECK: 0x2C IMAGE_REL_ARM64_SECTION func
5155
; CHECK: }
5256
; CHECK: ]
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
; RUN: not llvm-mc < %s -triple arm64-apple-darwin -filetype=obj -o - 2>&1 | FileCheck %s
2+
3+
; CHECK: error: ADR/ADRP relocations must be GOT relative
4+
adrp x3, Lbar
5+
Lbar:
6+
ret
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
; RUN: llvm-mc < %s -triple arm64-apple-darwin -filetype=obj -o - | llvm-readobj -r - | FileCheck %s
2+
3+
adrp x3, Lbar@page
4+
; CHECK: ARM64_RELOC_PAGE21
5+
Lbar:
6+
ret

0 commit comments

Comments
 (0)