forked from OSchip/llvm-project
[Mips] Handle R_MIPS_JALR relocation to omptimize jalr/jr instructions
llvm-svn: 242759
This commit is contained in:
parent
61459cef40
commit
f9db71eaec
|
|
@ -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 getRelocationParams(uint32_t rType) {
|
|||
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 getRelocationParams(uint32_t rType) {
|
|||
}
|
||||
}
|
||||
|
||||
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_t P, uint64_t S, int64_t A) {
|
|||
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(const Reference &ref) {
|
|||
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(const Reference &ref) {
|
|||
}
|
||||
}
|
||||
|
||||
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> calculateRelocation(Reference::KindValue kind,
|
|||
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>::applyRelocation(
|
|||
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.
|
||||
|
|
|
|||
|
|
@ -771,6 +771,10 @@ void RelocationPass<ELFT>::handleReference(const MipsELFDefinedAtom<ELFT> &atom,
|
|||
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>
|
||||
|
|
|
|||
|
|
@ -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 ]
|
||||
|
|
@ -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
|
||||
...
|
||||
|
|
@ -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
|
||||
...
|
||||
Loading…
Reference in New Issue