From 3f5d634c7334c15bdf2e68a977c9c5a7bf2af2ec Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 18 Apr 2016 12:07:13 +0000 Subject: [PATCH] Have getRelExpr handle all cases on x86. This requires adding a few more expression types, but is already a small simplification. Having Writer.cpp know the exact expression will also allow further simplifications. llvm-svn: 266604 --- lld/ELF/InputSection.cpp | 18 +++++++++++++++-- lld/ELF/InputSection.h | 5 +++++ lld/ELF/Target.cpp | 52 ++++++++++++++---------------------------------- lld/ELF/Writer.cpp | 2 +- 4 files changed, 37 insertions(+), 40 deletions(-) diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index c0acd53..9c3d312 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -159,9 +159,11 @@ 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 &File, RelExpr Expr) { + typedef typename ELFT::uint uintX_t; switch (Expr) { case R_TLSLD: - return Out::Got->getTlsIndexVA() + A; + return Out::Got->getTlsIndexOff() + A - + Out::Got->getNumEntries() * sizeof(uintX_t); case R_TLSLD_PC: return Out::Got->getTlsIndexVA() + A - P; case R_THUNK: @@ -169,7 +171,8 @@ getSymVA(uint32_t Type, typename ELFT::uint A, typename ELFT::uint P, case R_PPC_TOC: return getPPC64TocBase() + A; case R_TLSGD: - return Out::Got->getGlobalDynAddr(Body) + A; + return Out::Got->getGlobalDynOffset(Body) + A - + Out::Got->getNumEntries() * sizeof(uintX_t); case R_TLSGD_PC: return Out::Got->getGlobalDynAddr(Body) + A - P; case R_PLT: @@ -179,6 +182,11 @@ getSymVA(uint32_t Type, typename ELFT::uint A, typename ELFT::uint P, return Body.getPltVA() + A - P; case R_SIZE: return Body.getSize() + A; + case R_GOTREL: + return Body.getVA(A) - Out::Got->getVA(); + case R_GOT_FROM_END: + return Body.getGotOffset() + A - + Out::Got->getNumEntries() * sizeof(uintX_t); case R_GOT: case R_RELAX_TLS_GD_TO_IE: return Body.getGotVA() + A; @@ -187,6 +195,12 @@ getSymVA(uint32_t Type, typename ELFT::uint A, typename ELFT::uint P, case R_GOT_PC: case R_RELAX_TLS_GD_TO_IE_PC: return Body.getGotVA() + A - P; + case R_GOTONLY_PC: + return Out::Got->getVA() + A - P; + case R_TLS: + return Body.getVA(A) - Out::TlsPhdr->p_memsz; + case R_NEG_TLS: + return Out::TlsPhdr->p_memsz - Body.getVA(A); case R_ABS: case R_RELAX_TLS_GD_TO_LE: case R_RELAX_TLS_IE_TO_LE: diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h index 3a3035f..57725733 100644 --- a/lld/ELF/InputSection.h +++ b/lld/ELF/InputSection.h @@ -29,11 +29,15 @@ template class OutputSectionBase; enum RelExpr { R_ABS, R_GOT, + R_GOTONLY_PC, + R_GOTREL, + R_GOT_FROM_END, R_GOT_PAGE_PC, R_GOT_PC, R_MIPS_GOT, R_MIPS_GOT_LOCAL, R_MIPS_GP0, + R_NEG_TLS, R_PAGE_PC, R_PC, R_PLT, @@ -48,6 +52,7 @@ enum RelExpr { R_RELAX_TLS_LD_TO_LE, R_SIZE, R_THUNK, + R_TLS, R_TLSGD, R_TLSGD_PC, R_TLSLD, diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index d62fa18..8c58617 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -372,12 +372,20 @@ RelExpr X86TargetInfo::getRelExpr(uint32_t Type, const SymbolBody &S) const { return R_TLSLD; case R_386_PLT32: case R_386_PC32: - case R_386_GOTPC: return R_PC; - case R_386_GOT32: - case R_386_TLS_GOTIE: + case R_386_GOTPC: + return R_GOTONLY_PC; case R_386_TLS_IE: return R_GOT; + case R_386_GOT32: + case R_386_TLS_GOTIE: + return R_GOT_FROM_END; + case R_386_GOTOFF: + return R_GOTREL; + case R_386_TLS_LE: + return R_TLS; + case R_386_TLS_LE_32: + return R_NEG_TLS; } } @@ -507,38 +515,8 @@ uint64_t X86TargetInfo::getImplicitAddend(const uint8_t *Buf, void X86TargetInfo::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { - switch (Type) { - case R_386_32: - case R_386_PC32: - case R_386_PLT32: - case R_386_TLS_IE: - case R_386_TLS_LDO_32: - write32le(Loc, Val); - break; - case R_386_GOTOFF: - write32le(Loc, Val - Out::Got->getVA()); - break; - case R_386_GOTPC: - write32le(Loc, Val + Out::Got->getVA()); - break; - case R_386_GOT32: - case R_386_TLS_GD: - case R_386_TLS_LDM: { - uint64_t V = Val - Out::Got->getVA() - - Out::Got->getNumEntries() * 4; - checkInt<32>(V, Type); - write32le(Loc, V); - break; - } - case R_386_TLS_LE: - write32le(Loc, Val - Out::TlsPhdr->p_memsz); - break; - case R_386_TLS_LE_32: - write32le(Loc, Out::TlsPhdr->p_memsz - Val); - break; - default: - fatal("unrecognized reloc " + Twine(Type)); - } + checkInt<32>(Val, Type); + write32le(Loc, Val); } bool X86TargetInfo::needsDynRelative(uint32_t Type) const { @@ -623,13 +601,13 @@ void X86TargetInfo::relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, else *Op = 0x80 | Reg | (Reg << 3); } - relocateOne(Loc, R_386_TLS_LE, Val); + relocateOne(Loc, R_386_TLS_LE, Val - Out::TlsPhdr->p_memsz); } void X86TargetInfo::relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const { if (Type == R_386_TLS_LDO_32) { - relocateOne(Loc, R_386_TLS_LE, Val); + relocateOne(Loc, R_386_TLS_LE, Val - Out::TlsPhdr->p_memsz); return; } diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 325e571b..c799d54 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -563,7 +563,7 @@ void Writer::scanRelocs(InputSectionBase &C, ArrayRef Rels) { // If a relocation needs GOT, we create a GOT slot for the symbol. if (Expr == R_GOT || Expr == R_MIPS_GOT || Expr == R_MIPS_GOT_LOCAL || - Expr == R_GOT_PAGE_PC || Expr == R_GOT_PC) { + Expr == R_GOT_PAGE_PC || Expr == R_GOT_PC || Expr == R_GOT_FROM_END) { uint32_t T = Body.isTls() ? Target->getTlsGotRel(Type) : Type; C.Relocations.push_back({Expr, T, Offset, Addend, &Body}); if (Body.isInGot()) -- 2.7.4