Don't store an Elf_Sym for most symbols.

Our symbol representation was redundant, and some times would get out of
sync. It had an Elf_Sym, but some fields were copied to SymbolBody.

Different parts of the code were checking the bits in SymbolBody and
others were checking Elf_Sym.

There are two general approaches to fix this:
* Copy the required information and don't store and Elf_Sym.
* Don't copy the information and always use the Elf_Smy.

The second way sounds tempting, but has a big problem: we would have to
template SymbolBody. I started doing it, but it requires templeting
*everything* and creates a bit chicken and egg problem at the driver
where we have to find ELFT before we can create an ArchiveFile for
example.

As much as possible I compared the test differences with what gold and
bfd produce to make sure they are still valid. In most cases we are just
adding hidden visibility to a local symbol, which is harmless.

In most tests this is a small speedup. The only slowdown was scylla
(1.006X). The largest speedup was clang with no --build-id, -O3 or
--gc-sections (i.e.: focus on the relocations): 1.019X.

llvm-svn: 265293
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index d4f6120..ae4fab1 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -31,7 +31,6 @@
 template <class ELFT>
 static typename ELFT::uint getSymVA(const SymbolBody &Body,
                                     typename ELFT::uint &Addend) {
-  typedef typename ELFT::Sym Elf_Sym;
   typedef typename ELFT::uint uintX_t;
 
   switch (Body.kind()) {
@@ -45,18 +44,24 @@
     auto &D = cast<DefinedRegular<ELFT>>(Body);
     InputSectionBase<ELFT> *SC = D.Section;
 
+    // According to the ELF spec reference to a local symbol from outside
+    // the group are not allowed. Unfortunately .eh_frame breaks that rule
+    // and must be treated specially. For now we just replace the symbol with
+    // 0.
+    if (SC == &InputSection<ELFT>::Discarded)
+      return 0;
+
     // This is an absolute symbol.
     if (!SC)
-      return D.Sym.st_value;
+      return D.Value;
 
-    const Elf_Sym &Sym = D.Sym;
-    uintX_t Offset = Sym.st_value;
-    if (Sym.getType() == STT_SECTION) {
+    uintX_t Offset = D.Value;
+    if (D.isSection()) {
       Offset += Addend;
       Addend = 0;
     }
     uintX_t VA = SC->OutSec->getVA() + SC->getOffset(Offset);
-    if (Sym.getType() == STT_TLS)
+    if (D.isTls())
       return VA - Out<ELFT>::TlsPhdr->p_vaddr;
     return VA;
   }
@@ -66,7 +71,7 @@
     auto &SS = cast<SharedSymbol<ELFT>>(Body);
     if (!SS.NeedsCopyOrPltAddr)
       return 0;
-    if (SS.IsFunc)
+    if (SS.isFunc())
       return Body.getPltVA<ELFT>();
     return Out<ELFT>::Bss->getVA() + SS.OffsetInBss;
   }
@@ -82,6 +87,13 @@
   llvm_unreachable("invalid symbol kind");
 }
 
+SymbolBody::SymbolBody(Kind K, uint32_t NameOffset, uint8_t Other, uint8_t Type)
+    : SymbolKind(K), MustBeInDynSym(false), NeedsCopyOrPltAddr(false),
+      Type(Type), Binding(STB_LOCAL), Other(Other), NameOffset(NameOffset) {
+  IsUsedInRegularObj =
+      K != SharedKind && K != LazyKind && K != DefinedBitcodeKind;
+}
+
 // Returns true if a symbol can be replaced at load-time by a symbol
 // with the same name defined in other ELF executable or DSO.
 bool SymbolBody::isPreemptible() const {
@@ -109,7 +121,7 @@
     return false;
   if (getVisibility() != STV_DEFAULT)
     return false;
-  if (Config->Bsymbolic || (Config->BsymbolicFunctions && IsFunc))
+  if (Config->Bsymbolic || (Config->BsymbolicFunctions && isFunc()))
     return false;
   return true;
 }
@@ -143,21 +155,17 @@
 }
 
 template <class ELFT> typename ELFT::uint SymbolBody::getSize() const {
-  if (const typename ELFT::Sym *Sym = getElfSym<ELFT>())
-    return Sym->st_size;
+  if (const auto *C = dyn_cast<DefinedCommon>(this))
+    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 *U = dyn_cast<UndefinedElf<ELFT>>(this))
+    return U->Size;
   return 0;
 }
 
-template <class ELFT> const typename ELFT::Sym *SymbolBody::getElfSym() const {
-  if (auto *S = dyn_cast<DefinedRegular<ELFT>>(this))
-    return &S->Sym;
-  if (auto *S = dyn_cast<SharedSymbol<ELFT>>(this))
-    return &S->Sym;
-  if (auto *S = dyn_cast<UndefinedElf<ELFT>>(this))
-    return &S->Sym;
-  return nullptr;
-}
-
 static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
   if (VA == STV_DEFAULT)
     return VB;
@@ -185,8 +193,9 @@
   if (L > R)
     return -Other->compare<ELFT>(this);
 
-  Visibility = Other->Visibility =
-      getMinVisibility(Visibility, Other->Visibility);
+  uint8_t V = getMinVisibility(getVisibility(), Other->getVisibility());
+  setVisibility(V);
+  Other->setVisibility(V);
 
   if (IsUsedInRegularObj || Other->IsUsedInRegularObj)
     IsUsedInRegularObj = Other->IsUsedInRegularObj = true;
