Skip to content

Commit 1e7f592

Browse files
committed
[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
1 parent d26a067 commit 1e7f592

File tree

3 files changed

+86
-2
lines changed

3 files changed

+86
-2
lines changed

llvm/lib/MC/WinCOFFObjectWriter.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,9 @@ void WinCOFFWriter::executePostLayoutBinding(MCAssembler &Asm,
847847

848848
if (Mode != DwoOnly)
849849
for (const MCSymbol &Symbol : Asm.symbols())
850-
if (!Symbol.isTemporary())
850+
// Define non-temporary or temporary static (private-linkage) symbols
851+
if (!Symbol.isTemporary() ||
852+
cast<MCSymbolCOFF>(Symbol).getClass() == COFF::IMAGE_SYM_CLASS_STATIC)
851853
DefineSymbol(Symbol, Asm, Layout);
852854
}
853855

@@ -909,7 +911,7 @@ void WinCOFFWriter::recordRelocation(MCAssembler &Asm,
909911
Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment);
910912

911913
// Turn relocations for temporary symbols into section relocations.
912-
if (A.isTemporary()) {
914+
if (A.isTemporary() && !SymbolMap[&A]) {
913915
MCSection *TargetSection = &A.getSection();
914916
assert(
915917
SectionMap.contains(TargetSection) &&

llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,13 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target,
314314
return (Value >> 2) & 0x3fff;
315315
case AArch64::fixup_aarch64_pcrel_branch26:
316316
case AArch64::fixup_aarch64_pcrel_call26:
317+
if (TheTriple.isOSBinFormatCOFF() && !IsResolved && SignedValue != 0) {
318+
// MSVC link.exe and lld do not support this relocation type
319+
// with a non-zero offset
320+
Ctx.reportError(Fixup.getLoc(),
321+
"cannot perform a PC-relative fixup with a non-zero "
322+
"symbol offset");
323+
}
317324
// Signed 28-bit immediate
318325
if (!isInt<28>(SignedValue))
319326
Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// RUN: llvm-mc -triple aarch64-unknown-windows-msvc -filetype obj %s -o - | llvm-objdump -D -r - | FileCheck %s
2+
// 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
3+
4+
.text
5+
main:
6+
nop
7+
b .Ltarget
8+
b .Lother_target
9+
10+
// A privte label target in the same section
11+
.def .Ltarget
12+
.scl 3
13+
.type 32
14+
.endef
15+
.p2align 2
16+
.Ltarget:
17+
ret
18+
19+
// A privte label target in another section
20+
.section "other"
21+
nop
22+
nop
23+
nop
24+
nop
25+
nop
26+
nop
27+
nop
28+
nop
29+
.def .Lother_target
30+
.scl 3
31+
.type 32
32+
.endef
33+
.p2align 2
34+
.Lother_target:
35+
ret
36+
37+
// Check that both branches have a relocation with a zero offset.
38+
//
39+
// CHECK: 0000000000000000 <main>:
40+
// CHECK: 0: d503201f nop
41+
// CHECK: 4: 14000000 b 0x4 <main+0x4>
42+
// CHECK: 0000000000000004: IMAGE_REL_ARM64_BRANCH26 .Ltarget
43+
// CHECK: 8: 14000000 b 0x8 <main+0x8>
44+
// CHECK: 0000000000000008: IMAGE_REL_ARM64_BRANCH26 .Lother_target
45+
// CHECK: 000000000000000c <.Ltarget>:
46+
// CHECK: c: d65f03c0 ret
47+
// CHECK: 0000000000000000 <other>:
48+
// CHECK: 0: d503201f nop
49+
// CHECK: 4: d503201f nop
50+
// CHECK: 8: d503201f nop
51+
// CHECK: c: d503201f nop
52+
// CHECK: 10: d503201f nop
53+
// CHECK: 14: d503201f nop
54+
// CHECK: 18: d503201f nop
55+
// CHECK: 1c: d503201f nop
56+
// CHECK: 0000000000000020 <.Lother_target>:
57+
// CHECK: 20: d65f03c0 ret
58+
59+
.ifdef ERR
60+
.section "err"
61+
err:
62+
nop
63+
b .Lerr_target+4
64+
// ERR: [[#@LINE-1]]:5: error: cannot perform a PC-relative fixup with a non-zero symbol offset
65+
66+
.def .Lerr_target
67+
.scl 3
68+
.type 32
69+
.p2align 2
70+
.endef
71+
.Lerr_target:
72+
nop
73+
nop
74+
ret
75+
.endif

0 commit comments

Comments
 (0)