Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 14 Jan 2017 15:39:25 +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: r312181 - in vendor/lld/dist: . COFF ELF test/COFF test/COFF/Inputs test/ELF test/ELF/Inputs test/ELF/invalid test/ELF/linkerscript test/ELF/lto
Message-ID:  <201701141539.v0EFdPdV027274@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dim
Date: Sat Jan 14 15:39:25 2017
New Revision: 312181
URL: https://svnweb.freebsd.org/changeset/base/312181

Log:
  Vendor import of lld release_40 branch r292009:
  https://llvm.org/svn/llvm-project/lld/branches/release_40@292009

Added:
  vendor/lld/dist/test/COFF/Inputs/pdb1.yaml
  vendor/lld/dist/test/COFF/Inputs/pdb2.yaml
  vendor/lld/dist/test/ELF/Inputs/relocation-copy-relro.s   (contents, props changed)
  vendor/lld/dist/test/ELF/Inputs/unknown-reloc.s   (contents, props changed)
  vendor/lld/dist/test/ELF/incompatible-section-types2.s   (contents, props changed)
  vendor/lld/dist/test/ELF/merge-section-types.s   (contents, props changed)
  vendor/lld/dist/test/ELF/relocation-copy-relro.s   (contents, props changed)
  vendor/lld/dist/test/ELF/relocation-none-i686.test
  vendor/lld/dist/test/ELF/unknown-reloc.s   (contents, props changed)
  vendor/lld/dist/test/ELF/version-script-anonymous-local.s   (contents, props changed)
Deleted:
  vendor/lld/dist/test/COFF/dumppdb.test
Modified:
  vendor/lld/dist/CMakeLists.txt
  vendor/lld/dist/COFF/PDB.cpp
  vendor/lld/dist/ELF/Driver.cpp
  vendor/lld/dist/ELF/Error.cpp
  vendor/lld/dist/ELF/Error.h
  vendor/lld/dist/ELF/InputFiles.cpp
  vendor/lld/dist/ELF/InputSection.cpp
  vendor/lld/dist/ELF/InputSection.h
  vendor/lld/dist/ELF/LinkerScript.cpp
  vendor/lld/dist/ELF/OutputSections.cpp
  vendor/lld/dist/ELF/OutputSections.h
  vendor/lld/dist/ELF/Relocations.cpp
  vendor/lld/dist/ELF/SymbolTable.cpp
  vendor/lld/dist/ELF/Symbols.cpp
  vendor/lld/dist/ELF/Symbols.h
  vendor/lld/dist/ELF/SyntheticSections.cpp
  vendor/lld/dist/ELF/Target.cpp
  vendor/lld/dist/ELF/Writer.cpp
  vendor/lld/dist/test/COFF/pdb.test
  vendor/lld/dist/test/ELF/Inputs/copy-rel-pie.s
  vendor/lld/dist/test/ELF/aarch64-condb-reloc.s
  vendor/lld/dist/test/ELF/aarch64-gnu-ifunc-plt.s
  vendor/lld/dist/test/ELF/aarch64-tstbr14-reloc.s
  vendor/lld/dist/test/ELF/amdgpu-relocs.s
  vendor/lld/dist/test/ELF/arm-abs32-dyn.s
  vendor/lld/dist/test/ELF/arm-exidx-shared.s
  vendor/lld/dist/test/ELF/arm-fpic-got.s
  vendor/lld/dist/test/ELF/arm-gnu-ifunc-plt.s
  vendor/lld/dist/test/ELF/arm-pie-relative.s
  vendor/lld/dist/test/ELF/arm-plt-reloc.s
  vendor/lld/dist/test/ELF/arm-thumb-interwork-shared.s
  vendor/lld/dist/test/ELF/arm-thumb-plt-reloc.s
  vendor/lld/dist/test/ELF/arm-tls-norelax-gd-ie.s
  vendor/lld/dist/test/ELF/arm-tls-norelax-gd-le.s
  vendor/lld/dist/test/ELF/arm-tls-norelax-ie-le.s
  vendor/lld/dist/test/ELF/arm-tls-norelax-ld-le.s
  vendor/lld/dist/test/ELF/basic-mips.s
  vendor/lld/dist/test/ELF/basic.s
  vendor/lld/dist/test/ELF/basic64be.s
  vendor/lld/dist/test/ELF/combrelocs.s
  vendor/lld/dist/test/ELF/copy-rel-pie.s
  vendor/lld/dist/test/ELF/dynamic-reloc-index.s
  vendor/lld/dist/test/ELF/dynamic-reloc.s
  vendor/lld/dist/test/ELF/format-binary.test
  vendor/lld/dist/test/ELF/gnu-ifunc-plt-i386.s
  vendor/lld/dist/test/ELF/gnu-ifunc-plt.s
  vendor/lld/dist/test/ELF/gnu-ifunc-shared.s
  vendor/lld/dist/test/ELF/got-aarch64.s
  vendor/lld/dist/test/ELF/got-plt-header.s
  vendor/lld/dist/test/ELF/gotpc-relax-nopic.s
  vendor/lld/dist/test/ELF/i386-merge.s
  vendor/lld/dist/test/ELF/incompatible-section-types.s
  vendor/lld/dist/test/ELF/invalid/invalid-relocation-x64.s
  vendor/lld/dist/test/ELF/linkerscript/orphan.s
  vendor/lld/dist/test/ELF/linkerscript/repsection-symbol.s
  vendor/lld/dist/test/ELF/linkerscript/sort-non-script.s
  vendor/lld/dist/test/ELF/lto/undefined-puts.ll
  vendor/lld/dist/test/ELF/lto/visibility.ll
  vendor/lld/dist/test/ELF/mips-26.s
  vendor/lld/dist/test/ELF/mips-32.s
  vendor/lld/dist/test/ELF/mips-64-disp.s
  vendor/lld/dist/test/ELF/mips-64-got.s
  vendor/lld/dist/test/ELF/mips-64.s
  vendor/lld/dist/test/ELF/mips-dynamic.s
  vendor/lld/dist/test/ELF/mips-got-and-copy.s
  vendor/lld/dist/test/ELF/mips-got-extsym.s
  vendor/lld/dist/test/ELF/mips-got-hilo.s
  vendor/lld/dist/test/ELF/mips-got-redundant.s
  vendor/lld/dist/test/ELF/mips-got-relocs.s
  vendor/lld/dist/test/ELF/mips-got-weak.s
  vendor/lld/dist/test/ELF/mips-got16.s
  vendor/lld/dist/test/ELF/mips-gp-ext.s
  vendor/lld/dist/test/ELF/mips-gp-lowest.s
  vendor/lld/dist/test/ELF/mips-hilo-gp-disp.s
  vendor/lld/dist/test/ELF/mips-hilo.s
  vendor/lld/dist/test/ELF/mips-options.s
  vendor/lld/dist/test/ELF/mips-pc-relocs.s
  vendor/lld/dist/test/ELF/mips-plt-r6.s
  vendor/lld/dist/test/ELF/mips-tls-64.s
  vendor/lld/dist/test/ELF/mips-tls-static-64.s
  vendor/lld/dist/test/ELF/mips-tls-static.s
  vendor/lld/dist/test/ELF/mips-tls.s
  vendor/lld/dist/test/ELF/mips-xgot-order.s
  vendor/lld/dist/test/ELF/plt-aarch64.s
  vendor/lld/dist/test/ELF/plt-i686.s
  vendor/lld/dist/test/ELF/plt.s
  vendor/lld/dist/test/ELF/ppc64-relocs.s
  vendor/lld/dist/test/ELF/ppc64-shared-rel-toc.s
  vendor/lld/dist/test/ELF/ppc64-toc-restore.s
  vendor/lld/dist/test/ELF/rel-offset.s
  vendor/lld/dist/test/ELF/relative-dynamic-reloc-pie.s
  vendor/lld/dist/test/ELF/relative-dynamic-reloc-ppc64.s
  vendor/lld/dist/test/ELF/relative-dynamic-reloc.s
  vendor/lld/dist/test/ELF/relocation-copy-flags.s
  vendor/lld/dist/test/ELF/relocation-i686.s
  vendor/lld/dist/test/ELF/relocation-non-alloc.s
  vendor/lld/dist/test/ELF/relocation.s
  vendor/lld/dist/test/ELF/section-layout.s
  vendor/lld/dist/test/ELF/section-name.s
  vendor/lld/dist/test/ELF/sort-norosegment.s
  vendor/lld/dist/test/ELF/startstop.s
  vendor/lld/dist/test/ELF/synthetic-got.s
  vendor/lld/dist/test/ELF/tls-dynamic-i686.s
  vendor/lld/dist/test/ELF/tls-dynamic.s
  vendor/lld/dist/test/ELF/tls-offset.s
  vendor/lld/dist/test/ELF/undef-with-plt-addr.s
  vendor/lld/dist/test/ELF/undefined-versioned-symbol.s
  vendor/lld/dist/test/ELF/x86-64-tls-gd-local.s

