Index: ELF/InputSection.h =================================================================== --- ELF/InputSection.h +++ ELF/InputSection.h @@ -81,7 +81,7 @@ private: template - uint8_t *findMipsPairedReloc(uint8_t *Buf, const RelTy *Rel, + int16_t findMipsPairedAddend(uint8_t *Buf, SymbolBody &Sym, const RelTy *Rel, const RelTy *End); }; Index: ELF/InputSection.cpp =================================================================== --- ELF/InputSection.cpp +++ ELF/InputSection.cpp @@ -143,13 +143,17 @@ } } +template static int16_t readSignedLo16(uint8_t *Loc) { + return read32(Loc) & 0xffff; +} + template template -uint8_t *InputSectionBase::findMipsPairedReloc(uint8_t *Buf, +int16_t InputSectionBase::findMipsPairedAddend(uint8_t *Buf, + SymbolBody &Sym, const RelTy *Rel, const RelTy *End) { uint32_t SymIndex = Rel->getSymbol(Config->Mips64EL); - SymbolBody &Sym = File->getSymbolBody(SymIndex).repl(); uint32_t Type = getMipsPairType(Rel, Sym); // Some MIPS relocations use addend calculated from addend of the relocation @@ -157,7 +161,7 @@ // combined addend in case of REL relocation record format only. // See p. 4-17 at ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf if (RelTy::IsRela || Type == R_MIPS_NONE) - return nullptr; + return 0; for (const RelTy *RI = Rel; RI != End; ++RI) { if (RI->getType(Config->Mips64EL) != Type) @@ -166,10 +170,14 @@ continue; uintX_t Offset = getOffset(RI->r_offset); if (Offset == (uintX_t)-1) - return nullptr; - return Buf + Offset; + break; + return readSignedLo16(Buf + Offset); } - return nullptr; + unsigned OldType = Rel->getType(Config->Mips64EL); + StringRef OldName = getELFRelocationTypeName(Config->EMachine, OldType); + StringRef NewName = getELFRelocationTypeName(Config->EMachine, Type); + warning("can't find matching " + NewName + " relocation for " + OldName); + return 0; } template @@ -192,7 +200,7 @@ template static uintX_t getMipsGotVA(const SymbolBody &Body, uintX_t SymVA, - uint8_t *BufLoc, uint8_t *PairedLoc) { + uint8_t *BufLoc, int16_t PairedAddend) { if (Body.isLocal()) { // If relocation against MIPS local symbol requires GOT entry, this entry // should be initialized by 'page address'. This address is high 16-bits @@ -200,9 +208,7 @@ // calculated using addends from R_MIPS_GOT16 and paired R_MIPS_LO16 // relocations. const endianness E = ELFT::TargetEndianness; - uint64_t AHL = read32(BufLoc) << 16; - if (PairedLoc) - AHL += SignExtend64<16>(read32(PairedLoc)); + uint64_t AHL = (read32(BufLoc) << 16) + PairedAddend; return Out::Got->getMipsLocalPageAddr(SymVA + AHL); } if (!Body.isPreemptible()) @@ -270,15 +276,15 @@ } uintX_t SymVA = Body.getVA(A); - uint8_t *PairedLoc = nullptr; + int16_t PairedAddend = 0; if (Config->EMachine == EM_MIPS) - PairedLoc = findMipsPairedReloc(Buf, &RI, Rels.end()); + PairedAddend = findMipsPairedAddend(Buf, Body, &RI, Rels.end()); if (Target->needsPlt(Type, Body)) { SymVA = Body.getPltVA() + A; } else if (Target->needsGot(Type, Body)) { if (Config->EMachine == EM_MIPS) - SymVA = getMipsGotVA(Body, SymVA, BufLoc, PairedLoc) + A; + SymVA = getMipsGotVA(Body, SymVA, BufLoc, PairedAddend) + A; else SymVA = Body.getGotVA() + A; if (Body.IsTls) @@ -297,7 +303,7 @@ } uintX_t Size = Body.getSize(); Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA, Size + A, - PairedLoc); + PairedAddend); } } Index: ELF/Target.h =================================================================== --- ELF/Target.h +++ ELF/Target.h @@ -63,7 +63,7 @@ virtual void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, uint64_t SA, uint64_t ZA = 0, - uint8_t *PairedLoc = nullptr) const = 0; + int16_t PairedAddend = 0) const = 0; virtual bool isGotRelative(uint32_t Type) const; bool canRelaxTls(uint32_t Type, const SymbolBody *S) const; template Index: ELF/Target.cpp =================================================================== --- ELF/Target.cpp +++ ELF/Target.cpp @@ -92,7 +92,7 @@ bool needsPltImpl(uint32_t Type) const override; void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, uint64_t SA, uint64_t ZA = 0, - uint8_t *PairedLoc = nullptr) const override; + int16_t PairedAddend = 0) const override; size_t relaxTlsGdToIe(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, uint64_t SA) const override; @@ -127,7 +127,7 @@ bool needsPltImpl(uint32_t Type) const override; void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, uint64_t SA, uint64_t ZA = 0, - uint8_t *PairedLoc = nullptr) const override; + int16_t PairedAddend = 0) const override; bool isRelRelative(uint32_t Type) const override; bool isSizeRel(uint32_t Type) const override; @@ -145,8 +145,8 @@ public: PPCTargetInfo(); void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, - uint64_t SA, uint64_t ZA = 0, - uint8_t *PairedLoc = nullptr) const override; + uint64_t SA, uint64_t ZA, + int16_t PairedAddend) const override; bool isRelRelative(uint32_t Type) const override; }; @@ -158,8 +158,8 @@ bool needsGot(uint32_t Type, SymbolBody &S) const override; bool needsPltImpl(uint32_t Type) const override; void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, - uint64_t SA, uint64_t ZA = 0, - uint8_t *PairedLoc = nullptr) const override; + uint64_t SA, uint64_t ZA, + int16_t PairedAddend) const override; bool isRelRelative(uint32_t Type) const override; }; @@ -180,8 +180,7 @@ bool needsPltImpl(uint32_t Type) const override; void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, uint64_t SA, uint64_t ZA = 0, - uint8_t *PairedLoc = nullptr) const override; - + int16_t PairedAddend = 0) const override; size_t relaxTlsGdToLe(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, uint64_t SA) const override; size_t relaxTlsIeToLe(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, @@ -195,8 +194,8 @@ public: AMDGPUTargetInfo() {} void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, - uint64_t SA, uint64_t ZA = 0, - uint8_t *PairedLoc = nullptr) const override; + uint64_t SA, uint64_t ZA, + int16_t PairedAddend) const override; }; template class MipsTargetInfo final : public TargetInfo { @@ -212,8 +211,8 @@ bool needsGot(uint32_t Type, SymbolBody &S) const override; bool needsPltImpl(uint32_t Type) const override; void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, - uint64_t S, uint64_t ZA = 0, - uint8_t *PairedLoc = nullptr) const override; + uint64_t SA, uint64_t ZA, + int16_t PairedAddend) const override; bool isHintRel(uint32_t Type) const override; bool isRelRelative(uint32_t Type) const override; bool refersToGotEntry(uint32_t Type) const override; @@ -519,7 +518,7 @@ void X86TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, uint64_t SA, uint64_t ZA, - uint8_t *PairedLoc) const { + int16_t PairedAddend) const { switch (Type) { case R_386_32: add32le(Loc, SA); @@ -936,7 +935,7 @@ void X86_64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, uint64_t SA, uint64_t ZA, - uint8_t *PairedLoc) const { + int16_t PairedAddend) const { switch (Type) { case R_X86_64_32: checkUInt<32>(SA, Type); @@ -996,7 +995,7 @@ void PPCTargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, uint64_t SA, uint64_t ZA, - uint8_t *PairedLoc) const { + int16_t PairedAddend) const { switch (Type) { case R_PPC_ADDR16_HA: write16be(Loc, applyPPCHa(SA)); @@ -1100,7 +1099,7 @@ void PPC64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, uint64_t SA, uint64_t ZA, - uint8_t *PairedLoc) const { + int16_t PairedAddend) const { uint64_t TB = getPPC64TocBase(); // For a TOC-relative relocation, adjust the addend and proceed in terms of @@ -1391,7 +1390,7 @@ void AArch64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, uint64_t SA, - uint64_t ZA, uint8_t *PairedLoc) const { + uint64_t ZA, int16_t PairedAddend) const { switch (Type) { case R_AARCH64_ABS16: checkIntUInt<16>(SA, Type); @@ -1567,7 +1566,7 @@ // That's why the AMDGPU port works without implementing this function. void AMDGPUTargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, uint64_t SA, uint64_t ZA, - uint8_t *PairedLoc) const { + int16_t PairedAddend) const { llvm_unreachable("not implemented"); } @@ -1654,8 +1653,8 @@ } template -static int64_t readMipsAHL(uint8_t *HiLoc, uint8_t *LoLoc) { - return ((read32(HiLoc) & 0xffff) << 16) + readSignedLo16(LoLoc); +static int64_t readMipsAHL(uint8_t *HiLoc, int16_t PairedAddend) { + return ((read32(HiLoc) & 0xffff) << 16) + PairedAddend; } template @@ -1712,7 +1711,8 @@ template void MipsTargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, uint64_t S, - uint64_t ZA, uint8_t *PairedLoc) const { + uint64_t ZA, + int16_t PairedAddend) const { const endianness E = ELFT::TargetEndianness; // Thread pointer and DRP offsets from the start of TLS data area. // https://www.linux-mips.org/wiki/NPTL @@ -1749,12 +1749,7 @@ write32(Loc, S + int32_t(read32(Loc)) - getMipsGpAddr()); break; 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); - } + writeMipsHi16(Loc, S + readMipsAHL(Loc, PairedAddend)); break; case R_MIPS_JALR: // Ignore this optimization relocation for now @@ -1778,12 +1773,7 @@ applyMipsPcReloc(Loc, Type, P, S); break; 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); - } + writeMipsHi16(Loc, S + readMipsAHL(Loc, PairedAddend) - P); break; case R_MIPS_PCLO16: writeMipsLo16(Loc, S + readSignedLo16(Loc) - P); Index: test/ELF/mips-hilo-hi-only.s =================================================================== --- test/ELF/mips-hilo-hi-only.s +++ test/ELF/mips-hilo-hi-only.s @@ -18,8 +18,8 @@ # CHECK: Disassembly of section .text: # CHECK-NEXT: __start: -# CHECK-NEXT: 20000: 3c 08 00 02 lui $8, 2 -# ^-- %hi(__start) w/o addend +# CHECK-NEXT: 20000: 3c 08 00 03 lui $8, 3 +# ^-- %hi(__start+0x10000) # CHECK-NEXT 20004: 21 08 00 08 addi $8, $8, 8 # ^-- %lo(_label)