This patch addresses gp relative fixups/relocations for jump tables.
authorAkira Hatanaka <ahatanaka@mips.com>
Wed, 23 Nov 2011 22:18:04 +0000 (22:18 +0000)
committerAkira Hatanaka <ahatanaka@mips.com>
Wed, 23 Nov 2011 22:18:04 +0000 (22:18 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@145112 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCFixup.h
include/llvm/MC/MCObjectStreamer.h
include/llvm/Support/ELF.h
lib/MC/ELFObjectWriter.cpp
lib/MC/ELFObjectWriter.h
lib/MC/MCAsmBackend.cpp
lib/MC/MCObjectStreamer.cpp
lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp

index 6fde797e40fdaa414211011a2c86a4f2cac7fb96..740427083d54141177aeabfd1a3b63b517069db3 100644 (file)
@@ -26,6 +26,10 @@ enum MCFixupKind {
   FK_PCRel_2,    ///< A two-byte pc relative fixup.
   FK_PCRel_4,    ///< A four-byte pc relative fixup.
   FK_PCRel_8,    ///< A eight-byte pc relative fixup.
+  FK_GPRel_1,    ///< A one-byte gp relative fixup.
+  FK_GPRel_2,    ///< A two-byte gp relative fixup.
+  FK_GPRel_4,    ///< A four-byte gp relative fixup.
+  FK_GPRel_8,    ///< A eight-byte gp relative fixup.
 
   FirstTargetFixupKind = 128,
 
index f897e64f4456680edb2892fa4de098e7926c8730..01d254a49c837a65808c099dbdc34e4d178af390 100644 (file)
@@ -77,6 +77,7 @@ public:
                                         unsigned PointerSize);
   virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
                                          const MCSymbol *Label);
+  virtual void EmitGPRel32Value(const MCExpr *Value);
   virtual void Finish();
 
   /// @}
index c5b85e2e6a12efadbb228ce1e19e4967d23838d7..a3906b1dbab1788876a77b952ffc0b3acc3cab44 100644 (file)
@@ -599,7 +599,23 @@ enum {
   R_ARM_THM_TLS_DESCSEQ32     = 0x82
 };
 
+// Mips Specific e_flags
+enum {
+  EF_MIPS_NOREORDER = 0x00000001, // Don't reorder instructions
+  EF_MIPS_PIC       = 0x00000002, // Position independent code
+  EF_MIPS_CPIC      = 0x00000004, // Call object with Position independent code
+  EF_MIPS_ARCH_1    = 0x00000000, // MIPS1 instruction set
+  EF_MIPS_ARCH_2    = 0x10000000, // MIPS2 instruction set
+  EF_MIPS_ARCH_3    = 0x20000000, // MIPS3 instruction set
+  EF_MIPS_ARCH_4    = 0x30000000, // MIPS4 instruction set
+  EF_MIPS_ARCH_5    = 0x40000000, // MIPS5 instruction set
+  EF_MIPS_ARCH_32   = 0x60000000, // MIPS32 instruction set
+  EF_MIPS_ARCH_32R2 = 0x70000000, // mips32r2
+  EF_MIPS_ARCH      = 0xf0000000  // Mask for applying EF_MIPS_ARCH_ variant
+};
+
 // ELF Relocation types for Mips
