[llvm] r316287 - [mips] Adds support for R_MIPS_26, HIGHER, HIGHEST relocations in RuntimeDyld.

Nitesh Jain via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 22 02:47:41 PDT 2017


Author: nitesh.jain
Date: Sun Oct 22 02:47:41 2017
New Revision: 316287

URL: http://llvm.org/viewvc/llvm-project?rev=316287&view=rev
Log:
[mips] Adds support for R_MIPS_26, HIGHER, HIGHEST relocations in RuntimeDyld.

Reviewers: sdardis

Subscribers: jaydeep, bhushan, llvm-commits

Differential Revision: https://reviews.llvm.org/D38314

Modified:
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.cpp
    llvm/trunk/test/ExecutionEngine/RuntimeDyld/Mips/ELF_Mips64r2N64_PIC_relocations.s
    llvm/trunk/test/ExecutionEngine/RuntimeDyld/Mips/ELF_N32_relocations.s

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp?rev=316287&r1=316286&r2=316287&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp Sun Oct 22 02:47:41 2017
@@ -878,7 +878,7 @@ uint8_t *RuntimeDyldImpl::createStubFunc
     // and stubs for branches Thumb - ARM and ARM - Thumb.
     writeBytesUnaligned(0xe51ff004, Addr, 4); // ldr pc, [pc, #-4]
     return Addr + 4;
