[lld] r360838 - Simplify SymbolTable::add{Defined, Undefined, ...} functions.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Wed May 15 19:14:00 PDT 2019


Author: ruiu
Date: Wed May 15 19:14:00 2019
New Revision: 360838

URL: http://llvm.org/viewvc/llvm-project?rev=360838&view=rev
Log:
Simplify SymbolTable::add{Defined,Undefined,...} functions.

SymbolTable's add-family functions have lots of parameters because
when they have to create a new symbol, they forward given arguments
to Symbol's constructors. Therefore, the functions take at least as
many arguments as their corresponding constructors.

This patch simplifies the add-family functions. Now, the functions
take a symbol instead of arguments to construct a symbol. If there's
no existing symbol, a given symbol is memcpy'ed to the symbol table.
Otherwise, the functions attempt to merge the existing and a given
new symbol.

I also eliminated `CanOmitFromDynSym` parameter, so that the functions
take really one argument.

Symbol classes are trivially constructible, so looks like constructing
them to pass to add-family functions is as cheap as passing a lot of
arguments to the functions. A quick benchmark showed that this patch
seems performance-neutral.

This is a preparation for
http://lists.llvm.org/pipermail/llvm-dev/2019-April/131902.html

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

Modified:
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/LTO.cpp
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/SymbolTable.h
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=360838&r1=360837&r2=360838&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Wed May 15 19:14:00 2019
@@ -1329,14 +1329,14 @@ template <class ELFT> static void handle
 // that point to a non-existent DSO.
 static void demoteSharedSymbols() {
   for (Symbol *Sym : Symtab->getSymbols()) {
-    if (auto *S = dyn_cast<SharedSymbol>(Sym)) {
-      if (!S->getFile().IsNeeded) {
-        bool Used = S->Used;
-        replaceSymbol<Undefined>(S, nullptr, S->getName(), STB_WEAK, S->StOther,
-                                 S->Type);
-        S->Used = Used;
-      }
-    }
+    auto *S = dyn_cast<SharedSymbol>(Sym);
+    if (!S || S->getFile().IsNeeded)
+      continue;
+
+    bool Used = S->Used;
+    Undefined New(nullptr, S->getName(), STB_WEAK, S->StOther, S->Type);
+    replaceSymbol(S, &New);
+    S->Used = Used;
   }
 }
 
@@ -1405,8 +1405,8 @@ static void findKeepUniqueSections(opt::
 }
 
 template <class ELFT> static Symbol *addUndefined(StringRef Name) {
-  return Symtab->addUndefined<ELFT>(Name, STB_GLOBAL, STV_DEFAULT, 0, false,
-                                    nullptr);
+  return Symtab->addUndefined<ELFT>(
+      Undefined{nullptr, Name, STB_GLOBAL, STV_DEFAULT, 0});
 }
 
 // The --wrap option is a feature to rename symbols so that you can write

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=360838&r1=360837&r2=360838&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Wed May 15 19:14:00 2019
@@ -864,13 +864,12 @@ template <class ELFT> void ObjFile<ELFT>
 }
 
 template <class ELFT> Symbol *ObjFile<ELFT>::createSymbol(const Elf_Sym *Sym) {
-  int Binding = Sym->getBinding();
-
   uint32_t SecIdx = getSectionIndex(*Sym);
   if (SecIdx >= this->Sections.size())
     fatal(toString(this) + ": invalid section index: " + Twine(SecIdx));
 
   InputSectionBase *Sec = this->Sections[SecIdx];
+  uint8_t Binding = Sym->getBinding();
   uint8_t StOther = Sym->st_other;
   uint8_t Type = Sym->getType();
   uint64_t Value = Sym->st_value;
@@ -886,7 +885,6 @@ template <class ELFT> Symbol *ObjFile<EL
     StringRefZ Name = this->StringTable.data() + Sym->st_name;
     if (Sym->st_shndx == SHN_UNDEF)
       return make<Undefined>(this, Name, Binding, StOther, Type);
-
     return make<Defined>(this, Name, Binding, StOther, Type, Value, Size, Sec);
   }
 
@@ -894,26 +892,27 @@ template <class ELFT> Symbol *ObjFile<EL
 
   switch (Sym->st_shndx) {
   case SHN_UNDEF:
-    return Symtab->addUndefined<ELFT>(Name, Binding, StOther, Type,
-                                      /*CanOmitFromDynSym=*/false, this);
+    return Symtab->addUndefined<ELFT>(
+        Undefined{this, Name, Binding, StOther, Type});
   case SHN_COMMON:
     if (Value == 0 || Value >= UINT32_MAX)
       fatal(toString(this) + ": common symbol '" + Name +
             "' has invalid alignment: " + Twine(Value));
-    return Symtab->addCommon(Name, Size, Value, Binding, StOther, Type, *this);
+    return Symtab->addCommon(
+        Defined{this, Name, Binding, StOther, Type, Value, Size, nullptr});
   }
 
   switch (Binding) {
   default:
-    fatal(toString(this) + ": unexpected binding: " + Twine(Binding));
+    fatal(toString(this) + ": unexpected binding: " + Twine((int)Binding));
   case STB_GLOBAL:
   case STB_WEAK:
   case STB_GNU_UNIQUE:
     if (Sec == &InputSection::Discarded)
-      return Symtab->addUndefined<ELFT>(Name, Binding, StOther, Type,
-                                        /*CanOmitFromDynSym=*/false, this);
-    return Symtab->addDefined(Name, StOther, Type, Value, Size, Binding, Sec,
-                              this);
+      return Symtab->addUndefined<ELFT>(
+          Undefined{this, Name, Binding, StOther, Type});
+    return Symtab->addDefined(
+        Defined{this, Name, Binding, StOther, Type, Value, Size, Sec});
   }
 }
 
@@ -923,7 +922,7 @@ ArchiveFile::ArchiveFile(std::unique_ptr
 
 template <class ELFT> void ArchiveFile::parse() {
   for (const Archive::Symbol &Sym : File->symbols())
-    Symtab->addLazyArchive<ELFT>(Sym.getName(), *this, Sym);
+    Symtab->addLazyArchive<ELFT>(LazyArchive{*this, Sym});
 }
 
 // Returns a buffer pointing to a member file containing a given symbol.
@@ -1124,9 +1123,8 @@ template <class ELFT> void SharedFile::p
     }
 
     if (Sym.isUndefined()) {
-      Symbol *S = Symtab->addUndefined<ELFT>(Name, Sym.getBinding(),
-                                             Sym.st_other, Sym.getType(),
-                                             /*CanOmitFromDynSym=*/false, this);
+      Symbol *S = Symtab->addUndefined<ELFT>(
+          Undefined{this, Name, Sym.getBinding(), Sym.st_other, Sym.getType()});
       S->ExportDynamic = true;
       continue;
     }
