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.

llvm-svn: 285784
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 131aff5..45b9a85 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -722,19 +722,15 @@
   // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
   if (Config->EMachine == EM_MIPS)
     Header.sh_flags = SHF_ALLOC;
+
+  addEntries();
 }
 
-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); };
-
-  // 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 @@
   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 @@
   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 @@
   }
 
   // +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) {
diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h
index e14776c..1a00a23 100644
--- a/lld/ELF/OutputSections.h
+++ b/lld/ELF/OutputSections.h
@@ -640,11 +640,15 @@
   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>
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 1e5e3a2..af4fe83 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -218,6 +218,7 @@
   // 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 @@
     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 @@
 
   // 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)
diff --git a/lld/test/ELF/dynamic-reloc.s b/lld/test/ELF/dynamic-reloc.s
index 5e23ba9..a08d0c39 100644
--- a/lld/test/ELF/dynamic-reloc.s
+++ b/lld/test/ELF/dynamic-reloc.s
@@ -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: ]
 
diff --git a/lld/test/ELF/shared-be.s b/lld/test/ELF/shared-be.s
index 12eb313..c969793 100644
--- a/lld/test/ELF/shared-be.s
+++ b/lld/test/ELF/shared-be.s
@@ -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
diff --git a/lld/test/ELF/shared.s b/lld/test/ELF/shared.s
index c9ef377..38ba946 100644
--- a/lld/test/ELF/shared.s
+++ b/lld/test/ELF/shared.s
@@ -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: ]
 
diff --git a/lld/test/ELF/verneed.s b/lld/test/ELF/verneed.s
index 0b3992c0..4835e41 100644
--- a/lld/test/ELF/verneed.s
+++ b/lld/test/ELF/verneed.s
@@ -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: }