[llvm] r267307 - [MC/ELF] Implement support for GOTPCRELX/REX_GOTPCRELX.

Davide Italiano via llvm-commits llvm-commits at lists.llvm.org
Sat Apr 23 18:03:57 PDT 2016


Author: davide
Date: Sat Apr 23 20:03:57 2016
New Revision: 267307

URL: http://llvm.org/viewvc/llvm-project?rev=267307&view=rev
Log:
[MC/ELF] Implement support for GOTPCRELX/REX_GOTPCRELX.

The option to control the emission of the new relocations
is -relax-relocations (blatantly copied from GNU as).
It can't be enabled by default because it breaks relatively
recent versions of ld.bfd/ld.gold (late 2015).

Added:
    llvm/trunk/test/MC/ELF/got-relaxed.s
Modified:
    llvm/trunk/include/llvm/MC/MCAsmInfo.h
    llvm/trunk/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
    llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp

Modified: llvm/trunk/include/llvm/MC/MCAsmInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAsmInfo.h?rev=267307&r1=267306&r2=267307&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAsmInfo.h (original)
+++ llvm/trunk/include/llvm/MC/MCAsmInfo.h Sat Apr 23 20:03:57 2016
@@ -363,6 +363,10 @@ protected:
   /// expressions as logical rather than arithmetic.
   bool UseLogicalShr;
 
+  // If true, emit GOTPCRELX/REX_GOTPCRELX instead of GOTPCREL, on
+  // X86_64 ELF.
+  bool RelaxELFRelocations;
+
 public:
   explicit MCAsmInfo();
   virtual ~MCAsmInfo();
@@ -568,6 +572,8 @@ public:
   }
 
   bool shouldUseLogicalShr() const { return UseLogicalShr; }
+
+  bool canRelaxRelocations() const { return RelaxELFRelocations; }
 };
 }
 

Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp?rev=267307&r1=267306&r2=267307&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp Sat Apr 23 20:03:57 2016
@@ -9,6 +9,7 @@
 
 #include "MCTargetDesc/X86FixupKinds.h"
 #include "MCTargetDesc/X86MCTargetDesc.h"
+#include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCELFObjectWriter.h"
 #include "llvm/MC/MCExpr.h"
@@ -84,10 +85,10 @@ static void checkIs32(MCContext &Ctx, SM
                     "32 bit reloc applied to a field with a different size");
 }
 
-static unsigned getRelocType64(MCContext &Ctx, const MCFixup &Fixup,
+static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc,
                                MCSymbolRefExpr::VariantKind Modifier,
-                               X86_64RelType Type, bool IsPCRel) {
-  SMLoc Loc = Fixup.getLoc();
+                               X86_64RelType Type, bool IsPCRel,
+                               unsigned Kind) {
   switch (Modifier) {
   default:
     llvm_unreachable("Unimplemented");
@@ -173,7 +174,19 @@ static unsigned getRelocType64(MCContext
     return ELF::R_X86_64_PLT32;
   case MCSymbolRefExpr::VK_GOTPCREL:
     checkIs32(Ctx, Loc, Type);
-    return ELF::R_X86_64_GOTPCREL;
+    // Older versions of ld.bfd/ld.gold/lld
+    // do not support GOTPCRELX/REX_GOTPCRELX,
+    // and we want to keep back-compatibility.
+    if (!Ctx.getAsmInfo()->canRelaxRelocations())
+      return ELF::R_X86_64_GOTPCREL;
+    switch (Kind) {
+    default:
+      return ELF::R_X86_64_GOTPCREL;
+    case X86::reloc_riprel_4byte:
+      return ELF::R_X86_64_GOTPCRELX;
+    case X86::reloc_riprel_4byte_movq_load:
+      return ELF::R_X86_64_REX_GOTPCRELX;
+    }
   }
 }
 
@@ -259,7 +272,8 @@ unsigned X86ELFObjectWriter::getRelocTyp
   MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
   X86_64RelType Type = getType64(Fixup.getKind(), Modifier, IsPCRel);
   if (getEMachine() == ELF::EM_X86_64)
-    return getRelocType64(Ctx, Fixup, Modifier, Type, IsPCRel);
+    return getRelocType64(Ctx, Fixup.getLoc(), Modifier, Type, IsPCRel,
+                          Fixup.getKind());
 
   assert((getEMachine() == ELF::EM_386 || getEMachine() == ELF::EM_IAMCU) &&
          "Unsupported ELF machine type.");

Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp?rev=267307&r1=267306&r2=267307&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp Sat Apr 23 20:03:57 2016
@@ -35,6 +35,10 @@ AsmWriterFlavor("x86-asm-syntax", cl::in
              clEnumValEnd));
 
 static cl::opt<bool>
+RelaxELFRel("relax-relocations", cl::init(false),
+  cl::desc("Emit R_X86_64_GOTPCRELX instead of R_X86_64_GOTPCREL"));
+
+static cl::opt<bool>
 MarkedJTDataRegions("mark-data-regions", cl::init(false),
   cl::desc("Mark code section jump table data regions."),
   cl::Hidden);
@@ -111,6 +115,8 @@ X86ELFMCAsmInfo::X86ELFMCAsmInfo(const T
   // Always enable the integrated assembler by default.
   // Clang also enabled it when the OS is Solaris but that is redundant here.
   UseIntegratedAssembler = true;
+
+  RelaxELFRelocations = RelaxELFRel;
 }
 
 const MCExpr *

Added: llvm/trunk/test/MC/ELF/got-relaxed.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/got-relaxed.s?rev=267307&view=auto
==============================================================================
--- llvm/trunk/test/MC/ELF/got-relaxed.s (added)
+++ llvm/trunk/test/MC/ELF/got-relaxed.s Sat Apr 23 20:03:57 2016
@@ -0,0 +1,18 @@
+// RUN: llvm-mc -filetype=obj -relax-relocations -triple x86_64-pc-linux-gnu %s -o - | llvm-readobj -r -t | FileCheck %s
+
+// Test that this produces the correct relaxed relocations.
+
+        movl	foo at GOT, %eax
+        movl	foo at GOTPCREL(%rip), %eax
+        movq  foo at GOTPCREL(%rip), %rax
+
+// CHECK:      Relocations [
+// CHECK:        Section ({{[^ ]+}}) .rela.text {
+// CHECK-NEXT:       0x{{[^ ]+}} R_X86_64_GOT32 foo 0x{{[^ ]+}}
+// CHECK-NEXT:       0x{{[^ ]+}} R_X86_64_GOTPCRELX foo 0x{{[^ ]+}}
+// CHECK-NEXT:       0x{{[^ ]+}} R_X86_64_REX_GOTPCRELX foo 0x{{[^ ]+}}
+// CHECK-NEXT:   }
+// CHECK-NEXT: ]
+
+// CHECK:        Symbols [
+// CHECK-NOT:          _GLOBAL_OFFSET_TABLE_




More information about the llvm-commits mailing list