De-template SharedSymbol.

Differential Revision: https://reviews.llvm.org/D30351

llvm-svn: 296303
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index f0572d2..d158883 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -78,7 +78,7 @@
     return In<ELFT>::Common->OutSec->Addr + In<ELFT>::Common->OutSecOff +
            cast<DefinedCommon>(Body).Offset;
   case SymbolBody::SharedKind: {
-    auto &SS = cast<SharedSymbol<ELFT>>(Body);
+    auto &SS = cast<SharedSymbol>(Body);
     if (SS.NeedsCopy)
       return SS.Section->OutSec->Addr + SS.Section->OutSecOff;
     if (SS.NeedsPltAddr)
@@ -167,8 +167,8 @@
     return C->Size;
   if (const auto *DR = dyn_cast<DefinedRegular<ELFT>>(this))
     return DR->Size;
-  if (const auto *S = dyn_cast<SharedSymbol<ELFT>>(this))
-    return S->Sym.st_size;
+  if (const auto *S = dyn_cast<SharedSymbol>(this))
+    return S->getSize<ELFT>();
   return 0;
 }
 
@@ -237,6 +237,17 @@
   this->File = File;
 }
 
+// If a shared symbol is referred via a copy relocation, its alignment
+// becomes part of the ABI. This function returns a symbol alignment.
+// Because symbols don't have alignment attributes, we need to infer that.
+template <class ELFT> uint64_t SharedSymbol::getAlignment() const {
+  auto *File = cast<SharedFile<ELFT>>(this->File);
+  uint64_t SecAlign = File->getSection(getSym<ELFT>())->sh_addralign;
+  uint64_t SymValue = getSym<ELFT>().st_value;
+  uint64_t SymAlign = uint64_t(1) << countTrailingZeros(SymValue);
+  return std::min(SecAlign, SymAlign);
+}
+
 InputFile *Lazy::fetch() {
   if (auto *S = dyn_cast<LazyArchive>(this))
     return S->fetch();
@@ -348,12 +359,12 @@
 template uint64_t SymbolBody::template getSize<ELF64LE>() const;
 template uint64_t SymbolBody::template getSize<ELF64BE>() const;
 
-template class elf::SharedSymbol<ELF32LE>;
-template class elf::SharedSymbol<ELF32BE>;
-template class elf::SharedSymbol<ELF64LE>;
-template class elf::SharedSymbol<ELF64BE>;
-
 template class elf::DefinedRegular<ELF32LE>;
 template class elf::DefinedRegular<ELF32BE>;
 template class elf::DefinedRegular<ELF64LE>;
 template class elf::DefinedRegular<ELF64BE>;
+
+template uint64_t SharedSymbol::template getAlignment<ELF32LE>() const;
+template uint64_t SharedSymbol::template getAlignment<ELF32BE>() const;
+template uint64_t SharedSymbol::template getAlignment<ELF64LE>() const;
+template uint64_t SharedSymbol::template getAlignment<ELF64BE>() const;