[ELF] - R_X86_64_SIZE64/R_X86_64_SIZE32 relocations implemented.

R_X86_64_SIZE64/R_X86_64_SIZE32 relocations were introduced in 0.98v of "System V Application Binary Interface x86-64" (http://www.x86-64.org/documentation/abi.pdf).

Calculation for them is Z + A, where:
Z - Represents the size of the symbol whose index resides in the relocation entry.
A - Represents the addend used to compute the value of the relocatable field.

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

llvm-svn: 255332
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 2c58be3..4d24dd9 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -123,6 +123,14 @@
 }
 
 template <class ELFT>
+static typename llvm::object::ELFFile<ELFT>::uintX_t
+getSymSize(SymbolBody &Body) {
+  if (auto *SS = dyn_cast<Defined<ELFT>>(&Body))
+    return SS->Sym.st_size;
+  return 0;
+}
+
+template <class ELFT>
 template <bool isRela>
 void InputSectionBase<ELFT>::relocate(uint8_t *Buf, uint8_t *BufEnd,
                                       RelIteratorRange<isRela> Rels) {
@@ -153,7 +161,7 @@
     const Elf_Shdr *SymTab = File->getSymbolTable();
     if (SymIndex < SymTab->sh_info) {
       uintX_t SymVA = getLocalRelTarget(*File, RI);
-      Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA,
+      Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA, 0,
                           findMipsPairedReloc(Buf, Type, NextRelocs));
       continue;
     }
@@ -191,11 +199,13 @@
     } else if (!Target->relocNeedsCopy(Type, Body) &&
                isa<SharedSymbol<ELFT>>(Body)) {
       continue;
-    } else if (Target->isTlsDynReloc(Type)) {
+    } else if (Target->isTlsDynReloc(Type) ||
+               Target->isSizeDynReloc(Type, Body)) {
       continue;
     }
-    Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc,
-                        SymVA + getAddend<ELFT>(RI),
+    uintX_t A = getAddend<ELFT>(RI);
+    uintX_t Size = getSymSize<ELFT>(Body);
+    Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA + A, Size + A,
                         findMipsPairedReloc(Buf, Type, NextRelocs));
   }
 }