[lld] r266604 - Have getRelExpr handle all cases on x86.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 18 05:07:20 PDT 2016
Author: rafael
Date: Mon Apr 18 07:07:13 2016
New Revision: 266604
URL: http://llvm.org/viewvc/llvm-project?rev=266604&view=rev
Log:
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.
Modified:
lld/trunk/ELF/InputSection.cpp
lld/trunk/ELF/InputSection.h
lld/trunk/ELF/Target.cpp
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=266604&r1=266603&r2=266604&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Mon Apr 18 07:07:13 2016
@@ -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<ELFT> &File, RelExpr Expr) {
+ typedef typename ELFT::uint uintX_t;
switch (Expr) {
case R_TLSLD:
- return Out<ELFT>::Got->getTlsIndexVA() + A;
+ return Out<ELFT>::Got->getTlsIndexOff() + A -
+ Out<ELFT>::Got->getNumEntries() * sizeof(uintX_t);
case R_TLSLD_PC:
return Out<ELFT>::Got->getTlsIndexVA() + A - P;
case R_THUNK:
@@ -169,7 +171,8 @@ getSymVA(uint32_t Type, typename ELFT::u
case R_PPC_TOC:
return getPPC64TocBase() + A;
case R_TLSGD:
- return Out<ELFT>::Got->getGlobalDynAddr(Body) + A;
+ return Out<ELFT>::Got->getGlobalDynOffset(Body) + A -
+ Out<ELFT>::Got->getNumEntries() * sizeof(uintX_t);
case R_TLSGD_PC:
return Out<ELFT>::Got->getGlobalDynAddr(Body) + A - P;
case R_PLT:
@@ -179,6 +182,11 @@ getSymVA(uint32_t Type, typename ELFT::u
return Body.getPltVA<ELFT>() + A - P;
case R_SIZE:
return Body.getSize<ELFT>() + A;
+ case R_GOTREL:
+ return Body.getVA<ELFT>(A) - Out<ELFT>::Got->getVA();
+ case R_GOT_FROM_END:
+ return Body.getGotOffset<ELFT>() + A -
+ Out<ELFT>::Got->getNumEntries() * sizeof(uintX_t);
case R_GOT:
case R_RELAX_TLS_GD_TO_IE:
return Body.getGotVA<ELFT>() + A;
@@ -187,6 +195,12 @@ getSymVA(uint32_t Type, typename ELFT::u
case R_GOT_PC:
case R_RELAX_TLS_GD_TO_IE_PC:
return Body.getGotVA<ELFT>() + A - P;
+ case R_GOTONLY_PC:
+ return Out<ELFT>::Got->getVA() + A - P;
+ case R_TLS:
+ return Body.getVA<ELFT>(A) - Out<ELF32LE>::TlsPhdr->p_memsz;
+ case R_NEG_TLS:
+ return Out<ELF32LE>::TlsPhdr->p_memsz - Body.getVA<ELFT>(A);
case R_ABS:
case R_RELAX_TLS_GD_TO_LE:
case R_RELAX_TLS_IE_TO_LE:
Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=266604&r1=266603&r2=266604&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Mon Apr 18 07:07:13 2016
@@ -29,11 +29,15 @@ template <class ELFT> class OutputSectio
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,
Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=266604&r1=266603&r2=266604&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Mon Apr 18 07:07:13 2016
@@ -372,12 +372,20 @@ RelExpr X86TargetInfo::getRelExpr(uint32
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::getImplicitAdden
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<ELF32LE>::Got->getVA());
- break;
- case R_386_GOTPC:
- write32le(Loc, Val + Out<ELF32LE>::Got->getVA());
- break;
- case R_386_GOT32:
- case R_386_TLS_GD:
- case R_386_TLS_LDM: {
- uint64_t V = Val - Out<ELF32LE>::Got->getVA() -
- Out<ELF32LE>::Got->getNumEntries() * 4;
- checkInt<32>(V, Type);
- write32le(Loc, V);
- break;
- }
- case R_386_TLS_LE:
- write32le(Loc, Val - Out<ELF32LE>::TlsPhdr->p_memsz);
- break;
- case R_386_TLS_LE_32:
- write32le(Loc, Out<ELF32LE>::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
else
*Op = 0x80 | Reg | (Reg << 3);
}
- relocateOne(Loc, R_386_TLS_LE, Val);
+ relocateOne(Loc, R_386_TLS_LE, Val - Out<ELF32LE>::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<ELF32LE>::TlsPhdr->p_memsz);
return;
}
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=266604&r1=266603&r2=266604&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Apr 18 07:07:13 2016
@@ -563,7 +563,7 @@ void Writer<ELFT>::scanRelocs(InputSecti
// 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())
More information about the llvm-commits
mailing list