[lld] r246326 - Add support for weak absolute symbols.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 28 13:19:35 PDT 2015


Author: rafael
Date: Fri Aug 28 15:19:34 2015
New Revision: 246326

URL: http://llvm.org/viewvc/llvm-project?rev=246326&view=rev
Log:
Add support for weak absolute symbols.

On ELF being weak is independent of what we call the kind of the symbol. So
this also makes the code simpler.

Modified:
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/elf2/Inputs/resolution.s
    lld/trunk/test/elf2/resolution.s

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=246326&r1=246325&r2=246326&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Fri Aug 28 15:19:34 2015
@@ -113,13 +113,10 @@ SymbolBody *elf2::ObjectFile<ELFT>::crea
   default:
     error("unexpected binding");
   case STB_GLOBAL:
+  case STB_WEAK:
     if (Sym->isUndefined())
       return new (Alloc) Undefined<ELFT>(Name, *Sym);
     return new (Alloc) DefinedRegular<ELFT>(Name, *Sym, *Chunks[SecIndex]);
-  case STB_WEAK:
-    if (Sym->isUndefined())
-      return new (Alloc) UndefinedWeak<ELFT>(Name, *Sym);
-    return new (Alloc) DefinedWeak<ELFT>(Name, *Sym, *Chunks[SecIndex]);
   }
 }
 

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=246326&r1=246325&r2=246326&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Fri Aug 28 15:19:34 2015
@@ -20,27 +20,17 @@ using namespace lld::elf2;
 // Returns 1, 0 or -1 if this symbol should take precedence
 // over the Other, tie or lose, respectively.
 int SymbolBody::compare(SymbolBody *Other) {
-  Kind LK = kind();
-  Kind RK = Other->kind();
+  std::pair<bool, bool> L(isDefined(), isWeak());
+  std::pair<bool, bool> R(Other->isDefined(), Other->isWeak());
 
-  // Normalize so that the smaller kind is on the left.
-  if (LK > RK)
+  // Normalize
+  if (L > R)
     return -Other->compare(this);
 
-  // First handle comparisons between two different kinds.
-  if (LK != RK)
-    return 1;
+  if (L != R)
+    return -1;
 
-  // Now handle the case where the kinds are the same.
-  switch (LK) {
-  case DefinedAbsoluteKind:
-  case DefinedRegularKind:
+  if (L.first && !L.second)
     return 0;
-  case DefinedWeakKind:
-  case UndefinedKind:
-  case UndefinedWeakKind:
-  case UndefinedSyntheticKind:
-    return 1;
-  }
-  llvm_unreachable("unknown symbol kind");
+  return 1;
 }

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=246326&r1=246325&r2=246326&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Fri Aug 28 15:19:34 2015
@@ -40,18 +40,19 @@ public:
     DefinedFirst = 0,
     DefinedRegularKind = 0,
     DefinedAbsoluteKind = 1,
-    DefinedWeakKind = 2,
-    DefinedLast = 2,
-    UndefinedWeakKind = 3,
-    UndefinedKind = 4,
-    UndefinedSyntheticKind = 5
+    DefinedLast = 1,
+    UndefinedKind = 2,
+    UndefinedSyntheticKind = 3
   };
 
   Kind kind() const { return static_cast<Kind>(SymbolKind); }
 
-  bool isStrongUndefined() {
+  bool isWeak() const { return IsWeak; }
+  bool isUndefined() const {
     return SymbolKind == UndefinedKind || SymbolKind == UndefinedSyntheticKind;
   }
+  bool isDefined() const { return !isUndefined(); }
+  bool isStrongUndefined() { return !IsWeak && isUndefined(); }
 
   // Returns the symbol name.
   StringRef getName() const { return Name; }
@@ -71,10 +72,12 @@ public:
   int compare(SymbolBody *Other);
 
 protected:
-  SymbolBody(Kind K, StringRef Name) : SymbolKind(K), Name(Name) {}
+  SymbolBody(Kind K, StringRef Name, bool IsWeak)
+      : SymbolKind(K), IsWeak(IsWeak), Name(Name) {}
 
 protected:
   const unsigned SymbolKind : 8;
+  const unsigned IsWeak : 1;
   StringRef Name;
   Symbol *Backref = nullptr;
 };
@@ -90,7 +93,8 @@ template <class ELFT> class ELFSymbolBod
 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) {}
+      : SymbolBody(K, Name, Sym.getBinding() == llvm::ELF::STB_WEAK), Sym(Sym) {
+  }
 
 public:
   const Elf_Sym &Sym;
@@ -113,6 +117,8 @@ protected:
 public:
   explicit Defined(Kind K, StringRef N, const Elf_Sym &Sym)
       : ELFSymbolBody<ELFT>(K, N, Sym) {}
+
+  static bool classof(const SymbolBody *S) { return S->isDefined(); }
 };
 
 template <class ELFT> class DefinedAbsolute : public Defined<ELFT> {
@@ -122,63 +128,37 @@ template <class ELFT> class DefinedAbsol
 public:
   explicit DefinedAbsolute(StringRef N, const Elf_Sym &Sym)
       : Defined<ELFT>(Base::DefinedAbsoluteKind, N, Sym) {}
-};
-
-template <class ELFT> class DefinedInSection : public Defined<ELFT> {
-  typedef ELFSymbolBody<ELFT> Base;
-  typedef typename Base::Kind Kind;
-
-public:
-  typedef typename Base::Elf_Sym Elf_Sym;
-
-  explicit DefinedInSection(Kind K, StringRef N, const Elf_Sym &Sym,
-                            SectionChunk<ELFT> &Section)
-      : Defined<ELFT>(K, N, Sym), Section(Section) {}
 
   static bool classof(const SymbolBody *S) {
-    Kind K = S->kind();
-    return Base::DefinedFirst <= K && K <= Base::DefinedLast;
+    return S->kind() == Base::DefinedAbsoluteKind;
   }
-
-  const SectionChunk<ELFT> &Section;
 };
 
 // Regular defined symbols read from object file symbol tables.
