From e5532a12f7473ec9f3b32fdfb41728790fd9bab7 Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Wed, 31 Aug 2016 11:47:21 +0000 Subject: [PATCH] [ELF][MIPS] Support R_MIPS_HIGHER / R_MIPS_HIGHEST relocations calculation llvm-svn: 280223 --- lld/ELF/Target.cpp | 20 ++++++++++++++++++++ lld/test/ELF/mips-higher-highest.s | 21 +++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 lld/test/ELF/mips-higher-highest.s diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index f18789a..3f97079 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -1967,6 +1967,20 @@ static void writeMipsHi16(uint8_t *Loc, uint64_t V) { } template +static void writeMipsHigher(uint8_t *Loc, uint64_t V) { + uint32_t Instr = read32(Loc); + uint16_t Res = ((V + 0x80008000) >> 32) & 0xffff; + write32(Loc, (Instr & 0xffff0000) | Res); +} + +template +static void writeMipsHighest(uint8_t *Loc, uint64_t V) { + uint32_t Instr = read32(Loc); + uint16_t Res = ((V + 0x800080008000) >> 48) & 0xffff; + write32(Loc, (Instr & 0xffff0000) | Res); +} + +template static void writeMipsLo16(uint8_t *Loc, uint64_t V) { uint32_t Instr = read32(Loc); write32(Loc, (Instr & 0xffff0000) | (V & 0xffff)); @@ -2150,6 +2164,12 @@ void MipsTargetInfo::relocateOne(uint8_t *Loc, uint32_t Type, case R_MIPS_TLS_TPREL_HI16: writeMipsHi16(Loc, Val); break; + case R_MIPS_HIGHER: + writeMipsHigher(Loc, Val); + break; + case R_MIPS_HIGHEST: + writeMipsHighest(Loc, Val); + break; case R_MIPS_JALR: // Ignore this optimization relocation for now break; diff --git a/lld/test/ELF/mips-higher-highest.s b/lld/test/ELF/mips-higher-highest.s new file mode 100644 index 0000000..123b51a --- /dev/null +++ b/lld/test/ELF/mips-higher-highest.s @@ -0,0 +1,21 @@ +# Check R_MIPS_HIGHER / R_MIPS_HIGHEST relocations calculation. + +# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \ +# RUN: %S/Inputs/mips-dynamic.s -o %t2.o +# RUN: ld.lld %t1.o %t2.o -o %t.exe +# RUN: llvm-objdump -d %t.exe | FileCheck %s + +# REQUIRES: mips + + .global __start +__start: + lui $6, %highest(_foo+0x300047FFF7FF7) + daddiu $6, $6, %higher(_foo+0x300047FFF7FF7) + lui $7, %highest(_foo+0x300047FFF7FF8) + ld $7, %higher (_foo+0x300047FFF7FF8)($7) + +# CHECK: 20000: 3c 06 00 03 lui $6, 3 +# CHECK-NEXT: 20004: 64 c6 00 05 daddiu $6, $6, 5 +# CHECK-NEXT: 20008: 3c 07 00 03 lui $7, 3 +# CHECK-NEXT: 2000c: dc e7 00 05 ld $7, 5($7) -- 2.7.4