@@ -212,48 +221,61 @@
   return isCommon() ? -1 : 1;
 }
 
-Defined::Defined(Kind K, StringRef Name, bool IsWeak, bool IsLocal,
-                 uint8_t Visibility, uint8_t Type)
-    : SymbolBody(K, Name, IsWeak, IsLocal, Visibility, Type) {}
+Defined::Defined(Kind K, StringRef Name, uint8_t Binding, uint8_t Visibility,
+                 uint8_t Type)
+    : SymbolBody(K, Name, Binding, Visibility, Type) {}
+
+Defined::Defined(Kind K, uint32_t NameOffset, uint8_t Visibility, uint8_t Type)
+    : SymbolBody(K, NameOffset, Visibility, Type) {}
 
 DefinedBitcode::DefinedBitcode(StringRef Name, bool IsWeak, uint8_t Visibility)
-    : Defined(DefinedBitcodeKind, Name, IsWeak, false, Visibility,
-              0 /* Type */) {}
+    : Defined(DefinedBitcodeKind, Name, IsWeak ? STB_WEAK : STB_GLOBAL,
+              Visibility, 0 /* Type */) {}
 
 bool DefinedBitcode::classof(const SymbolBody *S) {
   return S->kind() == DefinedBitcodeKind;
 }
 
-Undefined::Undefined(SymbolBody::Kind K, StringRef N, bool IsWeak,
+Undefined::Undefined(SymbolBody::Kind K, StringRef N, uint8_t Binding,
+                     uint8_t Other, uint8_t Type)
+    : SymbolBody(K, N, Binding, Other, Type), CanKeepUndefined(false) {}
+
+Undefined::Undefined(SymbolBody::Kind K, uint32_t NameOffset,
                      uint8_t Visibility, uint8_t Type)
-    : SymbolBody(K, N, IsWeak, false, Visibility, Type),
-      CanKeepUndefined(false) {}
+    : SymbolBody(K, NameOffset, Visibility, Type), CanKeepUndefined(false) {}
 
 Undefined::Undefined(StringRef N, bool IsWeak, uint8_t Visibility,
                      bool CanKeepUndefined)
-    : Undefined(SymbolBody::UndefinedKind, N, IsWeak, Visibility, 0 /* Type */) {
+    : Undefined(SymbolBody::UndefinedKind, N, IsWeak ? STB_WEAK : STB_GLOBAL,
+                Visibility, 0 /* Type */) {
   this->CanKeepUndefined = CanKeepUndefined;
 }
 
 template <typename ELFT>
 UndefinedElf<ELFT>::UndefinedElf(StringRef N, const Elf_Sym &Sym)
-    : Undefined(SymbolBody::UndefinedElfKind, N,
-                Sym.getBinding() == llvm::ELF::STB_WEAK, Sym.getVisibility(),
+    : Undefined(SymbolBody::UndefinedElfKind, N, Sym.getBinding(), Sym.st_other,
                 Sym.getType()),
-      Sym(Sym) {}
+      Size(Sym.st_size) {}
+
+template <typename ELFT>
+UndefinedElf<ELFT>::UndefinedElf(uint32_t NameOffset, const Elf_Sym &Sym)
+    : Undefined(SymbolBody::UndefinedElfKind, NameOffset, Sym.st_other,
+                Sym.getType()),
+      Size(Sym.st_size) {
+  assert(Sym.getBinding() == STB_LOCAL);
+}
 
 template <typename ELFT>
 DefinedSynthetic<ELFT>::DefinedSynthetic(StringRef N, uintX_t Value,
                                          OutputSectionBase<ELFT> &Section,
                                          uint8_t Visibility)
-    : Defined(SymbolBody::DefinedSyntheticKind, N, false, false, Visibility,
+    : Defined(SymbolBody::DefinedSyntheticKind, N, STB_GLOBAL, Visibility,
               0 /* Type */),
       Value(Value), Section(Section) {}
 
 DefinedCommon::DefinedCommon(StringRef N, uint64_t Size, uint64_t Alignment,
-                             bool IsWeak, uint8_t Visibility)
-    : Defined(SymbolBody::DefinedCommonKind, N, IsWeak, false, Visibility,
-              0 /* Type */),
+                             uint8_t Binding, uint8_t Visibility, uint8_t Type)
+    : Defined(SymbolBody::DefinedCommonKind, N, Binding, Visibility, Type),
       Alignment(Alignment), Size(Size) {}
 
 std::unique_ptr<InputFile> Lazy::getMember() {
@@ -317,11 +339,6 @@
 template uint64_t SymbolBody::template getSize<ELF64LE>() const;
 template uint64_t SymbolBody::template getSize<ELF64BE>() const;
 
-template const ELF32LE::Sym *SymbolBody::template getElfSym<ELF32LE>() const;
-template const ELF32BE::Sym *SymbolBody::template getElfSym<ELF32BE>() const;
-template const ELF64LE::Sym *SymbolBody::template getElfSym<ELF64LE>() const;
-template const ELF64BE::Sym *SymbolBody::template getElfSym<ELF64BE>() const;
-
 template uint32_t SymbolBody::template getThunkVA<ELF32LE>() const;
 template uint32_t SymbolBody::template getThunkVA<ELF32BE>() const;
 template uint64_t SymbolBody::template getThunkVA<ELF64LE>() const;