[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