[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;
       }