Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 8 May 2017 17:13:44 +0000 (UTC)
From:      Dimitry Andric <dim@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org
Subject:   svn commit: r317957 - in vendor/lld/dist: . COFF ELF include/lld/Core include/lld/Support lib/Core test/ELF test/ELF/Inputs test/ELF/linkerscript test/ELF/linkerscript/Inputs test/ELF/lto test/ELF/...
Message-ID:  <201705081713.v48HDiRV043006@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dim
Date: Mon May  8 17:13:44 2017
New Revision: 317957
URL: https://svnweb.freebsd.org/changeset/base/317957

Log:
  Vendor import of lld trunk r302418:
  https://llvm.org/svn/llvm-project/lld/trunk@302418

Added:
  vendor/lld/dist/include/lld/Core/TaskGroup.h   (contents, props changed)
  vendor/lld/dist/lib/Core/TaskGroup.cpp   (contents, props changed)
  vendor/lld/dist/test/ELF/Inputs/i386-static-tls-model1.s   (contents, props changed)
  vendor/lld/dist/test/ELF/Inputs/i386-static-tls-model2.s   (contents, props changed)
  vendor/lld/dist/test/ELF/Inputs/i386-static-tls-model3.s   (contents, props changed)
  vendor/lld/dist/test/ELF/Inputs/i386-static-tls-model4.s   (contents, props changed)
  vendor/lld/dist/test/ELF/i386-static-tls-model.s   (contents, props changed)
  vendor/lld/dist/test/ELF/linkerscript/Inputs/compress-debug-sections.s   (contents, props changed)
  vendor/lld/dist/test/ELF/linkerscript/compress-debug-sections.s   (contents, props changed)
  vendor/lld/dist/test/ELF/lto/Inputs/duplicated-name.ll
  vendor/lld/dist/test/ELF/lto/duplicated-name.ll
Deleted:
  vendor/lld/dist/include/lld/Support/
Modified:
  vendor/lld/dist/CMakeLists.txt
  vendor/lld/dist/COFF/Chunks.h
  vendor/lld/dist/COFF/ICF.cpp
  vendor/lld/dist/COFF/PDB.cpp
  vendor/lld/dist/ELF/Config.h
  vendor/lld/dist/ELF/Driver.cpp
  vendor/lld/dist/ELF/InputFiles.cpp
  vendor/lld/dist/ELF/InputFiles.h
  vendor/lld/dist/ELF/LinkerScript.cpp
  vendor/lld/dist/ELF/LinkerScript.h
  vendor/lld/dist/ELF/Options.td
  vendor/lld/dist/ELF/OutputSections.cpp
  vendor/lld/dist/ELF/Relocations.cpp
  vendor/lld/dist/ELF/SymbolTable.cpp
  vendor/lld/dist/ELF/Symbols.cpp
  vendor/lld/dist/ELF/SyntheticSections.cpp
  vendor/lld/dist/ELF/Target.cpp
  vendor/lld/dist/ELF/Target.h
  vendor/lld/dist/ELF/Writer.cpp
  vendor/lld/dist/ELF/Writer.h
  vendor/lld/dist/include/lld/Core/Parallel.h
  vendor/lld/dist/lib/Core/CMakeLists.txt
  vendor/lld/dist/test/ELF/defsym.s
  vendor/lld/dist/test/ELF/i386-tls-ie-shared.s
  vendor/lld/dist/test/ELF/lto/archive-no-index.ll
  vendor/lld/dist/test/ELF/lto/thin-archivecollision.ll
  vendor/lld/dist/test/ELF/tls-dynamic-i686.s
  vendor/lld/dist/test/ELF/tls-offset.s
  vendor/lld/dist/test/ELF/tls-opt-iele-i686-nopic.s
  vendor/lld/dist/unittests/CoreTests/CMakeLists.txt

Modified: vendor/lld/dist/CMakeLists.txt
==============================================================================
--- vendor/lld/dist/CMakeLists.txt	Mon May  8 17:13:41 2017	(r317956)
+++ vendor/lld/dist/CMakeLists.txt	Mon May  8 17:13:44 2017	(r317957)
@@ -221,3 +221,4 @@ endif()
 add_subdirectory(docs)
 add_subdirectory(COFF)
 add_subdirectory(ELF)
+

Modified: vendor/lld/dist/COFF/Chunks.h
==============================================================================
--- vendor/lld/dist/COFF/Chunks.h	Mon May  8 17:13:41 2017	(r317956)
+++ vendor/lld/dist/COFF/Chunks.h	Mon May  8 17:13:44 2017	(r317957)
@@ -201,7 +201,7 @@ private:
 
   // Used for ICF (Identical COMDAT Folding)
   void replace(SectionChunk *Other);
-  uint32_t Color[2] = {0, 0};
+  uint32_t Class[2] = {0, 0};
 
   // Sym points to a section symbol if this is a COMDAT chunk.
   DefinedRegular *Sym = nullptr;

Modified: vendor/lld/dist/COFF/ICF.cpp
==============================================================================
--- vendor/lld/dist/COFF/ICF.cpp	Mon May  8 17:13:41 2017	(r317956)
+++ vendor/lld/dist/COFF/ICF.cpp	Mon May  8 17:13:44 2017	(r317957)
@@ -49,10 +49,10 @@ private:
 
   size_t findBoundary(size_t Begin, size_t End);
 