Modified: vendor/lld/dist/CMakeLists.txt
==============================================================================
--- vendor/lld/dist/CMakeLists.txt	Sat Jan 14 15:39:18 2017	(r312180)
+++ vendor/lld/dist/CMakeLists.txt	Sat Jan 14 15:39:25 2017	(r312181)
@@ -12,6 +12,7 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRE
   endif()
 
   execute_process(COMMAND "${LLVM_CONFIG_PATH}" "--obj-root" "--includedir"
+                          "--cmakedir"
                   RESULT_VARIABLE HAD_ERROR
                   OUTPUT_VARIABLE LLVM_CONFIG_OUTPUT
                   OUTPUT_STRIP_TRAILING_WHITESPACE)
@@ -23,12 +24,12 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRE
 
   list(GET LLVM_CONFIG_OUTPUT 0 OBJ_ROOT)
   list(GET LLVM_CONFIG_OUTPUT 1 MAIN_INCLUDE_DIR)
+  list(GET LLVM_CONFIG_OUTPUT 2 LLVM_CMAKE_PATH)
 
   set(LLVM_OBJ_ROOT ${OBJ_ROOT} CACHE PATH "path to LLVM build tree")
   set(LLVM_MAIN_INCLUDE_DIR ${MAIN_INCLUDE_DIR} CACHE PATH "path to llvm/include")
 
   file(TO_CMAKE_PATH ${LLVM_OBJ_ROOT} LLVM_BINARY_DIR)
-  set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm")
 
   if(NOT EXISTS "${LLVM_CMAKE_PATH}/LLVMConfig.cmake")
     message(FATAL_ERROR "LLVMConfig.cmake not found")

Modified: vendor/lld/dist/COFF/PDB.cpp
==============================================================================
--- vendor/lld/dist/COFF/PDB.cpp	Sat Jan 14 15:39:18 2017	(r312180)
+++ vendor/lld/dist/COFF/PDB.cpp	Sat Jan 14 15:39:25 2017	(r312181)
@@ -14,8 +14,12 @@
 #include "SymbolTable.h"
 #include "Symbols.h"
 #include "llvm/DebugInfo/CodeView/CVDebugRecord.h"
+#include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
 #include "llvm/DebugInfo/CodeView/SymbolDumper.h"
-#include "llvm/DebugInfo/CodeView/TypeDumper.h"
+#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
+#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
+#include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
+#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
 #include "llvm/DebugInfo/MSF/ByteStream.h"
 #include "llvm/DebugInfo/MSF/MSFBuilder.h"
 #include "llvm/DebugInfo/MSF/MSFCommon.h"
@@ -61,44 +65,75 @@ static SectionChunk *findByName(std::vec
   return nullptr;
 }
 
-static ArrayRef<uint8_t> getDebugT(ObjectFile *File) {
-  SectionChunk *Sec = findByName(File->getDebugChunks(), ".debug$T");
+static ArrayRef<uint8_t> getDebugSection(ObjectFile *File, StringRef SecName) {
+  SectionChunk *Sec = findByName(File->getDebugChunks(), SecName);
   if (!Sec)
     return {};
 
   // First 4 bytes are section magic.
   ArrayRef<uint8_t> Data = Sec->getContents();
   if (Data.size() < 4)
-    fatal(".debug$T too short");
+    fatal(SecName + " too short");
   if (read32le(Data.data()) != COFF::DEBUG_SECTION_MAGIC)
-    fatal(".debug$T has an invalid magic");
+    fatal(SecName + " has an invalid magic");
   return Data.slice(4);
 }
 
+// Merge .debug$T sections and returns it.
+static std::vector<uint8_t> mergeDebugT(SymbolTable *Symtab) {
+  ScopedPrinter W(outs());
+
+  // Visit all .debug$T sections to add them to Builder.
+  codeview::TypeTableBuilder Builder(BAlloc);
+  for (ObjectFile *File : Symtab->ObjectFiles) {
+    ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T");
+    if (Data.empty())
+      continue;
+
+    msf::ByteStream Stream(Data);
+    codeview::CVTypeArray Types;
+    msf::StreamReader Reader(Stream);
+    if (auto EC = Reader.readArray(Types, Reader.getLength()))
+      fatal(EC, "Reader::readArray failed");
+    if (!codeview::mergeTypeStreams(Builder, Types))
+      fatal("codeview::mergeTypeStreams failed");
+  }
+
+  // Construct section contents.
+  std::vector<uint8_t> V;
+  Builder.ForEachRecord([&](TypeIndex TI, ArrayRef<uint8_t> Rec) {
+    V.insert(V.end(), Rec.begin(), Rec.end());
+  });
+  return V;
+}
+
 static void dumpDebugT(ScopedPrinter &W, ObjectFile *File) {
-  ArrayRef<uint8_t> Data = getDebugT(File);
+  ListScope LS(W, "DebugT");
+  ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T");
   if (Data.empty())
     return;
 
-  msf::ByteStream Stream(Data);
-  CVTypeDumper TypeDumper(&W, false);
-  if (auto EC = TypeDumper.dump(Data))
+  TypeDatabase TDB;
+  TypeDumpVisitor TDV(TDB, &W, false);
+  CVTypeDumper TypeDumper(TDB);
+  if (auto EC = TypeDumper.dump(Data, TDV))
     fatal(EC, "CVTypeDumper::dump failed");
 }
 
 static void dumpDebugS(ScopedPrinter &W, ObjectFile *File) {
-  SectionChunk *Sec = findByName(File->getDebugChunks(), ".debug$S");
-  if (!Sec)
+  ListScope LS(W, "DebugS");
+  ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$S");
+  if (Data.empty())
     return;
 
-  msf::ByteStream Stream(Sec->getContents());
+  msf::ByteStream Stream(Data);
   CVSymbolArray Symbols;
   msf::StreamReader Reader(Stream);
   if (auto EC = Reader.readArray(Symbols, Reader.getLength()))
     fatal(EC, "StreamReader.readArray<CVSymbolArray> failed");
 
-  CVTypeDumper TypeDumper(&W, false);
-  CVSymbolDumper SymbolDumper(W, TypeDumper, nullptr, false);
+  TypeDatabase TDB;
+  CVSymbolDumper SymbolDumper(W, TDB, nullptr, false);
   if (auto EC = SymbolDumper.dump(Symbols))
     fatal(EC, "CVSymbolDumper::dump failed");
 }
@@ -113,21 +148,15 @@ static void dumpCodeView(SymbolTable *Sy
   }
 }
 
