diff options
-rw-r--r-- | lld/ELF/Target.cpp | 33 |
1 files changed, 16 insertions, 17 deletions
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index a955657d553..97fb676edcc 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -1647,6 +1647,12 @@ static void writeMipsHi16(uint8_t *Loc, uint64_t V) { } template <endianness E> +static void writeMipsLo16(uint8_t *Loc, uint64_t V) { + uint32_t Instr = read32<E>(Loc); + write32<E>(Loc, (Instr & 0xffff0000) | (V & 0xffff)); +} + +template <endianness E> static int64_t readMipsAHL(uint8_t *HiLoc, uint8_t *LoLoc) { return ((read32<E>(HiLoc) & 0xffff) << 16) + SignExtend64<16>(read32<E>(LoLoc) & 0xffff); @@ -1664,10 +1670,9 @@ void MipsTargetInfo<ELFT>::writePltZero(uint8_t *Buf) const { write32<E>(Buf + 24, 0x0320f809); // jalr $25 write32<E>(Buf + 28, 0x2718fffe); // subu $24, $24, 2 uint64_t Got = Out<ELFT>::GotPlt->getVA(); - uint64_t Plt = Out<ELFT>::Plt->getVA(); writeMipsHi16<E>(Buf, Got); - relocateOne(Buf + 4, Buf + 8, R_MIPS_LO16, Plt + 4, Got); - relocateOne(Buf + 8, Buf + 12, R_MIPS_LO16, Plt + 8, Got); + writeMipsLo16<E>(Buf + 4, Got); + writeMipsLo16<E>(Buf + 8, Got); } template <class ELFT> @@ -1680,8 +1685,8 @@ void MipsTargetInfo<ELFT>::writePlt(uint8_t *Buf, uint64_t GotEntryAddr, write32<E>(Buf + 8, 0x03200008); // jr $25 write32<E>(Buf + 12, 0x25f80000); // addiu $24, $15, %lo(.got.plt entry) writeMipsHi16<E>(Buf, GotEntryAddr); - relocateOne(Buf + 4, Buf + 8, R_MIPS_LO16, PltEntryAddr + 4, GotEntryAddr); - relocateOne(Buf + 12, Buf + 16, R_MIPS_LO16, PltEntryAddr + 8, GotEntryAddr); + writeMipsLo16<E>(Buf + 4, GotEntryAddr); + writeMipsLo16<E>(Buf + 12, GotEntryAddr); } template <class ELFT> @@ -1727,14 +1732,14 @@ void MipsTargetInfo<ELFT>::relocateOne(uint8_t *Loc, uint8_t *BufEnd, int64_t V = S - getMipsGpAddr<ELFT>(); if (Type == R_MIPS_GOT16) checkInt<16>(V, Type); - write32<E>(Loc, (read32<E>(Loc) & 0xffff0000) | (V & 0xffff)); + writeMipsLo16<E>(Loc, V); break; } case R_MIPS_GPREL16: { uint32_t Instr = read32<E>(Loc); int64_t V = S + SignExtend64<16>(Instr & 0xffff) - getMipsGpAddr<ELFT>(); checkInt<16>(V, Type); - write32<E>(Loc, (Instr & 0xffff0000) | (V & 0xffff)); + writeMipsLo16<E>(Loc, V); break; } case R_MIPS_GPREL32: @@ -1751,12 +1756,9 @@ void MipsTargetInfo<ELFT>::relocateOne(uint8_t *Loc, uint8_t *BufEnd, case R_MIPS_JALR: // Ignore this optimization relocation for now break; - case R_MIPS_LO16: { - uint32_t Instr = read32<E>(Loc); - int64_t AHL = SignExtend64<16>(Instr & 0xffff); - write32<E>(Loc, (Instr & 0xffff0000) | ((S + AHL) & 0xffff)); + case R_MIPS_LO16: + writeMipsLo16<E>(Loc, S + SignExtend64<16>(read32<E>(Loc) & 0xffff)); break; - } case R_MIPS_PC16: applyMipsPcReloc<E, 16, 2>(Loc, Type, P, S); break; @@ -1780,12 +1782,9 @@ void MipsTargetInfo<ELFT>::relocateOne(uint8_t *Loc, uint8_t *BufEnd, writeMipsHi16<E>(Loc, S - P); } break; - case R_MIPS_PCLO16: { - uint32_t Instr = read32<E>(Loc); - int64_t AHL = SignExtend64<16>(Instr & 0xffff); - write32<E>(Loc, (Instr & 0xffff0000) | ((S + AHL - P) & 0xffff)); + case R_MIPS_PCLO16: + writeMipsLo16<E>(Loc, S + SignExtend64<16>(read32<E>(Loc) & 0xffff) - P); break; - } default: fatal("unrecognized reloc " + Twine(Type)); } |