[lld] r271814 - Use adjustRelaxExpr for tls relaxations too.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Sat Jun 4 16:22:43 PDT 2016
Author: rafael
Date: Sat Jun 4 18:22:34 2016
New Revision: 271814
URL: http://llvm.org/viewvc/llvm-project?rev=271814&view=rev
Log:
Use adjustRelaxExpr for tls relaxations too.
This remove some EM_386 specific code from InputSection.cpp and opens
the way for more relaxations.
Modified:
lld/trunk/ELF/InputSection.cpp
lld/trunk/ELF/Relocations.cpp
lld/trunk/ELF/Relocations.h
lld/trunk/ELF/Target.cpp
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=271814&r1=271813&r2=271814&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Sat Jun 4 18:22:34 2016
@@ -141,44 +141,16 @@ static uint64_t getAArch64Page(uint64_t
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::u
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::u
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(ui
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:
Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=271814&r1=271813&r2=271814&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Sat Jun 4 18:22:34 2016
@@ -148,7 +148,8 @@ static unsigned handleTlsRelocation(uint
// depending on the symbol being locally defined or not.
if (isPreemptible(Body, Type)) {
C.Relocations.push_back(
- {R_RELAX_TLS_GD_TO_IE, Type, Offset, Addend, &Body});
+ {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_IE), Type,
+ Offset, Addend, &Body});
if (!Body.isInGot()) {
Out<ELFT>::Got->addEntry(Body);
Out<ELFT>::RelaDyn->addReloc({Target->TlsGotRel, Out<ELFT>::Got,
@@ -158,7 +159,8 @@ static unsigned handleTlsRelocation(uint
return 2;
}
C.Relocations.push_back(
- {R_RELAX_TLS_GD_TO_LE, Type, Offset, Addend, &Body});
+ {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_LE), Type,
+ Offset, Addend, &Body});
return Target->TlsGdRelaxSkip;
}
Modified: lld/trunk/ELF/Relocations.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.h?rev=271814&r1=271813&r2=271814&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.h (original)
+++ lld/trunk/ELF/Relocations.h Sat Jun 4 18:22:34 2016
@@ -42,7 +42,9 @@ enum RelExpr {
R_RELAX_GOT_PC,
R_RELAX_GOT_PC_NOPIC,
R_RELAX_TLS_GD_TO_IE,
+ R_RELAX_TLS_GD_TO_IE_END,
R_RELAX_TLS_GD_TO_LE,
+ R_RELAX_TLS_GD_TO_LE_NEG,
R_RELAX_TLS_IE_TO_LE,
R_RELAX_TLS_LD_TO_LE,
R_SIZE,
Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=271814&r1=271813&r2=271814&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Sat Jun 4 18:22:34 2016
@@ -92,6 +92,8 @@ public:
int32_t Index, unsigned RelOff) const override;
void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
+ RelExpr adjustRelaxExpr(uint32_t Type, const uint8_t *Data,
+ RelExpr Expr) const override;
void relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
void relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
void relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
@@ -309,6 +311,18 @@ RelExpr X86TargetInfo::getRelExpr(uint32
}
}
+RelExpr X86TargetInfo::adjustRelaxExpr(uint32_t Type, const uint8_t *Data,
+ RelExpr Expr) const {
+ switch (Expr) {
+ default:
+ return Expr;
+ case R_RELAX_TLS_GD_TO_IE:
+ return R_RELAX_TLS_GD_TO_IE_END;
+ case R_RELAX_TLS_GD_TO_LE:
+ return R_RELAX_TLS_GD_TO_LE_NEG;
+ }
+}
+
void X86TargetInfo::writeGotPltHeader(uint8_t *Buf) const {
write32le(Buf, Out<ELF32LE>::Dynamic->getVA());
}
More information about the llvm-commits
mailing list