[llvm] 1e7f592 - [MC][COFF][AArch64] Avoid incorrect IMAGE_REL_ARM64_BRANCH26 relocations.
Hiroshi Yamauchi via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 17 14:40:10 PDT 2023
Author: Hiroshi Yamauchi
Date: 2023-08-17T14:31:31-07:00
New Revision: 1e7f592a890aad860605cf5220530b3744e107ba
URL: https://github.com/llvm/llvm-project/commit/1e7f592a890aad860605cf5220530b3744e107ba
DIFF: https://github.com/llvm/llvm-project/commit/1e7f592a890aad860605cf5220530b3744e107ba.diff
LOG: [MC][COFF][AArch64] Avoid incorrect IMAGE_REL_ARM64_BRANCH26 relocations.
For a b/bl instruction that branches a temporary symbol (private
assembly label), an IMAGE_REL_ARM64_BRANCH26 relocation to another
symbol + a non-zero offset could be emitted but the linkers don't
support this type of relocation and cause incorrect relocations and
crashes. Avoid emitting this type of relocations.
Differential Revision: https://reviews.llvm.org/D155732
Added:
llvm/test/MC/AArch64/coff-relocations-branch26.s
Modified:
llvm/lib/MC/WinCOFFObjectWriter.cpp
llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
Removed:
################################################################################
diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp
index c203280d2c107e..fd8af1f8cdb8b2 100644
--- a/llvm/lib/MC/WinCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp
@@ -847,7 +847,9 @@ void WinCOFFWriter::executePostLayoutBinding(MCAssembler &Asm,
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<MCSymbolCOFF>(Symbol).getClass() == COFF::IMAGE_SYM_CLASS_STATIC)
DefineSymbol(Symbol, Asm, Layout);
}
@@ -909,7 +911,7 @@ void WinCOFFWriter::recordRelocation(MCAssembler &Asm,
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
index 59cf53e85c824a..b5d230668a5e9f 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
@@ -314,6 +314,13 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target,
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
index 00000000000000..4cd47032309cae
--- /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 <main>:
+// CHECK: 0: d503201f nop
+// CHECK: 4: 14000000 b 0x4 <main+0x4>
+// CHECK: 0000000000000004: IMAGE_REL_ARM64_BRANCH26 .Ltarget
+// CHECK: 8: 14000000 b 0x8 <main+0x8>
+// CHECK: 0000000000000008: IMAGE_REL_ARM64_BRANCH26 .Lother_target
+// CHECK: 000000000000000c <.Ltarget>:
+// CHECK: c: d65f03c0 ret
+// CHECK: 0000000000000000 <other>:
+// 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
More information about the llvm-commits
mailing list