-static void addTypeInfo(SymbolTable *Symtab,
-                        pdb::TpiStreamBuilder &TpiBuilder) {
-  for (ObjectFile *File : Symtab->ObjectFiles) {
-    ArrayRef<uint8_t> Data = getDebugT(File);
-    if (Data.empty())
-      continue;
-
-    msf::ByteStream Stream(Data);
-    codeview::CVTypeArray Records;
-    msf::StreamReader Reader(Stream);
-    if (auto EC = Reader.readArray(Records, Reader.getLength()))
-      fatal(EC, "Reader.readArray failed");
-    for (const codeview::CVType &Rec : Records)
-      TpiBuilder.addTypeRecord(Rec);
-  }
+static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder,
+                        ArrayRef<uint8_t> Data) {
+  msf::ByteStream Stream(Data);
+  codeview::CVTypeArray Records;
+  msf::StreamReader Reader(Stream);
+  if (auto EC = Reader.readArray(Records, Reader.getLength()))
+    fatal(EC, "Reader.readArray failed");
+  for (const codeview::CVType &Rec : Records)
+    TpiBuilder.addTypeRecord(Rec);
 }
 
 // Creates a PDB file.
@@ -162,8 +191,11 @@ void coff::createPDB(StringRef Path, Sym
   // Add an empty TPI stream.
   auto &TpiBuilder = Builder.getTpiBuilder();
   TpiBuilder.setVersionHeader(pdb::PdbTpiV80);
-  if (Config->DebugPdb)
-    addTypeInfo(Symtab, TpiBuilder);
+  std::vector<uint8_t> TpiData;
+  if (Config->DebugPdb) {
+    TpiData = mergeDebugT(Symtab);
+    addTypeInfo(TpiBuilder, TpiData);
+  }
 
   // Add an empty IPI stream.
   auto &IpiBuilder = Builder.getIpiBuilder();

Modified: vendor/lld/dist/ELF/Driver.cpp
==============================================================================
--- vendor/lld/dist/ELF/Driver.cpp	Sat Jan 14 15:39:18 2017	(r312180)
+++ vendor/lld/dist/ELF/Driver.cpp	Sat Jan 14 15:39:25 2017	(r312181)
@@ -24,6 +24,7 @@
 #include "lld/Driver/Driver.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/Object/Decompressor.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/TarWriter.h"
@@ -815,7 +816,7 @@ template <class ELFT> void LinkerDriver:
           [](InputSectionBase<ELFT> *S) {
             if (!S->Live)
               return;
-            if (S->isCompressed())
+            if (Decompressor::isCompressedELFSection(S->Flags, S->Name))
               S->uncompress();
             if (auto *MS = dyn_cast<MergeInputSection<ELFT>>(S))
               MS->splitIntoPieces();

Modified: vendor/lld/dist/ELF/Error.cpp
==============================================================================
--- vendor/lld/dist/ELF/Error.cpp	Sat Jan 14 15:39:18 2017	(r312180)
+++ vendor/lld/dist/ELF/Error.cpp	Sat Jan 14 15:39:25 2017	(r312181)
@@ -103,4 +103,8 @@ void elf::fatal(std::error_code EC, cons
   fatal(Prefix + ": " + EC.message());
 }
 
+void elf::fatal(Error &E, const Twine &Prefix) {
+  fatal(Prefix + ": " + llvm::toString(std::move(E)));
+}
+
 } // namespace lld

Modified: vendor/lld/dist/ELF/Error.h
==============================================================================
--- vendor/lld/dist/ELF/Error.h	Sat Jan 14 15:39:18 2017	(r312180)
+++ vendor/lld/dist/ELF/Error.h	Sat Jan 14 15:39:25 2017	(r312181)
@@ -44,6 +44,7 @@ void error(std::error_code EC, const Twi
 LLVM_ATTRIBUTE_NORETURN void exitLld(int Val);
 LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
 LLVM_ATTRIBUTE_NORETURN void fatal(std::error_code EC, const Twine &Prefix);
+LLVM_ATTRIBUTE_NORETURN void fatal(Error &E, const Twine &Prefix);
 
 // check() functions are convenient functions to strip errors
 // from error-or-value objects.
@@ -55,11 +56,7 @@ template <class T> T check(ErrorOr<T> E)
 
 template <class T> T check(Expected<T> E) {
   if (!E)
-    handleAllErrors(std::move(E.takeError()),
-                    [](llvm::ErrorInfoBase &EIB) -> Error {
-                      fatal(EIB.message());
-                      return Error::success();
-                    });
+    fatal(llvm::toString(E.takeError()));
   return std::move(*E);
 }
 

Modified: vendor/lld/dist/ELF/InputFiles.cpp
==============================================================================
--- vendor/lld/dist/ELF/InputFiles.cpp	Sat Jan 14 15:39:18 2017	(r312180)
+++ vendor/lld/dist/ELF/InputFiles.cpp	Sat Jan 14 15:39:25 2017	(r312181)
@@ -857,8 +857,8 @@ template <class ELFT> void BinaryFile::p
   StringRef EndName = Saver.save(Twine(Filename) + "_end");
   StringRef SizeName = Saver.save(Twine(Filename) + "_size");
 
-  auto *Section =
-      make<InputSection<ELFT>>(SHF_ALLOC, SHT_PROGBITS, 8, Data, ".data");
+  auto *Section = make<InputSection<ELFT>>(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,
+                                           8, Data, ".data");
   Sections.push_back(Section);
 
   elf::Symtab<ELFT>::X->addRegular(StartName, STV_DEFAULT, STT_OBJECT, 0, 0,

Modified: vendor/lld/dist/ELF/InputSection.cpp
==============================================================================
--- vendor/lld/dist/ELF/InputSection.cpp	Sat Jan 14 15:39:18 2017	(r312180)
+++ vendor/lld/dist/ELF/InputSection.cpp	Sat Jan 14 15:39:25 2017	(r312181)
@@ -19,6 +19,7 @@
 #include "SyntheticSections.h"
 #include "Target.h"
 #include "Thunks.h"
+#include "llvm/Object/Decompressor.h"
 #include "llvm/Support/Compression.h"
 #include "llvm/Support/Endian.h"
 #include <mutex>
@@ -35,7 +36,10 @@ using namespace lld::elf;
 // Returns a string to construct an error message.
 template <class ELFT>
 std::string lld::toString(const InputSectionBase<ELFT> *Sec) {
-  return (Sec->getFile()->getName() + ":(" + Sec->Name + ")").str();
+  // File can be absent if section is synthetic.
+  std::string FileName =
+      Sec->getFile() ? Sec->getFile()->getName() : "<internal>";
+  return (FileName + ":(" + Sec->Name + ")").str();
 }
 
 template <class ELFT>
@@ -102,11 +106,6 @@ template <class ELFT> size_t InputSectio
   return Data.size();
 }
 
-// Returns a string for an error message.
-template <class SectionT> static std::string getName(SectionT *Sec) {
-  return (Sec->getFile()->getName() + ":(" + Sec->Name + ")").str();
-}
-
 template <class ELFT>
 typename ELFT::uint InputSectionBase<ELFT>::getOffset(uintX_t Offset) const {
   switch (kind()) {
@@ -128,71 +127,23 @@ typename ELFT::uint InputSectionBase<ELF
   llvm_unreachable("invalid section kind");
 }
 
-template <class ELFT> bool InputSectionBase<ELFT>::isCompressed() const {
-  return (Flags & SHF_COMPRESSED) || Name.startswith(".zdebug");
-}
-
-// Returns compressed data and its size when uncompressed.
-template <class ELFT>
-std::pair<ArrayRef<uint8_t>, uint64_t>
-InputSectionBase<ELFT>::getElfCompressedData(ArrayRef<uint8_t> Data) {
-  // Compressed section with Elf_Chdr is the ELF standard.
-  if (Data.size() < sizeof(Elf_Chdr))
-    fatal(toString(this) + ": corrupted compressed section");
-  auto *Hdr = reinterpret_cast<const Elf_Chdr *>(Data.data());
-  if (Hdr->ch_type != ELFCOMPRESS_ZLIB)
-    fatal(toString(this) + ": unsupported compression type");
-  return {Data.slice(sizeof(*Hdr)), Hdr->ch_size};
-}
-
-// Returns compressed data and its size when uncompressed.
-template <class ELFT>
-std::pair<ArrayRef<uint8_t>, uint64_t>
-InputSectionBase<ELFT>::getRawCompressedData(ArrayRef<uint8_t> Data) {
-  // Compressed sections without Elf_Chdr header contain this header
-  // instead. This is a GNU extension.
-  struct ZlibHeader {
-    char Magic[4]; // Should be "ZLIB"
-    char Size[8];  // Uncompressed size in big-endian
-  };
-
-  if (Data.size() < sizeof(ZlibHeader))
-    fatal(toString(this) + ": corrupted compressed section");
-  auto *Hdr = reinterpret_cast<const ZlibHeader *>(Data.data());
-  if (memcmp(Hdr->Magic, "ZLIB", 4))
-    fatal(toString(this) + ": broken ZLIB-compressed section");
-  return {Data.slice(sizeof(*Hdr)), read64be(Hdr->Size)};
-}
-
 // Uncompress section contents. Note that this function is called
 // from parallel_for_each, so it must be thread-safe.
 template <class ELFT> void InputSectionBase<ELFT>::uncompress() {
-  if (!zlib::isAvailable())
-    fatal(toString(this) +
-          ": build lld with zlib to enable compressed sections support");
-
-  // This section is compressed. Here we decompress it. Ideally, all
-  // compressed sections have SHF_COMPRESSED bit and their contents
-  // start with headers of Elf_Chdr type. However, sections whose
-  // names start with ".zdebug_" don't have the bit and contains a raw
-  // ZLIB-compressed data (which is a bad thing because section names
-  // shouldn't be significant in ELF.) We need to be able to read both.
-  ArrayRef<uint8_t> Buf; // Compressed data
-  size_t Size;           // Uncompressed size
-  if (Flags & SHF_COMPRESSED)
-    std::tie(Buf, Size) = getElfCompressedData(Data);
-  else
-    std::tie(Buf, Size) = getRawCompressedData(Data);
+  Decompressor Decompressor = check(Decompressor::create(
+      Name, toStringRef(Data), ELFT::TargetEndianness == llvm::support::little,
+      ELFT::Is64Bits));
 
-  // Uncompress Buf.
+  size_t Size = Decompressor.getDecompressedSize();
   char *OutputBuf;
   {
     static std::mutex Mu;
     std::lock_guard<std::mutex> Lock(Mu);
     OutputBuf = BAlloc.Allocate<char>(Size);
   }
-  if (zlib::uncompress(toStringRef(Buf), OutputBuf, Size) != zlib::StatusOK)
-    fatal(toString(this) + ": error while uncompressing section");
+
+  if (Error E = Decompressor.decompress({OutputBuf, Size}))
+    fatal(E, toString(this));
   Data = ArrayRef<uint8_t>((uint8_t *)OutputBuf, Size);
 }
 

Modified: vendor/lld/dist/ELF/InputSection.h
==============================================================================
--- vendor/lld/dist/ELF/InputSection.h	Sat Jan 14 15:39:18 2017	(r312180)
+++ vendor/lld/dist/ELF/InputSection.h	Sat Jan 14 15:39:25 2017	(r312181)
@@ -138,22 +138,12 @@ public:
   // section.
   uintX_t getOffset(uintX_t Offset) const;
 
-  // ELF supports ZLIB-compressed section.
-  // Returns true if the section is compressed.
-  bool isCompressed() const;
   void uncompress();
 
   // Returns a source location string. Used to construct an error message.
   std::string getLocation(uintX_t Offset);
 
   void relocate(uint8_t *Buf, uint8_t *BufEnd);
-
-private:
-  std::pair<ArrayRef<uint8_t>, uint64_t>
-  getElfCompressedData(ArrayRef<uint8_t> Data);
-
-  std::pair<ArrayRef<uint8_t>, uint64_t>
-  getRawCompressedData(ArrayRef<uint8_t> Data);
 };
 
 // SectionPiece represents a piece of splittable section contents.

Modified: vendor/lld/dist/ELF/LinkerScript.cpp
==============================================================================
--- vendor/lld/dist/ELF/LinkerScript.cpp	Sat Jan 14 15:39:18 2017	(r312180)
+++ vendor/lld/dist/ELF/LinkerScript.cpp	Sat Jan 14 15:39:25 2017	(r312181)
@@ -1014,6 +1014,7 @@ private:
   void readAnonymousDeclaration();
   void readVersionDeclaration(StringRef VerStr);
   std::vector<SymbolVersion> readSymbols();
+  void readLocals();
 
   ScriptConfiguration &Opt = *ScriptConfig;
   bool IsUnderSysroot;
@@ -1861,17 +1862,22 @@ void ScriptParser::readAnonymousDeclarat
   if (consume("global:") || peek() != "local:")
     Config->VersionScriptGlobals = readSymbols();
 
-  // Next, read local symbols.
-  if (consume("local:")) {
-    if (consume("*")) {
+  readLocals();
+  expect("}");
+  expect(";");
+}
+
+void ScriptParser::readLocals() {
+  if (!consume("local:"))
+    return;
+  std::vector<SymbolVersion> Locals = readSymbols();
+  for (SymbolVersion V : Locals) {
+    if (V.Name == "*") {
       Config->DefaultSymbolVersion = VER_NDX_LOCAL;
-      expect(";");
-    } else {
-      setError("local symbol list for anonymous version is not supported");
+      continue;
     }
+    Config->VersionScriptLocals.push_back(V);
   }
-  expect("}");
-  expect(";");
 }
 
 // Reads a list of symbols, e.g. "VerStr { global: foo; bar; local: *; };".
@@ -1885,16 +1891,7 @@ void ScriptParser::readVersionDeclaratio
   if (consume("global:") || peek() != "local:")
     Config->VersionDefinitions.back().Globals = readSymbols();
 
-  // Read local symbols.
-  if (consume("local:")) {
-    if (consume("*")) {
-      Config->DefaultSymbolVersion = VER_NDX_LOCAL;
-      expect(";");
-    } else {
-      for (SymbolVersion V : readSymbols())
-        Config->VersionScriptLocals.push_back(V);
-    }
-  }
+  readLocals();
   expect("}");
 
   // Each version may have a parent version. For example, "Ver2"

Modified: vendor/lld/dist/ELF/OutputSections.cpp
==============================================================================
--- vendor/lld/dist/ELF/OutputSections.cpp	Sat Jan 14 15:39:18 2017	(r312180)
+++ vendor/lld/dist/ELF/OutputSections.cpp	Sat Jan 14 15:39:25 2017	(r312181)
@@ -636,7 +636,12 @@ OutputSectionFactory<ELFT>::create(const
     if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(C->Flags))
       error("Section has flags incompatible with others with the same name " +
             toString(C));
-    if (Sec->Type != C->Type)
+    // Convert notbits to progbits if they are mixed. This happens is some
+    // linker scripts.
+    if (Sec->Type == SHT_NOBITS && C->Type == SHT_PROGBITS)
+      Sec->Type = SHT_PROGBITS;
+    if (Sec->Type != C->Type &&
+        !(Sec->Type == SHT_PROGBITS && C->Type == SHT_NOBITS))
       error("Section has different type from others with the same name " +
             toString(C));
     Sec->Flags |= Flags;

Modified: vendor/lld/dist/ELF/OutputSections.h
==============================================================================
--- vendor/lld/dist/ELF/OutputSections.h	Sat Jan 14 15:39:18 2017	(r312180)
+++ vendor/lld/dist/ELF/OutputSections.h	Sat Jan 14 15:39:25 2017	(r312181)
@@ -206,6 +206,7 @@ template <class ELFT> struct Out {
   static uint8_t First;
   static EhOutputSection<ELFT> *EhFrame;
   static OutputSection<ELFT> *Bss;
+  static OutputSection<ELFT> *BssRelRo;
   static OutputSectionBase *Opd;
   static uint8_t *OpdBuf;
   static PhdrEntry *TlsPhdr;
@@ -252,6 +253,7 @@ template <class ELFT> uint64_t getHeader
 template <class ELFT> uint8_t Out<ELFT>::First;
 template <class ELFT> EhOutputSection<ELFT> *Out<ELFT>::EhFrame;
 template <class ELFT> OutputSection<ELFT> *Out<ELFT>::Bss;
+template <class ELFT> OutputSection<ELFT> *Out<ELFT>::BssRelRo;
 template <class ELFT> OutputSectionBase *Out<ELFT>::Opd;
 template <class ELFT> uint8_t *Out<ELFT>::OpdBuf;
 template <class ELFT> PhdrEntry *Out<ELFT>::TlsPhdr;

Modified: vendor/lld/dist/ELF/Relocations.cpp
==============================================================================
--- vendor/lld/dist/ELF/Relocations.cpp	Sat Jan 14 15:39:18 2017	(r312180)
+++ vendor/lld/dist/ELF/Relocations.cpp	Sat Jan 14 15:39:25 2017	(r312181)
@@ -399,7 +399,21 @@ template <class ELFT> static uint32_t ge
   return 1 << TrailingZeros;
 }
 
-// Reserve space in .bss for copy relocation.
+template <class ELFT> static bool isReadOnly(SharedSymbol<ELFT> *SS) {
+  typedef typename ELFT::uint uintX_t;
+  typedef typename ELFT::Phdr Elf_Phdr;
+
+  // Determine if the symbol is read-only by scanning the DSO's program headers.
+  uintX_t Value = SS->Sym.st_value;
+  for (const Elf_Phdr &Phdr : check(SS->file()->getObj().program_headers()))
+    if ((Phdr.p_type == ELF::PT_LOAD || Phdr.p_type == ELF::PT_GNU_RELRO) &&
+        !(Phdr.p_flags & ELF::PF_W) && Value >= Phdr.p_vaddr &&
+        Value < Phdr.p_vaddr + Phdr.p_memsz)
+      return true;
+  return false;
+}
+
+// Reserve space in .bss or .bss.rel.ro for copy relocation.
 template <class ELFT> static void addCopyRelSymbol(SharedSymbol<ELFT> *SS) {
   typedef typename ELFT::uint uintX_t;
   typedef typename ELFT::Sym Elf_Sym;
@@ -409,10 +423,16 @@ template <class ELFT> static void addCop
   if (SymSize == 0)
     fatal("cannot create a copy relocation for symbol " + toString(*SS));
 
+  // See if this symbol is in a read-only segment. If so, preserve the symbol's
+  // memory protection by reserving space in the .bss.rel.ro section.
+  bool IsReadOnly = isReadOnly(SS);
+  OutputSection<ELFT> *CopySec =
+      IsReadOnly ? Out<ELFT>::BssRelRo : Out<ELFT>::Bss;
+
   uintX_t Alignment = getAlignment(SS);
-  uintX_t Off = alignTo(Out<ELFT>::Bss->Size, Alignment);
-  Out<ELFT>::Bss->Size = Off + SymSize;
-  Out<ELFT>::Bss->updateAlignment(Alignment);
+  uintX_t Off = alignTo(CopySec->Size, Alignment);
+  CopySec->Size = Off + SymSize;
+  CopySec->updateAlignment(Alignment);
   uintX_t Shndx = SS->Sym.st_shndx;
   uintX_t Value = SS->Sym.st_value;
   // Look through the DSO's dynamic symbol table for aliases and create a
@@ -425,12 +445,12 @@ template <class ELFT> static void addCop
         Symtab<ELFT>::X->find(check(S.getName(SS->file()->getStringTable()))));
     if (!Alias)
       continue;
-    Alias->OffsetInBss = Off;
+    Alias->CopyIsInBssRelRo = IsReadOnly;
+    Alias->CopyOffset = Off;
     Alias->NeedsCopyOrPltAddr = true;
     Alias->symbol()->IsUsedInRegularObj = true;
   }
-  In<ELFT>::RelaDyn->addReloc(
-      {Target->CopyRel, Out<ELFT>::Bss, SS->OffsetInBss, false, SS, 0});
+  In<ELFT>::RelaDyn->addReloc({Target->CopyRel, CopySec, Off, false, SS, 0});
 }
 
 template <class ELFT>

Modified: vendor/lld/dist/ELF/SymbolTable.cpp
==============================================================================
--- vendor/lld/dist/ELF/SymbolTable.cpp	Sat Jan 14 15:39:18 2017	(r312180)
+++ vendor/lld/dist/ELF/SymbolTable.cpp	Sat Jan 14 15:39:25 2017	(r312181)
@@ -605,19 +605,16 @@ SymbolTable<ELFT>::findAllByVersion(Symb
 
 // If there's only one anonymous version definition in a version
 // script file, the script does not actually define any symbol version,
-// but just specifies symbols visibilities. We assume that the script was
-// in the form of { global: foo; bar; local *; }. So, local is default.
-// In this function, we make specified symbols global.
+// but just specifies symbols visibilities.
 template <class ELFT> void SymbolTable<ELFT>::handleAnonymousVersion() {
-  for (SymbolVersion &Ver : Config->VersionScriptGlobals) {
-    if (Ver.HasWildcard) {
-      for (SymbolBody *B : findAllByVersion(Ver))
-        B->symbol()->VersionId = VER_NDX_GLOBAL;
-      continue;
-    }
-    for (SymbolBody *B : findByVersion(Ver))
-      B->symbol()->VersionId = VER_NDX_GLOBAL;
-  }
+  for (SymbolVersion &Ver : Config->VersionScriptGlobals)
+    assignExactVersion(Ver, VER_NDX_GLOBAL, "global");
+  for (SymbolVersion &Ver : Config->VersionScriptGlobals)
+    assignWildcardVersion(Ver, VER_NDX_GLOBAL);
+  for (SymbolVersion &Ver : Config->VersionScriptLocals)
+    assignExactVersion(Ver, VER_NDX_LOCAL, "local");
+  for (SymbolVersion &Ver : Config->VersionScriptLocals)
+    assignWildcardVersion(Ver, VER_NDX_LOCAL);
 }
 
 // Set symbol versions to symbols. This function handles patterns
@@ -673,10 +670,7 @@ template <class ELFT> void SymbolTable<E
       Sym->body()->parseSymbolVersion();
 
   // Handle edge cases first.
-  if (!Config->VersionScriptGlobals.empty()) {
-    handleAnonymousVersion();
-    return;
-  }
+  handleAnonymousVersion();
 
   if (Config->VersionDefinitions.empty())
     return;
@@ -687,8 +681,6 @@ template <class ELFT> void SymbolTable<E
 
   // First, we assign versions to exact matching symbols,
   // i.e. version definitions not containing any glob meta-characters.
-  for (SymbolVersion &Ver : Config->VersionScriptLocals)
-    assignExactVersion(Ver, VER_NDX_LOCAL, "local");
   for (VersionDefinition &V : Config->VersionDefinitions)
     for (SymbolVersion &Ver : V.Globals)
       assignExactVersion(Ver, V.Id, V.Name);
@@ -697,8 +689,6 @@ template <class ELFT> void SymbolTable<E
   // i.e. version definitions containing glob meta-characters.
   // Note that because the last match takes precedence over previous matches,
   // we iterate over the definitions in the reverse order.
-  for (SymbolVersion &Ver : Config->VersionScriptLocals)
-    assignWildcardVersion(Ver, VER_NDX_LOCAL);
   for (VersionDefinition &V : llvm::reverse(Config->VersionDefinitions))
     for (SymbolVersion &Ver : V.Globals)
       assignWildcardVersion(Ver, V.Id);

Modified: vendor/lld/dist/ELF/Symbols.cpp
==============================================================================
--- vendor/lld/dist/ELF/Symbols.cpp	Sat Jan 14 15:39:18 2017	(r312180)
+++ vendor/lld/dist/ELF/Symbols.cpp	Sat Jan 14 15:39:25 2017	(r312181)
@@ -81,7 +81,7 @@ static typename ELFT::uint getSymVA(cons
       return 0;
     if (SS.isFunc())
       return Body.getPltVA<ELFT>();
-    return Out<ELFT>::Bss->Addr + SS.OffsetInBss;
+    return SS.getBssSectionForCopy()->Addr + SS.CopyOffset;
   }
   case SymbolBody::UndefinedKind:
     return 0;
@@ -97,7 +97,8 @@ SymbolBody::SymbolBody(Kind K, StringRef
                        uint8_t Type)
     : SymbolKind(K), NeedsCopyOrPltAddr(false), IsLocal(IsLocal),
       IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false),
-      IsInIgot(false), Type(Type), StOther(StOther), Name(Name) {}
+      IsInIgot(false), CopyIsInBssRelRo(false), Type(Type), StOther(StOther),
+      Name(Name) {}
 
 // Returns true if a symbol can be replaced at load-time by a symbol
 // with the same name defined in other ELF executable or DSO.
@@ -245,6 +246,12 @@ Undefined<ELFT>::Undefined(StringRefZ Na
   this->File = File;
 }
 
+template <typename ELFT>
+OutputSection<ELFT> *SharedSymbol<ELFT>::getBssSectionForCopy() const {
+  assert(needsCopy());
+  return CopyIsInBssRelRo ? Out<ELFT>::BssRelRo : Out<ELFT>::Bss;
+}
+
 DefinedCommon::DefinedCommon(StringRef Name, uint64_t Size, uint64_t Alignment,
                              uint8_t StOther, uint8_t Type, InputFile *File)
     : Defined(SymbolBody::DefinedCommonKind, Name, /*IsLocal=*/false, StOther,
@@ -287,10 +294,22 @@ InputFile *LazyObject::fetch() {
   return createObjectFile(MBRef);
 }
 
-bool Symbol::includeInDynsym() const {
+uint8_t Symbol::computeBinding() const {
+  if (Config->Relocatable)
+    return Binding;
   if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
+    return STB_LOCAL;
+  if (VersionId == VER_NDX_LOCAL && !body()->isUndefined())
+    return STB_LOCAL;
+  if (Config->NoGnuUnique && Binding == STB_GNU_UNIQUE)
+    return STB_GLOBAL;
+  return Binding;
+}
+
+bool Symbol::includeInDynsym() const {
+  if (computeBinding() == STB_LOCAL)
     return false;
-  return (ExportDynamic && VersionId != VER_NDX_LOCAL) || body()->isShared() ||
+  return ExportDynamic || body()->isShared() ||
          (body()->isUndefined() && Config->Shared);
 }
 
@@ -366,6 +385,11 @@ template class elf::Undefined<ELF32BE>;
 template class elf::Undefined<ELF64LE>;
 template class elf::Undefined<ELF64BE>;
 
+template class elf::SharedSymbol<ELF32LE>;
+template class elf::SharedSymbol<ELF32BE>;
+template class elf::SharedSymbol<ELF64LE>;
+template class elf::SharedSymbol<ELF64BE>;
+
 template class elf::DefinedRegular<ELF32LE>;
 template class elf::DefinedRegular<ELF32BE>;
 template class elf::DefinedRegular<ELF64LE>;

Modified: vendor/lld/dist/ELF/Symbols.h
==============================================================================
--- vendor/lld/dist/ELF/Symbols.h	Sat Jan 14 15:39:18 2017	(r312180)
+++ vendor/lld/dist/ELF/Symbols.h	Sat Jan 14 15:39:25 2017	(r312181)
@@ -123,6 +123,11 @@ public:
   // True if this symbol is in the Igot sub-section of the .got.plt or .got.
   unsigned IsInIgot : 1;
 
+  // True if this is a shared symbol in a read-only segment which requires a
+  // copy relocation. This causes space for the symbol to be allocated in the
+  // .bss.rel.ro section.
+  unsigned CopyIsInBssRelRo : 1;
+
   // The following fields have the same meaning as the ELF symbol attributes.
   uint8_t Type;    // symbol type
   uint8_t StOther; // st_other field value
@@ -282,13 +287,15 @@ public:
   // This field is a pointer to the symbol's version definition.
   const Elf_Verdef *Verdef;
 
-  // OffsetInBss is significant only when needsCopy() is true.
-  uintX_t OffsetInBss = 0;
+  // CopyOffset is significant only when needsCopy() is true.
+  uintX_t CopyOffset = 0;
 
   // If non-null the symbol has a Thunk that may be used as an alternative
   // destination for callers of this Symbol.
   Thunk<ELFT> *ThunkData = nullptr;
   bool needsCopy() const { return this->NeedsCopyOrPltAddr && !this->isFunc(); }
+
+  OutputSection<ELFT> *getBssSectionForCopy() const;
 };
 
 // This class represents a symbol defined in an archive file. It is
@@ -413,6 +420,7 @@ struct Symbol {
   unsigned InVersionScript : 1;
 
   bool includeInDynsym() const;
+  uint8_t computeBinding() const;
   bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; }
 
   // This field is used to store the Symbol's SymbolBody. This instantiation of

Modified: vendor/lld/dist/ELF/SyntheticSections.cpp
==============================================================================
--- vendor/lld/dist/ELF/SyntheticSections.cpp	Sat Jan 14 15:39:18 2017	(r312180)
+++ vendor/lld/dist/ELF/SyntheticSections.cpp	Sat Jan 14 15:39:25 2017	(r312181)
@@ -1060,18 +1060,6 @@ static bool sortMipsSymbols(const Symbol
   return L->GotIndex < R->GotIndex;
 }
 
-static uint8_t getSymbolBinding(SymbolBody *Body) {
-  Symbol *S = Body->symbol();
-  if (Config->Relocatable)
-    return S->Binding;
-  uint8_t Visibility = S->Visibility;
-  if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
-    return STB_LOCAL;
-  if (Config->NoGnuUnique && S->Binding == STB_GNU_UNIQUE)
-    return STB_GLOBAL;
-  return S->Binding;
-}
-
 template <class ELFT> void SymbolTableSection<ELFT>::finalize() {
   this->OutSec->Link = this->Link = StrTabSec.OutSec->SectionIndex;
   this->OutSec->Info = this->Info = NumLocals + 1;
@@ -1085,11 +1073,12 @@ template <class ELFT> void SymbolTableSe
   }
 
   if (!StrTabSec.isDynamic()) {
-    std::stable_sort(Symbols.begin(), Symbols.end(),
-                     [](const SymbolTableEntry &L, const SymbolTableEntry &R) {
-                       return getSymbolBinding(L.Symbol) == STB_LOCAL &&
-                              getSymbolBinding(R.Symbol) != STB_LOCAL;
-                     });
+    std::stable_sort(
+        Symbols.begin(), Symbols.end(),
+        [](const SymbolTableEntry &L, const SymbolTableEntry &R) {
+          return L.Symbol->symbol()->computeBinding() == STB_LOCAL &&
+                 R.Symbol->symbol()->computeBinding() != STB_LOCAL;
+        });
     return;
   }
   if (In<ELFT>::GnuHashTab)
@@ -1159,7 +1148,7 @@ void SymbolTableSection<ELFT>::writeGlob
     uint8_t Type = Body->Type;
     uintX_t Size = Body->getSize<ELFT>();
 
-    ESym->setBindingAndType(getSymbolBinding(Body), Type);
+    ESym->setBindingAndType(Body->symbol()->computeBinding(), Type);
     ESym->st_size = Size;
     ESym->st_name = StrOff;
     ESym->setVisibility(Body->symbol()->Visibility);
@@ -1201,10 +1190,12 @@ SymbolTableSection<ELFT>::getOutputSecti
   }
   case SymbolBody::DefinedCommonKind:
     return In<ELFT>::Common->OutSec;
-  case SymbolBody::SharedKind:
-    if (cast<SharedSymbol<ELFT>>(Sym)->needsCopy())
-      return Out<ELFT>::Bss;
+  case SymbolBody::SharedKind: {
+    auto &SS = cast<SharedSymbol<ELFT>>(*Sym);
+    if (SS.needsCopy())
+      return SS.getBssSectionForCopy();
     break;
+  }
   case SymbolBody::UndefinedKind:
   case SymbolBody::LazyArchiveKind:
   case SymbolBody::LazyObjectKind:

Modified: vendor/lld/dist/ELF/Target.cpp
==============================================================================
--- vendor/lld/dist/ELF/Target.cpp	Sat Jan 14 15:39:18 2017	(r312180)
+++ vendor/lld/dist/ELF/Target.cpp	Sat Jan 14 15:39:25 2017	(r312181)
@@ -356,7 +356,9 @@ X86TargetInfo::X86TargetInfo() {
 
 RelExpr X86TargetInfo::getRelExpr(uint32_t Type, const SymbolBody &S) const {
   switch (Type) {
-  default:
+  case R_386_16:
+  case R_386_32:
+  case R_386_TLS_LDO_32:
     return R_ABS;
   case R_386_TLS_GD:
     return R_TLSGD;
@@ -381,6 +383,12 @@ RelExpr X86TargetInfo::getRelExpr(uint32
     return R_TLS;
   case R_386_TLS_LE_32:
     return R_NEG_TLS;
+  case R_386_NONE:
+    return R_HINT;
+  default:
+    error("do not know how to handle relocation '" + toString(Type) + "' (" +
+          Twine(Type) + ")");
+    return R_HINT;
   }
 }
 
@@ -623,7 +631,11 @@ template <class ELFT>
 RelExpr X86_64TargetInfo<ELFT>::getRelExpr(uint32_t Type,
                                            const SymbolBody &S) const {
   switch (Type) {
-  default:
+  case R_X86_64_32:
+  case R_X86_64_32S:
+  case R_X86_64_64:
+  case R_X86_64_DTPOFF32:
+  case R_X86_64_DTPOFF64:
     return R_ABS;
   case R_X86_64_TPOFF32:
     return R_TLS;
@@ -649,6 +661,10 @@ RelExpr X86_64TargetInfo<ELFT>::getRelEx
     return R_GOT_PC;
   case R_X86_64_NONE:
     return R_HINT;
+  default:
+    error("do not know how to handle relocation '" + toString(Type) + "' (" +
+          Twine(Type) + ")");
+    return R_HINT;
   }
 }
 
@@ -870,7 +886,7 @@ void X86_64TargetInfo<ELFT>::relocateOne
     write64le(Loc, Val);
     break;
   default:
-    error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
+    llvm_unreachable("unexpected relocation");
   }
 }
 

Modified: vendor/lld/dist/ELF/Writer.cpp
==============================================================================
--- vendor/lld/dist/ELF/Writer.cpp	Sat Jan 14 15:39:18 2017	(r312180)
+++ vendor/lld/dist/ELF/Writer.cpp	Sat Jan 14 15:39:25 2017	(r312181)
@@ -250,6 +250,8 @@ template <class ELFT> void Writer<ELFT>:
   // Create singleton output sections.
   Out<ELFT>::Bss =
       make<OutputSection<ELFT>>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
+  Out<ELFT>::BssRelRo = make<OutputSection<ELFT>>(".bss.rel.ro", SHT_NOBITS,
+                                                  SHF_ALLOC | SHF_WRITE);
   In<ELFT>::DynStrTab = make<StringTableSection<ELFT>>(".dynstr", true);
   In<ELFT>::Dynamic = make<DynamicSection<ELFT>>();
   Out<ELFT>::EhFrame = make<EhOutputSection<ELFT>>();
@@ -498,6 +500,8 @@ template <class ELFT> bool elf::isRelroS
     return true;
   if (In<ELFT>::MipsGot && Sec == In<ELFT>::MipsGot->OutSec)
     return true;
+  if (Sec == Out<ELFT>::BssRelRo)
+    return true;
   StringRef S = Sec->getName();
   return S == ".data.rel.ro" || S == ".ctors" || S == ".dtors" || S == ".jcr" ||
          S == ".eh_frame" || S == ".openbsd.randomdata";
@@ -557,30 +561,38 @@ static bool compareSectionsNonScript(con
 
   // If we got here we know that both A and B are in the same PT_LOAD.
 
-  // The TLS initialization block needs to be a single contiguous block in a R/W
-  // PT_LOAD, so stick TLS sections directly before R/W sections. The TLS NOBITS
-  // sections are placed here as they don't take up virtual address space in the
-  // PT_LOAD.
   bool AIsTls = A->Flags & SHF_TLS;
   bool BIsTls = B->Flags & SHF_TLS;
-  if (AIsTls != BIsTls)
-    return AIsTls;
-
-  // The next requirement we have is to put nobits sections last. The
-  // reason is that the only thing the dynamic linker will see about
-  // them is a p_memsz that is larger than p_filesz. Seeing that it
-  // zeros the end of the PT_LOAD, so that has to correspond to the
-  // nobits sections.
   bool AIsNoBits = A->Type == SHT_NOBITS;
   bool BIsNoBits = B->Type == SHT_NOBITS;
-  if (AIsNoBits != BIsNoBits)
-    return BIsNoBits;
 
-  // We place RelRo section before plain r/w ones.
+  // The first requirement we have is to put (non-TLS) nobits sections last. The
+  // reason is that the only thing the dynamic linker will see about them is a
+  // p_memsz that is larger than p_filesz. Seeing that it zeros the end of the
+  // PT_LOAD, so that has to correspond to the nobits sections.
+  bool AIsNonTlsNoBits = AIsNoBits && !AIsTls;
+  bool BIsNonTlsNoBits = BIsNoBits && !BIsTls;
+  if (AIsNonTlsNoBits != BIsNonTlsNoBits)
+    return BIsNonTlsNoBits;
+
+  // We place nobits RelRo sections before plain r/w ones, and non-nobits RelRo
+  // sections after r/w ones, so that the RelRo sections are contiguous.
   bool AIsRelRo = isRelroSection<ELFT>(A);
   bool BIsRelRo = isRelroSection<ELFT>(B);
   if (AIsRelRo != BIsRelRo)
-    return AIsRelRo;
+    return AIsNonTlsNoBits ? AIsRelRo : BIsRelRo;
+
+  // The TLS initialization block needs to be a single contiguous block in a R/W
+  // PT_LOAD, so stick TLS sections directly before the other RelRo R/W
+  // sections. The TLS NOBITS sections are placed here as they don't take up
+  // virtual address space in the PT_LOAD.
+  if (AIsTls != BIsTls)
+    return AIsTls;
+
+  // Within the TLS initialization block, the non-nobits sections need to appear
+  // first.
+  if (AIsNoBits != BIsNoBits)
+    return BIsNoBits;
 
   // Some architectures have additional ordering restrictions for sections
   // within the same PT_LOAD.
@@ -1071,6 +1083,8 @@ template <class ELFT> void Writer<ELFT>:
 template <class ELFT> void Writer<ELFT>::addPredefinedSections() {
   if (Out<ELFT>::Bss->Size > 0)
     OutputSections.push_back(Out<ELFT>::Bss);
+  if (Out<ELFT>::BssRelRo->Size > 0)
+    OutputSections.push_back(Out<ELFT>::BssRelRo);
 
   auto OS = dyn_cast_or_null<OutputSection<ELFT>>(findSection(".ARM.exidx"));
   if (OS && !OS->Sections.empty() && !Config->Relocatable)
@@ -1272,8 +1286,9 @@ void Writer<ELFT>::addPtArmExid(std::vec
   Phdrs.push_back(ARMExidx);
 }
 
-// The first section of each PT_LOAD and the first section after PT_GNU_RELRO
-// have to be page aligned so that the dynamic linker can set the permissions.
+// The first section of each PT_LOAD, the first section in PT_GNU_RELRO and the
+// first section after PT_GNU_RELRO have to be page aligned so that the dynamic
+// linker can set the permissions.
 template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
   for (const PhdrEntry &P : Phdrs)
     if (P.p_type == PT_LOAD && P.First)
@@ -1282,6 +1297,8 @@ template <class ELFT> void Writer<ELFT>:
   for (const PhdrEntry &P : Phdrs) {
     if (P.p_type != PT_GNU_RELRO)
       continue;
+    if (P.First)
+      P.First->PageAlign = true;
     // Find the first section after PT_GNU_RELRO. If it is in a PT_LOAD we
     // have to align it to a page.
     auto End = OutputSections.end();
@@ -1635,10 +1652,12 @@ static void unlinkAsync(StringRef Path) 
   // Path as a new file. If we do that in a different thread, the new
   // thread can remove the new file.
   SmallString<128> TempPath;
-  if (auto EC = sys::fs::createUniqueFile(Path + "tmp%%%%%%%%", TempPath))
-    fatal(EC, "createUniqueFile failed");
-  if (auto EC = sys::fs::rename(Path, TempPath))
-    fatal(EC, "rename failed");
+  if (sys::fs::createUniqueFile(Path + "tmp%%%%%%%%", TempPath))
+    return;
+  if (sys::fs::rename(Path, TempPath)) {
+    sys::fs::remove(TempPath);
+    return;
+  }
 
   // Remove TempPath in background.
   std::thread([=] { ::remove(TempPath.str().str().c_str()); }).detach();

Added: vendor/lld/dist/test/COFF/Inputs/pdb1.yaml
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/lld/dist/test/COFF/Inputs/pdb1.yaml	Sat Jan 14 15:39:25 2017	(r312181)
@@ -0,0 +1,172 @@
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [  ]
+sections:
+  - Name:            .drectve
+    Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
+    Alignment:       1
+    SectionData:     2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
+  - Name:            '.debug$S'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    SectionData:     04000000F1000000580000001A00011100000000443A5C625C72657434322D6D61696E2E6F626A003A003C1100600000D00013000000F259000013000000F25900004D6963726F736F667420285229204F7074696D697A696E6720436F6D70696C657200F10000004E0000002A0047110000000000000000000000000E000000040000000900000005100000000000000000006D61696E001C001210280000000000000000000000000000000000000000000042110002004F110000F20000002000000000000000000000000E0000000000000001000000140000000000000002000080F400000018000000010000001001C538722F63570DF6705DDE06FE96E5D10000F30000001300000000643A5C625C72657434322D6D61696E2E630000F10000000800000006004C110E100000
+    Relocations:
+      - VirtualAddress:  140
+        SymbolName:      main
+        Type:            IMAGE_REL_AMD64_SECREL
+      - VirtualAddress:  144
+        SymbolName:      main
+        Type:            IMAGE_REL_AMD64_SECTION
+      - VirtualAddress:  196
+        SymbolName:      main
+        Type:            IMAGE_REL_AMD64_SECREL
+      - VirtualAddress:  200
+        SymbolName:      main
+        Type:            IMAGE_REL_AMD64_SECTION
+  - Name:            '.debug$T'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    SectionData:     0400000006000112000000000E0008107400000000000000001000000A000210011000000C0001000A00011201000000000000000E0008107400000000000000031000001200011600000000041000006D61696E00F3F2F10E0001160000000001100000666F6F000E00051600000000443A5C6200F3F2F12200051600000000433A5C767331345C56435C42494E5C616D6436345C636C2E6578650002010516000000002D5A37202D63202D4D54202D49433A5C767331345C56435C494E434C554445202D49433A5C767331345C56435C41544C4D46435C494E434C554445202D4922433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C31305C696E636C7564655C31302E302E31303135302E305C7563727422202D4922433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C4E4554465853444B5C342E365C696E636C7564655C756D22202D4922433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C382E315C696E636C7564655C73686172656422000A0004160100000009100000820005160A100000202D4922433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C382E315C696E636C7564655C
 756D22202D4922433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C382E315C696E636C7564655C77696E727422202D5443202D5800F3F2F1160005160000000072657434322D6D61696E2E6300F3F2F11600051600000000443A5C625C76633134302E70646200F11A000316050007100000081000000C1000000D1000000B100000F2F1
+  - Name:            '.text$mn'
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       16
+    SectionData:     4883EC28E8000000004883C428C3
+    Relocations:
+      - VirtualAddress:  5
+        SymbolName:      foo
+        Type:            IMAGE_REL_AMD64_REL32
+  - Name:            .xdata
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     '0104010004420000'
+  - Name:            .pdata
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     '000000000E00000000000000'
+    Relocations:
+      - VirtualAddress:  0

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



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