The Mips specific relocation R_MIPS_GOT_DISP
authorJack Carter <jcarter@mips.com>
Fri, 13 Jul 2012 19:15:47 +0000 (19:15 +0000)
committerJack Carter <jcarter@mips.com>
Fri, 13 Jul 2012 19:15:47 +0000 (19:15 +0000)
is used in cases where global symbols are
directly represented in the GOT and we use an
offset into the global offset table.

This patch adds direct object support for R_MIPS_GOT_DISP.

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

lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h
lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
test/MC/Mips/r-mips-got-disp.ll [new file with mode: 0644]

index 575f2cfda5b55766f83cfc499dcd42d4b0ba9fa8..6fe0c11911d1897d0bc2fc6907a4724d5d9159ee 100644 (file)
@@ -40,6 +40,7 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
   case Mips::fixup_Mips_GPOFF_LO:
   case Mips::fixup_Mips_GOT_PAGE:
   case Mips::fixup_Mips_GOT_OFST:
+  case Mips::fixup_Mips_GOT_DISP:
     break;
   case Mips::fixup_Mips_PC16:
     // So far we are only using this type for branches.
@@ -166,7 +167,8 @@ public:
       { "fixup_Mips_GPOFF_HI",     0,     16,   0 },
       { "fixup_Mips_GPOFF_LO",     0,     16,   0 },
       { "fixup_Mips_GOT_PAGE",     0,     16,   0 },
-      { "fixup_Mips_GOT_OFST",     0,     16,   0 }
+      { "fixup_Mips_GOT_OFST",     0,     16,   0 },
+      { "fixup_Mips_GOT_DISP",     0,     16,   0 }
     };
 
     if (Kind < FirstTargetFixupKind)
index 9f9272886e0f7e9025ae3a476b966e55b6cc00f2..77c1524531c3a0756bc987d72456f42fdf8a9e86 100644 (file)
@@ -156,6 +156,9 @@ unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target,
   case Mips::fixup_Mips_GOT_OFST:
     Type = ELF::R_MIPS_GOT_OFST;
     break;
+  case Mips::fixup_Mips_GOT_DISP:
+    Type = ELF::R_MIPS_GOT_DISP;
+    break;
   case Mips::fixup_Mips_GPOFF_HI:
     Type = setRType((unsigned)ELF::R_MIPS_GPREL16, Type);
     Type = setRType2((unsigned)ELF::R_MIPS_SUB, Type);
index 1f6000cc8ce7163f83b095b8105e5fabd11b74e4..f5cbbd537d1c4d16a01e78a5150b19d2594a5dbe 100644 (file)
@@ -107,6 +107,9 @@ namespace Mips {
     // resulting in - R_MIPS_GOT_OFST
     fixup_Mips_GOT_OFST,
 
+    // resulting in - R_MIPS_GOT_DISP
+    fixup_Mips_GOT_DISP,
+
     // Marker
     LastTargetFixupKind,
     NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
index 1bd1420c91d450ff8d5f67da3da5992979563a87..ff3b3a7ed1c2d85e2b568af37475310f9ca8f2b6 100644 (file)
@@ -201,9 +201,6 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,
   switch(cast<MCSymbolRefExpr>(Expr)->getKind()) {
   default: llvm_unreachable("Unknown fixup kind!");
     break;
-  case MCSymbolRefExpr::VK_Mips_GOT_DISP :
-    llvm_unreachable("fixup kind VK_Mips_GOT_DISP not supported for direct object!");
-    break;
   case MCSymbolRefExpr::VK_Mips_GPOFF_HI :
     FixupKind = Mips::fixup_Mips_GPOFF_HI;
     break;
@@ -216,6 +213,9 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,
   case MCSymbolRefExpr::VK_Mips_GOT_OFST :
     FixupKind = Mips::fixup_Mips_GOT_OFST;
     break;
+  case MCSymbolRefExpr::VK_Mips_GOT_DISP :
+    FixupKind = Mips::fixup_Mips_GOT_DISP;
+    break;
   case MCSymbolRefExpr::VK_Mips_GPREL:
     FixupKind = Mips::fixup_Mips_GPREL16;
     break;
diff --git a/test/MC/Mips/r-mips-got-disp.ll b/test/MC/Mips/r-mips-got-disp.ll
new file mode 100644 (file)
index 0000000..73396ac
--- /dev/null
@@ -0,0 +1,18 @@
+; RUN: llc -march=mips64el -filetype=obj -mcpu=mips64r2 < %s -o - | elf-dump --dump-section-data  | FileCheck %s
+
+; Check that the R_MIPS_GOT_DISP relocations were created.
+
+; CHECK:     ('r_type', 0x13)
+
+@shl = global i64 1, align 8
+@.str = private unnamed_addr constant [8 x i8] c"0x%llx\0A\00", align 1
+
+define i32 @main() nounwind {
+entry:
+  %0 = load i64* @shl, align 8
+  %call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([8 x i8]* @.str, i64 0, i64 0), i64 %0) nounwind
+  ret i32 0
+}
+
+declare i32 @printf(i8* nocapture, ...) nounwind
+