Handle _GLOBAL_OFFSET_TABLE_ in 64 bit mode.
authorRafael Espindola <rafael.espindola@gmail.com>
Mon, 21 Apr 2014 21:15:45 +0000 (21:15 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Mon, 21 Apr 2014 21:15:45 +0000 (21:15 +0000)
With this MC is able to handle _GLOBAL_OFFSET_TABLE_ in 64 bit mode, which is
needed for medium and large code models.

This fixes pr19470.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206793 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
lib/Target/X86/MCTargetDesc/X86FixupKinds.h
lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
test/MC/ELF/relocation.s

index cfe8918574f3494ac6da525da179679e646c8f3a..bf30a8e6663306b2b324bbd84f67c9b5122424d5 100644 (file)
@@ -58,6 +58,7 @@ static unsigned getFixupKindLog2Size(unsigned Kind) {
   case FK_PCRel_8:
   case FK_SecRel_8:
   case FK_Data_8:
+  case X86::reloc_global_offset_table8:
     return 3;
   }
 }
index c44d88d48b6fb8cebbd9960bf5b04bdaf9073cf4..c4a1af861575a21a1ad60ee2dafd6e0535780a95 100644 (file)
@@ -98,6 +98,12 @@ unsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target,
     } else {
       switch ((unsigned)Fixup.getKind()) {
       default: llvm_unreachable("invalid fixup kind!");
+      case X86::reloc_global_offset_table8:
+        Type = ELF::R_X86_64_GOTPC64;
+        break;
+      case X86::reloc_global_offset_table:
+        Type = ELF::R_X86_64_GOTPC32;
+        break;
       case FK_Data_8:
         switch (Modifier) {
         default:
index f2e34cbe0d65aa0af84dc52af0a2a594ba1c8f19..09396b790df2744a9159fa5c004c459fade5c61b 100644 (file)
@@ -23,6 +23,7 @@ enum Fixups {
   reloc_global_offset_table,                 // 32-bit, relative to the start
                                              // of the instruction. Used only
                                              // for _GLOBAL_OFFSET_TABLE_.
+  reloc_global_offset_table8,                // 64-bit variant.
   // Marker
   LastTargetFixupKind,
   NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
index e6fb0377f00f86a088bfc8d85fc32e88a726adae..4dcb6fd918811f63431b71f7cba644cca5fc2aee 100644 (file)
@@ -339,7 +339,13 @@ EmitImmediate(const MCOperand &DispOp, SMLoc Loc, unsigned Size,
     if (Kind != GOT_None) {
       assert(ImmOffset == 0);
 
-      FixupKind = MCFixupKind(X86::reloc_global_offset_table);
+      if (Size == 8) {
+        FixupKind = MCFixupKind(X86::reloc_global_offset_table8);
+      } else {
+        assert(Size == 4);
+        FixupKind = MCFixupKind(X86::reloc_global_offset_table);
+      }
+
       if (Kind == GOT_Normal)
         ImmOffset = CurByte;
     } else if (Expr->getKind() == MCExpr::SymbolRef) {
index 7755f06f3f4819d52ae42ca990ab475d1265dee2..318d60fdc823f099cfa63c637935673fccb213b0 100644 (file)
@@ -30,6 +30,9 @@ bar:
 
         leaq    -1+foo(%rip), %r11
 
+        movl  $_GLOBAL_OFFSET_TABLE_, %eax
+        movabs  $_GLOBAL_OFFSET_TABLE_, %rax
+
 // CHECK:        Section {
 // CHECK:          Name: .rela.text
 // CHECK:          Relocations [
@@ -56,6 +59,8 @@ bar:
 // CHECK-NEXT:       0x8F R_X86_64_PC8 foo 0x8F
 // CHECK-NEXT:       0x91 R_X86_64_PLT32 foo 0xFFFFFFFFFFFFFFFE
 // CHECK-NEXT:       0x98 R_X86_64_PC32 foo 0xFFFFFFFFFFFFFFFB
+// CHECK-NEXT:       0x9D R_X86_64_GOTPC32 _GLOBAL_OFFSET_TABLE_ 0x1
+// CHECK-NEXT:       0xA3 R_X86_64_GOTPC64 _GLOBAL_OFFSET_TABLE_ 0x2
 // CHECK-NEXT:     ]
 // CHECK-NEXT:   }