Skip to content

Commit c618692

Browse files
committed
[AArch64][X86] Allow 64-bit label differences lower to IMAGE_REL_*_REL32
`IMAGE_REL_ARM64_REL64/IMAGE_REL_AMD64_REL64` do not exist and `.quad a - .` is currently not representable. For instrumentation, `.quad a - .` is useful representing a cross-section reference in a metadata section, to allow ELF medium/large code models. The COFF limitation makes such generic instrumentations inconvenient. I plan to make a PGO/coverage metadata section field relative in D104556. Differential Revision: https://reviews.llvm.org/D104564
1 parent 3996311 commit c618692

File tree

5 files changed

+34
-7
lines changed

5 files changed

+34
-7
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@ unsigned AArch64WinCOFFObjectWriter::getRelocType(
4848
bool IsCrossSection, const MCAsmBackend &MAB) const {
4949
unsigned FixupKind = Fixup.getKind();
5050
if (IsCrossSection) {
51-
if (FixupKind != FK_Data_4) {
51+
// IMAGE_REL_ARM64_REL64 does not exist. We treat FK_Data_8 as FK_PCRel_4 so
52+
// that .xword a-b can lower to IMAGE_REL_ARM64_REL32. This allows generic
53+
// instrumentation to not bother with the COFF limitation. A negative value
54+
// needs attention.
55+
if (FixupKind != FK_Data_4 && FixupKind != FK_Data_8) {
5256
Ctx.reportError(Fixup.getLoc(), "Cannot represent this expression");
5357
return COFF::IMAGE_REL_ARM64_ADDR32;
5458
}

llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,26 @@ unsigned X86WinCOFFObjectWriter::getRelocType(MCContext &Ctx,
4242
const MCFixup &Fixup,
4343
bool IsCrossSection,
4444
const MCAsmBackend &MAB) const {
45+
const bool Is64Bit = getMachine() == COFF::IMAGE_FILE_MACHINE_AMD64;
4546
unsigned FixupKind = Fixup.getKind();
4647
if (IsCrossSection) {
47-
if (FixupKind != FK_Data_4 && FixupKind != llvm::X86::reloc_signed_4byte) {
48+
// IMAGE_REL_AMD64_REL64 does not exist. We treat FK_Data_8 as FK_PCRel_4 so
49+
// that .quad a-b can lower to IMAGE_REL_AMD64_REL32. This allows generic
50+
// instrumentation to not bother with the COFF limitation. A negative value
51+
// needs attention.
52+
if (FixupKind == FK_Data_4 || FixupKind == llvm::X86::reloc_signed_4byte ||
53+
(FixupKind == FK_Data_8 && Is64Bit)) {
54+
FixupKind = FK_PCRel_4;
55+
} else {
4856
Ctx.reportError(Fixup.getLoc(), "Cannot represent this expression");
4957
return COFF::IMAGE_REL_AMD64_ADDR32;
5058
}
51-
FixupKind = FK_PCRel_4;
5259
}
5360

5461
MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
5562
MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
5663

57-
if (getMachine() == COFF::IMAGE_FILE_MACHINE_AMD64) {
64+
if (Is64Bit) {
5865
switch (FixupKind) {
5966
case FK_PCRel_4:
6067
case X86::reloc_riprel_4byte:

llvm/test/MC/AArch64/coff-relocations.s

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ tbz x0, #0, target
6767
.word .Linfo_bar - .Ltable
6868
.word .Linfo_foo - .Ltable
6969

70+
// As an extension, we allow 64-bit label differences. They lower to
71+
// IMAGE_REL_ARM64_REL32 because IMAGE_REL_ARM64_REL64 does not exist.
72+
.xword .Linfo_foo - .Ltable
73+
7074
// CHECK: Format: COFF-ARM64
7175
// CHECK: Arch: aarch64
7276
// CHECK: AddressSize: 64bit
@@ -96,6 +100,7 @@ tbz x0, #0, target
96100
// CHECK: Section (4) .rdata {
97101
// CHECK: 0x0 IMAGE_REL_ARM64_REL32 .text
98102
// CHECK: 0x4 IMAGE_REL_ARM64_REL32 .text
103+
// CHECK: 0x8 IMAGE_REL_ARM64_REL32 .text
99104
// CHECK: }
100105
// CHECK: ]
101106

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// RUN: not llvm-mc -filetype=obj -triple i686-pc-win32 %s -o /dev/null 2>&1 | FileCheck %s --check-prefixes=CHECK,I686
12
// RUN: not llvm-mc -filetype=obj -triple x86_64-pc-win32 %s -o /dev/null 2>&1 | FileCheck %s
23

34

@@ -7,6 +8,5 @@
78
// CHECK: [[@LINE+1]]:{{[0-9]+}}: error: Cannot represent this expression
89
.short foo - .
910

10-
// CHECK: [[@LINE+1]]:{{[0-9]+}}: error: Cannot represent this expression
11+
// I686: [[@LINE+1]]:{{[0-9]+}}: error: Cannot represent this expression
1112
.quad foo - .
12-

llvm/test/MC/COFF/cross-section-relative.s

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ t6:
5757

5858
.long foobar - .
5959

60+
// As an extension, we allow 64-bit label differences. They lower to
61+
// IMAGE_REL_AMD64_REL32 because IMAGE_REL_AMD64_REL64 does not exist.
62+
.quad foobar - .
63+
6064
// READOBJ: Section {
6165
// READOBJ: Number:
6266
// READOBJ: Name: .fix (2E 66 69 78 00 00 00 00)
@@ -77,7 +81,8 @@ t6:
7781
// READOBJ-NEXT: SectionData (
7882
// READOBJ-NEXT: 0000: 04000000 00000000 00000000 00000000 |
7983
// READOBJ-NEXT: 0010: 01020000 00000000 00010000 00000000 |
80-
// READOBJ-NEXT: 0020: 04000000 00000000 04000000 |
84+
// READOBJ-NEXT: 0020: 04000000 00000000 04000000 04000000 |
85+
// READOBJ-NEXT: 0030: 00000000 |
8186
// READOBJ-NEXT: )
8287
// READOBJ-NEXT: }
8388
// READOBJ-NEXT: ]
@@ -107,5 +112,11 @@ t6:
107112
// READOBJ-NEXT: Symbol: foobar
108113
// READOBJ-NEXT: SymbolIndex: 20
109114
// READOBJ-NEXT: }
115+
// READOBJ-NEXT: Relocation {
116+
// READOBJ-NEXT: Offset: 0x2C
117+
// READOBJ-NEXT: Type: IMAGE_REL_AMD64_REL32 (4)
118+
// READOBJ-NEXT: Symbol: foobar
119+
// READOBJ-NEXT: SymbolIndex: 20
120+
// READOBJ-NEXT: }
110121
// READOBJ-NEXT: }
111122
// READOBJ-NEXT:]

0 commit comments

Comments
 (0)