+// .
 enum {
   R_MIPS_NONE              =  0,
   R_MIPS_16                =  1,
index 4491d4b16b6f63ea7b9b24501a32f531c2001fd6..bd28069a3153b663123ab93ecc5446bbb2c13a86 100644 (file)
@@ -1825,6 +1825,12 @@ MipsELFObjectWriter::MipsELFObjectWriter(MCELFObjectTargetWriter *MOTW,
 
 MipsELFObjectWriter::~MipsELFObjectWriter() {}
 
+// FIXME: get the real EABI Version from the Triple.
+void MipsELFObjectWriter::WriteEFlags() {
+  Write32(ELF::EF_MIPS_NOREORDER |
+          ELF::EF_MIPS_ARCH_32R2);
+}
+
 unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target,
                                            const MCFixup &Fixup,
                                            bool IsPCRel,
@@ -1840,6 +1846,9 @@ unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target,
   case FK_Data_4:
     Type = ELF::R_MIPS_32;
     break;
+  case FK_GPRel_4:
+    Type = ELF::R_MIPS_GPREL32;
+    break;
   case Mips::fixup_Mips_GPREL16:
     Type = ELF::R_MIPS_GPREL16;
     break;
index ca6cdfc5ce1544c4eb181bed16a7dcf91072f545..78382065dbcbb3d9f5ea1062c7a73dcb80aa562c 100644 (file)
@@ -442,6 +442,8 @@ class ELFObjectWriter : public MCObjectWriter {
                         bool IsLittleEndian);
 
     virtual ~MipsELFObjectWriter();
+    virtual void WriteEFlags();
+
   protected:
     virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
                                   bool IsPCRel, bool IsRelocWithSymbol,
index 2c150f456cf6c6e9b35a2e833f459edb39807dd4..936ed55e54d3cbdd55d75ec718e40e0dc6857084 100644 (file)
@@ -21,14 +21,18 @@ MCAsmBackend::~MCAsmBackend() {
 const MCFixupKindInfo &
 MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
   static const MCFixupKindInfo Builtins[] = {
-    { "FK_Data_1", 0, 8, 0 },
-    { "FK_Data_2", 0, 16, 0 },
-    { "FK_Data_4", 0, 32, 0 },
-    { "FK_Data_8", 0, 64, 0 },
-    { "FK_PCRel_1", 0, 8, MCFixupKindInfo::FKF_IsPCRel },
+    { "FK_Data_1",  0,  8, 0 },
+    { "FK_Data_2",  0, 16, 0 },
+    { "FK_Data_4",  0, 32, 0 },
+    { "FK_Data_8",  0, 64, 0 },
+    { "FK_PCRel_1", 0,  8, MCFixupKindInfo::FKF_IsPCRel },
     { "FK_PCRel_2", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
     { "FK_PCRel_4", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
-    { "FK_PCRel_8", 0, 64, MCFixupKindInfo::FKF_IsPCRel }
+    { "FK_PCRel_8", 0, 64, MCFixupKindInfo::FKF_IsPCRel },
+    { "FK_GPRel_1", 0,  8, 0 },
+    { "FK_GPRel_2", 0, 16, 0 },
+    { "FK_GPRel_4", 0, 32, 0 },
+    { "FK_GPRel_8", 0, 64, 0 }
   };
   
   assert((size_t)Kind <= sizeof(Builtins) / sizeof(Builtins[0]) &&
index a04ae0812a3eca20ccc8acd9f876b572d4b814cc..90c957f7be8a2e28a8676950f67ee766b64df2d8 100644 (file)
@@ -245,6 +245,16 @@ void MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
   EmitFill(Res, Value, 0);
 }
 
+// Associate GPRel32 fixup with data and resize data area
+void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
+  MCDataFragment *DF = getOrCreateDataFragment();
+
+  DF->addFixup(MCFixup::Create(DF->getContents().size(),
+                               Value,
+                               FK_GPRel_4));
+  DF->getContents().resize(DF->getContents().size() + 4, 0);
+}
+
 void MCObjectStreamer::Finish() {
   // Dump out the dwarf file & directory tables and line tables.
   if (getContext().hasDwarfFiles())
index 4f017d0b20365ce9e02869a27a56f19541818d22..7bc5fe4a6e4e2fb54e51d1a09f1c9296396cf71b 100644 (file)
@@ -58,6 +58,7 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
   switch (Kind) {
   default:
     break;
+  case FK_GPRel_4:
   case FK_Data_4:
     Value &= 0xffffffff;
     break;
@@ -68,6 +69,9 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
   case Mips::fixup_Mips_PC16:
     Value &= 0x0000ffff;
     break;
+  case Mips::fixup_Mips_HI16:
+    Value >>= 16;
+    break;
   }
 
   return Value;
@@ -104,15 +108,17 @@ public:
       llvm_unreachable("Unknown fixup kind!");
     case Mips::fixup_Mips_GOT16: // This will be fixed up at link time
      break;
+    case FK_GPRel_4:
     case FK_Data_4:
     case Mips::fixup_Mips_26:
     case Mips::fixup_Mips_LO16:
     case Mips::fixup_Mips_PC16:
+    case Mips::fixup_Mips_HI16:
       // For each byte of the fragment that the fixup touches, mask i
       // the fixup value. The Value has been "split up" into the appr
       // bitfields above.
       for (unsigned i = 0; i != 4; ++i) // FIXME - Need to support 2 and 8 bytes
-        Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
+        Data[Offset + i] += uint8_t((Value >> (i * 8)) & 0xff);
       break;
     }
   }