Add a DT_SYMTAB entry in the dynamic section.
authorRafael Espindola <rafael.espindola@gmail.com>
Fri, 11 Sep 2015 01:14:39 +0000 (01:14 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Fri, 11 Sep 2015 01:14:39 +0000 (01:14 +0000)
With this a trivial shared binary runs with the glibc dynamic linker:

LD_LIBRARY_PATH=.  /lib64/ld-2.20.so ./t

llvm-svn: 247370

lld/ELF/Writer.cpp
lld/test/elf2/shared.s

index 4856c5d..24e74e6 100644 (file)
@@ -174,6 +174,8 @@ public:
     ++NumVisible;
   }
 
+  StringTableSection<ELFT::Is64Bits> &getStrTabSec() { return StrTabSec; }
+
 private:
   SymbolTable &Table;
   StringTableSection<ELFT::Is64Bits> &StrTabSec;
@@ -181,23 +183,25 @@ private:
   const Writer<ELFT> &W;
 };
 
-template <bool Is64Bits>
-class DynamicSection final : public OutputSectionBase<Is64Bits> {
-  typedef OutputSectionBase<Is64Bits> Base;
+template <class ELFT>
+class DynamicSection final : public OutputSectionBase<ELFT::Is64Bits> {
+  typedef OutputSectionBase<ELFT::Is64Bits> Base;
   typedef typename Base::HeaderT HeaderT;
   typedef typename Base::Elf_Dyn Elf_Dyn;
 
 public:
-  DynamicSection(SymbolTable &SymTab, StringTableSection<Is64Bits> &DynStrSec)
-      : OutputSectionBase<Is64Bits>(".dynamic", SHT_DYNAMIC,
-                                    SHF_ALLOC | SHF_WRITE),
-        DynStrSec(DynStrSec), SymTab(SymTab) {
+  DynamicSection(SymbolTable &SymTab, SymbolTableSection<ELFT> &DynSymSec)
+      : OutputSectionBase<ELFT::Is64Bits>(".dynamic", SHT_DYNAMIC,
+                                          SHF_ALLOC | SHF_WRITE),
+        DynStrSec(DynSymSec.getStrTabSec()), DynSymSec(DynSymSec),
+        SymTab(SymTab) {
     typename Base::HeaderT &Header = this->Header;
-    Header.sh_addralign = Is64Bits ? 8 : 4;
-    Header.sh_entsize = Is64Bits ? 16 : 8;
+    Header.sh_addralign = ELFT::Is64Bits ? 8 : 4;
+    Header.sh_entsize = ELFT::Is64Bits ? 16 : 8;
 
     unsigned NumEntries = 0;
 
+    ++NumEntries; // DT_SYMTAB
     ++NumEntries; // DT_STRTAB
     ++NumEntries; // DT_STRSZ
 
@@ -219,6 +223,10 @@ public:
   void writeTo(uint8_t *Buf) override {
     auto *P = reinterpret_cast<Elf_Dyn *>(Buf);
 
+    P->d_tag = DT_SYMTAB;
+    P->d_un.d_ptr = DynSymSec.getVA();
+    ++P;
+
     P->d_tag = DT_STRTAB;
     P->d_un.d_ptr = DynStrSec.getVA();
     ++P;
@@ -241,7 +249,8 @@ public:
   }
 
 private:
-  StringTableSection<Is64Bits> &DynStrSec;
+  StringTableSection<ELFT::Is64Bits> &DynStrSec;
+  SymbolTableSection<ELFT> &DynSymSec;
   SymbolTable &SymTab;
 };
 
@@ -255,7 +264,7 @@ public:
   typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
   Writer(SymbolTable *T)
       : StrTabSec(false), DynStrSec(true), SymTabSec(*this, *T, StrTabSec),
-        DynSymSec(*this, *T, DynStrSec), DynamicSec(*T, DynStrSec) {}
+        DynSymSec(*this, *T, DynStrSec), DynamicSec(*T, DynSymSec) {}
   void run();
 
   const OutputSection<ELFT> &getBSS() const {
@@ -286,7 +295,7 @@ private:
   SymbolTableSection<ELFT> SymTabSec;
   SymbolTableSection<ELFT> DynSymSec;
 
-  DynamicSection<ELFT::Is64Bits> DynamicSec;
+  DynamicSection<ELFT> DynamicSec;
 
   OutputSection<ELFT> *BSSSec = nullptr;
 };
index 2e7c413..707efde 100644 (file)
@@ -3,6 +3,20 @@
 // RUN: llvm-readobj --program-headers --dynamic-table -t -s -dyn-symbols %t | FileCheck %s
 // REQUIRES: x86
 
+// CHECK:        Name: .dynsym
+// CHECK-NEXT:   Type: SHT_DYNSYM
+// CHECK-NEXT:   Flags [
+// CHECK-NEXT:     SHF_ALLOC
+// CHECK-NEXT:   ]
+// CHECK-NEXT:   Address: [[DYNSYMADDR:.*]]
+// CHECK-NEXT:   Offset: 0x2000
+// CHECK-NEXT:   Size: 48
+// CHECK-NEXT:   Link: 6
+// CHECK-NEXT:   Info: 1
+// CHECK-NEXT:   AddressAlignment: 4
+// CHECK-NEXT:   EntrySize: 16
+// CHECK-NEXT: }
+
 // CHECK:        Name: .dynamic
 // CHECK-NEXT:   Type: SHT_DYNAMIC
 // CHECK-NEXT:   Flags [
 
 // CHECK:      DynamicSection [
 // CHECK-NEXT:   Tag        Type                 Name/Value
+// CHECK-NEXT:   0x00000006 SYMTAB               [[DYNSYMADDR]]
 // CHECK-NEXT:   0x00000005 STRTAB               [[DYNSTRADDR]]
 // CHECK-NEXT:   0x0000000A STRSZ
 // CHECK-NEXT:   0x00000001 NEEDED               SharedLibrary ({{.*}}/Inputs/i686-simple-library.so)