Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 Oct 2019 17:52:46 +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: r353950 - in vendor/lld/dist: . COFF Common ELF ELF/Arch docs include/lld/Common include/lld/Core include/lld/ReaderWriter lib/Driver lib/ReaderWriter lib/ReaderWriter/MachO lib/ReaderW...
Message-ID:  <201910231752.x9NHqkRl078470@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dim
Date: Wed Oct 23 17:52:45 2019
New Revision: 353950
URL: https://svnweb.freebsd.org/changeset/base/353950

Log:
  Vendor import of stripped lld trunk r375505, the last commit before the
  upstream Subversion repository was made read-only, and the LLVM project
  migrated to GitHub:
  
  https://llvm.org/svn/llvm-project/lld/trunk@375505

Added:
  vendor/lld/dist/Common/DWARF.cpp
  vendor/lld/dist/ELF/ARMErrataFix.cpp
  vendor/lld/dist/ELF/ARMErrataFix.h
  vendor/lld/dist/include/lld/Common/DWARF.h
Modified:
  vendor/lld/dist/CMakeLists.txt
  vendor/lld/dist/COFF/CMakeLists.txt
  vendor/lld/dist/COFF/Config.h
  vendor/lld/dist/COFF/DLL.cpp
  vendor/lld/dist/COFF/DebugTypes.cpp
  vendor/lld/dist/COFF/Driver.cpp
  vendor/lld/dist/COFF/Driver.h
  vendor/lld/dist/COFF/DriverUtils.cpp
  vendor/lld/dist/COFF/ICF.cpp
  vendor/lld/dist/COFF/InputFiles.cpp
  vendor/lld/dist/COFF/InputFiles.h
  vendor/lld/dist/COFF/LTO.cpp
  vendor/lld/dist/COFF/MapFile.cpp
  vendor/lld/dist/COFF/MinGW.cpp
  vendor/lld/dist/COFF/Options.td
  vendor/lld/dist/COFF/PDB.cpp
  vendor/lld/dist/COFF/PDB.h
  vendor/lld/dist/COFF/SymbolTable.cpp
  vendor/lld/dist/COFF/SymbolTable.h
  vendor/lld/dist/COFF/Symbols.cpp
  vendor/lld/dist/COFF/Symbols.h
  vendor/lld/dist/COFF/Writer.cpp
  vendor/lld/dist/Common/CMakeLists.txt
  vendor/lld/dist/Common/ErrorHandler.cpp
  vendor/lld/dist/Common/Strings.cpp
  vendor/lld/dist/Common/TargetOptionsCommandFlags.cpp
  vendor/lld/dist/ELF/AArch64ErrataFix.cpp
  vendor/lld/dist/ELF/Arch/AArch64.cpp
  vendor/lld/dist/ELF/Arch/AMDGPU.cpp
  vendor/lld/dist/ELF/Arch/ARM.cpp
  vendor/lld/dist/ELF/Arch/AVR.cpp
  vendor/lld/dist/ELF/Arch/Hexagon.cpp
  vendor/lld/dist/ELF/Arch/MSP430.cpp
  vendor/lld/dist/ELF/Arch/Mips.cpp
  vendor/lld/dist/ELF/Arch/MipsArchTree.cpp
  vendor/lld/dist/ELF/Arch/PPC.cpp
  vendor/lld/dist/ELF/Arch/PPC64.cpp
  vendor/lld/dist/ELF/Arch/RISCV.cpp
  vendor/lld/dist/ELF/Arch/SPARCV9.cpp
  vendor/lld/dist/ELF/Arch/X86.cpp
  vendor/lld/dist/ELF/Arch/X86_64.cpp
  vendor/lld/dist/ELF/CMakeLists.txt
  vendor/lld/dist/ELF/CallGraphSort.cpp
  vendor/lld/dist/ELF/Config.h
  vendor/lld/dist/ELF/DWARF.cpp
  vendor/lld/dist/ELF/DWARF.h
  vendor/lld/dist/ELF/Driver.cpp
  vendor/lld/dist/ELF/DriverUtils.cpp
  vendor/lld/dist/ELF/EhFrame.cpp
  vendor/lld/dist/ELF/ICF.cpp
  vendor/lld/dist/ELF/InputFiles.cpp
  vendor/lld/dist/ELF/InputFiles.h
  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/MapFile.cpp
  vendor/lld/dist/ELF/MarkLive.cpp
  vendor/lld/dist/ELF/Options.td
  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/ScriptLexer.cpp
  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/Symbols.h
  vendor/lld/dist/ELF/SyntheticSections.cpp
  vendor/lld/dist/ELF/SyntheticSections.h
  vendor/lld/dist/ELF/Target.cpp
  vendor/lld/dist/ELF/Writer.cpp
  vendor/lld/dist/ELF/Writer.h
  vendor/lld/dist/docs/ReleaseNotes.rst
  vendor/lld/dist/docs/WebAssembly.rst
  vendor/lld/dist/docs/conf.py
  vendor/lld/dist/docs/ld.lld.1
  vendor/lld/dist/include/lld/Common/ErrorHandler.h
  vendor/lld/dist/include/lld/Common/LLVM.h
  vendor/lld/dist/include/lld/Common/Strings.h
  vendor/lld/dist/include/lld/Common/TargetOptionsCommandFlags.h
  vendor/lld/dist/include/lld/Core/File.h
  vendor/lld/dist/include/lld/ReaderWriter/MachOLinkingContext.h
  vendor/lld/dist/lib/Driver/DarwinLdDriver.cpp
  vendor/lld/dist/lib/ReaderWriter/FileArchive.cpp
  vendor/lld/dist/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
  vendor/lld/dist/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
  vendor/lld/dist/lib/ReaderWriter/MachO/DebugInfo.h
  vendor/lld/dist/lib/ReaderWriter/MachO/GOTPass.cpp
  vendor/lld/dist/lib/ReaderWriter/MachO/LayoutPass.cpp
  vendor/lld/dist/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
  vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
  vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
  vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
  vendor/lld/dist/lib/ReaderWriter/MachO/ObjCPass.cpp
  vendor/lld/dist/lib/ReaderWriter/MachO/ShimPass.cpp
  vendor/lld/dist/lib/ReaderWriter/MachO/TLVPass.cpp
  vendor/lld/dist/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
  vendor/lld/dist/tools/lld/lld.cpp

