[ELF] - fixed not properly handled @GOTTPOFF relocation against local symbols

This patch changes sequence of applying relocations, moving tls optimized relocation handling code before code for other locals.
Without that change relocation @GOTTPOFF against local symbol caused runtime error ("unrecognized reloc ...").
That change also should fix other tls optimized relocations, but I did not check them, that's a field for another patch.

R_X86_64_GOTTPOFF relocations against locals can be found when linking against libc.a(malloc.o):
000000000036 000600000016 R_X86_64_GOTTPOFF 0000000000000000 libc_tsd_MALLOC - 4
000000000131 000600000016 R_X86_64_GOTTPOFF 0000000000000000 libc_tsd_MALLOC - 4

Differential revision: http://reviews.llvm.org/D15581

llvm-svn: 256145
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 71dbc6c..51fac66 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -161,60 +161,66 @@
       continue;
     }
 
+    const Elf_Shdr *SymTab = File->getSymbolTable();
+    SymbolBody *Body = nullptr;
+    if (SymIndex >= SymTab->sh_info)
+      Body = File->getSymbolBody(SymIndex)->repl();
+
+    if (Target->isTlsOptimized(Type, Body)) {
+      uintX_t SymVA;
+      if (!Body)
+        SymVA = getLocalRelTarget(*File, RI, 0);
+      else if (Target->relocNeedsGot(Type, *Body))
+        SymVA = Out<ELFT>::Got->getEntryAddr(*Body);
+      else
+        SymVA = getSymVA<ELFT>(*Body);
+      // By optimizing TLS relocations, it is sometimes needed to skip
+      // relocations that immediately follow TLS relocations. This function
+      // knows how many slots we need to skip.
+      I += Target->relocateTlsOptimize(BufLoc, BufEnd, Type, AddrLoc, SymVA,
+                                       *Body);
+      continue;
+    }
+
     // Handle relocations for local symbols -- they never get
     // resolved so we don't allocate a SymbolBody.
-    const Elf_Shdr *SymTab = File->getSymbolTable();
-    if (SymIndex < SymTab->sh_info) {
-      uintX_t SymVA = getLocalRelTarget(*File, RI);
+    uintX_t A = getAddend<ELFT>(RI);
+    if (!Body) {
+      uintX_t SymVA = getLocalRelTarget(*File, RI, A);
       Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA, 0,
                           findMipsPairedReloc(Buf, SymIndex, Type, NextRelocs));
       continue;
     }
 
-    SymbolBody &Body = *File->getSymbolBody(SymIndex)->repl();
-
     if (Target->isTlsGlobalDynamicReloc(Type) &&
-        !Target->isTlsOptimized(Type, &Body)) {
+        !Target->isTlsOptimized(Type, Body)) {
       Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc,
-                          Out<ELFT>::Got->getGlobalDynAddr(Body) +
+                          Out<ELFT>::Got->getGlobalDynAddr(*Body) +
                               getAddend<ELFT>(RI));
       continue;
     }
 
-    if (Target->isTlsOptimized(Type, &Body)) {
-      uintX_t SymVA = Target->relocNeedsGot(Type, Body)
-                          ? Out<ELFT>::Got->getEntryAddr(Body)
-                          : getSymVA<ELFT>(Body);
-      // By optimizing TLS relocations, it is sometimes needed to skip
-      // relocations that immediately follow TLS relocations. This function
-      // knows how many slots we need to skip.
-      I += Target->relocateTlsOptimize(BufLoc, BufEnd, Type, AddrLoc, SymVA,
-                                       Body);
-      continue;
-    }
-
-    uintX_t SymVA = getSymVA<ELFT>(Body);
-    if (Target->relocNeedsPlt(Type, Body)) {
-      SymVA = Out<ELFT>::Plt->getEntryAddr(Body);
+    uintX_t SymVA = getSymVA<ELFT>(*Body);
+    if (Target->relocNeedsPlt(Type, *Body)) {
+      SymVA = Out<ELFT>::Plt->getEntryAddr(*Body);
       Type = Target->getPltRefReloc(Type);
-    } else if (Target->relocNeedsGot(Type, Body)) {
-      SymVA = Out<ELFT>::Got->getEntryAddr(Body);
-      if (Body.isTls())
+    } else if (Target->relocNeedsGot(Type, *Body)) {
+      SymVA = Out<ELFT>::Got->getEntryAddr(*Body);
+      if (Body->isTls())
         Type = Target->getTlsGotReloc(Type);
-    } else if (!Target->needsCopyRel(Type, Body) &&
-               isa<SharedSymbol<ELFT>>(Body)) {
+    } else if (!Target->needsCopyRel(Type, *Body) &&
+               isa<SharedSymbol<ELFT>>(*Body)) {
       continue;
-    } else if (Target->isTlsDynReloc(Type, Body) ||
-               Target->isSizeDynReloc(Type, Body)) {
+    } else if (Target->isTlsDynReloc(Type, *Body) ||
+               Target->isSizeDynReloc(Type, *Body)) {
       continue;
     } else if (Config->EMachine == EM_MIPS) {
-      if (Type == R_MIPS_HI16 && &Body == Config->MipsGpDisp)
+      if (Type == R_MIPS_HI16 && Body == Config->MipsGpDisp)
         SymVA = getMipsGpAddr<ELFT>() - AddrLoc;
-      else if (Type == R_MIPS_LO16 && &Body == Config->MipsGpDisp)
+      else if (Type == R_MIPS_LO16 && Body == Config->MipsGpDisp)
         SymVA = getMipsGpAddr<ELFT>() - AddrLoc + 4;
     }
-    uintX_t A = getAddend<ELFT>(RI);
-    uintX_t Size = getSymSize<ELFT>(Body);
+    uintX_t Size = getSymSize<ELFT>(*Body);
     Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA + A, Size + A,
                         findMipsPairedReloc(Buf, SymIndex, Type, NextRelocs));
   }