[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