[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 ¶ms,
+ 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