-  void forEachColorRange(size_t Begin, size_t End,
+  void forEachClassRange(size_t Begin, size_t End,
                          std::function<void(size_t, size_t)> Fn);
 
-  void forEachColor(std::function<void(size_t, size_t)> Fn);
+  void forEachClass(std::function<void(size_t, size_t)> Fn);
 
   std::vector<SectionChunk *> Chunks;
   int Cnt = 0;
@@ -85,7 +85,7 @@ bool ICF::isEligible(SectionChunk *C) {
   return C->isCOMDAT() && C->isLive() && Global && Executable && !Writable;
 }
 
-// Split a range into smaller ranges by recoloring sections
+// Split an equivalence class into smaller classes.
 void ICF::segregate(size_t Begin, size_t End, bool Constant) {
   while (Begin < End) {
     // Divide [Begin, End) into two. Let Mid be the start index of the
@@ -101,7 +101,7 @@ void ICF::segregate(size_t Begin, size_t
     // Split [Begin, End) into [Begin, Mid) and [Mid, End).
     uint32_t Id = NextId++;
     for (size_t I = Begin; I < Mid; ++I)
-      Chunks[I]->Color[(Cnt + 1) % 2] = Id;
+      Chunks[I]->Class[(Cnt + 1) % 2] = Id;
 
     // If we created a group, we need to iterate the main loop again.
     if (Mid != End)
@@ -130,7 +130,7 @@ bool ICF::equalsConstant(const SectionCh
     if (auto *D1 = dyn_cast<DefinedRegular>(B1))
       if (auto *D2 = dyn_cast<DefinedRegular>(B2))
         return D1->getValue() == D2->getValue() &&
-               D1->getChunk()->Color[Cnt % 2] == D2->getChunk()->Color[Cnt % 2];
+               D1->getChunk()->Class[Cnt % 2] == D2->getChunk()->Class[Cnt % 2];
     return false;
   };
   if (!std::equal(A->Relocs.begin(), A->Relocs.end(), B->Relocs.begin(), Eq))
@@ -155,7 +155,7 @@ bool ICF::equalsVariable(const SectionCh
       return true;
     if (auto *D1 = dyn_cast<DefinedRegular>(B1))
       if (auto *D2 = dyn_cast<DefinedRegular>(B2))
-        return D1->getChunk()->Color[Cnt % 2] == D2->getChunk()->Color[Cnt % 2];
+        return D1->getChunk()->Class[Cnt % 2] == D2->getChunk()->Class[Cnt % 2];
     return false;
   };
   return std::equal(A->Relocs.begin(), A->Relocs.end(), B->Relocs.begin(), Eq);
@@ -163,12 +163,12 @@ bool ICF::equalsVariable(const SectionCh
 
 size_t ICF::findBoundary(size_t Begin, size_t End) {
   for (size_t I = Begin + 1; I < End; ++I)
-    if (Chunks[Begin]->Color[Cnt % 2] != Chunks[I]->Color[Cnt % 2])
+    if (Chunks[Begin]->Class[Cnt % 2] != Chunks[I]->Class[Cnt % 2])
       return I;
   return End;
 }
 
-void ICF::forEachColorRange(size_t Begin, size_t End,
+void ICF::forEachClassRange(size_t Begin, size_t End,
                             std::function<void(size_t, size_t)> Fn) {
   if (Begin > 0)
     Begin = findBoundary(Begin - 1, End);
@@ -180,12 +180,12 @@ void ICF::forEachColorRange(size_t Begin
   }
 }
 
-// Call Fn on each color group.
-void ICF::forEachColor(std::function<void(size_t, size_t)> Fn) {
+// Call Fn on each class group.
+void ICF::forEachClass(std::function<void(size_t, size_t)> Fn) {
   // If the number of sections are too small to use threading,
   // call Fn sequentially.
   if (Chunks.size() < 1024) {
-    forEachColorRange(0, Chunks.size(), Fn);
+    forEachClassRange(0, Chunks.size(), Fn);
     return;
   }
 
@@ -193,9 +193,9 @@ void ICF::forEachColor(std::function<voi
   size_t NumShards = 256;
   size_t Step = Chunks.size() / NumShards;
   parallel_for(size_t(0), NumShards, [&](size_t I) {
-    forEachColorRange(I * Step, (I + 1) * Step, Fn);
+    forEachClassRange(I * Step, (I + 1) * Step, Fn);
   });
-  forEachColorRange(Step * NumShards, Chunks.size(), Fn);
+  forEachClassRange(Step * NumShards, Chunks.size(), Fn);
 }
 
 // Merge identical COMDAT sections.
@@ -209,11 +209,11 @@ void ICF::run(const std::vector<Chunk *>
       continue;
 
     if (isEligible(SC)) {
-      // Set MSB to 1 to avoid collisions with non-hash colors.
-      SC->Color[0] = getHash(SC) | (1 << 31);
+      // Set MSB to 1 to avoid collisions with non-hash classs.
+      SC->Class[0] = getHash(SC) | (1 << 31);
       Chunks.push_back(SC);
     } else {
-      SC->Color[0] = NextId++;
+      SC->Class[0] = NextId++;
     }
   }
 
@@ -224,25 +224,25 @@ void ICF::run(const std::vector<Chunk *>
   // the same group are consecutive in the vector.
   std::stable_sort(Chunks.begin(), Chunks.end(),
                    [](SectionChunk *A, SectionChunk *B) {
-                     return A->Color[0] < B->Color[0];
+                     return A->Class[0] < B->Class[0];
                    });
 
   // Compare static contents and assign unique IDs for each static content.
-  forEachColor([&](size_t Begin, size_t End) { segregate(Begin, End, true); });
+  forEachClass([&](size_t Begin, size_t End) { segregate(Begin, End, true); });
   ++Cnt;
 
   // Split groups by comparing relocations until convergence is obtained.
   do {
     Repeat = false;
-    forEachColor(
+    forEachClass(
         [&](size_t Begin, size_t End) { segregate(Begin, End, false); });
     ++Cnt;
   } while (Repeat);
 
   log("ICF needed " + Twine(Cnt) + " iterations");
 
-  // Merge sections in the same colors.
-  forEachColor([&](size_t Begin, size_t End) {
+  // Merge sections in the same classs.
+  forEachClass([&](size_t Begin, size_t End) {
     if (End - Begin == 1)
       return;
 

Modified: vendor/lld/dist/COFF/PDB.cpp
==============================================================================
--- vendor/lld/dist/COFF/PDB.cpp	Mon May  8 17:13:41 2017	(r317956)
+++ vendor/lld/dist/COFF/PDB.cpp	Mon May  8 17:13:44 2017	(r317957)
@@ -133,7 +133,7 @@ static void dumpDebugT(ScopedPrinter &W,
   if (Data.empty())
     return;
 
-  TypeDatabase TDB;
+  TypeDatabase TDB(0);
   TypeDumpVisitor TDV(TDB, &W, false);
   // Use a default implementation that does not follow type servers and instead
   // just dumps the contents of the TypeServer2 record.
@@ -154,7 +154,7 @@ static void dumpDebugS(ScopedPrinter &W,
   if (auto EC = Reader.readArray(Symbols, Reader.getLength()))
     fatal(EC, "StreamReader.readArray<CVSymbolArray> failed");
 
-  TypeDatabase TDB;
+  TypeDatabase TDB(0);
   CVSymbolDumper SymbolDumper(W, TDB, nullptr, false);
   if (auto EC = SymbolDumper.dump(Symbols))
     fatal(EC, "CVSymbolDumper::dump failed");

Modified: vendor/lld/dist/ELF/Config.h
==============================================================================
--- vendor/lld/dist/ELF/Config.h	Mon May  8 17:13:41 2017	(r317956)
+++ vendor/lld/dist/ELF/Config.h	Mon May  8 17:13:44 2017	(r317957)
@@ -73,6 +73,7 @@ struct VersionDefinition {
 // Most fields are initialized by the driver.
 struct Configuration {
   InputFile *FirstElf = nullptr;
+  bool HasStaticTlsModel = false;
   uint8_t OSABI = 0;
   llvm::CachePruningPolicy ThinLTOCachePolicy;
   llvm::StringMap<uint64_t> SectionStartMap;
@@ -99,7 +100,6 @@ struct Configuration {
   std::vector<SymbolVersion> VersionScriptLocals;
   std::vector<uint8_t> BuildIdVector;
   bool AllowMultipleDefinition;
-  bool ArchiveWithoutSymbolsSeen = false;
   bool AsNeeded = false;
   bool Bsymbolic;
   bool BsymbolicFunctions;

Modified: vendor/lld/dist/ELF/Driver.cpp
==============================================================================
--- vendor/lld/dist/ELF/Driver.cpp	Mon May  8 17:13:41 2017	(r317956)
+++ vendor/lld/dist/ELF/Driver.cpp	Mon May  8 17:13:44 2017	(r317957)
@@ -123,13 +123,13 @@ static std::tuple<ELFKind, uint16_t, uin
 
 // Returns slices of MB by parsing MB as an archive file.
 // Each slice consists of a member file in the archive.
-std::vector<MemoryBufferRef>
-static getArchiveMembers(MemoryBufferRef MB) {
+std::vector<std::pair<MemoryBufferRef, uint64_t>> static getArchiveMembers(
+    MemoryBufferRef MB) {
   std::unique_ptr<Archive> File =
       check(Archive::create(MB),
             MB.getBufferIdentifier() + ": failed to parse archive");
 
-  std::vector<MemoryBufferRef> V;
+  std::vector<std::pair<MemoryBufferRef, uint64_t>> V;
   Error Err = Error::success();
   for (const ErrorOr<Archive::Child> &COrErr : File->children(Err)) {
     Archive::Child C =
@@ -139,7 +139,7 @@ static getArchiveMembers(MemoryBufferRef
         check(C.getMemoryBufferRef(),
               MB.getBufferIdentifier() +
                   ": could not get the buffer for a child of the archive");
-    V.push_back(MBRef);
+    V.push_back(std::make_pair(MBRef, C.getChildOffset()));
   }
   if (Err)
     fatal(MB.getBufferIdentifier() + ": Archive::children failed: " +
@@ -152,8 +152,7 @@ static getArchiveMembers(MemoryBufferRef
   return V;
 }
 
-// Opens and parses a file. Path has to be resolved already.
-// Newly created memory buffers are owned by this driver.
+// Opens a file and create a file object. Path has to be resolved already.
 void LinkerDriver::addFile(StringRef Path, bool WithLOption) {
   using namespace sys::fs;
 
@@ -171,14 +170,31 @@ void LinkerDriver::addFile(StringRef Pat
   case file_magic::unknown:
     readLinkerScript(MBRef);
     return;
-  case file_magic::archive:
+  case file_magic::archive: {
+    // Handle -whole-archive.
     if (InWholeArchive) {
-      for (MemoryBufferRef MB : getArchiveMembers(MBRef))
-        Files.push_back(createObjectFile(MB, Path));
+      for (const auto &P : getArchiveMembers(MBRef))
+        Files.push_back(createObjectFile(P.first, Path, P.second));
       return;
     }
-    Files.push_back(make<ArchiveFile>(MBRef));
+
+    std::unique_ptr<Archive> File =
+        check(Archive::create(MBRef), Path + ": failed to parse archive");
+
+    // If an archive file has no symbol table, it is likely that a user
+    // is attempting LTO and using a default ar command that doesn't
+    // understand the LLVM bitcode file. It is a pretty common error, so
+    // we'll handle it as if it had a symbol table.
+    if (!File->hasSymbolTable()) {
+      for (const auto &P : getArchiveMembers(MBRef))
+        Files.push_back(make<LazyObjectFile>(P.first, Path, P.second));
+      return;
+    }
+
+    // Handle the regular case.
+    Files.push_back(make<ArchiveFile>(std::move(File)));
     return;
+  }
   case file_magic::elf_shared_object:
     if (Config->Relocatable) {
       error("attempted static link of dynamic object " + Path);
@@ -199,7 +215,7 @@ void LinkerDriver::addFile(StringRef Pat
     return;
   default:
     if (InLib)
-      Files.push_back(make<LazyObjectFile>(MBRef));
+      Files.push_back(make<LazyObjectFile>(MBRef, "", 0));
     else
       Files.push_back(createObjectFile(MBRef));
   }

Modified: vendor/lld/dist/ELF/InputFiles.cpp
==============================================================================
--- vendor/lld/dist/ELF/InputFiles.cpp	Mon May  8 17:13:41 2017	(r317956)
+++ vendor/lld/dist/ELF/InputFiles.cpp	Mon May  8 17:13:44 2017	(r317957)
@@ -596,17 +596,13 @@ SymbolBody *elf::ObjectFile<ELFT>::creat
   }
 }
 
-template <class ELFT> void ArchiveFile::parse() {
-  File = check(Archive::create(MB),
-               MB.getBufferIdentifier() + ": failed to parse archive");
+ArchiveFile::ArchiveFile(std::unique_ptr<Archive> &&File)
+    : InputFile(ArchiveKind, File->getMemoryBufferRef()),
+      File(std::move(File)) {}
 
-  // Read the symbol table to construct Lazy objects.
-  for (const Archive::Symbol &Sym : File->symbols()) {
+template <class ELFT> void ArchiveFile::parse() {
+  for (const Archive::Symbol &Sym : File->symbols())
     Symtab<ELFT>::X->addLazyArchive(this, Sym);
-  }
-
-  if (File->symbols().begin() == File->symbols().end())
-    Config->ArchiveWithoutSymbolsSeen = true;
 }
 
 // Returns a buffer pointing to a member file containing a given symbol.
@@ -981,6 +977,13 @@ MemoryBufferRef LazyObjectFile::getBuffe
   return MB;
 }
 
+InputFile *LazyObjectFile::fetch() {
+  MemoryBufferRef MBRef = getBuffer();
+  if (MBRef.getBuffer().empty())
+    return nullptr;
+  return createObjectFile(MBRef, ArchiveName, OffsetInArchive);
+}
+
 template <class ELFT> void LazyObjectFile::parse() {
   for (StringRef Sym : getSymbols())
     Symtab<ELFT>::X->addLazyObject(Sym, *this);

Modified: vendor/lld/dist/ELF/InputFiles.h
==============================================================================
--- vendor/lld/dist/ELF/InputFiles.h	Mon May  8 17:13:41 2017	(r317956)
+++ vendor/lld/dist/ELF/InputFiles.h	Mon May  8 17:13:44 2017	(r317957)
@@ -219,7 +219,11 @@ private:
 // archive file semantics.
 class LazyObjectFile : public InputFile {
 public:
-  explicit LazyObjectFile(MemoryBufferRef M) : InputFile(LazyObjectKind, M) {}
+  LazyObjectFile(MemoryBufferRef M, StringRef ArchiveName,
+                 uint64_t OffsetInArchive)
+      : InputFile(LazyObjectKind, M), OffsetInArchive(OffsetInArchive) {
+    this->ArchiveName = ArchiveName;
+  }
 
   static bool classof(const InputFile *F) {
     return F->kind() == LazyObjectKind;
@@ -227,6 +231,7 @@ public:
 
   template <class ELFT> void parse();
   MemoryBufferRef getBuffer();
+  InputFile *fetch();
 
 private:
   std::vector<StringRef> getSymbols();
@@ -234,12 +239,13 @@ private:
   std::vector<StringRef> getBitcodeSymbols();
 
   bool Seen = false;
+  uint64_t OffsetInArchive;
 };
 
 // An ArchiveFile object represents a .a file.
 class ArchiveFile : public InputFile {
 public:
-  explicit ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {}
+  explicit ArchiveFile(std::unique_ptr<Archive> &&File);
   static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }
   template <class ELFT> void parse();
 

Modified: vendor/lld/dist/ELF/LinkerScript.cpp
==============================================================================
--- vendor/lld/dist/ELF/LinkerScript.cpp	Mon May  8 17:13:41 2017	(r317956)
+++ vendor/lld/dist/ELF/LinkerScript.cpp	Mon May  8 17:13:44 2017	(r317957)
@@ -406,27 +406,22 @@ void LinkerScript::processCommands(Outpu
       }
 
       // Add input sections to an output section.
-      unsigned Pos = 0;
-      for (InputSectionBase *S : V) {
-        // The actual offset will be computed during
-        // assignAddresses. For now, use the index as a very crude
-        // approximation so that it is at least easy for other code to
-        // know the section order.
-        cast<InputSection>(S)->OutSecOff = Pos++;
+      for (InputSectionBase *S : V)
         Factory.addInputSec(S, Cmd->Name, Cmd->Sec);
+      if (OutputSection *Sec = Cmd->Sec) {
+        assert(Sec->SectionIndex == INT_MAX);
+        Sec->SectionIndex = I;
       }
     }
   }
   CurOutSec = nullptr;
 }
 
-void LinkerScript::fabricateDefaultCommands(bool AllocateHeader) {
+void LinkerScript::fabricateDefaultCommands() {
   std::vector<BaseCommand *> Commands;
 
   // Define start address
-  uint64_t StartAddr = Config->ImageBase;
-  if (AllocateHeader)
-    StartAddr += elf::getHeaderSize();
+  uint64_t StartAddr = Config->ImageBase + elf::getHeaderSize();
 
   // The Sections with -T<section> have been sorted in order of ascending
   // address. We must lower StartAddr if the lowest -T<section address> as
@@ -488,6 +483,11 @@ void LinkerScript::addOrphanSections(Out
     } else {
       auto *Cmd = cast<OutputSectionCommand>(*I);
       Factory.addInputSec(S, Name, Cmd->Sec);
+      if (OutputSection *Sec = Cmd->Sec) {
+        unsigned Index = std::distance(Opt.Commands.begin(), I);
+        assert(Sec->SectionIndex == INT_MAX || Sec->SectionIndex == Index);
+        Sec->SectionIndex = Index;
+      }
       auto *ISD = make<InputSectionDescription>("");
       ISD->Sections.push_back(S);
       Cmd->Commands.push_back(ISD);
@@ -495,17 +495,22 @@ void LinkerScript::addOrphanSections(Out
   }
 }
 
-static bool isTbss(OutputSection *Sec) {
-  return (Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS;
+uint64_t LinkerScript::advance(uint64_t Size, unsigned Align) {
+  bool IsTbss = (CurOutSec->Flags & SHF_TLS) && CurOutSec->Type == SHT_NOBITS;
+  uint64_t Start = IsTbss ? Dot + ThreadBssOffset : Dot;
+  Start = alignTo(Start, Align);
+  uint64_t End = Start + Size;
+
+  if (IsTbss)
+    ThreadBssOffset = End - Dot;
+  else
+    Dot = End;
+  return End;
 }
 
 void LinkerScript::output(InputSection *S) {
-  bool IsTbss = isTbss(CurOutSec);
-
-  uint64_t Pos = IsTbss ? Dot + ThreadBssOffset : Dot;
-  Pos = alignTo(Pos, S->Alignment);
-  S->OutSecOff = Pos - CurOutSec->Addr;
-  Pos += S->getSize();
+  uint64_t Pos = advance(S->getSize(), S->Alignment);
+  S->OutSecOff = Pos - S->getSize() - CurOutSec->Addr;
 
   // Update output section size after adding each section. This is so that
   // SIZEOF works correctly in the case below:
@@ -524,11 +529,6 @@ void LinkerScript::output(InputSection *
             " bytes");
     }
   }
-
-  if (IsTbss)
-    ThreadBssOffset = Pos - Dot;
-  else
-    Dot = Pos;
 }
 
 void LinkerScript::switchTo(OutputSection *Sec) {
@@ -536,9 +536,7 @@ void LinkerScript::switchTo(OutputSectio
     return;
 
   CurOutSec = Sec;
-
-  Dot = alignTo(Dot, CurOutSec->Alignment);
-  CurOutSec->Addr = isTbss(CurOutSec) ? Dot + ThreadBssOffset : Dot;
+  CurOutSec->Addr = advance(0, CurOutSec->Alignment);
 
   // If neither AT nor AT> is specified for an allocatable section, the linker
   // will set the LMA such that the difference between VMA and LMA for the
@@ -643,6 +641,11 @@ void LinkerScript::assignOffsets(OutputS
     Dot = CurMemRegion->Offset;
   switchTo(Sec);
 
+  // We do not support custom layout for compressed debug sectons.
+  // At this point we already know their size and have compressed content.
+  if (CurOutSec->Flags & SHF_COMPRESSED)
+    return;
+
   for (BaseCommand *C : Cmd->Commands)
     process(*C);
 }
@@ -678,8 +681,9 @@ void LinkerScript::adjustSectionsBeforeS
   // consequeces and gives us a section to put the symbol in.
   uint64_t Flags = SHF_ALLOC;
   uint32_t Type = SHT_PROGBITS;
-  for (BaseCommand *Base : Opt.Commands) {
-    auto *Cmd = dyn_cast<OutputSectionCommand>(Base);
+
+  for (int I = 0, E = Opt.Commands.size(); I != E; ++I) {
+    auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I]);
     if (!Cmd)
       continue;
     if (OutputSection *Sec = Cmd->Sec) {
@@ -692,6 +696,7 @@ void LinkerScript::adjustSectionsBeforeS
       continue;
 
     auto *OutSec = make<OutputSection>(Cmd->Name, Type, Flags);
+    OutSec->SectionIndex = I;
     OutputSections->push_back(OutSec);
     Cmd->Sec = OutSec;
   }
@@ -894,6 +899,48 @@ void LinkerScript::synchronize() {
   }
 }
 
+static bool allocateHeaders(std::vector<PhdrEntry> &Phdrs,
+                            ArrayRef<OutputSection *> OutputSections,
+                            uint64_t Min) {
+  auto FirstPTLoad =
+      std::find_if(Phdrs.begin(), Phdrs.end(),
+                   [](const PhdrEntry &E) { return E.p_type == PT_LOAD; });
+  if (FirstPTLoad == Phdrs.end())
+    return false;
+
+  uint64_t HeaderSize = getHeaderSize();
+  if (HeaderSize <= Min || Script->hasPhdrsCommands()) {
+    Min = alignDown(Min - HeaderSize, Config->MaxPageSize);
+    Out::ElfHeader->Addr = Min;
+    Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size;
+    return true;
+  }
+
+  assert(FirstPTLoad->First == Out::ElfHeader);
+  OutputSection *ActualFirst = nullptr;
+  for (OutputSection *Sec : OutputSections) {
+    if (Sec->FirstInPtLoad == Out::ElfHeader) {
+      ActualFirst = Sec;
+      break;
+    }
+  }
+  if (ActualFirst) {
+    for (OutputSection *Sec : OutputSections)
+      if (Sec->FirstInPtLoad == Out::ElfHeader)
+        Sec->FirstInPtLoad = ActualFirst;
+    FirstPTLoad->First = ActualFirst;
+  } else {
+    Phdrs.erase(FirstPTLoad);
+  }
+
+  auto PhdrI = std::find_if(Phdrs.begin(), Phdrs.end(), [](const PhdrEntry &E) {
+    return E.p_type == PT_PHDR;
+  });
+  if (PhdrI != Phdrs.end())
+    Phdrs.erase(PhdrI);
+  return false;
+}
+
 void LinkerScript::assignAddresses(std::vector<PhdrEntry> &Phdrs) {
   // Assign addresses as instructed by linker script SECTIONS sub-commands.
   Dot = 0;
@@ -994,12 +1041,17 @@ static void writeInt(uint8_t *Buf, uint6
     llvm_unreachable("unsupported Size argument");
 }
 
-void LinkerScript::writeDataBytes(StringRef Name, uint8_t *Buf) {
-  int I = getSectionIndex(Name);
-  if (I == INT_MAX)
+void LinkerScript::writeDataBytes(OutputSection *Sec, uint8_t *Buf) {
+  auto I = std::find_if(Opt.Commands.begin(), Opt.Commands.end(),
+                        [=](BaseCommand *Base) {
+                          if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
+                            if (Cmd->Sec == Sec)
+                              return true;
+                          return false;
+                        });
+  if (I == Opt.Commands.end())
     return;
-
-  auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I]);
+  auto *Cmd = cast<OutputSectionCommand>(*I);
   for (BaseCommand *Base : Cmd->Commands)
     if (auto *Data = dyn_cast<BytesDataCommand>(Base))
       writeInt(Buf + Data->Offset, Data->Expression().getValue(), Data->Size);
@@ -1013,18 +1065,6 @@ bool LinkerScript::hasLMA(StringRef Name
   return false;
 }
 
-// Returns the index of the given section name in linker script
-// SECTIONS commands. Sections are laid out as the same order as they
-// were in the script. If a given name did not appear in the script,
-// it returns INT_MAX, so that it will be laid out at end of file.
-int LinkerScript::getSectionIndex(StringRef Name) {
-  for (int I = 0, E = Opt.Commands.size(); I != E; ++I)
-    if (auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I]))
-      if (Cmd->Name == Name)
-        return I;
-  return INT_MAX;
-}
-
 ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) {
   if (S == ".")
     return {CurOutSec, Dot - CurOutSec->Addr};

Modified: vendor/lld/dist/ELF/LinkerScript.h
==============================================================================
--- vendor/lld/dist/ELF/LinkerScript.h	Mon May  8 17:13:41 2017	(r317956)
+++ vendor/lld/dist/ELF/LinkerScript.h	Mon May  8 17:13:44 2017	(r317957)
@@ -228,6 +228,7 @@ protected:
   MemoryRegion *findMemoryRegion(OutputSectionCommand *Cmd);
 
   void switchTo(OutputSection *Sec);
+  uint64_t advance(uint64_t Size, unsigned Align);
   void output(InputSection *Sec);
   void process(BaseCommand &Base);
 
@@ -252,7 +253,7 @@ public:
   bool isDefined(StringRef S);
 
   std::vector<OutputSection *> *OutputSections;
-  void fabricateDefaultCommands(bool AllocateHeader);
+  void fabricateDefaultCommands();
   void addOrphanSections(OutputSectionFactory &Factory);
   void removeEmptyCommands();
   void adjustSectionsBeforeSorting();
@@ -269,9 +270,8 @@ public:
   void processNonSectionCommands();
   void synchronize();
   void assignAddresses(std::vector<PhdrEntry> &Phdrs);
-  int getSectionIndex(StringRef Name);
 
-  void writeDataBytes(StringRef Name, uint8_t *Buf);
+  void writeDataBytes(OutputSection *Sec, uint8_t *Buf);
   void addSymbol(SymbolAssignment *Cmd);
   void processCommands(OutputSectionFactory &Factory);
 

Modified: vendor/lld/dist/ELF/Options.td
==============================================================================
--- vendor/lld/dist/ELF/Options.td	Mon May  8 17:13:41 2017	(r317956)
+++ vendor/lld/dist/ELF/Options.td	Mon May  8 17:13:44 2017	(r317957)
@@ -290,6 +290,7 @@ def alias_L__library_path: J<"library-pa
 def alias_define_common_d: Flag<["-"], "d">, Alias<define_common>;
 def alias_define_common_dc: F<"dc">, Alias<define_common>;
 def alias_define_common_dp: F<"dp">, Alias<define_common>;
+def alias_defsym: S<"defsym">, Alias<defsym>;
 def alias_discard_all_x: Flag<["-"], "x">, Alias<discard_all>;
 def alias_discard_locals_X: Flag<["-"], "X">, Alias<discard_locals>;
 def alias_dynamic_list: J<"dynamic-list=">, Alias<dynamic_list>;

Modified: vendor/lld/dist/ELF/OutputSections.cpp
==============================================================================
--- vendor/lld/dist/ELF/OutputSections.cpp	Mon May  8 17:13:41 2017	(r317956)
+++ vendor/lld/dist/ELF/OutputSections.cpp	Mon May  8 17:13:44 2017	(r317957)
@@ -68,7 +68,8 @@ void OutputSection::writeHeaderTo(typena
 OutputSection::OutputSection(StringRef Name, uint32_t Type, uint64_t Flags)
     : SectionBase(Output, Name, Flags, /*Entsize*/ 0, /*Alignment*/ 1, Type,
                   /*Info*/ 0,
-                  /*Link*/ 0) {}
+                  /*Link*/ 0),
+      SectionIndex(INT_MAX) {}
 
 static bool compareByFilePosition(InputSection *A, InputSection *B) {
   // Synthetic doesn't have link order dependecy, stable_sort will keep it last
@@ -139,12 +140,24 @@ template <class ELFT> void OutputSection
   this->Info = S->OutSec->SectionIndex;
 }
 
+static uint64_t updateOffset(uint64_t Off, InputSection *S) {
+  Off = alignTo(Off, S->Alignment);
+  S->OutSecOff = Off;
+  return Off + S->getSize();
+}
+
 void OutputSection::addSection(InputSection *S) {
   assert(S->Live);
   Sections.push_back(S);
   S->OutSec = this;
   this->updateAlignment(S->Alignment);
 
+  // The actual offsets will be computed by assignAddresses. For now, use
+  // crude approximation so that it is at least easy for other code to know the
+  // section order. It is also used to calculate the output section size early
+  // for compressed debug sections.
+  this->Size = updateOffset(Size, S);
+
   // If this section contains a table of fixed-size entries, sh_entsize
   // holds the element size. Consequently, if this contains two or more
   // input sections, all of them must have the same sh_entsize. However,
@@ -159,11 +172,8 @@ void OutputSection::addSection(InputSect
 // and scan relocations to setup sections' offsets.
 void OutputSection::assignOffsets() {
   uint64_t Off = 0;
-  for (InputSection *S : Sections) {
-    Off = alignTo(Off, S->Alignment);
-    S->OutSecOff = Off;
-    Off += S->getSize();
-  }
+  for (InputSection *S : Sections)
+    Off = updateOffset(Off, S);
   this->Size = Off;
 }
 
@@ -305,7 +315,7 @@ template <class ELFT> void OutputSection
 
   // Linker scripts may have BYTE()-family commands with which you
   // can write arbitrary bytes to the output. Process them if any.
-  Script->writeDataBytes(Name, Buf);
+  Script->writeDataBytes(this, Buf);
 }
 
 static uint64_t getOutFlags(InputSectionBase *S) {

Modified: vendor/lld/dist/ELF/Relocations.cpp
==============================================================================
--- vendor/lld/dist/ELF/Relocations.cpp	Mon May  8 17:13:41 2017	(r317956)
+++ vendor/lld/dist/ELF/Relocations.cpp	Mon May  8 17:13:44 2017	(r317957)
@@ -233,7 +233,7 @@ handleTlsRelocation(uint32_t Type, Symbo
   }
 
   // Local-Dynamic relocs can be relaxed to Local-Exec.
-  if (Target->isTlsLocalDynamicRel(Type) && !Config->Shared) {
+  if (isRelExprOneOf<R_ABS, R_TLSLD, R_TLSLD_PC>(Expr) && !Config->Shared) {
     C.Relocations.push_back(
         {R_RELAX_TLS_LD_TO_LE, Type, Offset, Addend, &Body});
     return 1;
@@ -282,7 +282,8 @@ handleTlsRelocation(uint32_t Type, Symbo
 
   // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally
   // defined.
-  if (Target->isTlsInitialExecRel(Type) && !Config->Shared && !IsPreemptible) {
+  if (isRelExprOneOf<R_GOT, R_GOT_FROM_END, R_GOT_PC, R_GOT_PAGE_PC>(Expr) &&
+      !Config->Shared && !IsPreemptible) {
     C.Relocations.push_back(
         {R_RELAX_TLS_IE_TO_LE, Type, Offset, Addend, &Body});
     return 1;
@@ -694,17 +695,6 @@ static void reportUndefined(SymbolBody &
     warn(Msg);
   } else {
     error(Msg);
-
-    if (Config->ArchiveWithoutSymbolsSeen) {
-      message("At least one archive listed no symbols in its index."
-              " This can happen when creating archives with a version"
-              " of ar that does not understand the object files in"
-              " the archive. For example, if you are using LLVM"
-              " bitcode objects (such as created by -flto), you may"
-              " need to use llvm-ar or GNU ar with a plugin.");
-      // Reset to false so that we print the message only once.
-      Config->ArchiveWithoutSymbolsSeen = false;
-    }
   }
 }
 

Modified: vendor/lld/dist/ELF/SymbolTable.cpp
==============================================================================
--- vendor/lld/dist/ELF/SymbolTable.cpp	Mon May  8 17:13:41 2017	(r317956)
+++ vendor/lld/dist/ELF/SymbolTable.cpp	Mon May  8 17:13:44 2017	(r317957)
@@ -540,13 +540,10 @@ void SymbolTable<ELFT>::addLazyObject(St
     return;
 
   // See comment for addLazyArchive above.
-  if (S->isWeak()) {
+  if (S->isWeak())
     replaceBody<LazyObject>(S, Name, Obj, S->body()->Type);
-  } else {
-    MemoryBufferRef MBRef = Obj.getBuffer();
-    if (!MBRef.getBuffer().empty())
-      addFile(createObjectFile(MBRef));
-  }
+  else if (InputFile *F = Obj.fetch())
+    addFile(F);
 }
 
 // Process undefined (-u) flags by loading lazy symbols named by those flags.

Modified: vendor/lld/dist/ELF/Symbols.cpp
==============================================================================
--- vendor/lld/dist/ELF/Symbols.cpp	Mon May  8 17:13:41 2017	(r317956)
+++ vendor/lld/dist/ELF/Symbols.cpp	Mon May  8 17:13:44 2017	(r317957)
@@ -327,12 +327,7 @@ InputFile *LazyArchive::fetch() {
   return createObjectFile(MBInfo.first, file()->getName(), MBInfo.second);
 }
 
-InputFile *LazyObject::fetch() {
-  MemoryBufferRef MBRef = file()->getBuffer();
-  if (MBRef.getBuffer().empty())
-    return nullptr;
-  return createObjectFile(MBRef);
-}
+InputFile *LazyObject::fetch() { return file()->fetch(); }
 
 uint8_t Symbol::computeBinding() const {
   if (Config->Relocatable)

Modified: vendor/lld/dist/ELF/SyntheticSections.cpp
==============================================================================
--- vendor/lld/dist/ELF/SyntheticSections.cpp	Mon May  8 17:13:41 2017	(r317956)
+++ vendor/lld/dist/ELF/SyntheticSections.cpp	Mon May  8 17:13:44 2017	(r317957)
@@ -1038,6 +1038,15 @@ template <class ELFT> void DynamicSectio
   if (!Config->SoName.empty())
     add({DT_SONAME, In<ELFT>::DynStrTab->addString(Config->SoName)});
 
+  if (!Config->Shared && !Config->Relocatable)
+    add({DT_DEBUG, (uint64_t)0});
+}
+
+// Add remaining entries to complete .dynamic contents.
+template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
+  if (this->Size)
+    return; // Already finalized.
+
   // Set DT_FLAGS and DT_FLAGS_1.
   uint32_t DtFlags = 0;
   uint32_t DtFlags1 = 0;
@@ -1055,21 +1064,14 @@ template <class ELFT> void DynamicSectio
     DtFlags |= DF_ORIGIN;
     DtFlags1 |= DF_1_ORIGIN;
   }
+  if (Config->HasStaticTlsModel)
+    DtFlags |= DF_STATIC_TLS;
 
   if (DtFlags)
     add({DT_FLAGS, DtFlags});
   if (DtFlags1)
     add({DT_FLAGS_1, DtFlags1});
 
-  if (!Config->Shared && !Config->Relocatable)
-    add({DT_DEBUG, (uint64_t)0});
-}
-
-// Add remaining entries to complete .dynamic contents.
-template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
-  if (this->Size)
-    return; // Already finalized.
-
   this->Link = In<ELFT>::DynStrTab->OutSec->SectionIndex;
   if (In<ELFT>::RelaDyn->OutSec->Size > 0) {
     bool IsRela = Config->IsRela;

Modified: vendor/lld/dist/ELF/Target.cpp
==============================================================================
--- vendor/lld/dist/ELF/Target.cpp	Mon May  8 17:13:41 2017	(r317956)
+++ vendor/lld/dist/ELF/Target.cpp	Mon May  8 17:13:44 2017	(r317957)
@@ -124,8 +124,6 @@ public:
   int64_t getImplicitAddend(const uint8_t *Buf, uint32_t Type) const override;
   void writeGotPltHeader(uint8_t *Buf) const override;
   uint32_t getDynRel(uint32_t Type) const override;
-  bool isTlsLocalDynamicRel(uint32_t Type) const override;
-  bool isTlsInitialExecRel(uint32_t Type) const override;
   void writeGotPlt(uint8_t *Buf, const SymbolBody &S) const override;
   void writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const override;
   void writePltHeader(uint8_t *Buf) const override;
@@ -147,8 +145,6 @@ public:
   RelExpr getRelExpr(uint32_t Type, const SymbolBody &S,
                      const uint8_t *Loc) const override;
   bool isPicRel(uint32_t Type) const override;
-  bool isTlsLocalDynamicRel(uint32_t Type) const override;
-  bool isTlsInitialExecRel(uint32_t Type) const override;
   void writeGotPltHeader(uint8_t *Buf) const override;
   void writeGotPlt(uint8_t *Buf, const SymbolBody &S) const override;
   void writePltHeader(uint8_t *Buf) const override;
@@ -193,7 +189,6 @@ public:
   RelExpr getRelExpr(uint32_t Type, const SymbolBody &S,
                      const uint8_t *Loc) const override;
   bool isPicRel(uint32_t Type) const override;
-  bool isTlsInitialExecRel(uint32_t Type) const override;
   void writeGotPlt(uint8_t *Buf, const SymbolBody &S) const override;
   void writePltHeader(uint8_t *Buf) const override;
   void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
@@ -303,10 +298,6 @@ bool TargetInfo::needsThunk(RelExpr Expr
   return false;
 }
 
-bool TargetInfo::isTlsInitialExecRel(uint32_t Type) const { return false; }
-
-bool TargetInfo::isTlsLocalDynamicRel(uint32_t Type) const { return false; }
-
 void TargetInfo::writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const {
   writeGotPlt(Buf, S);
 }
@@ -360,6 +351,15 @@ X86TargetInfo::X86TargetInfo() {
 
 RelExpr X86TargetInfo::getRelExpr(uint32_t Type, const SymbolBody &S,
                                   const uint8_t *Loc) const {
+  // There are 4 different TLS variable models with varying degrees of
+  // flexibility and performance. LocalExec and InitialExec models are fast but
+  // less-flexible models. They cannot be used for dlopen(). If they are in use,
+  // we set DF_STATIC_TLS in the ELF header so that the runtime can reject such
+  // DSOs.
+  if (Type == R_386_TLS_LE || Type == R_386_TLS_LE_32 || Type == R_386_TLS_IE ||
+      Type == R_386_TLS_GOTIE)
+    Config->HasStaticTlsModel = true;
+
   switch (Type) {
   case R_386_8:
   case R_386_16:
@@ -451,14 +451,6 @@ uint32_t X86TargetInfo::getDynRel(uint32
   return Type;
 }
 
-bool X86TargetInfo::isTlsLocalDynamicRel(uint32_t Type) const {
-  return Type == R_386_TLS_LDO_32 || Type == R_386_TLS_LDM;
-}
-
-bool X86TargetInfo::isTlsInitialExecRel(uint32_t Type) const {
-  return Type == R_386_TLS_IE || Type == R_386_TLS_GOTIE;
-}
-
 void X86TargetInfo::writePltHeader(uint8_t *Buf) const {
   if (Config->Pic) {
     const uint8_t V[] = {
@@ -772,17 +764,6 @@ bool X86_64TargetInfo<ELFT>::isPicRel(ui
 }
 
 template <class ELFT>
-bool X86_64TargetInfo<ELFT>::isTlsInitialExecRel(uint32_t Type) const {
-  return Type == R_X86_64_GOTTPOFF;
-}
-
-template <class ELFT>
-bool X86_64TargetInfo<ELFT>::isTlsLocalDynamicRel(uint32_t Type) const {
-  return Type == R_X86_64_DTPOFF32 || Type == R_X86_64_DTPOFF64 ||
-         Type == R_X86_64_TLSLD;
-}
-
-template <class ELFT>
 void X86_64TargetInfo<ELFT>::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type,
                                             uint64_t Val) const {
   // Convert
@@ -1383,11 +1364,6 @@ bool AArch64TargetInfo::usesOnlyLowPageB
   }
 }
 
-bool AArch64TargetInfo::isTlsInitialExecRel(uint32_t Type) const {
-  return Type == R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 ||
-         Type == R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC;
-}
-
 bool AArch64TargetInfo::isPicRel(uint32_t Type) const {
   return Type == R_AARCH64_ABS32 || Type == R_AARCH64_ABS64;
 }

Modified: vendor/lld/dist/ELF/Target.h
==============================================================================
--- vendor/lld/dist/ELF/Target.h	Mon May  8 17:13:41 2017	(r317956)
+++ vendor/lld/dist/ELF/Target.h	Mon May  8 17:13:44 2017	(r317957)
@@ -23,8 +23,6 @@ class SymbolBody;
 
 class TargetInfo {
 public:
-  virtual bool isTlsInitialExecRel(uint32_t Type) const;
-  virtual bool isTlsLocalDynamicRel(uint32_t Type) const;
   virtual bool isPicRel(uint32_t Type) const { return true; }
   virtual uint32_t getDynRel(uint32_t Type) const { return Type; }
   virtual void writeGotPltHeader(uint8_t *Buf) const {}

Modified: vendor/lld/dist/ELF/Writer.cpp
==============================================================================
--- vendor/lld/dist/ELF/Writer.cpp	Mon May  8 17:13:41 2017	(r317956)
+++ vendor/lld/dist/ELF/Writer.cpp	Mon May  8 17:13:44 2017	(r317957)
@@ -62,7 +62,6 @@ private:
   void assignFileOffsets();
   void assignFileOffsetsBinary();
   void setPhdrs();
-  void fixHeaders();
   void fixSectionAlignments();
   void fixPredefinedSymbols();
   void openFile();
@@ -86,7 +85,6 @@ private:
 
   uint64_t FileSize;
   uint64_t SectionHeaderOff;
-  bool AllocateHeader = true;
 };
 } // anonymous namespace
 
@@ -252,7 +250,7 @@ template <class ELFT> void Writer<ELFT>:
   } else {
     if (!Script->Opt.HasSections) {
       fixSectionAlignments();
-      Script->fabricateDefaultCommands(AllocateHeader);
+      Script->fabricateDefaultCommands();
     }
     Script->synchronize();
     Script->assignAddresses(Phdrs);
@@ -747,15 +745,12 @@ static bool compareSectionsNonScript(con
 // Output section ordering is determined by this function.
 template <class ELFT>
 static bool compareSections(const OutputSection *A, const OutputSection *B) {
-  // For now, put sections mentioned in a linker script first.
-  int AIndex = Script->getSectionIndex(A->Name);
-  int BIndex = Script->getSectionIndex(B->Name);
-  bool AInScript = AIndex != INT_MAX;
-  bool BInScript = BIndex != INT_MAX;
-  if (AInScript != BInScript)
-    return AInScript;
-  // If both are in the script, use that order.
-  if (AInScript)
+  // For now, put sections mentioned in a linker script
+  // first. Sections not on linker script will have a SectionIndex of
+  // INT_MAX.
+  int AIndex = A->SectionIndex;
+  int BIndex = B->SectionIndex;
+  if (AIndex != BIndex)
     return AIndex < BIndex;
 
   return compareSectionsNonScript<ELFT>(A, B);
@@ -1021,9 +1016,8 @@ template <class ELFT> void Writer<ELFT>:
   auto I = OutputSections.begin();
   auto E = OutputSections.end();
   auto NonScriptI =
-      std::find_if(OutputSections.begin(), E, [](OutputSection *S) {
-        return Script->getSectionIndex(S->Name) == INT_MAX;
-      });
+      std::find_if(OutputSections.begin(), E,
+                   [](OutputSection *S) { return S->SectionIndex == INT_MAX; });
   while (NonScriptI != E) {
     auto BestPos = std::max_element(
         I, NonScriptI, [&](OutputSection *&A, OutputSection *&B) {
@@ -1176,7 +1170,7 @@ template <class ELFT> void Writer<ELFT>:
   if (!Config->Relocatable && !Config->OFormatBinary) {
     Phdrs = Script->hasPhdrsCommands() ? Script->createPhdrs() : createPhdrs();
     addPtArmExid(Phdrs);
-    fixHeaders();
+    Out::ProgramHeaders->Size = sizeof(Elf_Phdr) * Phdrs.size();
   }
 
   // Dynamic section must be the last one in this list and dynamic
@@ -1321,6 +1315,11 @@ template <class ELFT> std::vector<PhdrEn
   // Add the first PT_LOAD segment for regular output sections.
   uint64_t Flags = computeFlags(PF_R);
   PhdrEntry *Load = AddHdr(PT_LOAD, Flags);
+
+  // Add the headers. We will remove them if they don't fit.
+  Load->add(Out::ElfHeader);
+  Load->add(Out::ProgramHeaders);
+
   for (OutputSection *Sec : OutputSections) {
     if (!(Sec->Flags & SHF_ALLOC))
       break;
@@ -1447,64 +1446,6 @@ template <class ELFT> void Writer<ELFT>:
   }
 }
 
-bool elf::allocateHeaders(std::vector<PhdrEntry> &Phdrs,
-                          ArrayRef<OutputSection *> OutputSections,
-                          uint64_t Min) {
-  auto FirstPTLoad =
-      std::find_if(Phdrs.begin(), Phdrs.end(),
-                   [](const PhdrEntry &E) { return E.p_type == PT_LOAD; });

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201705081713.v48HDiRV043006>