mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-28 03:46:06 +00:00
Refactor R_RELAX_TLS_* value computation.
This makes it explicit that each R_RELAX_TLS_* is equivalent to some other expression. With this I think we are at a sweet spot for how much is done in Target.cpp. I did experiment with moving *all* the value math out of it. It has the advantage that we know the final value in target independent code, but it gets quite verbose. llvm-svn: 270277
This commit is contained in:
parent
14d965166c
commit
ebed1fe0de
@ -135,15 +135,44 @@ 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);
|
||||
@ -168,7 +197,6 @@ getSymVA(uint32_t Type, typename ELFT::uint A, typename ELFT::uint P,
|
||||
case R_GOTREL:
|
||||
return Body.getVA<ELFT>(A) - Out<ELFT>::Got->getVA();
|
||||
case R_GOT_FROM_END:
|
||||
case R_RELAX_TLS_GD_TO_IE:
|
||||
return Body.getGotOffset<ELFT>() + A -
|
||||
Out<ELFT>::Got->getNumEntries() * sizeof(uintX_t);
|
||||
case R_GOT:
|
||||
@ -176,13 +204,9 @@ getSymVA(uint32_t Type, typename ELFT::uint A, typename ELFT::uint P,
|
||||
case R_GOT_PAGE_PC:
|
||||
return getAArch64Page(Body.getGotVA<ELFT>() + A) - getAArch64Page(P);
|
||||
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_RELAX_TLS_GD_TO_LE:
|
||||
case R_RELAX_TLS_IE_TO_LE:
|
||||
case R_RELAX_TLS_LD_TO_LE:
|
||||
case R_TLS:
|
||||
if (Target->TcbSize)
|
||||
return Body.getVA<ELFT>(A) +
|
||||
@ -308,7 +332,6 @@ void InputSectionBase<ELFT>::relocate(uint8_t *Buf, uint8_t *BufEnd) {
|
||||
case R_RELAX_TLS_GD_TO_LE:
|
||||
Target->relaxTlsGdToLe(BufLoc, Type, SymVA);
|
||||
break;
|
||||
case R_RELAX_TLS_GD_TO_IE_PC:
|
||||
case R_RELAX_TLS_GD_TO_IE:
|
||||
Target->relaxTlsGdToIe(BufLoc, Type, SymVA);
|
||||
break;
|
||||
|
@ -47,7 +47,6 @@ enum RelExpr {
|
||||
R_PPC_PLT_OPD,
|
||||
R_PPC_TOC,
|
||||
R_RELAX_TLS_GD_TO_IE,
|
||||
R_RELAX_TLS_GD_TO_IE_PC,
|
||||
R_RELAX_TLS_GD_TO_LE,
|
||||
R_RELAX_TLS_IE_TO_LE,
|
||||
R_RELAX_TLS_LD_TO_LE,
|
||||
|
@ -400,7 +400,7 @@ void X86TargetInfo::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type,
|
||||
0x81, 0xe8, 0x00, 0x00, 0x00, 0x00 // subl 0(%ebx), %eax
|
||||
};
|
||||
memcpy(Loc - 3, Inst, sizeof(Inst));
|
||||
relocateOne(Loc + 5, R_386_32, -Val);
|
||||
relocateOne(Loc + 5, R_386_32, Val);
|
||||
}
|
||||
|
||||
void X86TargetInfo::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type,
|
||||
|
@ -336,9 +336,8 @@ static unsigned handleTlsRelocation(uint32_t Type, SymbolBody &Body,
|
||||
// Global-Dynamic relocs can be relaxed to Initial-Exec or Local-Exec
|
||||
// depending on the symbol being locally defined or not.
|
||||
if (Body.isPreemptible()) {
|
||||
Expr =
|
||||
Expr == R_TLSGD_PC ? R_RELAX_TLS_GD_TO_IE_PC : R_RELAX_TLS_GD_TO_IE;
|
||||
C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
|
||||
C.Relocations.push_back(
|
||||
{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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user