diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp --- a/llvm/lib/MC/WinCOFFObjectWriter.cpp +++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp @@ -847,7 +847,9 @@ if (Mode != DwoOnly) for (const MCSymbol &Symbol : Asm.symbols()) - if (!Symbol.isTemporary()) + // Define non-temporary or temporary static (private-linkage) symbols + if (!Symbol.isTemporary() || + cast(Symbol).getClass() == COFF::IMAGE_SYM_CLASS_STATIC) DefineSymbol(Symbol, Asm, Layout); } @@ -909,7 +911,7 @@ Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment); // Turn relocations for temporary symbols into section relocations. - if (A.isTemporary()) { + if (A.isTemporary() && !SymbolMap[&A]) { MCSection *TargetSection = &A.getSection(); assert( SectionMap.contains(TargetSection) && diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp @@ -314,6 +314,13 @@ return (Value >> 2) & 0x3fff; case AArch64::fixup_aarch64_pcrel_branch26: case AArch64::fixup_aarch64_pcrel_call26: + if (TheTriple.isOSBinFormatCOFF() && !IsResolved && SignedValue != 0) { + // MSVC link.exe and lld do not support this relocation type + // with a non-zero offset + Ctx.reportError(Fixup.getLoc(), + "cannot perform a PC-relative fixup with a non-zero " + "symbol offset"); + } // Signed 28-bit immediate if (!isInt<28>(SignedValue)) Ctx.reportError(Fixup.getLoc(), "fixup value out of range"); diff --git a/llvm/test/MC/AArch64/coff-relocations-branch26.s b/llvm/test/MC/AArch64/coff-relocations-branch26.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/coff-relocations-branch26.s @@ -0,0 +1,75 @@ +// RUN: llvm-mc -triple aarch64-unknown-windows-msvc -filetype obj %s -o - | llvm-objdump -D -r - | FileCheck %s +// RUN: not llvm-mc -triple aarch64-unknown-windows-msvc -filetype obj --defsym ERR=1 %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR + + .text +main: + nop + b .Ltarget + b .Lother_target + +// A privte label target in the same section + .def .Ltarget + .scl 3 + .type 32 + .endef + .p2align 2 +.Ltarget: + ret + +// A privte label target in another section + .section "other" + nop + nop + nop + nop + nop + nop + nop + nop + .def .Lother_target + .scl 3 + .type 32 + .endef + .p2align 2 +.Lother_target: + ret + +// Check that both branches have a relocation with a zero offset. +// +// CHECK: 0000000000000000
: +// CHECK: 0: d503201f nop +// CHECK: 4: 14000000 b 0x4 +// CHECK: 0000000000000004: IMAGE_REL_ARM64_BRANCH26 .Ltarget +// CHECK: 8: 14000000 b 0x8 +// CHECK: 0000000000000008: IMAGE_REL_ARM64_BRANCH26 .Lother_target +// CHECK: 000000000000000c <.Ltarget>: +// CHECK: c: d65f03c0 ret +// CHECK: 0000000000000000 : +// CHECK: 0: d503201f nop +// CHECK: 4: d503201f nop +// CHECK: 8: d503201f nop +// CHECK: c: d503201f nop +// CHECK: 10: d503201f nop +// CHECK: 14: d503201f nop +// CHECK: 18: d503201f nop +// CHECK: 1c: d503201f nop +// CHECK: 0000000000000020 <.Lother_target>: +// CHECK: 20: d65f03c0 ret + +.ifdef ERR + .section "err" +err: + nop + b .Lerr_target+4 +// ERR: [[#@LINE-1]]:5: error: cannot perform a PC-relative fixup with a non-zero symbol offset + + .def .Lerr_target + .scl 3 + .type 32 + .p2align 2 + .endef +.Lerr_target: + nop + nop + ret +.endif