[lld] r285784 - Add strings to .dynstr early.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 1 19:18:02 PDT 2016


Author: ruiu
Date: Tue Nov  1 21:18:01 2016
New Revision: 285784

URL: http://llvm.org/viewvc/llvm-project?rev=285784&view=rev
Log:
Add strings to .dynstr early.

Previously, we added strings from DynamicSection::finalize().
It was a bit tricky because finalize() is supposed to fix the final
size of the section, but adding new strings would change the size of
.dynstr section. So there was a dependency between finalize functions
of .dynamic and .dynstr.

However, I noticed that we can elimiante the dependency by simply
add strings early; we don't have to do that in finalize() but can do
from DynamicSection's ctor.

This patch defines a new function, DynamicSection::addEntries, to
add .dynamic entries that doesn't depend on other sections.

Modified:
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/ELF/dynamic-reloc.s
    lld/trunk/test/ELF/shared-be.s
    lld/trunk/test/ELF/shared.s
    lld/trunk/test/ELF/verneed.s

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=285784&r1=285783&r2=285784&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Tue Nov  1 21:18:01 2016
@@ -722,19 +722,15 @@ DynamicSection<ELFT>::DynamicSection()
   // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
   if (Config->EMachine == EM_MIPS)
     Header.sh_flags = SHF_ALLOC;
-}
-
-template <class ELFT> void DynamicSection<ELFT>::finalize() {
-  if (this->Header.sh_size)
-    return; // Already finalized.
-
-  Elf_Shdr &Header = this->Header;
-  Header.sh_link = Out<ELFT>::DynStrTab->SectionIndex;
 
-  auto Add = [=](Entry E) { Entries.push_back(E); };
+  addEntries();
+}
 
-  // Add strings. We know that these are the last strings to be added to
-  // DynStrTab and doing this here allows this function to set DT_STRSZ.
+// There are some dynamic entries that don't depend on other sections.
+// Such entries can be set early.
+template <class ELFT> void DynamicSection<ELFT>::addEntries() {
+  // Add strings to .dynstr early so that .dynstr's size will be
+  // fixed early.
   for (StringRef S : Config->AuxiliaryList)
     Add({DT_AUXILIARY, Out<ELFT>::DynStrTab->addString(S)});
   if (!Config->RPath.empty())
@@ -746,7 +742,37 @@ template <class ELFT> void DynamicSectio
   if (!Config->SoName.empty())
     Add({DT_SONAME, Out<ELFT>::DynStrTab->addString(Config->SoName)});
 
-  Out<ELFT>::DynStrTab->finalize();
+  // Set DT_FLAGS and DT_FLAGS_1.
+  uint32_t DtFlags = 0;
+  uint32_t DtFlags1 = 0;
+  if (Config->Bsymbolic)
+    DtFlags |= DF_SYMBOLIC;
+  if (Config->ZNodelete)
+    DtFlags1 |= DF_1_NODELETE;
+  if (Config->ZNow) {
+    DtFlags |= DF_BIND_NOW;
+    DtFlags1 |= DF_1_NOW;
+  }
+  if (Config->ZOrigin) {
+    DtFlags |= DF_ORIGIN;
+    DtFlags1 |= DF_1_ORIGIN;
+  }
+
+  if (DtFlags)
+    Add({DT_FLAGS, DtFlags});
+  if (DtFlags1)
+    Add({DT_FLAGS_1, DtFlags1});
+
+  if (!Config->Entry.empty())
+    Add({DT_DEBUG, (uint64_t)0});
+}
+
+// Add remaining entries to complete .dynamic contents.
+template <class ELFT> void DynamicSection<ELFT>::finalize() {
+  if (this->Header.sh_size)
+    return; // Already finalized.
+
+  this->Header.sh_link = Out<ELFT>::DynStrTab->SectionIndex;
 
   if (Out<ELFT>::RelaDyn->hasRelocs()) {
     bool IsRela = Config->Rela;
@@ -799,29 +825,6 @@ template <class ELFT> void DynamicSectio
   if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Fini))
     Add({DT_FINI, B});
 
