svn commit: r319788 - in vendor/lld/dist: COFF ELF include/lld/Core include/lld/ReaderWriter lib/Core lib/Driver lib/ReaderWriter lib/ReaderWriter/MachO lib/ReaderWriter/YAML test test/COFF test/EL...

Dimitry Andric dim at FreeBSD.org
Sat Jun 10 13:44:53 UTC 2017


Author: dim
Date: Sat Jun 10 13:44:49 2017
New Revision: 319788
URL: https://svnweb.freebsd.org/changeset/base/319788

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

Added:
  vendor/lld/dist/test/ELF/Inputs/relocatable-comdat-multiple.s   (contents, props changed)
  vendor/lld/dist/test/ELF/arm-thumb-thunk-symbols.s   (contents, props changed)
  vendor/lld/dist/test/ELF/dso_handle.s   (contents, props changed)
  vendor/lld/dist/test/ELF/i386-reloc-large-addend.s   (contents, props changed)
  vendor/lld/dist/test/ELF/i386-reloc-range.s   (contents, props changed)
  vendor/lld/dist/test/ELF/icf-comdat.s   (contents, props changed)
  vendor/lld/dist/test/ELF/linkerscript/emit-relocs-multiple.s   (contents, props changed)
  vendor/lld/dist/test/ELF/linkerscript/noload.s   (contents, props changed)
  vendor/lld/dist/test/ELF/lto/Inputs/defsym-bar.ll
  vendor/lld/dist/test/ELF/lto/Inputs/wrap-bar.ll
  vendor/lld/dist/test/ELF/lto/defsym.ll
  vendor/lld/dist/test/ELF/lto/wrap-1.ll
  vendor/lld/dist/test/ELF/lto/wrap-2.ll
  vendor/lld/dist/test/ELF/mips-npic-call-pic-script.s   (contents, props changed)
  vendor/lld/dist/test/ELF/relocatable-comdat-multiple.s   (contents, props changed)
  vendor/lld/dist/test/ELF/relocatable-compressed-input.s   (contents, props changed)
  vendor/lld/dist/test/ELF/relocatable-empty-archive.s   (contents, props changed)
Modified:
  vendor/lld/dist/COFF/CMakeLists.txt
  vendor/lld/dist/COFF/Chunks.cpp
  vendor/lld/dist/COFF/Driver.cpp
  vendor/lld/dist/COFF/InputFiles.cpp
  vendor/lld/dist/ELF/CMakeLists.txt
  vendor/lld/dist/ELF/Config.h
  vendor/lld/dist/ELF/Driver.cpp
  vendor/lld/dist/ELF/EhFrame.cpp
  vendor/lld/dist/ELF/GdbIndex.h
  vendor/lld/dist/ELF/ICF.cpp
  vendor/lld/dist/ELF/InputFiles.cpp
  vendor/lld/dist/ELF/InputSection.cpp
  vendor/lld/dist/ELF/InputSection.h
  vendor/lld/dist/ELF/LTO.cpp
  vendor/lld/dist/ELF/LinkerScript.cpp
  vendor/lld/dist/ELF/LinkerScript.h
  vendor/lld/dist/ELF/Mips.cpp
  vendor/lld/dist/ELF/OutputSections.cpp
  vendor/lld/dist/ELF/OutputSections.h
  vendor/lld/dist/ELF/Relocations.cpp
  vendor/lld/dist/ELF/Relocations.h
  vendor/lld/dist/ELF/ScriptParser.cpp
  vendor/lld/dist/ELF/SymbolTable.cpp
  vendor/lld/dist/ELF/SymbolTable.h
  vendor/lld/dist/ELF/Symbols.cpp
  vendor/lld/dist/ELF/SyntheticSections.cpp
  vendor/lld/dist/ELF/SyntheticSections.h
  vendor/lld/dist/ELF/Target.cpp
  vendor/lld/dist/ELF/Thunks.cpp
  vendor/lld/dist/ELF/Writer.cpp
  vendor/lld/dist/include/lld/Core/Reader.h
  vendor/lld/dist/include/lld/ReaderWriter/MachOLinkingContext.h
  vendor/lld/dist/lib/Core/CMakeLists.txt
  vendor/lld/dist/lib/Core/Reader.cpp
  vendor/lld/dist/lib/Core/SymbolTable.cpp
  vendor/lld/dist/lib/Driver/DarwinLdDriver.cpp
  vendor/lld/dist/lib/ReaderWriter/FileArchive.cpp
  vendor/lld/dist/lib/ReaderWriter/MachO/ExecutableAtoms.h
  vendor/lld/dist/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
  vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFile.h
  vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
  vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h
  vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
  vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
  vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
  vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
  vendor/lld/dist/lib/ReaderWriter/MachO/WriterMachO.cpp
  vendor/lld/dist/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
  vendor/lld/dist/test/CMakeLists.txt
  vendor/lld/dist/test/COFF/pdb-none.test
  vendor/lld/dist/test/COFF/pdb.test
  vendor/lld/dist/test/ELF/aarch64-undefined-weak.s
  vendor/lld/dist/test/ELF/amdgpu-globals.s
  vendor/lld/dist/test/ELF/amdgpu-kernels.s
  vendor/lld/dist/test/ELF/arm-icf-exidx.s
  vendor/lld/dist/test/ELF/arm-thumb-no-undefined-thunk.s
  vendor/lld/dist/test/ELF/arm-thumb-undefined-weak.s
  vendor/lld/dist/test/ELF/arm-undefined-weak.s
  vendor/lld/dist/test/ELF/ehdr_start.s
  vendor/lld/dist/test/ELF/emit-relocs-merge.s
  vendor/lld/dist/test/ELF/gdb-index-empty.s
  vendor/lld/dist/test/ELF/linkerscript/early-assign-symbol.s
  vendor/lld/dist/test/ELF/linkerscript/expr-invalid-sec.s
  vendor/lld/dist/unittests/DriverTests/DarwinLdDriverTest.cpp
  vendor/lld/dist/unittests/MachOTests/MachONormalizedFileBinaryReaderTests.cpp
  vendor/lld/dist/unittests/MachOTests/MachONormalizedFileBinaryWriterTests.cpp
  vendor/lld/dist/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp
  vendor/lld/dist/unittests/MachOTests/MachONormalizedFileYAMLTests.cpp

