[ELF] - Create _DYNAMIC symbol for dynamic output
authorGeorge Rimar <grimar@accesssoftek.com>
Tue, 1 Mar 2016 16:23:13 +0000 (16:23 +0000)
committerGeorge Rimar <grimar@accesssoftek.com>
Tue, 1 Mar 2016 16:23:13 +0000 (16:23 +0000)
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

16 files changed:
lld/ELF/SymbolTable.cpp
lld/ELF/SymbolTable.h
lld/ELF/Symbols.cpp
lld/ELF/Symbols.h
lld/ELF/Writer.cpp
lld/test/ELF/basic-ppc.s
lld/test/ELF/comdat.s
lld/test/ELF/discard-merge-locals.s
lld/test/ELF/discard-merge-unnamed.s
lld/test/ELF/discard-none.s
lld/test/ELF/dynamic.s [new file with mode: 0644]
lld/test/ELF/gc-sections-local-sym.s
lld/test/ELF/local-dynamic.s
lld/test/ELF/section-symbol.s
lld/test/ELF/shared.s
lld/test/ELF/visibility.s

index c40377c..095ad86 100644 (file)
@@ -186,9 +186,9 @@ SymbolBody *SymbolTable<ELFT>::addAbsolute(StringRef Name, Elf_Sym &ESym) {
 
 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;
 }
index 1f602e7..a2a991a 100644 (file)
@@ -58,7 +58,7 @@ public:
   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();
index 6e094a3..a1e936e 100644 (file)
@@ -192,8 +192,9 @@ UndefinedElf<ELFT>::UndefinedElf(StringRef N, const Elf_Sym &Sym)
 
 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) {}
 