-  uint32_t DtFlags = 0;
-  uint32_t DtFlags1 = 0;
-  if (Config->Bsymbolic)
-    DtFlags |= DF_SYMBOLIC;
-  if (Config->ZNodelete)
-    DtFlags1 |= DF_1_NODELETE;
-  if (Config->ZNow) {
-    DtFlags |= DF_BIND_NOW;
-    DtFlags1 |= DF_1_NOW;
-  }
-  if (Config->ZOrigin) {
-    DtFlags |= DF_ORIGIN;
-    DtFlags1 |= DF_1_ORIGIN;
-  }
-
-  if (DtFlags)
-    Add({DT_FLAGS, DtFlags});
-  if (DtFlags1)
-    Add({DT_FLAGS_1, DtFlags1});
-
-  if (!Config->Entry.empty())
-    Add({DT_DEBUG, (uint64_t)0});
-
   bool HasVerNeed = Out<ELFT>::VerNeed->getNeedNum() != 0;
   if (HasVerNeed || Out<ELFT>::VerDef)
     Add({DT_VERSYM, Out<ELFT>::VerSym});
@@ -850,7 +853,7 @@ template <class ELFT> void DynamicSectio
   }
 
   // +1 for DT_NULL
-  Header.sh_size = (Entries.size() + 1) * Header.sh_entsize;
+  this->Header.sh_size = (Entries.size() + 1) * this->Header.sh_entsize;
 }
 
 template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=285784&r1=285783&r2=285784&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Tue Nov  1 21:18:01 2016
@@ -640,11 +640,15 @@ class DynamicSection final : public Outp
   std::vector<Entry> Entries;
 
 public:
-  explicit DynamicSection();
+  DynamicSection();
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
   typename Base::Kind getKind() const override { return Base::Dynamic; }
   static bool classof(const Base *B) { return B->getKind() == Base::Dynamic; }
+
+private:
+  void addEntries();
+  void Add(Entry E) { Entries.push_back(E); }
 };
 
 template <class ELFT>

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=285784&r1=285783&r2=285784&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue Nov  1 21:18:01 2016
@@ -218,6 +218,7 @@ template <class ELFT> void Writer<ELFT>:
   // Create singleton output sections.
   Out<ELFT>::Bss =
       make<OutputSection<ELFT>>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
+  Out<ELFT>::DynStrTab = make<StringTableSection<ELFT>>(".dynstr", true);
   Out<ELFT>::Dynamic = make<DynamicSection<ELFT>>();
   Out<ELFT>::EhFrame = make<EhOutputSection<ELFT>>();
   Out<ELFT>::Got = make<GotSection<ELFT>>();
@@ -237,7 +238,6 @@ template <class ELFT> void Writer<ELFT>:
     Out<ELFT>::Interp = make<InterpSection<ELFT>>();
 
   if (!Symtab<ELFT>::X->getSharedFiles().empty() || Config->Pic) {
-    Out<ELFT>::DynStrTab = make<StringTableSection<ELFT>>(".dynstr", true);
     Out<ELFT>::DynSymTab =
         make<SymbolTableSection<ELFT>>(*Out<ELFT>::DynStrTab);
   }
@@ -837,11 +837,9 @@ template <class ELFT> void Writer<ELFT>:
 
   // Fill other section headers. The dynamic table is finalized
   // at the end because some tags like RELSZ depend on result
-  // of finalizing other sections. The dynamic string table is
-  // finalized once the .dynamic finalizer has added a few last
-  // strings. See DynamicSection::finalize()
+  // of finalizing other sections.
   for (OutputSectionBase<ELFT> *Sec : OutputSections)
-    if (Sec != Out<ELFT>::DynStrTab && Sec != Out<ELFT>::Dynamic)
+    if (Sec != Out<ELFT>::Dynamic)
       Sec->finalize();
 
   if (Out<ELFT>::DynSymTab)

Modified: lld/trunk/test/ELF/dynamic-reloc.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/dynamic-reloc.s?rev=285784&r1=285783&r2=285784&view=diff
==============================================================================
--- lld/trunk/test/ELF/dynamic-reloc.s (original)
+++ lld/trunk/test/ELF/dynamic-reloc.s Tue Nov  1 21:18:01 2016
@@ -44,6 +44,7 @@
 // CHECK: DynamicSection [
 // CHECK-NEXT:  Tag                Type                 Name/Value
 // CHECK-NEXT:  0x0000000000000001 NEEDED               SharedLibrary ({{.*}}2.so)
+// CHECK-NEXT:  0x0000000000000015 DEBUG                0x0
 // CHECK-NEXT:  0x0000000000000017 JMPREL
 // CHECK-NEXT:  0x0000000000000002 PLTRELSZ             24 (bytes)
 // CHECK-NEXT:  0x0000000000000003 PLTGOT
