diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp @@ -11,6 +11,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/BinaryFormat/COFF.h" #include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCFixup.h" #include "llvm/MC/MCFixupKindInfo.h" @@ -48,10 +49,33 @@ : Target.getSymA()->getKind(); const MCExpr *Expr = Fixup.getValue(); + if (const AArch64MCExpr *A64E = dyn_cast(Expr)) { + AArch64MCExpr::VariantKind RefKind = A64E->getKind(); + switch (AArch64MCExpr::getSymbolLoc(RefKind)) { + case AArch64MCExpr::VK_ABS: + case AArch64MCExpr::VK_SECREL: + // Supported + break; + default: + Ctx.reportError(Fixup.getLoc(), "relocation variant " + + A64E->getVariantKindName() + + " unsupported on COFF targets"); + return COFF::IMAGE_REL_ARM64_ABSOLUTE; // Dummy return value + } + } + switch (static_cast(Fixup.getKind())) { default: { - const MCFixupKindInfo &Info = MAB.getFixupKindInfo(Fixup.getKind()); - report_fatal_error(Twine("unsupported relocation type: ") + Info.Name); + if (const AArch64MCExpr *A64E = dyn_cast(Expr)) { + Ctx.reportError(Fixup.getLoc(), "relocation type " + + A64E->getVariantKindName() + + " unsupported on COFF targets"); + } else { + const MCFixupKindInfo &Info = MAB.getFixupKindInfo(Fixup.getKind()); + Ctx.reportError(Fixup.getLoc(), Twine("relocation type ") + Info.Name + + " unsupported on COFF targets"); + } + return COFF::IMAGE_REL_ARM64_ABSOLUTE; // Dummy return value } case FK_Data_4: diff --git a/llvm/test/MC/AArch64/coff-relocations-diags.s b/llvm/test/MC/AArch64/coff-relocations-diags.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/coff-relocations-diags.s @@ -0,0 +1,43 @@ +// RUN: not llvm-mc -triple aarch64-win32 -filetype=obj %s -o /dev/null 2>&1 | FileCheck %s + + adrp x0, :got:symbol + // CHECK: error: relocation variant :got: unsupported on COFF targets + // CHECK-NEXT: adrp x0, :got:symbol + // CHECK-NEXT: ^ + + ldr x0, [x0, :got_lo12:symbol] + // CHECK: error: relocation variant :got_lo12: unsupported on COFF targets + // CHECK-NEXT: ldr x0, [x0, :got_lo12:symbol] + // CHECK-NEXT: ^ + + adrp x0, :tlsdesc:symbol + // CHECK: error: relocation variant :tlsdesc: unsupported on COFF targets + // CHECK-NEXT: adrp x0, :tlsdesc:symbol + // CHECK-NEXT: ^ + add x0, x0, :tlsdesc_lo12:symbol + // CHECK: error: relocation variant :tlsdesc_lo12: unsupported on COFF targets + // CHECK-NEXT: add x0, x0, :tlsdesc_lo12:symbol + // CHECK-NEXT: ^ + + adrp x0, :gottprel:symbol + // CHECK: error: relocation variant :gottprel: unsupported on COFF targets + // CHECK-NEXT: adrp x0, :gottprel:symbol + // CHECK-NEXT: ^ + ldr x0, [x0, :gottprel_lo12:symbol] + // CHECK: error: relocation variant :gottprel_lo12: unsupported on COFF targets + // CHECK-NEXT: ldr x0, [x0, :gottprel_lo12:symbol] + // CHECK-NEXT: ^ + + add x0, x0, #:dtprel_hi12:symbol, lsl #12 + // CHECK: error: relocation variant :dtprel_hi12: unsupported on COFF targets + // CHECK-NEXT: add x0, x0, #:dtprel_hi12:symbol, lsl #12 + // CHECK-NEXT: ^ + add x0, x0, :dtprel_lo12:symbol + // CHECK: error: relocation variant :dtprel_lo12: unsupported on COFF targets + // CHECK-NEXT: add x0, x0, :dtprel_lo12:symbol + // CHECK-NEXT: ^ + + movz x0, #:abs_g0:symbol + // CHECK: error: relocation type :abs_g0: unsupported on COFF targets + // CHECK-NEXT: movz x0, #:abs_g0:symbol + // CHECK-NEXT: ^