Fix a bug that MIPS thunks can overwrite other section contents.

Peter Smith found while trying to support thunk creation for ARM that
LLD sometimes creates broken thunks for MIPS. The cause of the bug is
that we assign file offsets to input sections too early. We need to
create all sections and then assign section offsets because appending
thunks changes file offsets for all following sections.

This patch separates the pass to assign file offsets from thunk
creation pass. This effectively reverts r265673.

Differential Revision: http://reviews.llvm.org/D21598

llvm-svn: 273532
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 6e20305..9875269 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -793,24 +793,24 @@
 
   // Scan relocations. This must be done after every symbol is declared so that
   // we can correctly decide if a dynamic relocation is needed.
-  for (OutputSectionBase<ELFT> *Sec : OutputSections) {
-    Sec->forEachInputSection([&](InputSectionBase<ELFT> *S) {
-      if (auto *IS = dyn_cast<InputSection<ELFT>>(S)) {
-        // Set OutSecOff so that scanRelocations can use it.
-        uintX_t Off = alignTo(Sec->getSize(), S->Alignment);
-        IS->OutSecOff = Off;
-
-        scanRelocations(*IS);
-
-        // Now that scan relocs possibly changed the size, update the offset.
-        Sec->setSize(Off + S->getSize());
-      } else if (auto *EH = dyn_cast<EhInputSection<ELFT>>(S)) {
-        if (EH->RelocSection)
-          scanRelocations(*EH, *EH->RelocSection);
+  for (const std::unique_ptr<elf::ObjectFile<ELFT>> &F :
+       Symtab.getObjectFiles()) {
+    for (InputSectionBase<ELFT> *C : F->getSections()) {
+      if (isDiscarded(C))
+        continue;
+      if (auto *S = dyn_cast<InputSection<ELFT>>(C)) {
+        scanRelocations(*S);
+        continue;
       }
-    });
+      if (auto *S = dyn_cast<EhInputSection<ELFT>>(C))
+        if (S->RelocSection)
+          scanRelocations(*S, *S->RelocSection);
+    }
   }
 
+  for (OutputSectionBase<ELFT> *Sec : OutputSections)
+    Sec->assignOffsets();
+
   // Now that we have defined all possible symbols including linker-
   // synthesized ones. Visit all symbols to give the finishing touches.
   std::vector<DefinedCommon *> CommonSymbols;