@@ -1139,10 +1137,12 @@ template <class ELFT> void SharedFile::p
         Name == "_gp_disp")
       continue;
 
-    uint64_t Alignment = getAlignment<ELFT>(Sections, Sym);
-    if (!(Versyms[I] & VERSYM_HIDDEN))
-      Symtab->addShared(Name, Sym.getBinding(), Sym.st_other, Sym.getType(),
-                        Sym.st_value, Sym.st_size, Alignment, Idx, this);
+    uint32_t Alignment = getAlignment<ELFT>(Sections, Sym);
+    if (!(Versyms[I] & VERSYM_HIDDEN)) {
+      Symtab->addShared(SharedSymbol{*this, Name, Sym.getBinding(),
+                                     Sym.st_other, Sym.getType(), Sym.st_value,
+                                     Sym.st_size, Alignment, Idx});
+    }
 
     // Also add the symbol with the versioned name to handle undefined symbols
     // with explicit versions.
@@ -1161,9 +1161,9 @@ template <class ELFT> void SharedFile::p
         reinterpret_cast<const Elf_Verdef *>(Verdefs[Idx])->getAux()->vda_name;
     VersionedNameBuffer.clear();
     Name = (Name + "@" + VerName).toStringRef(VersionedNameBuffer);
-    Symtab->addShared(Saver.save(Name), Sym.getBinding(), Sym.st_other,
-                      Sym.getType(), Sym.st_value, Sym.st_size, Alignment, Idx,
-                      this);
+    Symtab->addShared(SharedSymbol{*this, Saver.save(Name), Sym.getBinding(),
+                                   Sym.st_other, Sym.getType(), Sym.st_value,
+                                   Sym.st_size, Alignment, Idx});
   }
 }
 
@@ -1252,28 +1252,28 @@ static Symbol *createBitcodeSymbol(const
                                    const lto::InputFile::Symbol &ObjSym,
                                    BitcodeFile &F) {
   StringRef Name = Saver.save(ObjSym.getName());
-  uint32_t Binding = ObjSym.isWeak() ? STB_WEAK : STB_GLOBAL;
-
+  uint8_t Binding = ObjSym.isWeak() ? STB_WEAK : STB_GLOBAL;
   uint8_t Type = ObjSym.isTLS() ? STT_TLS : STT_NOTYPE;
   uint8_t Visibility = mapVisibility(ObjSym.getVisibility());
   bool CanOmitFromDynSym = ObjSym.canBeOmittedFromSymbolTable();
 
   int C = ObjSym.getComdatIndex();
-  if (C != -1 && !KeptComdats[C])
-    return Symtab->addUndefined<ELFT>(Name, Binding, Visibility, Type,
-                                      CanOmitFromDynSym, &F);
-
-  if (ObjSym.isUndefined())
-    return Symtab->addUndefined<ELFT>(Name, Binding, Visibility, Type,
-                                      CanOmitFromDynSym, &F);
+  if (ObjSym.isUndefined() || (C != -1 && !KeptComdats[C])) {
+    Undefined New(&F, Name, Binding, Visibility, Type);
+    if (CanOmitFromDynSym)
+      New.ExportDynamic = false;
+    return Symtab->addUndefined<ELFT>(New);
+  }
 
   if (ObjSym.isCommon())
-    return Symtab->addCommon(Name, ObjSym.getCommonSize(),
-                             ObjSym.getCommonAlignment(), Binding, Visibility,
-                             STT_OBJECT, F);
-
-  return Symtab->addBitcode(Name, Binding, Visibility, Type, CanOmitFromDynSym,
-                            F);
+    return Symtab->addCommon(Defined{&F, Name, Binding, Visibility, STT_OBJECT,
+                                     ObjSym.getCommonAlignment(),
+                                     ObjSym.getCommonSize(), nullptr});
+
+  Defined New(&F, Name, Binding, Visibility, Type, 0, 0, nullptr);
+  if (CanOmitFromDynSym)
+    New.ExportDynamic = false;
+  return Symtab->addBitcode(New);
 }
 
 template <class ELFT>
@@ -1331,12 +1331,12 @@ void BinaryFile::parse() {
     if (!isAlnum(S[I]))
       S[I] = '_';
 
-  Symtab->addDefined(Saver.save(S + "_start"), STV_DEFAULT, STT_OBJECT, 0, 0,
-                     STB_GLOBAL, Section, nullptr);
-  Symtab->addDefined(Saver.save(S + "_end"), STV_DEFAULT, STT_OBJECT,
-                     Data.size(), 0, STB_GLOBAL, Section, nullptr);
-  Symtab->addDefined(Saver.save(S + "_size"), STV_DEFAULT, STT_OBJECT,
-                     Data.size(), 0, STB_GLOBAL, nullptr, nullptr);
+  Symtab->addDefined(Defined{nullptr, Saver.save(S + "_start"), STB_GLOBAL,
+                             STV_DEFAULT, STT_OBJECT, 0, 0, Section});
+  Symtab->addDefined(Defined{nullptr, Saver.save(S + "_end"), STB_GLOBAL,
+                             STV_DEFAULT, STT_OBJECT, Data.size(), 0, Section});
+  Symtab->addDefined(Defined{nullptr, Saver.save(S + "_size"), STB_GLOBAL,
+                             STV_DEFAULT, STT_OBJECT, Data.size(), 0, nullptr});
 }
 
 InputFile *elf::createObjectFile(MemoryBufferRef MB, StringRef ArchiveName,
@@ -1401,9 +1401,11 @@ template <class ELFT> void LazyObjFile::
   if (isBitcode(this->MB)) {
     std::unique_ptr<lto::InputFile> Obj =
         CHECK(lto::InputFile::create(this->MB), this);
-    for (const lto::InputFile::Symbol &Sym : Obj->symbols())
-      if (!Sym.isUndefined())
-        Symtab->addLazyObject<ELFT>(Saver.save(Sym.getName()), *this);
+    for (const lto::InputFile::Symbol &Sym : Obj->symbols()) {
+      if (Sym.isUndefined())
+        continue;
+      Symtab->addLazyObject<ELFT>(LazyObject{*this, Saver.save(Sym.getName())});
+    }
     return;
   }
 
@@ -1424,10 +1426,12 @@ template <class ELFT> void LazyObjFile::
     StringRef StringTable =
         CHECK(Obj.getStringTableForSymtab(Sec, Sections), this);
 
-    for (const typename ELFT::Sym &Sym : Syms.slice(FirstGlobal))
-      if (Sym.st_shndx != SHN_UNDEF)
-        Symtab->addLazyObject<ELFT>(CHECK(Sym.getName(StringTable), this),
-                                    *this);
+    for (const typename ELFT::Sym &Sym : Syms.slice(FirstGlobal)) {
+      if (Sym.st_shndx == SHN_UNDEF)
+        continue;
+      Symtab->addLazyObject<ELFT>(
+          LazyObject{*this, CHECK(Sym.getName(StringTable), this)});
+    }
     return;
   }
 }

