[ELF] Always use Script::assignAddresses()
    
This change fabricates linker script commands for the case where there is
no linker script SECTIONS to control address assignment. This permits us
to have a single Script->assignAddresses() function.
    
There is a small change in user-visible-behavior with respect to the
handling of .tbss SHT_NOBITS, SHF_TLS as the Script->assignAddresses()
requires setDot() to be called with monotically increasing addresses.
The tls-offset.s test has been updated so that the script and non-script
results match.

This change should make the non-script behavior of lld closer to an
equivalent linker script.

Differential Revision: https://reviews.llvm.org/D31888

llvm-svn: 300687
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index ab2ca22..63eb904 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -413,6 +413,56 @@
   CurOutSec = nullptr;
 }
 
+void LinkerScript::fabricateDefaultCommands(bool AllocateHeader) {
+  std::vector<BaseCommand *> Commands;
+
+  // Define start address
+  uint64_t StartAddr = Config->ImageBase;
+  if (AllocateHeader)
+    StartAddr += elf::getHeaderSize();
+
+  // The Sections with -T<section> are sorted in order of ascending address
+  // we must use this if it is lower than StartAddr as calls to setDot() must
+  // be monotonically increasing
+  if (!Config->SectionStartMap.empty()) {
+    uint64_t LowestSecStart = Config->SectionStartMap.begin()->second;
+    StartAddr = std::min(StartAddr, LowestSecStart);
+  }
+  Commands.push_back(
+      make<SymbolAssignment>(".", [=] { return StartAddr; }, ""));
+
+  // For each OutputSection that needs a VA fabricate an OutputSectionCommand
+  // with an InputSectionDescription describing the InputSections
+  for (OutputSection *Sec : *OutputSections) {
+    if (!(Sec->Flags & SHF_ALLOC))
+      continue;
+
+    auto I = Config->SectionStartMap.find(Sec->Name);
+    if (I != Config->SectionStartMap.end())
+      Commands.push_back(
+          make<SymbolAssignment>(".", [=] { return I->second; }, ""));
+
+    auto *OSCmd = make<OutputSectionCommand>(Sec->Name);
+    OSCmd->Sec = Sec;
+    if (Sec->PageAlign)
+      OSCmd->AddrExpr = [=] {
+        return alignTo(Script->getDot(), Config->MaxPageSize);
+      };
+    Commands.push_back(OSCmd);
+    if (Sec->Sections.size()) {
+      auto *ISD = make<InputSectionDescription>("");
+      OSCmd->Commands.push_back(ISD);
+      for (InputSection *ISec : Sec->Sections) {
+        ISD->Sections.push_back(ISec);
+        ISec->Assigned = true;
+      }
+    }
+  }
+  // SECTIONS commands run before other non SECTIONS commands
+  Commands.insert(Commands.end(), Opt.Commands.begin(), Opt.Commands.end());
+  Opt.Commands = std::move(Commands);
+}
+
 // Add sections that didn't match any sections command.
 void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
   for (InputSectionBase *S : InputSections)