[lld] r265536 - Change the type hierarchy for undefined symbols.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 6 06:22:41 PDT 2016


Author: rafael
Date: Wed Apr  6 08:22:41 2016
New Revision: 265536

URL: http://llvm.org/viewvc/llvm-project?rev=265536&view=rev
Log:
Change the type hierarchy for undefined symbols.

We have to differentiate undefined symbols from bitcode and undefined
symbols from other sources.

Undefined symbols from bitcode should not inhibit the symbol being
internalized. Undefined symbols from other sources should.

Added:
    lld/trunk/test/ELF/lto/Inputs/internalize-undef.ll
    lld/trunk/test/ELF/lto/internalize-undef.ll
Modified:
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/OutputSections.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/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=265536&r1=265535&r2=265536&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Wed Apr  6 08:22:41 2016
@@ -473,7 +473,7 @@ BitcodeFile::createSymbolBody(const Dens
   uint32_t Flags = Sym.getFlags();
   bool IsWeak = Flags & BasicSymbolRef::SF_Weak;
   if (Flags & BasicSymbolRef::SF_Undefined) {
-    Body = new (Alloc) Undefined(NameRef, IsWeak, Visibility, false);
+    Body = new (Alloc) UndefinedBitcode(NameRef, IsWeak, Visibility);
   } else if (Flags & BasicSymbolRef::SF_Common) {
     const DataLayout &DL = M.getDataLayout();
     uint64_t Size = DL.getTypeAllocSize(GV->getValueType());

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=265536&r1=265535&r2=265536&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Wed Apr  6 08:22:41 2016
@@ -1501,7 +1501,7 @@ SymbolTableSection<ELFT>::getOutputSecti
       return Out<ELFT>::Bss;
     break;
   case SymbolBody::UndefinedElfKind:
-  case SymbolBody::UndefinedKind:
+  case SymbolBody::UndefinedBitcodeKind:
   case SymbolBody::LazyKind:
     break;
   case SymbolBody::DefinedBitcodeKind:

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=265536&r1=265535&r2=265536&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Wed Apr  6 08:22:41 2016
@@ -122,7 +122,8 @@ template <class ELFT> void SymbolTable<E
 // Add an undefined symbol.
 template <class ELFT>
 SymbolBody *SymbolTable<ELFT>::addUndefined(StringRef Name) {
-  auto *Sym = new (Alloc) Undefined(Name, false, STV_DEFAULT, false);
+  auto *Sym = new (Alloc)
+      UndefinedElf<ELFT>(Name, STB_GLOBAL, STV_DEFAULT, /*Type*/ 0, false);
   resolve(Sym);
   return Sym;
 }
@@ -131,7 +132,8 @@ SymbolBody *SymbolTable<ELFT>::addUndefi
 // doesn't have to be resolved, thus "opt" (optional).
 template <class ELFT>
 SymbolBody *SymbolTable<ELFT>::addUndefinedOpt(StringRef Name) {
-  auto *Sym = new (Alloc) Undefined(Name, false, STV_HIDDEN, true);
+  auto *Sym = new (Alloc)
+      UndefinedElf<ELFT>(Name, STB_GLOBAL, STV_HIDDEN, /*Type*/ 0, true);
   resolve(Sym);
   return Sym;
 }
@@ -222,8 +224,8 @@ template <class ELFT> void SymbolTable<E
   SymbolBody *Existing = Sym->Body;
 
   if (auto *L = dyn_cast<Lazy>(Existing)) {
-    if (auto *Undef = dyn_cast<Undefined>(New)) {
-      addMemberFile(Undef, L);
+    if (New->isUndefined()) {
+      addMemberFile(New, L);
       return;
     }
     // Found a definition for something also in an archive.
@@ -273,16 +275,17 @@ template <class ELFT> SymbolBody *Symbol
 
 template <class ELFT> void SymbolTable<ELFT>::addLazy(Lazy *L) {
   Symbol *Sym = insert(L);
-  if (Sym->Body == L)
+  SymbolBody *Cur = Sym->Body;
+  if (Cur == L)
     return;
-  if (auto *Undef = dyn_cast<Undefined>(Sym->Body)) {
+  if (Cur->isUndefined()) {
     Sym->Body = L;
-    addMemberFile(Undef, L);
+    addMemberFile(Cur, L);
   }
 }
 
 template <class ELFT>
-void SymbolTable<ELFT>::addMemberFile(Undefined *Undef, Lazy *L) {
+void SymbolTable<ELFT>::addMemberFile(SymbolBody *Undef, Lazy *L) {
   if (Undef->isUsedInRegularObj())
     L->setUsedInRegularObj();
   // Weak undefined symbols should not fetch members from archives.

Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=265536&r1=265535&r2=265536&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Wed Apr  6 08:22:41 2016
@@ -19,7 +19,6 @@ namespace elf {
 class Lazy;
 template <class ELFT> class OutputSectionBase;
 struct Symbol;
-class Undefined;
 
 // SymbolTable is a bucket of all known symbols, including defined,
 // undefined, or lazy symbols (the last one is symbols in archive
@@ -68,7 +67,7 @@ public:
 private:
   Symbol *insert(SymbolBody *New);
   void addLazy(Lazy *New);
-  void addMemberFile(Undefined *Undef, Lazy *L);
+  void addMemberFile(SymbolBody *Undef, Lazy *L);
   void resolve(SymbolBody *Body);
   std::string conflictMsg(SymbolBody *Old, SymbolBody *New);
 

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=265536&r1=265535&r2=265536&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Wed Apr  6 08:22:41 2016
@@ -76,7 +76,7 @@ static typename ELFT::uint getSymVA(cons
     return Out<ELFT>::Bss->getVA() + SS.OffsetInBss;
   }
   case SymbolBody::UndefinedElfKind:
-  case SymbolBody::UndefinedKind:
+  case SymbolBody::UndefinedBitcodeKind:
     return 0;
   case SymbolBody::LazyKind:
     assert(Body.isUsedInRegularObj() && "lazy symbol reached writer");
@@ -91,8 +91,22 @@ SymbolBody::SymbolBody(Kind K, uint32_t
                        uint8_t Type)
     : SymbolKind(K), MustBeInDynSym(false), NeedsCopyOrPltAddr(false),
       Type(Type), Binding(STB_LOCAL), StOther(StOther), NameOffset(NameOffset) {
-  IsUsedInRegularObj =
-      K != SharedKind && K != LazyKind && K != DefinedBitcodeKind;
+  init();
+}
+
+SymbolBody::SymbolBody(Kind K, StringRef Name, uint8_t Binding, uint8_t StOther,
+                       uint8_t Type)
+    : SymbolKind(K), MustBeInDynSym(false), NeedsCopyOrPltAddr(false),
+      Type(Type), Binding(Binding), StOther(StOther),
+      Name({Name.data(), Name.size()}) {
+  assert(!isLocal());
+  init();
+}
+
+void SymbolBody::init() {
+  Kind K = kind();
+  IsUsedInRegularObj = K == DefinedRegularKind || K == DefinedCommonKind ||
+                       K == DefinedSyntheticKind || K == UndefinedElfKind;
 }
 
 // Returns true if a symbol can be replaced at load-time by a symbol
@@ -239,31 +253,27 @@ bool DefinedBitcode::classof(const Symbo
   return S->kind() == DefinedBitcodeKind;
 }
 
-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 StOther, uint8_t Type)
-    : SymbolBody(K, NameOffset, StOther, Type), CanKeepUndefined(false) {}
-
-Undefined::Undefined(StringRef N, bool IsWeak, uint8_t StOther,
-                     bool CanKeepUndefined)
-    : Undefined(SymbolBody::UndefinedKind, N, IsWeak ? STB_WEAK : STB_GLOBAL,
-                StOther, 0 /* Type */) {
-  this->CanKeepUndefined = CanKeepUndefined;
-}
+UndefinedBitcode::UndefinedBitcode(StringRef N, bool IsWeak, uint8_t StOther)
+    : SymbolBody(SymbolBody::UndefinedBitcodeKind, N,
+                 IsWeak ? STB_WEAK : STB_GLOBAL, StOther, 0 /* Type */) {}
 
 template <typename ELFT>
 UndefinedElf<ELFT>::UndefinedElf(StringRef N, const Elf_Sym &Sym)
-    : Undefined(SymbolBody::UndefinedElfKind, N, Sym.getBinding(), Sym.st_other,
-                Sym.getType()),
+    : SymbolBody(SymbolBody::UndefinedElfKind, N, Sym.getBinding(),
+                 Sym.st_other, Sym.getType()),
       Size(Sym.st_size) {}
 
 template <typename ELFT>
+UndefinedElf<ELFT>::UndefinedElf(StringRef Name, uint8_t Binding,
+                                 uint8_t StOther, uint8_t Type,
+                                 bool CanKeepUndefined)
+    : SymbolBody(SymbolBody::UndefinedElfKind, Name, Binding, StOther, Type),
+      CanKeepUndefined(CanKeepUndefined) {}
+
+template <typename ELFT>
 UndefinedElf<ELFT>::UndefinedElf(const Elf_Sym &Sym)
-    : Undefined(SymbolBody::UndefinedElfKind, Sym.st_name, Sym.st_other,
-                Sym.getType()),
+    : SymbolBody(SymbolBody::UndefinedElfKind, Sym.st_name, Sym.st_other,
+                 Sym.getType()),
       Size(Sym.st_size) {
   assert(Sym.getBinding() == STB_LOCAL);
 }

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=265536&r1=265535&r2=265536&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Wed Apr  6 08:22:41 2016
@@ -46,6 +46,8 @@ struct Symbol {
 
 // The base class for real symbol classes.
 class SymbolBody {
+  void init();
+
 public:
   enum Kind {
     DefinedFirst,
@@ -56,7 +58,7 @@ public:
     DefinedSyntheticKind,
     DefinedLast = DefinedSyntheticKind,
     UndefinedElfKind,
-    UndefinedKind,
+    UndefinedBitcodeKind,
     LazyKind
   };
 
@@ -64,7 +66,7 @@ public:
 
   bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; }
   bool isUndefined() const {
-    return SymbolKind == UndefinedKind || SymbolKind == UndefinedElfKind;
+    return SymbolKind == UndefinedBitcodeKind || SymbolKind == UndefinedElfKind;
   }
   bool isDefined() const { return SymbolKind <= DefinedLast; }
   bool isCommon() const { return SymbolKind == DefinedCommonKind; }
@@ -125,14 +127,7 @@ public:
 
 protected:
   SymbolBody(Kind K, StringRef Name, uint8_t Binding, uint8_t StOther,
-             uint8_t Type)
-      : SymbolKind(K), MustBeInDynSym(false), NeedsCopyOrPltAddr(false),
-        Type(Type), Binding(Binding), StOther(StOther),
-        Name({Name.data(), Name.size()}) {
-    assert(!isLocal());
-    IsUsedInRegularObj =
-        K != SharedKind && K != LazyKind && K != DefinedBitcodeKind;
-  }
+             uint8_t Type);
 
   SymbolBody(Kind K, uint32_t NameOffset, uint8_t StOther, uint8_t Type);
 
@@ -282,31 +277,27 @@ public:
   const OutputSectionBase<ELFT> &Section;
 };
 
-// Undefined symbol.
-class Undefined : public SymbolBody {
-  typedef SymbolBody::Kind Kind;
-  bool CanKeepUndefined;
-
-protected:
-  Undefined(Kind K, StringRef N, uint8_t Binding, uint8_t StOther,
-            uint8_t Type);
-  Undefined(Kind K, uint32_t NameOffset, uint8_t StOther, uint8_t Type);
-
+class UndefinedBitcode : public SymbolBody {
 public:
-  Undefined(StringRef N, bool IsWeak, uint8_t StOther, bool CanKeepUndefined);
+  UndefinedBitcode(StringRef N, bool IsWeak, uint8_t StOther);
 
-  static bool classof(const SymbolBody *S) { return S->isUndefined(); }
-
-  bool canKeepUndefined() const { return CanKeepUndefined; }
+  static bool classof(const SymbolBody *S) {
+    return S->kind() == UndefinedBitcodeKind;
+  }
 };
 
-template <class ELFT> class UndefinedElf : public Undefined {
+template <class ELFT> class UndefinedElf : public SymbolBody {
   typedef typename ELFT::uint uintX_t;
   typedef typename ELFT::Sym Elf_Sym;
+  bool CanKeepUndefined = false;
 
 public:
   UndefinedElf(StringRef N, const Elf_Sym &Sym);
   UndefinedElf(const Elf_Sym &Sym);
+  UndefinedElf(StringRef Name, uint8_t Binding, uint8_t StOther, uint8_t Type,
+               bool CanKeepUndefined);
+
+  bool canKeepUndefined() const { return CanKeepUndefined; }
 
   uintX_t Size;
 

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=265536&r1=265535&r2=265536&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Apr  6 08:22:41 2016
@@ -1069,9 +1069,11 @@ template <class ELFT> void Writer<ELFT>:
   std::vector<DefinedCommon *> CommonSymbols;
   for (auto &P : Symtab.getSymbols()) {
     SymbolBody *Body = P.second->Body;
-    if (auto *U = dyn_cast<Undefined>(Body))
-      if (!U->isWeak() && !U->canKeepUndefined())
+    if (Body->isUndefined() && !Body->isWeak()) {
+      auto *U = dyn_cast<UndefinedElf<ELFT>>(Body);
+      if (!U || !U->canKeepUndefined())
         reportUndefined<ELFT>(Symtab, Body);
+    }
 
     if (auto *C = dyn_cast<DefinedCommon>(Body))
       CommonSymbols.push_back(C);

Added: lld/trunk/test/ELF/lto/Inputs/internalize-undef.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/lto/Inputs/internalize-undef.ll?rev=265536&view=auto
==============================================================================
--- lld/trunk/test/ELF/lto/Inputs/internalize-undef.ll (added)
+++ lld/trunk/test/ELF/lto/Inputs/internalize-undef.ll Wed Apr  6 08:22:41 2016
@@ -0,0 +1,6 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f() {
+  ret void
+}

Added: lld/trunk/test/ELF/lto/internalize-undef.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/lto/internalize-undef.ll?rev=265536&view=auto
==============================================================================
--- lld/trunk/test/ELF/lto/internalize-undef.ll (added)
+++ lld/trunk/test/ELF/lto/internalize-undef.ll Wed Apr  6 08:22:41 2016
@@ -0,0 +1,16 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: llvm-as %p/Inputs/internalize-undef.ll -o %t2.o
+; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t -save-temps
+; RUN: llvm-dis < %t.lto.bc | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @f()
+define void @_start() {
+  call void @f()
+  ret void
+}
+
+; CHECK: define internal void @f()




More information about the llvm-commits mailing list