-  } else if (IsMipsO32ABI) {
+  } else if (IsMipsO32ABI || IsMipsN32ABI) {
     // 0:   3c190000        lui     t9,%hi(addr).
     // 4:   27390000        addiu   t9,t9,%lo(addr).
     // 8:   03200008        jr      t9.
@@ -886,13 +886,39 @@ uint8_t *RuntimeDyldImpl::createStubFunc
     const unsigned LuiT9Instr = 0x3c190000, AdduiT9Instr = 0x27390000;
     const unsigned NopInstr = 0x0;
     unsigned JrT9Instr = 0x03200008;
-    if ((AbiVariant & ELF::EF_MIPS_ARCH) == ELF::EF_MIPS_ARCH_32R6)
-        JrT9Instr = 0x03200009;
+    if ((AbiVariant & ELF::EF_MIPS_ARCH) == ELF::EF_MIPS_ARCH_32R6 ||
+        (AbiVariant & ELF::EF_MIPS_ARCH) == ELF::EF_MIPS_ARCH_64R6)
+      JrT9Instr = 0x03200009;
 
     writeBytesUnaligned(LuiT9Instr, Addr, 4);
-    writeBytesUnaligned(AdduiT9Instr, Addr+4, 4);
-    writeBytesUnaligned(JrT9Instr, Addr+8, 4);
-    writeBytesUnaligned(NopInstr, Addr+12, 4);
+    writeBytesUnaligned(AdduiT9Instr, Addr + 4, 4);
+    writeBytesUnaligned(JrT9Instr, Addr + 8, 4);
+    writeBytesUnaligned(NopInstr, Addr + 12, 4);
+    return Addr;
+  } else if (IsMipsN64ABI) {
+    // 0:   3c190000        lui     t9,%highest(addr).
+    // 4:   67390000        daddiu  t9,t9,%higher(addr).
+    // 8:   0019CC38        dsll    t9,t9,16.
+    // c:   67390000        daddiu  t9,t9,%hi(addr).
+    // 10:  0019CC38        dsll    t9,t9,16.
+    // 14:  67390000        daddiu  t9,t9,%lo(addr).
+    // 18:  03200008        jr      t9.
+    // 1c:  00000000        nop.
+    const unsigned LuiT9Instr = 0x3c190000, DaddiuT9Instr = 0x67390000,
+                   DsllT9Instr = 0x19CC38;
+    const unsigned NopInstr = 0x0;
+    unsigned JrT9Instr = 0x03200008;
+    if ((AbiVariant & ELF::EF_MIPS_ARCH) == ELF::EF_MIPS_ARCH_64R6)
+      JrT9Instr = 0x03200009;
+
+    writeBytesUnaligned(LuiT9Instr, Addr, 4);
+    writeBytesUnaligned(DaddiuT9Instr, Addr + 4, 4);
+    writeBytesUnaligned(DsllT9Instr, Addr + 8, 4);
+    writeBytesUnaligned(DaddiuT9Instr, Addr + 12, 4);
+    writeBytesUnaligned(DsllT9Instr, Addr + 16, 4);
+    writeBytesUnaligned(DaddiuT9Instr, Addr + 20, 4);
+    writeBytesUnaligned(JrT9Instr, Addr + 24, 4);
+    writeBytesUnaligned(NopInstr, Addr + 28, 4);
     return Addr;
   } else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) {
     // Depending on which version of the ELF ABI is in use, we need to

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp?rev=316287&r1=316286&r2=316287&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp Sun Oct 22 02:47:41 2017
@@ -1276,8 +1276,7 @@ RuntimeDyldELF::processRelocationRef(
         if (Value.SymbolName) {
           addRelocationForSymbol(REHi, Value.SymbolName);
           addRelocationForSymbol(RELo, Value.SymbolName);
-        }
-        else {
+        } else {
           addRelocationForSection(REHi, Value.SectionID);
           addRelocationForSection(RELo, Value.SectionID);
         }
@@ -1337,11 +1336,81 @@ RuntimeDyldELF::processRelocationRef(
         RE.SymOffset = allocateGOTEntries(1);
         GOTSymbolOffsets[TargetName] = RE.SymOffset;
       }
+      if (Value.SymbolName)
+        addRelocationForSymbol(RE, Value.SymbolName);
+      else
+        addRelocationForSection(RE, Value.SectionID);
+    } else if (RelType == ELF::R_MIPS_26) {
+      // This is an Mips branch relocation, need to use a stub function.
+      DEBUG(dbgs() << "\t\tThis is a Mips branch relocation.");
+      SectionEntry &Section = Sections[SectionID];
+
+      //  Look up for existing stub.
+      StubMap::const_iterator i = Stubs.find(Value);
+      if (i != Stubs.end()) {
+        RelocationEntry RE(SectionID, Offset, RelType, i->second);
+        addRelocationForSection(RE, SectionID);
+        DEBUG(dbgs() << " Stub function found\n");
+      } else {
+        // Create a new stub function.
+        DEBUG(dbgs() << " Create a new stub function\n");
+        Stubs[Value] = Section.getStubOffset();
+
+        unsigned AbiVariant;
+        O.getPlatformFlags(AbiVariant);
+
+        uint8_t *StubTargetAddr = createStubFunction(
+            Section.getAddressWithOffset(Section.getStubOffset()), AbiVariant);
+
+        if (IsMipsN32ABI) {
+          // Creating Hi and Lo relocations for the filled stub instructions.
+          RelocationEntry REHi(SectionID, StubTargetAddr - Section.getAddress(),
+                               ELF::R_MIPS_HI16, Value.Addend);
+          RelocationEntry RELo(SectionID,
+                               StubTargetAddr - Section.getAddress() + 4,
+                               ELF::R_MIPS_LO16, Value.Addend);
+          if (Value.SymbolName) {
+            addRelocationForSymbol(REHi, Value.SymbolName);
+            addRelocationForSymbol(RELo, Value.SymbolName);
+          } else {
+            addRelocationForSection(REHi, Value.SectionID);
+            addRelocationForSection(RELo, Value.SectionID);
+          }
+        } else {
+          // Creating Highest, Higher, Hi and Lo relocations for the filled stub
+          // instructions.
+          RelocationEntry REHighest(SectionID,
+                                    StubTargetAddr - Section.getAddress(),
+                                    ELF::R_MIPS_HIGHEST, Value.Addend);
+          RelocationEntry REHigher(SectionID,
+                                   StubTargetAddr - Section.getAddress() + 4,
+                                   ELF::R_MIPS_HIGHER, Value.Addend);
+          RelocationEntry REHi(SectionID,
+                               StubTargetAddr - Section.getAddress() + 12,
+                               ELF::R_MIPS_HI16, Value.Addend);
+          RelocationEntry RELo(SectionID,
+                               StubTargetAddr - Section.getAddress() + 20,
+                               ELF::R_MIPS_LO16, Value.Addend);
+          if (Value.SymbolName) {
+            addRelocationForSymbol(REHighest, Value.SymbolName);
+            addRelocationForSymbol(REHigher, Value.SymbolName);
+            addRelocationForSymbol(REHi, Value.SymbolName);
+            addRelocationForSymbol(RELo, Value.SymbolName);
+          } else {
+            addRelocationForSection(REHighest, Value.SectionID);
+            addRelocationForSection(REHigher, Value.SectionID);
+            addRelocationForSection(REHi, Value.SectionID);
+            addRelocationForSection(RELo, Value.SectionID);
+          }
+        }
+        RelocationEntry RE(SectionID, Offset, RelType, Section.getStubOffset());
+        addRelocationForSection(RE, SectionID);
+        Section.advanceStubOffset(getMaxStubSize());
+      }
+    } else {
+      processSimpleRelocation(SectionID, Offset, RelType, Value);
     }
-    if (Value.SymbolName)
-      addRelocationForSymbol(RE, Value.SymbolName);
-    else
-      addRelocationForSection(RE, Value.SectionID);
+  
   } else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) {
     if (RelType == ELF::R_PPC64_REL24) {
       // Determine ABI variant in use for this object.

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h?rev=316287&r1=316286&r2=316287&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h Sun Oct 22 02:47:41 2017
@@ -66,8 +66,10 @@ class RuntimeDyldELF : public RuntimeDyl
       return 20; // movz; movk; movk; movk; br
     if (Arch == Triple::arm || Arch == Triple::thumb)
       return 8; // 32-bit instruction and 32-bit address
-    else if (IsMipsO32ABI)
+    else if (IsMipsO32ABI || IsMipsN32ABI)
       return 16;
+    else if (IsMipsN64ABI)
+      return 32;
     else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le)
       return 44;
     else if (Arch == Triple::x86_64)

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.cpp?rev=316287&r1=316286&r2=316287&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.cpp Sun Oct 22 02:47:41 2017
@@ -116,6 +116,8 @@ int64_t RuntimeDyldELFMips::evaluateMIPS
                << format("%llx", Section.getLoadAddressWithOffset(Offset))
                << " Value: 0x" << format("%llx", Value) << " Type: 0x"
                << format("%x", Type) << " Addend: 0x" << format("%llx", Addend)
+               << " Offset: " << format("%llx" PRIx64, Offset)
+               << " SID: " << format("%d", SectionID)
                << " SymOffset: " << format("%x", SymOffset) << "\n");
 
   switch (Type) {
@@ -141,6 +143,10 @@ int64_t RuntimeDyldELFMips::evaluateMIPS
     return ((Value + Addend + 0x8000) >> 16) & 0xffff;
   case ELF::R_MIPS_LO16:
     return (Value + Addend) & 0xffff;
+  case ELF::R_MIPS_HIGHER:
+    return ((Value + Addend + 0x80008000) >> 32) & 0xffff;
+  case ELF::R_MIPS_HIGHEST:
+    return ((Value + Addend + 0x800080008000) >> 48) & 0xffff;
   case ELF::R_MIPS_CALL16:
   case ELF::R_MIPS_GOT_DISP:
   case ELF::R_MIPS_GOT_PAGE: {
@@ -215,6 +221,8 @@ void RuntimeDyldELFMips::applyMIPSReloca
   case ELF::R_MIPS_GPREL16:
   case ELF::R_MIPS_HI16:
   case ELF::R_MIPS_LO16:
+  case ELF::R_MIPS_HIGHER:
+  case ELF::R_MIPS_HIGHEST:
   case ELF::R_MIPS_PC16:
   case ELF::R_MIPS_PCHI16:
   case ELF::R_MIPS_PCLO16:
@@ -304,7 +312,8 @@ void RuntimeDyldELFMips::resolveMIPSO32R
                << format("%p", Section.getLoadAddressWithOffset(Offset))
                << " Value: " << format("%x", Value)
                << " Type: " << format("%x", Type)
-               << " Addend: " << format("%x", Addend) << "\n");
+               << " Addend: " << format("%x", Addend)
+               << " SymOffset: " << format("%x", Offset) << "\n");
 
   Value = evaluateMIPS32Relocation(Section, Offset, Value, Type);
 

