mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-10 13:51:37 +00:00
[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
This commit is contained in:
parent
907c7d040f
commit
992aad1a5d
@ -88,6 +88,9 @@ public:
|
||||
unsigned getPointerSize() const { return 8; }
|
||||
|
||||
unsigned getFixupKindContainereSizeInBytes(unsigned Kind) const;
|
||||
|
||||
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target) override;
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
@ -338,6 +341,26 @@ bool AArch64AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AArch64AsmBackend::shouldForceRelocation(const MCAssembler &Asm,
|
||||
const MCFixup &Fixup,
|
||||
const MCValue &Target) {
|
||||
// The ADRP instruction adds some multiple of 0x1000 to the current PC &
|
||||
// ~0xfff. This means that the required offset to reach a symbol can vary by
|
||||
// up to one step depending on where the ADRP is in memory. For example:
|
||||
//
|
||||
// ADRP x0, there
|
||||
// there:
|
||||
//
|
||||
// If the ADRP occurs at address 0xffc then "there" will be at 0x1000 and
|
||||
// we'll need that as an offset. At any other address "there" will be in the
|
||||
// same page as the ADRP and the instruction should encode 0x0. Assuming the
|
||||
// section isn't 0x1000-aligned, we therefore need to delegate this decision
|
||||
// to the linker -- a relocation!
|
||||
if ((uint32_t)Fixup.getKind() == AArch64::fixup_aarch64_pcrel_adrp_imm21)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
namespace CU {
|
||||
@ -544,31 +567,8 @@ public:
|
||||
MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override {
|
||||
return createAArch64ELFObjectWriter(OS, OSABI, IsLittleEndian, IsILP32);
|
||||
}
|
||||
|
||||
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target) override;
|
||||
};
|
||||
|
||||
bool ELFAArch64AsmBackend::shouldForceRelocation(const MCAssembler &Asm,
|
||||
const MCFixup &Fixup,
|
||||
const MCValue &Target) {
|
||||
// The ADRP instruction adds some multiple of 0x1000 to the current PC &
|
||||
// ~0xfff. This means that the required offset to reach a symbol can vary by
|
||||
// up to one step depending on where the ADRP is in memory. For example:
|
||||
//
|
||||
// ADRP x0, there
|
||||
// there:
|
||||
//
|
||||
// If the ADRP occurs at address 0xffc then "there" will be at 0x1000 and
|
||||
// we'll need that as an offset. At any other address "there" will be in the
|
||||
// same page as the ADRP and the instruction should encode 0x0. Assuming the
|
||||
// section isn't 0x1000-aligned, we therefore need to delegate this decision
|
||||
// to the linker -- a relocation!
|
||||
if ((uint32_t)Fixup.getKind() == AArch64::fixup_aarch64_pcrel_adrp_imm21)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -26,6 +26,10 @@ add x0, x0, :lo12:foo
|
||||
; IMAGE_REL_ARM64_PAGEOFFSET_12L
|
||||
ldr x0, [x0, :lo12:foo]
|
||||
|
||||
; IMAGE_REL_ARM64_PAGEBASE_REL21, even if the symbol offset is known
|
||||
adrp x0, bar
|
||||
bar:
|
||||
|
||||
; IMAGE_REL_ARM64_SECREL
|
||||
.secrel32 .Linfo_bar
|
||||
.Linfo_bar:
|
||||
@ -33,7 +37,6 @@ ldr x0, [x0, :lo12:foo]
|
||||
; IMAGE_REL_ARM64_SECTION
|
||||
.secidx func
|
||||
|
||||
|
||||
; CHECK: Format: COFF-ARM64
|
||||
; CHECK: Arch: aarch64
|
||||
; CHECK: AddressSize: 64bit
|
||||
@ -46,7 +49,8 @@ ldr x0, [x0, :lo12:foo]
|
||||
; CHECK: 0x18 IMAGE_REL_ARM64_PAGEBASE_REL21 foo
|
||||
; CHECK: 0x1C IMAGE_REL_ARM64_PAGEOFFSET_12A foo
|
||||
; CHECK: 0x20 IMAGE_REL_ARM64_PAGEOFFSET_12L foo
|
||||
; CHECK: 0x24 IMAGE_REL_ARM64_SECREL .text
|
||||
; CHECK: 0x28 IMAGE_REL_ARM64_SECTION func
|
||||
; CHECK: 0x24 IMAGE_REL_ARM64_PAGEBASE_REL21 bar
|
||||
; CHECK: 0x28 IMAGE_REL_ARM64_SECREL .text
|
||||
; CHECK: 0x2C IMAGE_REL_ARM64_SECTION func
|
||||
; CHECK: }
|
||||
; CHECK: ]
|
||||
|
6
test/MC/AArch64/macho-adrp-missing-reloc.s
Normal file
6
test/MC/AArch64/macho-adrp-missing-reloc.s
Normal file
@ -0,0 +1,6 @@
|
||||
; RUN: not llvm-mc < %s -triple arm64-apple-darwin -filetype=obj -o - 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK: error: ADR/ADRP relocations must be GOT relative
|
||||
adrp x3, Lbar
|
||||
Lbar:
|
||||
ret
|
6
test/MC/AArch64/macho-adrp-page.s
Normal file
6
test/MC/AArch64/macho-adrp-page.s
Normal file
@ -0,0 +1,6 @@
|
||||
; RUN: llvm-mc < %s -triple arm64-apple-darwin -filetype=obj -o - | llvm-readobj -r - | FileCheck %s
|
||||
|
||||
adrp x3, Lbar@page
|
||||
; CHECK: ARM64_RELOC_PAGE21
|
||||
Lbar:
|
||||
ret
|
Loading…
Reference in New Issue
Block a user