From 5628ee76318a887c811defe9f3e4c42d6b7c4236 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 15 Apr 2016 19:14:18 +0000 Subject: [PATCH] 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 --- lld/ELF/Target.cpp | 85 ++++++++++++---------------------------------- lld/ELF/Target.h | 1 - lld/ELF/Writer.cpp | 19 ++--------- 3 files changed, 25 insertions(+), 80 deletions(-) diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index 6246ad194727..b8e689d48668 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -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::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::needsCopyRelImpl(uint32_t Type) const { return !isRelRelative(Type) || Type == R_MIPS_LO16; } -template -bool MipsTargetInfo::needsGot(uint32_t Type, const SymbolBody &S) const { - return needsPlt(Type, S) || refersToGotEntry(Type); -} - template bool MipsTargetInfo::refersToGotEntry(uint32_t Type) const { return Type == R_MIPS_GOT16 || Type == R_MIPS_CALL16; diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h index ed32faa696a5..4d201f2e3337 100644 --- a/lld/ELF/Target.h +++ b/lld/ELF/Target.h @@ -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 }; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 48eee4394a9a..9b7cd5a51eb6 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -563,23 +563,10 @@ void Writer::scanRelocs(InputSectionBase &C, ArrayRef 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::Got->addEntry(Body);