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 @@ -45,6 +45,15 @@ unsigned AArch64WinCOFFObjectWriter::getRelocType( MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsCrossSection, const MCAsmBackend &MAB) const { + unsigned FixupKind = Fixup.getKind(); + if (IsCrossSection) { + if (FixupKind != FK_Data_4) { + Ctx.reportError(Fixup.getLoc(), "Cannot represent this expression"); + return COFF::IMAGE_REL_ARM64_ADDR32; + } + FixupKind = FK_PCRel_4; + } + auto Modifier = Target.isAbsolute() ? MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); const MCExpr *Expr = Fixup.getValue(); @@ -64,7 +73,7 @@ } } - switch (static_cast(Fixup.getKind())) { + switch (FixupKind) { default: { if (const AArch64MCExpr *A64E = dyn_cast(Expr)) { Ctx.reportError(Fixup.getLoc(), "relocation type " + @@ -78,6 +87,9 @@ return COFF::IMAGE_REL_ARM64_ABSOLUTE; // Dummy return value } + case FK_PCRel_4: + return COFF::IMAGE_REL_ARM64_REL32; + case FK_Data_4: switch (Modifier) { default: diff --git a/llvm/test/MC/AArch64/coff-relocations-diags.s b/llvm/test/MC/AArch64/coff-relocations-diags.s --- a/llvm/test/MC/AArch64/coff-relocations-diags.s +++ b/llvm/test/MC/AArch64/coff-relocations-diags.s @@ -37,7 +37,15 @@ // CHECK-NEXT: add x0, x0, :dtprel_lo12:symbol // CHECK-NEXT: ^ +label: movz x0, #:abs_g0:symbol // CHECK: error: relocation type :abs_g0: unsupported on COFF targets // CHECK-NEXT: movz x0, #:abs_g0:symbol // CHECK-NEXT: ^ + + .section .rdata, "dr" +table: + .short label - table + // CHECK: error: Cannot represent this expression + // CHECK-NEXT: .short label - table + // CHECK-NEXT: ^ diff --git a/llvm/test/MC/AArch64/coff-relocations.s b/llvm/test/MC/AArch64/coff-relocations.s --- a/llvm/test/MC/AArch64/coff-relocations.s +++ b/llvm/test/MC/AArch64/coff-relocations.s @@ -1,6 +1,7 @@ // RUN: llvm-mc -triple aarch64-windows -filetype obj -o %t.obj %s // RUN: llvm-readobj -r %t.obj | FileCheck %s // RUN: llvm-objdump -d %t.obj | FileCheck %s --check-prefix=DISASM +// RUN: llvm-objdump -s %t.obj | FileCheck %s --check-prefix=DATA // IMAGE_REL_ARM64_ADDR32 .Linfo_foo: @@ -61,6 +62,11 @@ // IMAGE_REL_ARM64_BRANCH14 tbz x0, #0, target +.section .rdata, "dr" +.Ltable: +.word .Linfo_bar - .Ltable +.word .Linfo_foo - .Ltable + // CHECK: Format: COFF-ARM64 // CHECK: Arch: aarch64 // CHECK: AddressSize: 64bit @@ -87,6 +93,10 @@ // CHECK: 0x50 IMAGE_REL_ARM64_BRANCH19 target // CHECK: 0x54 IMAGE_REL_ARM64_BRANCH14 target // CHECK: } +// CHECK: Section (4) .rdata { +// CHECK: 0x0 IMAGE_REL_ARM64_REL32 .text +// CHECK: 0x4 IMAGE_REL_ARM64_REL32 .text +// CHECK: } // CHECK: ] // DISASM: 30: 20 1a 09 b0 adrp x0, 0x12345000 @@ -97,3 +107,6 @@ // DISASM: 44: 00 00 40 91 add x0, x0, #0, lsl #12 // DISASM: 48: 00 00 40 f9 ldr x0, [x0] // DISASM: 4c: 20 1a 09 30 adr x0, #74565 + +// DATA: Contents of section .rdata: +// DATA-NEXT: 0000 2c000000 04000000