[lld] r242759 - [Mips] Handle R_MIPS_JALR relocation to omptimize jalr/jr instructions

Simon Atanasyan simon at atanasyan.com
Mon Jul 20 22:54:22 PDT 2015


Author: atanasyan
Date: Tue Jul 21 00:54:22 2015
New Revision: 242759

URL: http://llvm.org/viewvc/llvm-project?rev=242759&view=rev
Log:
[Mips] Handle R_MIPS_JALR relocation to omptimize jalr/jr instructions

Added:
    lld/trunk/test/elf/Mips/jalx-jalr.test
    lld/trunk/test/elf/Mips/rel-jalr-01.test
    lld/trunk/test/elf/Mips/rel-jalr-02.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp

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=242759&r1=242758&r2=242759&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp Tue Jul 21 00:54:22 2015
@@ -21,7 +21,8 @@ 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
+  ToMicro,   // cross isa jump to microMips symbol
+  ToMicroJalr// cross isa jump to microMips symbol referenced by R_MIPS_JALR
 };
 
 typedef std::function<std::error_code(int64_t, bool)> OverflowChecker;
@@ -178,7 +179,7 @@ static MipsRelocationParams getRelocatio
   case R_MICROMIPS_GOT_OFST:
     return {4, 0xffff, 0, true, signedCheck<16>};
   case R_MIPS_JALR:
-    return {4, 0x0, 0, false, dummyCheck};
+    return {4, 0xffffffff, 0, false, dummyCheck};
   case R_MICROMIPS_JALR:
     return {4, 0x0, 0, true, dummyCheck};
   case R_MIPS_JUMP_SLOT:
@@ -200,6 +201,10 @@ static MipsRelocationParams getRelocatio
   }
 }
 
+template <class ELFT>
+static uint64_t relocRead(const MipsRelocationParams &params,
+                          const uint8_t *loc);
+
 static int64_t getHi16(int64_t value) {
   return ((value + 0x8000) >> 16) & 0xffff;
 }
@@ -299,6 +304,22 @@ static ErrorOr<int64_t> relocPc26(uint64
   return S + A - P;
 }
 