@@ -53,7 +54,6 @@
 // CHECK-NEXT:  0x0000000000000005 STRTAB
 // CHECK-NEXT:  0x000000000000000A STRSZ
 // CHECK-NEXT:  0x0000000000000004 HASH
-// CHECK-NEXT:  0x0000000000000015 DEBUG                0x0
 // CHECK-NEXT:  0x0000000000000000 NULL                 0x0
 // CHECK-NEXT: ]
 

Modified: lld/trunk/test/ELF/shared-be.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/shared-be.s?rev=285784&r1=285783&r2=285784&view=diff
==============================================================================
--- lld/trunk/test/ELF/shared-be.s (original)
+++ lld/trunk/test/ELF/shared-be.s Tue Nov  1 21:18:01 2016
@@ -22,11 +22,11 @@
 // CHECK-NEXT:   Tag                Type                 Name/Value
 // CHECK-NEXT:   0x000000000000001D RUNPATH              foo:bar
 // CHECK-NEXT:   0x0000000000000001 NEEDED               SharedLibrary ({{.*}}2.so)
+// CHECK-NEXT:   0x0000000000000015 DEBUG                0x0
 // CHECK-NEXT:   0x0000000000000007 RELA                 [[RELADDR]]
 // CHECK-NEXT:   0x0000000000000008 RELASZ               [[RELSIZE]] (bytes)
 // CHECK-NEXT:   0x0000000000000009 RELAENT              [[RELENT]] (bytes)
-// CHECK:        0x0000000000000015 DEBUG                0x0
-// CHECK-NEXT:   0x0000000000000000 NULL                 0x0
+// CHECK:        0x0000000000000000 NULL                 0x0
 // CHECK-NEXT: ]
 
 .global _start

Modified: lld/trunk/test/ELF/shared.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/shared.s?rev=285784&r1=285783&r2=285784&view=diff
==============================================================================
--- lld/trunk/test/ELF/shared.s (original)
+++ lld/trunk/test/ELF/shared.s Tue Nov  1 21:18:01 2016
@@ -255,6 +255,7 @@
 // CHECK-NEXT:   Tag        Type                 Name/Value
 // CHECK-NEXT:   0x0000001D RUNPATH              foo:bar
 // CHECK-NEXT:   0x00000001 NEEDED               SharedLibrary ({{.*}}2.so)
+// CHECK-NEXT:   0x00000015 DEBUG                0x0
 // CHECK-NEXT:   0x00000011 REL                  [[RELADDR]]
 // CHECK-NEXT:   0x00000012 RELSZ                [[RELSIZE]] (bytes)
 // CHECK-NEXT:   0x00000013 RELENT               [[RELENT]] (bytes)
@@ -263,7 +264,6 @@
 // CHECK-NEXT:   0x00000005 STRTAB               [[DYNSTRADDR]]
 // CHECK-NEXT:   0x0000000A STRSZ
 // CHECK-NEXT:   0x00000004 HASH                 [[HASHADDR]]
-// CHECK-NEXT:   0x00000015 DEBUG                0x0
 // CHECK-NEXT:   0x00000000 NULL                 0x0
 // CHECK-NEXT: ]
 

Modified: lld/trunk/test/ELF/verneed.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/verneed.s?rev=285784&r1=285783&r2=285784&view=diff
==============================================================================
--- lld/trunk/test/ELF/verneed.s (original)
+++ lld/trunk/test/ELF/verneed.s Tue Nov  1 21:18:01 2016
@@ -60,9 +60,9 @@
 # CHECK-NEXT:   AddressAlignment: 1
 # CHECK-NEXT:   EntrySize: 0
 # CHECK-NEXT:   SectionData (
-# CHECK-NEXT:     0000: 00663100 7665726E 65656431 2E736F2E  |.f1.verneed1.so.|
-# CHECK-NEXT:     0010: 30007633 00663200 76320067 31007665  |0.v3.f2.v2.g1.ve|
-# CHECK-NEXT:     0020: 726E6565 64322E73 6F2E3000 763100    |rneed2.so.0.v1.|
+# CHECK-NEXT:     0000: 00766572 6E656564 312E736F 2E300076  |.verneed1.so.0.v|
+# CHECK-NEXT:     0010: 65726E65 6564322E 736F2E30 00663100  |erneed2.so.0.f1.|
+# CHECK-NEXT:     0020: 76330066 32007632 00673100 763100    |v3.f2.v2.g1.v1.|
 # CHECK-NEXT:   )
 # CHECK-NEXT: }
 




More information about the llvm-commits mailing list