Modified: lld/trunk/ELF/LTO.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LTO.cpp?rev=360838&r1=360837&r2=360838&view=diff
==============================================================================
--- lld/trunk/ELF/LTO.cpp (original)
+++ lld/trunk/ELF/LTO.cpp Wed May 15 19:14:00 2019
@@ -153,8 +153,8 @@ BitcodeCompiler::BitcodeCompiler() {
 BitcodeCompiler::~BitcodeCompiler() = default;
 
 static void undefine(Symbol *S) {
-  replaceSymbol<Undefined>(S, nullptr, S->getName(), STB_GLOBAL, STV_DEFAULT,
-                           S->Type);
+  Undefined New(nullptr, S->getName(), STB_GLOBAL, STV_DEFAULT, S->Type);
+  replaceSymbol(S, &New);
 }
 
 void BitcodeCompiler::add(BitcodeFile &F) {

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=360838&r1=360837&r2=360838&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Wed May 15 19:14:00 2019
@@ -166,13 +166,9 @@ void LinkerScript::addSymbol(SymbolAssig
     return;
 
   // Define a symbol.
-  Symbol *Sym;
-  uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
-  std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, Visibility,
-                                              /*CanOmitFromDynSym*/ false,
-                                              /*File*/ nullptr);
   ExprValue Value = Cmd->Expression();
   SectionBase *Sec = Value.isAbsolute() ? nullptr : Value.Sec;
+  uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
 
   // When this function is called, section addresses have not been
   // fixed yet. So, we may or may not know the value of the RHS
@@ -187,8 +183,12 @@ void LinkerScript::addSymbol(SymbolAssig
   // write expressions like this: `alignment = 16; . = ALIGN(., alignment)`.
   uint64_t SymValue = Value.Sec ? 0 : Value.getValue();
 
-  replaceSymbol<Defined>(Sym, nullptr, Cmd->Name, STB_GLOBAL, Visibility,
-                         STT_NOTYPE, SymValue, 0, Sec);
+  Defined New(nullptr, Cmd->Name, STB_GLOBAL, Visibility, STT_NOTYPE, SymValue,
+              0, Sec);
+
+  Symbol *Sym;
+  std::tie(Sym, std::ignore) = Symtab->insert(New);
+  replaceSymbol(Sym, &New);
   Cmd->Sym = cast<Defined>(Sym);
 }
 
@@ -198,14 +198,15 @@ static void declareSymbol(SymbolAssignme
   if (!shouldDefineSym(Cmd))
     return;
 
+  uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
+  Defined New(nullptr, Cmd->Name, STB_GLOBAL, Visibility, STT_NOTYPE, 0, 0,
+              nullptr);
+
   // We can't calculate final value right now.
   Symbol *Sym;
-  uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
-  std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, Visibility,
-                                              /*CanOmitFromDynSym*/ false,
-                                              /*File*/ nullptr);
-  replaceSymbol<Defined>(Sym, nullptr, Cmd->Name, STB_GLOBAL, Visibility,
-                         STT_NOTYPE, 0, 0, nullptr);
+  std::tie(Sym, std::ignore) = Symtab->insert(New);
+  replaceSymbol(Sym, &New);
+
   Cmd->Sym = cast<Defined>(Sym);
   Cmd->Provide = false;
   Sym->ScriptDefined = true;

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=360838&r1=360837&r2=360838&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Wed May 15 19:14:00 2019
@@ -529,8 +529,11 @@ static SmallSet<SharedSymbol *, 4> getSy
 static void replaceWithDefined(Symbol &Sym, SectionBase *Sec, uint64_t Value,
                                uint64_t Size) {
   Symbol Old = Sym;
-  replaceSymbol<Defined>(&Sym, Sym.File, Sym.getName(), Sym.Binding,
-                         Sym.StOther, Sym.Type, Value, Size, Sec);
+
+  Defined New(Sym.File, Sym.getName(), Sym.Binding, Sym.StOther, Sym.Type,
+              Value, Size, Sec);
+  replaceSymbol(&Sym, &New);
+
   Sym.PltIndex = Old.PltIndex;
   Sym.GotIndex = Old.GotIndex;
   Sym.VerdefIndex = Old.VerdefIndex;

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=360838&r1=360837&r2=360838&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Wed May 15 19:14:00 2019
@@ -86,14 +86,18 @@ static uint8_t getMinVisibility(uint8_t
   return std::min(VA, VB);
 }
 
-// Find an existing symbol or create and insert a new one.
-std::pair<Symbol *, bool> SymbolTable::insertName(StringRef Name) {
+// Find an existing symbol or create and insert a new one, then apply the given
+// attributes.
+std::pair<Symbol *, bool> SymbolTable::insert(const Symbol &New) {
+  // Find an existing symbol or create and insert a new one.
+
   // <name>@@<version> means the symbol is the default version. In that
   // case <name>@@<version> will be used to resolve references to <name>.
   //
   // Since this is a hot path, the following string search code is
   // optimized for speed. StringRef::find(char) is much faster than
   // StringRef::find(StringRef).
+  StringRef Name = New.getName();
   size_t Pos = Name.find('@');
   if (Pos != StringRef::npos && Pos + 1 < Name.size() && Name[Pos + 1] == '@')
     Name = Name.take_front(Pos);
@@ -109,70 +113,57 @@ std::pair<Symbol *, bool> SymbolTable::i
     Traced = true;
   }
 
-  if (!IsNew)
-    return {SymVector[SymIndex], false};
-
-  auto *Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
-  Sym->SymbolKind = Symbol::PlaceholderKind;
-  Sym->Visibility = STV_DEFAULT;
-  Sym->IsUsedInRegularObj = false;
-  Sym->ExportDynamic = false;
-  Sym->CanInline = true;
-  Sym->Traced = Traced;
-  Sym->VersionId = Config->DefaultSymbolVersion;
-  SymVector.push_back(Sym);
-  return {Sym, true};
-}
-
-// Find an existing symbol or create and insert a new one, then apply the given
-// attributes.
-std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name,
-                                              uint8_t Visibility,
-                                              bool CanOmitFromDynSym,
-                                              InputFile *File) {
-  Symbol *S;
-  bool WasInserted;
-  std::tie(S, WasInserted) = insertName(Name);
-
-  // Merge in the new symbol's visibility.
-  S->Visibility = getMinVisibility(S->Visibility, Visibility);
-
-  if (!CanOmitFromDynSym && (Config->Shared || Config->ExportDynamic))
-    S->ExportDynamic = true;
-
-  if (!File || File->kind() == InputFile::ObjKind)
-    S->IsUsedInRegularObj = true;
+  Symbol *Old;
+  if (IsNew) {
+    Old = reinterpret_cast<Symbol *>(make<SymbolUnion>());
+    SymVector.push_back(Old);
+
+    Old->SymbolKind = Symbol::PlaceholderKind;
+    Old->VersionId = Config->DefaultSymbolVersion;
+    Old->Visibility = STV_DEFAULT;
+    Old->IsUsedInRegularObj = false;
+    Old->ExportDynamic = false;
+    Old->CanInline = true;
+    Old->Traced = Traced;
+    Old->ScriptDefined = false;
+  } else {
+    Old = SymVector[SymIndex];
+  }
+
+  // Merge symbol properties.
+  Old->ExportDynamic = Old->ExportDynamic || New.ExportDynamic;
+  Old->IsUsedInRegularObj = Old->IsUsedInRegularObj || New.IsUsedInRegularObj;
+
+  // DSO symbols do not affect visibility in the output.
+  if (!isa<SharedSymbol>(&New))
+    Old->Visibility = getMinVisibility(Old->Visibility, New.Visibility);
 
-  return {S, WasInserted};
+  return {Old, IsNew};
 }
 
-static uint8_t getVisibility(uint8_t StOther) { return StOther & 3; }
-
-template <class ELFT>
-Symbol *SymbolTable::addUndefined(StringRef Name, uint8_t Binding,
-                                  uint8_t StOther, uint8_t Type,
-                                  bool CanOmitFromDynSym, InputFile *File) {
-  Symbol *S;
+template <class ELFT> Symbol *SymbolTable::addUndefined(const Undefined &New) {
+  Symbol *Old;
   bool WasInserted;
-  uint8_t Visibility = getVisibility(StOther);
-  std::tie(S, WasInserted) = insert(Name, Visibility, CanOmitFromDynSym, File);
+  std::tie(Old, WasInserted) = insert(New);
 
   // An undefined symbol with non default visibility must be satisfied
   // in the same DSO.
-  if (WasInserted || (isa<SharedSymbol>(S) && Visibility != STV_DEFAULT)) {
-    replaceSymbol<Undefined>(S, File, Name, Binding, StOther, Type);
-    return S;
+  if (WasInserted ||
+      (isa<SharedSymbol>(Old) && New.Visibility != STV_DEFAULT)) {
+    replaceSymbol(Old, &New);
+    return Old;
   }
 
-  if (S->isShared() || S->isLazy() || (S->isUndefined() && Binding != STB_WEAK))
-    S->Binding = Binding;
+  if (Old->isShared() || Old->isLazy() ||
+      (Old->isUndefined() && New.Binding != STB_WEAK))
+    Old->Binding = New.Binding;
 
-  if (S->isLazy()) {
+  if (Old->isLazy()) {
     // An undefined weak will not fetch archive members. See comment on Lazy in
     // Symbols.h for the details.
-    if (Binding == STB_WEAK) {
-      S->Type = Type;
-      return S;
+    if (New.Binding == STB_WEAK) {
+      Old->Type = New.Type;
+      return Old;
     }
 
     // Do extra check for --warn-backrefs.
@@ -225,17 +216,17 @@ Symbol *SymbolTable::addUndefined(String
     // A forms group 0. B form group 1. C and D (including their member object
     // files) form group 2. E forms group 3. I think that you can see how this
     // group assignment rule simulates the traditional linker's semantics.
-    bool Backref =
-        Config->WarnBackrefs && File && S->File->GroupId < File->GroupId;
-    fetchLazy<ELFT>(S);
+    bool Backref = Config->WarnBackrefs && New.File &&
+                   Old->File->GroupId < New.File->GroupId;
+    fetchLazy<ELFT>(Old);
 
     // We don't report backward references to weak symbols as they can be
     // overridden later.
-    if (Backref && !S->isWeak())
-      warn("backward reference detected: " + Name + " in " + toString(File) +
-           " refers to " + toString(S->File));
+    if (Backref && !Old->isWeak())
+      warn("backward reference detected: " + New.getName() + " in " +
+           toString(New.File) + " refers to " + toString(Old->File));
   }
-  return S;
+  return Old;
 }
 
 // Using .symver foo,foo@@VER unfortunately creates two symbols: foo and
@@ -244,12 +235,12 @@ Symbol *SymbolTable::addUndefined(String
 // FIXME: If users can transition to using
 // .symver foo,foo@@@VER
 // we can delete this hack.
-static int compareVersion(Symbol *S, StringRef Name) {
-  bool A = Name.contains("@@");
-  bool B = S->getName().contains("@@");
-  if (A && !B)
-    return 1;
+static int compareVersion(StringRef OldName, StringRef NewName) {
+  bool A = OldName.contains("@@");
+  bool B = NewName.contains("@@");
   if (!A && B)
+    return 1;
+  if (A && !B)
     return -1;
   return 0;
 }
@@ -257,17 +248,14 @@ static int compareVersion(Symbol *S, Str
 // We have a new defined symbol with the specified binding. Return 1 if the new
 // symbol should win, -1 if the new symbol should lose, or 0 if both symbols are
 // strong defined symbols.
-static int compareDefined(Symbol *S, bool WasInserted, uint8_t Binding,
-                          StringRef Name) {
-  if (WasInserted)
-    return 1;
-  if (!S->isDefined())
+static int compareDefined(const Symbol *Old, const Symbol *New) {
+  if (!Old->isDefined())
     return 1;
-  if (int R = compareVersion(S, Name))
-    return R;
-  if (Binding == STB_WEAK)
+  if (int Cmp = compareVersion(Old->getName(), New->getName()))
+    return Cmp;
+  if (New->Binding == STB_WEAK)
     return -1;
-  if (S->isWeak())
+  if (Old->isWeak())
     return 1;
   return 0;
 }
@@ -275,65 +263,77 @@ static int compareDefined(Symbol *S, boo
 // We have a new non-common defined symbol with the specified binding. Return 1
 // if the new symbol should win, -1 if the new symbol should lose, or 0 if there
 // is a conflict. If the new symbol wins, also update the binding.
-static int compareDefinedNonCommon(Symbol *S, bool WasInserted, uint8_t Binding,
-                                   bool IsAbsolute, uint64_t Value,
-                                   StringRef Name) {
-  if (int Cmp = compareDefined(S, WasInserted, Binding, Name))
+static int compareDefinedNonCommon(const Symbol *OldSym, const Defined *New) {
+  if (int Cmp = compareDefined(OldSym, New))
     return Cmp;
-  if (auto *R = dyn_cast<Defined>(S)) {
-    if (R->Section && isa<BssSection>(R->Section)) {
+
+  if (auto *Old = dyn_cast<Defined>(OldSym)) {
+    if (Old->Section && isa<BssSection>(Old->Section)) {
       // Non-common symbols take precedence over common symbols.
       if (Config->WarnCommon)
-        warn("common " + S->getName() + " is overridden");
+        warn("common " + Old->getName() + " is overridden");
       return 1;
     }
-    if (R->Section == nullptr && Binding == STB_GLOBAL && IsAbsolute &&
-        R->Value == Value)
+
+    if (New->File && isa<BitcodeFile>(New->File))
+      return 0;
+
+    if (Old->Section == nullptr && New->Section == nullptr &&
+        Old->Value == New->Value && New->Binding == STB_GLOBAL)
       return -1;
   }
   return 0;
 }
 
-Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment,
-                               uint8_t Binding, uint8_t StOther, uint8_t Type,
-                               InputFile &File) {
-  Symbol *S;
+Symbol *SymbolTable::addCommon(const Defined &New) {
+  Symbol *Old;
   bool WasInserted;
-  std::tie(S, WasInserted) = insert(N, getVisibility(StOther),
-                                    /*CanOmitFromDynSym*/ false, &File);
-
-  int Cmp = compareDefined(S, WasInserted, Binding, N);
-  if (Cmp < 0)
-    return S;
+  std::tie(Old, WasInserted) = insert(New);
 
-  if (Cmp > 0) {
-    auto *Bss = make<BssSection>("COMMON", Size, Alignment);
-    Bss->File = &File;
+  auto Replace = [&] {
+    auto *Bss = make<BssSection>("COMMON", New.Size, New.Value);
+    Bss->File = New.File;
     Bss->Live = !Config->GcSections;
     InputSections.push_back(Bss);
 
-    replaceSymbol<Defined>(S, &File, N, Binding, StOther, Type, 0, Size, Bss);
-    return S;
+    Defined Sym = New;
+    Sym.Value = 0;
+    Sym.Section = Bss;
+    replaceSymbol(Old, &Sym);
+  };
+
+  if (WasInserted) {
+    Replace();
+    return Old;
+  }
+
+  int Cmp = compareDefined(Old, &New);
+  if (Cmp < 0)
+    return Old;
+
+  if (Cmp > 0) {
+    Replace();
+    return Old;
   }
 
-  auto *D = cast<Defined>(S);
+  auto *D = cast<Defined>(Old);
   auto *Bss = dyn_cast_or_null<BssSection>(D->Section);
   if (!Bss) {
     // Non-common symbols take precedence over common symbols.
     if (Config->WarnCommon)
-      warn("common " + S->getName() + " is overridden");
-    return S;
+      warn("common " + Old->getName() + " is overridden");
+    return Old;
   }
 
   if (Config->WarnCommon)
     warn("multiple common of " + D->getName());
 
-  Bss->Alignment = std::max(Bss->Alignment, Alignment);
-  if (Size > Bss->Size) {
-    D->File = Bss->File = &File;
-    D->Size = Bss->Size = Size;
+  Bss->Alignment = std::max<uint32_t>(Bss->Alignment, New.Value);
+  if (New.Size > Bss->Size) {
+    D->File = Bss->File = New.File;
+    D->Size = Bss->Size = New.Size;
   }
-  return S;
+  return Old;
 }
 
 static void reportDuplicate(Symbol *Sym, InputFile *NewFile,
@@ -371,66 +371,62 @@ static void reportDuplicate(Symbol *Sym,
   error(Msg);
 }
 
-Defined *SymbolTable::addDefined(StringRef Name, uint8_t StOther, uint8_t Type,
-                                 uint64_t Value, uint64_t Size, uint8_t Binding,
-                                 SectionBase *Section, InputFile *File) {
-  Symbol *S;
+Defined *SymbolTable::addDefined(const Defined &New) {
+  Symbol *Old;
   bool WasInserted;
-  std::tie(S, WasInserted) = insert(Name, getVisibility(StOther),
-                                    /*CanOmitFromDynSym*/ false, File);
-  int Cmp = compareDefinedNonCommon(S, WasInserted, Binding, Section == nullptr,
-                                    Value, Name);
+  std::tie(Old, WasInserted) = insert(New);
+
+  if (WasInserted) {
+    replaceSymbol(Old, &New);
+    return cast<Defined>(Old);
+  }
+
+  int Cmp = compareDefinedNonCommon(Old, &New);
   if (Cmp > 0)
-    replaceSymbol<Defined>(S, File, Name, Binding, StOther, Type, Value, Size,
-                           Section);
+    replaceSymbol(Old, &New);
   else if (Cmp == 0)
-    reportDuplicate(S, File, dyn_cast_or_null<InputSectionBase>(Section),
-                    Value);
-  return cast<Defined>(S);
+    reportDuplicate(Old, New.File,
+                    dyn_cast_or_null<InputSectionBase>(New.Section), New.Value);
+  return cast<Defined>(Old);
 }
 
-void SymbolTable::addShared(StringRef Name, uint8_t Binding, uint8_t StOther,
-                            uint8_t Type, uint64_t Value, uint64_t Size,
-                            uint32_t Alignment, uint32_t VerdefIndex,
-                            InputFile *File) {
-  // DSO symbols do not affect visibility in the output, so we pass STV_DEFAULT
-  // as the visibility, which will leave the visibility in the symbol table
-  // unchanged.
-  Symbol *S;
+void SymbolTable::addShared(const SharedSymbol &New) {
+  Symbol *Old;
   bool WasInserted;
-  std::tie(S, WasInserted) = insert(Name, STV_DEFAULT,
-                                    /*CanOmitFromDynSym*/ true, File);
-  // Make sure we preempt DSO symbols with default visibility.
-  if (getVisibility(StOther) == STV_DEFAULT)
-    S->ExportDynamic = true;
+  std::tie(Old, WasInserted) = insert(New);
 
-  // An undefined symbol with non default visibility must be satisfied
-  // in the same DSO.
-  auto Replace = [&](uint8_t Binding) {
-    replaceSymbol<SharedSymbol>(S, *File, Name, Binding, StOther, Type, Value,
-                                Size, Alignment, VerdefIndex);
-  };
+  // Make sure we preempt DSO symbols with default visibility.
+  if (New.Visibility == STV_DEFAULT)
+    Old->ExportDynamic = true;
 
-  if (WasInserted)
-    Replace(Binding);
-  else if (S->Visibility == STV_DEFAULT && (S->isUndefined() || S->isLazy()))
-    Replace(S->Binding);
+  if (WasInserted) {
+    replaceSymbol(Old, &New);
+  } else if (Old->Visibility == STV_DEFAULT &&
+             (Old->isUndefined() || Old->isLazy())) {
+    // An undefined symbol with non default visibility must be satisfied
+    // in the same DSO.
+    uint8_t Binding = Old->Binding;
+    replaceSymbol(Old, &New);
+    Old->Binding = Binding;
+  }
 }
 
-Symbol *SymbolTable::addBitcode(StringRef Name, uint8_t Binding,
-                                uint8_t StOther, uint8_t Type,
-                                bool CanOmitFromDynSym, BitcodeFile &F) {
-  Symbol *S;
+Symbol *SymbolTable::addBitcode(const Defined &New) {
+  Symbol *Old;
   bool WasInserted;
-  std::tie(S, WasInserted) =
-      insert(Name, getVisibility(StOther), CanOmitFromDynSym, &F);
-  int Cmp = compareDefinedNonCommon(S, WasInserted, Binding,
-                                    /*IsAbs*/ false, /*Value*/ 0, Name);
+  std::tie(Old, WasInserted) = insert(New);
+
+  if (WasInserted) {
+    replaceSymbol(Old, &New);
+    return Old;
+  }
+
+  int Cmp = compareDefinedNonCommon(Old, &New);
   if (Cmp > 0)
-    replaceSymbol<Defined>(S, &F, Name, Binding, StOther, Type, 0, 0, nullptr);
+    replaceSymbol(Old, &New);
   else if (Cmp == 0)
-    reportDuplicate(S, &F, nullptr, 0);
-  return S;
+    reportDuplicate(Old, New.File, nullptr, 0);
+  return Old;
 }
 
 Symbol *SymbolTable::find(StringRef Name) {
@@ -442,53 +438,39 @@ Symbol *SymbolTable::find(StringRef Name
   return SymVector[It->second];
 }
 
-template <class ELFT>
-void SymbolTable::addLazyArchive(StringRef Name, ArchiveFile &File,
-                                 const object::Archive::Symbol Sym) {
-  Symbol *S;
+template <class ELFT, class LazyT> void SymbolTable::addLazy(const LazyT &New) {
+  Symbol *Old;
   bool WasInserted;
-  std::tie(S, WasInserted) = insertName(Name);
+  std::tie(Old, WasInserted) = insert(New);
+
   if (WasInserted) {
-    replaceSymbol<LazyArchive>(S, File, STT_NOTYPE, Sym);
+    replaceSymbol(Old, &New);
     return;
   }
-  if (!S->isUndefined())
+
+  if (!Old->isUndefined())
     return;
 
   // An undefined weak will not fetch archive members. See comment on Lazy in
   // Symbols.h for the details.
-  if (S->isWeak()) {
-    replaceSymbol<LazyArchive>(S, File, S->Type, Sym);
-    S->Binding = STB_WEAK;
+  if (Old->isWeak()) {
+    uint8_t Type = Old->Type;
+    replaceSymbol(Old, &New);
+    Old->Type = Type;
+    Old->Binding = STB_WEAK;
     return;
   }
 
-  if (InputFile *F = File.fetch(Sym))
+  if (InputFile *F = New.fetch())
     parseFile<ELFT>(F);
 }
 
-template <class ELFT>
-void SymbolTable::addLazyObject(StringRef Name, LazyObjFile &File) {
-  Symbol *S;
-  bool WasInserted;
-  std::tie(S, WasInserted) = insertName(Name);
-  if (WasInserted) {
-    replaceSymbol<LazyObject>(S, File, STT_NOTYPE, Name);
-    return;
-  }
-  if (!S->isUndefined())
-    return;
-
-  // An undefined weak will not fetch archive members. See comment on Lazy in
-  // Symbols.h for the details.
-  if (S->isWeak()) {
-    replaceSymbol<LazyObject>(S, File, S->Type, Name);
-    S->Binding = STB_WEAK;
-    return;
-  }
+template <class ELFT> void SymbolTable::addLazyArchive(const LazyArchive &New) {
+  addLazy<ELFT>(New);
+}
 
-  if (InputFile *F = File.fetch())
-    parseFile<ELFT>(F);
+template <class ELFT> void SymbolTable::addLazyObject(const LazyObject &New) {
+  addLazy<ELFT>(New);
 }
 
 template <class ELFT> void SymbolTable::fetchLazy(Symbol *Sym) {
@@ -664,37 +646,25 @@ void SymbolTable::scanVersionScript() {
     Sym->parseSymbolVersion();
 }
 
-template Symbol *SymbolTable::addUndefined<ELF32LE>(StringRef, uint8_t, uint8_t,
-                                                    uint8_t, bool, InputFile *);
-template Symbol *SymbolTable::addUndefined<ELF32BE>(StringRef, uint8_t, uint8_t,
-                                                    uint8_t, bool, InputFile *);
-template Symbol *SymbolTable::addUndefined<ELF64LE>(StringRef, uint8_t, uint8_t,
-                                                    uint8_t, bool, InputFile *);
-template Symbol *SymbolTable::addUndefined<ELF64BE>(StringRef, uint8_t, uint8_t,
-                                                    uint8_t, bool, InputFile *);
+template Symbol *SymbolTable::addUndefined<ELF32LE>(const Undefined &);
+template Symbol *SymbolTable::addUndefined<ELF32BE>(const Undefined &);
+template Symbol *SymbolTable::addUndefined<ELF64LE>(const Undefined &);
+template Symbol *SymbolTable::addUndefined<ELF64BE>(const Undefined &);
 
 template void SymbolTable::addCombinedLTOObject<ELF32LE>();
 template void SymbolTable::addCombinedLTOObject<ELF32BE>();
 template void SymbolTable::addCombinedLTOObject<ELF64LE>();
 template void SymbolTable::addCombinedLTOObject<ELF64BE>();
 
-template void
-SymbolTable::addLazyArchive<ELF32LE>(StringRef, ArchiveFile &,
-                                     const object::Archive::Symbol);
-template void
-SymbolTable::addLazyArchive<ELF32BE>(StringRef, ArchiveFile &,
-                                     const object::Archive::Symbol);
-template void
-SymbolTable::addLazyArchive<ELF64LE>(StringRef, ArchiveFile &,
-                                     const object::Archive::Symbol);
-template void
-SymbolTable::addLazyArchive<ELF64BE>(StringRef, ArchiveFile &,
-                                     const object::Archive::Symbol);
-
-template void SymbolTable::addLazyObject<ELF32LE>(StringRef, LazyObjFile &);
-template void SymbolTable::addLazyObject<ELF32BE>(StringRef, LazyObjFile &);
-template void SymbolTable::addLazyObject<ELF64LE>(StringRef, LazyObjFile &);
-template void SymbolTable::addLazyObject<ELF64BE>(StringRef, LazyObjFile &);
+template void SymbolTable::addLazyArchive<ELF32LE>(const LazyArchive &);
+template void SymbolTable::addLazyArchive<ELF32BE>(const LazyArchive &);
+template void SymbolTable::addLazyArchive<ELF64LE>(const LazyArchive &);
+template void SymbolTable::addLazyArchive<ELF64BE>(const LazyArchive &);
+
+template void SymbolTable::addLazyObject<ELF32LE>(const LazyObject &);
+template void SymbolTable::addLazyObject<ELF32BE>(const LazyObject &);
+template void SymbolTable::addLazyObject<ELF64LE>(const LazyObject &);
+template void SymbolTable::addLazyObject<ELF64BE>(const LazyObject &);
 
 template void SymbolTable::fetchLazy<ELF32LE>(Symbol *);
 template void SymbolTable::fetchLazy<ELF32BE>(Symbol *);

Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=360838&r1=360837&r2=360838&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Wed May 15 19:14:00 2019
@@ -17,8 +17,13 @@
 
 namespace lld {
 namespace elf {
+
 class Defined;
+class LazyArchive;
+class LazyObject;
 class SectionBase;
+class SharedSymbol;
+class Undefined;
 
 // SymbolTable is a bucket of all known symbols, including defined,
 // undefined, or lazy symbols (the last one is symbols in archive
@@ -39,33 +44,19 @@ public:
 
   ArrayRef<Symbol *> getSymbols() const { return SymVector; }
 
-  template <class ELFT>
-  Symbol *addUndefined(StringRef Name, uint8_t Binding, uint8_t StOther,
-                       uint8_t Type, bool CanOmitFromDynSym, InputFile *File);
-
-  Defined *addDefined(StringRef Name, uint8_t StOther, uint8_t Type,
-                      uint64_t Value, uint64_t Size, uint8_t Binding,
-                      SectionBase *Section, InputFile *File);
-
-  void addShared(StringRef Name, uint8_t Binding, uint8_t StOther, uint8_t Type,
-                 uint64_t Value, uint64_t Size, uint32_t Alignment,
-                 uint32_t VerdefIndex, InputFile *File);
+  template <class ELFT> Symbol *addUndefined(const Undefined &New);
 
-  template <class ELFT>
-  void addLazyArchive(StringRef Name, ArchiveFile &F,
-                      const llvm::object::Archive::Symbol S);
+  Defined *addDefined(const Defined &New);
 
-  template <class ELFT> void addLazyObject(StringRef Name, LazyObjFile &Obj);
+  void addShared(const SharedSymbol &New);
 
-  Symbol *addBitcode(StringRef Name, uint8_t Binding, uint8_t StOther,
-                     uint8_t Type, bool CanOmitFromDynSym, BitcodeFile &File);
+  template <class ELFT> void addLazyArchive(const LazyArchive &New);
+  template <class ELFT> void addLazyObject(const LazyObject &New);
 
-  Symbol *addCommon(StringRef Name, uint64_t Size, uint32_t Alignment,
-                    uint8_t Binding, uint8_t StOther, uint8_t Type,
-                    InputFile &File);
+  Symbol *addBitcode(const Defined &New);
+  Symbol *addCommon(const Defined &New);
 
-  std::pair<Symbol *, bool> insert(StringRef Name, uint8_t Visibility,
-                                   bool CanOmitFromDynSym, InputFile *File);
+  std::pair<Symbol *, bool> insert(const Symbol &New);
 
   template <class ELFT> void fetchLazy(Symbol *Sym);
 
@@ -81,7 +72,7 @@ public:
   llvm::DenseMap<StringRef, SharedFile *> SoNames;
 
 private:
-  std::pair<Symbol *, bool> insertName(StringRef Name);
+  template <class ELFT, class LazyT> void addLazy(const LazyT &New);
 
   std::vector<Symbol *> findByVersion(SymbolVersion Ver);
   std::vector<Symbol *> findAllByVersion(SymbolVersion Ver);

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=360838&r1=360837&r2=360838&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Wed May 15 19:14:00 2019
@@ -239,7 +239,9 @@ void Symbol::parseSymbolVersion() {
           Verstr);
 }
 
-InputFile *LazyArchive::fetch() { return cast<ArchiveFile>(File)->fetch(Sym); }
+InputFile *LazyArchive::fetch() const {
+  return cast<ArchiveFile>(File)->fetch(Sym);
+}
 
 MemoryBufferRef LazyArchive::getMemberBuffer() {
   Archive::Child C = CHECK(
@@ -250,6 +252,10 @@ MemoryBufferRef LazyArchive::getMemberBu
                    Sym.getName());
 }
 
+InputFile *LazyObject::fetch() const {
+  return cast<LazyObjFile>(File)->fetch();
+}
+
 uint8_t Symbol::computeBinding() const {
   if (Config->Relocatable)
     return Binding;

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=360838&r1=360837&r2=360838&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Wed May 15 19:14:00 2019
@@ -172,10 +172,13 @@ protected:
   Symbol(Kind K, InputFile *File, StringRefZ Name, uint8_t Binding,
          uint8_t StOther, uint8_t Type)
       : File(File), NameData(Name.Data), NameSize(Name.Size), Binding(Binding),
-        Type(Type), StOther(StOther), SymbolKind(K), NeedsPltAddr(false),
-        IsInIplt(false), GotInIgot(false), IsPreemptible(false),
-        Used(!Config->GcSections), NeedsTocRestore(false),
-        ScriptDefined(false) {}
+        Type(Type), StOther(StOther), SymbolKind(K), Visibility(StOther & 3),
+        IsUsedInRegularObj(!File || File->kind() == InputFile::ObjKind),
+        ExportDynamic(K != SharedKind &&
+                      (Config->Shared || Config->ExportDynamic)),
+        CanInline(false), Traced(false), NeedsPltAddr(false), IsInIplt(false),
+        GotInIgot(false), IsPreemptible(false), Used(!Config->GcSections),
+        NeedsTocRestore(false), ScriptDefined(false) {}
 
 public:
   // True the symbol should point to its PLT entry.
@@ -289,15 +292,14 @@ public:
 // symbol.
 class LazyArchive : public Symbol {
 public:
-  LazyArchive(InputFile &File, uint8_t Type,
-              const llvm::object::Archive::Symbol S)
+  LazyArchive(InputFile &File, const llvm::object::Archive::Symbol S)
       : Symbol(LazyArchiveKind, &File, S.getName(), llvm::ELF::STB_GLOBAL,
-               llvm::ELF::STV_DEFAULT, Type),
+               llvm::ELF::STV_DEFAULT, llvm::ELF::STT_NOTYPE),
         Sym(S) {}
 
   static bool classof(const Symbol *S) { return S->kind() == LazyArchiveKind; }
 
-  InputFile *fetch();
+  InputFile *fetch() const;
   MemoryBufferRef getMemberBuffer();
 
 private:
@@ -308,11 +310,13 @@ private:
 // --start-lib and --end-lib options.
 class LazyObject : public Symbol {
 public:
-  LazyObject(InputFile &File, uint8_t Type, StringRef Name)
+  LazyObject(InputFile &File, StringRef Name)
       : Symbol(LazyObjectKind, &File, Name, llvm::ELF::STB_GLOBAL,
-               llvm::ELF::STV_DEFAULT, Type) {}
+               llvm::ELF::STV_DEFAULT, llvm::ELF::STT_NOTYPE) {}
 
   static bool classof(const Symbol *S) { return S->kind() == LazyObjectKind; }
+
+  InputFile *fetch() const;
 };
 
 // Some linker-generated symbols need to be created as
@@ -361,8 +365,7 @@ union SymbolUnion {
 
 void printTraceSymbol(Symbol *Sym);
 
-template <typename T, typename... ArgT>
-void replaceSymbol(Symbol *S, ArgT &&... Arg) {
+template <typename T> void replaceSymbol(Symbol *Sym, const T *New) {
   using llvm::ELF::STT_TLS;
 
   static_assert(std::is_trivially_destructible<T>(),
@@ -373,34 +376,35 @@ void replaceSymbol(Symbol *S, ArgT &&...
   assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
          "Not a Symbol");
 
-  Symbol Sym = *S;
-
-  new (S) T(std::forward<ArgT>(Arg)...);
-
-  S->VersionId = Sym.VersionId;
-  S->Visibility = Sym.Visibility;
-  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
-  S->ExportDynamic = Sym.ExportDynamic;
-  S->CanInline = Sym.CanInline;
-  S->Traced = Sym.Traced;
-  S->ScriptDefined = Sym.ScriptDefined;
-
   // Symbols representing thread-local variables must be referenced by
   // TLS-aware relocations, and non-TLS symbols must be reference by
   // non-TLS relocations, so there's a clear distinction between TLS
   // and non-TLS symbols. It is an error if the same symbol is defined
   // as a TLS symbol in one file and as a non-TLS symbol in other file.
-  bool TlsMismatch = (Sym.Type == STT_TLS && S->Type != STT_TLS) ||
-                     (Sym.Type != STT_TLS && S->Type == STT_TLS);
+  if (Sym->SymbolKind != Symbol::PlaceholderKind && !Sym->isLazy() &&
+      !New->isLazy()) {
+    bool TlsMismatch = (Sym->Type == STT_TLS && New->Type != STT_TLS) ||
+                       (Sym->Type != STT_TLS && New->Type == STT_TLS);
+    if (TlsMismatch)
+      error("TLS attribute mismatch: " + toString(*Sym) + "\n>>> defined in " +
+            toString(New->File) + "\n>>> defined in " + toString(Sym->File));
+  }
+
+  Symbol Old = *Sym;
+  memcpy(Sym, New, sizeof(T));
 
-  if (Sym.SymbolKind != Symbol::PlaceholderKind && TlsMismatch && !Sym.isLazy())
-    error("TLS attribute mismatch: " + toString(Sym) + "\n>>> defined in " +
-          toString(Sym.File) + "\n>>> defined in " + toString(S->File));
+  Sym->VersionId = Old.VersionId;
+  Sym->Visibility = Old.Visibility;
+  Sym->IsUsedInRegularObj = Old.IsUsedInRegularObj;
+  Sym->ExportDynamic = Old.ExportDynamic;
+  Sym->CanInline = Old.CanInline;
+  Sym->Traced = Old.Traced;
+  Sym->ScriptDefined = Old.ScriptDefined;
 
   // Print out a log message if --trace-symbol was specified.
   // This is for debugging.
-  if (S->Traced)
-    printTraceSymbol(S);
+  if (Sym->Traced)
+    printTraceSymbol(Sym);
 }
 
 void maybeWarnUnorderableSymbol(const Symbol *Sym);

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=360838&r1=360837&r2=360838&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed May 15 19:14:00 2019
@@ -179,14 +179,15 @@ static Defined *addOptionalRegular(Strin
   Symbol *S = Symtab->find(Name);
   if (!S || S->isDefined())
     return nullptr;
-  return Symtab->addDefined(Name, StOther, STT_NOTYPE, Val,
-                            /*Size=*/0, Binding, Sec,
-                            /*File=*/nullptr);
+
+  return Symtab->addDefined(Defined{/*File=*/nullptr, Name, Binding, StOther,
+                                    STT_NOTYPE, Val,
+                                    /*Size=*/0, Sec});
 }
 
 static Defined *addAbsolute(StringRef Name) {
-  return Symtab->addDefined(Name, STV_HIDDEN, STT_NOTYPE, 0, 0, STB_GLOBAL,
-                            nullptr, nullptr);
+  return Symtab->addDefined(Defined{nullptr, Name, STB_GLOBAL, STV_HIDDEN,
+                                    STT_NOTYPE, 0, 0, nullptr});
 }
 
 // The linker is expected to define some symbols depending on
@@ -236,9 +237,9 @@ void elf::addReservedSymbols() {
       GotOff = 0x8000;
 
     ElfSym::GlobalOffsetTable =
-        Symtab->addDefined(GotSymName, STV_HIDDEN, STT_NOTYPE, GotOff,
-                           /*Size=*/0, STB_GLOBAL, Out::ElfHeader,
-                           /*File=*/nullptr);
+        Symtab->addDefined(Defined{/*File=*/nullptr, GotSymName, STB_GLOBAL,
+                                   STV_HIDDEN, STT_NOTYPE, GotOff,
+                                   /*Size=*/0, Out::ElfHeader});
   }
 
   // __ehdr_start is the location of ELF file headers. Note that we define
@@ -1588,9 +1589,9 @@ template <class ELFT> void Writer<ELFT>:
   // Even the author of gold doesn't remember why gold behaves that way.
   // https://sourceware.org/ml/binutils/2002-03/msg00360.html
   if (In.Dynamic->Parent)
-    Symtab->addDefined("_DYNAMIC", STV_HIDDEN, STT_NOTYPE, 0 /*Value*/,
-                       /*Size=*/0, STB_WEAK, In.Dynamic,
-                       /*File=*/nullptr);
+    Symtab->addDefined(Defined{/*File=*/nullptr, "_DYNAMIC", STB_WEAK,
+                               STV_HIDDEN, STT_NOTYPE,
+                               /*Value=*/0, /*Size=*/0, In.Dynamic});
 
   // Define __rel[a]_iplt_{start,end} symbols if needed.
   addRelIpltSymbols();




More information about the llvm-commits mailing list