[llvm] c618692 - [AArch64][X86] Allow 64-bit label differences lower to IMAGE_REL_*_REL32
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 21 14:32:31 PDT 2021
Author: Fangrui Song
Date: 2021-06-21T14:32:25-07:00
New Revision: c618692218d16e88fa20df56b29a8dd09c9e9db7
URL: https://github.com/llvm/llvm-project/commit/c618692218d16e88fa20df56b29a8dd09c9e9db7
DIFF: https://github.com/llvm/llvm-project/commit/c618692218d16e88fa20df56b29a8dd09c9e9db7.diff
LOG: [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
Added:
Modified:
llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp
llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
llvm/test/MC/AArch64/coff-relocations.s
llvm/test/MC/COFF/cross-section-relative-err.s
llvm/test/MC/COFF/cross-section-relative.s
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp
index fe5a6b147bba..0072af4cc16e 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp
@@ -48,7 +48,11 @@ unsigned AArch64WinCOFFObjectWriter::getRelocType(
bool IsCrossSection, const MCAsmBackend &MAB) const {
unsigned FixupKind = Fixup.getKind();
if (IsCrossSection) {
- if (FixupKind != FK_Data_4) {
+ // IMAGE_REL_ARM64_REL64 does not exist. We treat FK_Data_8 as FK_PCRel_4 so
+ // that .xword a-b can lower to IMAGE_REL_ARM64_REL32. This allows generic
+ // instrumentation to not bother with the COFF limitation. A negative value
+ // needs attention.
+ if (FixupKind != FK_Data_4 && FixupKind != FK_Data_8) {
Ctx.reportError(Fixup.getLoc(), "Cannot represent this expression");
return COFF::IMAGE_REL_ARM64_ADDR32;
}
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
index 760239f76505..075e85f4e243 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
@@ -42,19 +42,26 @@ unsigned X86WinCOFFObjectWriter::getRelocType(MCContext &Ctx,
const MCFixup &Fixup,
bool IsCrossSection,
const MCAsmBackend &MAB) const {
+ const bool Is64Bit = getMachine() == COFF::IMAGE_FILE_MACHINE_AMD64;
unsigned FixupKind = Fixup.getKind();
if (IsCrossSection) {
- if (FixupKind != FK_Data_4 && FixupKind != llvm::X86::reloc_signed_4byte) {
+ // IMAGE_REL_AMD64_REL64 does not exist. We treat FK_Data_8 as FK_PCRel_4 so
+ // that .quad a-b can lower to IMAGE_REL_AMD64_REL32. This allows generic
+ // instrumentation to not bother with the COFF limitation. A negative value
+ // needs attention.
+ if (FixupKind == FK_Data_4 || FixupKind == llvm::X86::reloc_signed_4byte ||
+ (FixupKind == FK_Data_8 && Is64Bit)) {
+ FixupKind = FK_PCRel_4;
+ } else {
Ctx.reportError(Fixup.getLoc(), "Cannot represent this expression");
return COFF::IMAGE_REL_AMD64_ADDR32;
}
- FixupKind = FK_PCRel_4;
}
MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
- if (getMachine() == COFF::IMAGE_FILE_MACHINE_AMD64) {
+ if (Is64Bit) {
switch (FixupKind) {
case FK_PCRel_4:
case X86::reloc_riprel_4byte:
diff --git a/llvm/test/MC/AArch64/coff-relocations.s b/llvm/test/MC/AArch64/coff-relocations.s
index e0fc30db6825..cfe1070b3a6d 100644
--- a/llvm/test/MC/AArch64/coff-relocations.s
+++ b/llvm/test/MC/AArch64/coff-relocations.s
@@ -67,6 +67,10 @@ tbz x0, #0, target
.word .Linfo_bar - .Ltable
.word .Linfo_foo - .Ltable
+// As an extension, we allow 64-bit label
diff erences. They lower to
+// IMAGE_REL_ARM64_REL32 because IMAGE_REL_ARM64_REL64 does not exist.
+.xword .Linfo_foo - .Ltable
+
// CHECK: Format: COFF-ARM64
// CHECK: Arch: aarch64
// CHECK: AddressSize: 64bit
@@ -96,6 +100,7 @@ tbz x0, #0, target
// CHECK: Section (4) .rdata {
// CHECK: 0x0 IMAGE_REL_ARM64_REL32 .text
// CHECK: 0x4 IMAGE_REL_ARM64_REL32 .text
+// CHECK: 0x8 IMAGE_REL_ARM64_REL32 .text
// CHECK: }
// CHECK: ]
diff --git a/llvm/test/MC/COFF/cross-section-relative-err.s b/llvm/test/MC/COFF/cross-section-relative-err.s
index e237f60e9a36..76bb22ffb46e 100644
--- a/llvm/test/MC/COFF/cross-section-relative-err.s
+++ b/llvm/test/MC/COFF/cross-section-relative-err.s
@@ -1,3 +1,4 @@
+// RUN: not llvm-mc -filetype=obj -triple i686-pc-win32 %s -o /dev/null 2>&1 | FileCheck %s --check-prefixes=CHECK,I686
// RUN: not llvm-mc -filetype=obj -triple x86_64-pc-win32 %s -o /dev/null 2>&1 | FileCheck %s
@@ -7,6 +8,5 @@
// CHECK: [[@LINE+1]]:{{[0-9]+}}: error: Cannot represent this expression
.short foo - .
-// CHECK: [[@LINE+1]]:{{[0-9]+}}: error: Cannot represent this expression
+// I686: [[@LINE+1]]:{{[0-9]+}}: error: Cannot represent this expression
.quad foo - .
-
diff --git a/llvm/test/MC/COFF/cross-section-relative.s b/llvm/test/MC/COFF/cross-section-relative.s
index 1d8fb709bdd1..6b52c8ea8646 100644
--- a/llvm/test/MC/COFF/cross-section-relative.s
+++ b/llvm/test/MC/COFF/cross-section-relative.s
@@ -57,6 +57,10 @@ t6:
.long foobar - .
+// As an extension, we allow 64-bit label
diff erences. They lower to
+// IMAGE_REL_AMD64_REL32 because IMAGE_REL_AMD64_REL64 does not exist.
+.quad foobar - .
+
// READOBJ: Section {
// READOBJ: Number:
// READOBJ: Name: .fix (2E 66 69 78 00 00 00 00)
@@ -77,7 +81,8 @@ t6:
// READOBJ-NEXT: SectionData (
// READOBJ-NEXT: 0000: 04000000 00000000 00000000 00000000 |
// READOBJ-NEXT: 0010: 01020000 00000000 00010000 00000000 |
-// READOBJ-NEXT: 0020: 04000000 00000000 04000000 |
+// READOBJ-NEXT: 0020: 04000000 00000000 04000000 04000000 |
+// READOBJ-NEXT: 0030: 00000000 |
// READOBJ-NEXT: )
// READOBJ-NEXT: }
// READOBJ-NEXT: ]
@@ -107,5 +112,11 @@ t6:
// READOBJ-NEXT: Symbol: foobar
// READOBJ-NEXT: SymbolIndex: 20
// READOBJ-NEXT: }
+// READOBJ-NEXT: Relocation {
+// READOBJ-NEXT: Offset: 0x2C
+// READOBJ-NEXT: Type: IMAGE_REL_AMD64_REL32 (4)
+// READOBJ-NEXT: Symbol: foobar
+// READOBJ-NEXT: SymbolIndex: 20
+// READOBJ-NEXT: }
// READOBJ-NEXT: }
// READOBJ-NEXT:]
More information about the llvm-commits
mailing list