diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index 2418644cf04d..a955657d5530 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -1646,6 +1646,12 @@ static void writeMipsHi16(uint8_t *Loc, uint64_t V) { write32(Loc, (Instr & 0xffff0000) | mipsHigh(V)); } +template +static int64_t readMipsAHL(uint8_t *HiLoc, uint8_t *LoLoc) { + return ((read32(HiLoc) & 0xffff) << 16) + + SignExtend64<16>(read32(LoLoc) & 0xffff); +} + template void MipsTargetInfo::writePltZero(uint8_t *Buf) const { const endianness E = ELFT::TargetEndianness; @@ -1734,18 +1740,14 @@ void MipsTargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, case R_MIPS_GPREL32: write32(Loc, S + int32_t(read32(Loc)) - getMipsGpAddr()); break; - case R_MIPS_HI16: { - uint32_t Instr = read32(Loc); - if (PairedLoc) { - uint64_t AHL = ((Instr & 0xffff) << 16) + - SignExtend64<16>(read32(PairedLoc) & 0xffff); - writeMipsHi16(Loc, S + AHL); - } else { + case R_MIPS_HI16: + if (PairedLoc) + writeMipsHi16(Loc, S + readMipsAHL(Loc, PairedLoc)); + else { warning("Can't find matching R_MIPS_LO16 relocation for R_MIPS_HI16"); writeMipsHi16(Loc, S); } break; - } case R_MIPS_JALR: // Ignore this optimization relocation for now break; @@ -1770,17 +1772,14 @@ void MipsTargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, case R_MIPS_PC32: applyMipsPcReloc(Loc, Type, P, S); break; - case R_MIPS_PCHI16: { - if (PairedLoc) { - uint64_t AHL = ((read32(Loc) & 0xffff) << 16) + - SignExtend64<16>(read32(PairedLoc) & 0xffff); - writeMipsHi16(Loc, S + AHL - P); - } else { + case R_MIPS_PCHI16: + if (PairedLoc) + writeMipsHi16(Loc, S + readMipsAHL(Loc, PairedLoc) - P); + else { warning("Can't find matching R_MIPS_PCLO16 relocation for R_MIPS_PCHI16"); writeMipsHi16(Loc, S - P); } break; - } case R_MIPS_PCLO16: { uint32_t Instr = read32(Loc); int64_t AHL = SignExtend64<16>(Instr & 0xffff);