[lld] r231639 - [Mips] Fix incorrect handling of cross mode jumps

Simon Atanasyan simon at atanasyan.com
Mon Mar 9 03:53:15 PDT 2015


Author: atanasyan
Date: Mon Mar  9 05:53:15 2015
New Revision: 231639

URL: http://llvm.org/viewvc/llvm-project?rev=231639&view=rev
Log:
[Mips] Fix incorrect handling of cross mode jumps

We should not take in account a type of "source" symbol. Cross mode jump
adjustment is requred when target symbol and relocation belong to
different (regular/microMIPS) instruction sets.

Modified:
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
    lld/trunk/test/elf/Mips/la25-stub-micro.test
    lld/trunk/test/elf/Mips/r26-1-micro.test

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp?rev=231639&r1=231638&r2=231639&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp Mon Mar  9 05:53:15 2015
@@ -17,6 +17,14 @@ using namespace elf;
 using namespace llvm::ELF;
 using namespace llvm::support;
 
+namespace {
+enum class CrossJumpMode {
+  None,      // Not a jump or non-isa-cross jump
+  ToRegular, // cross isa jump to regular symbol
+  ToMicro    // cross isa jump to microMips symbol
+};
+}
+
 static inline void applyReloc(uint32_t &ins, uint32_t result, uint32_t mask) {
   ins = (ins & ~mask) | (result & mask);
 }
@@ -140,12 +148,16 @@ static void reloc32hi16(uint32_t &ins, u
   applyReloc(ins, (S + A + 0x8000) & 0xffff0000, 0xffffffff);
 }
 
