Skip to content

Commit

Permalink
[ELF][MIPS] Support R_MIPS_PC32 relocation handling
Browse files Browse the repository at this point in the history
llvm-svn: 259782
  • Loading branch information
atanasyan committed Feb 4, 2016
1 parent 597df21 commit e364e2e
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 11 deletions.
25 changes: 15 additions & 10 deletions lld/ELF/Target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1437,16 +1437,17 @@ bool MipsTargetInfo<ELFT>::needsPlt(uint32_t Type, const SymbolBody &S) const {

static uint16_t mipsHigh(uint64_t V) { return (V + 0x8000) >> 16; }

template <endianness E, uint8_t BSIZE>
template <endianness E, uint8_t BSIZE, uint8_t SHIFT>
static void applyMipsPcReloc(uint8_t *Loc, uint32_t Type, uint64_t P,
uint64_t SA) {
uint32_t Mask = ~(0xffffffff << BSIZE);
uint32_t Mask = 0xffffffff >> (32 - BSIZE);
uint32_t Instr = read32<E>(Loc);
int64_t A = SignExtend64<BSIZE + 2>((Instr & Mask) << 2);
checkAlignment<4>(SA + A, Type);
int64_t A = SignExtend64<BSIZE + SHIFT>((Instr & Mask) << SHIFT);
if (SHIFT > 0)
checkAlignment<(1 << SHIFT)>(SA + A, Type);
int64_t V = SA + A - P;
checkInt<BSIZE + 2>(V, Type);
write32<E>(Loc, (Instr & ~Mask) | ((V >> 2) & Mask));
checkInt<BSIZE + SHIFT>(V, Type);
write32<E>(Loc, (Instr & ~Mask) | ((V >> SHIFT) & Mask));
}

template <class ELFT>
Expand Down Expand Up @@ -1498,16 +1499,19 @@ void MipsTargetInfo<ELFT>::relocateOne(uint8_t *Loc, uint8_t *BufEnd,
break;
}
case R_MIPS_PC16:
applyMipsPcReloc<E, 16>(Loc, Type, P, SA);
applyMipsPcReloc<E, 16, 2>(Loc, Type, P, SA);
break;
case R_MIPS_PC19_S2:
applyMipsPcReloc<E, 19>(Loc, Type, P, SA);
applyMipsPcReloc<E, 19, 2>(Loc, Type, P, SA);
break;
case R_MIPS_PC21_S2:
applyMipsPcReloc<E, 21>(Loc, Type, P, SA);
applyMipsPcReloc<E, 21, 2>(Loc, Type, P, SA);
break;
case R_MIPS_PC26_S2:
applyMipsPcReloc<E, 26>(Loc, Type, P, SA);
applyMipsPcReloc<E, 26, 2>(Loc, Type, P, SA);
break;
case R_MIPS_PC32:
applyMipsPcReloc<E, 32, 0>(Loc, Type, P, SA);
break;
case R_MIPS_PCHI16: {
uint32_t Instr = read32<E>(Loc);
Expand Down Expand Up @@ -1546,6 +1550,7 @@ bool MipsTargetInfo<ELFT>::isRelRelative(uint32_t Type) const {
case R_MIPS_PC19_S2:
case R_MIPS_PC21_S2:
case R_MIPS_PC26_S2:
case R_MIPS_PC32:
case R_MIPS_PCHI16:
case R_MIPS_PCLO16:
return true;
Expand Down
9 changes: 8 additions & 1 deletion lld/test/ELF/mips-pc-relocs.s
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
# RUN: -mcpu=mips32r6 %S/Inputs/mips-dynamic.s -o %t2.o
# RUN: ld.lld %t1.o %t2.o -o %t.exe
# RUN: llvm-objdump -mcpu=mips32r6 -d -t %t.exe | FileCheck %s
# RUN: llvm-objdump -mcpu=mips32r6 -d -t -s %t.exe | FileCheck %s

# REQUIRES: mips

Expand All @@ -19,6 +19,9 @@ __start:
aluipc $2, %pcrel_hi(_foo) # R_MIPS_PCHI16
addiu $2, $2, %pcrel_lo(_foo) # R_MIPS_PCLO16

.data
.word _foo+8-. # R_MIPS_PC32

# CHECK: Disassembly of section .text:
# CHECK-NEXT: __start:
# CHECK-NEXT: 20000: ec c8 00 08 lwpc $6, 32
Expand All @@ -34,5 +37,9 @@ __start:
# CHECK-NEXT: 20014: 24 42 00 0c addiu $2, $2, 12
# ^-- %lo(0x20020-0x20014)

# CHECK: Contents of section .data:
# CHECK-NEXT: 30000 ffff0028 00000000 00000000 00000000
# ^-- 0x20020 + 8 - 0x30000

# CHECK: 00020000 .text 00000000 __start
# CHECK: 00020020 .text 00000000 _foo

0 comments on commit e364e2e

Please sign in to comment.