lld: sort relocations
No functional change; applied to facilitate merge of later LLD commit. Reviewed by: dim, Rafael Espíndola Obtained from: LLD r298797 MFC after: 3 days Differential Revision: https://reviews.freebsd.org/D11190
This commit is contained in:
parent
1a20115c11
commit
dbb5554133
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=319955
@ -290,82 +290,37 @@ static typename ELFT::uint
|
||||
getRelocTargetVA(uint32_t Type, typename ELFT::uint A, typename ELFT::uint P,
|
||||
const SymbolBody &Body, RelExpr Expr) {
|
||||
switch (Expr) {
|
||||
case R_HINT:
|
||||
case R_TLSDESC_CALL:
|
||||
llvm_unreachable("cannot relocate hint relocs");
|
||||
case R_TLSLD:
|
||||
return In<ELFT>::Got->getTlsIndexOff() + A - In<ELFT>::Got->getSize();
|
||||
case R_TLSLD_PC:
|
||||
return In<ELFT>::Got->getTlsIndexVA() + A - P;
|
||||
case R_THUNK_ABS:
|
||||
return Body.getThunkVA<ELFT>() + A;
|
||||
case R_THUNK_PC:
|
||||
case R_THUNK_PLT_PC:
|
||||
return Body.getThunkVA<ELFT>() + A - P;
|
||||
case R_PPC_TOC:
|
||||
return getPPC64TocBase() + A;
|
||||
case R_TLSGD:
|
||||
return In<ELFT>::Got->getGlobalDynOffset(Body) + A -
|
||||
In<ELFT>::Got->getSize();
|
||||
case R_TLSGD_PC:
|
||||
return In<ELFT>::Got->getGlobalDynAddr(Body) + A - P;
|
||||
case R_TLSDESC:
|
||||
return In<ELFT>::Got->getGlobalDynAddr(Body) + A;
|
||||
case R_TLSDESC_PAGE:
|
||||
return getAArch64Page(In<ELFT>::Got->getGlobalDynAddr(Body) + A) -
|
||||
getAArch64Page(P);
|
||||
case R_PLT:
|
||||
return Body.getPltVA<ELFT>() + A;
|
||||
case R_PLT_PC:
|
||||
case R_PPC_PLT_OPD:
|
||||
return Body.getPltVA<ELFT>() + A - P;
|
||||
case R_SIZE:
|
||||
return Body.getSize<ELFT>() + A;
|
||||
case R_ABS:
|
||||
case R_RELAX_GOT_PC_NOPIC:
|
||||
return Body.getVA<ELFT>(A);
|
||||
case R_GOT:
|
||||
case R_RELAX_TLS_GD_TO_IE_ABS:
|
||||
return Body.getGotVA<ELFT>() + A;
|
||||
case R_GOTONLY_PC:
|
||||
return In<ELFT>::Got->getVA() + A - P;
|
||||
case R_GOTONLY_PC_FROM_END:
|
||||
return In<ELFT>::Got->getVA() + A - P + In<ELFT>::Got->getSize();
|
||||
case R_GOTREL:
|
||||
return Body.getVA<ELFT>(A) - In<ELFT>::Got->getVA();
|
||||
case R_GOTREL_FROM_END:
|
||||
return Body.getVA<ELFT>(A) - In<ELFT>::Got->getVA() -
|
||||
In<ELFT>::Got->getSize();
|
||||
case R_RELAX_TLS_GD_TO_IE_END:
|
||||
case R_GOT_FROM_END:
|
||||
case R_RELAX_TLS_GD_TO_IE_END:
|
||||
return Body.getGotOffset<ELFT>() + A - In<ELFT>::Got->getSize();
|
||||
case R_RELAX_TLS_GD_TO_IE_ABS:
|
||||
case R_GOT:
|
||||
return Body.getGotVA<ELFT>() + A;
|
||||
case R_RELAX_TLS_GD_TO_IE_PAGE_PC:
|
||||
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 In<ELFT>::Got->getVA() + A - P;
|
||||
case R_GOTONLY_PC_FROM_END:
|
||||
return In<ELFT>::Got->getVA() + A - P + In<ELFT>::Got->getSize();
|
||||
case R_RELAX_TLS_LD_TO_LE:
|
||||
case R_RELAX_TLS_IE_TO_LE:
|
||||
case R_RELAX_TLS_GD_TO_LE:
|
||||
case R_TLS:
|
||||
// A weak undefined TLS symbol resolves to the base of the TLS
|
||||
// block, i.e. gets a value of zero. If we pass --gc-sections to
|
||||
// lld and .tbss is not referenced, it gets reclaimed and we don't
|
||||
// create a TLS program header. Therefore, we resolve this
|
||||
// statically to zero.
|
||||
if (Body.isTls() && (Body.isLazy() || Body.isUndefined()) &&
|
||||
Body.symbol()->isWeak())
|
||||
return 0;
|
||||
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:
|
||||
case R_RELAX_GOT_PC_NOPIC:
|
||||
return Body.getVA<ELFT>(A);
|
||||
case R_GOT_OFF:
|
||||
return Body.getGotOffset<ELFT>() + A;
|
||||
case R_GOT_PAGE_PC:
|
||||
case R_RELAX_TLS_GD_TO_IE_PAGE_PC:
|
||||
return getAArch64Page(Body.getGotVA<ELFT>() + A) - getAArch64Page(P);
|
||||
case R_GOT_PC:
|
||||
case R_RELAX_TLS_GD_TO_IE:
|
||||
return Body.getGotVA<ELFT>() + A - P;
|
||||
case R_HINT:
|
||||
case R_TLSDESC_CALL:
|
||||
llvm_unreachable("cannot relocate hint relocs");
|
||||
case R_MIPS_GOTREL:
|
||||
return Body.getVA<ELFT>(A) - In<ELFT>::MipsGot->getGp();
|
||||
case R_MIPS_GOT_LOCAL_PAGE:
|
||||
// If relocation against MIPS local symbol requires GOT entry, this entry
|
||||
// should be initialized by 'page address'. This address is high 16-bits
|
||||
@ -381,8 +336,6 @@ getRelocTargetVA(uint32_t Type, typename ELFT::uint A, typename ELFT::uint P,
|
||||
return In<ELFT>::MipsGot->getVA() +
|
||||
In<ELFT>::MipsGot->getBodyEntryOffset(Body, A) -
|
||||
In<ELFT>::MipsGot->getGp();
|
||||
case R_MIPS_GOTREL:
|
||||
return Body.getVA<ELFT>(A) - In<ELFT>::MipsGot->getGp();
|
||||
case R_MIPS_TLSGD:
|
||||
return In<ELFT>::MipsGot->getVA() + In<ELFT>::MipsGot->getTlsOffset() +
|
||||
In<ELFT>::MipsGot->getGlobalDynOffset(Body) -
|
||||
@ -390,6 +343,26 @@ getRelocTargetVA(uint32_t Type, typename ELFT::uint A, typename ELFT::uint P,
|
||||
case R_MIPS_TLSLD:
|
||||
return In<ELFT>::MipsGot->getVA() + In<ELFT>::MipsGot->getTlsOffset() +
|
||||
In<ELFT>::MipsGot->getTlsIndexOff() - In<ELFT>::MipsGot->getGp();
|
||||
case R_PAGE_PC:
|
||||
case R_PLT_PAGE_PC:
|
||||
if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak())
|
||||
return getAArch64Page(A);
|
||||
return getAArch64Page(Body.getVA<ELFT>(A)) - getAArch64Page(P);
|
||||
case R_PC:
|
||||
if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak()) {
|
||||
// On ARM and AArch64 a branch to an undefined weak resolves to the
|
||||
// next instruction, otherwise the place.
|
||||
if (Config->EMachine == EM_ARM)
|
||||
return getARMUndefinedRelativeWeakVA(Type, A, P);
|
||||
if (Config->EMachine == EM_AARCH64)
|
||||
return getAArch64UndefinedRelativeWeakVA(Type, A, P);
|
||||
}
|
||||
return Body.getVA<ELFT>(A) - P;
|
||||
case R_PLT:
|
||||
return Body.getPltVA<ELFT>() + A;
|
||||
case R_PLT_PC:
|
||||
case R_PPC_PLT_OPD:
|
||||
return Body.getPltVA<ELFT>() + A - P;
|
||||
case R_PPC_OPD: {
|
||||
uint64_t SymVA = Body.getVA<ELFT>(A);
|
||||
// If we have an undefined weak symbol, we might get here with a symbol
|
||||
@ -408,22 +381,50 @@ getRelocTargetVA(uint32_t Type, typename ELFT::uint A, typename ELFT::uint P,
|
||||
}
|
||||
return SymVA - P;
|
||||
}
|
||||
case R_PC:
|
||||
if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak()) {
|
||||
// On ARM and AArch64 a branch to an undefined weak resolves to the
|
||||
// next instruction, otherwise the place.
|
||||
if (Config->EMachine == EM_ARM)
|
||||
return getARMUndefinedRelativeWeakVA(Type, A, P);
|
||||
if (Config->EMachine == EM_AARCH64)
|
||||
return getAArch64UndefinedRelativeWeakVA(Type, A, P);
|
||||
}
|
||||
case R_PPC_TOC:
|
||||
return getPPC64TocBase() + A;
|
||||
case R_RELAX_GOT_PC:
|
||||
return Body.getVA<ELFT>(A) - P;
|
||||
case R_PLT_PAGE_PC:
|
||||
case R_PAGE_PC:
|
||||
if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak())
|
||||
return getAArch64Page(A);
|
||||
return getAArch64Page(Body.getVA<ELFT>(A)) - getAArch64Page(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:
|
||||
// A weak undefined TLS symbol resolves to the base of the TLS
|
||||
// block, i.e. gets a value of zero. If we pass --gc-sections to
|
||||
// lld and .tbss is not referenced, it gets reclaimed and we don't
|
||||
// create a TLS program header. Therefore, we resolve this
|
||||
// statically to zero.
|
||||
if (Body.isTls() && (Body.isLazy() || Body.isUndefined()) &&
|
||||
Body.symbol()->isWeak())
|
||||
return 0;
|
||||
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_SIZE:
|
||||
return Body.getSize<ELFT>() + A;
|
||||
case R_THUNK_ABS:
|
||||
return Body.getThunkVA<ELFT>() + A;
|
||||
case R_THUNK_PC:
|
||||
case R_THUNK_PLT_PC:
|
||||
return Body.getThunkVA<ELFT>() + A - P;
|
||||
case R_TLSDESC:
|
||||
return In<ELFT>::Got->getGlobalDynAddr(Body) + A;
|
||||
case R_TLSDESC_PAGE:
|
||||
return getAArch64Page(In<ELFT>::Got->getGlobalDynAddr(Body) + A) -
|
||||
getAArch64Page(P);
|
||||
case R_TLSGD:
|
||||
return In<ELFT>::Got->getGlobalDynOffset(Body) + A -
|
||||
In<ELFT>::Got->getSize();
|
||||
case R_TLSGD_PC:
|
||||
return In<ELFT>::Got->getGlobalDynAddr(Body) + A - P;
|
||||
case R_TLSLD:
|
||||
return In<ELFT>::Got->getTlsIndexOff() + A - In<ELFT>::Got->getSize();
|
||||
case R_TLSLD_PC:
|
||||
return In<ELFT>::Got->getTlsIndexVA() + A - P;
|
||||
}
|
||||
llvm_unreachable("Invalid expression");
|
||||
}
|
||||
|
@ -34,26 +34,26 @@ enum RelExpr {
|
||||
R_GOT_PAGE_PC,
|
||||
R_GOT_PC,
|
||||
R_HINT,
|
||||
R_MIPS_GOTREL,
|
||||
R_MIPS_GOT_LOCAL_PAGE,
|
||||
R_MIPS_GOT_OFF,
|
||||
R_MIPS_GOT_OFF32,
|
||||
R_MIPS_GOTREL,
|
||||
R_MIPS_TLSGD,
|
||||
R_MIPS_TLSLD,
|
||||
R_NEG_TLS,
|
||||
R_PAGE_PC,
|
||||
R_PC,
|
||||
R_PLT,
|
||||
R_PLT_PC,
|
||||
R_PLT_PAGE_PC,
|
||||
R_PLT_PC,
|
||||
R_PPC_OPD,
|
||||
R_PPC_PLT_OPD,
|
||||
R_PPC_TOC,
|
||||
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_IE_ABS,
|
||||
R_RELAX_TLS_GD_TO_IE_END,
|
||||
R_RELAX_TLS_GD_TO_IE_PAGE_PC,
|
||||
R_RELAX_TLS_GD_TO_LE,
|
||||
R_RELAX_TLS_GD_TO_LE_NEG,
|
||||
@ -65,8 +65,8 @@ enum RelExpr {
|
||||
R_THUNK_PLT_PC,
|
||||
R_TLS,
|
||||
R_TLSDESC,
|
||||
R_TLSDESC_PAGE,
|
||||
R_TLSDESC_CALL,
|
||||
R_TLSDESC_PAGE,
|
||||
R_TLSGD,
|
||||
R_TLSGD_PC,
|
||||
R_TLSLD,
|
||||
|
Loading…
Reference in New Issue
Block a user