-static void fixJumpOpCode(uint32_t &ins, uint64_t tgt, bool isMicro) {
-  uint32_t opNative = isMicro ? 0x3d : 0x03;
-  uint32_t opCross = isMicro ? 0x3c : 0x1d;
+static void adjustJumpOpCode(uint32_t &ins, uint64_t tgt, CrossJumpMode mode) {
+  if (mode == CrossJumpMode::None)
+    return;
+
+  bool toMicro = mode == CrossJumpMode::ToMicro;
+  uint32_t opNative = toMicro ? 0x03 : 0x3d;
+  uint32_t opCross = toMicro ? 0x1d : 0x3c;
 
   // FIXME (simon): Convert this into the regular fatal error.
-  if ((tgt & 1) == isMicro)
+  if ((tgt & 1) != toMicro)
     llvm_unreachable("Incorrect bit 0 for the jalx target");
 
   if (tgt & 2)
@@ -167,6 +179,22 @@ static bool isMicroMipsAtom(const Atom *
   return false;
 }
 
+static CrossJumpMode getCrossJumpMode(const Reference &ref) {
+  if (!isa<DefinedAtom>(ref.target()))
+    return CrossJumpMode::None;
+  bool isTgtMicro = isMicroMipsAtom(ref.target());
+  switch (ref.kindValue()) {
+  case R_MIPS_26:
+  case LLD_R_MIPS_GLOBAL_26:
+    return isTgtMicro ? CrossJumpMode::ToMicro : CrossJumpMode::None;
+  case R_MICROMIPS_26_S1:
+  case LLD_R_MICROMIPS_GLOBAL_26_S1:
+    return isTgtMicro ? CrossJumpMode::None : CrossJumpMode::ToRegular;
+  default:
+    return CrossJumpMode::None;
+  }
+}
+
 static bool needMicroShuffle(const Reference &ref) {
   if (ref.kindNamespace() != lld::Reference::KindNamespace::ELF)
     return false;
@@ -241,26 +269,11 @@ std::error_code RelocationHandler<ELFT>:
   if (shuffle)
     ins = microShuffle(ins);
 
-  bool isSrcMicroMips = isMicroMipsAtom(atom._atom);
-  bool isTgtMicroMips = isMicroMipsAtom(ref.target());
-  bool isCrossJump = isSrcMicroMips != isTgtMicroMips;
-
-  if (isTgtMicroMips)
+  if (isMicroMipsAtom(ref.target()))
     targetVAddress |= 1;
 
-  if (isCrossJump)
-    switch (ref.kindValue()) {
-    case R_MIPS_26:
-    case LLD_R_MIPS_GLOBAL_26:
-      fixJumpOpCode(ins, targetVAddress, false);
-      break;
-    case R_MICROMIPS_26_S1:
-    case LLD_R_MICROMIPS_GLOBAL_26_S1:
-      fixJumpOpCode(ins, targetVAddress, true);
-      break;
-    default:
-      break; // Do nothing.
-    }
+  CrossJumpMode crossJump = getCrossJumpMode(ref);
+  adjustJumpOpCode(ins, targetVAddress, crossJump);
 
   switch (ref.kindValue()) {
   case R_MIPS_NONE:
@@ -273,7 +286,7 @@ std::error_code RelocationHandler<ELFT>:
     break;
   case R_MICROMIPS_26_S1:
     reloc26loc(ins, relocVAddress, targetVAddress, ref.addend(),
-               isCrossJump ? 2 : 1);
+               crossJump != CrossJumpMode::None ? 2 : 1);
     break;
   case R_MIPS_HI16:
     relocHi16(ins, relocVAddress, targetVAddress, ref.addend(), isGpDisp);
@@ -361,7 +374,8 @@ std::error_code RelocationHandler<ELFT>:
     reloc26ext(ins, targetVAddress, ref.addend(), 2);
     break;
   case LLD_R_MICROMIPS_GLOBAL_26_S1:
-    reloc26ext(ins, targetVAddress, ref.addend(), isCrossJump ? 2 : 1);
+    reloc26ext(ins, targetVAddress, ref.addend(),
+               crossJump != CrossJumpMode::None ? 2 : 1);
     break;
   case LLD_R_MIPS_HI16:
     relocHi16(ins, 0, targetVAddress, 0, false);

Modified: lld/trunk/test/elf/Mips/la25-stub-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/la25-stub-micro.test?rev=231639&r1=231638&r2=231639&view=diff
==============================================================================
--- lld/trunk/test/elf/Mips/la25-stub-micro.test (original)
+++ lld/trunk/test/elf/Mips/la25-stub-micro.test Mon Mar  9 05:53:15 2015
@@ -125,6 +125,7 @@ Symbols:
     - Name:    loc
       Section: .text
       Value:   0x10
+      Size:    0x18
       Other:   [ STO_MIPS_MICROMIPS ]
     - Name:    .text
       Type:    STT_SECTION
@@ -132,6 +133,7 @@ Symbols:
   Global:
     - Name:    glob
       Section: .text
+      Size:    0x10
       Other:   [ STO_MIPS_MICROMIPS ]
     - Name:    T1
     - Name:    T1N

Modified: lld/trunk/test/elf/Mips/r26-1-micro.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/r26-1-micro.test?rev=231639&r1=231638&r2=231639&view=diff
==============================================================================
--- lld/trunk/test/elf/Mips/r26-1-micro.test (original)
+++ lld/trunk/test/elf/Mips/r26-1-micro.test Mon Mar  9 05:53:15 2015
@@ -19,7 +19,7 @@
 # Object file has three R_MICROMIPS_26_S1 relocations
 # OBJ-REL: Relocations [
 # OBJ-REL-NEXT:   Section (2) .rel.text {
-# OBJ-REL-NEXT:      0x8 R_MICROMIPS_26_S1 .text 0x0
+# OBJ-REL-NEXT:      0x8 R_MICROMIPS_26_S1 loc 0x0
 # OBJ-REL-NEXT:     0x10 R_MICROMIPS_26_S1 glob  0x0
 # OBJ-REL-NEXT:     0x18 R_MICROMIPS_26_S1 T1  0x0
 # OBJ-REL-NEXT:   }
@@ -55,7 +55,7 @@
 # DIS-NEXT:   400182:  02 0f         move    $24, $2
 
 # DIS:      Contents of section .text:
-# DIS-NEXT:  400184 09f82003 00000000 12006106 00000000  .. .......a.....
+# DIS-NEXT:  400184 09f82003 00000000 2400ca0c 00000000  .. .....$.......
 # DIS-NEXT:  400194 2000c20c 00000000 2000bc0c 00000000   ....... .......
 
 # so.o
@@ -105,7 +105,7 @@ Sections:
     Info:            .text
     Relocations:
       - Offset:          0x08
-        Symbol:          .text
+        Symbol:          loc
         Type:            R_MICROMIPS_26_S1
       - Offset:          0x10
         Symbol:          glob





More information about the llvm-commits mailing list