[lld] r247155 - Start adding content to the dynamic section.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 9 08:33:08 PDT 2015


Author: rafael
Date: Wed Sep  9 10:33:08 2015
New Revision: 247155

URL: http://llvm.org/viewvc/llvm-project?rev=247155&view=rev
Log:
Start adding content to the dynamic section.

With this patch we create a dynamic string table (it is allocated, unlike
the regular one) and the dynamic section has a DT_STRTAB pointing to it.

Modified:
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/elf2/basic.s
    lld/trunk/test/elf2/basic32.s
    lld/trunk/test/elf2/basic32be.s
    lld/trunk/test/elf2/basic64be.s
    lld/trunk/test/elf2/shared.s

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=247155&r1=247154&r2=247155&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Sep  9 10:33:08 2015
@@ -37,6 +37,8 @@ namespace {
 // non-overlapping file offsets and VAs.
 template <bool Is64Bits> class OutputSectionBase {
 public:
+  typedef
+      typename std::conditional<Is64Bits, Elf64_Dyn, Elf32_Dyn>::type Elf_Dyn;
   typedef typename std::conditional<Is64Bits, uint64_t, uint32_t>::type uintX_t;
   typedef
       typename std::conditional<Is64Bits, Elf64_Shdr, Elf32_Shdr>::type HeaderT;
@@ -48,7 +50,7 @@ public:
     Header.sh_flags = sh_flags;
   }
   void setVA(uintX_t VA) { Header.sh_addr = VA; }
-  uintX_t getVA() { return Header.sh_addr; }
+  uintX_t getVA() const { return Header.sh_addr; }
   void setFileOffset(uintX_t Off) { Header.sh_offset = Off; }
   template <endianness E>
   void writeHeaderTo(typename ELFFile<ELFType<E, Is64Bits>>::Elf_Shdr *SHdr);
@@ -105,7 +107,9 @@ public:
   llvm::StringTableBuilder StrTabBuilder;
 
   typedef typename OutputSectionBase<Is64Bits>::uintX_t uintX_t;
-  StringTableSection() : OutputSectionBase<Is64Bits>(".strtab", SHT_STRTAB, 0) {
+  StringTableSection(bool Dynamic)
+      : OutputSectionBase<Is64Bits>(Dynamic ? ".dynstr" : ".strtab", SHT_STRTAB,
+                                    Dynamic ? SHF_ALLOC : 0) {
     this->Header.sh_addralign = 1;
   }
 
@@ -158,25 +162,44 @@ private:
 
 template <bool Is64Bits>
 class DynamicSection final : public OutputSectionBase<Is64Bits> {
+  typedef OutputSectionBase<Is64Bits> Base;
+  typedef typename Base::HeaderT HeaderT;
+  typedef typename Base::Elf_Dyn Elf_Dyn;
+
 public:
-  DynamicSection(const StringTableSection<Is64Bits> &StrTabSec)
+  DynamicSection(const StringTableSection<Is64Bits> &DynStrSec)
       : OutputSectionBase<Is64Bits>(".dynamic", SHT_DYNAMIC,
                                     SHF_ALLOC | SHF_WRITE),
-        StrTabSec(StrTabSec) {
-    typedef OutputSectionBase<Is64Bits> Base;
+        DynStrSec(DynStrSec) {
     typename Base::HeaderT &Header = this->Header;
     Header.sh_addralign = Is64Bits ? 8 : 4;
     Header.sh_entsize = Is64Bits ? 16 : 8;
+
+    unsigned NumEntries = 0;
+
+    ++NumEntries; // DT_STRTAB
+    ++NumEntries; // DT_NULL
+
+    Header.sh_size = NumEntries * Header.sh_entsize;
   }
 
   void finalize() override {
-    this->Header.sh_link = StrTabSec.getSectionIndex();
+    this->Header.sh_link = DynStrSec.getSectionIndex();
   }
 
-  void writeTo(uint8_t *Buf) override {}
+  void writeTo(uint8_t *Buf) override {
+    auto *P = reinterpret_cast<Elf_Dyn *>(Buf);
+
+    P->d_tag = DT_STRTAB;
+    P->d_un.d_ptr = DynStrSec.getVA();
+    ++P;
+
+    P->d_tag = DT_NULL;
+    P->d_un.d_val = 0;
+  }
 
 private:
-  const StringTableSection<Is64Bits> &StrTabSec;
+  const StringTableSection<Is64Bits> &DynStrSec;
 };
 
 // The writer writes a SymbolTable result to a file.
@@ -187,7 +210,9 @@ public:
   typedef typename ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
   typedef typename ELFFile<ELFT>::Elf_Phdr Elf_Phdr;
   typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
-  Writer(SymbolTable *T) : SymTable(*T, StringTable), DynamicSec(StringTable) {}
+  Writer(SymbolTable *T)
+      : StrTabSec(false), DynStrSec(true), SymTable(*T, StrTabSec),
+        DynamicSec(DynStrSec) {}
   void run();
 
 private:
@@ -206,7 +231,8 @@ private:
   uintX_t SizeOfHeaders;
   uintX_t SectionHeaderOff;
 
-  StringTableSection<ELFT::Is64Bits> StringTable;
+  StringTableSection<ELFT::Is64Bits> StrTabSec;
+  StringTableSection<ELFT::Is64Bits> DynStrSec;
 
   SymbolTableSection<ELFT> SymTable;
 
@@ -488,7 +514,7 @@ template <class ELFT> void Writer<ELFT>:
   OutputSection<ELFT> *BSSSec = SymTable.BSSSec;
   // FIXME: Try to avoid the extra walk over all global symbols.
   unsigned &NumVisible = SymTable.NumVisible;
-  llvm::StringTableBuilder &Builder = StringTable.StrTabBuilder;
+  llvm::StringTableBuilder &Builder = StrTabSec.StrTabBuilder;
   std::vector<DefinedCommon<ELFT> *> CommonSymbols;
   for (auto &P : Symtab.getSymbols()) {
     StringRef Name = P.first;
@@ -515,12 +541,14 @@ template <class ELFT> void Writer<ELFT>:
   BSSSec->setSize(Off);
 
   OutputSections.push_back(&SymTable);
-  OutputSections.push_back(&StringTable);
+  OutputSections.push_back(&StrTabSec);
 
   const std::vector<std::unique_ptr<SharedFileBase>> &SharedFiles =
       Symtab.getSharedFiles();
-  if (!SharedFiles.empty())
+  if (!SharedFiles.empty()) {
     OutputSections.push_back(&DynamicSec);
+    OutputSections.push_back(&DynStrSec);
+  }
 
   std::stable_sort(OutputSections.begin(), OutputSections.end(),
                    compSec<ELFT::Is64Bits>);
@@ -536,7 +564,7 @@ template <class ELFT> void Writer<ELFT>:
   uintX_t FileOff = SizeOfHeaders;
 
   for (OutputSectionBase<ELFT::Is64Bits> *Sec : OutputSections) {
-    StringTable.add(Sec->getName());
+    StrTabSec.add(Sec->getName());
     Sec->finalize();
 
     uintX_t Align = Sec->getAlign();
@@ -605,13 +633,13 @@ template <class ELFT> void Writer<ELFT>:
   EHdr->e_phnum = NumSegments;
   EHdr->e_shentsize = sizeof(Elf_Shdr);
   EHdr->e_shnum = getNumSections();
-  EHdr->e_shstrndx = StringTable.getSectionIndex();
+  EHdr->e_shstrndx = StrTabSec.getSectionIndex();
 
   auto PHdrs = reinterpret_cast<Elf_Phdr *>(Buf + EHdr->e_phoff);
   PHdrs->p_type = PT_LOAD;
   PHdrs->p_flags = PF_R | PF_X;
   PHdrs->p_offset = 0x0000;
-  PHdrs->p_vaddr = 0x400000;
+  PHdrs->p_vaddr = 0x1000;
   PHdrs->p_paddr = PHdrs->p_vaddr;
   PHdrs->p_filesz = FileSize;
   PHdrs->p_memsz = FileSize;
@@ -624,8 +652,8 @@ template <class ELFT> void Writer<ELFT>:
     PHdrs->p_offset = DynamicSec.getFileOff();
     PHdrs->p_vaddr = DynamicSec.getVA();
     PHdrs->p_paddr = PHdrs->p_vaddr;
-    PHdrs->p_filesz = 0;
-    PHdrs->p_memsz = 0;
+    PHdrs->p_filesz = DynamicSec.getSize();
+    PHdrs->p_memsz = DynamicSec.getSize();
     PHdrs->p_align = DynamicSec.getAlign();
   }
 
@@ -633,7 +661,7 @@ template <class ELFT> void Writer<ELFT>:
   // First entry is null.
   ++SHdrs;
   for (OutputSectionBase<ELFT::Is64Bits> *Sec : OutputSections) {
-    Sec->setNameOffset(StringTable.getFileOff(Sec->getName()));
+    Sec->setNameOffset(StrTabSec.getFileOff(Sec->getName()));
     Sec->template writeHeaderTo<ELFT::TargetEndianness>(SHdrs++);
   }
 }

Modified: lld/trunk/test/elf2/basic.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/basic.s?rev=247155&r1=247154&r2=247155&view=diff
==============================================================================
--- lld/trunk/test/elf2/basic.s (original)
+++ lld/trunk/test/elf2/basic.s Wed Sep  9 10:33:08 2015
@@ -152,8 +152,8 @@ _start:
 # CHECK-NEXT:   ProgramHeader {
 # CHECK-NEXT:     Type: PT_LOAD (0x1)
 # CHECK-NEXT:     Offset: 0x0
-# CHECK-NEXT:     VirtualAddress: 0x400000
-# CHECK-NEXT:     PhysicalAddress: 0x400000
+# CHECK-NEXT:     VirtualAddress: 0x1000
+# CHECK-NEXT:     PhysicalAddress: 0x1000
 # CHECK-NEXT:     FileSize: 4592
 # CHECK-NEXT:     MemSize: 4592
 # CHECK-NEXT:     Flags [ (0x5)

Modified: lld/trunk/test/elf2/basic32.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/basic32.s?rev=247155&r1=247154&r2=247155&view=diff
==============================================================================
--- lld/trunk/test/elf2/basic32.s (original)
+++ lld/trunk/test/elf2/basic32.s Wed Sep  9 10:33:08 2015
@@ -131,8 +131,8 @@ _start:
 # CHECK-NEXT:   ProgramHeader {
 # CHECK-NEXT:     Type: PT_LOAD (0x1)
 # CHECK-NEXT:     Offset: 0x0
-# CHECK-NEXT:     VirtualAddress: 0x400000
-# CHECK-NEXT:     PhysicalAddress: 0x400000
+# CHECK-NEXT:     VirtualAddress: 0x1000
+# CHECK-NEXT:     PhysicalAddress: 0x1000
 # CHECK-NEXT:     FileSize: 4424
 # CHECK-NEXT:     MemSize: 4424
 # CHECK-NEXT:     Flags [ (0x5)

Modified: lld/trunk/test/elf2/basic32be.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/basic32be.s?rev=247155&r1=247154&r2=247155&view=diff
==============================================================================
--- lld/trunk/test/elf2/basic32be.s (original)
+++ lld/trunk/test/elf2/basic32be.s Wed Sep  9 10:33:08 2015
@@ -131,8 +131,8 @@ _start:
 # CHECK-NEXT:   ProgramHeader {
 # CHECK-NEXT:     Type: PT_LOAD (0x1)
 # CHECK-NEXT:     Offset: 0x0
-# CHECK-NEXT:     VirtualAddress: 0x400000
-# CHECK-NEXT:     PhysicalAddress: 0x400000
+# CHECK-NEXT:     VirtualAddress: 0x1000
+# CHECK-NEXT:     PhysicalAddress: 0x1000
 # CHECK-NEXT:     FileSize: 4424
 # CHECK-NEXT:     MemSize: 4424
 # CHECK-NEXT:     Flags [ (0x5)

Modified: lld/trunk/test/elf2/basic64be.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/basic64be.s?rev=247155&r1=247154&r2=247155&view=diff
==============================================================================
--- lld/trunk/test/elf2/basic64be.s (original)
+++ lld/trunk/test/elf2/basic64be.s Wed Sep  9 10:33:08 2015
@@ -152,8 +152,8 @@ _start:
 # CHECK-NEXT:   ProgramHeader {
 # CHECK-NEXT:     Type: PT_LOAD (0x1)
 # CHECK-NEXT:     Offset: 0x0
-# CHECK-NEXT:     VirtualAddress: 0x400000
-# CHECK-NEXT:     PhysicalAddress: 0x400000
+# CHECK-NEXT:     VirtualAddress: 0x1000
+# CHECK-NEXT:     PhysicalAddress: 0x1000
 # CHECK-NEXT:     FileSize: 4680
 # CHECK-NEXT:     MemSize: 4680
 # CHECK-NEXT:     Flags [ (0x5)

Modified: lld/trunk/test/elf2/shared.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/shared.s?rev=247155&r1=247154&r2=247155&view=diff
==============================================================================
--- lld/trunk/test/elf2/shared.s (original)
+++ lld/trunk/test/elf2/shared.s Wed Sep  9 10:33:08 2015
@@ -1,6 +1,6 @@
 // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
 // RUN: lld -flavor gnu2 %t.o %p/Inputs/i686-simple-library.so -o %t
-// RUN: llvm-readobj --program-headers -t -s %t | FileCheck %s
+// RUN: llvm-readobj --program-headers --dynamic-table -t -s %t | FileCheck %s
 // REQUIRES: x86
 
 // CHECK:        Name: .dynamic
@@ -11,19 +11,20 @@
 // CHECK-NEXT:   ]
 // CHECK-NEXT:   Address: [[ADDR:.*]]
 // CHECK-NEXT:   Offset: [[OFFSET:.*]]
-// CHECK-NEXT:   Size: 0
-// CHECK-NEXT:   Link: [[STRTAB:.*]]
+// CHECK-NEXT:   Size: [[SIZE:.*]]
+// CHECK-NEXT:   Link: [[DYNSTR:.*]]
 // CHECK-NEXT:   Info: 0
 // CHECK-NEXT:   AddressAlignment: [[ALIGN:.*]]
 // CHECK-NEXT:   EntrySize: 8
 // CHECK-NEXT: }
 
-// CHECK:        Index: [[STRTAB]]
-// CHECK-NEXT:   Name: .strtab
+// CHECK:        Index: [[DYNSTR]]
+// CHECK-NEXT:   Name: .dynstr
 // CHECK-NEXT:   Type: SHT_STRTAB
 // CHECK-NEXT:   Flags [
+// CHECK-NEXT:     SHF_ALLOC
 // CHECK-NEXT:   ]
-// CHECK-NEXT:   Address:
+// CHECK-NEXT:   Address: [[DYNSTRADDR:.*]]
 // CHECK-NEXT:   Offset:
 // CHECK-NEXT:   Size:
 // CHECK-NEXT:   Link: 0
@@ -63,14 +64,19 @@
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]
 
+// CHECK:      DynamicSection [
+// CHECK-NEXT:   Tag        Type                 Name/Value
+// CHECK-NEXT:   0x00000005 STRTAB               [[DYNSTRADDR]]
+// CHECK-NEXT:   0x00000000 NULL                 0x0
+// CHECK-NEXT: ]
 
 // CHECK:      ProgramHeader {
 // CHECK:        Type: PT_DYNAMIC
 // CHECK-NEXT:   Offset: [[OFFSET]]
 // CHECK-NEXT:   VirtualAddress: [[ADDR]]
 // CHECK-NEXT:   PhysicalAddress: [[ADDR]]
-// CHECK-NEXT:   FileSize: 0
-// CHECK-NEXT:   MemSize: 0
+// CHECK-NEXT:   FileSize: [[SIZE]]
+// CHECK-NEXT:   MemSize: [[SIZE]]
 // CHECK-NEXT:   Flags [
 // CHECK-NEXT:     PF_R
 // CHECK-NEXT:     PF_W




More information about the llvm-commits mailing list