diff options
Diffstat (limited to 'lld/ELF/Relocations.cpp')
-rw-r--r-- | lld/ELF/Relocations.cpp | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index ceb9a8b91cc..354533504a6 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -229,7 +229,7 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C, return 1; } - if (oneof<R_TLSLD_GOT, R_TLSLD_GOT_FROM_END, R_TLSLD_PC, R_TLSLD_HINT>( + if (oneof<R_TLSLD_GOT, R_TLSLD_GOTPLT, R_TLSLD_PC, R_TLSLD_HINT>( Expr)) { // Local-Dynamic relocs can be relaxed to Local-Exec. if (!Config->Shared) { @@ -274,7 +274,7 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C, } if (oneof<R_TLSDESC, R_AARCH64_TLSDESC_PAGE, R_TLSDESC_CALL, R_TLSGD_GOT, - R_TLSGD_GOT_FROM_END, R_TLSGD_PC>(Expr)) { + R_TLSGD_GOTPLT, R_TLSGD_PC>(Expr)) { if (Config->Shared) { if (In.Got->addDynTlsEntry(Sym)) { uint64_t Off = In.Got->getGlobalDynOffset(Sym); @@ -314,7 +314,7 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C, // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally // defined. - if (oneof<R_GOT, R_GOT_FROM_END, R_GOT_PC, R_AARCH64_GOT_PAGE_PC, R_GOT_OFF, + if (oneof<R_GOT, R_GOTPLT, R_GOT_PC, R_AARCH64_GOT_PAGE_PC, R_GOT_OFF, R_TLSIE_HINT>(Expr) && !Config->Shared && !Sym.IsPreemptible) { C.Relocations.push_back({R_RELAX_TLS_IE_TO_LE, Type, Offset, Addend, &Sym}); @@ -376,13 +376,13 @@ static bool needsPlt(RelExpr Expr) { static bool needsGot(RelExpr Expr) { return oneof<R_GOT, R_GOT_OFF, R_HEXAGON_GOT, R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_AARCH64_GOT_PAGE_PC, - R_GOT_PC, R_GOT_FROM_END>(Expr); + R_GOT_PC, R_GOTPLT>(Expr); } // True if this expression is of the form Sym - X, where X is a position in the // file (PC, or GOT for example). static bool isRelExpr(RelExpr Expr) { - return oneof<R_PC, R_GOTREL, R_GOTREL_FROM_END, R_MIPS_GOTREL, R_PPC_CALL, + return oneof<R_PC, R_GOTREL, R_GOTPLTREL, R_MIPS_GOTREL, R_PPC_CALL, R_PPC_CALL_PLT, R_AARCH64_PAGE_PC, R_RELAX_GOT_PC>(Expr); } @@ -398,11 +398,11 @@ static bool isRelExpr(RelExpr Expr) { static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym, InputSectionBase &S, uint64_t RelOff) { // These expressions always compute a constant - if (oneof<R_GOT_FROM_END, R_GOT_OFF, R_HEXAGON_GOT, R_TLSLD_GOT_OFF, + if (oneof<R_GOTPLT, R_GOT_OFF, R_HEXAGON_GOT, R_TLSLD_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOTREL, R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC, R_MIPS_TLSGD, R_AARCH64_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC, - R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_GOT, R_TLSGD_GOT_FROM_END, + R_GOTPLTONLY_PC, R_PLT_PC, R_TLSGD_GOT, R_TLSGD_GOTPLT, R_TLSGD_PC, R_PPC_CALL_PLT, R_TLSDESC_CALL, R_AARCH64_TLSDESC_PAGE, R_HINT, R_TLSLD_HINT, R_TLSIE_HINT>(E)) return true; @@ -1065,11 +1065,15 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I, Expr = fromPlt(Expr); } - // This relocation does not require got entry, but it is relative to got and - // needs it to be created. Here we request for that. - if (oneof<R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_GOTREL, R_GOTREL_FROM_END, - R_PPC_TOC>(Expr)) + // If the relocation does not emit a GOT or GOTPLT entry but its computation + // uses their addresses, we need GOT or GOTPLT to be created. + // + // The 4 types that relative GOTPLT are all x86 and x86-64 specific. + if (oneof<R_GOTPLTONLY_PC, R_GOTPLTREL, R_GOTPLT, R_TLSGD_GOTPLT>(Expr)) { + In.GotPlt->HasGotPltOffRel = true; + } else if (oneof<R_GOTONLY_PC, R_GOTREL, R_PPC_TOC>(Expr)) { In.Got->HasGotOffRel = true; + } // Read an addend. int64_t Addend = computeAddend<ELFT>(Rel, End, Sec, Expr, Sym.isLocal()); |