index ea2c2e1..ac67bf6 100644 (file)
@@ -250,8 +250,8 @@ template <class ELFT> class DefinedSynthetic : public Defined {
 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;
index d7e13e8..1277994 100644 (file)
@@ -1004,6 +1004,8 @@ template <class ELFT> bool Writer<ELFT>::createSections() {
   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 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
   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 @@ void Writer<ELFT>::addStartStopSymbols(OutputSectionBase<ELFT> *Sec) {
   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) {
index 1dc5822..83ace9a 100644 (file)
@@ -28,7 +28,7 @@
 // CHECK-NEXT:   Version: 1
 // CHECK-NEXT:   Entry: 0x0
 // CHECK-NEXT:   ProgramHeaderOffset: 0x34
-// CHECK-NEXT:   SectionHeaderOffset: 0x2084
+// CHECK-NEXT:   SectionHeaderOffset: 0x209C
 // CHECK-NEXT:   Flags [ (0x0)
 // CHECK-NEXT:   ]
 // CHECK-NEXT:   HeaderSize: 52
 // CHECK-NEXT:     ]
 // CHECK-NEXT:     Address: 0x0
 // CHECK-NEXT:     Offset: 0x2030
-// CHECK-NEXT:     Size: 16
+// CHECK-NEXT:     Size: 32
 // CHECK-NEXT:     Link: 8
 // CHECK-NEXT:     Info: 1
 // CHECK-NEXT:     AddressAlignment: 4
 // CHECK-NEXT:     EntrySize: 16
 // CHECK-NEXT:     SectionData (
 // CHECK-NEXT:       0000: 00000000 00000000 00000000 00000000  |................|
+// CHECK-NEXT:       0010: 00000001 00002000 00000000 00020005  |...... .........|
 // CHECK-NEXT:     )
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Section {
 // CHECK-NEXT:     Flags [ (0x0)
 // CHECK-NEXT:     ]
 // CHECK-NEXT:     Address: 0x0
-// CHECK-NEXT:     Offset: 0x2040
+// CHECK-NEXT:     Offset: 0x2050
 // CHECK-NEXT:     Size: 64
 // CHECK-NEXT:     Link: 0
 // CHECK-NEXT:     Info: 0
 // CHECK-NEXT:     Flags [ (0x0)
 // CHECK-NEXT:     ]
 // CHECK-NEXT:     Address: 0x0
-// CHECK-NEXT:     Offset: 0x2080
+// CHECK-NEXT:     Offset: 0x2090
 // CHECK-NEXT:     Size: 1
 // CHECK-NEXT:     Link: 0
 // CHECK-NEXT:     Info: 0
 // CHECK-NEXT:     AddressAlignment: 1
 // CHECK-NEXT:     EntrySize: 0
 // CHECK-NEXT:     SectionData (
-// CHECK-NEXT:       0000: 00                                   |.|
+// CHECK-NEXT:       0000: 005F4459 4E414D49 4300               |._DYNAMIC.|
 // CHECK-NEXT:     )
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]
index 4f8955e..d3c8c01 100644 (file)
@@ -61,6 +61,15 @@ foo:
 // READ-NEXT:     Section: .text
 // READ-NEXT:   }
 // READ-NEXT:   Symbol {
+// READ-NEXT:     Name: _DYNAMIC
+// READ-NEXT:     Value: 0x2000
+// READ-NEXT:     Size: 0
+// READ-NEXT:     Binding: Local
+// READ-NEXT:     Type: None
+// READ-NEXT:     Other: 2
+// READ-NEXT:     Section: .dynamic
+// READ-NEXT:   }
+// READ-NEXT:   Symbol {
 // READ-NEXT:     Name: abc
 // READ-NEXT:     Value: 0x0
 // READ-NEXT:     Size: 0
index 51676da..bf3f9b9 100644 (file)
 // CHECK-NEXT:     Other: 0
 // CHECK-NEXT:     Section: Undefined
 // CHECK-NEXT:   }
+// CHECK-NEXT:   Symbol {
+// CHECK-NEXT:     Name: _DYNAMIC
+// CHECK-NEXT:     Value: 0x2000
+// CHECK-NEXT:     Size: 0
+// CHECK-NEXT:     Binding: Local
+// CHECK-NEXT:     Type: None
+// CHECK-NEXT:     Other: 2
+// CHECK-NEXT:     Section: .dynamic
+// CHECK-NEXT:   }
 // CHECK-NEXT: ]
index bd0058c..e61aec5 100644 (file)
 // CHECK-NEXT:     Other: 0
 // CHECK-NEXT:     Section: Undefined
 // CHECK-NEXT:   }
+// CHECK-NEXT:   Symbol {
+// CHECK-NEXT:     Name: _DYNAMIC
+// CHECK-NEXT:     Value: 0x2000
+// CHECK-NEXT:     Size: 0
+// CHECK-NEXT:     Binding: Local
+// CHECK-NEXT:     Type: None
+// CHECK-NEXT:     Other: 2
+// CHECK-NEXT:     Section: .dynamic
+// CHECK-NEXT:   }
 // CHECK-NEXT: ]
index c13b544..e3a7a20 100644 (file)
@@ -21,7 +21,7 @@
 // CHECK-NEXT:     EntrySize:
 // CHECK-NEXT:     SectionData (
 // CHECK-NEXT:       0000: 002E4C6D 796F7468 65727661 72002E4C  |..Lmyothervar..L|
-// CHECK-NEXT:       0010: 6D797661 7200                        |myvar.|
+// CHECK-NEXT:       0010: 6D797661 72005F44 594E414D 494300    |myvar._DYNAMIC.|
 // CHECK-NEXT:     )
 // CHECK-NEXT:   }
 
diff --git a/lld/test/ELF/dynamic.s b/lld/test/ELF/dynamic.s
new file mode 100644 (file)
index 0000000..47c162a
--- /dev/null
@@ -0,0 +1,42 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t.o
+
+## Check that _DYNAMIC symbol is created when creating dynamic output,
+## and has hidden visibility and address equal to .dynamic section.
+# RUN: ld.lld -shared %t.o -o %t.so
+# RUN: llvm-readobj -sections -symbols %t.so | FileCheck %s
+# CHECK:      Section {
+# CHECK:        Index: 5
+# CHECK:        Name: .dynamic
+# CHECK-NEXT:   Type: SHT_DYNAMIC
+# CHECK-NEXT:   Flags [
+# CHECK-NEXT:     SHF_ALLOC
+# CHECK-NEXT:     SHF_WRITE
+# CHECK-NEXT:   ]
+# CHECK-NEXT:   Address: 0x[[ADDR:.*]]
+# CHECK-NEXT:   Offset: 0x1000
+# CHECK-NEXT:   Size:
+# CHECK-NEXT:   Link:
+# CHECK-NEXT:   Info:
+# CHECK-NEXT:   AddressAlignment:
+# CHECK-NEXT:   EntrySize:
+# CHECK-NEXT: }
+# CHECK:      Symbols [
+# CHECK:        Symbol {
+# CHECK:          Name: _DYNAMIC
+# CHECK-NEXT:     Value: 0x[[ADDR]]
+# CHECK-NEXT:     Size: 0
+# CHECK-NEXT:     Binding: Local
+# CHECK-NEXT:     Type: None
+# CHECK-NEXT:     Other: 2
+# CHECK-NEXT:     Section: .dynamic
+# CHECK-NEXT:   }
+
+# RUN: ld.lld %t.o -o %t.o
+# RUN: llvm-readobj -sections -symbols %t.o | FileCheck -check-prefix=NODYN %s
+# NODYN:    Symbols [
+# NODYN-NOT: Name: _DYNAMIC
+# NODYN:    ]
+
+.globl _start
+_start:
index 5102e30..db9f4c3 100644 (file)
@@ -21,7 +21,7 @@ zed:
 // CHECK-NEXT: AddressAlignment:
 // CHECK-NEXT: EntrySize:
 // CHECK-NEXT: SectionData (
-// CHECK-NEXT:   0000: 00666F6F 00                          |.foo.|
+// CHECK-NEXT:   0000: 00666F6F 005F4459 4E414D49 4300      |.foo._DYNAMIC.|
 // CHECK-NEXT: )
 
 // CHECK:      Symbols [
@@ -35,6 +35,15 @@ zed:
 // CHECK-NEXT:     Section: Undefined
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Symbol {
+// CHECK-NEXT:     Name: _DYNAMIC
+// CHECK-NEXT:     Value: 0x1000
+// CHECK-NEXT:     Size: 0
+// CHECK-NEXT:     Binding: Local
+// CHECK-NEXT:     Type: None
+// CHECK-NEXT:     Other: 2
+// CHECK-NEXT:     Section: .dynamic
+// CHECK-NEXT:   }
+// CHECK-NEXT:   Symbol {
 // CHECK-NEXT:     Name: foo
 // CHECK-NEXT:     Value:
 // CHECK-NEXT:     Size:
index 162c58c..156f74e 100644 (file)
 // CHECK-NEXT:     Section: .text
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Symbol {
+// CHECK-NEXT:     Name: _DYNAMIC
+// CHECK-NEXT:     Value: 0x1000
+// CHECK-NEXT:     Size: 0
+// CHECK-NEXT:     Binding: Local
+// CHECK-NEXT:     Type: None
+// CHECK-NEXT:     Other: 2
+// CHECK-NEXT:     Section: .dynamic
+// CHECK-NEXT:   }
+// CHECK-NEXT:   Symbol {
 // CHECK-NEXT:     Name: _start
 // CHECK-NEXT:     Value: 0x1000
 // CHECK-NEXT:     Size: 0
index 5f04606..072d9d4 100644 (file)
 // CHECK-NEXT:     Other: 0
 // CHECK-NEXT:     Section: .text
 // CHECK-NEXT:   }
+// CHECK-NEXT:   Symbol {
+// CHECK-NEXT:     Name: _DYNAMIC
+// CHECK-NEXT:     Value:
+// CHECK-NEXT:     Size: 0
+// CHECK-NEXT:     Binding: Local
+// CHECK-NEXT:     Type: None
+// CHECK-NEXT:     Other: 2
+// CHECK-NEXT:     Section: .dynamic
+// CHECK-NEXT:   }
 // CHECK-NEXT: ]
 
 foo:
index 1adda30..9cc235f 100644 (file)
 // CHECK-NEXT:     Section: Undefined
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Symbol {
+// CHECK-NEXT:     Name: _DYNAMIC
+// CHECK-NEXT:     Value: 0x12000
+// CHECK-NEXT:     Size: 0
+// CHECK-NEXT:     Binding: Local
+// CHECK-NEXT:     Type: None
+// CHECK-NEXT:     Other: 2
+// CHECK-NEXT:     Section: .dynamic
+// CHECK-NEXT:   }
+// CHECK-NEXT:   Symbol {
 // CHECK-NEXT:     Name: _start
 // CHECK-NEXT:     Value: 0x11000
 // CHECK-NEXT:     Size: 0
index d76ed07..1aa01d0 100644 (file)
 // CHECK-NEXT:     Section: .text
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Symbol {
+// CHECK-NEXT:     Name: _DYNAMIC
+// CHECK-NEXT:     Value: 0x2000
+// CHECK-NEXT:     Size: 0
+// CHECK-NEXT:     Binding: Local
+// CHECK-NEXT:     Type: None
+// CHECK-NEXT:     Other: 2
+// CHECK-NEXT:     Section: .dynamic
+// CHECK-NEXT:   }
+// CHECK-NEXT:   Symbol {
 // CHECK-NEXT:     Name: default
 // CHECK-NEXT:     Value:
 // CHECK-NEXT:     Size: 0