}
}
+template <endianness E> static int16_t readSignedLo16(uint8_t *Loc) {
+ return read32<E>(Loc) & 0xffff;
+}
+
template <class ELFT>
template <class RelTy>
-uint8_t *InputSectionBase<ELFT>::findMipsPairedReloc(uint8_t *Buf,
- const RelTy *Rel,
- const RelTy *End) {
+int32_t
+InputSectionBase<ELFT>::findMipsPairedAddend(uint8_t *Buf, uint8_t *BufLoc,
+ 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
// 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)
continue;
uintX_t Offset = getOffset(RI->r_offset);
if (Offset == (uintX_t)-1)
- return nullptr;
- return Buf + Offset;
+ break;
+ const endianness E = ELFT::TargetEndianness;
+ return ((read32<E>(BufLoc) & 0xffff) << 16) +
+ readSignedLo16<E>(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 <class ELFT, class uintX_t>
template <class ELFT, class uintX_t>
static uintX_t getMipsGotVA(const SymbolBody &Body, uintX_t SymVA,
- uint8_t *BufLoc, uint8_t *PairedLoc) {
- if (Body.isLocal()) {
+ uint8_t *BufLoc, uint64_t AHL) {
+ 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
// of sum the symbol's value and the addend. The addend in that case is
// calculated using addends from R_MIPS_GOT16 and paired R_MIPS_LO16
// relocations.
- const endianness E = ELFT::TargetEndianness;
- uint64_t AHL = read32<E>(BufLoc) << 16;
- if (PairedLoc)
- AHL += SignExtend64<16>(read32<E>(PairedLoc));
return Out<ELFT>::Got->getMipsLocalPageAddr(SymVA + AHL);
- }
if (!Body.isPreemptible())
// For non-local symbols GOT entries should contain their full
// addresses. But if such symbol cannot be preempted, we do not
}
uintX_t SymVA = Body.getVA<ELFT>(A);
- uint8_t *PairedLoc = nullptr;
if (Config->EMachine == EM_MIPS)
- PairedLoc = findMipsPairedReloc(Buf, &RI, Rels.end());
+ A += findMipsPairedAddend(Buf, BufLoc, Body, &RI, Rels.end());
if (Target->needsPlt(Type, Body)) {
SymVA = Body.getPltVA<ELFT>() + A;
} else if (Target->needsGot(Type, Body)) {
if (Config->EMachine == EM_MIPS)
- SymVA = getMipsGotVA<ELFT>(Body, SymVA, BufLoc, PairedLoc) + A;
+ SymVA = getMipsGotVA<ELFT>(Body, SymVA, BufLoc, A);
else
SymVA = Body.getGotVA<ELFT>() + A;
if (Body.IsTls)
continue;
}
uintX_t Size = Body.getSize<ELFT>();
- Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA, Size + A,
- PairedLoc);
+ Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA, Size + A);
}
}
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 = 0) const override;
size_t relaxTlsGdToIe(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
uint64_t P, uint64_t SA) const override;
bool refersToGotEntry(uint32_t Type) 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 = 0) const override;
bool isRelRelative(uint32_t Type) const override;
bool isSizeRel(uint32_t Type) const override;
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) const override;
bool isRelRelative(uint32_t Type) const override;
};
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) const override;
bool isRelRelative(uint32_t Type) const override;
};
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 = 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,
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) const override;
};
template <class ELFT> class MipsTargetInfo final : public TargetInfo {
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) const override;
bool isHintRel(uint32_t Type) const override;
bool isRelRelative(uint32_t Type) const override;
bool refersToGotEntry(uint32_t Type) const override;
}
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 {
+ uint64_t P, uint64_t SA, uint64_t ZA) const {
switch (Type) {
case R_386_32:
add32le(Loc, SA);
}
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 {
+ uint64_t P, uint64_t SA, uint64_t ZA) const {
switch (Type) {
case R_X86_64_32:
checkUInt<32>(SA, Type);
bool PPCTargetInfo::isRelRelative(uint32_t Type) const { return false; }
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 {
+ uint64_t P, uint64_t SA, uint64_t ZA) const {
switch (Type) {
case R_PPC_ADDR16_HA:
write16be(Loc, applyPPCHa(SA));
}
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 {
+ uint64_t P, uint64_t SA, uint64_t ZA) const {
uint64_t TB = getPPC64TocBase();
// For a TOC-relative relocation, adjust the addend and proceed in terms of
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) const {
switch (Type) {
case R_AARCH64_ABS16:
checkIntUInt<16>(SA, Type);
// actually called (relocateOne is called for each relocation).
// 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 {
+ uint64_t P, uint64_t SA, uint64_t ZA) const {
llvm_unreachable("not implemented");
}
return SignExtend32<16>(read32<E>(Loc) & 0xffff);
}
-template <endianness E>
-static int64_t readMipsAHL(uint8_t *HiLoc, uint8_t *LoLoc) {
- return ((read32<E>(HiLoc) & 0xffff) << 16) + readSignedLo16<E>(LoLoc);
-}
-
template <class ELFT>
void MipsTargetInfo<ELFT>::writePltZero(uint8_t *Buf) const {
const endianness E = ELFT::TargetEndianness;
template <class ELFT>
void MipsTargetInfo<ELFT>::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) 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
write32<E>(Loc, S + int32_t(read32<E>(Loc)) - getMipsGpAddr<ELFT>());
break;
case R_MIPS_HI16:
- if (PairedLoc)
- writeMipsHi16<E>(Loc, S + readMipsAHL<E>(Loc, PairedLoc));
- else {
- warning("can't find matching R_MIPS_LO16 relocation for R_MIPS_HI16");
- writeMipsHi16<E>(Loc, S);
- }
+ writeMipsHi16<E>(Loc, S);
break;
case R_MIPS_JALR:
// Ignore this optimization relocation for now
applyMipsPcReloc<E, 32, 0>(Loc, Type, P, S);
break;
case R_MIPS_PCHI16:
- if (PairedLoc)
- writeMipsHi16<E>(Loc, S + readMipsAHL<E>(Loc, PairedLoc) - P);
- else {
- warning("can't find matching R_MIPS_PCLO16 relocation for R_MIPS_PCHI16");
- writeMipsHi16<E>(Loc, S - P);
- }
+ writeMipsHi16<E>(Loc, S - P);
break;
case R_MIPS_PCLO16:
writeMipsLo16<E>(Loc, S + readSignedLo16<E>(Loc) - P);