Remove `Type` parameter from SymbolTable::insert(). NFC.
authorRui Ueyama <ruiu@google.com>
Fri, 12 Oct 2018 18:29:18 +0000 (18:29 +0000)
committerRui Ueyama <ruiu@google.com>
Fri, 12 Oct 2018 18:29:18 +0000 (18:29 +0000)
`Type` parameter was used only to check for TLS attribute mismatch,
but we can do that when we actually replace symbols, so we don't need
to type as an argument. This change should simplify the interface of
the symbol table a bit.

llvm-svn: 344394

lld/ELF/LinkerScript.cpp
lld/ELF/SymbolTable.cpp
lld/ELF/SymbolTable.h
lld/ELF/Symbols.cpp
lld/ELF/Symbols.h

index d189862..d1ca2a6 100644 (file)
@@ -169,7 +169,7 @@ void LinkerScript::addSymbol(SymbolAssignment *Cmd) {
   // Define a symbol.
   Symbol *Sym;
   uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
-  std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, /*Type*/ 0, Visibility,
+  std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, Visibility,
                                               /*CanOmitFromDynSym*/ false,
                                               /*File*/ nullptr);
   ExprValue Value = Cmd->Expression();
@@ -202,7 +202,7 @@ static void declareSymbol(SymbolAssignment *Cmd) {
   // 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, /*Type*/ 0, Visibility,
+  std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, Visibility,
                                               /*CanOmitFromDynSym*/ false,
                                               /*File*/ nullptr);
   replaceSymbol<Defined>(Sym, nullptr, Cmd->Name, STB_GLOBAL, Visibility,
index 38d0edc..f99b2a3 100644 (file)
@@ -197,6 +197,7 @@ std::pair<Symbol *, bool> SymbolTable::insertName(StringRef Name) {
     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;
@@ -209,7 +210,7 @@ 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(StringRef Name, uint8_t Type,
+std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name,
                                               uint8_t Visibility,
                                               bool CanOmitFromDynSym,
                                               InputFile *File) {
@@ -226,11 +227,6 @@ std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, uint8_t Type,
   if (!File || File->kind() == InputFile::ObjKind)
     S->IsUsedInRegularObj = true;
 
-  bool HasTlsAttr = !WasInserted && (!S->isLazy() || S->isTls());
-  if (HasTlsAttr && (Type == STT_TLS) != S->isTls())
-    error("TLS attribute mismatch: " + toString(*S) + "\n>>> defined in " +
-          toString(S->File) + "\n>>> defined in " + toString(File));
-
   return {S, WasInserted};
 }
 
@@ -243,8 +239,7 @@ Symbol *SymbolTable::addUndefined(StringRef Name, uint8_t Binding,
   Symbol *S;
   bool WasInserted;
   uint8_t Visibility = getVisibility(StOther);
-  std::tie(S, WasInserted) =
-      insert(Name, Type, Visibility, CanOmitFromDynSym, File);
+  std::tie(S, WasInserted) = insert(Name, Visibility, CanOmitFromDynSym, File);
 
   // An undefined symbol with non default visibility must be satisfied
   // in the same DSO.
@@ -392,7 +387,7 @@ Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment,
                                InputFile &File) {
   Symbol *S;
   bool WasInserted;
-  std::tie(S, WasInserted) = insert(N, Type, getVisibility(StOther),
+  std::tie(S, WasInserted) = insert(N, getVisibility(StOther),
                                     /*CanOmitFromDynSym*/ false, &File);
 
   int Cmp = compareDefined(S, WasInserted, Binding, N);
@@ -469,7 +464,7 @@ Symbol *SymbolTable::addDefined(StringRef Name, uint8_t StOther, uint8_t Type,
                                 SectionBase *Section, InputFile *File) {
   Symbol *S;
   bool WasInserted;
-  std::tie(S, WasInserted) = insert(Name, Type, getVisibility(StOther),
+  std::tie(S, WasInserted) = insert(Name, getVisibility(StOther),
                                     /*CanOmitFromDynSym*/ false, File);
   int Cmp = compareDefinedNonCommon(S, WasInserted, Binding, Section == nullptr,
                                     Value, Name);
@@ -491,7 +486,7 @@ void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> &File,
   // unchanged.
   Symbol *S;
   bool WasInserted;
-  std::tie(S, WasInserted) = insert(Name, Sym.getType(), STV_DEFAULT,
+  std::tie(S, WasInserted) = insert(Name, STV_DEFAULT,
                                     /*CanOmitFromDynSym*/ true, &File);
   // Make sure we preempt DSO symbols with default visibility.
   if (Sym.getVisibility() == STV_DEFAULT)
@@ -520,7 +515,7 @@ Symbol *SymbolTable::addBitcode(StringRef Name, uint8_t Binding,
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) =
-      insert(Name, Type, getVisibility(StOther), CanOmitFromDynSym, &F);
+      insert(Name, getVisibility(StOther), CanOmitFromDynSym, &F);
   int Cmp = compareDefinedNonCommon(S, WasInserted, Binding,
                                     /*IsAbs*/ false, /*Value*/ 0, Name);
   if (Cmp > 0)
index fbf2fd8..e91e5cc 100644 (file)
@@ -67,9 +67,8 @@ public:
                     uint8_t Binding, uint8_t StOther, uint8_t Type,
                     InputFile &File);
 
-  std::pair<Symbol *, bool> insert(StringRef Name, uint8_t Type,
-                                   uint8_t Visibility, bool CanOmitFromDynSym,
-                                   InputFile *File);
+  std::pair<Symbol *, bool> insert(StringRef Name, uint8_t Visibility,
+                                   bool CanOmitFromDynSym, InputFile *File);
 
   template <class ELFT> void fetchLazy(Symbol *Sym);
 
index 7a35377..0ed0ef6 100644 (file)
@@ -110,6 +110,8 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {
   case Symbol::LazyObjectKind:
     assert(Sym.IsUsedInRegularObj && "lazy symbol reached writer");
     return 0;
+  case Symbol::PlaceholderKind:
+    llvm_unreachable("placeholder symbol reached writer");
   }
   llvm_unreachable("invalid symbol kind");
 }
index 7bae773..f380861 100644 (file)
 
 namespace lld {
 namespace elf {
+class Symbol;
+class InputFile;
+} // namespace elf
+
+std::string toString(const elf::Symbol &);
+std::string toString(const elf::InputFile *);
+
+namespace elf {
 
 class ArchiveFile;
 class BitcodeFile;
@@ -50,6 +58,7 @@ struct StringRefZ {
 class Symbol {
 public:
   enum Kind {
+    PlaceholderKind,
     DefinedKind,
     SharedKind,
     UndefinedKind,
@@ -89,7 +98,7 @@ public:
   uint8_t Type;    // symbol type
   uint8_t StOther; // st_other field value
 
-  const uint8_t SymbolKind;
+  uint8_t SymbolKind;
 
   // Symbol visibility. This is the computed minimum visibility of all
   // observed non-DSO symbols.
@@ -359,6 +368,8 @@ void printTraceSymbol(Symbol *Sym);
 
 template <typename T, typename... ArgT>
 void replaceSymbol(Symbol *S, ArgT &&... Arg) {
+  using llvm::ELF::STT_TLS;
+
   static_assert(std::is_trivially_destructible<T>(),
                 "Symbol types must be trivially destructible");
   static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
@@ -379,6 +390,18 @@ void replaceSymbol(Symbol *S, ArgT &&... Arg) {
   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 && TlsMismatch && !Sym.isLazy())
+    error("TLS attribute mismatch: " + toString(Sym) + "\n>>> defined in " +
+          toString(Sym.File) + "\n>>> defined in " + toString(S->File));
+
   // Print out a log message if --trace-symbol was specified.
   // This is for debugging.
   if (S->Traced)
@@ -387,8 +410,6 @@ void replaceSymbol(Symbol *S, ArgT &&... Arg) {
 
 void warnUnorderableSymbol(const Symbol *Sym);
 } // namespace elf
-
-std::string toString(const elf::Symbol &B);
 } // namespace lld
 
 #endif