[lld] r245069 - ELF: Also record the type of undefined symbols.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 14 09:46:30 PDT 2015


Author: rafael
Date: Fri Aug 14 11:46:28 2015
New Revision: 245069

URL: http://llvm.org/viewvc/llvm-project?rev=245069&view=rev
Log:
ELF: Also record the type of undefined symbols.

Tested with a weak undefined. Testing with a plain undefined will have to wait
for support for -shared.

Modified:
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/elf2/symbols.s

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=245069&r1=245068&r2=245069&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Fri Aug 14 11:46:28 2015
@@ -86,11 +86,11 @@ SymbolBody *elf2::ObjectFile<ELFT>::crea
     error("unexpected binding");
   case STB_GLOBAL:
     if (Sym->isUndefined())
-      return new (Alloc) Undefined(Name);
+      return new (Alloc) Undefined<ELFT>(Name, *Sym);
     return new (Alloc) DefinedRegular<ELFT>(Name, *Sym);
   case STB_WEAK:
     if (Sym->isUndefined())
-      return new (Alloc) UndefinedWeak(Name);
+      return new (Alloc) UndefinedWeak<ELFT>(Name, *Sym);
     return new (Alloc) DefinedWeak<ELFT>(Name, *Sym);
   }
 }

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=245069&r1=245068&r2=245069&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Fri Aug 14 11:46:28 2015
@@ -16,7 +16,9 @@ using namespace llvm;
 using namespace lld;
 using namespace lld::elf2;
 
-SymbolTable::SymbolTable() { resolve(new (Alloc) Undefined("_start")); }
+SymbolTable::SymbolTable() {
+  resolve(new (Alloc) SyntheticUndefined("_start"));
+}
 
 void SymbolTable::addFile(std::unique_ptr<InputFile> File) {
   File->parse();
@@ -39,9 +41,9 @@ void SymbolTable::addObject(ObjectFileBa
 
 void SymbolTable::reportRemainingUndefines() {
   for (auto &I : Symtab) {
-    Symbol *Sym = I.second;
-    if (auto *Undef = dyn_cast<Undefined>(Sym->Body))
-      error(Twine("undefined symbol: ") + Undef->getName());
+    SymbolBody *Body = I.second->Body;
+    if (Body->isStrongUndefined())
+      error(Twine("undefined symbol: ") + Body->getName());
   }
 }
 

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=245069&r1=245068&r2=245069&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Fri Aug 14 11:46:28 2015
@@ -38,6 +38,7 @@ int SymbolBody::compare(SymbolBody *Othe
   case DefinedWeakKind:
   case UndefinedKind:
   case UndefinedWeakKind:
+  case UndefinedSyntheticKind:
     return 1;
   }
   llvm_unreachable("unknown symbol kind");

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=245069&r1=245068&r2=245069&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Fri Aug 14 11:46:28 2015
@@ -40,11 +40,16 @@ public:
     DefinedWeakKind = 1,
     DefinedLast = 1,
     UndefinedWeakKind = 2,
-    UndefinedKind = 3
+    UndefinedKind = 3,
+    UndefinedSyntheticKind = 4
   };
 
   Kind kind() const { return static_cast<Kind>(SymbolKind); }
 
+  bool isStrongUndefined() {
+    return SymbolKind == UndefinedKind || SymbolKind == UndefinedSyntheticKind;
+  }
+
   // Returns the symbol name.
   StringRef getName() const { return Name; }
 
@@ -70,19 +75,43 @@ protected:
   Symbol *Backref = nullptr;
 };
 
+// This is for symbols created from elf files and not from the command line.
+// Since they come from object files, they have a Elf_Sym.
+//
+// FIXME: Another alternative is to give every symbol an Elf_Sym. To do that
+// we have to delay creating the symbol table until the output format is
+// known and some of its methods will be templated. We should experiment with
+// that once we have a bit more code.
+template <class ELFT> class ELFSymbolBody : public SymbolBody {
+protected:
+  typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
+  ELFSymbolBody(Kind K, StringRef Name, const Elf_Sym &Sym)
+      : SymbolBody(K, Name), Sym(Sym) {}
+
+public:
+  const Elf_Sym &Sym;
+
+  static bool classof(const SymbolBody *S) {
+    Kind K = S->kind();
+    return K >= DefinedFirst && K <= UndefinedKind;
+  }
+};
+
 // The base class for any defined symbols, including absolute symbols,
 // etc.