-template <class ELFT> class DefinedRegular : public DefinedInSection<ELFT> {
+template <class ELFT> class DefinedRegular : public Defined<ELFT> {
   typedef Defined<ELFT> Base;
   typedef typename Base::Elf_Sym Elf_Sym;
 
 public:
   explicit DefinedRegular(StringRef N, const Elf_Sym &Sym,
                           SectionChunk<ELFT> &Section)
-      : DefinedInSection<ELFT>(Base::DefinedRegularKind, N, Sym, Section) {}
+      : Defined<ELFT>(Base::DefinedRegularKind, N, Sym), Section(Section) {}
 
   static bool classof(const SymbolBody *S) {
     return S->kind() == Base::DefinedRegularKind;
   }
-};
 
-template <class ELFT> class DefinedWeak : public DefinedInSection<ELFT> {
-  typedef Defined<ELFT> Base;
-  typedef typename Base::Elf_Sym Elf_Sym;
-
-public:
-  explicit DefinedWeak(StringRef N, const Elf_Sym &Sym,
-                       SectionChunk<ELFT> &Section)
-      : DefinedInSection<ELFT>(Base::DefinedWeakKind, N, Sym, Section) {}
-
-  static bool classof(const SymbolBody *S) {
-    return S->kind() == Base::DefinedWeakKind;
-  }
+  const SectionChunk<ELFT> &Section;
 };
 
 // Undefined symbols.
 class SyntheticUndefined : public SymbolBody {
 public:
-  explicit SyntheticUndefined(StringRef N) : SymbolBody(UndefinedKind, N) {}
+  explicit SyntheticUndefined(StringRef N)
+      : SymbolBody(UndefinedKind, N, false) {}
 
   static bool classof(const SymbolBody *S) {
-    return S->kind() == UndefinedKind;
+    return S->kind() == UndefinedSyntheticKind;
   }
 };
 
@@ -195,19 +175,6 @@ public:
   }
 };
 
-template <class ELFT> class UndefinedWeak : public ELFSymbolBody<ELFT> {
-  typedef ELFSymbolBody<ELFT> Base;
-  typedef typename Base::Elf_Sym Elf_Sym;
-
-public:
-  explicit UndefinedWeak(StringRef N, const Elf_Sym &Sym)
-      : ELFSymbolBody<ELFT>(Base::UndefinedWeakKind, N, Sym) {}
-
-  static bool classof(const SymbolBody *S) {
-    return S->kind() == Base::UndefinedWeakKind;
-  }
-};
-
 } // namespace elf2
 } // namespace lld
 

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=246326&r1=246325&r2=246326&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Aug 28 15:19:34 2015
@@ -246,7 +246,7 @@ template <class ELFT> void OutputSection
         if (!Body)
           continue;
         // Skip undefined weak for now.
-        if (isa<UndefinedWeak<ELFT>>(Body))
+        if (isa<Undefined<ELFT>>(Body) && Body->isWeak())
           continue;
         if (!isa<DefinedRegular<ELFT>>(Body))
           error(Twine("Can't relocate symbol ") + Body->getName());
@@ -300,18 +300,17 @@ template <class ELFT> void SymbolTableSe
     const Elf_Sym *InputSym = nullptr;
 
     switch (Body->kind()) {
-    case SymbolBody::UndefinedKind:
     case SymbolBody::UndefinedSyntheticKind:
       llvm_unreachable("Should be defined by now");
-    case SymbolBody::DefinedWeakKind:
     case SymbolBody::DefinedRegularKind: {
-      auto *Def = cast<DefinedInSection<ELFT>>(Body);
+      auto *Def = cast<DefinedRegular<ELFT>>(Body);
       InputSym = &Def->Sym;
       Section = &Def->Section;
       break;
     }
+    case SymbolBody::UndefinedKind:
+      assert(Body->isWeak() && "Should be defined by now");
     case SymbolBody::DefinedAbsoluteKind:
-    case SymbolBody::UndefinedWeakKind:
       InputSym = &cast<ELFSymbolBody<ELFT>>(Body)->Sym;
       break;
     }

Modified: lld/trunk/test/elf2/Inputs/resolution.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/Inputs/resolution.s?rev=246326&r1=246325&r2=246326&view=diff
==============================================================================
--- lld/trunk/test/elf2/Inputs/resolution.s (original)
+++ lld/trunk/test/elf2/Inputs/resolution.s Fri Aug 28 15:19:34 2015
@@ -8,3 +8,6 @@ _start:
 
 .weak bar
 bar:
+
+.weak abs
+abs = 123

Modified: lld/trunk/test/elf2/resolution.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/resolution.s?rev=246326&r1=246325&r2=246326&view=diff
==============================================================================
--- lld/trunk/test/elf2/resolution.s (original)
+++ lld/trunk/test/elf2/resolution.s Fri Aug 28 15:19:34 2015
@@ -16,3 +16,6 @@ foo:
 
 .weak zed
 .long zed
+
+.global abs
+abs = 123




More information about the llvm-commits mailing list