Modified: vendor/lld/dist/COFF/CMakeLists.txt
==============================================================================
--- vendor/lld/dist/COFF/CMakeLists.txt	Sat Jun 10 13:44:46 2017	(r319787)
+++ vendor/lld/dist/COFF/CMakeLists.txt	Sat Jun 10 13:44:49 2017	(r319788)
@@ -25,6 +25,7 @@ add_lld_library(lldCOFF
 
   LINK_COMPONENTS
   ${LLVM_TARGETS_TO_BUILD}
+  BinaryFormat
   BitReader
   Core
   DebugInfoCodeView

Modified: vendor/lld/dist/COFF/Chunks.cpp
==============================================================================
--- vendor/lld/dist/COFF/Chunks.cpp	Sat Jun 10 13:44:46 2017	(r319787)
+++ vendor/lld/dist/COFF/Chunks.cpp	Sat Jun 10 13:44:49 2017	(r319788)
@@ -12,8 +12,8 @@
 #include "InputFiles.h"
 #include "Symbols.h"
 #include "llvm/ADT/Twine.h"
+#include "llvm/BinaryFormat/COFF.h"
 #include "llvm/Object/COFF.h"
-#include "llvm/Support/COFF.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/raw_ostream.h"

Modified: vendor/lld/dist/COFF/Driver.cpp
==============================================================================
--- vendor/lld/dist/COFF/Driver.cpp	Sat Jun 10 13:44:46 2017	(r319787)
+++ vendor/lld/dist/COFF/Driver.cpp	Sat Jun 10 13:44:49 2017	(r319788)
@@ -18,6 +18,7 @@
 #include "lld/Driver/Driver.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/BinaryFormat/Magic.h"
 #include "llvm/Object/ArchiveWriter.h"
 #include "llvm/Object/COFFImportFile.h"
 #include "llvm/Object/COFFModuleDefinition.h"
@@ -40,8 +41,6 @@ using namespace llvm;
 using namespace llvm::object;
 using namespace llvm::COFF;
 using llvm::sys::Process;
-using llvm::sys::fs::file_magic;
-using llvm::sys::fs::identify_magic;
 
 namespace lld {
 namespace coff {
@@ -457,17 +456,11 @@ static void createImportLibrary() {
 static void parseModuleDefs(StringRef Path) {
   std::unique_ptr<MemoryBuffer> MB = check(
     MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path);
-  MemoryBufferRef MBRef = MB->getMemBufferRef();
+  COFFModuleDefinition M =
+      check(parseCOFFModuleDefinition(MB->getMemBufferRef(), Config->Machine));
 
-  Expected<COFFModuleDefinition> Def =
-      parseCOFFModuleDefinition(MBRef, Config->Machine);
-  if (!Def)
-    fatal(errorToErrorCode(Def.takeError()).message());
-
-  COFFModuleDefinition &M = *Def;
   if (Config->OutputFile.empty())
     Config->OutputFile = Saver.save(M.OutputFile);
-
   if (M.ImageBase)
     Config->ImageBase = M.ImageBase;
   if (M.StackReserve)

Modified: vendor/lld/dist/COFF/InputFiles.cpp
==============================================================================
--- vendor/lld/dist/COFF/InputFiles.cpp	Sat Jun 10 13:44:46 2017	(r319787)
+++ vendor/lld/dist/COFF/InputFiles.cpp	Sat Jun 10 13:44:49 2017	(r319788)
@@ -19,9 +19,9 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/ADT/Twine.h"
+#include "llvm/BinaryFormat/COFF.h"
 #include "llvm/Object/Binary.h"
 #include "llvm/Object/COFF.h"
-#include "llvm/Support/COFF.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"

Modified: vendor/lld/dist/ELF/CMakeLists.txt
==============================================================================
--- vendor/lld/dist/ELF/CMakeLists.txt	Sat Jun 10 13:44:46 2017	(r319787)
+++ vendor/lld/dist/ELF/CMakeLists.txt	Sat Jun 10 13:44:49 2017	(r319788)
@@ -36,6 +36,7 @@ add_lld_library(lldELF
   LINK_COMPONENTS
   ${LLVM_TARGETS_TO_BUILD}
   Analysis
+  BinaryFormat
   BitReader
   BitWriter
   Codegen

Modified: vendor/lld/dist/ELF/Config.h
==============================================================================
--- vendor/lld/dist/ELF/Config.h	Sat Jun 10 13:44:46 2017	(r319787)
+++ vendor/lld/dist/ELF/Config.h	Sat Jun 10 13:44:49 2017	(r319788)
@@ -13,9 +13,9 @@
 #include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSet.h"
+#include "llvm/BinaryFormat/ELF.h"
 #include "llvm/Support/CachePruning.h"
 #include "llvm/Support/CodeGen.h"
-#include "llvm/Support/ELF.h"
 #include "llvm/Support/Endian.h"
 
 #include <vector>
@@ -67,6 +67,12 @@ struct VersionDefinition {
   size_t NameOff = 0; // Offset in the string table
 };
 
+// Structure for mapping renamed symbols
+struct RenamedSymbol {
+  Symbol *Target;
+  uint8_t OrigBinding;
+};
+
 // This struct contains the global configuration for the linker.
 // Most fields are direct mapping from the command line options
 // and such fields have the same name as the corresponding options.
@@ -98,6 +104,7 @@ struct Configuration {
   std::vector<SymbolVersion> VersionScriptGlobals;
   std::vector<SymbolVersion> VersionScriptLocals;
   std::vector<uint8_t> BuildIdVector;
+  llvm::MapVector<Symbol *, RenamedSymbol> RenamedSymbols;
   bool AllowMultipleDefinition;
   bool AsNeeded = false;
   bool Bsymbolic;

Modified: vendor/lld/dist/ELF/Driver.cpp
==============================================================================
--- vendor/lld/dist/ELF/Driver.cpp	Sat Jun 10 13:44:46 2017	(r319787)
+++ vendor/lld/dist/ELF/Driver.cpp	Sat Jun 10 13:44:49 2017	(r319788)
@@ -185,7 +185,7 @@ void LinkerDriver::addFile(StringRef Path, bool WithLO
     // 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()) {
+    if (!File->isEmpty() && !File->hasSymbolTable()) {
       for (const auto &P : getArchiveMembers(MBRef))
         Files.push_back(make<LazyObjectFile>(P.first, Path, P.second));
       return;
@@ -970,6 +970,14 @@ template <class ELFT> void LinkerDriver::link(opt::Inp
   Symtab.scanShlibUndefined();
   Symtab.scanVersionScript();
 
+  // Create wrapped symbols for -wrap option.
+  for (auto *Arg : Args.filtered(OPT_wrap))
+    Symtab.addSymbolWrap(Arg->getValue());
+
+  // Create alias symbols for -defsym option.
+  for (std::pair<StringRef, StringRef> &Def : getDefsym(Args))
+    Symtab.addSymbolAlias(Def.first, Def.second);
+
   Symtab.addCombinedLTOObject();
   if (ErrorCount)
     return;
@@ -979,12 +987,8 @@ template <class ELFT> void LinkerDriver::link(opt::Inp
   for (StringRef Sym : Script->Opt.ReferencedSymbols)
     Symtab.addUndefined(Sym);
 
-  for (auto *Arg : Args.filtered(OPT_wrap))
-    Symtab.wrap(Arg->getValue());
-
-  // Handle --defsym=sym=alias option.
-  for (std::pair<StringRef, StringRef> &Def : getDefsym(Args))
-    Symtab.alias(Def.first, Def.second);
+  // Apply symbol renames for -wrap and -defsym
+  Symtab.applySymbolRenames();
 
   // Now that we have a complete list of input files.
   // Beyond this point, no new files are added.

Modified: vendor/lld/dist/ELF/EhFrame.cpp
==============================================================================
--- vendor/lld/dist/ELF/EhFrame.cpp	Sat Jun 10 13:44:46 2017	(r319787)
+++ vendor/lld/dist/ELF/EhFrame.cpp	Sat Jun 10 13:44:49 2017	(r319788)
@@ -22,8 +22,8 @@
 #include "Relocations.h"
 #include "Strings.h"
 
+#include "llvm/BinaryFormat/Dwarf.h"
 #include "llvm/Object/ELF.h"
-#include "llvm/Support/Dwarf.h"
 #include "llvm/Support/Endian.h"
 
 using namespace llvm;

Modified: vendor/lld/dist/ELF/GdbIndex.h
==============================================================================
--- vendor/lld/dist/ELF/GdbIndex.h	Sat Jun 10 13:44:46 2017	(r319787)
+++ vendor/lld/dist/ELF/GdbIndex.h	Sat Jun 10 13:44:49 2017	(r319788)
@@ -24,7 +24,30 @@ struct AddressEntry {
   InputSection *Section;
   uint64_t LowAddress;
   uint64_t HighAddress;
-  size_t CuIndex;
+  uint32_t CuIndex;
+};
+
+// Struct represents single entry of compilation units list area of gdb index.
+// It consist of CU offset in .debug_info section and it's size.
+struct CompilationUnitEntry {
+  uint64_t CuOffset;
+  uint64_t CuLength;
+};
+
+// Represents data about symbol and type names which are used
+// to build symbol table and constant pool area of gdb index.
+struct NameTypeEntry {
+  StringRef Name;
+  uint8_t Type;
+};
+
+// We fill one GdbIndexDataChunk for each object where scan of
+// debug information performed. That information futher used
+// for filling gdb index section areas.
+struct GdbIndexChunk {
+  std::vector<AddressEntry> AddressArea;
+  std::vector<CompilationUnitEntry> CompilationUnits;
+  std::vector<NameTypeEntry> NamesAndTypes;
 };
 
 // Element of GdbHashTab hash table.

Modified: vendor/lld/dist/ELF/ICF.cpp
==============================================================================
--- vendor/lld/dist/ELF/ICF.cpp	Sat Jun 10 13:44:46 2017	(r319787)
+++ vendor/lld/dist/ELF/ICF.cpp	Sat Jun 10 13:44:49 2017	(r319788)
@@ -78,8 +78,8 @@
 #include "SymbolTable.h"
 #include "Threads.h"
 #include "llvm/ADT/Hashing.h"
+#include "llvm/BinaryFormat/ELF.h"
 #include "llvm/Object/ELF.h"
-#include "llvm/Support/ELF.h"
 #include <algorithm>
 #include <atomic>
 

Modified: vendor/lld/dist/ELF/InputFiles.cpp
==============================================================================
--- vendor/lld/dist/ELF/InputFiles.cpp	Sat Jun 10 13:44:46 2017	(r319787)
+++ vendor/lld/dist/ELF/InputFiles.cpp	Sat Jun 10 13:44:49 2017	(r319788)
@@ -306,21 +306,23 @@ void elf::ObjectFile<ELFT>::initializeSections(
 
     switch (Sec.sh_type) {
     case SHT_GROUP: {
-      // We discard comdat sections usually. When -r we should not do that. We
-      // still do deduplication in this case to simplify implementation, because
-      // otherwise merging group sections together would requre additional
-      // regeneration of its contents.
-      bool New = ComdatGroups
-                     .insert(CachedHashStringRef(
-                         getShtGroupSignature(ObjSections, Sec)))
-                     .second;
-      if (New && Config->Relocatable)
-        this->Sections[I] = createInputSection(Sec, SectionStringTable);
-      else
-        this->Sections[I] = &InputSection::Discarded;
-      if (New)
+      // De-duplicate section groups by their signatures.
+      StringRef Signature = getShtGroupSignature(ObjSections, Sec);
+      bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second;
+      this->Sections[I] = &InputSection::Discarded;
+
+      // If it is a new section group, we want to keep group members.
+      // Group leader sections, which contain indices of group members, are
+      // discarded because they are useless beyond this point. The only
+      // exception is the -r option because in order to produce re-linkable
+      // object files, we want to pass through basically everything.
+      if (IsNew) {
+        if (Config->Relocatable)
+          this->Sections[I] = createInputSection(Sec, SectionStringTable);
         continue;
+      }
 
+      // Otherwise, discard group members.
       for (uint32_t SecIndex : getShtGroupEntries(Sec)) {
         if (SecIndex >= Size)
           fatal(toString(this) +

Modified: vendor/lld/dist/ELF/InputSection.cpp
==============================================================================
--- vendor/lld/dist/ELF/InputSection.cpp	Sat Jun 10 13:44:46 2017	(r319787)
+++ vendor/lld/dist/ELF/InputSection.cpp	Sat Jun 10 13:44:49 2017	(r319788)
@@ -20,6 +20,7 @@
 #include "Target.h"
 #include "Thunks.h"
 #include "llvm/Object/Decompressor.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/Compression.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/Path.h"
@@ -72,6 +73,16 @@ InputSectionBase::InputSectionBase(InputFile *File, ui
   this->Alignment = V;
 }
 
+// Drop SHF_GROUP bit unless we are producing a re-linkable object file.
+// SHF_GROUP is a marker that a section belongs to some comdat group.
+// That flag doesn't make sense in an executable.
+static uint64_t getFlags(uint64_t Flags) {
+  Flags &= ~(uint64_t)SHF_INFO_LINK;
+  if (!Config->Relocatable)
+    Flags &= ~(uint64_t)SHF_GROUP;
+  return Flags;
+}
+
 // GNU assembler 2.24 and LLVM 4.0.0's MC (the newest release as of
 // March 2017) fail to infer section types for sections starting with
 // ".init_array." or ".fini_array.". They set SHT_PROGBITS instead of
@@ -94,7 +105,7 @@ template <class ELFT>
 InputSectionBase::InputSectionBase(elf::ObjectFile<ELFT> *File,
                                    const typename ELFT::Shdr *Hdr,
                                    StringRef Name, Kind SectionKind)
-    : InputSectionBase(File, Hdr->sh_flags & ~SHF_INFO_LINK,
+    : InputSectionBase(File, getFlags(Hdr->sh_flags),
                        getType(Hdr->sh_type, Name), Hdr->sh_entsize,
                        Hdr->sh_link, Hdr->sh_info, Hdr->sh_addralign,
                        getSectionContents(File, Hdr), Name, SectionKind) {
@@ -308,23 +319,21 @@ OutputSection *InputSection::getParent() const {
   return cast_or_null<OutputSection>(Parent);
 }
 
-void InputSection::copyShtGroup(uint8_t *Buf) {
-  assert(this->Type == SHT_GROUP);
+// Copy SHT_GROUP section contents. Used only for the -r option.
+template <class ELFT> void InputSection::copyShtGroup(uint8_t *Buf) {
+  // ELFT::Word is the 32-bit integral type in the target endianness.
+  typedef typename ELFT::Word u32;
+  ArrayRef<u32> From = getDataAs<u32>();
+  auto *To = reinterpret_cast<u32 *>(Buf);
 
-  ArrayRef<uint32_t> From = getDataAs<uint32_t>();
-  uint32_t *To = reinterpret_cast<uint32_t *>(Buf);
-
-  // First entry is a flag word, we leave it unchanged.
+  // The first entry is not a section number but a flag.
   *To++ = From[0];
 
-  // Here we adjust indices of sections that belong to group as it
-  // might change during linking.
+  // Adjust section numbers because section numbers in an input object
+  // files are different in the output.
   ArrayRef<InputSectionBase *> Sections = this->File->getSections();
-  for (uint32_t Val : From.slice(1)) {
-    uint32_t Index = read32(&Val, Config->Endianness);
-    write32(To++, Sections[Index]->getOutputSection()->SectionIndex,
-            Config->Endianness);
-  }
+  for (uint32_t Idx : From.slice(1))
+    *To++ = Sections[Idx]->getOutputSection()->SectionIndex;
 }
 
 InputSectionBase *InputSection::getRelocatedSection() {
@@ -682,7 +691,7 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uin
       // Patch a nop (0x60000000) to a ld.
       if (BufLoc + 8 <= BufEnd && read32be(BufLoc + 4) == 0x60000000)
         write32be(BufLoc + 4, 0xe8410028); // ld %r2, 40(%r1)
-    // fallthrough
+      LLVM_FALLTHROUGH;
     default:
       Target->relocateOne(BufLoc, Type, TargetVA);
       break;
@@ -712,10 +721,9 @@ template <class ELFT> void InputSection::writeTo(uint8
     return;
   }
 
-  // If -r is given, linker should keep SHT_GROUP sections. We should fixup
-  // them, see copyShtGroup().
+  // If -r is given, we may have a SHT_GROUP section.
   if (this->Type == SHT_GROUP) {
-    copyShtGroup(Buf + OutSecOff);
+    copyShtGroup<ELFT>(Buf + OutSecOff);
     return;
   }
 

Modified: vendor/lld/dist/ELF/InputSection.h
==============================================================================
--- vendor/lld/dist/ELF/InputSection.h	Sat Jun 10 13:44:46 2017	(r319787)
+++ vendor/lld/dist/ELF/InputSection.h	Sat Jun 10 13:44:49 2017	(r319788)
@@ -325,7 +325,7 @@ class InputSection : public InputSectionBase { (privat
   template <class ELFT, class RelTy>
   void copyRelocations(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
 
-  void copyShtGroup(uint8_t *Buf);
+  template <class ELFT> void copyShtGroup(uint8_t *Buf);
 };
 
 // The list of all input sections.

Modified: vendor/lld/dist/ELF/LTO.cpp
==============================================================================
--- vendor/lld/dist/ELF/LTO.cpp	Sat Jun 10 13:44:46 2017	(r319787)
+++ vendor/lld/dist/ELF/LTO.cpp	Sat Jun 10 13:44:49 2017	(r319788)
@@ -17,13 +17,13 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Twine.h"
+#include "llvm/BinaryFormat/ELF.h"
 #include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/LTO/Caching.h"
 #include "llvm/LTO/Config.h"
 #include "llvm/LTO/LTO.h"
 #include "llvm/Object/SymbolicFile.h"
 #include "llvm/Support/CodeGen.h"
-#include "llvm/Support/ELF.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -136,6 +136,7 @@ void BitcodeCompiler::add(BitcodeFile &F) {
         Sym->IsUsedInRegularObj || (R.Prevailing && Sym->includeInDynsym());
     if (R.Prevailing)
       undefine(Sym);
+    R.LinkerRedefined = Config->RenamedSymbols.count(Sym);
   }
   checkError(LTOObj->add(std::move(F.Obj), Resols));
 }

Modified: vendor/lld/dist/ELF/LinkerScript.cpp
==============================================================================
--- vendor/lld/dist/ELF/LinkerScript.cpp	Sat Jun 10 13:44:46 2017	(r319787)
+++ vendor/lld/dist/ELF/LinkerScript.cpp	Sat Jun 10 13:44:49 2017	(r319788)
@@ -25,9 +25,9 @@
 #include "Writer.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/ELF.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Compression.h"
-#include "llvm/Support/ELF.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FileSystem.h"
@@ -54,7 +54,7 @@ uint64_t ExprValue::getValue() const {
   if (Sec) {
     if (OutputSection *OS = Sec->getOutputSection())
       return alignTo(Sec->getOffset(Val) + OS->Addr, Alignment);
-    error("unable to evaluate expression: input section " + Sec->Name +
+    error(Loc + ": unable to evaluate expression: input section " + Sec->Name +
           " has no output section assigned");
   }
   return alignTo(Val, Alignment);
@@ -431,6 +431,8 @@ void LinkerScript::processCommands(OutputSectionFactor
       if (OutputSection *Sec = Cmd->Sec) {
         assert(Sec->SectionIndex == INT_MAX);
         Sec->SectionIndex = I;
+        if (Cmd->Noload)
+          Sec->Type = SHT_NOBITS;
         SecToCommand[Sec] = Cmd;
       }
     }
@@ -442,7 +444,7 @@ void LinkerScript::fabricateDefaultCommands() {
   std::vector<BaseCommand *> Commands;
 
   // Define start address
-  uint64_t StartAddr = Config->ImageBase + elf::getHeaderSize();
+  uint64_t StartAddr = -1;
 
   // The Sections with -T<section> have been sorted in order of ascending
   // address. We must lower StartAddr if the lowest -T<section address> as
@@ -450,8 +452,12 @@ void LinkerScript::fabricateDefaultCommands() {
   for (auto& KV : Config->SectionStartMap)
     StartAddr = std::min(StartAddr, KV.second);
 
-  Commands.push_back(
-      make<SymbolAssignment>(".", [=] { return StartAddr; }, ""));
+  Commands.push_back(make<SymbolAssignment>(
+      ".",
+      [=] {
+        return std::min(StartAddr, Config->ImageBase + elf::getHeaderSize());
+      },
+      ""));
 
   // For each OutputSection that needs a VA fabricate an OutputSectionCommand
   // with an InputSectionDescription describing the InputSections
@@ -870,51 +876,6 @@ void LinkerScript::processNonSectionCommands() {
   }
 }
 
-// Do a last effort at synchronizing the linker script "AST" and the section
-// list. This is needed to account for last minute changes, like adding a
-// .ARM.exidx terminator and sorting SHF_LINK_ORDER sections.
-//
-// FIXME: We should instead create the "AST" earlier and the above changes would
-// be done directly in the "AST".
-//
-// This can only handle new sections being added and sections being reordered.
-void LinkerScript::synchronize() {
-  for (BaseCommand *Base : Opt.Commands) {
-    auto *Cmd = dyn_cast<OutputSectionCommand>(Base);
-    if (!Cmd)
-      continue;
-    ArrayRef<InputSection *> Sections = Cmd->Sec->Sections;
-    std::vector<InputSection **> ScriptSections;
-    DenseSet<InputSection *> ScriptSectionsSet;
-    for (BaseCommand *Base : Cmd->Commands) {
-      auto *ISD = dyn_cast<InputSectionDescription>(Base);
-      if (!ISD)
-        continue;
-      for (InputSection *&IS : ISD->Sections) {
-        if (IS->Live) {
-          ScriptSections.push_back(&IS);
-          ScriptSectionsSet.insert(IS);
-        }
-      }
-    }
-    std::vector<InputSection *> Missing;
-    for (InputSection *IS : Sections)
-      if (!ScriptSectionsSet.count(IS))
-        Missing.push_back(IS);
-    if (!Missing.empty()) {
-      auto ISD = make<InputSectionDescription>("");
-      ISD->Sections = Missing;
-      Cmd->Commands.push_back(ISD);
-      for (InputSection *&IS : ISD->Sections)
-        if (IS->Live)
-          ScriptSections.push_back(&IS);
-    }
-    assert(ScriptSections.size() == Sections.size());
-    for (int I = 0, N = Sections.size(); I < N; ++I)
-      *ScriptSections[I] = Sections[I];
-  }
-}
-
 static bool
 allocateHeaders(std::vector<PhdrEntry> &Phdrs,
                 ArrayRef<OutputSectionCommand *> OutputSectionCommands,
@@ -1071,6 +1032,81 @@ static void writeInt(uint8_t *Buf, uint64_t Data, uint
     llvm_unreachable("unsupported Size argument");
 }
 
+static bool compareByFilePosition(InputSection *A, InputSection *B) {
+  // Synthetic doesn't have link order dependecy, stable_sort will keep it last
+  if (A->kind() == InputSectionBase::Synthetic ||
+      B->kind() == InputSectionBase::Synthetic)
+    return false;
+  InputSection *LA = A->getLinkOrderDep();
+  InputSection *LB = B->getLinkOrderDep();
+  OutputSection *AOut = LA->getParent();
+  OutputSection *BOut = LB->getParent();
+  if (AOut != BOut)
+    return AOut->SectionIndex < BOut->SectionIndex;
+  return LA->OutSecOff < LB->OutSecOff;
+}
+
+template <class ELFT>
+static void finalizeShtGroup(OutputSection *OS,
+                             ArrayRef<InputSection *> Sections) {
+  // sh_link field for SHT_GROUP sections should contain the section index of
+  // the symbol table.
+  OS->Link = InX::SymTab->getParent()->SectionIndex;
+
+  // sh_info then contain index of an entry in symbol table section which
+  // provides signature of the section group.
+  elf::ObjectFile<ELFT> *Obj = Sections[0]->getFile<ELFT>();
+  assert(Config->Relocatable && Sections.size() == 1);
+  ArrayRef<SymbolBody *> Symbols = Obj->getSymbols();
+  OS->Info = InX::SymTab->getSymbolIndex(Symbols[Sections[0]->Info - 1]);
+}
+
+template <class ELFT> void OutputSectionCommand::finalize() {
+  // Link order may be distributed across several InputSectionDescriptions
+  // but sort must consider them all at once.
+  std::vector<InputSection **> ScriptSections;
+  std::vector<InputSection *> Sections;
+  for (BaseCommand *Base : Commands)
+    if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
+      for (InputSection *&IS : ISD->Sections) {
+        ScriptSections.push_back(&IS);
+        Sections.push_back(IS);
+      }
+
+  if ((Sec->Flags & SHF_LINK_ORDER)) {
+    std::sort(Sections.begin(), Sections.end(), compareByFilePosition);
+    for (int I = 0, N = Sections.size(); I < N; ++I)
+      *ScriptSections[I] = Sections[I];
+
+    // We must preserve the link order dependency of sections with the
+    // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We
+    // need to translate the InputSection sh_link to the OutputSection sh_link,
+    // all InputSections in the OutputSection have the same dependency.
+    if (auto *D = Sections.front()->getLinkOrderDep())
+      Sec->Link = D->getParent()->SectionIndex;
+  }
+
+  uint32_t Type = Sec->Type;
+  if (Type == SHT_GROUP) {
+    finalizeShtGroup<ELFT>(Sec, Sections);
+    return;
+  }
+
+  if (!Config->CopyRelocs || (Type != SHT_RELA && Type != SHT_REL))
+    return;
+
+  InputSection *First = Sections[0];
+  if (isa<SyntheticSection>(First))
+    return;
+
+  Sec->Link = InX::SymTab->getParent()->SectionIndex;
+  // sh_info for SHT_REL[A] sections should contain the section header index of
+  // the section to which the relocation applies.
+  InputSectionBase *S = First->getRelocatedSection();
+  Sec->Info = S->getOutputSection()->SectionIndex;
+  Sec->Flags |= SHF_INFO_LINK;
+}
+
 // Compress section contents if this section contains debug info.
 template <class ELFT> void OutputSectionCommand::maybeCompress() {
   typedef typename ELFT::Chdr Elf_Chdr;
@@ -1099,6 +1135,9 @@ template <class ELFT> void OutputSectionCommand::maybe
 }
 
 template <class ELFT> void OutputSectionCommand::writeTo(uint8_t *Buf) {
+  if (Sec->Type == SHT_NOBITS)
+    return;
+
   Sec->Loc = Buf;
 
   // We may have already rendered compressed content when using
@@ -1110,9 +1149,6 @@ template <class ELFT> void OutputSectionCommand::write
     return;
   }
 
-  if (Sec->Type == SHT_NOBITS)
-    return;
-
   // Write leading padding.
   std::vector<InputSection *> Sections;
   for (BaseCommand *Cmd : Commands)
@@ -1156,12 +1192,12 @@ bool LinkerScript::hasLMA(OutputSection *Sec) {
 
 ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) {
   if (S == ".")
-    return {CurOutSec, Dot - CurOutSec->Addr};
+    return {CurOutSec, Dot - CurOutSec->Addr, Loc};
   if (SymbolBody *B = findSymbol(S)) {
     if (auto *D = dyn_cast<DefinedRegular>(B))
-      return {D->Section, D->Value};
+      return {D->Section, D->Value, Loc};
     if (auto *C = dyn_cast<DefinedCommon>(B))
-      return {InX::Common, C->Offset};
+      return {InX::Common, C->Offset, Loc};
   }
   error(Loc + ": symbol not found: " + S);
   return 0;
@@ -1201,3 +1237,8 @@ template void OutputSectionCommand::maybeCompress<ELF3
 template void OutputSectionCommand::maybeCompress<ELF32BE>();
 template void OutputSectionCommand::maybeCompress<ELF64LE>();
 template void OutputSectionCommand::maybeCompress<ELF64BE>();
+
+template void OutputSectionCommand::finalize<ELF32LE>();
+template void OutputSectionCommand::finalize<ELF32BE>();
+template void OutputSectionCommand::finalize<ELF64LE>();
+template void OutputSectionCommand::finalize<ELF64BE>();

Modified: vendor/lld/dist/ELF/LinkerScript.h
==============================================================================
--- vendor/lld/dist/ELF/LinkerScript.h	Sat Jun 10 13:44:46 2017	(r319787)
+++ vendor/lld/dist/ELF/LinkerScript.h	Sat Jun 10 13:44:49 2017	(r319788)
@@ -42,15 +42,14 @@ struct ExprValue {
   uint64_t Val;
   bool ForceAbsolute;
   uint64_t Alignment = 1;
+  std::string Loc;
 
   ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val,
-            uint64_t Alignment)
-      : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute), Alignment(Alignment) {
-  }
-  ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val)
-      : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute) {}
-  ExprValue(SectionBase *Sec, uint64_t Val) : ExprValue(Sec, false, Val) {}
-  ExprValue(uint64_t Val) : ExprValue(nullptr, Val) {}
+            const Twine &Loc)
+      : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute), Loc(Loc.str()) {}
+  ExprValue(SectionBase *Sec, uint64_t Val, const Twine &Loc)
+      : ExprValue(Sec, false, Val, Loc) {}
+  ExprValue(uint64_t Val) : ExprValue(nullptr, Val, "") {}
   bool isAbsolute() const { return ForceAbsolute || Sec == nullptr; }
   uint64_t getValue() const;
   uint64_t getSecAddr() const;
@@ -135,7 +134,9 @@ struct OutputSectionCommand : BaseCommand {
   ConstraintKind Constraint = ConstraintKind::NoConstraint;
   std::string Location;
   std::string MemoryRegionName;
+  bool Noload = false;
 
+  template <class ELFT> void finalize();
   template <class ELFT> void writeTo(uint8_t *Buf);
   template <class ELFT> void maybeCompress();
   uint32_t getFiller();
@@ -281,7 +282,6 @@ class LinkerScript final { (public)
   void assignOffsets(OutputSectionCommand *Cmd);
   void placeOrphanSections();
   void processNonSectionCommands();
-  void synchronize();
   void assignAddresses(std::vector<PhdrEntry> &Phdrs,
                        ArrayRef<OutputSectionCommand *> OutputSectionCommands);
 

Modified: vendor/lld/dist/ELF/Mips.cpp
==============================================================================
--- vendor/lld/dist/ELF/Mips.cpp	Sat Jun 10 13:44:46 2017	(r319787)
+++ vendor/lld/dist/ELF/Mips.cpp	Sat Jun 10 13:44:49 2017	(r319788)
@@ -16,8 +16,8 @@
 #include "SymbolTable.h"
 #include "Writer.h"
 
+#include "llvm/BinaryFormat/ELF.h"
 #include "llvm/Object/ELF.h"
-#include "llvm/Support/ELF.h"
 #include "llvm/Support/MipsABIFlags.h"
 
 using namespace llvm;

Modified: vendor/lld/dist/ELF/OutputSections.cpp
==============================================================================
--- vendor/lld/dist/ELF/OutputSections.cpp	Sat Jun 10 13:44:46 2017	(r319787)
+++ vendor/lld/dist/ELF/OutputSections.cpp	Sat Jun 10 13:44:49 2017	(r319788)
@@ -16,7 +16,7 @@
 #include "SyntheticSections.h"
 #include "Target.h"
 #include "Threads.h"
-#include "llvm/Support/Dwarf.h"
+#include "llvm/BinaryFormat/Dwarf.h"
 #include "llvm/Support/MD5.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/SHA1.h"
@@ -70,67 +70,6 @@ OutputSection::OutputSection(StringRef Name, uint32_t 
                   /*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
-  if (A->kind() == InputSectionBase::Synthetic ||
-      B->kind() == InputSectionBase::Synthetic)
-    return false;
-  InputSection *LA = A->getLinkOrderDep();
-  InputSection *LB = B->getLinkOrderDep();
-  OutputSection *AOut = LA->getParent();
-  OutputSection *BOut = LB->getParent();
-  if (AOut != BOut)
-    return AOut->SectionIndex < BOut->SectionIndex;
-  return LA->OutSecOff < LB->OutSecOff;
-}
-
-template <class ELFT> static void finalizeShtGroup(OutputSection *Sec) {
-  // sh_link field for SHT_GROUP sections should contain the section index of
-  // the symbol table.
-  Sec->Link = InX::SymTab->getParent()->SectionIndex;
-
-  // sh_info then contain index of an entry in symbol table section which
-  // provides signature of the section group.
-  elf::ObjectFile<ELFT> *Obj = Sec->Sections[0]->getFile<ELFT>();
-  assert(Config->Relocatable && Sec->Sections.size() == 1);
-  ArrayRef<SymbolBody *> Symbols = Obj->getSymbols();
-  Sec->Info = InX::SymTab->getSymbolIndex(Symbols[Sec->Sections[0]->Info - 1]);
-}
-
-template <class ELFT> void OutputSection::finalize() {
-  if ((this->Flags & SHF_LINK_ORDER) && !this->Sections.empty()) {
-    std::sort(Sections.begin(), Sections.end(), compareByFilePosition);
-    assignOffsets();
-
-    // We must preserve the link order dependency of sections with the
-    // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We
-    // need to translate the InputSection sh_link to the OutputSection sh_link,
-    // all InputSections in the OutputSection have the same dependency.
-    if (auto *D = this->Sections.front()->getLinkOrderDep())
-      this->Link = D->getParent()->SectionIndex;
-  }
-
-  uint32_t Type = this->Type;
-  if (Type == SHT_GROUP) {
-    finalizeShtGroup<ELFT>(this);
-    return;
-  }
-
-  if (!Config->CopyRelocs || (Type != SHT_RELA && Type != SHT_REL))
-    return;
-
-  InputSection *First = Sections[0];
-  if (isa<SyntheticSection>(First))
-    return;
-
-  this->Link = InX::SymTab->getParent()->SectionIndex;
-  // sh_info for SHT_REL[A] sections should contain the section header index of
-  // the section to which the relocation applies.
-  InputSectionBase *S = First->getRelocatedSection();
-  Info = S->getOutputSection()->SectionIndex;
-  Flags |= SHF_INFO_LINK;
-}
-
 static uint64_t updateOffset(uint64_t Off, InputSection *S) {
   Off = alignTo(Off, S->Alignment);
   S->OutSecOff = Off;
@@ -162,9 +101,12 @@ void OutputSection::addSection(InputSection *S) {
 // This function is called after we sort input sections
 // and scan relocations to setup sections' offsets.
 void OutputSection::assignOffsets() {
+  OutputSectionCommand *Cmd = Script->getCmd(this);
   uint64_t Off = 0;
-  for (InputSection *S : Sections)
-    Off = updateOffset(Off, S);
+  for (BaseCommand *Base : Cmd->Commands)
+    if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
+      for (InputSection *S : ISD->Sections)
+        Off = updateOffset(Off, S);
   this->Size = Off;
 }
 
@@ -333,6 +275,31 @@ void elf::reportDiscarded(InputSectionBase *IS) {
 
 void OutputSectionFactory::addInputSec(InputSectionBase *IS,
                                        StringRef OutsecName) {
+  // Sections with the SHT_GROUP attribute reach here only when the - r option
+  // is given. Such sections define "section groups", and InputFiles.cpp has
+  // dedup'ed section groups by their signatures. For the -r, we want to pass
+  // through all SHT_GROUP sections without merging them because merging them
+  // creates broken section contents.
+  if (IS->Type == SHT_GROUP) {
+    OutputSection *Out = nullptr;
+    addInputSec(IS, OutsecName, Out);
+    return;
+  }
+
+  // Imagine .zed : { *(.foo) *(.bar) } script. Both foo and bar may have
+  // relocation sections .rela.foo and .rela.bar for example. Most tools do
+  // not allow multiple REL[A] sections for output section. Hence we
+  // should combine these relocation sections into single output.
+  // We skip synthetic sections because it can be .rela.dyn/.rela.plt or any
+  // other REL[A] sections created by linker itself.
+  if (!isa<SyntheticSection>(IS) &&
+      (IS->Type == SHT_REL || IS->Type == SHT_RELA)) {
+    auto *Sec = cast<InputSection>(IS);
+    OutputSection *Out = Sec->getRelocatedSection()->getOutputSection();
+    addInputSec(IS, OutsecName, Out->RelocationSection);
+    return;
+  }
+
   SectionKey Key = createKey(IS, OutsecName);
   OutputSection *&Sec = Map[Key];
   return addInputSec(IS, OutsecName, Sec);
@@ -346,10 +313,6 @@ void OutputSectionFactory::addInputSec(InputSectionBas
     return;
   }
 
-  uint64_t Flags = IS->Flags;
-  if (!Config->Relocatable)
-    Flags &= ~(uint64_t)SHF_GROUP;
-
   if (Sec) {
     if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->Flags))
       error("incompatible section flags for " + Sec->Name +
@@ -366,9 +329,9 @@ void OutputSectionFactory::addInputSec(InputSectionBas
               "\n>>> output section " + Sec->Name + ": " +
               getELFSectionTypeName(Config->EMachine, Sec->Type));
     }
-    Sec->Flags |= Flags;
+    Sec->Flags |= IS->Flags;
   } else {
-    Sec = make<OutputSection>(OutsecName, IS->Type, Flags);
+    Sec = make<OutputSection>(OutsecName, IS->Type, IS->Flags);
     OutputSections.push_back(Sec);
   }
 
@@ -405,8 +368,3 @@ template void OutputSection::writeHeaderTo<ELF32LE>(EL
 template void OutputSection::writeHeaderTo<ELF32BE>(ELF32BE::Shdr *Shdr);
 template void OutputSection::writeHeaderTo<ELF64LE>(ELF64LE::Shdr *Shdr);
 template void OutputSection::writeHeaderTo<ELF64BE>(ELF64BE::Shdr *Shdr);
-
-template void OutputSection::finalize<ELF32LE>();
-template void OutputSection::finalize<ELF32BE>();
-template void OutputSection::finalize<ELF64LE>();
-template void OutputSection::finalize<ELF64BE>();

Modified: vendor/lld/dist/ELF/OutputSections.h
==============================================================================
--- vendor/lld/dist/ELF/OutputSections.h	Sat Jun 10 13:44:46 2017	(r319787)
+++ vendor/lld/dist/ELF/OutputSections.h	Sat Jun 10 13:44:49 2017	(r319788)
@@ -67,6 +67,11 @@ class OutputSection final : public SectionBase { (publ
   // formula: Off = Off_first + VA - VA_first.
   OutputSection *FirstInPtLoad = nullptr;
 
+  // Pointer to a relocation section for this section. Usually nullptr because
+  // we consume relocations, but if --emit-relocs is specified (which is rare),
+  // it may have a non-null value.
+  OutputSection *RelocationSection = nullptr;
+
   // The following fields correspond to Elf_Shdr members.
   uint64_t Size = 0;
   uint64_t Offset = 0;
@@ -78,7 +83,6 @@ class OutputSection final : public SectionBase { (publ
   void sort(std::function<int(InputSectionBase *S)> Order);
   void sortInitFini();
   void sortCtorsDtors();
-  template <class ELFT> void finalize();
   void assignOffsets();
   std::vector<InputSection *> Sections;
 

Modified: vendor/lld/dist/ELF/Relocations.cpp
==============================================================================
--- vendor/lld/dist/ELF/Relocations.cpp	Sat Jun 10 13:44:46 2017	(r319787)
+++ vendor/lld/dist/ELF/Relocations.cpp	Sat Jun 10 13:44:49 2017	(r319788)
@@ -43,6 +43,7 @@
 
 #include "Relocations.h"
 #include "Config.h"
+#include "LinkerScript.h"
 #include "Memory.h"
 #include "OutputSections.h"
 #include "Strings.h"
@@ -967,48 +968,51 @@ template <class ELFT> void elf::scanRelocations(InputS
 // in the Sections vector, and recalculate the InputSection output section
 // offsets.
 // This may invalidate any output section offsets stored outside of InputSection
-void ThunkCreator::mergeThunks(OutputSection *OS,
-                               std::vector<ThunkSection *> &Thunks) {
-  // Order Thunks in ascending OutSecOff
-  auto ThunkCmp = [](const ThunkSection *A, const ThunkSection *B) {
-    return A->OutSecOff < B->OutSecOff;
-  };
-  std::stable_sort(Thunks.begin(), Thunks.end(), ThunkCmp);
+void ThunkCreator::mergeThunks() {
+  for (auto &KV : ThunkSections) {
+    std::vector<InputSection *> *ISR = KV.first;
+    std::vector<ThunkSection *> &Thunks = KV.second;
 
-  // Merge sorted vectors of Thunks and InputSections by OutSecOff
-  std::vector<InputSection *> Tmp;
-  Tmp.reserve(OS->Sections.size() + Thunks.size());
-  auto MergeCmp = [](const InputSection *A, const InputSection *B) {
-    // std::merge requires a strict weak ordering.
-    if (A->OutSecOff < B->OutSecOff)
-      return true;
-    if (A->OutSecOff == B->OutSecOff)
-      // Check if Thunk is immediately before any specific Target InputSection
-      // for example Mips LA25 Thunks.
-      if (auto *TA = dyn_cast<ThunkSection>(A))
-        if (TA && TA->getTargetInputSection() == B)
-          return true;
-    return false;
-  };
-  std::merge(OS->Sections.begin(), OS->Sections.end(), Thunks.begin(),
-             Thunks.end(), std::back_inserter(Tmp), MergeCmp);
-  OS->Sections = std::move(Tmp);
-  OS->assignOffsets();
+    // Order Thunks in ascending OutSecOff
+    auto ThunkCmp = [](const ThunkSection *A, const ThunkSection *B) {
+      return A->OutSecOff < B->OutSecOff;
+    };
+    std::stable_sort(Thunks.begin(), Thunks.end(), ThunkCmp);
+
+    // Merge sorted vectors of Thunks and InputSections by OutSecOff
+    std::vector<InputSection *> Tmp;
+    Tmp.reserve(ISR->size() + Thunks.size());
+    auto MergeCmp = [](const InputSection *A, const InputSection *B) {
+      // std::merge requires a strict weak ordering.
+      if (A->OutSecOff < B->OutSecOff)
+        return true;
+      if (A->OutSecOff == B->OutSecOff)
+        // Check if Thunk is immediately before any specific Target InputSection
+        // for example Mips LA25 Thunks.
+        if (auto *TA = dyn_cast<ThunkSection>(A))
+          if (TA && TA->getTargetInputSection() == B)
+            return true;
+      return false;
+    };
+    std::merge(ISR->begin(), ISR->end(), Thunks.begin(), Thunks.end(),
+               std::back_inserter(Tmp), MergeCmp);
+    *ISR = std::move(Tmp);
+  }
 }
 
-ThunkSection *ThunkCreator::getOSThunkSec(ThunkSection *&TS,
-                                          OutputSection *OS) {
-  if (TS == nullptr) {
+ThunkSection *ThunkCreator::getOSThunkSec(OutputSection *OS,
+                                          std::vector<InputSection *> *ISR) {
+  if (CurTS == nullptr) {
     uint32_t Off = 0;
     for (auto *IS : OS->Sections) {
       Off = IS->OutSecOff + IS->getSize();
       if ((IS->Flags & SHF_EXECINSTR) == 0)
         break;
     }
-    TS = make<ThunkSection>(OS, Off);
-    ThunkSections[OS].push_back(TS);
+    CurTS = make<ThunkSection>(OS, Off);
+    ThunkSections[ISR].push_back(CurTS);
   }
-  return TS;
+  return CurTS;
 }
 
 ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS, OutputSection *OS) {
@@ -1017,7 +1021,21 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection
     return TS;
   auto *TOS = IS->getParent();
   TS = make<ThunkSection>(TOS, IS->OutSecOff);
-  ThunkSections[TOS].push_back(TS);
+
+  // Find InputSectionRange within TOS that IS is in
+  OutputSectionCommand *C = Script->getCmd(TOS);
+  std::vector<InputSection *> *Range = nullptr;
+  for (BaseCommand *BC : C->Commands)
+    if (auto *ISD = dyn_cast<InputSectionDescription> (BC)) {
+      InputSection *first = ISD->Sections.front();
+      InputSection *last = ISD->Sections.back();
+      if (IS->OutSecOff >= first->OutSecOff &&
+          IS->OutSecOff <= last->OutSecOff) {
+        Range = &ISD->Sections;
+        break;
+      }
+    }
+  ThunkSections[Range].push_back(TS);
   ThunkedSections[IS] = TS;
   return TS;
 }
@@ -1030,6 +1048,27 @@ std::pair<Thunk *, bool> ThunkCreator::getThunk(Symbol
   return std::make_pair(res.first->second, res.second);
 }
 
+// Call Fn on every executable InputSection accessed via the linker script
+// InputSectionDescription::Sections.
+void ThunkCreator::forEachExecInputSection(
+    ArrayRef<OutputSectionCommand *> OutputSections,
+    std::function<void(OutputSection *, std::vector<InputSection *> *,
+                       InputSection *)>
+        Fn) {
+  for (OutputSectionCommand *Cmd : OutputSections) {
+    OutputSection *OS = Cmd->Sec;
+    if (!(OS->Flags & SHF_ALLOC) || !(OS->Flags & SHF_EXECINSTR))
+      continue;
+    if (OutputSectionCommand *C = Script->getCmd(OS))
+      for (BaseCommand *BC : C->Commands)
+        if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) {
+          CurTS = nullptr;
+          for (InputSection* IS : ISD->Sections)
+            Fn(OS, &ISD->Sections, IS);
+        }
+  }
+}
+
 // Process all relocations from the InputSections that have been assigned
 // to OutputSections and redirect through Thunks if needed.
 //
@@ -1040,42 +1079,41 @@ std::pair<Thunk *, bool> ThunkCreator::getThunk(Symbol
 //

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


More information about the svn-src-all mailing list