-template <class ELFT> class Defined : public SymbolBody {
+template <class ELFT> class Defined : public ELFSymbolBody<ELFT> {
+  typedef ELFSymbolBody<ELFT> Base;
+  typedef typename Base::Kind Kind;
+
 public:
-  typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
-  const Elf_Sym &Sym;
+  typedef typename Base::Elf_Sym Elf_Sym;
 
   explicit Defined(Kind K, StringRef N, const Elf_Sym &Sym)
-      : SymbolBody(K, N), Sym(Sym) {}
+      : ELFSymbolBody<ELFT>(K, N, Sym) {}
 
   static bool classof(const SymbolBody *S) {
     Kind K = S->kind();
-    return DefinedFirst <= K && K <= DefinedLast;
+    return Base::DefinedFirst <= K && K <= Base::DefinedLast;
   }
 };
 
@@ -114,21 +143,38 @@ public:
 };
 
 // Undefined symbols.
-class Undefined : public SymbolBody {
+class SyntheticUndefined : public SymbolBody {
 public:
-  explicit Undefined(StringRef N) : SymbolBody(UndefinedKind, N) {}
+  explicit SyntheticUndefined(StringRef N) : SymbolBody(UndefinedKind, N) {}
 
   static bool classof(const SymbolBody *S) {
     return S->kind() == UndefinedKind;
   }
 };
 
-class UndefinedWeak : public SymbolBody {
+template <class ELFT> class Undefined : public ELFSymbolBody<ELFT> {
+  typedef ELFSymbolBody<ELFT> Base;
+  typedef typename Base::Elf_Sym Elf_Sym;
+
+public:
+  explicit Undefined(StringRef N, const Elf_Sym &Sym)
+      : ELFSymbolBody<ELFT>(Base::UndefinedKind, N, Sym) {}
+
+  static bool classof(const SymbolBody *S) {
+    return S->kind() == Base::UndefinedKind;
+  }
+};
+
+template <class ELFT> class UndefinedWeak : public ELFSymbolBody<ELFT> {
+  typedef ELFSymbolBody<ELFT> Base;
+  typedef typename Base::Elf_Sym Elf_Sym;
+
 public:
-  explicit UndefinedWeak(StringRef N) : SymbolBody(UndefinedWeakKind, N) {}
+  explicit UndefinedWeak(StringRef N, const Elf_Sym &Sym)
+      : ELFSymbolBody<ELFT>(Base::UndefinedWeakKind, N, Sym) {}
 
   static bool classof(const SymbolBody *S) {
-    return S->kind() == UndefinedWeakKind;
+    return S->kind() == Base::UndefinedWeakKind;
   }
 };
 

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=245069&r1=245068&r2=245069&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Aug 14 11:46:28 2015
@@ -224,16 +224,16 @@ template <class ELFT> void SymbolTableSe
     uint8_t Type = 0;
     switch (Body->kind()) {
     case SymbolBody::UndefinedKind:
+    case SymbolBody::UndefinedSyntheticKind:
       llvm_unreachable("Should be defined by now");
     case SymbolBody::DefinedRegularKind:
       Binding = STB_GLOBAL;
       Type = cast<DefinedRegular<ELFT>>(Body)->Sym.getType();
       break;
     case SymbolBody::DefinedWeakKind:
-      Type = cast<DefinedWeak<ELFT>>(Body)->Sym.getType();
-    // Fallthrough
     case SymbolBody::UndefinedWeakKind:
       Binding = STB_WEAK;
+      Type = cast<ELFSymbolBody<ELFT>>(Body)->Sym.getType();
       break;
     }
     ESym->setBindingAndType(Binding, Type);

Modified: lld/trunk/test/elf2/symbols.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/symbols.s?rev=245069&r1=245068&r2=245069&view=diff
==============================================================================
--- lld/trunk/test/elf2/symbols.s (original)
+++ lld/trunk/test/elf2/symbols.s Fri Aug 14 11:46:28 2015
@@ -11,6 +11,10 @@ _start:
 .weak foo
 foo:
 
+.type bar, @object
+.weak bar
+.long bar
+
 // CHECK:      Symbols [
 // CHECK-NEXT:   Symbol {
 // CHECK-NEXT:     Name:  (0)
@@ -30,6 +34,15 @@ foo:
 // CHECK-NEXT:     Other: 0
 // CHECK-NEXT:     Section: Undefined (0x0)
 // CHECK-NEXT:   }
+// CHECK-NEXT:   Symbol {
+// CHECK-NEXT:     Name: bar
+// CHECK-NEXT:     Value: 0x0
+// CHECK-NEXT:     Size: 0
+// CHECK-NEXT:     Binding: Weak (0x2)
+// CHECK-NEXT:     Type: Object (0x1)
+// CHECK-NEXT:     Other: 0
+// CHECK-NEXT:     Section: Undefined (0x0)
+// CHECK-NEXT:   }
 // CHECK-NEXT:   Symbol {
 // CHECK-NEXT:     Name: foo
 // CHECK-NEXT:     Value: 0x0




More information about the llvm-commits mailing list