[ELF][MIPS] Fix initialization of TLS-related GOT entries
This patch allows static linking of TLS code. To do that it fixes
GOT entries initialization.
If TLS-related GOT entry created for a preemptible symbol i.e. has
a corresponding dynamic relocation, leave the entry initialized by zero.
Write down adjusted TLS symbol's values otherwise. For the adjustments
calculation use offsets for thread-local storage.
https://www.linux-mips.org/wiki/NPTL
llvm-svn: 280914
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 0244f02..af72aaa 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -93,7 +93,7 @@
InputSectionBase<ELFT> &C, typename ELFT::uint Offset,
typename ELFT::uint Addend, RelExpr Expr) {
if (Expr == R_MIPS_TLSLD) {
- if (Out<ELFT>::Got->addTlsIndex())
+ if (Out<ELFT>::Got->addTlsIndex() && Config->Pic)
Out<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel, Out<ELFT>::Got,
Out<ELFT>::Got->getTlsIndexOff(), false,
nullptr, 0});
@@ -101,7 +101,7 @@
return 1;
}
if (Target->isTlsGlobalDynamicRel(Type)) {
- if (Out<ELFT>::Got->addDynTlsEntry(Body)) {
+ if (Out<ELFT>::Got->addDynTlsEntry(Body) && Body.isPreemptible()) {
typedef typename ELFT::uint uintX_t;
uintX_t Off = Out<ELFT>::Got->getGlobalDynOffset(Body);
Out<ELFT>::RelaDyn->addReloc(
@@ -666,9 +666,9 @@
// for detailed description:
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
Out<ELFT>::Got->addMipsEntry(Body, Addend, Expr);
- if (Body.isTls())
+ if (Body.isTls() && Body.isPreemptible())
AddDyn({Target->TlsGotRel, Out<ELFT>::Got, Body.getGotOffset<ELFT>(),
- !Preemptible, &Body, 0});
+ false, &Body, 0});
continue;
}