Modified: llvm/trunk/test/ExecutionEngine/RuntimeDyld/Mips/ELF_Mips64r2N64_PIC_relocations.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/RuntimeDyld/Mips/ELF_Mips64r2N64_PIC_relocations.s?rev=316287&r1=316286&r2=316287&view=diff
==============================================================================
--- llvm/trunk/test/ExecutionEngine/RuntimeDyld/Mips/ELF_Mips64r2N64_PIC_relocations.s (original)
+++ llvm/trunk/test/ExecutionEngine/RuntimeDyld/Mips/ELF_Mips64r2N64_PIC_relocations.s Sun Oct 22 02:47:41 2017
@@ -44,7 +44,7 @@ bar:
 	sd	$4, 8($fp)
 
 # Test R_MIPS_26 relocation.
-# rtdyld-check:  decode_operand(insn1, 0)[27:0] = foo[27:0]
+# rtdyld-check:  decode_operand(insn1, 0)[27:0] = stub_addr(test_ELF_Mips64N64.o, .text, foo)[27:0]
 insn1:
 	.option pic0
 	jal   foo

Modified: llvm/trunk/test/ExecutionEngine/RuntimeDyld/Mips/ELF_N32_relocations.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/RuntimeDyld/Mips/ELF_N32_relocations.s?rev=316287&r1=316286&r2=316287&view=diff
==============================================================================
--- llvm/trunk/test/ExecutionEngine/RuntimeDyld/Mips/ELF_N32_relocations.s (original)
+++ llvm/trunk/test/ExecutionEngine/RuntimeDyld/Mips/ELF_N32_relocations.s Sun Oct 22 02:47:41 2017
@@ -44,7 +44,7 @@ bar:
 	sd	$4, 8($fp)
 
 # Test R_MIPS_26 relocation.
-# rtdyld-check:  decode_operand(insn1, 0)[27:0] = foo[27:0]
+# rtdyld-check:  decode_operand(insn1, 0)[27:0] = stub_addr(test_ELF_N32.o, .text, foo)[27:0]
 insn1:
 	.option pic0
 	jal   foo




More information about the llvm-commits mailing list