Modified: vendor/lld/dist/CMakeLists.txt
==============================================================================
--- vendor/lld/dist/CMakeLists.txt	Wed Oct 23 17:52:41 2019	(r353949)
+++ vendor/lld/dist/CMakeLists.txt	Wed Oct 23 17:52:45 2019	(r353950)
@@ -56,7 +56,6 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
   include(HandleLLVMOptions)
 
   if(LLVM_INCLUDE_TESTS)
-    set(Python_ADDITIONAL_VERSIONS 2.7)
     include(FindPythonInterp)
     if(NOT PYTHONINTERP_FOUND)
       message(FATAL_ERROR

Modified: vendor/lld/dist/COFF/CMakeLists.txt
==============================================================================
--- vendor/lld/dist/COFF/CMakeLists.txt	Wed Oct 23 17:52:41 2019	(r353949)
+++ vendor/lld/dist/COFF/CMakeLists.txt	Wed Oct 23 17:52:45 2019	(r353950)
@@ -28,8 +28,10 @@ add_lld_library(lldCOFF
   BinaryFormat
   Core
   DebugInfoCodeView
+  DebugInfoDWARF
   DebugInfoMSF
   DebugInfoPDB
+  Demangle
   LibDriver
   LTO
   MC

Modified: vendor/lld/dist/COFF/Config.h
==============================================================================
--- vendor/lld/dist/COFF/Config.h	Wed Oct 23 17:52:41 2019	(r353949)
+++ vendor/lld/dist/COFF/Config.h	Wed Oct 23 17:52:45 2019	(r353950)
@@ -122,6 +122,7 @@ struct Configuration {
   bool dll = false;
   StringRef implib;
   std::vector<Export> exports;
+  bool hadExplicitExports;
   std::set<std::string> delayLoads;
   std::map<std::string, int> dllOrder;
   Symbol *delayLoadHelper = nullptr;
@@ -189,6 +190,10 @@ struct Configuration {
   // Used for /thinlto-object-suffix-replace:
   std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace;
 
+  // Used for /lto-obj-path:
+  llvm::StringRef ltoObjPath;
+
+  uint64_t align = 4096;
   uint64_t imageBase = -1;
   uint64_t fileAlign = 512;
   uint64_t stackReserve = 1024 * 1024;

Modified: vendor/lld/dist/COFF/DLL.cpp
==============================================================================
--- vendor/lld/dist/COFF/DLL.cpp	Wed Oct 23 17:52:41 2019	(r353949)
+++ vendor/lld/dist/COFF/DLL.cpp	Wed Oct 23 17:52:45 2019	(r353950)
@@ -135,7 +135,7 @@ class NullChunk : public NonSectionChunk { (private)
 static std::vector<std::vector<DefinedImportData *>>
 binImports(const std::vector<DefinedImportData *> &imports) {
   // Group DLL-imported symbols by DLL name because that's how
-  // symbols are layed out in the import descriptor table.
+  // symbols are laid out in the import descriptor table.
   auto less = [](const std::string &a, const std::string &b) {
     return config->dllOrder[a] < config->dllOrder[b];
   };
@@ -188,7 +188,7 @@ class DelayDirectoryChunk : public NonSectionChunk { (
 
 // Initial contents for delay-loaded functions.
 // This code calls __delayLoadHelper2 function to resolve a symbol
-// and then overwrites its jump table slot with the result
+// which then overwrites its jump table slot with the result
 // for subsequent function calls.
 static const uint8_t thunkX64[] = {
     0x48, 0x8D, 0x05, 0, 0, 0, 0,       // lea     rax, [__imp_<FUNCNAME>]

Modified: vendor/lld/dist/COFF/DebugTypes.cpp
==============================================================================
--- vendor/lld/dist/COFF/DebugTypes.cpp	Wed Oct 23 17:52:41 2019	(r353949)
+++ vendor/lld/dist/COFF/DebugTypes.cpp	Wed Oct 23 17:52:45 2019	(r353950)
@@ -17,11 +17,12 @@
 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
 #include "llvm/Support/Path.h"
 
-using namespace lld;
-using namespace lld::coff;
 using namespace llvm;
 using namespace llvm::codeview;
 
+namespace lld {
+namespace coff {
+
 namespace {
 // The TypeServerSource class represents a PDB type server, a file referenced by
 // OBJ files compiled with MSVC /Zi. A single PDB can be shared by several OBJ
@@ -96,27 +97,25 @@ TpiSource::TpiSource(TpiKind k, const ObjFile *f) : ki
   GC.push_back(std::unique_ptr<TpiSource>(this));
 }
 
-TpiSource *lld::coff::makeTpiSource(const ObjFile *f) {
+TpiSource *makeTpiSource(const ObjFile *f) {
   return new TpiSource(TpiSource::Regular, f);
 }
 
-TpiSource *lld::coff::makeUseTypeServerSource(const ObjFile *f,
+TpiSource *makeUseTypeServerSource(const ObjFile *f,
                                               const TypeServer2Record *ts) {
   TypeServerSource::enqueue(f, *ts);
   return new UseTypeServerSource(f, ts);
 }
 
-TpiSource *lld::coff::makePrecompSource(const ObjFile *f) {
+TpiSource *makePrecompSource(const ObjFile *f) {
   return new PrecompSource(f);
 }
 
-TpiSource *lld::coff::makeUsePrecompSource(const ObjFile *f,
+TpiSource *makeUsePrecompSource(const ObjFile *f,
                                            const PrecompRecord *precomp) {
   return new UsePrecompSource(f, precomp);
 }
 
-namespace lld {
-namespace coff {
 template <>
 const PrecompRecord &retrieveDependencyInfo(const TpiSource *source) {
   assert(source->kind == TpiSource::UsingPCH);
@@ -128,8 +127,6 @@ const TypeServer2Record &retrieveDependencyInfo(const 
   assert(source->kind == TpiSource::UsingPDB);
   return ((const UseTypeServerSource *)source)->typeServerDependency;
 }
-} // namespace coff
-} // namespace lld
 
 std::map<std::string, std::pair<std::string, TypeServerSource *>>
     TypeServerSource::instances;
@@ -210,8 +207,7 @@ TypeServerSource::findFromFile(const ObjFile *dependen
 
 // FIXME: Temporary interface until PDBLinker::maybeMergeTypeServerPDB() is
 // moved here.
-Expected<llvm::pdb::NativeSession *>
-lld::coff::findTypeServerSource(const ObjFile *f) {
+Expected<llvm::pdb::NativeSession *> findTypeServerSource(const ObjFile *f) {
   Expected<TypeServerSource *> ts = TypeServerSource::findFromFile(f);
   if (!ts)
     return ts.takeError();
@@ -231,7 +227,7 @@ void TypeServerSource::enqueue(const ObjFile *dependen
   if (!it.second)
     return; // another OBJ already scheduled this PDB for load
 
-  driver->enqueuePath(*p, false);
+  driver->enqueuePath(*p, false, false);
 }
 
 // Create an instance of TypeServerSource or an error string if the PDB couldn't
@@ -239,7 +235,7 @@ void TypeServerSource::enqueue(const ObjFile *dependen
 // will be merged in. NOTE - a PDB load failure is not a link error: some
 // debug info will simply be missing from the final PDB - that is the default
 // accepted behavior.
-void lld::coff::loadTypeServerSource(llvm::MemoryBufferRef m) {
+void loadTypeServerSource(llvm::MemoryBufferRef m) {
   std::string path = normalizePdbPath(m.getBufferIdentifier());
 
   Expected<TypeServerSource *> ts = TypeServerSource::getInstance(m);
@@ -266,3 +262,6 @@ Expected<TypeServerSource *> TypeServerSource::getInst
     return info.takeError();
   return new TypeServerSource(m, session.release());
 }
+
+} // namespace coff
+} // namespace lld

Modified: vendor/lld/dist/COFF/Driver.cpp
==============================================================================
--- vendor/lld/dist/COFF/Driver.cpp	Wed Oct 23 17:52:41 2019	(r353949)
+++ vendor/lld/dist/COFF/Driver.cpp	Wed Oct 23 17:52:45 2019	(r353950)
@@ -27,6 +27,7 @@
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/BinaryFormat/Magic.h"
+#include "llvm/LTO/LTO.h"
 #include "llvm/Object/ArchiveWriter.h"
 #include "llvm/Object/COFFImportFile.h"
 #include "llvm/Object/COFFModuleDefinition.h"
@@ -36,6 +37,7 @@
 #include "llvm/Option/Option.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/LEB128.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Process.h"
 #include "llvm/Support/TarWriter.h"
@@ -62,16 +64,16 @@ LinkerDriver *driver;
 bool link(ArrayRef<const char *> args, bool canExitEarly, raw_ostream &diag) {
   errorHandler().logName = args::getFilenameWithoutExe(args[0]);
   errorHandler().errorOS = &diag;
-  errorHandler().colorDiagnostics = diag.has_colors();
   errorHandler().errorLimitExceededMsg =
       "too many errors emitted, stopping now"
       " (use /errorlimit:0 to see all errors)";
   errorHandler().exitEarly = canExitEarly;
-  config = make<Configuration>();
+  enableColors(diag.has_colors());
 
+  config = make<Configuration>();
   symtab = make<SymbolTable>();
-
   driver = make<LinkerDriver>();
+
   driver->link(args);
 
   // Call exit() if we can to avoid calling destructors.
@@ -169,7 +171,7 @@ MemoryBufferRef LinkerDriver::takeBuffer(std::unique_p
 }
 
 void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb,
-                             bool wholeArchive) {
+                             bool wholeArchive, bool lazy) {
   StringRef filename = mb->getBufferIdentifier();
 
   MemoryBufferRef mbref = takeBuffer(std::move(mb));
@@ -184,19 +186,28 @@ void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuf
     if (wholeArchive) {
       std::unique_ptr<Archive> file =
           CHECK(Archive::create(mbref), filename + ": failed to parse archive");
+      Archive *archive = file.get();
+      make<std::unique_ptr<Archive>>(std::move(file)); // take ownership
 
-      for (MemoryBufferRef m : getArchiveMembers(file.get()))
-        addArchiveBuffer(m, "<whole-archive>", filename, 0);
+      int memberIndex = 0;
+      for (MemoryBufferRef m : getArchiveMembers(archive))
+        addArchiveBuffer(m, "<whole-archive>", filename, memberIndex++);
       return;
     }
     symtab->addFile(make<ArchiveFile>(mbref));
     break;
   case file_magic::bitcode:
-    symtab->addFile(make<BitcodeFile>(mbref, "", 0));
+    if (lazy)
+      symtab->addFile(make<LazyObjFile>(mbref));
+    else
+      symtab->addFile(make<BitcodeFile>(mbref, "", 0));
     break;
   case file_magic::coff_object:
   case file_magic::coff_import_library:
-    symtab->addFile(make<ObjFile>(mbref));
+    if (lazy)
+      symtab->addFile(make<LazyObjFile>(mbref));
+    else
+      symtab->addFile(make<ObjFile>(mbref));
     break;
   case file_magic::pdb:
     loadTypeServerSource(mbref);
@@ -217,7 +228,7 @@ void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuf
   }
 }
 
-void LinkerDriver::enqueuePath(StringRef path, bool wholeArchive) {
+void LinkerDriver::enqueuePath(StringRef path, bool wholeArchive, bool lazy) {
   auto future =
       std::make_shared<std::future<MBErrPair>>(createFutureForFile(path));
   std::string pathStr = path;
@@ -237,7 +248,7 @@ void LinkerDriver::enqueuePath(StringRef path, bool wh
       else
         error(msg + "; did you mean '" + nearest + "'");
     } else
-      driver->addBuffer(std::move(mbOrErr.first), wholeArchive);
+      driver->addBuffer(std::move(mbOrErr.first), wholeArchive, lazy);
   });
 }
 
@@ -268,13 +279,12 @@ void LinkerDriver::addArchiveBuffer(MemoryBufferRef mb
 }
 
 void LinkerDriver::enqueueArchiveMember(const Archive::Child &c,
-                                        StringRef symName,
+                                        const Archive::Symbol &sym,
                                         StringRef parentName) {
 
-  auto reportBufferError = [=](Error &&e,
-                              StringRef childName) {
+  auto reportBufferError = [=](Error &&e, StringRef childName) {
     fatal("could not get the buffer for the member defining symbol " +
-          symName + ": " + parentName + "(" + childName + "): " +
+          toCOFFString(sym) + ": " + parentName + "(" + childName + "): " +
           toString(std::move(e)));
   };
 
@@ -285,7 +295,8 @@ void LinkerDriver::enqueueArchiveMember(const Archive:
       reportBufferError(mbOrErr.takeError(), check(c.getFullName()));
     MemoryBufferRef mb = mbOrErr.get();
     enqueueTask([=]() {
-      driver->addArchiveBuffer(mb, symName, parentName, offsetInArchive);
+      driver->addArchiveBuffer(mb, toCOFFString(sym), parentName,
+                               offsetInArchive);
     });
     return;
   }
@@ -293,15 +304,17 @@ void LinkerDriver::enqueueArchiveMember(const Archive:
   std::string childName = CHECK(
       c.getFullName(),
       "could not get the filename for the member defining symbol " +
-      symName);
+      toCOFFString(sym));
   auto future = std::make_shared<std::future<MBErrPair>>(
       createFutureForFile(childName));
   enqueueTask([=]() {
     auto mbOrErr = future->get();
     if (mbOrErr.second)
       reportBufferError(errorCodeToError(mbOrErr.second), childName);
-    driver->addArchiveBuffer(takeBuffer(std::move(mbOrErr.first)), symName,
-                             parentName, /* OffsetInArchive */ 0);
+    // Pass empty string as archive name so that the original filename is
+    // used as the buffer identifier.
+    driver->addArchiveBuffer(takeBuffer(std::move(mbOrErr.first)),
+                             toCOFFString(sym), "", /*OffsetInArchive=*/0);
   });
 }
 
@@ -355,7 +368,7 @@ void LinkerDriver::parseDirectives(InputFile *file) {
       break;
     case OPT_defaultlib:
       if (Optional<StringRef> path = findLib(arg->getValue()))
-        enqueuePath(*path, false);
+        enqueuePath(*path, false, false);
       break;
     case OPT_entry:
       config->entry = addUndefined(mangle(arg->getValue()));
@@ -590,6 +603,7 @@ static std::string createResponseFile(const opt::Input
   for (auto *arg : args) {
     switch (arg->getOption().getID()) {
     case OPT_linkrepro:
+    case OPT_reproduce:
     case OPT_INPUT:
     case OPT_defaultlib:
     case OPT_libpath:
@@ -704,9 +718,8 @@ static std::string getImplibPath() {
   return out.str();
 }
 
+// The import name is calculated as follows:
 //
-// The import name is caculated as the following:
-//
 //        | LIBRARY w/ ext |   LIBRARY w/o ext   | no LIBRARY
 //   -----+----------------+---------------------+------------------
 //   LINK | {value}        | {value}.{.dll/.exe} | {output name}
@@ -987,30 +1000,37 @@ static void parsePDBAltPath(StringRef altPath) {
   config->pdbAltPath = buf;
 }
 
-/// Check that at most one resource obj file was used.
+/// Convert resource files and potentially merge input resource object
+/// trees into one resource tree.
 /// Call after ObjFile::Instances is complete.
-static void diagnoseMultipleResourceObjFiles() {
-  // The .rsrc$01 section in a resource obj file contains a tree description
-  // of resources.  Merging multiple resource obj files would require merging
-  // the trees instead of using usual linker section merging semantics.
-  // Since link.exe disallows linking more than one resource obj file with
-  // LNK4078, mirror that.  The normal use of resource files is to give the
-  // linker many .res files, which are then converted to a single resource obj
-  // file internally, so this is not a big restriction in practice.
-  ObjFile *resourceObjFile = nullptr;
+void LinkerDriver::convertResources() {
+  std::vector<ObjFile *> resourceObjFiles;
+
   for (ObjFile *f : ObjFile::instances) {
-    if (!f->isResourceObjFile)
-      continue;
+    if (f->isResourceObjFile())
+      resourceObjFiles.push_back(f);
+  }
 
-    if (!resourceObjFile) {
-      resourceObjFile = f;
-      continue;
-    }
-
-    error(toString(f) +
+  if (!config->mingw &&
+      (resourceObjFiles.size() > 1 ||
+       (resourceObjFiles.size() == 1 && !resources.empty()))) {
+    error((!resources.empty() ? "internal .obj file created from .res files"
+                              : toString(resourceObjFiles[1])) +
           ": more than one resource obj file not allowed, already got " +
-          toString(resourceObjFile));
+          toString(resourceObjFiles.front()));
+    return;
   }
+
+  if (resources.empty() && resourceObjFiles.size() <= 1) {
+    // No resources to convert, and max one resource object file in
+    // the input. Keep that preconverted resource section as is.
+    for (ObjFile *f : resourceObjFiles)
+      f->includeResourceChunks();
+    return;
+  }
+  ObjFile *f = make<ObjFile>(convertResToCOFF(resources, resourceObjFiles));
+  symtab->addFile(f);
+  f->includeResourceChunks();
 }
 
 // In MinGW, if no symbols are chosen to be exported, then all symbols are
@@ -1051,6 +1071,26 @@ void LinkerDriver::maybeExportMinGWSymbols(const opt::
   });
 }
 
+// lld has a feature to create a tar file containing all input files as well as
+// all command line options, so that other people can run lld again with exactly
+// the same inputs. This feature is accessible via /linkrepro and /reproduce.
+//
+// /linkrepro and /reproduce are very similar, but /linkrepro takes a directory
+// name while /reproduce takes a full path. We have /linkrepro for compatibility
+// with Microsoft link.exe.
+Optional<std::string> getReproduceFile(const opt::InputArgList &args) {
+  if (auto *arg = args.getLastArg(OPT_reproduce))
+    return std::string(arg->getValue());
+
+  if (auto *arg = args.getLastArg(OPT_linkrepro)) {
+    SmallString<64> path = StringRef(arg->getValue());
+    sys::path::append(path, "repro.tar");
+    return path.str().str();
+  }
+
+  return None;
+}
+
 void LinkerDriver::link(ArrayRef<const char *> argsArr) {
   // Needed for LTO.
   InitializeAllTargetInfos();
@@ -1069,7 +1109,7 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
 
   // Parse command line options.
   ArgParser parser;
-  opt::InputArgList args = parser.parseLINK(argsArr);
+  opt::InputArgList args = parser.parse(argsArr);
 
   // Parse and evaluate -mllvm options.
   std::vector<const char *> v;
@@ -1113,17 +1153,15 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
   // options are handled.
   config->mingw = args.hasArg(OPT_lldmingw);
 
-  if (auto *arg = args.getLastArg(OPT_linkrepro)) {
-    SmallString<64> path = StringRef(arg->getValue());
-    sys::path::append(path, "repro.tar");
-
+  // Handle /linkrepro and /reproduce.
+  if (Optional<std::string> path = getReproduceFile(args)) {
     Expected<std::unique_ptr<TarWriter>> errOrWriter =
-        TarWriter::create(path, "repro");
+        TarWriter::create(*path, sys::path::stem(*path));
 
     if (errOrWriter) {
       tar = std::move(*errOrWriter);
     } else {
-      error("/linkrepro: failed to open " + path + ": " +
+      error("/linkrepro: failed to open " + *path + ": " +
             toString(errOrWriter.takeError()));
     }
   }
@@ -1139,7 +1177,8 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
   searchPaths.push_back("");
   for (auto *arg : args.filtered(OPT_libpath))
     searchPaths.push_back(arg->getValue());
-  addLibSearchPaths();
+  if (!args.hasArg(OPT_lldignoreenv))
+    addLibSearchPaths();
 
   // Handle /ignore
   for (auto *arg : args.filtered(OPT_ignore)) {
@@ -1419,6 +1458,13 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
   for (auto *arg : args.filtered(OPT_section))
     parseSection(arg->getValue());
 
+  // Handle /align
+  if (auto *arg = args.getLastArg(OPT_align)) {
+    parseNumbers(arg->getValue(), &config->align);
+    if (!isPowerOf2_64(config->align))
+      error("/align: not a power of two: " + StringRef(arg->getValue()));
+  }
+
   // Handle /aligncomm
   for (auto *arg : args.filtered(OPT_aligncomm))
     parseAligncomm(arg->getValue());
@@ -1464,6 +1510,7 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
       getOldNewOptions(args, OPT_thinlto_prefix_replace);
   config->thinLTOObjectSuffixReplace =
       getOldNewOptions(args, OPT_thinlto_object_suffix_replace);
+  config->ltoObjPath = args.getLastArgValue(OPT_lto_obj_path);
   // Handle miscellaneous boolean flags.
   config->allowBind = args.hasFlag(OPT_allowbind, OPT_allowbind_no, true);
   config->allowIsolation =
@@ -1528,19 +1575,45 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
     return false;
   };
 
-  // Create a list of input files. Files can be given as arguments
-  // for /defaultlib option.
-  for (auto *arg : args.filtered(OPT_INPUT, OPT_wholearchive_file))
-    if (Optional<StringRef> path = findFile(arg->getValue()))
-      enqueuePath(*path, isWholeArchive(*path));
+  // Create a list of input files. These can be given as OPT_INPUT options
+  // and OPT_wholearchive_file options, and we also need to track OPT_start_lib
+  // and OPT_end_lib.
+  bool inLib = false;
+  for (auto *arg : args) {
+    switch (arg->getOption().getID()) {
+    case OPT_end_lib:
+      if (!inLib)
+        error("stray " + arg->getSpelling());
+      inLib = false;
+      break;
+    case OPT_start_lib:
+      if (inLib)
+        error("nested " + arg->getSpelling());
+      inLib = true;
+      break;
+    case OPT_wholearchive_file:
+      if (Optional<StringRef> path = findFile(arg->getValue()))
+        enqueuePath(*path, true, inLib);
+      break;
+    case OPT_INPUT:
+      if (Optional<StringRef> path = findFile(arg->getValue()))
+        enqueuePath(*path, isWholeArchive(*path), inLib);
+      break;
+    default:
+      // Ignore other options.
+      break;
+    }
+  }
 
+  // Process files specified as /defaultlib. These should be enequeued after
+  // other files, which is why they are in a separate loop.
   for (auto *arg : args.filtered(OPT_defaultlib))
     if (Optional<StringRef> path = findLib(arg->getValue()))
-      enqueuePath(*path, false);
+      enqueuePath(*path, false, false);
 
   // Windows specific -- Create a resource file containing a manifest file.
   if (config->manifest == Configuration::Embed)
-    addBuffer(createManifestRes(), false);
+    addBuffer(createManifestRes(), false, false);
 
   // Read all input files given via the command line.
   run();
@@ -1565,12 +1638,6 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
   for (auto *arg : args.filtered(OPT_functionpadmin, OPT_functionpadmin_opt))
     parseFunctionPadMin(arg, config->machine);
 
-  // Input files can be Windows resource files (.res files). We use
-  // WindowsResource to convert resource files to a regular COFF file,
-  // then link the resulting file normally.
-  if (!resources.empty())
-    symtab->addFile(make<ObjFile>(convertResToCOFF(resources)));
-
   if (tar)
     tar->append("response.txt",
                 createResponseFile(args, filePaths,
@@ -1746,33 +1813,24 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
           u->weakAlias = symtab->addUndefined(to);
     }
 
+    // If any inputs are bitcode files, the LTO code generator may create
+    // references to library functions that are not explicit in the bitcode
+    // file's symbol table. If any of those library functions are defined in a
+    // bitcode file in an archive member, we need to arrange to use LTO to
+    // compile those archive members by adding them to the link beforehand.
+    if (!BitcodeFile::instances.empty())
+      for (auto *s : lto::LTO::getRuntimeLibcallSymbols())
+        symtab->addLibcall(s);
+
     // Windows specific -- if __load_config_used can be resolved, resolve it.
     if (symtab->findUnderscore("_load_config_used"))
       addUndefined(mangle("_load_config_used"));
   } while (run());
 
-  if (errorCount())
-    return;
-
-  // Do LTO by compiling bitcode input files to a set of native COFF files then
-  // link those files (unless -thinlto-index-only was given, in which case we
-  // resolve symbols and write indices, but don't generate native code or link).
-  symtab->addCombinedLTOObjects();
-
-  // If -thinlto-index-only is given, we should create only "index
-  // files" and not object files. Index file creation is already done
-  // in addCombinedLTOObject, so we are done if that's the case.
-  if (config->thinLTOIndexOnly)
-    return;
-
-  // If we generated native object files from bitcode files, this resolves
-  // references to the symbols we use from them.
-  run();
-
   if (args.hasArg(OPT_include_optional)) {
     // Handle /includeoptional
     for (auto *arg : args.filtered(OPT_include_optional))
-      if (dyn_cast_or_null<Lazy>(symtab->find(arg->getValue())))
+      if (dyn_cast_or_null<LazyArchive>(symtab->find(arg->getValue())))
         addUndefined(arg->getValue());
     while (run());
   }
@@ -1795,11 +1853,36 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
     run();
   }
 
-  // Make sure we have resolved all symbols.
-  symtab->reportRemainingUndefines();
+  // At this point, we should not have any symbols that cannot be resolved.
+  // If we are going to do codegen for link-time optimization, check for
+  // unresolvable symbols first, so we don't spend time generating code that
+  // will fail to link anyway.
+  if (!BitcodeFile::instances.empty() && !config->forceUnresolved)
+    symtab->reportUnresolvable();
   if (errorCount())
     return;
 
+  // Do LTO by compiling bitcode input files to a set of native COFF files then
+  // link those files (unless -thinlto-index-only was given, in which case we
+  // resolve symbols and write indices, but don't generate native code or link).
+  symtab->addCombinedLTOObjects();
+
+  // If -thinlto-index-only is given, we should create only "index
+  // files" and not object files. Index file creation is already done
+  // in addCombinedLTOObject, so we are done if that's the case.
+  if (config->thinLTOIndexOnly)
+    return;
+
+  // If we generated native object files from bitcode files, this resolves
+  // references to the symbols we use from them.
+  run();
+
+  // Resolve remaining undefined symbols and warn about imported locals.
+  symtab->resolveRemainingUndefines();
+  if (errorCount())
+    return;
+
+  config->hadExplicitExports = !config->exports.empty();
   if (config->mingw) {
     // In MinGW, all symbols are automatically exported if no symbols
     // are chosen to be exported.
@@ -1823,10 +1906,12 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
   }
 
   // Windows specific -- when we are creating a .dll file, we also
-  // need to create a .lib file.
+  // need to create a .lib file. In MinGW mode, we only do that when the
+  // -implib option is given explicitly, for compatibility with GNU ld.
   if (!config->exports.empty() || config->dll) {
     fixupExports();
-    createImportLibrary(/*asLib=*/false);
+    if (!config->mingw || !config->implib.empty())
+      createImportLibrary(/*asLib=*/false);
     assignExportOrdinals();
   }
 
@@ -1870,7 +1955,7 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr
     markLive(symtab->getChunks());
 
   // Needs to happen after the last call to addFile().
-  diagnoseMultipleResourceObjFiles();
+  convertResources();
 
   // Identify identical COMDAT sections to merge them.
   if (config->doICF) {

Modified: vendor/lld/dist/COFF/Driver.h
==============================================================================
--- vendor/lld/dist/COFF/Driver.h	Wed Oct 23 17:52:41 2019	(r353949)
+++ vendor/lld/dist/COFF/Driver.h	Wed Oct 23 17:52:45 2019	(r353950)
@@ -43,8 +43,8 @@ class COFFOptTable : public llvm::opt::OptTable { (pub
 
 class ArgParser {
 public:
-  // Concatenate LINK environment variable and given arguments and parse them.
-  llvm::opt::InputArgList parseLINK(std::vector<const char *> args);
+  // Parses command line options.
+  llvm::opt::InputArgList parse(llvm::ArrayRef<const char *> args);
 
   // Tokenizes a given string and then parses as command line options.
   llvm::opt::InputArgList parse(StringRef s) { return parse(tokenize(s)); }
@@ -56,8 +56,8 @@ class ArgParser { (public)
   parseDirectives(StringRef s);
 
 private:
-  // Parses command line options.
-  llvm::opt::InputArgList parse(llvm::ArrayRef<const char *> args);
+  // Concatenate LINK environment variable.
+  void addLINK(SmallVector<const char *, 256> &argv);
 
   std::vector<const char *> tokenize(StringRef s);
 
@@ -72,12 +72,12 @@ class LinkerDriver { (public)
   void parseDirectives(InputFile *file);
 
   // Used by ArchiveFile to enqueue members.
-  void enqueueArchiveMember(const Archive::Child &c, StringRef symName,
+  void enqueueArchiveMember(const Archive::Child &c, const Archive::Symbol &sym,
                             StringRef parentName);
 
   MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> mb);
 
-  void enqueuePath(StringRef path, bool wholeArchive);
+  void enqueuePath(StringRef path, bool wholeArchive, bool lazy);
 
 private:
   std::unique_ptr<llvm::TarWriter> tar; // for /linkrepro
@@ -98,6 +98,10 @@ class LinkerDriver { (public)
   // Library search path. The first element is always "" (current directory).
   std::vector<StringRef> searchPaths;
 
+  // Convert resource files and potentially merge input resource object
+  // trees into one resource tree.
+  void convertResources();
+
   void maybeExportMinGWSymbols(const llvm::opt::InputArgList &args);
 
   // We don't want to add the same file more than once.
@@ -120,7 +124,8 @@ class LinkerDriver { (public)
   StringRef findDefaultEntry();
   WindowsSubsystem inferSubsystem();
 
-  void addBuffer(std::unique_ptr<MemoryBuffer> mb, bool wholeArchive);
+  void addBuffer(std::unique_ptr<MemoryBuffer> mb, bool wholeArchive,
+                 bool lazy);
   void addArchiveBuffer(MemoryBufferRef mbref, StringRef symName,
                         StringRef parentName, uint64_t offsetInArchive);
 
@@ -184,7 +189,8 @@ void assignExportOrdinals();
 void checkFailIfMismatch(StringRef arg, InputFile *source);
 
 // Convert Windows resource files (.res files) to a .obj file.
-MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs);
+MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs,
+                                 ArrayRef<ObjFile *> objs);
 
 void runMSVCLinker(std::string rsp, ArrayRef<StringRef> objects);
 

Modified: vendor/lld/dist/COFF/DriverUtils.cpp
==============================================================================
--- vendor/lld/dist/COFF/DriverUtils.cpp	Wed Oct 23 17:52:41 2019	(r353949)
+++ vendor/lld/dist/COFF/DriverUtils.cpp	Wed Oct 23 17:52:45 2019	(r353950)
@@ -322,7 +322,7 @@ class TemporaryFile { (public)
 
     if (!contents.empty()) {
       std::error_code ec;
-      raw_fd_ostream os(path, ec, sys::fs::F_None);
+      raw_fd_ostream os(path, ec, sys::fs::OF_None);
       if (ec)
         fatal("failed to open " + path + ": " + ec.message());
       os << contents;
@@ -410,7 +410,7 @@ static std::string createManifestXmlWithExternalMt(Str
   // Create the default manifest file as a temporary file.
   TemporaryFile Default("defaultxml", "manifest");
   std::error_code ec;
-  raw_fd_ostream os(Default.path, ec, sys::fs::F_Text);
+  raw_fd_ostream os(Default.path, ec, sys::fs::OF_Text);
   if (ec)
     fatal("failed to open " + Default.path + ": " + ec.message());
   os << defaultXml;
@@ -511,7 +511,7 @@ void createSideBySideManifest() {
   if (path == "")
     path = config->outputFile + ".manifest";
   std::error_code ec;
-  raw_fd_ostream out(path, ec, sys::fs::F_Text);
+  raw_fd_ostream out(path, ec, sys::fs::OF_Text);
   if (ec)
     fatal("failed to create manifest: " + ec.message());
   out << createManifestXml();
@@ -700,26 +700,42 @@ void checkFailIfMismatch(StringRef arg, InputFile *sou
 
 // Convert Windows resource files (.res files) to a .obj file.
 // Does what cvtres.exe does, but in-process and cross-platform.
-MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs) {
-  object::WindowsResourceParser parser;
+MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs,
+                                 ArrayRef<ObjFile *> objs) {
+  object::WindowsResourceParser parser(/* MinGW */ config->mingw);
 
+  std::vector<std::string> duplicates;
   for (MemoryBufferRef mb : mbs) {
     std::unique_ptr<object::Binary> bin = check(object::createBinary(mb));
     object::WindowsResource *rf = dyn_cast<object::WindowsResource>(bin.get());
     if (!rf)
       fatal("cannot compile non-resource file as resource");
 
-    std::vector<std::string> duplicates;
     if (auto ec = parser.parse(rf, duplicates))
       fatal(toString(std::move(ec)));
+  }
 
-    for (const auto &dupeDiag : duplicates)
-      if (config->forceMultipleRes)
-        warn(dupeDiag);
-      else
-        error(dupeDiag);
+  // Note: This processes all .res files before all objs. Ideally they'd be
+  // handled in the same order they were linked (to keep the right one, if
+  // there are duplicates that are tolerated due to forceMultipleRes).
+  for (ObjFile *f : objs) {
+    object::ResourceSectionRef rsf;
+    if (auto ec = rsf.load(f->getCOFFObj()))
+      fatal(toString(f) + ": " + toString(std::move(ec)));
+
+    if (auto ec = parser.parse(rsf, f->getName(), duplicates))
+      fatal(toString(std::move(ec)));
   }
 
+  if (config->mingw)
+    parser.cleanUpManifests(duplicates);
+
+  for (const auto &dupeDiag : duplicates)
+    if (config->forceMultipleRes)
+      warn(dupeDiag);
+    else
+      error(dupeDiag);
+
   Expected<std::unique_ptr<MemoryBuffer>> e =
       llvm::object::writeWindowsResourceCOFF(config->machine, parser,
                                              config->timestamp);
@@ -757,15 +773,15 @@ static void handleColorDiagnostics(opt::InputArgList &
   if (!arg)
     return;
   if (arg->getOption().getID() == OPT_color_diagnostics) {
-    errorHandler().colorDiagnostics = true;
+    enableColors(true);
   } else if (arg->getOption().getID() == OPT_no_color_diagnostics) {
-    errorHandler().colorDiagnostics = false;
+    enableColors(false);
   } else {
     StringRef s = arg->getValue();
     if (s == "always")
-      errorHandler().colorDiagnostics = true;
+      enableColors(true);
     else if (s == "never")
-      errorHandler().colorDiagnostics = false;
+      enableColors(false);
     else if (s != "auto")
       error("unknown option: --color-diagnostics=" + s);
   }
@@ -792,13 +808,17 @@ opt::InputArgList ArgParser::parse(ArrayRef<const char
 
   // We need to get the quoting style for response files before parsing all
   // options so we parse here before and ignore all the options but
-  // --rsp-quoting.
+  // --rsp-quoting and /lldignoreenv.
+  // (This means --rsp-quoting can't be added through %LINK%.)
   opt::InputArgList args = table.ParseArgs(argv, missingIndex, missingCount);
 
-  // Expand response files (arguments in the form of @<filename>)
-  // and then parse the argument again.
+
+  // Expand response files (arguments in the form of @<filename>) and insert
+  // flags from %LINK% and %_LINK_%, and then parse the argument again.
   SmallVector<const char *, 256> expandedArgv(argv.data(),
                                               argv.data() + argv.size());
+  if (!args.hasArg(OPT_lldignoreenv))
+    addLINK(expandedArgv);
   cl::ExpandResponseFiles(saver, getQuotingStyle(args), expandedArgv);
   args = table.ParseArgs(makeArrayRef(expandedArgv).drop_front(), missingIndex,
                          missingCount);
@@ -868,7 +888,7 @@ ArgParser::parseDirectives(StringRef s) {
 // link.exe has an interesting feature. If LINK or _LINK_ environment
 // variables exist, their contents are handled as command line strings.
 // So you can pass extra arguments using them.
-opt::InputArgList ArgParser::parseLINK(std::vector<const char *> argv) {
+void ArgParser::addLINK(SmallVector<const char *, 256> &argv) {
   // Concatenate LINK env and command line arguments, and then parse them.
   if (Optional<std::string> s = Process::GetEnv("LINK")) {
     std::vector<const char *> v = tokenize(*s);
@@ -878,7 +898,6 @@ opt::InputArgList ArgParser::parseLINK(std::vector<con
     std::vector<const char *> v = tokenize(*s);
     argv.insert(std::next(argv.begin()), v.begin(), v.end());
   }
-  return parse(argv);
 }
 
 std::vector<const char *> ArgParser::tokenize(StringRef s) {

Modified: vendor/lld/dist/COFF/ICF.cpp
==============================================================================
--- vendor/lld/dist/COFF/ICF.cpp	Wed Oct 23 17:52:41 2019	(r353949)
+++ vendor/lld/dist/COFF/ICF.cpp	Wed Oct 23 17:52:45 2019	(r353950)
@@ -13,7 +13,7 @@
 //
 // On Windows, ICF is enabled by default.
 //
-// See ELF/ICF.cpp for the details about the algortihm.
+// See ELF/ICF.cpp for the details about the algorithm.
 //
 //===----------------------------------------------------------------------===//
 
@@ -77,7 +77,7 @@ class ICF { (private)
 // section is insignificant to the user program and the behaviour matches that
 // of the Visual C++ linker.
 bool ICF::isEligible(SectionChunk *c) {
-  // Non-comdat chunks, dead chunks, and writable chunks are not elegible.
+  // Non-comdat chunks, dead chunks, and writable chunks are not eligible.
   bool writable = c->getOutputCharacteristics() & llvm::COFF::IMAGE_SCN_MEM_WRITE;
   if (!c->isCOMDAT() || !c->live || writable)
     return false;
@@ -274,7 +274,7 @@ void ICF::run(ArrayRef<Chunk *> vec) {
       for (Symbol *b : sc->symbols())
         if (auto *sym = dyn_cast_or_null<DefinedRegular>(b))
           hash += sym->getChunk()->eqClass[cnt % 2];
-      // Set MSB to 1 to avoid collisions with non-hash classs.
+      // Set MSB to 1 to avoid collisions with non-hash classes.
       sc->eqClass[(cnt + 1) % 2] = hash | (1U << 31);
     });
   }
@@ -297,7 +297,7 @@ void ICF::run(ArrayRef<Chunk *> vec) {
 
   log("ICF needed " + Twine(cnt) + " iterations");
 
-  // Merge sections in the same classs.
+  // Merge sections in the same classes.
   forEachClass([&](size_t begin, size_t end) {
     if (end - begin == 1)
       return;

Modified: vendor/lld/dist/COFF/InputFiles.cpp
==============================================================================
--- vendor/lld/dist/COFF/InputFiles.cpp	Wed Oct 23 17:52:41 2019	(r353949)
+++ vendor/lld/dist/COFF/InputFiles.cpp	Wed Oct 23 17:52:45 2019	(r353950)
@@ -47,6 +47,24 @@ using llvm::Triple;
 using llvm::support::ulittle32_t;
 
 namespace lld {
+
+// Returns the last element of a path, which is supposed to be a filename.
+static StringRef getBasename(StringRef path) {
+  return sys::path::filename(path, sys::path::Style::windows);
+}
+
+// Returns a string in the format of "foo.obj" or "foo.obj(bar.lib)".
+std::string toString(const coff::InputFile *file) {
+  if (!file)
+    return "<internal>";
+  if (file->parentName.empty() || file->kind() == coff::InputFile::ImportKind)
+    return file->getName();
+
+  return (getBasename(file->parentName) + "(" + getBasename(file->getName()) +
+          ")")
+      .str();
+}
+
 namespace coff {
 
 std::vector<ObjFile *> ObjFile::instances;
@@ -73,6 +91,10 @@ static void checkAndSetWeakAlias(SymbolTable *symtab, 
   }
 }
 
+static bool ignoredSymbolName(StringRef name) {
+  return name == "@feat.00" || name == "@comp.id";
+}
+
 ArchiveFile::ArchiveFile(MemoryBufferRef m) : InputFile(ArchiveKind, m) {}
 
 void ArchiveFile::parse() {
@@ -81,20 +103,20 @@ void ArchiveFile::parse() {
 
   // Read the symbol table to construct Lazy objects.
   for (const Archive::Symbol &sym : file->symbols())
-    symtab->addLazy(this, sym);
+    symtab->addLazyArchive(this, sym);
 }
 
 // Returns a buffer pointing to a member file containing a given symbol.
-void ArchiveFile::addMember(const Archive::Symbol *sym) {
+void ArchiveFile::addMember(const Archive::Symbol &sym) {
   const Archive::Child &c =
-      CHECK(sym->getMember(),
-            "could not get the member for symbol " + sym->getName());
+      CHECK(sym.getMember(),
+            "could not get the member for symbol " + toCOFFString(sym));
 
   // Return an empty buffer if we have already returned the same buffer.
   if (!seen.insert(c.getChildOffset()).second)
     return;
 
-  driver->enqueueArchiveMember(c, sym->getName(), getName());
+  driver->enqueueArchiveMember(c, sym, getName());
 }
 
 std::vector<MemoryBufferRef> getArchiveMembers(Archive *file) {
@@ -116,6 +138,49 @@ std::vector<MemoryBufferRef> getArchiveMembers(Archive
   return v;
 }
 
+void LazyObjFile::fetch() {
+  if (mb.getBuffer().empty())
+    return;
+
+  InputFile *file;
+  if (isBitcode(mb))
+    file = make<BitcodeFile>(mb, "", 0, std::move(symbols));
+  else
+    file = make<ObjFile>(mb, std::move(symbols));
+  mb = {};
+  symtab->addFile(file);
+}
+
+void LazyObjFile::parse() {
+  if (isBitcode(this->mb)) {
+    // Bitcode file.
+    std::unique_ptr<lto::InputFile> obj =
+        CHECK(lto::InputFile::create(this->mb), this);
+    for (const lto::InputFile::Symbol &sym : obj->symbols()) {
+      if (!sym.isUndefined())
+        symtab->addLazyObject(this, sym.getName());
+    }
+    return;
+  }
+
+  // Native object file.
+  std::unique_ptr<Binary> coffObjPtr = CHECK(createBinary(mb), this);
+  COFFObjectFile *coffObj = cast<COFFObjectFile>(coffObjPtr.get());
+  uint32_t numSymbols = coffObj->getNumberOfSymbols();
+  for (uint32_t i = 0; i < numSymbols; ++i) {
+    COFFSymbolRef coffSym = check(coffObj->getSymbol(i));
+    if (coffSym.isUndefined() || !coffSym.isExternal() ||
+        coffSym.isWeakExternal())
+      continue;
+    StringRef name;

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



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