[ELF] - Create _DYNAMIC symbol for dynamic output

lld needs to provide _DYNAMIC symbol when creating a shared library
both bfd and gold do that.

This should fix the https://llvm.org/bugs/show_bug.cgi?id=26732

Differential revision: http://reviews.llvm.org/D17607

llvm-svn: 262348
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index c40377c..095ad86 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -186,9 +186,9 @@
 
 template <class ELFT>
 SymbolBody *SymbolTable<ELFT>::addSynthetic(StringRef Name,
-                                            OutputSectionBase<ELFT> &Section,
-                                            uintX_t Value) {
-  auto *Sym = new (Alloc) DefinedSynthetic<ELFT>(Name, Value, Section);
+                                            OutputSectionBase<ELFT> &Sec,
+                                            uintX_t Val, uint8_t Visibility) {
+  auto *Sym = new (Alloc) DefinedSynthetic<ELFT>(Name, Val, Sec, Visibility);
   resolve(Sym);
   return Sym;
 }
diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h
index 1f602e7..a2a991a 100644
--- a/lld/ELF/SymbolTable.h
+++ b/lld/ELF/SymbolTable.h
@@ -58,7 +58,7 @@
   SymbolBody *addUndefinedOpt(StringRef Name);
   SymbolBody *addAbsolute(StringRef Name, Elf_Sym &ESym);
   SymbolBody *addSynthetic(StringRef Name, OutputSectionBase<ELFT> &Section,
-                           uintX_t Value);
+                           uintX_t Value, uint8_t Visibility);
   SymbolBody *addIgnored(StringRef Name);
 
   void scanShlibUndefined();
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index 6e094a3..a1e936e 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -192,8 +192,9 @@
 
 template <typename ELFT>
 DefinedSynthetic<ELFT>::DefinedSynthetic(StringRef N, uintX_t Value,
-                                         OutputSectionBase<ELFT> &Section)
-    : Defined(SymbolBody::DefinedSyntheticKind, N, false, STV_DEFAULT,
+                                         OutputSectionBase<ELFT> &Section,
+                                         uint8_t Visibility)
+    : Defined(SymbolBody::DefinedSyntheticKind, N, false, Visibility,
               /*IsTls*/ false, /*IsFunction*/ false),
       Value(Value), Section(Section) {}
 
diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index ea2c2e1..ac67bf6 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -250,8 +250,8 @@
 public:
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
-  DefinedSynthetic(StringRef N, uintX_t Value,
-                   OutputSectionBase<ELFT> &Section);
+  DefinedSynthetic(StringRef N, uintX_t Value, OutputSectionBase<ELFT> &Section,
+                   uint8_t Visibility);
 
   static bool classof(const SymbolBody *S) {
     return S->kind() == SymbolBody::DefinedSyntheticKind;
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index d7e13e8..1277994 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -1004,6 +1004,8 @@
   addStartEndSymbols();
   for (OutputSectionBase<ELFT> *Sec : RegularSections)
     addStartStopSymbols(Sec);
+  if (isOutputDynamic())
+    Symtab.addSynthetic("_DYNAMIC", *Out<ELFT>::Dynamic, 0, STV_HIDDEN);
 
   // Define __rel[a]_iplt_{start,end} symbols if needed.
   addRelIpltSymbols();
@@ -1146,8 +1148,8 @@
   auto Define = [&](StringRef Start, StringRef End,
                     OutputSectionBase<ELFT> *OS) {
     if (OS) {
-      Symtab.addSynthetic(Start, *OS, 0);
-      Symtab.addSynthetic(End, *OS, OS->getSize());
+      Symtab.addSynthetic(Start, *OS, 0, STV_DEFAULT);
+      Symtab.addSynthetic(End, *OS, OS->getSize(), STV_DEFAULT);
     } else {
       Symtab.addIgnored(Start);
       Symtab.addIgnored(End);
@@ -1177,10 +1179,10 @@
   StringRef Stop = Saver.save("__stop_" + S);
   if (SymbolBody *B = Symtab.find(Start))
     if (B->isUndefined())
-      Symtab.addSynthetic(Start, *Sec, 0);
+      Symtab.addSynthetic(Start, *Sec, 0, STV_DEFAULT);
   if (SymbolBody *B = Symtab.find(Stop))
     if (B->isUndefined())
-      Symtab.addSynthetic(Stop, *Sec, Sec->getSize());
+      Symtab.addSynthetic(Stop, *Sec, Sec->getSize(), STV_DEFAULT);
 }
 
 template <class ELFT> static bool needsPtLoad(OutputSectionBase<ELFT> *Sec) {