+template <class ELFT>
+static ErrorOr<int64_t> relocJalr(uint64_t P, uint64_t S, bool isCrossJump,
+                                  uint8_t *location) {
+  uint64_t ins = relocRead<ELFT>(getRelocationParams(R_MIPS_JALR), location);
+  if (isCrossJump)
+    return ins;
+  int64_t off = S - P - 4;
+  if (!llvm::isInt<18>(off))
+    return ins;
+  if (ins == 0x0320f809) // jalr t9
+    return 0x04110000 | ((off >> 2) & 0xffff);
+  if (ins == 0x03200008) // jr t9
+    return 0x10000000 | ((off >> 2) & 0xffff);
+  return ins;
+}
+
 static int64_t relocRel32(int64_t A) {
   // If output relocation format is REL and the input one is RELA, the only
   // method to transfer the relocation addend from the input relocation
@@ -309,7 +330,7 @@ static int64_t relocRel32(int64_t A) {
 
 static std::error_code adjustJumpOpCode(uint64_t &ins, uint64_t tgt,
                                         CrossJumpMode mode) {
-  if (mode == CrossJumpMode::None)
+  if (mode == CrossJumpMode::None || mode == CrossJumpMode::ToMicroJalr)
     return std::error_code();
 
   bool toMicro = mode == CrossJumpMode::ToMicro;
@@ -345,6 +366,8 @@ static CrossJumpMode getCrossJumpMode(co
     return CrossJumpMode::None;
   bool isTgtMicro = isMicroMipsAtom(ref.target());
   switch (ref.kindValue()) {
+  case R_MIPS_JALR:
+    return isTgtMicro ? CrossJumpMode::ToMicroJalr : CrossJumpMode::None;
   case R_MIPS_26:
   case LLD_R_MIPS_GLOBAL_26:
     return isTgtMicro ? CrossJumpMode::ToMicro : CrossJumpMode::None;
@@ -356,11 +379,12 @@ static CrossJumpMode getCrossJumpMode(co
   }
 }
 
-static ErrorOr<int64_t> calculateRelocation(Reference::KindValue kind,
-                                            Reference::Addend addend,
-                                            uint64_t tgtAddr, uint64_t relAddr,
-                                            uint64_t gpAddr, bool isGP,
-                                            bool isCrossJump, bool isDynamic) {
+template <class ELFT>
+static ErrorOr<int64_t>
+calculateRelocation(Reference::KindValue kind, Reference::Addend addend,
+                    uint64_t tgtAddr, uint64_t relAddr, uint64_t gpAddr,
+                    bool isGP, bool isCrossJump, bool isDynamic,
+                    uint8_t *location) {
   switch (kind) {
   case R_MIPS_NONE:
     return 0;
@@ -461,6 +485,7 @@ static ErrorOr<int64_t> calculateRelocat
   case R_MICROMIPS_LITERAL:
     return tgtAddr + addend - gpAddr;
   case R_MIPS_JALR:
+    return relocJalr<ELFT>(relAddr, tgtAddr, isCrossJump, location);
   case R_MICROMIPS_JALR:
     // We do not do JALR optimization now.
     return 0;
@@ -591,8 +616,8 @@ std::error_code RelocationHandler<ELFT>:
     if (kind == R_MIPS_NONE)
       break;
     auto params = getRelocationParams(kind);
-    res = calculateRelocation(kind, *res, sym, relAddr, gpAddr, isGpDisp,
-                              isCrossJump, _ctx.isDynamic());
+    res = calculateRelocation<ELFT>(kind, *res, sym, relAddr, gpAddr, isGpDisp,
+                                    isCrossJump, _ctx.isDynamic(), location);
     if (auto ec = res.getError())
       return ec;
     // Check result for the last relocation only.

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp?rev=242759&r1=242758&r2=242759&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp Tue Jul 21 00:54:22 2015
@@ -771,6 +771,10 @@ void RelocationPass<ELFT>::handleReferen
     ref.setTarget(getTLSGOTEntry(ref.target(), ref.addend()));
   else if (kind == R_MIPS_GPREL32 || (isLocal(ref.target()) && isGpRelReloc(kind)))
     ref.setAddend(ref.addend() + atom.file().getGP0());
+  else if (kind == R_MIPS_JALR) {
+    if (_ctx.getOutputELFType() != ET_EXEC || !isLocalCall(ref.target()))
+      ref.setKindValue(R_MIPS_NONE);
+  }
 }
 
 template <typename ELFT>

Added: lld/trunk/test/elf/Mips/jalx-jalr.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/jalx-jalr.test?rev=242759&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/jalx-jalr.test (added)
+++ lld/trunk/test/elf/Mips/jalx-jalr.test Tue Jul 21 00:54:22 2015
@@ -0,0 +1,47 @@
+# Check that R_MIPS_JALR relocation does not affect code in case of cross jump.
+
+# RUN: yaml2obj -format=elf %s > %t.o
+# RUN: lld -flavor gnu -target mipsel -o %t.exe %t.o
+# RUN: llvm-objdump -s %t.exe | FileCheck %s
+
+# CHECK:      Contents of section .text:
+# CHECK-NEXT:  {{[0-9a-f]+}} 08002003 00000000
+
+FileHeader:
+  Class:    ELFCLASS32
+  Data:     ELFDATA2LSB
+  Type:     ET_REL
+  Machine:  EM_MIPS
+  Flags:    [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32,
+             EF_MIPS_MICROMIPS, EF_MIPS_ARCH_32R2]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  16
+    Content:       "0800200300000000"
+
+  - Name:          .rel.text
+    Type:          SHT_REL
+    Link:          .symtab
+    AddressAlign:  4
+    Info:          .text
+    Relocations:
+      - Offset:  0
+        Symbol:  M1
+        Type:    R_MIPS_JALR
+
+Symbols:
+  Global:
+    - Name:     __start
+      Type:     STT_FUNC
+      Section:  .text
+      Value:    0
+      Size:     4
+    - Name:     M1
+      Type:     STT_FUNC
+      Section:  .text
+      Value:    4
+      Size:     4
+      Other:    [ STO_MIPS_MICROMIPS ]

Added: lld/trunk/test/elf/Mips/rel-jalr-01.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/rel-jalr-01.test?rev=242759&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/rel-jalr-01.test (added)
+++ lld/trunk/test/elf/Mips/rel-jalr-01.test Tue Jul 21 00:54:22 2015
@@ -0,0 +1,101 @@
+# REQUIRES: mips
+
+# Check handling of the R_MIPS_JALR relocation.
+
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t1.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t1.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t2.o
+# RUN: lld -flavor gnu -target mipsel -o %t.exe %t2.o %t.so
+# RUN: llvm-objdump -d %t.exe | FileCheck %s
+
+# CHECK:      __start:
+# CHECK-NEXT:   {{[0-9a-f]+}}:   05 00 11 04   bal   24
+# CHECK-NEXT:   {{[0-9a-f]+}}:   00 00 00 00   nop
+# CHECK-NEXT:   {{[0-9a-f]+}}:   04 00 00 10   b     20
+# CHECK-NEXT:   {{[0-9a-f]+}}:   00 00 00 00   nop
+# CHECK-NEXT:   {{[0-9a-f]+}}:   09 f8 20 03   jalr  $25
+# CHECK-NEXT:   {{[0-9a-f]+}}:   00 00 00 00   nop
+
+# t1.o
+---
+FileHeader:
+  Class:    ELFCLASS32
+  Data:     ELFDATA2LSB
+  Type:     ET_REL
+  Machine:  EM_MIPS
+  Flags:    [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  16
+    Size:          4
+
+Symbols:
+  Global:
+    - Name:     T3
+      Type:     STT_FUNC
+      Section:  .text
+      Value:    0
+      Size:     4
+
+# t2.o
+---
+FileHeader:
+  Class:    ELFCLASS32
+  Data:     ELFDATA2LSB
+  Type:     ET_REL
+  Machine:  EM_MIPS
+  Flags:    [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  16
+    Content:       "09f8200300000000080020030000000009f82003000000000000000000000000"
+#                   ^ jalr T1       ^ j T2          ^ jalr T3
+
+  - Name:          .rel.text
+    Type:          SHT_REL
+    Link:          .symtab
+    AddressAlign:  4
+    Info:          .text
+    Relocations:
+      - Offset:  0
+        Symbol:  T1
+        Type:    R_MIPS_JALR
+      - Offset:  8
+        Symbol:  T2
+        Type:    R_MIPS_JALR
+      - Offset:  16
+        Symbol:  T3
+        Type:    R_MIPS_JALR
+
+  - Name:          .data
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:  16
+    Size:          0
+
+Symbols:
+  Local:
+    - Name:     T1
+      Type:     STT_FUNC
+      Section:  .text
+      Value:    24
+      Size:     4
+  Global:
+    - Name:     __start
+      Type:     STT_FUNC
+      Section:  .text
+      Value:    0
+      Size:     24
+    - Name:     T2
+      Type:     STT_FUNC
+      Section:  .text
+      Value:    28
+      Size:     4
+    - Name:     T3
+...

Added: lld/trunk/test/elf/Mips/rel-jalr-02.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/rel-jalr-02.test?rev=242759&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/rel-jalr-02.test (added)
+++ lld/trunk/test/elf/Mips/rel-jalr-02.test Tue Jul 21 00:54:22 2015
@@ -0,0 +1,68 @@
+# REQUIRES: mips
+
+# Check R_MIPS_JALR relocations do not affect the code
+# in case of relocatable targets.
+
+# RUN: yaml2obj -format=elf %s > %t.o
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t.o
+# RUN: llvm-objdump -d %t.so | FileCheck %s
+
+# CHECK:      __start:
+# CHECK-NEXT:   {{[0-9a-f]+}}:   09 f8 20 03   jalr  $25
+# CHECK-NEXT:   {{[0-9a-f]+}}:   00 00 00 00   nop
+# CHECK-NEXT:   {{[0-9a-f]+}}:   08 00 20 03   jr    $25
+# CHECK-NEXT:   {{[0-9a-f]+}}:   00 00 00 00   nop
+
+---
+FileHeader:
+  Class:    ELFCLASS32
+  Data:     ELFDATA2LSB
+  Type:     ET_REL
+  Machine:  EM_MIPS
+  Flags:    [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  16
+    Content:       "09f820030000000008002003000000000000000000000000"
+#                   ^ jalr          ^ jr            ^ T1    ^ T2
+
+  - Name:          .rel.text
+    Type:          SHT_REL
+    Link:          .symtab
+    AddressAlign:  4
+    Info:          .text
+    Relocations:
+      - Offset:  0
+        Symbol:  T1
+        Type:    R_MIPS_JALR
+      - Offset:  8
+        Symbol:  T2
+        Type:    R_MIPS_JALR
+
+  - Name:          .data
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:  16
+    Size:          0
+
+Symbols:
+  Global:
+    - Name:     __start
+      Type:     STT_FUNC
+      Section:  .text
+      Value:    0
+      Size:     16
+    - Name:     T1
+      Type:     STT_FUNC
+      Section:  .text
+      Value:    16
+      Size:     4
+    - Name:     T2
+      Type:     STT_FUNC
+      Section:  .text
+      Value:    20
+      Size:     4
+...





More information about the llvm-commits mailing list