forked from OSchip/llvm-project
Simplify got handling.
Each getRelExpr is now expected to return the correct got expression instead of having Writer patch it up with needsGot. llvm-svn: 266466
This commit is contained in:
parent
f9f1c5619a
commit
5628ee7631
|
@ -86,7 +86,6 @@ public:
|
|||
bool isRelRelative(uint32_t Type) const override;
|
||||
bool needsCopyRelImpl(uint32_t Type) const override;
|
||||
bool needsDynRelative(uint32_t Type) const override;
|
||||
bool needsGot(uint32_t Type, const SymbolBody &S) const override;
|
||||
bool needsPltImpl(uint32_t Type) const override;
|
||||
void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
|
||||
|
||||
|
@ -115,7 +114,6 @@ public:
|
|||
void writePlt(uint8_t *Buf, uint64_t GotEntryAddr, uint64_t PltEntryAddr,
|
||||
int32_t Index, unsigned RelOff) const override;
|
||||
bool needsCopyRelImpl(uint32_t Type) const override;
|
||||
bool needsGot(uint32_t Type, const SymbolBody &S) const override;
|
||||
bool refersToGotEntry(uint32_t Type) const override;
|
||||
bool needsPltImpl(uint32_t Type) const override;
|
||||
void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
|
||||
|
@ -141,7 +139,6 @@ public:
|
|||
RelExpr getRelExpr(uint32_t Type, const SymbolBody &S) const override;
|
||||
void writePlt(uint8_t *Buf, uint64_t GotEntryAddr, uint64_t PltEntryAddr,
|
||||
int32_t Index, unsigned RelOff) const override;
|
||||
bool needsGot(uint32_t Type, const SymbolBody &S) const override;
|
||||
bool needsPltImpl(uint32_t Type) const override;
|
||||
void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
|
||||
bool isRelRelative(uint32_t Type) const override;
|
||||
|
@ -161,7 +158,6 @@ public:
|
|||
uint32_t getTlsGotRel(uint32_t Type) const override;
|
||||
bool isRelRelative(uint32_t Type) const override;
|
||||
bool needsCopyRelImpl(uint32_t Type) const override;
|
||||
bool needsGot(uint32_t Type, const SymbolBody &S) const override;
|
||||
bool refersToGotEntry(uint32_t Type) const override;
|
||||
bool needsPltImpl(uint32_t Type) const override;
|
||||
void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
|
||||
|
@ -192,7 +188,6 @@ public:
|
|||
void writeGotHeader(uint8_t *Buf) const override;
|
||||
void writeThunk(uint8_t *Buf, uint64_t S) const override;
|
||||
bool needsCopyRelImpl(uint32_t Type) const override;
|
||||
bool needsGot(uint32_t Type, const SymbolBody &S) const override;
|
||||
bool needsPltImpl(uint32_t Type) const override;
|
||||
bool needsThunk(uint32_t Type, const InputFile &File,
|
||||
const SymbolBody &S) const override;
|
||||
|
@ -282,10 +277,6 @@ bool TargetInfo::isGotRelative(uint32_t Type) const { return false; }
|
|||
bool TargetInfo::isHintRel(uint32_t Type) const { return false; }
|
||||
bool TargetInfo::isRelRelative(uint32_t Type) const { return true; }
|
||||
|
||||
bool TargetInfo::needsGot(uint32_t Type, const SymbolBody &S) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TargetInfo::needsPltImpl(uint32_t Type) const { return false; }
|
||||
|
||||
bool TargetInfo::refersToGotEntry(uint32_t Type) const { return false; }
|
||||
|
@ -385,6 +376,10 @@ RelExpr X86TargetInfo::getRelExpr(uint32_t Type, const SymbolBody &S) const {
|
|||
case R_386_PC32:
|
||||
case R_386_GOTPC:
|
||||
return R_PC;
|
||||
case R_386_GOT32:
|
||||
case R_386_TLS_GOTIE:
|
||||
case R_386_TLS_IE:
|
||||
return R_GOT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -486,14 +481,6 @@ bool X86TargetInfo::needsCopyRelImpl(uint32_t Type) const {
|
|||
return Type == R_386_32 || Type == R_386_16 || Type == R_386_8;
|
||||
}
|
||||
|
||||
bool X86TargetInfo::needsGot(uint32_t Type, const SymbolBody &S) const {
|
||||
if (S.isTls() && Type == R_386_TLS_GD)
|
||||
return Target->canRelaxTls(Type, &S) && S.isPreemptible();
|
||||
if (Type == R_386_TLS_GOTIE || Type == R_386_TLS_IE)
|
||||
return !canRelaxTls(Type, &S);
|
||||
return Type == R_386_GOT32 || needsPlt(Type, S);
|
||||
}
|
||||
|
||||
bool X86TargetInfo::needsPltImpl(uint32_t Type) const {
|
||||
return Type == R_386_PLT32;
|
||||
}
|
||||
|
@ -689,13 +676,16 @@ RelExpr X86_64TargetInfo::getRelExpr(uint32_t Type, const SymbolBody &S) const {
|
|||
case R_X86_64_SIZE32:
|
||||
case R_X86_64_SIZE64:
|
||||
return R_SIZE;
|
||||
case R_X86_64_GOTPCREL:
|
||||
case R_X86_64_PLT32:
|
||||
case R_X86_64_PC32:
|
||||
case R_X86_64_TLSLD:
|
||||
case R_X86_64_GOTTPOFF:
|
||||
case R_X86_64_TLSGD:
|
||||
return R_PC;
|
||||
case R_X86_64_GOT32:
|
||||
return R_GOT;
|
||||
case R_X86_64_GOTPCREL:
|
||||
case R_X86_64_GOTTPOFF:
|
||||
return R_GOT_PC;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -746,14 +736,6 @@ bool X86_64TargetInfo::refersToGotEntry(uint32_t Type) const {
|
|||
Type == R_X86_64_REX_GOTPCRELX;
|
||||
}
|
||||
|
||||
bool X86_64TargetInfo::needsGot(uint32_t Type, const SymbolBody &S) const {
|
||||
if (Type == R_X86_64_TLSGD)
|
||||
return Target->canRelaxTls(Type, &S) && S.isPreemptible();
|
||||
if (Type == R_X86_64_GOTTPOFF)
|
||||
return !canRelaxTls(Type, &S);
|
||||
return refersToGotEntry(Type) || needsPlt(Type, S);
|
||||
}
|
||||
|
||||
uint32_t X86_64TargetInfo::getDynRel(uint32_t Type) const {
|
||||
if (Type == R_X86_64_PC32 || Type == R_X86_64_32)
|
||||
if (Config->Shared)
|
||||
|
@ -1058,22 +1040,6 @@ void PPC64TargetInfo::writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
|
|||
write32be(Buf + 28, 0x4e800420); // bctr
|
||||
}
|
||||
|
||||
bool PPC64TargetInfo::needsGot(uint32_t Type, const SymbolBody &S) const {
|
||||
if (needsPlt(Type, S))
|
||||
return true;
|
||||
|
||||
switch (Type) {
|
||||
default: return false;
|
||||
case R_PPC64_GOT16:
|
||||
case R_PPC64_GOT16_DS:
|
||||
case R_PPC64_GOT16_HA:
|
||||
case R_PPC64_GOT16_HI:
|
||||
case R_PPC64_GOT16_LO:
|
||||
case R_PPC64_GOT16_LO_DS:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool PPC64TargetInfo::needsPltImpl(uint32_t Type) const {
|
||||
// These are function calls that need to be redirected through a PLT stub.
|
||||
return Type == R_PPC64_REL24;
|
||||
|
@ -1210,10 +1176,14 @@ RelExpr AArch64TargetInfo::getRelExpr(uint32_t Type,
|
|||
case R_AARCH64_ADR_PREL_LO21:
|
||||
case R_AARCH64_TSTBR14:
|
||||
return R_PC;
|
||||
case R_AARCH64_ADR_GOT_PAGE:
|
||||
case R_AARCH64_ADR_PREL_PG_HI21:
|
||||
case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
|
||||
return R_PAGE_PC;
|
||||
case R_AARCH64_LD64_GOT_LO12_NC:
|
||||
case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
|
||||
return R_GOT;
|
||||
case R_AARCH64_ADR_GOT_PAGE:
|
||||
case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
|
||||
return R_GOT_PAGE_PC;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1337,19 +1307,6 @@ bool AArch64TargetInfo::needsCopyRelImpl(uint32_t Type) const {
|
|||
}
|
||||
}
|
||||
|
||||
bool AArch64TargetInfo::needsGot(uint32_t Type, const SymbolBody &S) const {
|
||||
switch (Type) {
|
||||
case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
|
||||
case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
|
||||
return !canRelaxTls(Type, &S);
|
||||
case R_AARCH64_ADR_GOT_PAGE:
|
||||
case R_AARCH64_LD64_GOT_LO12_NC:
|
||||
return true;
|
||||
default:
|
||||
return needsPlt(Type, S);
|
||||
}
|
||||
}
|
||||
|
||||
bool AArch64TargetInfo::refersToGotEntry(uint32_t Type) const {
|
||||
return Type == R_AARCH64_ADR_GOT_PAGE || Type == R_AARCH64_LD64_GOT_LO12_NC;
|
||||
}
|
||||
|
@ -1591,6 +1548,13 @@ RelExpr MipsTargetInfo<ELFT>::getRelExpr(uint32_t Type,
|
|||
case R_MIPS_PCHI16:
|
||||
case R_MIPS_PCLO16:
|
||||
return R_PC;
|
||||
case R_MIPS_GOT16:
|
||||
case R_MIPS_CALL16:
|
||||
if (S.isLocal())
|
||||
return R_MIPS_GOT_LOCAL;
|
||||
if (!S.isPreemptible())
|
||||
return R_MIPS_GOT;
|
||||
return R_GOT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1718,11 +1682,6 @@ bool MipsTargetInfo<ELFT>::needsCopyRelImpl(uint32_t Type) const {
|
|||
return !isRelRelative(Type) || Type == R_MIPS_LO16;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
bool MipsTargetInfo<ELFT>::needsGot(uint32_t Type, const SymbolBody &S) const {
|
||||
return needsPlt(Type, S) || refersToGotEntry(Type);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
bool MipsTargetInfo<ELFT>::refersToGotEntry(uint32_t Type) const {
|
||||
return Type == R_MIPS_GOT16 || Type == R_MIPS_CALL16;
|
||||
|
|
|
@ -57,7 +57,6 @@ public:
|
|||
virtual bool isRelRelative(uint32_t Type) const;
|
||||
|
||||
virtual bool needsDynRelative(uint32_t Type) const { return false; }
|
||||
virtual bool needsGot(uint32_t Type, const SymbolBody &S) const;
|
||||
virtual bool refersToGotEntry(uint32_t Type) const;
|
||||
|
||||
enum PltNeed { Plt_No, Plt_Explicit, Plt_Implicit };
|
||||
|
|
|
@ -563,23 +563,10 @@ void Writer<ELFT>::scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) {
|
|||
}
|
||||
|
||||
// If a relocation needs GOT, we create a GOT slot for the symbol.
|
||||
if (Target->needsGot(Type, Body)) {
|
||||
if (Expr == R_GOT || Expr == R_MIPS_GOT || Expr == R_MIPS_GOT_LOCAL ||
|
||||
Expr == R_GOT_PAGE_PC || Expr == R_GOT_PC) {
|
||||
uint32_t T = Body.isTls() ? Target->getTlsGotRel(Type) : Type;
|
||||
RelExpr E;
|
||||
if (Expr == R_PC)
|
||||
E = R_GOT_PC;
|
||||
else if (Expr == R_PAGE_PC)
|
||||
E = R_GOT_PAGE_PC;
|
||||
else if (Config->EMachine == EM_MIPS) {
|
||||
if (Body.isLocal())
|
||||
E = R_MIPS_GOT_LOCAL;
|
||||
else if (!Body.isPreemptible())
|
||||
E = R_MIPS_GOT;
|
||||
else
|
||||
E = R_GOT;
|
||||
} else
|
||||
E = R_GOT;
|
||||
C.Relocations.push_back({E, T, Offset, Addend, &Body});
|
||||
C.Relocations.push_back({Expr, T, Offset, Addend, &Body});
|
||||
if (Body.isInGot())
|
||||
continue;
|
||||
Out<ELFT>::Got->addEntry(Body);
|
||||
|
|
Loading…
Reference in New Issue