Skip to content

Commit 96306bb

Browse files
committedNov 25, 2015
[ELF2][MIPS] Support R_MIPS_CALL16 relocation
R_MIPS_CALL16 relocation provides the same result as R_MIPS_GOT16 relocation but does not need to check the result on overflow. Differential Revision: http://reviews.llvm.org/D14916 llvm-svn: 254092
1 parent 49affb8 commit 96306bb

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed
 

‎lld/ELF/Target.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ class AArch64TargetInfo final : public TargetInfo {
116116
template <class ELFT> class MipsTargetInfo final : public TargetInfo {
117117
public:
118118
MipsTargetInfo();
119+
unsigned getGotRefReloc(unsigned Type) const override;
119120
void writeGotHeaderEntries(uint8_t *Buf) const override;
120121
void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
121122
void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
@@ -875,6 +876,11 @@ template <class ELFT> MipsTargetInfo<ELFT>::MipsTargetInfo() {
875876
GotHeaderEntriesNum = 2;
876877
}
877878

879+
template <class ELFT>
880+
unsigned MipsTargetInfo<ELFT>::getGotRefReloc(unsigned Type) const {
881+
return Type;
882+
}
883+
878884
template <class ELFT>
879885
void MipsTargetInfo<ELFT>::writeGotHeaderEntries(uint8_t *Buf) const {
880886
typedef typename llvm::object::ELFFile<ELFT>::Elf_Off Elf_Off;
@@ -895,7 +901,7 @@ void MipsTargetInfo<ELFT>::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
895901
template <class ELFT>
896902
bool MipsTargetInfo<ELFT>::relocNeedsGot(uint32_t Type,
897903
const SymbolBody &S) const {
898-
return Type == R_MIPS_GOT16;
904+
return Type == R_MIPS_GOT16 || Type == R_MIPS_CALL16;
899905
}
900906

901907
template <class ELFT>
@@ -913,9 +919,10 @@ void MipsTargetInfo<ELFT>::relocateOne(uint8_t *Loc, uint8_t *BufEnd,
913919
case R_MIPS_32:
914920
add32<E>(Loc, SA);
915921
break;
922+
case R_MIPS_CALL16:
916923
case R_MIPS_GOT16: {
917924
int64_t V = SA - getMipsGpAddr<ELFT>();
918-
if (!isInt<16>(V))
925+
if (Type == R_MIPS_GOT16 && !isInt<16>(V))
919926
error("Relocation R_MIPS_GOT16 out of range");
920927
write32<E>(Loc, (read32<E>(Loc) & 0xffff0000) | (V & 0xffff));
921928
break;

‎lld/test/ELF/mips-call16.s

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Check R_MIPS_CALL16 relocation calculation.
2+
3+
# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
4+
# RUN: ld.lld %t.o -shared -o %t.exe
5+
# RUN: llvm-objdump -d %t.exe | FileCheck %s
6+
# RUN: llvm-readobj -mips-plt-got -symbols %t.exe \
7+
# RUN: | FileCheck -check-prefix=GOT %s
8+
9+
# REQUIRES: mips
10+
11+
.text
12+
.globl __start
13+
__start:
14+
lw $t0,%call16(g1)($gp)
15+
16+
.globl g1
17+
.type g1,@function
18+
g1:
19+
nop
20+
21+
# CHECK: Disassembly of section .text:
22+
# CHECK-NEXT: __start:
23+
# CHECK-NEXT: 10000: 8f 88 80 18 lw $8, -32744
24+
25+
# GOT: Name: g1
26+
# GOT-NEXT: Value: 0x[[ADDR:[0-9A-F]+]]
27+
28+
# GOT: Local entries [
29+
# GOT-NEXT: ]
30+
# GOT-NEXT: Global entries [
31+
# GOT-NEXT: Entry {
32+
# GOT-NEXT: Address:
33+
# GOT-NEXT: Access: -32744
34+
# GOT-NEXT: Initial: 0x[[ADDR]]
35+
# GOT-NEXT: Value: 0x[[ADDR]]
36+
# GOT-NEXT: Type: Function
37+
# GOT-NEXT: Section: .text
38+
# GOT-NEXT: Name: g1
39+
# GOT-NEXT: }
40+
# GOT-NEXT: ]

0 commit comments

Comments
 (0)