diff options
Diffstat (limited to 'lld/ELF/InputSection.cpp')
| -rw-r--r-- | lld/ELF/InputSection.cpp | 36 |
1 files changed, 8 insertions, 28 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index b6b09db506a..a90b3098a27 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -141,44 +141,16 @@ static uint64_t getAArch64Page(uint64_t Expr) { return Expr & (~static_cast<uint64_t>(0xFFF)); } -// For computing values, each R_RELAX_TLS_* corresponds to whatever expression -// the target uses in the mode this is being relaxed into. For example, anything -// that relaxes to LE just needs an R_TLS since that is what is used if we -// had a local exec expression to begin with. -static RelExpr getRelaxedExpr(RelExpr Expr) { - switch (Expr) { - default: - return Expr; - case R_RELAX_TLS_GD_TO_LE: - if (Config->EMachine == EM_386) - return R_NEG_TLS; - return R_TLS; - case R_RELAX_TLS_GD_TO_IE: - if (Config->EMachine == EM_386) - return R_GOT_FROM_END; - return R_GOT_PC; - case R_RELAX_TLS_IE_TO_LE: - case R_RELAX_TLS_LD_TO_LE: - return R_TLS; - } -} - template <class ELFT> static typename ELFT::uint getSymVA(uint32_t Type, typename ELFT::uint A, typename ELFT::uint P, const SymbolBody &Body, uint8_t *BufLoc, const elf::ObjectFile<ELFT> &File, RelExpr Expr) { typedef typename ELFT::uint uintX_t; - Expr = getRelaxedExpr(Expr); switch (Expr) { case R_HINT: llvm_unreachable("cannot relocate hint relocs"); - case R_RELAX_TLS_GD_TO_LE: - case R_RELAX_TLS_GD_TO_IE: - case R_RELAX_TLS_IE_TO_LE: - case R_RELAX_TLS_LD_TO_LE: - llvm_unreachable("Should have been mapped"); case R_TLSLD: return Out<ELFT>::Got->getTlsIndexOff() + A - Out<ELFT>::Got->getNumEntries() * sizeof(uintX_t); @@ -207,6 +179,7 @@ getSymVA(uint32_t Type, typename ELFT::uint A, typename ELFT::uint P, return Body.getSize<ELFT>() + A; case R_GOTREL: return Body.getVA<ELFT>(A) - Out<ELFT>::Got->getVA(); + case R_RELAX_TLS_GD_TO_IE_END: case R_GOT_FROM_END: return Body.getGotOffset<ELFT>() + A - Out<ELFT>::Got->getNumEntries() * sizeof(uintX_t); @@ -214,15 +187,20 @@ getSymVA(uint32_t Type, typename ELFT::uint A, typename ELFT::uint P, return Body.getGotVA<ELFT>() + A; case R_GOT_PAGE_PC: return getAArch64Page(Body.getGotVA<ELFT>() + A) - getAArch64Page(P); + case R_RELAX_TLS_GD_TO_IE: case R_GOT_PC: return Body.getGotVA<ELFT>() + A - P; case R_GOTONLY_PC: return Out<ELFT>::Got->getVA() + A - P; + case R_RELAX_TLS_LD_TO_LE: + case R_RELAX_TLS_IE_TO_LE: + case R_RELAX_TLS_GD_TO_LE: case R_TLS: if (Target->TcbSize) return Body.getVA<ELFT>(A) + alignTo(Target->TcbSize, Out<ELFT>::TlsPhdr->p_align); return Body.getVA<ELFT>(A) - Out<ELFT>::TlsPhdr->p_memsz; + case R_RELAX_TLS_GD_TO_LE_NEG: case R_NEG_TLS: return Out<ELF32LE>::TlsPhdr->p_memsz - Body.getVA<ELFT>(A); case R_ABS: @@ -342,9 +320,11 @@ void InputSectionBase<ELFT>::relocate(uint8_t *Buf, uint8_t *BufEnd) { Target->relaxTlsLdToLe(BufLoc, Type, SymVA); break; case R_RELAX_TLS_GD_TO_LE: + case R_RELAX_TLS_GD_TO_LE_NEG: Target->relaxTlsGdToLe(BufLoc, Type, SymVA); break; case R_RELAX_TLS_GD_TO_IE: + case R_RELAX_TLS_GD_TO_IE_END: Target->relaxTlsGdToIe(BufLoc, Type, SymVA); break; case R_PPC_PLT_OPD: |

