From c964afb2c8b540a8579c18d3a05379ceee704844 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Tue, 2 Nov 2021 13:32:31 -0700 Subject: [PATCH] [AArch64] Diagnose large adrp offset on Windows. On Windows, this relocation can only encode a 21-bit offset. Make sure we emit an error, instead of silently truncating the offset. Found investigating https://bugs.llvm.org/show_bug.cgi?id=52378 Differential Revision: https://reviews.llvm.org/D113051 --- llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp | 5 ++++- llvm/test/MC/AArch64/fixup-out-of-range.s | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp index 70a0e9da6af3..dbb8e85713cb 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp @@ -160,8 +160,11 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target, return AdrImmBits(Value & 0x1fffffULL); case AArch64::fixup_aarch64_pcrel_adrp_imm21: assert(!IsResolved); - if (TheTriple.isOSBinFormatCOFF()) + if (TheTriple.isOSBinFormatCOFF()) { + if (!isInt<21>(SignedValue)) + Ctx.reportError(Fixup.getLoc(), "fixup value out of range"); return AdrImmBits(Value & 0x1fffffULL); + } return AdrImmBits((Value & 0x1fffff000ULL) >> 12); case AArch64::fixup_aarch64_ldr_pcrel_imm19: case AArch64::fixup_aarch64_pcrel_branch19: diff --git a/llvm/test/MC/AArch64/fixup-out-of-range.s b/llvm/test/MC/AArch64/fixup-out-of-range.s index 500c1d1d1f9a..05d07b654fa8 100644 --- a/llvm/test/MC/AArch64/fixup-out-of-range.s +++ b/llvm/test/MC/AArch64/fixup-out-of-range.s @@ -1,5 +1,5 @@ // RUN: not llvm-mc -triple aarch64--none-eabi -filetype obj < %s -o /dev/null 2>&1 | FileCheck %s -// RUN: not llvm-mc -triple aarch64-windows -filetype obj < %s -o /dev/null 2>&1 | FileCheck %s +// RUN: not llvm-mc -triple aarch64-windows -filetype obj < %s -o /dev/null 2>&1 | FileCheck %s -check-prefixes=CHECK,CHECK-WIN // CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: fixup value out of range adr x0, distant @@ -70,6 +70,8 @@ // CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: relocation for a thread-local variable points to an absolute symbol movz x0, #:tprel_g0:value1 +// CHECK-WIN: :[[@LINE+1]]:{{[0-9]+}}: error: fixup value out of range + adrp x0, external+0x1000000 .byte 0 unaligned: