Merge 14aa57da0 for LLVM update to 353983

Change-Id: Iee1792355bab030d81eb4cb645257dbac2537641
diff --git a/COFF/Chunks.cpp b/COFF/Chunks.cpp
index 29131d7..8c73bda 100644
--- a/COFF/Chunks.cpp
+++ b/COFF/Chunks.cpp
@@ -1,9 +1,8 @@
 //===- Chunks.cpp ---------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -199,6 +198,7 @@
   case IMAGE_REL_ARM_BLX23T:    applyBranch24T(Off, SX - P - 4); break;
   case IMAGE_REL_ARM_SECTION:   applySecIdx(Off, OS); break;
   case IMAGE_REL_ARM_SECREL:    applySecRel(this, Off, OS, S); break;
+  case IMAGE_REL_ARM_REL32:     add32(Off, SX - P - 4); break;
   default:
     error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
           toString(File));
@@ -310,6 +310,7 @@
   case IMAGE_REL_ARM64_SECREL_HIGH12A: applySecRelHigh12A(this, Off, OS, S); break;
   case IMAGE_REL_ARM64_SECREL_LOW12L:  applySecRelLdr(this, Off, OS, S); break;
   case IMAGE_REL_ARM64_SECTION:        applySecIdx(Off, OS); break;
+  case IMAGE_REL_ARM64_REL32:          add32(Off, S - P - 4); break;
   default:
     error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
           toString(File));
@@ -669,18 +670,38 @@
     0xe7, 0x44,             // L1: add  pc, ip
 };
 
-size_t RangeExtensionThunk::getSize() const {
+size_t RangeExtensionThunkARM::getSize() const {
   assert(Config->Machine == ARMNT);
   return sizeof(ArmThunk);
 }
 
-void RangeExtensionThunk::writeTo(uint8_t *Buf) const {
+void RangeExtensionThunkARM::writeTo(uint8_t *Buf) const {
   assert(Config->Machine == ARMNT);
   uint64_t Offset = Target->getRVA() - RVA - 12;
   memcpy(Buf + OutputSectionOff, ArmThunk, sizeof(ArmThunk));
   applyMOV32T(Buf + OutputSectionOff, uint32_t(Offset));
 }
 
+// A position independent ARM64 adrp+add thunk, with a maximum range of
+// +/- 4 GB, which is enough for any PE-COFF.
+const uint8_t Arm64Thunk[] = {
+    0x10, 0x00, 0x00, 0x90, // adrp x16, Dest
+    0x10, 0x02, 0x00, 0x91, // add  x16, x16, :lo12:Dest
+    0x00, 0x02, 0x1f, 0xd6, // br   x16
+};
+
+size_t RangeExtensionThunkARM64::getSize() const {
+  assert(Config->Machine == ARM64);
+  return sizeof(Arm64Thunk);
+}
+
+void RangeExtensionThunkARM64::writeTo(uint8_t *Buf) const {
+  assert(Config->Machine == ARM64);
+  memcpy(Buf + OutputSectionOff, Arm64Thunk, sizeof(Arm64Thunk));
+  applyArm64Addr(Buf + OutputSectionOff + 0, Target->getRVA(), RVA, 12);
+  applyArm64Imm(Buf + OutputSectionOff + 4, Target->getRVA() & 0xfff, 0);
+}
+
 void LocalImportChunk::getBaserels(std::vector<Baserel> *Res) {
   Res->emplace_back(getRVA());
 }
diff --git a/COFF/Chunks.h b/COFF/Chunks.h
index 5f2d806..954c753 100644
--- a/COFF/Chunks.h
+++ b/COFF/Chunks.h
@@ -1,9 +1,8 @@
 //===- Chunks.h -------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -224,6 +223,9 @@
   // The COMDAT leader symbol if this is a COMDAT chunk.
   DefinedRegular *Sym = nullptr;
 
+  // The COMDAT selection if this is a COMDAT chunk.
+  llvm::COFF::COMDATType Selection = (llvm::COFF::COMDATType)0;
+
   ArrayRef<coff_relocation> Relocs;
 
   // Used by the garbage collector.
@@ -311,7 +313,7 @@
 };
 
 // Windows-specific.
-// A chunk for DLL import jump table entry. In a final output, it's
+// A chunk for DLL import jump table entry. In a final output, its
 // contents will be a JMP instruction to some __imp_ symbol.
 class ImportThunkChunkX64 : public Chunk {
 public:
@@ -355,9 +357,18 @@
   Defined *ImpSymbol;
 };
 
-class RangeExtensionThunk : public Chunk {
+class RangeExtensionThunkARM : public Chunk {
 public:
-  explicit RangeExtensionThunk(Defined *T) : Target(T) {}
+  explicit RangeExtensionThunkARM(Defined *T) : Target(T) {}
+  size_t getSize() const override;
+  void writeTo(uint8_t *Buf) const override;
+
+  Defined *Target;
+};
+
+class RangeExtensionThunkARM64 : public Chunk {
+public:
+  explicit RangeExtensionThunkARM64(Defined *T) : Target(T) {}
   size_t getSize() const override;
   void writeTo(uint8_t *Buf) const override;
 
diff --git a/COFF/Config.h b/COFF/Config.h
index 12b74c7..31e6afa 100644
--- a/COFF/Config.h
+++ b/COFF/Config.h
@@ -1,9 +1,8 @@
 //===- Config.h -------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -197,6 +196,7 @@
   bool MinGW = false;
   bool WarnMissingOrderSymbol = true;
   bool WarnLocallyDefinedImported = true;
+  bool WarnDebugInfoUnusable = true;
   bool Incremental = true;
   bool IntegrityCheck = false;
   bool KillAt = false;
diff --git a/COFF/DLL.cpp b/COFF/DLL.cpp
index 599cc58..6c31b78 100644
--- a/COFF/DLL.cpp
+++ b/COFF/DLL.cpp
@@ -1,9 +1,8 @@
 //===- DLL.cpp ------------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -47,6 +46,7 @@
   }
 
   void writeTo(uint8_t *Buf) const override {
+    memset(Buf + OutputSectionOff, 0, getSize());
     write16le(Buf + OutputSectionOff, Hint);
     memcpy(Buf + OutputSectionOff + 2, Name.data(), Name.size());
   }
@@ -63,7 +63,10 @@
   size_t getSize() const override { return Config->Wordsize; }
 
   void writeTo(uint8_t *Buf) const override {
-    write32le(Buf + OutputSectionOff, HintName->getRVA());
+    if (Config->is64())
+      write64le(Buf + OutputSectionOff, HintName->getRVA());
+    else
+      write32le(Buf + OutputSectionOff, HintName->getRVA());
   }
 
   Chunk *HintName;
@@ -99,6 +102,8 @@
   size_t getSize() const override { return sizeof(ImportDirectoryTableEntry); }
 
   void writeTo(uint8_t *Buf) const override {
+    memset(Buf + OutputSectionOff, 0, getSize());
+
     auto *E = (coff_import_directory_table_entry *)(Buf + OutputSectionOff);
     E->ImportLookupTableRVA = LookupTab->getRVA();
     E->NameRVA = DLLName->getRVA();
@@ -118,6 +123,10 @@
   bool hasData() const override { return false; }
   size_t getSize() const override { return Size; }
 
+  void writeTo(uint8_t *Buf) const override {
+    memset(Buf + OutputSectionOff, 0, Size);
+  }
+
 private:
   size_t Size;
 };
@@ -160,6 +169,8 @@
   }
 
   void writeTo(uint8_t *Buf) const override {
+    memset(Buf + OutputSectionOff, 0, getSize());
+
     auto *E = (delay_import_directory_table_entry *)(Buf + OutputSectionOff);
     E->Attributes = 1;
     E->Name = DLLName->getRVA();
@@ -392,6 +403,8 @@
   }
 
   void writeTo(uint8_t *Buf) const override {
+    memset(Buf + OutputSectionOff, 0, getSize());
+
     auto *E = (export_directory_table_entry *)(Buf + OutputSectionOff);
     E->NameRVA = DLLName->getRVA();
     E->OrdinalBase = 0;
diff --git a/COFF/DLL.h b/COFF/DLL.h
index a298271..4ad0298 100644
--- a/COFF/DLL.h
+++ b/COFF/DLL.h
@@ -1,9 +1,8 @@
 //===- DLL.h ----------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/COFF/Driver.cpp b/COFF/Driver.cpp
index 78b4704..10c761d 100644
--- a/COFF/Driver.cpp
+++ b/COFF/Driver.cpp
@@ -1,9 +1,8 @@
 //===- Driver.cpp ---------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -225,23 +224,33 @@
 void LinkerDriver::enqueueArchiveMember(const Archive::Child &C,
                                         StringRef SymName,
                                         StringRef ParentName) {
+
+  auto ReportBufferError = [=](Error &&E,
+                              StringRef ChildName) {
+    fatal("could not get the buffer for the member defining symbol " +
+          SymName + ": " + ParentName + "(" + ChildName + "): " +
+          toString(std::move(E)));
+  };
+
   if (!C.getParent()->isThin()) {
-    MemoryBufferRef MB = CHECK(
-        C.getMemoryBufferRef(),
-        "could not get the buffer for the member defining symbol " + SymName);
+    Expected<MemoryBufferRef> MBOrErr = C.getMemoryBufferRef();
+    if (!MBOrErr)
+      ReportBufferError(MBOrErr.takeError(), check(C.getFullName()));
+    MemoryBufferRef MB = MBOrErr.get();
     enqueueTask([=]() { Driver->addArchiveBuffer(MB, SymName, ParentName); });
     return;
   }
 
-  auto Future = std::make_shared<std::future<MBErrPair>>(createFutureForFile(
-      CHECK(C.getFullName(),
-            "could not get the filename for the member defining symbol " +
-                SymName)));
+  std::string ChildName = CHECK(
+      C.getFullName(),
+      "could not get the filename for the member defining symbol " +
+      SymName);
+  auto Future = std::make_shared<std::future<MBErrPair>>(
+      createFutureForFile(ChildName));
   enqueueTask([=]() {
     auto MBOrErr = Future->get();
     if (MBOrErr.second)
-      fatal("could not get the buffer for the member defining " + SymName +
-            ": " + MBOrErr.second.message());
+      ReportBufferError(errorCodeToError(MBOrErr.second), ChildName);
     Driver->addArchiveBuffer(takeBuffer(std::move(MBOrErr.first)), SymName,
                              ParentName);
   });
@@ -986,11 +995,17 @@
 
   // Handle /ignore
   for (auto *Arg : Args.filtered(OPT_ignore)) {
-    if (StringRef(Arg->getValue()) == "4037")
-      Config->WarnMissingOrderSymbol = false;
-    else if (StringRef(Arg->getValue()) == "4217")
-      Config->WarnLocallyDefinedImported = false;
-    // Other warning numbers are ignored.
+    SmallVector<StringRef, 8> Vec;
+    StringRef(Arg->getValue()).split(Vec, ',');
+    for (StringRef S : Vec) {
+      if (S == "4037")
+        Config->WarnMissingOrderSymbol = false;
+      else if (S == "4099")
+        Config->WarnDebugInfoUnusable = false;
+      else if (S == "4217")
+        Config->WarnLocallyDefinedImported = false;
+      // Other warning numbers are ignored.
+    }
   }
 
   // Handle /out
diff --git a/COFF/Driver.h b/COFF/Driver.h
index e779721..a792986 100644
--- a/COFF/Driver.h
+++ b/COFF/Driver.h
@@ -1,9 +1,8 @@
 //===- Driver.h -------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/COFF/DriverUtils.cpp b/COFF/DriverUtils.cpp
index 3a11895..c022f93 100644
--- a/COFF/DriverUtils.cpp
+++ b/COFF/DriverUtils.cpp
@@ -1,9 +1,8 @@
 //===- DriverUtils.cpp ----------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/COFF/ICF.cpp b/COFF/ICF.cpp
index 34ea360..7684b2c 100644
--- a/COFF/ICF.cpp
+++ b/COFF/ICF.cpp
@@ -1,9 +1,8 @@
 //===- ICF.cpp ------------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -263,19 +262,21 @@
 
   // Initially, we use hash values to partition sections.
   parallelForEach(Chunks, [&](SectionChunk *SC) {
-    SC->Class[1] = xxHash64(SC->getContents());
+    SC->Class[0] = xxHash64(SC->getContents());
   });
 
   // Combine the hashes of the sections referenced by each section into its
   // hash.
-  parallelForEach(Chunks, [&](SectionChunk *SC) {
-    uint32_t Hash = SC->Class[1];
-    for (Symbol *B : SC->symbols())
-      if (auto *Sym = dyn_cast_or_null<DefinedRegular>(B))
-        Hash ^= Sym->getChunk()->Class[1];
-    // Set MSB to 1 to avoid collisions with non-hash classs.
-    SC->Class[0] = Hash | (1U << 31);
-  });
+  for (unsigned Cnt = 0; Cnt != 2; ++Cnt) {
+    parallelForEach(Chunks, [&](SectionChunk *SC) {
+      uint32_t Hash = SC->Class[Cnt % 2];
+      for (Symbol *B : SC->symbols())
+        if (auto *Sym = dyn_cast_or_null<DefinedRegular>(B))
+          Hash += Sym->getChunk()->Class[Cnt % 2];
+      // Set MSB to 1 to avoid collisions with non-hash classs.
+      SC->Class[(Cnt + 1) % 2] = Hash | (1U << 31);
+    });
+  }
 
   // From now on, sections in Chunks are ordered so that sections in
   // the same group are consecutive in the vector.
diff --git a/COFF/ICF.h b/COFF/ICF.h
index 9c54e0c..f692c8a 100644
--- a/COFF/ICF.h
+++ b/COFF/ICF.h
@@ -1,9 +1,8 @@
 //===- ICF.h --------------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/COFF/InputFiles.cpp b/COFF/InputFiles.cpp
index f35dcda..ba46184 100644
--- a/COFF/InputFiles.cpp
+++ b/COFF/InputFiles.cpp
@@ -1,9 +1,8 @@
 //===- InputFiles.cpp -----------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -127,6 +126,13 @@
   initializeSymbols();
 }
 
+const coff_section* ObjFile::getSection(uint32_t I) {
+  const coff_section *Sec;
+  if (auto EC = COFFObj->getSection(I, Sec))
+    fatal("getSection failed: #" + Twine(I) + ": " + EC.message());
+  return Sec;
+}
+
 // We set SectionChunk pointers in the SparseChunks vector to this value
 // temporarily to mark comdat sections as having an unknown resolution. As we
 // walk the object file's symbol table, once we visit either a leader symbol or
@@ -140,10 +146,7 @@
   Chunks.reserve(NumSections);
   SparseChunks.resize(NumSections + 1);
   for (uint32_t I = 1; I < NumSections + 1; ++I) {
-    const coff_section *Sec;
-    if (auto EC = COFFObj->getSection(I, Sec))
-      fatal("getSection failed: #" + Twine(I) + ": " + EC.message());
-
+    const coff_section *Sec = getSection(I);
     if (Sec->Characteristics & IMAGE_SCN_LNK_COMDAT)
       SparseChunks[I] = PendingComdat;
     else
@@ -154,10 +157,9 @@
 SectionChunk *ObjFile::readSection(uint32_t SectionNumber,
                                    const coff_aux_section_definition *Def,
                                    StringRef LeaderName) {
-  const coff_section *Sec;
+  const coff_section *Sec = getSection(SectionNumber);
+
   StringRef Name;
-  if (auto EC = COFFObj->getSection(SectionNumber, Sec))
-    fatal("getSection failed: #" + Twine(SectionNumber) + ": " + EC.message());
   if (auto EC = COFFObj->getSectionName(Sec, Name))
     fatal("getSectionName failed: #" + Twine(SectionNumber) + ": " +
           EC.message());
@@ -181,8 +183,8 @@
   // of the linker; they are just a data section containing relocations.
   // We can just link them to complete debug info.
   //
-  // CodeView needs a linker support. We need to interpret and debug
-  // info, and then write it to a separate .pdb file.
+  // CodeView needs linker support. We need to interpret debug info,
+  // and then write it to a separate .pdb file.
 
   // Ignore DWARF debug info unless /debug is given.
   if (!Config->Debug && Name.startswith(".debug_"))
@@ -223,22 +225,38 @@
 
 void ObjFile::readAssociativeDefinition(COFFSymbolRef Sym,
                                         const coff_aux_section_definition *Def,
-                                        uint32_t ParentSection) {
-  SectionChunk *Parent = SparseChunks[ParentSection];
+                                        uint32_t ParentIndex) {
+  SectionChunk *Parent = SparseChunks[ParentIndex];
+  int32_t SectionNumber = Sym.getSectionNumber();
 
-  // If the parent is pending, it probably means that its section definition
-  // appears after us in the symbol table. Leave the associated section as
-  // pending; we will handle it during the second pass in initializeSymbols().
-  if (Parent == PendingComdat)
+  auto Diag = [&]() {
+    StringRef Name, ParentName;
+    COFFObj->getSymbolName(Sym, Name);
+
+    const coff_section *ParentSec = getSection(ParentIndex);
+    COFFObj->getSectionName(ParentSec, ParentName);
+    error(toString(this) + ": associative comdat " + Name + " (sec " +
+          Twine(SectionNumber) + ") has invalid reference to section " +
+          ParentName + " (sec " + Twine(ParentIndex) + ")");
+  };
+
+  if (Parent == PendingComdat) {
+    // This can happen if an associative comdat refers to another associative
+    // comdat that appears after it (invalid per COFF spec) or to a section
+    // without any symbols.
+    Diag();
     return;
+  }
 
   // Check whether the parent is prevailing. If it is, so are we, and we read
   // the section; otherwise mark it as discarded.
-  int32_t SectionNumber = Sym.getSectionNumber();
   if (Parent) {
-    SparseChunks[SectionNumber] = readSection(SectionNumber, Def, "");
-    if (SparseChunks[SectionNumber])
-      Parent->addAssociative(SparseChunks[SectionNumber]);
+    SectionChunk *C = readSection(SectionNumber, Def, "");
+    SparseChunks[SectionNumber] = C;
+    if (C) {
+      C->Selection = IMAGE_COMDAT_SELECT_ASSOCIATIVE;
+      Parent->addAssociative(C);
+    }
   } else {
     SparseChunks[SectionNumber] = nullptr;
   }
@@ -290,7 +308,7 @@
     return Symtab->addUndefined(Name, this, false);
   }
   if (SC)
-    return make<DefinedRegular>(this, /*Name*/ "", false,
+    return make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false,
                                 /*IsExternal*/ false, Sym.getGeneric(), SC);
   return nullptr;
 }
@@ -326,8 +344,7 @@
       // was pending at the point when the symbol was read. This can happen in
       // two cases:
       // 1) section definition symbol for a comdat leader;
-      // 2) symbol belongs to a comdat section associated with a section whose
-      //    section definition symbol appears later in the symbol table.
+      // 2) symbol belongs to a comdat section associated with another section.
       // In both of these cases, we can expect the section to be resolved by
       // the time we finish visiting the remaining symbols in the symbol
       // table. So we postpone the handling of this symbol until that time.
@@ -338,7 +355,7 @@
 
   for (uint32_t I : PendingIndexes) {
     COFFSymbolRef Sym = check(COFFObj->getSymbol(I));
-    if (auto *Def = Sym.getSectionDefinition()) {
+    if (const coff_aux_section_definition *Def = Sym.getSectionDefinition()) {
       if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)
         readAssociativeDefinition(Sym, Def);
       else if (Config->MinGW)
@@ -413,23 +430,143 @@
     fatal(toString(this) + ": " + GetName() +
           " should not refer to non-existent section " + Twine(SectionNumber));
 
-  // Handle comdat leader symbols.
+  // Comdat handling.
+  // A comdat symbol consists of two symbol table entries.
+  // The first symbol entry has the name of the section (e.g. .text), fixed
+  // values for the other fields, and one auxilliary record.
+  // The second symbol entry has the name of the comdat symbol, called the
+  // "comdat leader".
+  // When this function is called for the first symbol entry of a comdat,
+  // it sets ComdatDefs and returns None, and when it's called for the second
+  // symbol entry it reads ComdatDefs and then sets it back to nullptr.
+
+  // Handle comdat leader.
   if (const coff_aux_section_definition *Def = ComdatDefs[SectionNumber]) {
     ComdatDefs[SectionNumber] = nullptr;
-    Symbol *Leader;
+    DefinedRegular *Leader;
+
     if (Sym.isExternal()) {
       std::tie(Leader, Prevailing) =
           Symtab->addComdat(this, GetName(), Sym.getGeneric());
     } else {
-      Leader = make<DefinedRegular>(this, /*Name*/ "", false,
+      Leader = make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false,
                                     /*IsExternal*/ false, Sym.getGeneric());
       Prevailing = true;
     }
 
+    if (Def->Selection < (int)IMAGE_COMDAT_SELECT_NODUPLICATES ||
+        // Intentionally ends at IMAGE_COMDAT_SELECT_LARGEST: link.exe
+        // doesn't understand IMAGE_COMDAT_SELECT_NEWEST either.
+        Def->Selection > (int)IMAGE_COMDAT_SELECT_LARGEST) {
+      fatal("unknown comdat type " + std::to_string((int)Def->Selection) +
+            " for " + GetName() + " in " + toString(this));
+    }
+    COMDATType Selection = (COMDATType)Def->Selection;
+
+    if (!Prevailing && Leader->isCOMDAT()) {
+      // There's already an existing comdat for this symbol: `Leader`.
+      // Use the comdats's selection field to determine if the new
+      // symbol in `Sym` should be discarded, produce a duplicate symbol
+      // error, etc.
+
+      SectionChunk *LeaderChunk = nullptr;
+      COMDATType LeaderSelection = IMAGE_COMDAT_SELECT_ANY;
+
+      if (Leader->Data) {
+        LeaderChunk = Leader->getChunk();
+        LeaderSelection = LeaderChunk->Selection;
+      } else {
+        // FIXME: comdats from LTO files don't know their selection; treat them
+        // as "any".
+        Selection = LeaderSelection;
+      }
+
+      if ((Selection == IMAGE_COMDAT_SELECT_ANY &&
+           LeaderSelection == IMAGE_COMDAT_SELECT_LARGEST) ||
+          (Selection == IMAGE_COMDAT_SELECT_LARGEST &&
+           LeaderSelection == IMAGE_COMDAT_SELECT_ANY)) {
+        // cl.exe picks "any" for vftables when building with /GR- and
+        // "largest" when building with /GR. To be able to link object files
+        // compiled with each flag, "any" and "largest" are merged as "largest".
+        LeaderSelection = Selection = IMAGE_COMDAT_SELECT_LARGEST;
+      }
+
+      // Other than that, comdat selections must match.  This is a bit more
+      // strict than link.exe which allows merging "any" and "largest" if "any"
+      // is the first symbol the linker sees, and it allows merging "largest"
+      // with everything (!) if "largest" is the first symbol the linker sees.
+      // Making this symmetric independent of which selection is seen first
+      // seems better though.
+      // (This behavior matches ModuleLinker::getComdatResult().)
+      if (Selection != LeaderSelection) {
+        std::string Msg = ("conflicting comdat type for " + toString(*Leader) +
+                           ": " + Twine((int)LeaderSelection) + " in " +
+                           toString(Leader->getFile()) + " and " +
+                           Twine((int)Selection) + " in " + toString(this))
+                              .str();
+        if (Config->ForceMultiple)
+          warn(Msg);
+        else
+          error(Msg);
+      }
+
+      switch (Selection) {
+      case IMAGE_COMDAT_SELECT_NODUPLICATES:
+        Symtab->reportDuplicate(Leader, this);
+        break;
+
+      case IMAGE_COMDAT_SELECT_ANY:
+        // Nothing to do.
+        break;
+
+      case IMAGE_COMDAT_SELECT_SAME_SIZE:
+        if (LeaderChunk->getSize() != getSection(SectionNumber)->SizeOfRawData)
+          Symtab->reportDuplicate(Leader, this);
+        break;
+
+      case IMAGE_COMDAT_SELECT_EXACT_MATCH: {
+        SectionChunk NewChunk(this, getSection(SectionNumber));
+        // link.exe only compares section contents here and doesn't complain
+        // if the two comdat sections have e.g. different alignment.
+        // Match that.
+        if (LeaderChunk->getContents() != NewChunk.getContents())
+          Symtab->reportDuplicate(Leader, this);
+        break;
+      }
+
+      case IMAGE_COMDAT_SELECT_ASSOCIATIVE:
+        // createDefined() is never called for IMAGE_COMDAT_SELECT_ASSOCIATIVE.
+        // (This means lld-link doesn't produce duplicate symbol errors for
+        // associative comdats while link.exe does, but associate comdats
+        // are never extern in practice.)
+        llvm_unreachable("createDefined not called for associative comdats");
+
+      case IMAGE_COMDAT_SELECT_LARGEST:
+        if (LeaderChunk->getSize() < getSection(SectionNumber)->SizeOfRawData) {
+          // Replace the existing comdat symbol with the new one.
+          // FIXME: This is incorrect: With /opt:noref, the previous sections
+          // make it into the final executable as well. Correct handling would
+          // be to undo reading of the whole old section that's being replaced,
+          // or doing one pass that determines what the final largest comdat
+          // is for all IMAGE_COMDAT_SELECT_LARGEST comdats and then reading
+          // only the largest one.
+          replaceSymbol<DefinedRegular>(
+              Leader, this, GetName(), /*IsCOMDAT*/ true,
+              /*IsExternal*/ true, Sym.getGeneric(), nullptr);
+          Prevailing = true;
+        }
+        break;
+
+      case IMAGE_COMDAT_SELECT_NEWEST:
+        llvm_unreachable("should have been rejected earlier");
+      }
+    }
+
     if (Prevailing) {
       SectionChunk *C = readSection(SectionNumber, Def, GetName());
       SparseChunks[SectionNumber] = C;
       C->Sym = cast<DefinedRegular>(Leader);
+      C->Selection = Selection;
       cast<DefinedRegular>(Leader)->Data = &C->Repl;
     } else {
       SparseChunks[SectionNumber] = nullptr;
@@ -437,20 +574,16 @@
     return Leader;
   }
 
-  // Read associative section definitions and prepare to handle the comdat
-  // leader symbol by setting the section's ComdatDefs pointer if we encounter a
-  // non-associative comdat.
+  // Prepare to handle the comdat leader symbol by setting the section's
+  // ComdatDefs pointer if we encounter a non-associative comdat.
   if (SparseChunks[SectionNumber] == PendingComdat) {
-    if (auto *Def = Sym.getSectionDefinition()) {
-      if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)
-        readAssociativeDefinition(Sym, Def);
-      else
+    if (const coff_aux_section_definition *Def = Sym.getSectionDefinition()) {
+      if (Def->Selection != IMAGE_COMDAT_SELECT_ASSOCIATIVE)
         ComdatDefs[SectionNumber] = Def;
     }
+    return None;
   }
 
-  if (SparseChunks[SectionNumber] == PendingComdat)
-    return None;
   return createRegular(Sym);
 }
 
@@ -522,6 +655,8 @@
       MB.getBuffer(), Saver.save(ParentName + MB.getBufferIdentifier()))));
   std::vector<std::pair<Symbol *, bool>> Comdat(Obj->getComdatTable().size());
   for (size_t I = 0; I != Obj->getComdatTable().size(); ++I)
+    // FIXME: lto::InputFile doesn't keep enough data to do correct comdat
+    // selection handling.
     Comdat[I] = Symtab->addComdat(this, Saver.save(Obj->getComdatTable()[I]));
   for (const lto::InputFile::Symbol &ObjSym : Obj->symbols()) {
     StringRef SymName = Saver.save(ObjSym.getName());
diff --git a/COFF/InputFiles.h b/COFF/InputFiles.h
index 9e15607..6bf0af3 100644
--- a/COFF/InputFiles.h
+++ b/COFF/InputFiles.h
@@ -1,9 +1,8 @@
 //===- InputFiles.h ---------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -154,9 +153,11 @@
   // When using Microsoft precompiled headers, this is the PCH's key.
   // The same key is used by both the precompiled object, and objects using the
   // precompiled object. Any difference indicates out-of-date objects.
-  llvm::Optional<llvm::codeview::EndPrecompRecord> EndPrecomp;
+  llvm::Optional<uint32_t> PCHSignature;
 
 private:
+  const coff_section* getSection(uint32_t I);
+
   void initializeChunks();
   void initializeSymbols();
 
diff --git a/COFF/LTO.cpp b/COFF/LTO.cpp
index 92d9ff0..bfbfc24 100644
--- a/COFF/LTO.cpp
+++ b/COFF/LTO.cpp
@@ -1,9 +1,8 @@
 //===- LTO.cpp ------------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -11,6 +10,7 @@
 #include "Config.h"
 #include "InputFiles.h"
 #include "Symbols.h"
+#include "lld/Common/Args.h"
 #include "lld/Common/ErrorHandler.h"
 #include "lld/Common/Strings.h"
 #include "lld/Common/TargetOptionsCommandFlags.h"
@@ -43,7 +43,7 @@
 
 static std::unique_ptr<lto::LTO> createLTO() {
   lto::Config C;
-  C.Options = InitTargetOptionsFromCodeGenFlags();
+  C.Options = initTargetOptionsFromCodeGenFlags();
 
   // Always emit a section per function/datum with LTO. LLVM LTO should get most
   // of the benefit of linker GC, but there are still opportunities for ICF.
@@ -60,8 +60,9 @@
   C.DisableVerify = true;
   C.DiagHandler = diagnosticHandler;
   C.OptLevel = Config->LTOO;
-  C.CPU = GetCPUStr();
-  C.MAttrs = GetMAttrs();
+  C.CPU = getCPUStr();
+  C.MAttrs = getMAttrs();
+  C.CGOptLevel = args::getCGOptLevel(Config->LTOO);
 
   if (Config->SaveTemps)
     checkError(C.addSaveTemps(std::string(Config->OutputFile) + ".",
diff --git a/COFF/LTO.h b/COFF/LTO.h
index f009246..222945c 100644
--- a/COFF/LTO.h
+++ b/COFF/LTO.h
@@ -1,9 +1,8 @@
 //===- LTO.h ----------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/COFF/MapFile.cpp b/COFF/MapFile.cpp
index fd48942..f8cdcc1 100644
--- a/COFF/MapFile.cpp
+++ b/COFF/MapFile.cpp
@@ -1,9 +1,8 @@
 //===- MapFile.cpp --------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/COFF/MapFile.h b/COFF/MapFile.h
index 0d0d68c..f702dc6 100644
--- a/COFF/MapFile.h
+++ b/COFF/MapFile.h
@@ -1,9 +1,8 @@
 //===- MapFile.h ------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/COFF/MarkLive.cpp b/COFF/MarkLive.cpp
index 18b1c9c..e7d407b 100644
--- a/COFF/MarkLive.cpp
+++ b/COFF/MarkLive.cpp
@@ -1,9 +1,8 @@
 //===- MarkLive.cpp -------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/COFF/MarkLive.h b/COFF/MarkLive.h
index 5b652dd..3d7ef93 100644
--- a/COFF/MarkLive.h
+++ b/COFF/MarkLive.h
@@ -1,9 +1,8 @@
 //===- MarkLive.h -----------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/COFF/MinGW.cpp b/COFF/MinGW.cpp
index b2c8c4e..ee9833e 100644
--- a/COFF/MinGW.cpp
+++ b/COFF/MinGW.cpp
@@ -1,9 +1,8 @@
 //===- MinGW.cpp ----------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/COFF/MinGW.h b/COFF/MinGW.h
index f9c5e3e..51448dd 100644
--- a/COFF/MinGW.h
+++ b/COFF/MinGW.h
@@ -1,9 +1,8 @@
 //===- MinGW.h --------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/COFF/Options.td b/COFF/Options.td
index f5dcd27..acf1bc5 100644
--- a/COFF/Options.td
+++ b/COFF/Options.td
@@ -66,13 +66,18 @@
 
 def disallowlib : Joined<["/", "-", "-?"], "disallowlib:">, Alias<nodefaultlib>;
 
-def manifest : F<"manifest">;
-def manifest_colon : P<"manifest", "Create manifest file">;
+def manifest : F<"manifest">, HelpText<"Create .manifest file">;
+def manifest_colon : P<
+    "manifest",
+    "NO disables manifest output; EMBED[,ID=#] embeds manifest as resource in the image">;
 def manifestuac : P<"manifestuac", "User access control">;
-def manifestfile : P<"manifestfile", "Manifest file path">;
-def manifestdependency : P<"manifestdependency",
-                           "Attributes for <dependency> in manifest file">;
-def manifestinput : P<"manifestinput", "Specify manifest file">;
+def manifestfile : P<"manifestfile", "Manifest output path, with /manifest">;
+def manifestdependency : P<
+    "manifestdependency",
+    "Attributes for <dependency> element in manifest file; implies /manifest">;
+def manifestinput : P<
+    "manifestinput",
+    "Additional manifest inputs; only valid with /manifest:embed">;
 
 // We cannot use multiclass P because class name "incl" is different
 // from its command line option name. We do this because "include" is
@@ -89,10 +94,13 @@
 def debugtype : P<"debugtype", "Debug Info Options">;
 def dll : F<"dll">, HelpText<"Create a DLL">;
 def driver : P<"driver", "Generate a Windows NT Kernel Mode Driver">;
-def nodefaultlib_all : F<"nodefaultlib">;
-def noentry : F<"noentry">;
+def nodefaultlib_all : F<"nodefaultlib">,
+    HelpText<"Remove all default libraries">;
+def noentry : F<"noentry">,
+    HelpText<"Don't add reference to DllMainCRTStartup; only valid with /dll">;
 def profile : F<"profile">;
-def repro : F<"Brepro">, HelpText<"Use a hash of the executable as the PE header timestamp">;
+def repro : F<"Brepro">,
+    HelpText<"Use a hash of the executable as the PE header timestamp">;
 def swaprun_cd : F<"swaprun:cd">;
 def swaprun_net : F<"swaprun:net">;
 def verbose : F<"verbose">;
diff --git a/COFF/PDB.cpp b/COFF/PDB.cpp
index 3c99d1f..4070ad4 100644
--- a/COFF/PDB.cpp
+++ b/COFF/PDB.cpp
@@ -1,9 +1,8 @@
 //===- PDB.cpp ------------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -53,6 +52,7 @@
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/JamCRC.h"
+#include "llvm/Support/Parallel.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include <memory>
@@ -213,7 +213,7 @@
   std::vector<pdb::SecMapEntry> SectionMap;
 
   /// Type index mappings of type server PDBs that we've loaded so far.
-  std::map<GUID, CVIndexMap> TypeServerIndexMappings;
+  std::map<codeview::GUID, CVIndexMap> TypeServerIndexMappings;
 
   /// Type index mappings of precompiled objects type map that we've loaded so
   /// far.
@@ -221,7 +221,7 @@
 
   /// List of TypeServer PDBs which cannot be loaded.
   /// Cached to prevent repeated load attempts.
-  std::map<GUID, std::string> MissingTypeServerPDBs;
+  std::map<codeview::GUID, std::string> MissingTypeServerPDBs;
 };
 
 class DebugSHandler {
@@ -287,18 +287,24 @@
   // It's not absolute in any path syntax.  Relative paths necessarily refer to
   // the local file system, so we can make it native without ending up with a
   // nonsensical path.
-  sys::path::native(FileName);
   if (Config->PDBSourcePath.empty()) {
+    sys::path::native(FileName);
     sys::fs::make_absolute(FileName);
     return;
   }
-  // Only apply native and dot removal to the relative file path.  We want to
-  // leave the path the user specified untouched since we assume they specified
-  // it for a reason.
-  sys::path::remove_dots(FileName, /*remove_dot_dots=*/true);
 
+  // Try to guess whether /PDBSOURCEPATH is a unix path or a windows path.
+  // Since PDB's are more of a Windows thing, we make this conservative and only
+  // decide that it's a unix path if we're fairly certain.  Specifically, if
+  // it starts with a forward slash.
   SmallString<128> AbsoluteFileName = Config->PDBSourcePath;
-  sys::path::append(AbsoluteFileName, FileName);
+  sys::path::Style GuessedStyle = AbsoluteFileName.startswith("/")
+                                      ? sys::path::Style::posix
+                                      : sys::path::Style::windows;
+  sys::path::append(AbsoluteFileName, GuessedStyle, FileName);
+  sys::path::native(AbsoluteFileName, GuessedStyle);
+  sys::path::remove_dots(AbsoluteFileName, true, GuessedStyle);
+
   FileName = std::move(AbsoluteFileName);
 }
 
@@ -493,13 +499,13 @@
 
     if (auto Err = mergeTypeAndIdRecords(GlobalIDTable, GlobalTypeTable,
                                          ObjectIndexMap->TPIMap, Types, Hashes,
-                                         File->EndPrecomp))
+                                         File->PCHSignature))
       fatal("codeview::mergeTypeAndIdRecords failed: " +
             toString(std::move(Err)));
   } else {
     if (auto Err =
             mergeTypeAndIdRecords(IDTable, TypeTable, ObjectIndexMap->TPIMap,
-                                  Types, File->EndPrecomp))
+                                  Types, File->PCHSignature))
       fatal("codeview::mergeTypeAndIdRecords failed: " +
             toString(std::move(Err)));
   }
@@ -507,7 +513,7 @@
 }
 
 static Expected<std::unique_ptr<pdb::NativeSession>>
-tryToLoadPDB(const GUID &GuidFromObj, StringRef TSPath) {
+tryToLoadPDB(const codeview::GUID &GuidFromObj, StringRef TSPath) {
   // Ensure the file exists before anything else. We want to return ENOENT,
   // "file not found", even if the path points to a removable device (in which
   // case the return message would be EAGAIN, "resource unavailable try again")
@@ -550,7 +556,7 @@
           TypeDeserializer::deserializeAs(const_cast<CVType &>(FirstType), TS))
     fatal("error reading record: " + toString(std::move(EC)));
 
-  const GUID &TSId = TS.getGuid();
+  const codeview::GUID &TSId = TS.getGuid();
   StringRef TSPath = TS.getName();
 
   // First, check if the PDB has previously failed to load.
@@ -631,7 +637,7 @@
     auto IpiHashes =
         GloballyHashedType::hashIds(ExpectedIpi->typeArray(), TpiHashes);
 
-    Optional<EndPrecompRecord> EndPrecomp;
+    Optional<uint32_t> EndPrecomp;
     // Merge TPI first, because the IPI stream will reference type indices.
     if (auto Err = mergeTypeRecords(GlobalTypeTable, IndexMap.TPIMap,
                                     ExpectedTpi->typeArray(), TpiHashes, EndPrecomp))
@@ -743,10 +749,10 @@
 
   addObjFile(PrecompFile, &IndexMap);
 
-  if (!PrecompFile->EndPrecomp)
+  if (!PrecompFile->PCHSignature)
     fatal(PrecompFile->getName() + " is not a precompiled headers object");
 
-  if (Precomp.getSignature() != PrecompFile->EndPrecomp->getSignature())
+  if (Precomp.getSignature() != PrecompFile->PCHSignature.getValueOr(0))
     return createFileError(
         Precomp.getPrecompFilePath().str(),
         make_error<pdb::PDBError>(pdb::pdb_error_code::signature_out_of_date));
@@ -1300,8 +1306,12 @@
 
   // If the .debug$T sections fail to merge, assume there is no debug info.
   if (!IndexMapResult) {
-    auto FileName = sys::path::filename(Path);
-    warn("Cannot use debug info for '" + FileName + "'\n" +
+    if (!Config->WarnDebugInfoUnusable) {
+      consumeError(IndexMapResult.takeError());
+      return;
+    }
+    StringRef FileName = sys::path::filename(Path);
+    warn("Cannot use debug info for '" + FileName + "' [LNK4099]\n" +
          ">>> failed to load reference " +
          StringRef(toString(IndexMapResult.takeError())));
     return;
@@ -1387,10 +1397,10 @@
 
   if (!Publics.empty()) {
     // Sort the public symbols and add them to the stream.
-    std::sort(Publics.begin(), Publics.end(),
-              [](const PublicSym32 &L, const PublicSym32 &R) {
-                return L.Name < R.Name;
-              });
+    sort(parallel::par, Publics.begin(), Publics.end(),
+         [](const PublicSym32 &L, const PublicSym32 &R) {
+           return L.Name < R.Name;
+         });
     for (const PublicSym32 &Pub : Publics)
       GsiBuilder.addPublicSymbol(Pub);
   }
@@ -1735,20 +1745,26 @@
   if (!findLineTable(C, Addr, CVStrTab, Checksums, Lines, OffsetInLinetable))
     return {"", 0};
 
-  uint32_t NameIndex;
-  uint32_t LineNumber;
+  Optional<uint32_t> NameIndex;
+  Optional<uint32_t> LineNumber;
   for (LineColumnEntry &Entry : Lines) {
     for (const LineNumberEntry &LN : Entry.LineNumbers) {
-      if (LN.Offset > OffsetInLinetable) {
-        StringRef Filename =
-            ExitOnErr(getFileName(CVStrTab, Checksums, NameIndex));
-        return {Filename, LineNumber};
-      }
       LineInfo LI(LN.Flags);
+      if (LN.Offset > OffsetInLinetable) {
+        if (!NameIndex) {
+          NameIndex = Entry.NameIndex;
+          LineNumber = LI.getStartLine();
+        }
+        StringRef Filename =
+            ExitOnErr(getFileName(CVStrTab, Checksums, *NameIndex));
+        return {Filename, *LineNumber};
+      }
       NameIndex = Entry.NameIndex;
       LineNumber = LI.getStartLine();
     }
   }
-  StringRef Filename = ExitOnErr(getFileName(CVStrTab, Checksums, NameIndex));
-  return {Filename, LineNumber};
+  if (!NameIndex)
+    return {"", 0};
+  StringRef Filename = ExitOnErr(getFileName(CVStrTab, Checksums, *NameIndex));
+  return {Filename, *LineNumber};
 }
diff --git a/COFF/PDB.h b/COFF/PDB.h
index ea7a999..d954e09 100644
--- a/COFF/PDB.h
+++ b/COFF/PDB.h
@@ -1,9 +1,8 @@
 //===- PDB.h ----------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/COFF/SymbolTable.cpp b/COFF/SymbolTable.cpp
index 1a9e045..1828929 100644
--- a/COFF/SymbolTable.cpp
+++ b/COFF/SymbolTable.cpp
@@ -1,9 +1,8 @@
 //===- SymbolTable.cpp ----------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -400,7 +399,7 @@
   return S;
 }
 
-std::pair<Symbol *, bool>
+std::pair<DefinedRegular *, bool>
 SymbolTable::addComdat(InputFile *F, StringRef N,
                        const coff_symbol_generic *Sym) {
   Symbol *S;
@@ -409,11 +408,12 @@
   if (WasInserted || !isa<DefinedRegular>(S)) {
     replaceSymbol<DefinedRegular>(S, F, N, /*IsCOMDAT*/ true,
                                   /*IsExternal*/ true, Sym, nullptr);
-    return {S, true};
+    return {cast<DefinedRegular>(S), true};
   }
-  if (!cast<DefinedRegular>(S)->isCOMDAT())
+  auto *ExistingSymbol = cast<DefinedRegular>(S);
+  if (!ExistingSymbol->isCOMDAT())
     reportDuplicate(S, F);
-  return {S, false};
+  return {ExistingSymbol, false};
 }
 
 Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size,
diff --git a/COFF/SymbolTable.h b/COFF/SymbolTable.h
index 00e55db..7f74863 100644
--- a/COFF/SymbolTable.h
+++ b/COFF/SymbolTable.h
@@ -1,9 +1,8 @@
 //===- SymbolTable.h --------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -28,6 +27,7 @@
 class CommonChunk;
 class Defined;
 class DefinedAbsolute;
+class DefinedRegular;
 class DefinedRelative;
 class Lazy;
 class SectionChunk;
@@ -89,7 +89,7 @@
   Symbol *addRegular(InputFile *F, StringRef N,
                      const llvm::object::coff_symbol_generic *S = nullptr,
                      SectionChunk *C = nullptr);
-  std::pair<Symbol *, bool>
+  std::pair<DefinedRegular *, bool>
   addComdat(InputFile *F, StringRef N,
             const llvm::object::coff_symbol_generic *S = nullptr);
   Symbol *addCommon(InputFile *F, StringRef N, uint64_t Size,
diff --git a/COFF/Symbols.cpp b/COFF/Symbols.cpp
index ccaf864..781fe9f 100644
--- a/COFF/Symbols.cpp
+++ b/COFF/Symbols.cpp
@@ -1,9 +1,8 @@
 //===- Symbols.cpp --------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/COFF/Symbols.h b/COFF/Symbols.h
index 9e9bd73..718aceb 100644
--- a/COFF/Symbols.h
+++ b/COFF/Symbols.h
@@ -1,9 +1,8 @@
 //===- Symbols.h ------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -39,7 +38,7 @@
 public:
   enum Kind {
     // The order of these is significant. We start with the regular defined
-    // symbols as those are the most prevelant and the zero tag is the cheapest
+    // symbols as those are the most prevalent and the zero tag is the cheapest
     // to set. Among the defined kinds, the lower the kind is preferred over
     // the higher kind when testing whether one symbol should take precedence
     // over another.
diff --git a/COFF/Writer.cpp b/COFF/Writer.cpp
index 258796e..d883a47 100644
--- a/COFF/Writer.cpp
+++ b/COFF/Writer.cpp
@@ -1,9 +1,8 @@
 //===- Writer.cpp ---------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -157,6 +156,33 @@
   mutable codeview::DebugInfo *BuildId = nullptr;
 };
 
+// PartialSection represents a group of chunks that contribute to an
+// OutputSection. Collating a collection of PartialSections of same name and
+// characteristics constitutes the OutputSection.
+class PartialSectionKey {
+public:
+  StringRef Name;
+  unsigned Characteristics;
+
+  bool operator<(const PartialSectionKey &Other) const {
+    int C = Name.compare(Other.Name);
+    if (C == 1)
+      return false;
+    if (C == 0)
+      return Characteristics < Other.Characteristics;
+    return true;
+  }
+};
+
+class PartialSection {
+public:
+  PartialSection(StringRef N, uint32_t Chars)
+      : Name(N), Characteristics(Chars) {}
+  StringRef Name;
+  unsigned Characteristics;
+  std::vector<Chunk *> Chunks;
+};
+
 // The writer writes a SymbolTable result to a file.
 class Writer {
 public:
@@ -168,8 +194,7 @@
   void createMiscChunks();
   void createImportTables();
   void appendImportThunks();
-  void locateImportTables(
-      std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> &Map);
+  void locateImportTables();
   void createExportTable();
   void mergeSections();
   void readRelocTargets();
@@ -194,6 +219,10 @@
   void writeBuildId();
   void sortExceptionTable();
   void sortCRTSectionChunks(std::vector<Chunk *> &Chunks);
+  void addSyntheticIdata();
+  bool fixGnuImportChunks();
+  PartialSection *createPartialSection(StringRef Name, uint32_t OutChars);
+  PartialSection *findPartialSection(StringRef Name, uint32_t OutChars);
 
   llvm::Optional<coff_symbol16> createSymbol(Defined *D);
   size_t addEntryToStringTable(StringRef Str);
@@ -203,9 +232,9 @@
   void addBaserelBlocks(std::vector<Baserel> &V);
 
   uint32_t getSizeOfInitializedData();
-  std::map<StringRef, std::vector<DefinedImportData *>> binImports();
 
   std::unique_ptr<FileOutputBuffer> &Buffer;
+  std::map<PartialSectionKey, PartialSection *> PartialSections;
   std::vector<OutputSection *> OutputSections;
   std::vector<char> Strtab;
   std::vector<llvm::object::coff_symbol16> OutputSymtab;
@@ -306,16 +335,31 @@
 // Check whether the target address S is in range from a relocation
 // of type RelType at address P.
 static bool isInRange(uint16_t RelType, uint64_t S, uint64_t P, int Margin) {
-  assert(Config->Machine == ARMNT);
-  int64_t Diff = AbsoluteDifference(S, P + 4) + Margin;
-  switch (RelType) {
-  case IMAGE_REL_ARM_BRANCH20T:
-    return isInt<21>(Diff);
-  case IMAGE_REL_ARM_BRANCH24T:
-  case IMAGE_REL_ARM_BLX23T:
-    return isInt<25>(Diff);
-  default:
-    return true;
+  if (Config->Machine == ARMNT) {
+    int64_t Diff = AbsoluteDifference(S, P + 4) + Margin;
+    switch (RelType) {
+    case IMAGE_REL_ARM_BRANCH20T:
+      return isInt<21>(Diff);
+    case IMAGE_REL_ARM_BRANCH24T:
+    case IMAGE_REL_ARM_BLX23T:
+      return isInt<25>(Diff);
+    default:
+      return true;
+    }
+  } else if (Config->Machine == ARM64) {
+    int64_t Diff = AbsoluteDifference(S, P) + Margin;
+    switch (RelType) {
+    case IMAGE_REL_ARM64_BRANCH26:
+      return isInt<28>(Diff);
+    case IMAGE_REL_ARM64_BRANCH19:
+      return isInt<21>(Diff);
+    case IMAGE_REL_ARM64_BRANCH14:
+      return isInt<16>(Diff);
+    default:
+      return true;
+    }
+  } else {
+    llvm_unreachable("Unexpected architecture");
   }
 }
 
@@ -327,7 +371,17 @@
   Defined *&LastThunk = LastThunks[Target->getRVA()];
   if (LastThunk && isInRange(Type, LastThunk->getRVA(), P, Margin))
     return {LastThunk, false};
-  RangeExtensionThunk *C = make<RangeExtensionThunk>(Target);
+  Chunk *C;
+  switch (Config->Machine) {
+  case ARMNT:
+    C = make<RangeExtensionThunkARM>(Target);
+    break;
+  case ARM64:
+    C = make<RangeExtensionThunkARM64>(Target);
+    break;
+  default:
+    llvm_unreachable("Unexpected architecture");
+  }
   Defined *D = make<DefinedSynthetic>("", C);
   LastThunk = D;
   return {D, true};
@@ -344,14 +398,14 @@
 // After adding thunks, we verify that all relocations are in range (with
 // no extra margin requirements). If this failed, we restart (throwing away
 // the previously created thunks) and retry with a wider margin.
-static bool createThunks(std::vector<Chunk *> &Chunks, int Margin) {
+static bool createThunks(OutputSection *OS, int Margin) {
   bool AddressesChanged = false;
   DenseMap<uint64_t, Defined *> LastThunks;
   size_t ThunksSize = 0;
   // Recheck Chunks.size() each iteration, since we can insert more
   // elements into it.
-  for (size_t I = 0; I != Chunks.size(); ++I) {
-    SectionChunk *SC = dyn_cast_or_null<SectionChunk>(Chunks[I]);
+  for (size_t I = 0; I != OS->Chunks.size(); ++I) {
+    SectionChunk *SC = dyn_cast_or_null<SectionChunk>(OS->Chunks[I]);
     if (!SC)
       continue;
     size_t ThunkInsertionSpot = I + 1;
@@ -388,7 +442,8 @@
         Chunk *ThunkChunk = Thunk->getChunk();
         ThunkChunk->setRVA(
             ThunkInsertionRVA); // Estimate of where it will be located.
-        Chunks.insert(Chunks.begin() + ThunkInsertionSpot, ThunkChunk);
+        ThunkChunk->setOutputSection(OS);
+        OS->Chunks.insert(OS->Chunks.begin() + ThunkInsertionSpot, ThunkChunk);
         ThunkInsertionSpot++;
         ThunksSize += ThunkChunk->getSize();
         ThunkInsertionRVA += ThunkChunk->getSize();
@@ -428,7 +483,7 @@
 // Assign addresses and add thunks if necessary.
 void Writer::finalizeAddresses() {
   assignAddresses();
-  if (Config->Machine != ARMNT)
+  if (Config->Machine != ARMNT && Config->Machine != ARM64)
     return;
 
   size_t OrigNumChunks = 0;
@@ -477,7 +532,7 @@
     // to avoid things going out of range due to the added thunks.
     bool AddressesChanged = false;
     for (OutputSection *Sec : OutputSections)
-      AddressesChanged |= createThunks(Sec->Chunks, Margin);
+      AddressesChanged |= createThunks(Sec, Margin);
     // If the verification above thought we needed thunks, we should have
     // added some.
     assert(AddressesChanged);
@@ -568,34 +623,32 @@
 // be formed correctly, the section chunks within each .idata$* section need
 // to be grouped by library, and sorted alphabetically within each library
 // (which makes sure the header comes first and the trailer last).
-static bool fixGnuImportChunks(
-    std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> &Map) {
+bool Writer::fixGnuImportChunks() {
   uint32_t RDATA = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
 
   // Make sure all .idata$* section chunks are mapped as RDATA in order to
   // be sorted into the same sections as our own synthesized .idata chunks.
-  for (auto &Pair : Map) {
-    StringRef SectionName = Pair.first.first;
-    uint32_t OutChars = Pair.first.second;
-    if (!SectionName.startswith(".idata"))
+  for (auto It : PartialSections) {
+    PartialSection *PSec = It.second;
+    if (!PSec->Name.startswith(".idata"))
       continue;
-    if (OutChars == RDATA)
+    if (PSec->Characteristics == RDATA)
       continue;
-    std::vector<Chunk *> &SrcVect = Pair.second;
-    std::vector<Chunk *> &DestVect = Map[{SectionName, RDATA}];
-    DestVect.insert(DestVect.end(), SrcVect.begin(), SrcVect.end());
-    SrcVect.clear();
+    PartialSection *RDataSec = createPartialSection(PSec->Name, RDATA);
+    RDataSec->Chunks.insert(RDataSec->Chunks.end(), PSec->Chunks.begin(),
+                            PSec->Chunks.end());
+    PSec->Chunks.clear();
   }
 
   bool HasIdata = false;
   // Sort all .idata$* chunks, grouping chunks from the same library,
   // with alphabetical ordering of the object fils within a library.
-  for (auto &Pair : Map) {
-    StringRef SectionName = Pair.first.first;
-    if (!SectionName.startswith(".idata"))
+  for (auto It : PartialSections) {
+    PartialSection *PSec = It.second;
+    if (!PSec->Name.startswith(".idata"))
       continue;
 
-    std::vector<Chunk *> &Chunks = Pair.second;
+    std::vector<Chunk *> &Chunks = PSec->Chunks;
     if (!Chunks.empty())
       HasIdata = true;
     std::stable_sort(Chunks.begin(), Chunks.end(), [&](Chunk *S, Chunk *T) {
@@ -621,9 +674,7 @@
 
 // Add generated idata chunks, for imported symbols and DLLs, and a
 // terminator in .idata$2.
-static void addSyntheticIdata(
-    IdataContents &Idata,
-    std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> &Map) {
+void Writer::addSyntheticIdata() {
   uint32_t RDATA = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
   Idata.create();
 
@@ -631,8 +682,8 @@
   // chunks from other linked in object files to be grouped together.
   // See Microsoft PE/COFF spec 5.4 for details.
   auto Add = [&](StringRef N, std::vector<Chunk *> &V) {
-    std::vector<Chunk *> &DestVect = Map[{N, RDATA}];
-    DestVect.insert(DestVect.end(), V.begin(), V.end());
+    PartialSection *PSec = createPartialSection(N, RDATA);
+    PSec->Chunks.insert(PSec->Chunks.end(), V.begin(), V.end());
   };
 
   // The loader assumes a specific order of data.
@@ -646,20 +697,22 @@
 
 // Locate the first Chunk and size of the import directory list and the
 // IAT.
-void Writer::locateImportTables(
-    std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> &Map) {
+void Writer::locateImportTables() {
   uint32_t RDATA = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
-  std::vector<Chunk *> &ImportTables = Map[{".idata$2", RDATA}];
-  if (!ImportTables.empty())
-    ImportTableStart = ImportTables.front();
-  for (Chunk *C : ImportTables)
-    ImportTableSize += C->getSize();
 
-  std::vector<Chunk *> &IAT = Map[{".idata$5", RDATA}];
-  if (!IAT.empty())
-    IATStart = IAT.front();
-  for (Chunk *C : IAT)
-    IATSize += C->getSize();
+  if (PartialSection *ImportDirs = findPartialSection(".idata$2", RDATA)) {
+    if (!ImportDirs->Chunks.empty())
+      ImportTableStart = ImportDirs->Chunks.front();
+    for (Chunk *C : ImportDirs->Chunks)
+      ImportTableSize += C->getSize();
+  }
+
+  if (PartialSection *ImportAddresses = findPartialSection(".idata$5", RDATA)) {
+    if (!ImportAddresses->Chunks.empty())
+      IATStart = ImportAddresses->Chunks.front();
+    for (Chunk *C : ImportAddresses->Chunks)
+      IATSize += C->getSize();
+  }
 }
 
 // Create output section objects and add them to OutputSections.
@@ -699,7 +752,6 @@
   DtorsSec = CreateSection(".dtors", DATA | R | W);
 
   // Then bin chunks by name and output characteristics.
-  std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> Map;
   for (Chunk *C : Symtab->getChunks()) {
     auto *SC = dyn_cast<SectionChunk>(C);
     if (SC && !SC->Live) {
@@ -707,33 +759,36 @@
         SC->printDiscardedMessage();
       continue;
     }
-    Map[{C->getSectionName(), C->getOutputCharacteristics()}].push_back(C);
+    PartialSection *PSec = createPartialSection(C->getSectionName(),
+                                                C->getOutputCharacteristics());
+    PSec->Chunks.push_back(C);
   }
 
   // Even in non MinGW cases, we might need to link against GNU import
   // libraries.
-  bool HasIdata = fixGnuImportChunks(Map);
+  bool HasIdata = fixGnuImportChunks();
   if (!Idata.empty())
     HasIdata = true;
 
   if (HasIdata)
-    addSyntheticIdata(Idata, Map);
+    addSyntheticIdata();
 
   // Process an /order option.
   if (!Config->Order.empty())
-    for (auto &Pair : Map)
-      sortBySectionOrder(Pair.second);
+    for (auto It : PartialSections)
+      sortBySectionOrder(It.second->Chunks);
 
   if (HasIdata)
-    locateImportTables(Map);
+    locateImportTables();
 
   // Then create an OutputSection for each section.
   // '$' and all following characters in input section names are
   // discarded when determining output section. So, .text$foo
   // contributes to .text, for example. See PE/COFF spec 3.2.
-  for (auto &Pair : Map) {
-    StringRef Name = getOutputSectionName(Pair.first.first);
-    uint32_t OutChars = Pair.first.second;
+  for (auto It : PartialSections) {
+    PartialSection *PSec = It.second;
+    StringRef Name = getOutputSectionName(PSec->Name);
+    uint32_t OutChars = PSec->Characteristics;
 
     if (Name == ".CRT") {
       // In link.exe, there is a special case for the I386 target where .CRT
@@ -742,14 +797,13 @@
       // special case for all architectures.
       OutChars = DATA | R;
 
-      log("Processing section " + Pair.first.first + " -> " + Name);
+      log("Processing section " + PSec->Name + " -> " + Name);
 
-      sortCRTSectionChunks(Pair.second);
+      sortCRTSectionChunks(PSec->Chunks);
     }
 
     OutputSection *Sec = CreateSection(Name, OutChars);
-    std::vector<Chunk *> &Chunks = Pair.second;
-    for (Chunk *C : Chunks)
+    for (Chunk *C : PSec->Chunks)
       Sec->addChunk(C);
   }
 
@@ -1717,3 +1771,19 @@
     return;
   RelocSec->addChunk(make<BaserelChunk>(Page, &V[I], &V[0] + J));
 }
+
+PartialSection *Writer::createPartialSection(StringRef Name,
+                                             uint32_t OutChars) {
+  PartialSection *&PSec = PartialSections[{Name, OutChars}];
+  if (PSec)
+    return PSec;
+  PSec = make<PartialSection>(Name, OutChars);
+  return PSec;
+}
+
+PartialSection *Writer::findPartialSection(StringRef Name, uint32_t OutChars) {
+  auto It = PartialSections.find({Name, OutChars});
+  if (It != PartialSections.end())
+    return It->second;
+  return nullptr;
+}
diff --git a/COFF/Writer.h b/COFF/Writer.h
index 7275824..c430917 100644
--- a/COFF/Writer.h
+++ b/COFF/Writer.h
@@ -1,9 +1,8 @@
 //===- Writer.h -------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/Common/Args.cpp b/Common/Args.cpp
index 3f0671d..b57b940 100644
--- a/Common/Args.cpp
+++ b/Common/Args.cpp
@@ -1,9 +1,8 @@
 //===- Args.cpp -----------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -18,6 +17,15 @@
 using namespace llvm;
 using namespace lld;
 
+// TODO(sbc): Remove this once CGOptLevel can be set completely based on bitcode
+// function metadata.
+CodeGenOpt::Level lld::args::getCGOptLevel(int OptLevelLTO) {
+  if (OptLevelLTO == 3)
+    return CodeGenOpt::Aggressive;
+  assert(OptLevelLTO < 3);
+  return CodeGenOpt::Default;
+}
+
 int lld::args::getInteger(opt::InputArgList &Args, unsigned Key, int Default) {
   auto *A = Args.getLastArg(Key);
   if (!A)
diff --git a/Common/ErrorHandler.cpp b/Common/ErrorHandler.cpp
index c059516..7c68353 100644
--- a/Common/ErrorHandler.cpp
+++ b/Common/ErrorHandler.cpp
@@ -1,9 +1,8 @@
 //===- ErrorHandler.cpp ---------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/Common/Memory.cpp b/Common/Memory.cpp
index efc5bcc..5a6ead4 100644
--- a/Common/Memory.cpp
+++ b/Common/Memory.cpp
@@ -1,9 +1,8 @@
 //===- Memory.cpp ---------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/Common/Reproduce.cpp b/Common/Reproduce.cpp
index 7be4ea6..cae8512 100644
--- a/Common/Reproduce.cpp
+++ b/Common/Reproduce.cpp
@@ -1,9 +1,8 @@
 //===- Reproduce.cpp - Utilities for creating reproducers -----------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/Common/Strings.cpp b/Common/Strings.cpp
index 6f74865..afd5bd3 100644
--- a/Common/Strings.cpp
+++ b/Common/Strings.cpp
@@ -1,9 +1,8 @@
 //===- Strings.cpp -------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/Common/TargetOptionsCommandFlags.cpp b/Common/TargetOptionsCommandFlags.cpp
index 7a3fc51..d4c29d7 100644
--- a/Common/TargetOptionsCommandFlags.cpp
+++ b/Common/TargetOptionsCommandFlags.cpp
@@ -1,9 +1,8 @@
 //===-- TargetOptionsCommandFlags.cpp ---------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -20,16 +19,17 @@
 #include "llvm/Target/TargetOptions.h"
 
 // Define an externally visible version of
-// InitTargetOptionsFromCodeGenFlags, so that its functionality can be
+// initTargetOptionsFromCodeGenFlags, so that its functionality can be
 // used without having to include llvm/CodeGen/CommandFlags.inc, which
 // would lead to multiple definitions of the command line flags.
-llvm::TargetOptions lld::InitTargetOptionsFromCodeGenFlags() {
+llvm::TargetOptions lld::initTargetOptionsFromCodeGenFlags() {
   return ::InitTargetOptionsFromCodeGenFlags();
 }
 
-llvm::Optional<llvm::CodeModel::Model> lld::GetCodeModelFromCMModel() {
+llvm::Optional<llvm::CodeModel::Model> lld::getCodeModelFromCMModel() {
   return getCodeModel();
 }
 
-std::string lld::GetCPUStr() { return ::getCPUStr(); }
-std::vector<std::string> lld::GetMAttrs() { return ::MAttrs; }
+std::string lld::getCPUStr() { return ::getCPUStr(); }
+
+std::vector<std::string> lld::getMAttrs() { return ::MAttrs; }
diff --git a/Common/Threads.cpp b/Common/Threads.cpp
index c64b8c3..5e0af28 100644
--- a/Common/Threads.cpp
+++ b/Common/Threads.cpp
@@ -1,9 +1,8 @@
 //===- Threads.cpp --------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/Common/Timer.cpp b/Common/Timer.cpp
index 89f9829..3086253 100644
--- a/Common/Timer.cpp
+++ b/Common/Timer.cpp
@@ -1,9 +1,8 @@
 //===- Timer.cpp ----------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/Common/Version.cpp b/Common/Version.cpp
index 6226c9a..41a3236 100644
--- a/Common/Version.cpp
+++ b/Common/Version.cpp
@@ -1,9 +1,8 @@
 //===- lib/Common/Version.cpp - LLD Version Number ---------------*- C++-=====//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/ELF/AArch64ErrataFix.cpp b/ELF/AArch64ErrataFix.cpp
index ac753cb..a0653b9 100644
--- a/ELF/AArch64ErrataFix.cpp
+++ b/ELF/AArch64ErrataFix.cpp
@@ -1,9 +1,8 @@
 //===- AArch64ErrataFix.cpp -----------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 // This file implements Section Patching for the purpose of working around
diff --git a/ELF/AArch64ErrataFix.h b/ELF/AArch64ErrataFix.h
index edd154d..48ddb7c 100644
--- a/ELF/AArch64ErrataFix.h
+++ b/ELF/AArch64ErrataFix.h
@@ -1,9 +1,8 @@
 //===- AArch64ErrataFix.h ---------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/Arch/AArch64.cpp b/ELF/Arch/AArch64.cpp
index 08ffe2a..694da89 100644
--- a/ELF/Arch/AArch64.cpp
+++ b/ELF/Arch/AArch64.cpp
@@ -1,9 +1,8 @@
 //===- AArch64.cpp --------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/Arch/AMDGPU.cpp b/ELF/Arch/AMDGPU.cpp
index a7c6c84..4d863fa 100644
--- a/ELF/Arch/AMDGPU.cpp
+++ b/ELF/Arch/AMDGPU.cpp
@@ -1,9 +1,8 @@
 //===- AMDGPU.cpp ---------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/Arch/ARM.cpp b/ELF/Arch/ARM.cpp
index 5f1485f..321b327 100644
--- a/ELF/Arch/ARM.cpp
+++ b/ELF/Arch/ARM.cpp
@@ -1,9 +1,8 @@
 //===- ARM.cpp ------------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -491,14 +490,12 @@
     break;
   case R_ARM_MOVT_ABS:
   case R_ARM_MOVT_PREL:
-    checkInt(Loc, Val, 32, Type);
     write32le(Loc, (read32le(Loc) & ~0x000f0fff) |
                        (((Val >> 16) & 0xf000) << 4) | ((Val >> 16) & 0xfff));
     break;
   case R_ARM_THM_MOVT_ABS:
   case R_ARM_THM_MOVT_PREL:
     // Encoding T1: A = imm4:i:imm3:imm8
-    checkInt(Loc, Val, 32, Type);
     write16le(Loc,
               0xf2c0 |                     // opcode
                   ((Val >> 17) & 0x0400) | // i
diff --git a/ELF/Arch/AVR.cpp b/ELF/Arch/AVR.cpp
index 637da37..9ccbd64 100644
--- a/ELF/Arch/AVR.cpp
+++ b/ELF/Arch/AVR.cpp
@@ -1,9 +1,8 @@
 //===- AVR.cpp ------------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/ELF/Arch/Hexagon.cpp b/ELF/Arch/Hexagon.cpp
index b4d33be..580600a 100644
--- a/ELF/Arch/Hexagon.cpp
+++ b/ELF/Arch/Hexagon.cpp
@@ -1,9 +1,8 @@
 //===-- Hexagon.cpp -------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/Arch/MSP430.cpp b/ELF/Arch/MSP430.cpp
new file mode 100644
index 0000000..e104c8c
--- /dev/null
+++ b/ELF/Arch/MSP430.cpp
@@ -0,0 +1,93 @@
+//===- MSP430.cpp ---------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// The MSP430 is a 16-bit microcontroller RISC architecture. The instruction set
+// has only 27 core instructions orthogonally augmented with a variety
+// of addressing modes for source and destination operands. Entire address space
+// of MSP430 is 64KB (the extended MSP430X architecture is not considered here).
+// A typical MSP430 MCU has several kilobytes of RAM and ROM, plenty
+// of peripherals and is generally optimized for a low power consumption.
+//
+//===----------------------------------------------------------------------===//
+
+#include "InputFiles.h"
+#include "Symbols.h"
+#include "Target.h"
+#include "lld/Common/ErrorHandler.h"
+#include "llvm/Object/ELF.h"
+#include "llvm/Support/Endian.h"
+
+using namespace llvm;
+using namespace llvm::object;
+using namespace llvm::support::endian;
+using namespace llvm::ELF;
+using namespace lld;
+using namespace lld::elf;
+
+namespace {
+class MSP430 final : public TargetInfo {
+public:
+  MSP430();
+  RelExpr getRelExpr(RelType Type, const Symbol &S,
+                     const uint8_t *Loc) const override;
+  void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
+};
+} // namespace
+
+MSP430::MSP430() {
+  // mov.b #0, r3
+  TrapInstr = {0x43, 0x43, 0x43, 0x43};
+}
+
+RelExpr MSP430::getRelExpr(RelType Type, const Symbol &S,
+                           const uint8_t *Loc) const {
+  switch (Type) {
+  case R_MSP430_10_PCREL:
+  case R_MSP430_16_PCREL:
+  case R_MSP430_16_PCREL_BYTE:
+  case R_MSP430_2X_PCREL:
+  case R_MSP430_RL_PCREL:
+  case R_MSP430_SYM_DIFF:
+    return R_PC;
+  default:
+    return R_ABS;
+  }
+}
+
+void MSP430::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
+  switch (Type) {
+  case R_MSP430_8:
+    checkIntUInt(Loc, Val, 8, Type);
+    *Loc = Val;
+    break;
+  case R_MSP430_16:
+  case R_MSP430_16_PCREL:
+  case R_MSP430_16_BYTE:
+  case R_MSP430_16_PCREL_BYTE:
+    checkIntUInt(Loc, Val, 16, Type);
+    write16le(Loc, Val);
+    break;
+  case R_MSP430_32:
+    checkIntUInt(Loc, Val, 32, Type);
+    write32le(Loc, Val);
+    break;
+  case R_MSP430_10_PCREL: {
+    int16_t Offset = ((int16_t)Val >> 1) - 1;
+    checkInt(Loc, Offset, 10, Type);
+    write16le(Loc, (read16le(Loc) & 0xFC00) | (Offset & 0x3FF));
+    break;
+  }
+  default:
+    error(getErrorLocation(Loc) + "unrecognized reloc " + toString(Type));
+  }
+}
+
+TargetInfo *elf::getMSP430TargetInfo() {
+  static MSP430 Target;
+  return &Target;
+}
diff --git a/ELF/Arch/Mips.cpp b/ELF/Arch/Mips.cpp
index 23b0c1d..a6d7e19 100644
--- a/ELF/Arch/Mips.cpp
+++ b/ELF/Arch/Mips.cpp
@@ -1,9 +1,8 @@
 //===- MIPS.cpp -----------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/Arch/MipsArchTree.cpp b/ELF/Arch/MipsArchTree.cpp
index 98ceac3..562a5ff 100644
--- a/ELF/Arch/MipsArchTree.cpp
+++ b/ELF/Arch/MipsArchTree.cpp
@@ -1,9 +1,8 @@
 //===- MipsArchTree.cpp --------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===---------------------------------------------------------------------===//
 //
diff --git a/ELF/Arch/PPC.cpp b/ELF/Arch/PPC.cpp
index 7673780..9a32e8c 100644
--- a/ELF/Arch/PPC.cpp
+++ b/ELF/Arch/PPC.cpp
@@ -1,9 +1,8 @@
 //===- PPC.cpp ------------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/Arch/PPC64.cpp b/ELF/Arch/PPC64.cpp
index 4d42a26..4f5aa45 100644
--- a/ELF/Arch/PPC64.cpp
+++ b/ELF/Arch/PPC64.cpp
@@ -1,9 +1,8 @@
 //===- PPC64.cpp ----------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -99,10 +98,16 @@
   return 0;
 }
 
+bool elf::isPPC64SmallCodeModelTocReloc(RelType Type) {
+  // The only small code model relocations that access the .toc section.
+  return Type == R_PPC64_TOC16 || Type == R_PPC64_TOC16_DS;
+}
+
 namespace {
 class PPC64 final : public TargetInfo {
 public:
   PPC64();
+  int getTlsGdRelaxSkip(RelType Type) const override;
   uint32_t calcEFlags() const override;
   RelExpr getRelExpr(RelType Type, const Symbol &S,
                      const uint8_t *Loc) const override;
@@ -233,6 +238,20 @@
   write32(TrapInstr.data(), 0x7fe00008);
 }
 
+int PPC64::getTlsGdRelaxSkip(RelType Type) const {
+  // A __tls_get_addr call instruction is marked with 2 relocations:
+  //
+  //   R_PPC64_TLSGD / R_PPC64_TLSLD: marker relocation
+  //   R_PPC64_REL24: __tls_get_addr
+  //
+  // After the relaxation we no longer call __tls_get_addr and should skip both
+  // relocations to not create a false dependence on __tls_get_addr being
+  // defined.
+  if (Type == R_PPC64_TLSGD || Type == R_PPC64_TLSLD)
+    return 2;
+  return 1;
+}
+
 static uint32_t getEFlags(InputFile *File) {
   if (Config->EKind == ELF64BEKind)
     return cast<ObjFile<ELF64BE>>(File)->getObj().getHeader()->e_flags;
@@ -597,17 +616,27 @@
   }
 }
 
-static bool isTocRelType(RelType Type) {
-  return Type == R_PPC64_TOC16_HA || Type == R_PPC64_TOC16_LO_DS ||
-         Type == R_PPC64_TOC16_LO;
+static bool isTocOptType(RelType Type) {
+  switch (Type) {
+  case R_PPC64_GOT16_HA:
+  case R_PPC64_GOT16_LO_DS:
+  case R_PPC64_TOC16_HA:
+  case R_PPC64_TOC16_LO_DS:
+  case R_PPC64_TOC16_LO:
+    return true;
+  default:
+    return false;
+  }
 }
 
 void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
-  // We need to save the original relocation type to determine if we should
-  // toc-optimize the instructions being relocated.
-  bool IsTocRelType = isTocRelType(Type);
-  // For TOC-relative and GOT-indirect relocations, proceed in terms of the
-  // corresponding ADDR16 relocation type.
+  // We need to save the original relocation type to use in diagnostics, and
+  // use the original type to determine if we should toc-optimize the
+  // instructions being relocated.
+  RelType OriginalType = Type;
+  bool ShouldTocOptimize =  isTocOptType(Type);
+  // For dynamic thread pointer relative, toc-relative, and got-indirect
+  // relocations, proceed in terms of the corresponding ADDR16 relocation type.
   std::tie(Type, Val) = toAddr16Rel(Type, Val);
 
   switch (Type) {
@@ -620,22 +649,22 @@
   }
   case R_PPC64_ADDR16:
   case R_PPC64_TPREL16:
-    checkInt(Loc, Val, 16, Type);
+    checkInt(Loc, Val, 16, OriginalType);
     write16(Loc, Val);
     break;
   case R_PPC64_ADDR16_DS:
   case R_PPC64_TPREL16_DS: {
-    checkInt(Loc, Val, 16, Type);
+    checkInt(Loc, Val, 16, OriginalType);
     // DQ-form instructions use bits 28-31 as part of the instruction encoding
     // DS-form instructions only use bits 30-31.
     uint16_t Mask = isDQFormInstruction(readInstrFromHalf16(Loc)) ? 0xF : 0x3;
-    checkAlignment(Loc, lo(Val), Mask + 1, Type);
+    checkAlignment(Loc, lo(Val), Mask + 1, OriginalType);
     write16(Loc, (read16(Loc) & Mask) | lo(Val));
   } break;
   case R_PPC64_ADDR16_HA:
   case R_PPC64_REL16_HA:
   case R_PPC64_TPREL16_HA:
-    if (Config->TocOptimize && IsTocRelType && ha(Val) == 0)
+    if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0)
       writeInstrFromHalf16(Loc, 0x60000000);
     else
       write16(Loc, ha(Val));
@@ -667,7 +696,7 @@
     // When the high-adjusted part of a toc relocation evalutes to 0, it is
     // changed into a nop. The lo part then needs to be updated to use the
     // toc-pointer register r2, as the base register.
-    if (Config->TocOptimize && IsTocRelType && ha(Val) == 0) {
+    if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0) {
       uint32_t Instr = readInstrFromHalf16(Loc);
       if (isInstructionUpdateForm(Instr))
         error(getErrorLocation(Loc) +
@@ -684,8 +713,8 @@
     // DS-form instructions only use bits 30-31.
     uint32_t Inst = readInstrFromHalf16(Loc);
     uint16_t Mask = isDQFormInstruction(Inst) ? 0xF : 0x3;
-    checkAlignment(Loc, lo(Val), Mask + 1, Type);
-    if (Config->TocOptimize && IsTocRelType && ha(Val) == 0) {
+    checkAlignment(Loc, lo(Val), Mask + 1, OriginalType);
+    if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0) {
       // When the high-adjusted part of a toc relocation evalutes to 0, it is
       // changed into a nop. The lo part then needs to be updated to use the toc
       // pointer register r2, as the base register.
diff --git a/ELF/Arch/RISCV.cpp b/ELF/Arch/RISCV.cpp
index 461e8d3..29a5ae6 100644
--- a/ELF/Arch/RISCV.cpp
+++ b/ELF/Arch/RISCV.cpp
@@ -1,9 +1,8 @@
 //===- RISCV.cpp ----------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/Arch/SPARCV9.cpp b/ELF/Arch/SPARCV9.cpp
index 831aa20..50017d0 100644
--- a/ELF/Arch/SPARCV9.cpp
+++ b/ELF/Arch/SPARCV9.cpp
@@ -1,9 +1,8 @@
 //===- SPARCV9.cpp --------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/Arch/X86.cpp b/ELF/Arch/X86.cpp
index e910375..307f94f 100644
--- a/ELF/Arch/X86.cpp
+++ b/ELF/Arch/X86.cpp
@@ -1,9 +1,8 @@
 //===- X86.cpp ------------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -24,6 +23,7 @@
 class X86 : public TargetInfo {
 public:
   X86();
+  int getTlsGdRelaxSkip(RelType Type) const override;
   RelExpr getRelExpr(RelType Type, const Symbol &S,
                      const uint8_t *Loc) const override;
   int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override;
@@ -59,7 +59,6 @@
   GotPltEntrySize = 4;
   PltEntrySize = 16;
   PltHeaderSize = 16;
-  TlsGdRelaxSkip = 2;
   TrapInstr = {0xcc, 0xcc, 0xcc, 0xcc}; // 0xcc = INT3
 
   // Align to the non-PAE large page size (known as a superpage or huge page).
@@ -67,10 +66,20 @@
   DefaultImageBase = 0x400000;
 }
 
-static bool hasBaseReg(uint8_t ModRM) { return (ModRM & 0xc7) != 0x5; }
+int X86::getTlsGdRelaxSkip(RelType Type) const {
+  return 2;
+}
 
 RelExpr X86::getRelExpr(RelType Type, const Symbol &S,
                         const uint8_t *Loc) const {
+  // There are 4 different TLS variable models with varying degrees of
+  // flexibility and performance. LocalExec and InitialExec models are fast but
+  // less-flexible models. If they are in use, we set DF_STATIC_TLS flag in the
+  // dynamic section to let runtime know about that.
+  if (Type == R_386_TLS_LE || Type == R_386_TLS_LE_32 || Type == R_386_TLS_IE ||
+      Type == R_386_TLS_GOTIE)
+    Config->HasStaticTlsModel = true;
+
   switch (Type) {
   case R_386_8:
   case R_386_16:
@@ -108,14 +117,14 @@
     // load an GOT address to a register, which is usually %ebx.
     //
     // So, there are two ways to refer to symbol foo's GOT entry: foo@GOT or
-    // foo@GOT(%reg).
+    // foo@GOT(%ebx).
     //
     // foo@GOT is not usable in PIC. If we are creating a PIC output and if we
     // find such relocation, we should report an error. foo@GOT is resolved to
     // an *absolute* address of foo's GOT entry, because both GOT address and
     // foo's offset are known. In other words, it's G + A.
     //
-    // foo@GOT(%reg) needs to be resolved to a *relative* offset from a GOT to
+    // foo@GOT(%ebx) needs to be resolved to a *relative* offset from a GOT to
     // foo's GOT entry in the table, because GOT address is not known but foo's
     // offset in the table is known. It's G + A - GOT.
     //
@@ -123,12 +132,12 @@
     // different use cases. In order to distinguish them, we have to read a
     // machine instruction.
     //
-    // The following code implements it. We assume that Loc[0] is the first
-    // byte of a displacement or an immediate field of a valid machine
+    // The following code implements it. We assume that Loc[0] is the first byte
+    // of a displacement or an immediate field of a valid machine
     // instruction. That means a ModRM byte is at Loc[-1]. By taking a look at
-    // the byte, we can determine whether the instruction is register-relative
-    // (i.e. it was generated for foo@GOT(%reg)) or absolute (i.e. foo@GOT).
-    return hasBaseReg(Loc[-1]) ? R_GOT_FROM_END : R_GOT;
+    // the byte, we can determine whether the instruction uses the operand as an
+    // absolute address (R_GOT) or a register-relative address (R_GOT_FROM_END).
+    return (Loc[-1] & 0xc7) == 0x5 ? R_GOT : R_GOT_FROM_END;
   case R_386_TLS_GOTIE:
     return R_GOT_FROM_END;
   case R_386_GOTOFF:
diff --git a/ELF/Arch/X86_64.cpp b/ELF/Arch/X86_64.cpp
index 0631415..bfe2ba8 100644
--- a/ELF/Arch/X86_64.cpp
+++ b/ELF/Arch/X86_64.cpp
@@ -1,9 +1,8 @@
 //===- X86_64.cpp ---------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -26,6 +25,7 @@
 template <class ELFT> class X86_64 : public TargetInfo {
 public:
   X86_64();
+  int getTlsGdRelaxSkip(RelType Type) const override;
   RelExpr getRelExpr(RelType Type, const Symbol &S,
                      const uint8_t *Loc) const override;
   RelType getDynRel(RelType Type) const override;
@@ -66,7 +66,6 @@
   GotPltEntrySize = 8;
   PltEntrySize = 16;
   PltHeaderSize = 16;
-  TlsGdRelaxSkip = 2;
   TrapInstr = {0xcc, 0xcc, 0xcc, 0xcc}; // 0xcc = INT3
 
   // Align to the large page size (known as a superpage or huge page).
@@ -75,8 +74,16 @@
 }
 
 template <class ELFT>
+int X86_64<ELFT>::getTlsGdRelaxSkip(RelType Type) const {
+  return 2;
+}
+
+template <class ELFT>
 RelExpr X86_64<ELFT>::getRelExpr(RelType Type, const Symbol &S,
                                  const uint8_t *Loc) const {
+  if (Type == R_X86_64_GOTTPOFF)
+    Config->HasStaticTlsModel = true;
+
   switch (Type) {
   case R_X86_64_8:
   case R_X86_64_16:
@@ -97,6 +104,8 @@
     return R_SIZE;
   case R_X86_64_PLT32:
     return R_PLT_PC;
+  case R_X86_64_PC8:
+  case R_X86_64_PC16:
   case R_X86_64_PC32:
   case R_X86_64_PC64:
     return R_PC;
@@ -264,15 +273,6 @@
 template <class ELFT>
 void X86_64<ELFT>::relaxTlsLdToLe(uint8_t *Loc, RelType Type,
                                   uint64_t Val) const {
-  // Convert
-  //   leaq bar@tlsld(%rip), %rdi
-  //   callq __tls_get_addr@PLT
-  //   leaq bar@dtpoff(%rax), %rcx
-  // to
-  //   .word 0x6666
-  //   .byte 0x66
-  //   mov %fs:0,%rax
-  //   leaq bar@tpoff(%rax), %rcx
   if (Type == R_X86_64_DTPOFF64) {
     write64le(Loc, Val);
     return;
@@ -287,7 +287,37 @@
       0x66,                                                 // .byte 0x66
       0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:0,%rax
   };
-  memcpy(Loc - 3, Inst, sizeof(Inst));
+
+  if (Loc[4] == 0xe8) {
+    // Convert
+    //   leaq bar@tlsld(%rip), %rdi           # 48 8d 3d <Loc>
+    //   callq __tls_get_addr@PLT             # e8 <disp32>
+    //   leaq bar@dtpoff(%rax), %rcx
+    // to
+    //   .word 0x6666
+    //   .byte 0x66
+    //   mov %fs:0,%rax
+    //   leaq bar@tpoff(%rax), %rcx
+    memcpy(Loc - 3, Inst, sizeof(Inst));
+    return;
+  }
+
+  if (Loc[4] == 0xff && Loc[5] == 0x15) {
+    // Convert
+    //   leaq  x@tlsld(%rip),%rdi               # 48 8d 3d <Loc>
+    //   call *__tls_get_addr@GOTPCREL(%rip)    # ff 15 <disp32>
+    // to
+    //   .long  0x66666666
+    //   movq   %fs:0,%rax
+    // See "Table 11.9: LD -> LE Code Transition (LP64)" in
+    // https://raw.githubusercontent.com/wiki/hjl-tools/x86-psABI/x86-64-psABI-1.0.pdf
+    Loc[-3] = 0x66;
+    memcpy(Loc - 2, Inst, sizeof(Inst));
+    return;
+  }
+
+  error(getErrorLocation(Loc - 3) +
+        "expected R_X86_64_PLT32 or R_X86_64_GOTPCRELX after R_X86_64_TLSLD");
 }
 
 template <class ELFT>
@@ -297,10 +327,18 @@
     checkUInt(Loc, Val, 8, Type);
     *Loc = Val;
     break;
+  case R_X86_64_PC8:
+    checkInt(Loc, Val, 8, Type);
+    *Loc = Val;
+    break;
   case R_X86_64_16:
     checkUInt(Loc, Val, 16, Type);
     write16le(Loc, Val);
     break;
+  case R_X86_64_PC16:
+    checkInt(Loc, Val, 16, Type);
+    write16le(Loc, Val);
+    break;
   case R_X86_64_32:
     checkUInt(Loc, Val, 32, Type);
     write32le(Loc, Val);
diff --git a/ELF/Bits.h b/ELF/Bits.h
deleted file mode 100644
index 13d4032..0000000
--- a/ELF/Bits.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===- Bits.h ---------------------------------------------------*- C++ -*-===//
-//
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_ELF_BITS_H
-#define LLD_ELF_BITS_H
-
-#include "Config.h"
-#include "llvm/Support/Endian.h"
-
-namespace lld {
-namespace elf {
-
-inline uint64_t readUint(uint8_t *Buf) {
-  if (Config->Is64)
-    return llvm::support::endian::read64(Buf, Config->Endianness);
-  return llvm::support::endian::read32(Buf, Config->Endianness);
-}
-
-inline void writeUint(uint8_t *Buf, uint64_t Val) {
-  if (Config->Is64)
-    llvm::support::endian::write64(Buf, Val, Config->Endianness);
-  else
-    llvm::support::endian::write32(Buf, Val, Config->Endianness);
-}
-
-} // namespace elf
-} // namespace lld
-
-#endif
diff --git a/ELF/CMakeLists.txt b/ELF/CMakeLists.txt
index 51fc1e5..a1c23b0 100644
--- a/ELF/CMakeLists.txt
+++ b/ELF/CMakeLists.txt
@@ -15,6 +15,7 @@
   Arch/Hexagon.cpp
   Arch/Mips.cpp
   Arch/MipsArchTree.cpp
+  Arch/MSP430.cpp
   Arch/PPC.cpp
   Arch/PPC64.cpp
   Arch/RISCV.cpp
diff --git a/ELF/CallGraphSort.cpp b/ELF/CallGraphSort.cpp
index 2a7d786..2e50c50 100644
--- a/ELF/CallGraphSort.cpp
+++ b/ELF/CallGraphSort.cpp
@@ -1,9 +1,8 @@
 //===- CallGraphSort.cpp --------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/ELF/CallGraphSort.h b/ELF/CallGraphSort.h
index 3f96dc8..5a09227 100644
--- a/ELF/CallGraphSort.h
+++ b/ELF/CallGraphSort.h
@@ -1,9 +1,8 @@
 //===- CallGraphSort.h ------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/Config.h b/ELF/Config.h
index 8fb760e..4e6c44f 100644
--- a/ELF/Config.h
+++ b/ELF/Config.h
@@ -1,9 +1,8 @@
 //===- Config.h -------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -18,6 +17,7 @@
 #include "llvm/Support/CachePruning.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Endian.h"
+#include <atomic>
 #include <vector>
 
 namespace lld {
@@ -120,6 +120,7 @@
                   uint64_t>
       CallGraphProfile;
   bool AllowMultipleDefinition;
+  bool AllowShlibUndefined;
   bool AndroidPackDynRelocs;
   bool ARMHasBlx = false;
   bool ARMHasMovtMovw = false;
@@ -159,6 +160,7 @@
   bool OFormatBinary;
   bool Omagic;
   bool OptRemarksWithHotness;
+  bool PicThunk;
   bool Pie;
   bool PrintGcSections;
   bool PrintIcfSections;
@@ -252,6 +254,20 @@
   // if that's true.)
   bool IsMips64EL;
 
+  // True if we need to set the DF_STATIC_TLS flag to an output file,
+  // which works as a hint to the dynamic loader that the file contains
+  // code compiled with the static TLS model. The thread-local variable
+  // compiled with the static TLS model is faster but less flexible, and
+  // it may not be loaded using dlopen().
+  //
+  // We set this flag to true when we see a relocation for the static TLS
+  // model. Once this becomes true, it will never become false.
+  //
+  // Since the flag is updated by multi-threaded code, we use std::atomic.
+  // (Writing to a variable is not considered thread-safe even if the
+  // variable is boolean and we always set the same value from all threads.)
+  std::atomic<bool> HasStaticTlsModel{false};
+
   // Holds set of ELF header flags for the target.
   uint32_t EFlags = 0;
 
diff --git a/ELF/DWARF.cpp b/ELF/DWARF.cpp
index 17e1a4d..ad1363b 100644
--- a/ELF/DWARF.cpp
+++ b/ELF/DWARF.cpp
@@ -1,9 +1,8 @@
 //===- DWARF.cpp ----------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/ELF/DWARF.h b/ELF/DWARF.h
index 8ecf02c..0979615 100644
--- a/ELF/DWARF.h
+++ b/ELF/DWARF.h
@@ -1,9 +1,8 @@
 //===- DWARF.h -----------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===-------------------------------------------------------------------===//
 
diff --git a/ELF/Driver.cpp b/ELF/Driver.cpp
index 51daa81..e2aa7e9 100644
--- a/ELF/Driver.cpp
+++ b/ELF/Driver.cpp
@@ -1,9 +1,8 @@
 //===- Driver.cpp ---------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -130,7 +129,7 @@
           .Cases("elf32btsmip", "elf32btsmipn32", {ELF32BEKind, EM_MIPS})
           .Cases("elf32ltsmip", "elf32ltsmipn32", {ELF32LEKind, EM_MIPS})
           .Case("elf32lriscv", {ELF32LEKind, EM_RISCV})
-          .Case("elf32ppc", {ELF32BEKind, EM_PPC})
+          .Cases("elf32ppc", "elf32ppclinux", {ELF32BEKind, EM_PPC})
           .Case("elf64btsmip", {ELF64BEKind, EM_MIPS})
           .Case("elf64ltsmip", {ELF64LEKind, EM_MIPS})
           .Case("elf64lriscv", {ELF64LEKind, EM_RISCV})
@@ -371,6 +370,7 @@
 
   // Interpret this flag early because error() depends on them.
   errorHandler().ErrorLimit = args::getInteger(Args, OPT_error_limit, 20);
+  checkZOptions(Args);
 
   // Handle -help
   if (Args.hasArg(OPT_help)) {
@@ -411,7 +411,6 @@
   }
 
   readConfigs(Args);
-  checkZOptions(Args);
 
   // The behavior of -v or --version is a bit strange, but this is
   // needed for compatibility with GNU linkers.
@@ -757,6 +756,9 @@
       Args.hasFlag(OPT_allow_multiple_definition,
                    OPT_no_allow_multiple_definition, false) ||
       hasZOption(Args, "muldefs");
+  Config->AllowShlibUndefined =
+      Args.hasFlag(OPT_allow_shlib_undefined, OPT_no_allow_shlib_undefined,
+                   Args.hasArg(OPT_shared));
   Config->AuxiliaryList = args::getStrings(Args, OPT_auxiliary);
   Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic);
   Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions);
@@ -1006,6 +1008,7 @@
   Config->Endianness = Config->IsLE ? endianness::little : endianness::big;
   Config->IsMips64EL = (K == ELF64LEKind && M == EM_MIPS);
   Config->Pic = Config->Pie || Config->Shared;
+  Config->PicThunk = Args.hasArg(OPT_pic_veneer, Config->Pic);
   Config->Wordsize = Config->Is64 ? 8 : 4;
 
   // ELF defines two different ways to store relocation addends as shown below:
@@ -1550,6 +1553,9 @@
   Out::ElfHeader = make<OutputSection>("", 0, SHF_ALLOC);
   Out::ElfHeader->Size = sizeof(typename ELFT::Ehdr);
 
+  // Create wrapped symbols for -wrap option.
+  std::vector<WrappedSymbol> Wrapped = addWrappedSymbols<ELFT>(Args);
+
   // We need to create some reserved symbols such as _end. Create them.
   if (!Config->Relocatable)
     addReservedSymbols();
@@ -1562,9 +1568,6 @@
   if (!Config->Relocatable)
     Symtab->scanVersionScript();
 
-  // Create wrapped symbols for -wrap option.
-  std::vector<WrappedSymbol> Wrapped = addWrappedSymbols<ELFT>(Args);
-
   // Do link-time optimization if given files are LLVM bitcode files.
   // This compiles bitcode files into real object files.
   //
diff --git a/ELF/Driver.h b/ELF/Driver.h
index 81d7f60..dd66893 100644
--- a/ELF/Driver.h
+++ b/ELF/Driver.h
@@ -1,9 +1,8 @@
 //===- Driver.h -------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/DriverUtils.cpp b/ELF/DriverUtils.cpp
index e51d02e..4f2ef4d 100644
--- a/ELF/DriverUtils.cpp
+++ b/ELF/DriverUtils.cpp
@@ -1,9 +1,8 @@
 //===- DriverUtils.cpp ----------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/ELF/EhFrame.cpp b/ELF/EhFrame.cpp
index 95d444b..1d3745e 100644
--- a/ELF/EhFrame.cpp
+++ b/ELF/EhFrame.cpp
@@ -1,9 +1,8 @@
 //===- EhFrame.cpp -------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/ELF/EhFrame.h b/ELF/EhFrame.h
index 5112891..165d72b 100644
--- a/ELF/EhFrame.h
+++ b/ELF/EhFrame.h
@@ -1,9 +1,8 @@
 //===- EhFrame.h ------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/Filesystem.cpp b/ELF/Filesystem.cpp
index 5cf240e..957534a 100644
--- a/ELF/Filesystem.cpp
+++ b/ELF/Filesystem.cpp
@@ -1,9 +1,8 @@
 //===- Filesystem.cpp -----------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/ELF/Filesystem.h b/ELF/Filesystem.h
index 987a74a..c92a5d2 100644
--- a/ELF/Filesystem.h
+++ b/ELF/Filesystem.h
@@ -1,9 +1,8 @@
 //===- Filesystem.h ---------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/ICF.cpp b/ELF/ICF.cpp
index e917ae7..7c07a42 100644
--- a/ELF/ICF.cpp
+++ b/ELF/ICF.cpp
@@ -1,9 +1,8 @@
 //===- ICF.cpp ------------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -426,16 +425,17 @@
 // Combine the hashes of the sections referenced by the given section into its
 // hash.
 template <class ELFT, class RelTy>
-static void combineRelocHashes(InputSection *IS, ArrayRef<RelTy> Rels) {
-  uint32_t Hash = IS->Class[1];
+static void combineRelocHashes(unsigned Cnt, InputSection *IS,
+                               ArrayRef<RelTy> Rels) {
+  uint32_t Hash = IS->Class[Cnt % 2];
   for (RelTy Rel : Rels) {
     Symbol &S = IS->template getFile<ELFT>()->getRelocTargetSym(Rel);
     if (auto *D = dyn_cast<Defined>(&S))
       if (auto *RelSec = dyn_cast_or_null<InputSection>(D->Section))
-        Hash ^= RelSec->Class[1];
+        Hash += RelSec->Class[Cnt % 2];
   }
   // Set MSB to 1 to avoid collisions with non-hash IDs.
-  IS->Class[0] = Hash | (1U << 31);
+  IS->Class[(Cnt + 1) % 2] = Hash | (1U << 31);
 }
 
 static void print(const Twine &S) {
@@ -453,15 +453,17 @@
 
   // Initially, we use hash values to partition sections.
   parallelForEach(Sections, [&](InputSection *S) {
-    S->Class[1] = xxHash64(S->data());
+    S->Class[0] = xxHash64(S->data());
   });
 
-  parallelForEach(Sections, [&](InputSection *S) {
-    if (S->AreRelocsRela)
-      combineRelocHashes<ELFT>(S, S->template relas<ELFT>());
-    else
-      combineRelocHashes<ELFT>(S, S->template rels<ELFT>());
-  });
+  for (unsigned Cnt = 0; Cnt != 2; ++Cnt) {
+    parallelForEach(Sections, [&](InputSection *S) {
+      if (S->AreRelocsRela)
+        combineRelocHashes<ELFT>(Cnt, S, S->template relas<ELFT>());
+      else
+        combineRelocHashes<ELFT>(Cnt, S, S->template rels<ELFT>());
+    });
+  }
 
   // From now on, sections in Sections vector are ordered so that sections
   // in the same equivalence class are consecutive in the vector.
diff --git a/ELF/ICF.h b/ELF/ICF.h
index a6c8636..ed828fc 100644
--- a/ELF/ICF.h
+++ b/ELF/ICF.h
@@ -1,9 +1,8 @@
 //===- ICF.h --------------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/InputFiles.cpp b/ELF/InputFiles.cpp
index a85e5e6..c3e5b2f 100644
--- a/ELF/InputFiles.cpp
+++ b/ELF/InputFiles.cpp
@@ -1,9 +1,8 @@
 //===- InputFiles.cpp -----------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -320,17 +319,6 @@
   return Signature;
 }
 
-template <class ELFT>
-ArrayRef<typename ObjFile<ELFT>::Elf_Word>
-ObjFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) {
-  const ELFFile<ELFT> &Obj = this->getObj();
-  ArrayRef<Elf_Word> Entries =
-      CHECK(Obj.template getSectionContentsAsArray<Elf_Word>(&Sec), this);
-  if (Entries.empty() || Entries[0] != GRP_COMDAT)
-    fatal(toString(this) + ": unsupported SHT_GROUP format");
-  return Entries.slice(1);
-}
-
 template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) {
   // On a regular link we don't merge sections if -O0 (default is -O1). This
   // sometimes makes the linker significantly faster, although the output will
@@ -413,9 +401,8 @@
     const Elf_Shdr &Sec = ObjSections[I];
 
     if (Sec.sh_type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE)
-      CGProfile = check(
-          this->getObj().template getSectionContentsAsArray<Elf_CGProfile>(
-              &Sec));
+      CGProfile =
+          check(Obj.template getSectionContentsAsArray<Elf_CGProfile>(&Sec));
 
     // SHF_EXCLUDE'ed sections are discarded by the linker. However,
     // if -r is given, we'll let the final link discard such sections.
@@ -440,18 +427,25 @@
     case SHT_GROUP: {
       // De-duplicate section groups by their signatures.
       StringRef Signature = getShtGroupSignature(ObjSections, Sec);
-      bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second;
       this->Sections[I] = &InputSection::Discarded;
 
-      // We only support GRP_COMDAT type of group. Get the all entries of the
-      // section here to let getShtGroupEntries to check the type early for us.
-      ArrayRef<Elf_Word> Entries = getShtGroupEntries(Sec);
 
-      // If it is a new section group, we want to keep group members.
-      // Group leader sections, which contain indices of group members, are
-      // discarded because they are useless beyond this point. The only
-      // exception is the -r option because in order to produce re-linkable
-      // object files, we want to pass through basically everything.
+      ArrayRef<Elf_Word> Entries =
+          CHECK(Obj.template getSectionContentsAsArray<Elf_Word>(&Sec), this);
+      if (Entries.empty())
+        fatal(toString(this) + ": empty SHT_GROUP");
+
+      // The first word of a SHT_GROUP section contains flags. Currently,
+      // the standard defines only "GRP_COMDAT" flag for the COMDAT group.
+      // An group with the empty flag doesn't define anything; such sections
+      // are just skipped.
+      if (Entries[0] == 0)
+        continue;
+
+      if (Entries[0] != GRP_COMDAT)
+        fatal(toString(this) + ": unsupported SHT_GROUP format");
+
+      bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second;
       if (IsNew) {
         if (Config->Relocatable)
           this->Sections[I] = createInputSection(Sec);
@@ -459,7 +453,7 @@
       }
 
       // Otherwise, discard group members.
-      for (uint32_t SecIndex : Entries) {
+      for (uint32_t SecIndex : Entries.slice(1)) {
         if (SecIndex >= Size)
           fatal(toString(this) +
                 ": invalid section index in group: " + Twine(SecIndex));
@@ -739,7 +733,8 @@
   // sections. Drop those sections to avoid duplicate symbol errors.
   // FIXME: This is glibc PR20543, we should remove this hack once that has been
   // fixed for a while.
-  if (Name.startswith(".gnu.linkonce."))
+  if (Name == ".gnu.linkonce.t.__x86.get_pc_thunk.bx" ||
+      Name == ".gnu.linkonce.t.__i686.get_pc_thunk.bx")
     return &InputSection::Discarded;
 
   // If we are creating a new .build-id section, strip existing .build-id
@@ -867,7 +862,7 @@
 
 // Partially parse the shared object file so that we can call
 // getSoName on this object.
-template <class ELFT> void SharedFile<ELFT>::parseSoName() {
+template <class ELFT> void SharedFile<ELFT>::parseDynamic() {
   const Elf_Shdr *DynamicSec = nullptr;
   const ELFFile<ELFT> Obj = this->getObj();
   ArrayRef<Elf_Shdr> Sections = CHECK(Obj.sections(), this);
@@ -904,12 +899,16 @@
   ArrayRef<Elf_Dyn> Arr =
       CHECK(Obj.template getSectionContentsAsArray<Elf_Dyn>(DynamicSec), this);
   for (const Elf_Dyn &Dyn : Arr) {
-    if (Dyn.d_tag == DT_SONAME) {
+    if (Dyn.d_tag == DT_NEEDED) {
+      uint64_t Val = Dyn.getVal();
+      if (Val >= this->StringTable.size())
+        fatal(toString(this) + ": invalid DT_NEEDED entry");
+      DtNeeded.push_back(this->StringTable.data() + Val);
+    } else if (Dyn.d_tag == DT_SONAME) {
       uint64_t Val = Dyn.getVal();
       if (Val >= this->StringTable.size())
         fatal(toString(this) + ": invalid DT_SONAME entry");
       SoName = this->StringTable.data() + Val;
-      return;
     }
   }
 }
@@ -977,7 +976,7 @@
   return (Ret > UINT32_MAX) ? 0 : Ret;
 }
 
-// Fully parse the shared object file. This must be called after parseSoName().
+// Fully parse the shared object file. This must be called after parseDynamic().
 //
 // This function parses symbol versions. If a DSO has version information,
 // the file has a ".gnu.version_d" section which contains symbol version
@@ -1081,6 +1080,8 @@
   case Triple::mips64:
   case Triple::mips64el:
     return EM_MIPS;
+  case Triple::msp430:
+    return EM_MSP430;
   case Triple::ppc:
     return EM_PPC;
   case Triple::ppc64:
diff --git a/ELF/InputFiles.h b/ELF/InputFiles.h
index 5094ddd..105e5ec 100644
--- a/ELF/InputFiles.h
+++ b/ELF/InputFiles.h
@@ -1,9 +1,8 @@
 //===- InputFiles.h ---------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -114,6 +113,17 @@
   // True if this is an argument for --just-symbols. Usually false.
   bool JustSymbols = false;
 
+  // On PPC64 we need to keep track of which files contain small code model
+  // relocations that access the .toc section. To minimize the chance of a
+  // relocation overflow, files that do contain said relocations should have
+  // their .toc sections sorted closer to the .got section than files that do
+  // not contain any small code model relocations. Thats because the toc-pointer
+  // is defined to point at .got + 0x8000 and the instructions used with small
+  // code model relocations support immediates in the range [-0x8000, 0x7FFC],
+  // making the addressable range relative to the toc pointer
+  // [.got, .got + 0xFFFC].
+  bool PPC64SmallCodeModelTocRelocs = false;
+
   // GroupId is used for --warn-backrefs which is an optional error
   // checking feature. All files within the same --{start,end}-group or
   // --{start,end}-lib get the same group ID. Otherwise, each file gets a new
@@ -175,7 +185,6 @@
 
   StringRef getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
                                  const Elf_Shdr &Sec);
-  ArrayRef<Elf_Word> getShtGroupEntries(const Elf_Shdr &Sec);
 
 public:
   static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; }
@@ -324,6 +333,7 @@
 
 public:
   std::vector<const Elf_Verdef *> Verdefs;
+  std::vector<StringRef> DtNeeded;
   std::string SoName;
 
   static bool classof(const InputFile *F) {
@@ -332,7 +342,7 @@
 
   SharedFile(MemoryBufferRef M, StringRef DefaultSoName);
 
-  void parseSoName();
+  void parseDynamic();
   void parseRest();
   uint32_t getAlignment(ArrayRef<Elf_Shdr> Sections, const Elf_Sym &Sym);
   std::vector<const Elf_Verdef *> parseVerdefs();
@@ -350,6 +360,9 @@
   // data structures in the output file.
   std::map<const Elf_Verdef *, NeededVer> VerdefMap;
 
+  // Used for --no-allow-shlib-undefined.
+  bool AllNeededIsKnown;
+
   // Used for --as-needed
   bool IsNeeded;
 };
diff --git a/ELF/InputSection.cpp b/ELF/InputSection.cpp
index 30a9fc2..e70ea15 100644
--- a/ELF/InputSection.cpp
+++ b/ELF/InputSection.cpp
@@ -1,9 +1,8 @@
 //===- InputSection.cpp ---------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -288,14 +287,17 @@
 // Returns a source location string. Used to construct an error message.
 template <class ELFT>
 std::string InputSectionBase::getLocation(uint64_t Offset) {
+  std::string SecAndOffset = (Name + "+0x" + utohexstr(Offset)).str();
+
   // We don't have file for synthetic sections.
   if (getFile<ELFT>() == nullptr)
-    return (Config->OutputFile + ":(" + Name + "+0x" + utohexstr(Offset) + ")")
+    return (Config->OutputFile + ":(" + SecAndOffset + ")")
         .str();
 
   // First check if we can get desired values from debugging information.
   if (Optional<DILineInfo> Info = getFile<ELFT>()->getDILineInfo(this, Offset))
-    return Info->FileName + ":" + std::to_string(Info->Line);
+    return Info->FileName + ":" + std::to_string(Info->Line) + ":(" +
+           SecAndOffset + ")";
 
   // File->SourceFile contains STT_FILE symbol that contains a
   // source file name. If it's missing, we use an object file name.
@@ -304,10 +306,10 @@
     SrcFile = toString(File);
 
   if (Defined *D = getEnclosingFunction<ELFT>(Offset))
-    return SrcFile + ":(function " + toString(*D) + ")";
+    return SrcFile + ":(function " + toString(*D) + ": " + SecAndOffset + ")";
 
   // If there's no symbol, print out the offset in the section.
-  return (SrcFile + ":(" + Name + "+0x" + utohexstr(Offset) + ")").str();
+  return (SrcFile + ":(" + SecAndOffset + ")");
 }
 
 // This function is intended to be used for constructing an error message.
@@ -575,6 +577,10 @@
     // Variant 1. The thread pointer points to a TCB with a fixed 2-word size,
     // followed by a variable amount of alignment padding, followed by the TLS
     // segment.
+    //
+    // NB: While the ARM/AArch64 ABI formally has a 2-word TCB size, lld
+    // effectively increases the TCB size to 8 words for Android compatibility.
+    // It accomplishes this by increasing the segment's alignment.
     return alignTo(Config->Wordsize * 2, Out::TlsPhdr->p_align);
   case EM_386:
   case EM_X86_64:
@@ -605,7 +611,6 @@
   case R_ARM_SBREL:
     return Sym.getVA(A) - getARMStaticBase(Sym);
   case R_GOT:
-  case R_GOT_PLT:
   case R_RELAX_TLS_GD_TO_IE_ABS:
     return Sym.getGotVA() + A;
   case R_GOTONLY_PC:
@@ -624,7 +629,6 @@
   case R_RELAX_TLS_GD_TO_IE_GOT_OFF:
     return Sym.getGotOffset() + A;
   case R_AARCH64_GOT_PAGE_PC:
-  case R_AARCH64_GOT_PAGE_PC_PLT:
   case R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC:
     return getAArch64Page(Sym.getGotVA() + A) - getAArch64Page(P);
   case R_GOT_PC:
@@ -674,10 +678,6 @@
     uint64_t Val = Sym.isUndefWeak() ? P + A : Sym.getVA(A);
     return getAArch64Page(Val) - getAArch64Page(P);
   }
-  case R_AARCH64_PLT_PAGE_PC: {
-    uint64_t Val = Sym.isUndefWeak() ? P + A : Sym.getPltVA() + A;
-    return getAArch64Page(Val) - getAArch64Page(P);
-  }
   case R_RISCV_PC_INDIRECT: {
     if (const Relocation *HiRel = getRISCVPCRelHi20(&Sym, A))
       return getRelocTargetVA(File, HiRel->Type, HiRel->Addend, Sym.getVA(),
diff --git a/ELF/InputSection.h b/ELF/InputSection.h
index 34f411e..51c186d 100644
--- a/ELF/InputSection.h
+++ b/ELF/InputSection.h
@@ -1,9 +1,8 @@
 //===- InputSection.h -------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/LTO.cpp b/ELF/LTO.cpp
index ca44581..6eecb79 100644
--- a/ELF/LTO.cpp
+++ b/ELF/LTO.cpp
@@ -1,9 +1,8 @@
 //===- LTO.cpp ------------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -13,6 +12,7 @@
 #include "LinkerScript.h"
 #include "SymbolTable.h"
 #include "Symbols.h"
+#include "lld/Common/Args.h"
 #include "lld/Common/ErrorHandler.h"
 #include "lld/Common/TargetOptionsCommandFlags.h"
 #include "llvm/ADT/STLExtras.h"
@@ -68,7 +68,7 @@
   lto::Config C;
 
   // LLD supports the new relocations and address-significance tables.
-  C.Options = InitTargetOptionsFromCodeGenFlags();
+  C.Options = initTargetOptionsFromCodeGenFlags();
   C.Options.RelaxELFRelocations = true;
   C.Options.EmitAddrsig = true;
 
@@ -83,12 +83,13 @@
   else
     C.RelocModel = Reloc::Static;
 
-  C.CodeModel = GetCodeModelFromCMModel();
+  C.CodeModel = getCodeModelFromCMModel();
   C.DisableVerify = Config->DisableVerify;
   C.DiagHandler = diagnosticHandler;
   C.OptLevel = Config->LTOO;
-  C.CPU = GetCPUStr();
-  C.MAttrs = GetMAttrs();
+  C.CPU = getCPUStr();
+  C.MAttrs = getMAttrs();
+  C.CGOptLevel = args::getCGOptLevel(Config->LTOO);
 
   // Set up a custom pipeline if we've been asked to.
   C.OptPipeline = Config->LTONewPmPasses;
diff --git a/ELF/LTO.h b/ELF/LTO.h
index a190da3..0f0b5bc 100644
--- a/ELF/LTO.h
+++ b/ELF/LTO.h
@@ -1,9 +1,8 @@
 //===- LTO.h ----------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/ELF/LinkerScript.cpp b/ELF/LinkerScript.cpp
index fbc0254..2341938 100644
--- a/ELF/LinkerScript.cpp
+++ b/ELF/LinkerScript.cpp
@@ -1,9 +1,8 @@
 //===- LinkerScript.cpp ---------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/ELF/LinkerScript.h b/ELF/LinkerScript.h
index 5116198..b993810 100644
--- a/ELF/LinkerScript.h
+++ b/ELF/LinkerScript.h
@@ -1,9 +1,8 @@
 //===- LinkerScript.h -------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/MapFile.cpp b/ELF/MapFile.cpp
index b0dc620..cc5b31d 100644
--- a/ELF/MapFile.cpp
+++ b/ELF/MapFile.cpp
@@ -1,9 +1,8 @@
 //===- MapFile.cpp --------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/ELF/MapFile.h b/ELF/MapFile.h
index 0282425..7e79389 100644
--- a/ELF/MapFile.h
+++ b/ELF/MapFile.h
@@ -1,9 +1,8 @@
 //===- MapFile.h ------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/MarkLive.cpp b/ELF/MarkLive.cpp
index 7264e1c..e603203 100644
--- a/ELF/MarkLive.cpp
+++ b/ELF/MarkLive.cpp
@@ -1,9 +1,8 @@
 //===- MarkLive.cpp -------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -250,9 +249,10 @@
 
     if (Sec->Flags & SHF_LINK_ORDER)
       continue;
-    if (isReserved<ELFT>(Sec) || Script->shouldKeep(Sec))
+
+    if (isReserved<ELFT>(Sec) || Script->shouldKeep(Sec)) {
       Enqueue(Sec, 0);
-    else if (isValidCIdentifier(Sec->Name)) {
+    } else if (isValidCIdentifier(Sec->Name)) {
       CNamedSections[Saver.save("__start_" + Sec->Name)].push_back(Sec);
       CNamedSections[Saver.save("__stop_" + Sec->Name)].push_back(Sec);
     }
@@ -267,10 +267,16 @@
 // input sections. This function make some or all of them on
 // so that they are emitted to the output file.
 template <class ELFT> void elf::markLive() {
-  // If -gc-sections is missing, no sections are removed.
   if (!Config->GcSections) {
+    // If -gc-sections is missing, no sections are removed.
     for (InputSectionBase *Sec : InputSections)
       Sec->Live = true;
+
+    // If a DSO defines a symbol referenced in a regular object, it is needed.
+    for (Symbol *Sym : Symtab->getSymbols())
+      if (auto *S = dyn_cast<SharedSymbol>(Sym))
+        if (S->IsUsedInRegularObj && !S->isWeak())
+          S->getFile<ELFT>().IsNeeded = true;
     return;
   }
 
diff --git a/ELF/MarkLive.h b/ELF/MarkLive.h
index c9b99ad..63b5b26 100644
--- a/ELF/MarkLive.h
+++ b/ELF/MarkLive.h
@@ -1,9 +1,8 @@
 //===- MarkLive.h -----------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/Options.td b/ELF/Options.td
index e43a21b..1792d5e 100644
--- a/ELF/Options.td
+++ b/ELF/Options.td
@@ -63,6 +63,10 @@
     "Allow multiple definitions",
     "Do not allow multiple definitions (default)">;
 
+defm allow_shlib_undefined: B<"allow-shlib-undefined",
+    "Allow unresolved references in shared libraries (default when linking a shared library)",
+    "Do not allow unresolved references in shared libraries (default when linking an executable)">;
+
 defm apply_dynamic_relocs: B<"apply-dynamic-relocs",
     "Apply link-time values for dynamic relocations",
     "Do not apply link-time values for dynamic relocations (default)">;
@@ -255,6 +259,9 @@
     "Use SHT_ANDROID_RELR / DT_ANDROID_RELR* tags instead of SHT_RELR / DT_RELR*",
     "Use SHT_RELR / DT_RELR* tags (default)">;
 
+def pic_veneer: F<"pic-veneer">,
+  HelpText<"Always generate position independent thunks (veneers)">;
+
 defm pie: B<"pie",
     "Create a position independent executable",
     "Do not create a position independent executable (default)">;
@@ -489,12 +496,10 @@
 def plugin_opt_slash: J<"plugin-opt=/">;
 
 // Options listed below are silently ignored for now for compatibility.
-def: F<"allow-shlib-undefined">;
 def: F<"detect-odr-violations">;
 def: Flag<["-"], "g">;
 def: F<"long-plt">;
 def: F<"no-add-needed">;
-def: F<"no-allow-shlib-undefined">;
 def: F<"no-copy-dt-needed-entries">;
 def: F<"no-ctors-in-init-array">;
 def: F<"no-keep-memory">;
diff --git a/ELF/OutputSections.cpp b/ELF/OutputSections.cpp
index c1442c0..6c40e45 100644
--- a/ELF/OutputSections.cpp
+++ b/ELF/OutputSections.cpp
@@ -1,9 +1,8 @@
 //===- OutputSections.cpp -------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/OutputSections.h b/ELF/OutputSections.h
index 113bf68..2ea7de6 100644
--- a/ELF/OutputSections.h
+++ b/ELF/OutputSections.h
@@ -1,9 +1,8 @@
 //===- OutputSections.h -----------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/Relocations.cpp b/ELF/Relocations.cpp
index c75ae4f..668db47 100644
--- a/ELF/Relocations.cpp
+++ b/ELF/Relocations.cpp
@@ -1,9 +1,8 @@
 //===- Relocations.cpp ----------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -66,6 +65,14 @@
 using namespace lld;
 using namespace lld::elf;
 
+static Optional<std::string> getLinkerScriptLocation(const Symbol &Sym) {
+  for (BaseCommand *Base : Script->SectionCommands)
+    if (auto *Cmd = dyn_cast<SymbolAssignment>(Base))
+      if (Cmd->Sym == &Sym)
+        return Cmd->Location;
+  return None;
+}
+
 // Construct a message in the following format.
 //
 // >>> defined in /home/alice/src/foo.o
@@ -73,8 +80,13 @@
 // >>>               /home/alice/src/bar.o:(.text+0x1)
 static std::string getLocation(InputSectionBase &S, const Symbol &Sym,
                                uint64_t Off) {
-  std::string Msg =
-      "\n>>> defined in " + toString(Sym.File) + "\n>>> referenced by ";
+  std::string Msg = "\n>>> defined in ";
+  if (Sym.File)
+    Msg += toString(Sym.File);
+  else if (Optional<std::string> Loc = getLinkerScriptLocation(Sym))
+    Msg += *Loc;
+
+  Msg += "\n>>> referenced by ";
   std::string Src = S.getSrcMsg(Sym, Off);
   if (!Src.empty())
     Msg += Src + "\n>>>               ";
@@ -193,7 +205,7 @@
       C.Relocations.push_back(
           {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_LD_TO_LE), Type,
            Offset, Addend, &Sym});
-      return Target->TlsGdRelaxSkip;
+      return Target->getTlsGdRelaxSkip(Type);
     }
     if (Expr == R_TLSLD_HINT)
       return 1;
@@ -266,7 +278,7 @@
           {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_LE), Type,
            Offset, Addend, &Sym});
     }
-    return Target->TlsGdRelaxSkip;
+    return Target->getTlsGdRelaxSkip(Type);
   }
 
   // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally
@@ -324,8 +336,7 @@
 
 // Returns true if Expr refers a PLT entry.
 static bool needsPlt(RelExpr Expr) {
-  return isRelExprOneOf<R_PLT_PC, R_PPC_CALL_PLT, R_PLT, R_AARCH64_PLT_PAGE_PC,
-                        R_GOT_PLT, R_AARCH64_GOT_PAGE_PC_PLT>(Expr);
+  return isRelExprOneOf<R_PLT_PC, R_PPC_CALL_PLT, R_PLT>(Expr);
 }
 
 // Returns true if Expr refers a GOT entry. Note that this function
@@ -334,8 +345,7 @@
 static bool needsGot(RelExpr Expr) {
   return isRelExprOneOf<R_GOT, R_GOT_OFF, R_HEXAGON_GOT, R_MIPS_GOT_LOCAL_PAGE,
                         R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_AARCH64_GOT_PAGE_PC,
-                        R_AARCH64_GOT_PAGE_PC_PLT, R_GOT_PC, R_GOT_FROM_END,
-                        R_GOT_PLT>(Expr);
+                        R_GOT_PC, R_GOT_FROM_END>(Expr);
 }
 
 // True if this expression is of the form Sym - X, where X is a position in the
@@ -416,14 +426,8 @@
     return R_PPC_CALL_PLT;
   case R_PC:
     return R_PLT_PC;
-  case R_AARCH64_PAGE_PC:
-    return R_AARCH64_PLT_PAGE_PC;
-  case R_AARCH64_GOT_PAGE_PC:
-    return R_AARCH64_GOT_PAGE_PC_PLT;
   case R_ABS:
     return R_PLT;
-  case R_GOT:
-    return R_GOT_PLT;
   default:
     return Expr;
   }
@@ -650,6 +654,10 @@
     Msg += Src + "\n>>>               ";
   Msg += Sec.getObjMsg(Offset);
 
+  if (Sym.getName().startswith("_ZTV"))
+    Msg += "\nthe vtable symbol may be undefined because the class is missing "
+           "its key function (see https://lld.llvm.org/missingkeyfunction)";
+
   if ((Config->UnresolvedSymbols == UnresolvedPolicy::Warn && CanBeExternal) ||
       Config->NoinhibitExec) {
     warn(Msg);
@@ -751,14 +759,7 @@
 template <class ELFT> static void addGotEntry(Symbol &Sym) {
   In.Got->addEntry(Sym);
 
-  RelExpr Expr;
-  if (Sym.isTls())
-    Expr = R_TLS;
-  else if (Sym.isGnuIFunc())
-    Expr = R_PLT;
-  else
-    Expr = R_ABS;
-
+  RelExpr Expr = Sym.isTls() ? R_TLS : R_ABS;
   uint64_t Off = Sym.getGotOffset();
 
   // If a GOT slot value can be calculated at link-time, which is now,
@@ -953,6 +954,15 @@
               getLocation(Sec, Sym, Offset));
 }
 
+struct IRelativeReloc {
+  RelType Type;
+  InputSectionBase *Sec;
+  uint64_t Offset;
+  Symbol *Sym;
+};
+
+static std::vector<IRelativeReloc> IRelativeRelocs;
+
 template <class ELFT, class RelTy>
 static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
                       RelTy *End) {
@@ -984,32 +994,40 @@
   if (isRelExprOneOf<R_HINT, R_NONE>(Expr))
     return;
 
-  // Strenghten or relax relocations.
+  // We can separate the small code model relocations into 2 categories:
+  // 1) Those that access the compiler generated .toc sections.
+  // 2) Those that access the linker allocated got entries.
+  // lld allocates got entries to symbols on demand. Since we don't try to sort
+  // the got entries in any way, we don't have to track which objects have
+  // got-based small code model relocs. The .toc sections get placed after the
+  // end of the linker allocated .got section and we do sort those so sections
+  // addressed with small code model relocations come first.
+  if (Config->EMachine == EM_PPC64 && isPPC64SmallCodeModelTocReloc(Type))
+    Sec.File->PPC64SmallCodeModelTocRelocs = true;
+
+  if (Sym.isGnuIFunc() && !Config->ZText && Config->WarnIfuncTextrel) {
+    warn("using ifunc symbols when text relocations are allowed may produce "
+         "a binary that will segfault, if the object file is linked with "
+         "old version of glibc (glibc 2.28 and earlier). If this applies to "
+         "you, consider recompiling the object files without -fPIC and "
+         "without -Wl,-z,notext option. Use -no-warn-ifunc-textrel to "
+         "turn off this warning." +
+         getLocation(Sec, Sym, Offset));
+  }
+
+  // Relax relocations.
   //
-  // GNU ifunc symbols must be accessed via PLT because their addresses
-  // are determined by runtime.
-  //
-  // On the other hand, if we know that a PLT entry will be resolved within
-  // the same ELF module, we can skip PLT access and directly jump to the
-  // destination function. For example, if we are linking a main exectuable,
-  // all dynamic symbols that can be resolved within the executable will
-  // actually be resolved that way at runtime, because the main exectuable
-  // is always at the beginning of a search list. We can leverage that fact.
-  if (Sym.isGnuIFunc()) {
-    if (!Config->ZText && Config->WarnIfuncTextrel) {
-      warn("using ifunc symbols when text relocations are allowed may produce "
-           "a binary that will segfault, if the object file is linked with "
-           "old version of glibc (glibc 2.28 and earlier). If this applies to "
-           "you, consider recompiling the object files without -fPIC and "
-           "without -Wl,-z,notext option. Use -no-warn-ifunc-textrel to "
-           "turn off this warning." +
-           getLocation(Sec, Sym, Offset));
-    }
-    Expr = toPlt(Expr);
-  } else if (!Sym.IsPreemptible && Expr == R_GOT_PC && !isAbsoluteValue(Sym)) {
-    Expr = Target->adjustRelaxExpr(Type, RelocatedAddr, Expr);
-  } else if (!Sym.IsPreemptible) {
-    Expr = fromPlt(Expr);
+  // If we know that a PLT entry will be resolved within the same ELF module, we
+  // can skip PLT access and directly jump to the destination function. For
+  // example, if we are linking a main exectuable, all dynamic symbols that can
+  // be resolved within the executable will actually be resolved that way at
+  // runtime, because the main exectuable is always at the beginning of a search
+  // list. We can leverage that fact.
+  if (!Sym.IsPreemptible && !Sym.isGnuIFunc()) {
+    if (Expr == R_GOT_PC && !isAbsoluteValue(Sym))
+      Expr = Target->adjustRelaxExpr(Type, RelocatedAddr, Expr);
+    else
+      Expr = fromPlt(Expr);
   }
 
   // This relocation does not require got entry, but it is relative to got and
@@ -1029,28 +1047,136 @@
     return;
   }
 
-  // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.
-  if (needsPlt(Expr) && !Sym.isInPlt()) {
-    if (Sym.isGnuIFunc() && !Sym.IsPreemptible)
-      addPltEntry<ELFT>(In.Iplt, In.IgotPlt, In.RelaIplt, Target->IRelativeRel,
-                        Sym);
-    else
+  // Non-preemptible ifuncs require special handling. First, handle the usual
+  // case where the symbol isn't one of these.
+  if (!Sym.isGnuIFunc() || Sym.IsPreemptible) {
+    // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.
+    if (needsPlt(Expr) && !Sym.isInPlt())
       addPltEntry<ELFT>(In.Plt, In.GotPlt, In.RelaPlt, Target->PltRel, Sym);
-  }
 
-  // Create a GOT slot if a relocation needs GOT.
-  if (needsGot(Expr)) {
-    if (Config->EMachine == EM_MIPS) {
-      // MIPS ABI has special rules to process GOT entries and doesn't
-      // require relocation entries for them. A special case is TLS
-      // relocations. In that case dynamic loader applies dynamic
-      // relocations to initialize TLS GOT entries.
-      // See "Global Offset Table" in Chapter 5 in the following document
-      // for detailed description:
-      // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
-      In.MipsGot->addEntry(*Sec.File, Sym, Addend, Expr);
-    } else if (!Sym.isInGot()) {
-      addGotEntry<ELFT>(Sym);
+    // Create a GOT slot if a relocation needs GOT.
+    if (needsGot(Expr)) {
+      if (Config->EMachine == EM_MIPS) {
+        // MIPS ABI has special rules to process GOT entries and doesn't
+        // require relocation entries for them. A special case is TLS
+        // relocations. In that case dynamic loader applies dynamic
+        // relocations to initialize TLS GOT entries.
+        // See "Global Offset Table" in Chapter 5 in the following document
+        // for detailed description:
+        // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
+        In.MipsGot->addEntry(*Sec.File, Sym, Addend, Expr);
+      } else if (!Sym.isInGot()) {
+        addGotEntry<ELFT>(Sym);
+      }
+    }
+  } else {
+    // Handle a reference to a non-preemptible ifunc. These are special in a
+    // few ways:
+    //
+    // - Unlike most non-preemptible symbols, non-preemptible ifuncs do not have
+    //   a fixed value. But assuming that all references to the ifunc are
+    //   GOT-generating or PLT-generating, the handling of an ifunc is
+    //   relatively straightforward. We create a PLT entry in Iplt, which is
+    //   usually at the end of .plt, which makes an indirect call using a
+    //   matching GOT entry in IgotPlt, which is usually at the end of .got.plt.
+    //   The GOT entry is relocated using an IRELATIVE relocation in RelaIplt,
+    //   which is usually at the end of .rela.plt. Unlike most relocations in
+    //   .rela.plt, which may be evaluated lazily without -z now, dynamic
+    //   loaders evaluate IRELATIVE relocs eagerly, which means that for
+    //   IRELATIVE relocs only, GOT-generating relocations can point directly to
+    //   .got.plt without requiring a separate GOT entry.
+    //
+    // - Despite the fact that an ifunc does not have a fixed value, compilers
+    //   that are not passed -fPIC will assume that they do, and will emit
+    //   direct (non-GOT-generating, non-PLT-generating) relocations to the
+    //   symbol. This means that if a direct relocation to the symbol is
+    //   seen, the linker must set a value for the symbol, and this value must
+    //   be consistent no matter what type of reference is made to the symbol.
+    //   This can be done by creating a PLT entry for the symbol in the way
+    //   described above and making it canonical, that is, making all references
+    //   point to the PLT entry instead of the resolver. In lld we also store
+    //   the address of the PLT entry in the dynamic symbol table, which means
+    //   that the symbol will also have the same value in other modules.
+    //   Because the value loaded from the GOT needs to be consistent with
+    //   the value computed using a direct relocation, a non-preemptible ifunc
+    //   may end up with two GOT entries, one in .got.plt that points to the
+    //   address returned by the resolver and is used only by the PLT entry,
+    //   and another in .got that points to the PLT entry and is used by
+    //   GOT-generating relocations.
+    //
+    // - The fact that these symbols do not have a fixed value makes them an
+    //   exception to the general rule that a statically linked executable does
+    //   not require any form of dynamic relocation. To handle these relocations
+    //   correctly, the IRELATIVE relocations are stored in an array which a
+    //   statically linked executable's startup code must enumerate using the
+    //   linker-defined symbols __rela?_iplt_{start,end}.
+    //
+    // - An absolute relocation to a non-preemptible ifunc (such as a global
+    //   variable containing a pointer to the ifunc) needs to be relocated in
+    //   the exact same way as a GOT entry, so we can avoid needing to make the
+    //   PLT entry canonical by translating such relocations into IRELATIVE
+    //   relocations in the RelaIplt.
+    if (!Sym.isInPlt()) {
+      // Create PLT and GOTPLT slots for the symbol.
+      Sym.IsInIplt = true;
+
+      // Create a copy of the symbol to use as the target of the IRELATIVE
+      // relocation in the IgotPlt. This is in case we make the PLT canonical
+      // later, which would overwrite the original symbol.
+      //
+      // FIXME: Creating a copy of the symbol here is a bit of a hack. All
+      // that's really needed to create the IRELATIVE is the section and value,
+      // so ideally we should just need to copy those.
+      auto *DirectSym = make<Defined>(cast<Defined>(Sym));
+      addPltEntry<ELFT>(In.Iplt, In.IgotPlt, In.RelaIplt, Target->IRelativeRel,
+                        *DirectSym);
+      Sym.PltIndex = DirectSym->PltIndex;
+    }
+    if (Expr == R_ABS && Addend == 0 && (Sec.Flags & SHF_WRITE)) {
+      // We might be able to represent this as an IRELATIVE. But we don't know
+      // yet whether some later relocation will make the symbol point to a
+      // canonical PLT, which would make this either a dynamic RELATIVE (PIC) or
+      // static (non-PIC) relocation. So we keep a record of the information
+      // required to process the relocation, and after scanRelocs() has been
+      // called on all relocations, the relocation is resolved by
+      // addIRelativeRelocs().
+      IRelativeRelocs.push_back({Type, &Sec, Offset, &Sym});
+      return;
+    }
+    if (needsGot(Expr)) {
+      // Redirect GOT accesses to point to the Igot.
+      //
+      // This field is also used to keep track of whether we ever needed a GOT
+      // entry. If we did and we make the PLT canonical later, we'll need to
+      // create a GOT entry pointing to the PLT entry for Sym.
+      Sym.GotInIgot = true;
+    } else if (!needsPlt(Expr)) {
+      // Make the ifunc's PLT entry canonical by changing the value of its
+      // symbol to redirect all references to point to it.
+      unsigned EntryOffset = Sym.PltIndex * Target->PltEntrySize;
+      if (Config->ZRetpolineplt)
+        EntryOffset += Target->PltHeaderSize;
+
+      auto &D = cast<Defined>(Sym);
+      D.Section = In.Iplt;
+      D.Value = EntryOffset;
+      D.Size = 0;
+      // It's important to set the symbol type here so that dynamic loaders
+      // don't try to call the PLT as if it were an ifunc resolver.
+      D.Type = STT_FUNC;
+
+      if (Sym.GotInIgot) {
+        // We previously encountered a GOT generating reference that we
+        // redirected to the Igot. Now that the PLT entry is canonical we must
+        // clear the redirection to the Igot and add a GOT entry. As we've
+        // changed the symbol type to STT_FUNC future GOT generating references
+        // will naturally use this GOT entry.
+        //
+        // We don't need to worry about creating a MIPS GOT here because ifuncs
+        // aren't a thing on MIPS.
+        Sym.GotInIgot = false;
+        addGotEntry<ELFT>(Sym);
+      }
     }
   }
 
@@ -1080,6 +1206,21 @@
     scanRelocs<ELFT>(S, S.rels<ELFT>());
 }
 
+// Figure out which representation to use for any absolute relocs to
+// non-preemptible ifuncs that we visited during scanRelocs().
+void elf::addIRelativeRelocs() {
+  for (IRelativeReloc &R : IRelativeRelocs) {
+    if (R.Sym->Type == STT_GNU_IFUNC)
+      In.RelaIplt->addReloc(
+          {Target->IRelativeRel, R.Sec, R.Offset, true, R.Sym, 0});
+    else if (Config->Pic)
+      addRelativeReloc(R.Sec, R.Offset, R.Sym, 0, R_ABS, R.Type);
+    else
+      R.Sec->Relocations.push_back({R_ABS, R.Type, R.Offset, 0, R.Sym});
+  }
+  IRelativeRelocs.clear();
+}
+
 static bool mergeCmp(const InputSection *A, const InputSection *B) {
   // std::merge requires a strict weak ordering.
   if (A->OutSecOff < B->OutSecOff)
diff --git a/ELF/Relocations.h b/ELF/Relocations.h
index d00e68b..12a731b 100644
--- a/ELF/Relocations.h
+++ b/ELF/Relocations.h
@@ -1,9 +1,8 @@
 //===- Relocations.h -------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -34,19 +33,11 @@
   R_ABS,
   R_ADDEND,
   R_AARCH64_GOT_PAGE_PC,
-  // The expression is used for IFUNC support. Describes PC-relative
-  // address of the memory page of GOT entry. This entry is used for
-  // a redirection to IPLT.
-  R_AARCH64_GOT_PAGE_PC_PLT,
   R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC,
   R_AARCH64_PAGE_PC,
-  R_AARCH64_PLT_PAGE_PC,
   R_AARCH64_TLSDESC_PAGE,
   R_ARM_SBREL,
   R_GOT,
-  // The expression is used for IFUNC support. Evaluates to GOT entry,
-  // containing redirection to the IPLT.
-  R_GOT_PLT,
   R_GOTONLY_PC,
   R_GOTONLY_PC_FROM_END,
   R_GOTREL,
@@ -155,6 +146,8 @@
 
 template <class ELFT> void scanRelocations(InputSectionBase &);
 
+void addIRelativeRelocs();
+
 class ThunkSection;
 class Thunk;
 struct InputSectionDescription;
diff --git a/ELF/ScriptLexer.cpp b/ELF/ScriptLexer.cpp
index 9a372c6..cd4873c 100644
--- a/ELF/ScriptLexer.cpp
+++ b/ELF/ScriptLexer.cpp
@@ -1,9 +1,8 @@
 //===- ScriptLexer.cpp ----------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/ELF/ScriptLexer.h b/ELF/ScriptLexer.h
index fc6b5b1..19ec3a8 100644
--- a/ELF/ScriptLexer.h
+++ b/ELF/ScriptLexer.h
@@ -1,9 +1,8 @@
 //===- ScriptLexer.h --------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/ScriptParser.cpp b/ELF/ScriptParser.cpp
index eee3f0e..96ab5cc 100644
--- a/ELF/ScriptParser.cpp
+++ b/ELF/ScriptParser.cpp
@@ -1,9 +1,8 @@
 //===- ScriptParser.cpp ---------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -94,7 +93,6 @@
   SortSectionPolicy readSortKind();
   SymbolAssignment *readProvideHidden(bool Provide, bool Hidden);
   SymbolAssignment *readAssignment(StringRef Tok);
-  std::tuple<ELFKind, uint16_t, bool> readBfdName();
   void readSort();
   Expr readAssert();
   Expr readConstant();
@@ -331,7 +329,7 @@
 void ScriptParser::readExtern() {
   expect("(");
   while (!errorCount() && !consume(")"))
-    Config->Undefined.push_back(next());
+    Config->Undefined.push_back(unquote(next()));
 }
 
 void ScriptParser::readGroup() {
@@ -385,39 +383,25 @@
     skip();
 }
 
-std::tuple<ELFKind, uint16_t, bool> ScriptParser::readBfdName() {
-  StringRef S = unquote(next());
-  if (S == "elf32-i386")
-    return std::make_tuple(ELF32LEKind, EM_386, false);
-  if (S == "elf32-iamcu")
-    return std::make_tuple(ELF32LEKind, EM_IAMCU, false);
-  if (S == "elf32-littlearm")
-    return std::make_tuple(ELF32LEKind, EM_ARM, false);
-  if (S == "elf32-x86-64")
-    return std::make_tuple(ELF32LEKind, EM_X86_64, false);
-  if (S == "elf64-littleaarch64")
-    return std::make_tuple(ELF64LEKind, EM_AARCH64, false);
-  if (S == "elf64-powerpc")
-    return std::make_tuple(ELF64BEKind, EM_PPC64, false);
-  if (S == "elf64-powerpcle")
-    return std::make_tuple(ELF64LEKind, EM_PPC64, false);
-  if (S == "elf64-x86-64")
-    return std::make_tuple(ELF64LEKind, EM_X86_64, false);
-  if (S == "elf32-tradbigmips")
-    return std::make_tuple(ELF32BEKind, EM_MIPS, false);
-  if (S == "elf32-ntradbigmips")
-    return std::make_tuple(ELF32BEKind, EM_MIPS, true);
-  if (S == "elf32-tradlittlemips")
-    return std::make_tuple(ELF32LEKind, EM_MIPS, false);
-  if (S == "elf32-ntradlittlemips")
-    return std::make_tuple(ELF32LEKind, EM_MIPS, true);
-  if (S == "elf64-tradbigmips")
-    return std::make_tuple(ELF64BEKind, EM_MIPS, false);
-  if (S == "elf64-tradlittlemips")
-    return std::make_tuple(ELF64LEKind, EM_MIPS, false);
-
-  setError("unknown output format name: " + S);
-  return std::make_tuple(ELFNoneKind, EM_NONE, false);
+static std::pair<ELFKind, uint16_t> parseBfdName(StringRef S) {
+  return StringSwitch<std::pair<ELFKind, uint16_t>>(S)
+      .Case("elf32-i386", {ELF32LEKind, EM_386})
+      .Case("elf32-iamcu", {ELF32LEKind, EM_IAMCU})
+      .Case("elf32-littlearm", {ELF32LEKind, EM_ARM})
+      .Case("elf32-x86-64", {ELF32LEKind, EM_X86_64})
+      .Case("elf64-aarch64", {ELF64LEKind, EM_AARCH64})
+      .Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64})
+      .Case("elf32-powerpc", {ELF32BEKind, EM_PPC})
+      .Case("elf64-powerpc", {ELF64BEKind, EM_PPC64})
+      .Case("elf64-powerpcle", {ELF64LEKind, EM_PPC64})
+      .Case("elf64-x86-64", {ELF64LEKind, EM_X86_64})
+      .Cases("elf32-tradbigmips", "elf32-bigmips", {ELF32BEKind, EM_MIPS})
+      .Case("elf32-ntradbigmips", {ELF32BEKind, EM_MIPS})
+      .Case("elf32-tradlittlemips", {ELF32LEKind, EM_MIPS})
+      .Case("elf32-ntradlittlemips", {ELF32LEKind, EM_MIPS})
+      .Case("elf64-tradbigmips", {ELF64BEKind, EM_MIPS})
+      .Case("elf64-tradlittlemips", {ELF64LEKind, EM_MIPS})
+      .Default({ELFNoneKind, EM_NONE});
 }
 
 // Parse OUTPUT_FORMAT(bfdname) or OUTPUT_FORMAT(bfdname, big, little).
@@ -425,9 +409,16 @@
 void ScriptParser::readOutputFormat() {
   expect("(");
 
-  std::tuple<ELFKind, uint16_t, bool> BfdTuple = readBfdName();
-  if (Config->EKind == ELFNoneKind)
-    std::tie(Config->EKind, Config->EMachine, Config->MipsN32Abi) = BfdTuple;
+  StringRef Name = unquote(next());
+  StringRef S = Name;
+  if (S.consume_back("-freebsd"))
+    Config->OSABI = ELFOSABI_FREEBSD;
+
+  std::tie(Config->EKind, Config->EMachine) = parseBfdName(S);
+  if (Config->EMachine == EM_NONE)
+    setError("unknown output format name: " + Name);
+  if (S == "elf32-ntradlittlemips" || S == "elf32-ntradbigmips")
+    Config->MipsN32Abi = true;
 
   if (consume(")"))
     return;
diff --git a/ELF/ScriptParser.h b/ELF/ScriptParser.h
index d48d5aa..bc578ac 100644
--- a/ELF/ScriptParser.h
+++ b/ELF/ScriptParser.h
@@ -1,9 +1,8 @@
 //===- ScriptParser.h -------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/SymbolTable.cpp b/ELF/SymbolTable.cpp
index e372461..e25682f 100644
--- a/ELF/SymbolTable.cpp
+++ b/ELF/SymbolTable.cpp
@@ -1,9 +1,8 @@
 //===- SymbolTable.cpp ----------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -93,9 +92,21 @@
   // .so file
   if (auto *F = dyn_cast<SharedFile<ELFT>>(File)) {
     // DSOs are uniquified not by filename but by soname.
-    F->parseSoName();
-    if (errorCount() || !SoNames.insert(F->SoName).second)
+    F->parseDynamic();
+    if (errorCount())
       return;
+
+    // If a DSO appears more than once on the command line with and without
+    // --as-needed, --no-as-needed takes precedence over --as-needed because a
+    // user can add an extra DSO with --no-as-needed to force it to be added to
+    // the dependency list.
+    DenseMap<StringRef, InputFile *>::iterator It;
+    bool WasInserted;
+    std::tie(It, WasInserted) = SoNames.try_emplace(F->SoName, F);
+    cast<SharedFile<ELFT>>(It->second)->IsNeeded |= F->IsNeeded;
+    if (!WasInserted)
+      return;
+
     SharedFiles.push_back(F);
     F->parseRest();
     return;
@@ -251,10 +262,6 @@
   if (S->isShared() || S->isLazy() || (S->isUndefined() && Binding != STB_WEAK))
     S->Binding = Binding;
 
-  if (!Config->GcSections && Binding != STB_WEAK)
-    if (auto *SS = dyn_cast<SharedSymbol>(S))
-      SS->getFile<ELFT>().IsNeeded = true;
-
   if (S->isLazy()) {
     // An undefined weak will not fetch archive members. See comment on Lazy in
     // Symbols.h for the details.
@@ -319,7 +326,7 @@
 
     // We don't report backward references to weak symbols as they can be
     // overridden later.
-    if (Backref && S->Binding != STB_WEAK)
+    if (Backref && !S->isWeak())
       warn("backward reference detected: " + Name + " in " + toString(File) +
            " refers to " + toString(S->File));
   }
@@ -494,19 +501,16 @@
 
   // An undefined symbol with non default visibility must be satisfied
   // in the same DSO.
-  if (WasInserted ||
-      ((S->isUndefined() || S->isLazy()) && S->Visibility == STV_DEFAULT)) {
-    uint8_t Binding = S->Binding;
-    bool WasUndefined = S->isUndefined();
-    replaceSymbol<SharedSymbol>(S, File, Name, Sym.getBinding(), Sym.st_other,
+  auto Replace = [&](uint8_t Binding) {
+    replaceSymbol<SharedSymbol>(S, File, Name, Binding, Sym.st_other,
                                 Sym.getType(), Sym.st_value, Sym.st_size,
                                 Alignment, VerdefIndex);
-    if (!WasInserted) {
-      S->Binding = Binding;
-      if (!S->isWeak() && !Config->GcSections && WasUndefined)
-        File.IsNeeded = true;
-    }
-  }
+  };
+
+  if (WasInserted)
+    Replace(Sym.getBinding());
+  else if (S->Visibility == STV_DEFAULT && (S->isUndefined() || S->isLazy()))
+    Replace(S->Binding);
 }
 
 Symbol *SymbolTable::addBitcode(StringRef Name, uint8_t Binding,
diff --git a/ELF/SymbolTable.h b/ELF/SymbolTable.h
index b5fd8d3..9822ed7 100644
--- a/ELF/SymbolTable.h
+++ b/ELF/SymbolTable.h
@@ -1,9 +1,8 @@
 //===- SymbolTable.h --------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -80,6 +79,9 @@
 
   void handleDynamicList();
 
+  // Set of .so files to not link the same shared object file more than once.
+  llvm::DenseMap<StringRef, InputFile *> SoNames;
+
 private:
   std::pair<Symbol *, bool> insertName(StringRef Name);
 
@@ -107,9 +109,6 @@
   // is used to uniquify them.
   llvm::DenseSet<llvm::CachedHashStringRef> ComdatGroups;
 
-  // Set of .so files to not link the same shared object file more than once.
-  llvm::DenseSet<StringRef> SoNames;
-
   // A map from demangled symbol names to their symbol objects.
   // This mapping is 1:N because two symbols with different versions
   // can have the same name. We use this map to handle "extern C++ {}"
diff --git a/ELF/Symbols.cpp b/ELF/Symbols.cpp
index da7fdb5..96e23b9 100644
--- a/ELF/Symbols.cpp
+++ b/ELF/Symbols.cpp
@@ -1,9 +1,8 @@
 //===- Symbols.cpp --------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -38,6 +37,7 @@
 Defined *ElfSym::MipsGp;
 Defined *ElfSym::MipsGpDisp;
 Defined *ElfSym::MipsLocalGp;
+Defined *ElfSym::RelaIpltStart;
 Defined *ElfSym::RelaIpltEnd;
 
 static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {
@@ -120,20 +120,24 @@
   return OutVA + Addend;
 }
 
-uint64_t Symbol::getGotVA() const { return In.Got->getVA() + getGotOffset(); }
+uint64_t Symbol::getGotVA() const {
+  if (GotInIgot)
+    return In.IgotPlt->getVA() + getGotPltOffset();
+  return In.Got->getVA() + getGotOffset();
+}
 
 uint64_t Symbol::getGotOffset() const {
   return GotIndex * Target->GotEntrySize;
 }
 
 uint64_t Symbol::getGotPltVA() const {
-  if (this->IsInIgot)
+  if (IsInIplt)
     return In.IgotPlt->getVA() + getGotPltOffset();
   return In.GotPlt->getVA() + getGotPltOffset();
 }
 
 uint64_t Symbol::getGotPltOffset() const {
-  if (IsInIgot)
+  if (IsInIplt)
     return PltIndex * Target->GotPltEntrySize;
   return (PltIndex + Target->GotPltHeaderEntriesNum) * Target->GotPltEntrySize;
 }
diff --git a/ELF/Symbols.h b/ELF/Symbols.h
index 803cb80..fc48b09 100644
--- a/ELF/Symbols.h
+++ b/ELF/Symbols.h
@@ -1,9 +1,8 @@
 //===- Symbols.h ------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -182,7 +181,7 @@
          uint8_t StOther, uint8_t Type)
       : File(File), NameData(Name.Data), NameSize(Name.Size), Binding(Binding),
         Type(Type), StOther(StOther), SymbolKind(K), NeedsPltAddr(false),
-        IsInIplt(false), IsInIgot(false), IsPreemptible(false),
+        IsInIplt(false), GotInIgot(false), IsPreemptible(false),
         Used(!Config->GcSections), NeedsTocRestore(false),
         ScriptDefined(false) {}
 
@@ -191,11 +190,13 @@
   // For SharedSymbol only.
   unsigned NeedsPltAddr : 1;
 
-  // True if this symbol is in the Iplt sub-section of the Plt.
+  // True if this symbol is in the Iplt sub-section of the Plt and the Igot
+  // sub-section of the .got.plt or .got.
   unsigned IsInIplt : 1;
 
-  // True if this symbol is in the Igot sub-section of the .got.plt or .got.
-  unsigned IsInIgot : 1;
+  // True if this symbol needs a GOT entry and its GOT entry is actually in
+  // Igot. This will be true only for certain non-preemptible ifuncs.
+  unsigned GotInIgot : 1;
 
   // True if this symbol is preemptible at load time.
   unsigned IsPreemptible : 1;
@@ -352,7 +353,8 @@
   static Defined *MipsGpDisp;
   static Defined *MipsLocalGp;
 
-  // __rela_iplt_end or __rel_iplt_end
+  // __rel{,a}_iplt_{start,end} symbols.
+  static Defined *RelaIpltStart;
   static Defined *RelaIpltEnd;
 };
 
diff --git a/ELF/SyntheticSections.cpp b/ELF/SyntheticSections.cpp
index 293d845..e0d418a 100644
--- a/ELF/SyntheticSections.cpp
+++ b/ELF/SyntheticSections.cpp
@@ -1,9 +1,8 @@
 //===- SyntheticSections.cpp ----------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -15,7 +14,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "SyntheticSections.h"
-#include "Bits.h"
 #include "Config.h"
 #include "InputFiles.h"
 #include "LinkerScript.h"
@@ -59,6 +57,17 @@
 
 constexpr size_t MergeNoTailSection::NumShards;
 
+static uint64_t readUint(uint8_t *Buf) {
+  return Config->Is64 ? read64(Buf) : read32(Buf);
+}
+
+static void writeUint(uint8_t *Buf, uint64_t Val) {
+  if (Config->Is64)
+    write64(Buf, Val);
+  else
+    write32(Buf, Val);
+}
+
 // Returns an LLD version string.
 static ArrayRef<uint8_t> getVersion() {
   // Check LLD_VERSION first for ease of testing.
@@ -1133,7 +1142,6 @@
                        Target->GotPltEntrySize, getIgotPltName()) {}
 
 void IgotPltSection::addEntry(Symbol &Sym) {
-  Sym.IsInIgot = true;
   assert(Sym.PltIndex == Entries.size());
   Entries.push_back(&Sym);
 }
@@ -1296,6 +1304,8 @@
   }
   if (!Config->ZText)
     DtFlags |= DF_TEXTREL;
+  if (Config->HasStaticTlsModel)
+    DtFlags |= DF_STATIC_TLS;
 
   if (DtFlags)
     addInt(DT_FLAGS, DtFlags);
@@ -1513,8 +1523,10 @@
   else
     getParent()->Link = 0;
 
-  if (In.RelaIplt == this || In.RelaPlt == this)
+  if (In.RelaPlt == this)
     getParent()->Info = In.GotPlt->getParent()->SectionIndex;
+  if (In.RelaIplt == this)
+    getParent()->Info = In.IgotPlt->getParent()->SectionIndex;
 }
 
 RelrBaseSection::RelrBaseSection()
@@ -1803,7 +1815,7 @@
   std::vector<uint64_t> Offsets;
   for (const RelativeReloc &Rel : Relocs)
     Offsets.push_back(Rel.getOffset());
-  llvm::sort(Offsets.begin(), Offsets.end());
+  llvm::sort(Offsets);
 
   // For each leading relocation, find following ones that can be folded
   // as a bitmap and fold them.
@@ -2176,6 +2188,8 @@
 void GnuHashTableSection::writeBloomFilter(uint8_t *Buf) {
   unsigned C = Config->Is64 ? 64 : 32;
   for (const Entry &Sym : Symbols) {
+    // When C = 64, we choose a word with bits [6:...] and set 1 to two bits in
+    // the word using bits [0:5] and [26:31].
     size_t I = (Sym.Hash / C) & (MaskWords - 1);
     uint64_t Val = readUint(Buf + I * Config->Wordsize);
     Val |= uint64_t(1) << (Sym.Hash % C);
@@ -2329,10 +2343,8 @@
 template <class ELFT> void PltSection::addEntry(Symbol &Sym) {
   Sym.PltIndex = Entries.size();
   RelocationBaseSection *PltRelocSection = In.RelaPlt;
-  if (IsIplt) {
+  if (IsIplt)
     PltRelocSection = In.RelaIplt;
-    Sym.IsInIplt = true;
-  }
   unsigned RelOff =
       static_cast<RelocationSection<ELFT> *>(PltRelocSection)->getRelocOffset();
   Entries.push_back(std::make_pair(&Sym, RelOff));
@@ -2412,11 +2424,14 @@
 
   uint32_t CuIdx = 0;
   for (std::unique_ptr<DWARFUnit> &Cu : Dwarf.compile_units()) {
-    DWARFAddressRangesVector Ranges;
-    Cu->collectAddressRanges(Ranges);
+    Expected<DWARFAddressRangesVector> Ranges = Cu->collectAddressRanges();
+    if (!Ranges) {
+      error(toString(Sec) + ": " + toString(Ranges.takeError()));
+      return {};
+    }
 
     ArrayRef<InputSectionBase *> Sections = Sec->File->getSections();
-    for (DWARFAddressRange &R : Ranges) {
+    for (DWARFAddressRange &R : *Ranges) {
       InputSectionBase *S = Sections[R.SectionIndex];
       if (!S || S == &InputSection::Discarded || !S->Live)
         continue;
@@ -2429,6 +2444,7 @@
     }
     ++CuIdx;
   }
+
   return Ret;
 }
 
diff --git a/ELF/SyntheticSections.h b/ELF/SyntheticSections.h
index 63d7897..90e1e12 100644
--- a/ELF/SyntheticSections.h
+++ b/ELF/SyntheticSections.h
@@ -1,9 +1,8 @@
 //===- SyntheticSection.h ---------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -317,8 +316,9 @@
     size_t StartIndex = 0;
 
     struct PageBlock {
-      size_t FirstIndex = 0;
-      size_t Count = 0;
+      size_t FirstIndex;
+      size_t Count;
+      PageBlock() : FirstIndex(0), Count(0) {}
     };
 
     // Map output sections referenced by MIPS GOT relocations
@@ -619,7 +619,8 @@
   void addSymbols(std::vector<SymbolTableEntry> &Symbols);
 
 private:
-  enum { Shift2 = 6 };
+  // See the comment in writeBloomFilter.
+  enum { Shift2 = 26 };
 
   void writeBloomFilter(uint8_t *Buf);
   void writeHashTable(uint8_t *Buf);
diff --git a/ELF/Target.cpp b/ELF/Target.cpp
index a629354..f902d67 100644
--- a/ELF/Target.cpp
+++ b/ELF/Target.cpp
@@ -1,9 +1,8 @@
 //===- Target.cpp ---------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -75,6 +74,8 @@
     default:
       llvm_unreachable("unsupported MIPS target");
     }
+  case EM_MSP430:
+    return getMSP430TargetInfo();
   case EM_PPC:
     return getPPCTargetInfo();
   case EM_PPC64:
diff --git a/ELF/Target.h b/ELF/Target.h
index e7a31e7..c7d29b6 100644
--- a/ELF/Target.h
+++ b/ELF/Target.h
@@ -1,9 +1,8 @@
 //===- Target.h -------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -33,6 +32,7 @@
   virtual void writeGotPlt(uint8_t *Buf, const Symbol &S) const {};
   virtual void writeIgotPlt(uint8_t *Buf, const Symbol &S) const;
   virtual int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const;
+  virtual int getTlsGdRelaxSkip(RelType Type) const { return 1; }
 
   // If lazy binding is supported, the first entry of the PLT has code
   // to call the dynamic linker to resolve PLT entries the first time
@@ -81,7 +81,6 @@
 
   virtual ~TargetInfo();
 
-  unsigned TlsGdRelaxSkip = 1;
   unsigned PageSize = 4096;
   unsigned DefaultMaxPageSize = 4096;
 
@@ -146,6 +145,7 @@
 TargetInfo *getARMTargetInfo();
 TargetInfo *getAVRTargetInfo();
 TargetInfo *getHexagonTargetInfo();
+TargetInfo *getMSP430TargetInfo();
 TargetInfo *getPPC64TargetInfo();
 TargetInfo *getPPCTargetInfo();
 TargetInfo *getRISCVTargetInfo();
@@ -176,6 +176,10 @@
 // to the local entry-point.
 unsigned getPPC64GlobalEntryToLocalEntryOffset(uint8_t StOther);
 
+// Returns true if a relocation is a small code model relocation that accesses
+// the .toc section.
+bool isPPC64SmallCodeModelTocReloc(RelType Type);
+
 uint64_t getPPC64TocBase();
 uint64_t getAArch64Page(uint64_t Expr);
 
diff --git a/ELF/Thunks.cpp b/ELF/Thunks.cpp
index 5486f23..d7150d4 100644
--- a/ELF/Thunks.cpp
+++ b/ELF/Thunks.cpp
@@ -1,9 +1,8 @@
 //===- Thunks.cpp --------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===---------------------------------------------------------------------===//
 //
@@ -484,7 +483,7 @@
   };
   uint64_t S = getARMThunkDestVA(Destination);
   uint64_t P = getThunkTargetSym()->getVA();
-  uint64_t Offset = S - P - 16;
+  int64_t Offset = S - P - 16;
   memcpy(Buf, Data, sizeof(Data));
   Target->relocateOne(Buf, R_ARM_MOVW_PREL_NC, Offset);
   Target->relocateOne(Buf + 4, R_ARM_MOVT_PREL, Offset);
@@ -505,7 +504,7 @@
   };
   uint64_t S = getARMThunkDestVA(Destination);
   uint64_t P = getThunkTargetSym()->getVA() & ~0x1;
-  uint64_t Offset = S - P - 12;
+  int64_t Offset = S - P - 12;
   memcpy(Buf, Data, sizeof(Data));
   Target->relocateOne(Buf, R_ARM_THM_MOVW_PREL_NC, Offset);
   Target->relocateOne(Buf + 4, R_ARM_THM_MOVT_PREL, Offset);
@@ -722,7 +721,7 @@
 static Thunk *addThunkAArch64(RelType Type, Symbol &S) {
   if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26)
     fatal("unrecognized relocation type");
-  if (Config->Pic)
+  if (Config->PicThunk)
     return make<AArch64ADRPThunk>(S);
   return make<AArch64ABSLongThunk>(S);
 }
@@ -739,7 +738,7 @@
   case R_ARM_JUMP24:
   case R_ARM_CALL:
   case R_ARM_THM_CALL:
-    if (Config->Pic)
+    if (Config->PicThunk)
       return make<ARMV5PILongThunk>(S);
     return make<ARMV5ABSLongThunk>(S);
   }
@@ -794,13 +793,13 @@
   case R_ARM_PLT32:
   case R_ARM_JUMP24:
   case R_ARM_CALL:
-    if (Config->Pic)
+    if (Config->PicThunk)
       return make<ARMV7PILongThunk>(S);
     return make<ARMV7ABSLongThunk>(S);
   case R_ARM_THM_JUMP19:
   case R_ARM_THM_JUMP24:
   case R_ARM_THM_CALL:
-    if (Config->Pic)
+    if (Config->PicThunk)
       return make<ThumbV7PILongThunk>(S);
     return make<ThumbV7ABSLongThunk>(S);
   }
@@ -820,7 +819,7 @@
   if (S.isInPlt())
     return make<PPC64PltCallStub>(S);
 
-  if (Config->Pic)
+  if (Config->PicThunk)
     return make<PPC64PILongBranchThunk>(S);
 
   return make<PPC64PDLongBranchThunk>(S);
diff --git a/ELF/Thunks.h b/ELF/Thunks.h
index ed82b4d..aa37227 100644
--- a/ELF/Thunks.h
+++ b/ELF/Thunks.h
@@ -1,9 +1,8 @@
 //===- Thunks.h --------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp
index 37a53a1..42c1c0b 100644
--- a/ELF/Writer.cpp
+++ b/ELF/Writer.cpp
@@ -1,9 +1,8 @@
 //===- Writer.cpp ---------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -910,12 +909,18 @@
 template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
   if (Config->Relocatable || needsInterpSection())
     return;
-  StringRef S = Config->IsRela ? "__rela_iplt_start" : "__rel_iplt_start";
-  addOptionalRegular(S, In.RelaIplt, 0, STV_HIDDEN, STB_WEAK);
 
-  S = Config->IsRela ? "__rela_iplt_end" : "__rel_iplt_end";
-  ElfSym::RelaIpltEnd =
-      addOptionalRegular(S, In.RelaIplt, 0, STV_HIDDEN, STB_WEAK);
+  // By default, __rela_iplt_{start,end} belong to a dummy section 0
+  // because .rela.plt might be empty and thus removed from output.
+  // We'll override Out::ElfHeader with In.RelaIplt later when we are
+  // sure that .rela.plt exists in output.
+  ElfSym::RelaIpltStart = addOptionalRegular(
+      Config->IsRela ? "__rela_iplt_start" : "__rel_iplt_start",
+      Out::ElfHeader, 0, STV_HIDDEN, STB_WEAK);
+
+  ElfSym::RelaIpltEnd = addOptionalRegular(
+      Config->IsRela ? "__rela_iplt_end" : "__rel_iplt_end",
+      Out::ElfHeader, 0, STV_HIDDEN, STB_WEAK);
 }
 
 template <class ELFT>
@@ -949,8 +954,12 @@
     ElfSym::GlobalOffsetTable->Section = GotSection;
   }
 
-  if (ElfSym::RelaIpltEnd)
+  // .rela_iplt_{start,end} mark the start and the end of .rela.plt section.
+  if (ElfSym::RelaIpltStart && !In.RelaIplt->empty()) {
+    ElfSym::RelaIpltStart->Section = In.RelaIplt;
+    ElfSym::RelaIpltEnd->Section = In.RelaIplt;
     ElfSym::RelaIpltEnd->Value = In.RelaIplt->getSize();
+  }
 
   PhdrEntry *Last = nullptr;
   PhdrEntry *LastRO = nullptr;
@@ -1241,6 +1250,24 @@
   if (Name == ".init" || Name == ".fini")
     return;
 
+  // .toc is allocated just after .got and is accessed using GOT-relative
+  // relocations. Object files compiled with small code model have an
+  // addressable range of [.got, .got + 0xFFFC] for GOT-relative relocations.
+  // To reduce the risk of relocation overflow, .toc contents are sorted so that
+  // sections having smaller relocation offsets are at beginning of .toc
+  if (Config->EMachine == EM_PPC64 && Name == ".toc") {
+    if (Script->HasSectionsCommand)
+      return;
+    assert(Sec->SectionCommands.size() == 1);
+    auto *ISD = cast<InputSectionDescription>(Sec->SectionCommands[0]);
+    std::stable_sort(ISD->Sections.begin(), ISD->Sections.end(),
+                     [](const InputSection *A, const InputSection *B) -> bool {
+                       return A->File->PPC64SmallCodeModelTocRelocs &&
+                              !B->File->PPC64SmallCodeModelTocRelocs;
+                     });
+    return;
+  }
+
   // Sort input sections by priority using the list provided
   // by --symbol-ordering-file.
   if (!Order.empty())
@@ -1650,11 +1677,34 @@
   if (!Config->Relocatable)
     forEachRelSec(scanRelocations<ELFT>);
 
+  addIRelativeRelocs();
+
   if (In.Plt && !In.Plt->empty())
     In.Plt->addSymbols();
   if (In.Iplt && !In.Iplt->empty())
     In.Iplt->addSymbols();
 
+  if (!Config->AllowShlibUndefined) {
+    // Error on undefined symbols in a shared object, if all of its DT_NEEDED
+    // entires are seen. These cases would otherwise lead to runtime errors
+    // reported by the dynamic linker.
+    //
+    // ld.bfd traces all DT_NEEDED to emulate the logic of the dynamic linker to
+    // catch more cases. That is too much for us. Our approach resembles the one
+    // used in ld.gold, achieves a good balance to be useful but not too smart.
+    for (InputFile *File : SharedFiles) {
+      SharedFile<ELFT> *F = cast<SharedFile<ELFT>>(File);
+      F->AllNeededIsKnown = llvm::all_of(F->DtNeeded, [&](StringRef Needed) {
+        return Symtab->SoNames.count(Needed);
+      });
+    }
+    for (Symbol *Sym : Symtab->getSymbols())
+      if (Sym->isUndefined() && !Sym->isWeak())
+        if (auto *F = dyn_cast_or_null<SharedFile<ELFT>>(Sym->File))
+          if (F->AllNeededIsKnown)
+            error(toString(F) + ": undefined reference to " + toString(*Sym));
+  }
+
   // Now that we have defined all possible global symbols including linker-
   // synthesized ones. Visit all symbols to give the finishing touches.
   for (Symbol *Sym : Symtab->getSymbols()) {
@@ -2181,11 +2231,23 @@
       P->p_memsz = alignTo(P->p_memsz, Target->PageSize);
     }
 
-    // The TLS pointer goes after PT_TLS for variant 2 targets. At least glibc
-    // will align it, so round up the size to make sure the offsets are
-    // correct.
-    if (P->p_type == PT_TLS && P->p_memsz)
+    if (P->p_type == PT_TLS && P->p_memsz) {
+      if (!Config->Shared &&
+          (Config->EMachine == EM_ARM || Config->EMachine == EM_AARCH64)) {
+        // On ARM/AArch64, reserve extra space (8 words) between the thread
+        // pointer and an executable's TLS segment by overaligning the segment.
+        // This reservation is needed for backwards compatibility with Android's
+        // TCB, which allocates several slots after the thread pointer (e.g.
+        // TLS_SLOT_STACK_GUARD==5). For simplicity, this overalignment is also
+        // done on other operating systems.
+        P->p_align = std::max<uint64_t>(P->p_align, Config->Wordsize * 8);
+      }
+
+      // The TLS pointer goes after PT_TLS for variant 2 targets. At least glibc
+      // will align it, so round up the size to make sure the offsets are
+      // correct.
       P->p_memsz = alignTo(P->p_memsz, P->p_align);
+    }
   }
 }
 
diff --git a/ELF/Writer.h b/ELF/Writer.h
index 7806f82..2ff99e6 100644
--- a/ELF/Writer.h
+++ b/ELF/Writer.h
@@ -1,9 +1,8 @@
 //===- Writer.h -------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/LICENSE.TXT b/LICENSE.TXT
index e05e184..cba22f6 100644
--- a/LICENSE.TXT
+++ b/LICENSE.TXT
@@ -1,10 +1,245 @@
 ==============================================================================
-lld License
+The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
+==============================================================================
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+    1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+    2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+    3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+    4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+    5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+    6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+    7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+    8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+    9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+    END OF TERMS AND CONDITIONS
+
+    APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+    Copyright [yyyy] [name of copyright owner]
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+
+---- LLVM Exceptions to the Apache 2.0 License ----
+
+As an exception, if, as a result of your compiling your source code, portions
+of this Software are embedded into an Object form of such source code, you
+may redistribute such embedded portions in such Object form without complying
+with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
+
+In addition, if you combine or link compiled forms of this Software with
+software that is licensed under the GPLv2 ("Combined Software") and if a
+court of competent jurisdiction determines that the patent provision (Section
+3), the indemnity provision (Section 9) or other Section of the License
+conflicts with the conditions of the GPLv2, you may retroactively and
+prospectively choose to deem waived or otherwise exclude such Section(s) of
+the License, but only in their entirety and only with respect to the Combined
+Software.
+
+==============================================================================
+Software from third parties included in the LLVM Project:
+==============================================================================
+The LLVM Project contains third party software which is under different license
+terms. All such code will be identified clearly using at least one of two
+mechanisms:
+1) It will be in a separate directory tree with its own `LICENSE.txt` or
+   `LICENSE` file at the top containing the specific license and restrictions
+   which apply to that software, or
+2) It will contain specific license and restriction terms at the top of every
+   file.
+
+==============================================================================
+Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy):
 ==============================================================================
 University of Illinois/NCSA
 Open Source License
 
-Copyright (c) 2011-2018 by the contributors listed in CREDITS.TXT
+Copyright (c) 2011-2019 by the contributors listed in CREDITS.TXT
 All rights reserved.
 
 Developed by:
@@ -41,22 +276,3 @@
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
 SOFTWARE.
-
-==============================================================================
-The lld software contains code written by third parties.  Such software will
-have its own individual LICENSE.TXT file in the directory in which it appears.
-This file will describe the copyrights, license, and restrictions which apply
-to that code.
-
-The disclaimer of warranty in the University of Illinois Open Source License
-applies to all code in the lld Distribution, and nothing in any of the
-other licenses gives permission to use the names of the LLVM Team or the
-University of Illinois to endorse or promote products derived from this
-Software.
-
-The following pieces of software have additional or alternate copyrights,
-licenses, and/or restrictions:
-
-Program             Directory
--------             ---------
-<none yet>
diff --git a/MinGW/Driver.cpp b/MinGW/Driver.cpp
index d682baf..920afd1 100644
--- a/MinGW/Driver.cpp
+++ b/MinGW/Driver.cpp
@@ -1,14 +1,31 @@
 //===- MinGW/Driver.cpp ---------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-///
-/// GNU ld style linker driver for COFF currently supporting mingw-w64.
-///
+//
+// MinGW is a GNU development environment for Windows. It consists of GNU
+// tools such as GCC and GNU ld. Unlike Cygwin, there's no POSIX-compatible
+// layer, as it aims to be a native development toolchain.
+//
+// lld/MinGW is a drop-in replacement for GNU ld/MinGW.
+//
+// Being a native development tool, a MinGW linker is not very different from
+// Microsoft link.exe, so a MinGW linker can be implemented as a thin wrapper
+// for lld/COFF. This driver takes Unix-ish command line options, translates
+// them to Windows-ish ones, and then passes them to lld/COFF.
+//
+// When this driver calls the lld/COFF driver, it passes a hidden option
+// "-lldmingw" along with other user-supplied options, to run the lld/COFF
+// linker in "MinGW mode".
+//
+// There are subtle differences between MS link.exe and GNU ld/MinGW, and GNU
+// ld/MinGW implements a few GNU-specific features. Such features are directly
+// implemented in lld/COFF and enabled only when the linker is running in MinGW
+// mode.
+//
 //===----------------------------------------------------------------------===//
 
 #include "lld/Common/Driver.h"
@@ -170,6 +187,9 @@
       Args.getLastArgValue(OPT_m) != "arm64pe" && !Args.hasArg(OPT_dynamicbase))
     Add("-dynamicbase:no");
 
+  if (Args.hasFlag(OPT_no_insert_timestamp, OPT_insert_timestamp, false))
+    Add("-timestamp:0");
+
   if (Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false))
     Add("-opt:ref");
   else
diff --git a/MinGW/Options.td b/MinGW/Options.td
index 948faa6..1eee1ca 100644
--- a/MinGW/Options.td
+++ b/MinGW/Options.td
@@ -6,6 +6,8 @@
 
 def L: JoinedOrSeparate<["-"], "L">, MetaVarName<"<dir>">,
   HelpText<"Add a directory to the library search path">;
+def Bdynamic: F<"Bdynamic">, HelpText<"Link against shared libraries">;
+def Bstatic: F<"Bstatic">, HelpText<"Do not link against shared libraries">;
 def dynamicbase: F<"dynamicbase">, HelpText<"Enable ASLR">;
 def entry: S<"entry">, MetaVarName<"<entry>">,
   HelpText<"Name of entry point symbol">;
@@ -14,12 +16,16 @@
 def gc_sections: F<"gc-sections">, HelpText<"Remove unused sections">;
 def icf: J<"icf=">, HelpText<"Identical code folding">;
 def image_base: S<"image-base">, HelpText<"Base address of the program">;
+def insert_timestamp: F<"insert-timestamp">,
+    HelpText<"Include PE header timestamp">;
 def kill_at: F<"kill-at">, HelpText<"Remove @n from exported symbols">;
 def l: JoinedOrSeparate<["-"], "l">, MetaVarName<"<libName>">,
   HelpText<"Root name of library to use">;
 def m: JoinedOrSeparate<["-"], "m">, HelpText<"Set target emulation">;
 def map: S<"Map">, HelpText<"Output a linker map">;
 def map_eq: J<"Map=">, Alias<map>;
+def no_insert_timestamp: F<"no-insert-timestamp">,
+    HelpText<"Don't include PE header timestamp">;
 def no_whole_archive: F<"no-whole-archive">,
     HelpText<"No longer include all object files for following archives">;
 def large_address_aware: Flag<["--"], "large-address-aware">,
@@ -52,29 +58,31 @@
 def Xlink : J<"Xlink=">, MetaVarName<"<arg>">,
     HelpText<"Pass <arg> to the COFF linker">;
 
-// Currently stubs to avoid errors
-def Bdynamic: F<"Bdynamic">, HelpText<"Link against shared libraries">;
-def Bstatic: F<"Bstatic">, HelpText<"Do not link against shared libraries">;
-def O: Joined<["-"], "O">, HelpText<"Optimize output file size">;
-def build_id: F<"build-id">;
-def disable_auto_image_base: F<"disable-auto-image-base">;
-def enable_auto_image_base: F<"enable-auto-image-base">;
-def enable_auto_import: F<"enable-auto-import">;
-def end_group: F<"end-group">;
-def full_shutdown: Flag<["--"], "full-shutdown">;
-def high_entropy_va: F<"high-entropy-va">, HelpText<"Enable 64-bit ASLR">;
-def major_image_version: S<"major-image-version">;
-def minor_image_version: S<"minor-image-version">;
-def no_seh: F<"no-seh">;
-def nxcompat: F<"nxcompat">, HelpText<"Enable data execution prevention">;
-def pic_executable: F<"pic-executable">;
-def sysroot: J<"sysroot">, HelpText<"Sysroot">;
-def start_group: F<"start-group">;
-def tsaware: F<"tsaware">, HelpText<"Create Terminal Server aware executable">;
-def v: Flag<["-"], "v">, HelpText<"Display the version number">;
-def version: F<"version">, HelpText<"Display the version number and exit">;
-
 // Alias
 def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>;
 def alias_strip_s: Flag<["-"], "s">, Alias<strip_all>;
 def alias_strip_S: Flag<["-"], "S">, Alias<strip_debug>;
+
+// Ignored options
+def: Joined<["-"], "O">;
+def: F<"build-id">;
+def: F<"disable-auto-image-base">;
+def: F<"enable-auto-image-base">;
+def: F<"enable-auto-import">;
+def: F<"end-group">;
+def: Flag<["--"], "full-shutdown">;
+def: F<"high-entropy-va">;
+def: S<"major-image-version">;
+def: S<"minor-image-version">;
+def: F<"no-seh">;
+def: F<"nxcompat">;
+def: F<"pic-executable">;
+def: S<"plugin">;
+def: J<"plugin=">;
+def: S<"plugin-opt">;
+def: J<"plugin-opt=">;
+def: J<"sysroot">;
+def: F<"start-group">;
+def: F<"tsaware">;
+def: Flag<["-"], "v">;
+def: F<"version">;
diff --git a/docs/NewLLD.rst b/docs/NewLLD.rst
index afdb41e..d01fb53 100644
--- a/docs/NewLLD.rst
+++ b/docs/NewLLD.rst
@@ -53,7 +53,7 @@
   until we need them to continue linking.
   When we need to do some costly operation (such as looking up
   a hash table for each symbol), we do it only once.
-  We obtain a handler (which is typically just a pointer to actual data)
+  We obtain a handle (which is typically just a pointer to actual data)
   on the first operation and use it throughout the process.
 
 * Efficient archive file handling
@@ -90,18 +90,18 @@
   `--end-group`, to let the linker loop over the files between the options until
   no new symbols are added to the set.
 
-  Visiting the same archive files multiple makes the linker slower.
+  Visiting the same archive files multiple times makes the linker slower.
 
   Here is how LLD approaches the problem. Instead of memorizing only undefined
   symbols, we program LLD so that it memorizes all symbols.  When it sees an
   undefined symbol that can be resolved by extracting an object file from an
-  archive file it previously visited, it immediately extracts the file and link
-  it.  It is doable because LLD does not forget symbols it have seen in archive
+  archive file it previously visited, it immediately extracts the file and links
+  it.  It is doable because LLD does not forget symbols it has seen in archive
   files.
 
-  We believe that the LLD's way is efficient and easy to justify.
+  We believe that LLD's way is efficient and easy to justify.
 
-  The semantics of LLD's archive handling is different from the traditional
+  The semantics of LLD's archive handling are different from the traditional
   Unix's.  You can observe it if you carefully craft archive files to exploit
   it.  However, in reality, we don't know any program that cannot link with our
   algorithm so far, so it's not going to cause trouble.
@@ -157,7 +157,7 @@
   - Undefined symbols represent undefined symbols, which need to be replaced by
     Defined symbols by the resolver until the link is complete.
   - Lazy symbols represent symbols we found in archive file headers
-    which can turn into Defined if we read archieve members.
+    which can turn into Defined if we read archive members.
 
   There's only one Symbol instance for each unique symbol name. This uniqueness
   is guaranteed by the symbol table. As the resolver reads symbols from input
@@ -307,3 +307,11 @@
   On Unix, your program is generally not guaranteed to be safe with ICF,
   although large programs happen to work correctly.
   LLD works fine with ICF for example.
+
+Other Info
+----------
+
+.. toctree::
+   :maxdepth: 1
+
+   missingkeyfunction
diff --git a/docs/Readers.rst b/docs/Readers.rst
index b69a0b3..eae1717 100644
--- a/docs/Readers.rst
+++ b/docs/Readers.rst
@@ -74,7 +74,7 @@
 object.  Any parsing state should be in ivars of your File subclass or in
 some temporary object.
 
-The key method to implement in a reader is::
+The key function to implement in a reader is::
 
   virtual error_code loadFile(LinkerInput &input,
                               std::vector<std::unique_ptr<File>> &result);
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index 30c1804..0b3cee5 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -1,19 +1,19 @@
 =======================
-lld 8.0.0 Release Notes
+lld 9.0.0 Release Notes
 =======================
 
 .. contents::
     :local:
 
 .. warning::
-   These are in-progress notes for the upcoming LLVM 8.0.0 release.
+   These are in-progress notes for the upcoming LLVM 9.0.0 release.
    Release notes for previous releases can be found on
    `the Download Page <https://releases.llvm.org/download.html>`_.
 
 Introduction
 ============
 
-This document contains the release notes for the lld linker, release 8.0.0.
+This document contains the release notes for the lld linker, release 9.0.0.
 Here we describe the status of lld, including major improvements
 from the previous release. All lld releases may be downloaded
 from the `LLVM releases web site <https://llvm.org/releases/>`_.
@@ -24,42 +24,17 @@
 ELF Improvements
 ----------------
 
-* lld now supports RISC-V. (`r339364
-  <https://reviews.llvm.org/rL339364>`_)
-
-* Default image base address has changed from 65536 to 2 MiB for i386
-  and 4 MiB for AArch64 to make lld-generated executables work better
-  with automatic superpage promotion. FreeBSD can promote contiguous
-  non-superpages to a superpage if they are aligned to the superpage
-  size. (`r342746 <https://reviews.llvm.org/rL342746>`_)
-
-* lld/Hexagon can now link Linux kernel and musl libc for Qualcomm
-  Hexagon ISA.
-
-* The following flags have been added: ``-z interpose``, ``-z global``
+* ...
 
 COFF Improvements
 -----------------
 
-* PDB GUID is set to hash of PDB contents instead to a random byte
-  sequence for build reproducibility.
-
-* The following flags have been added: ``/force:multiple``
-
-* lld now can link against import libraries produced by GNU tools.
-
-* lld can create thunks for ARM, to allow linking images over 16 MB.
+* ...
 
 MinGW Improvements
 ------------------
 
-* lld can now automatically import data variables from DLLs without the
-  use of the dllimport attribute.
-
-* lld can now use existing normal MinGW sysroots with import libraries and
-  CRT startup object files for GNU binutils. lld can handle most object
-  files produced by GCC, and thus works as a drop-in replacement for
-  ld.bfd in such environments.
+* ...
 
 MachO Improvements
 ------------------
@@ -69,7 +44,4 @@
 WebAssembly Improvements
 ------------------------
 
-* Add initial support for creating shared libraries (-shared).
-  Note: The shared library format is still under active development and may
-  undergo significant changes in future versions.
-  See: https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
+* ...
diff --git a/docs/WebAssembly.rst b/docs/WebAssembly.rst
index 424c1a1..016fdd7 100644
--- a/docs/WebAssembly.rst
+++ b/docs/WebAssembly.rst
@@ -11,8 +11,7 @@
 ------------------
 
 The format the input object files that lld expects is specified as part of the
-the WebAssembly tool conventions
-https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md.
+the WebAssembly tool conventions on linking_.
 
 This is object format that the llvm will produce when run with the
 ``wasm32-unknown-unknown`` target.  To build llvm with WebAssembly support
@@ -88,10 +87,32 @@
 By default the function table is neither imported nor exported, but defined
 for internal use only.
 
-When building shared libraries symbols are exported if they are marked
-as ``visibility=default``.  When building executables only the entry point is
-exported by default.  In addition any symbol included on the command line via
-``--export`` is also exported.
+Bahaviour
+---------
+
+In general, where possible, the WebAssembly linker attempts to emulate the
+behavior of a traditional ELF linker, and in particular the ELF port of lld.
+For more specific details on how this is achieved see the tool conventions on
+linking_.
+
+Imports and Exports
+~~~~~~~~~~~~~~~~~~~
+
+When building a shared library any symbols marked as ``visibility=default`` will
+be exported.  When building an executable, only the entry point and symbols
+flagged as ``WASM_SYMBOL_EXPORTED`` are exported by default.  In LLVM the
+``WASM_SYMBOL_EXPORTED`` flag is applied to any symbol in the ``llvm.used`` list
+which corresponds to ``__attribute__((used))`` in C/C++ sources.
+
+In addition, symbols can be exported via the linker command line using
+``--export``.
+
+Finally, just like with native ELF linker the ``--export-dynamic`` flag can be
+used to export symbol in the executable which are marked as
+``visibility=default``.
+
+Garbage Collection
+~~~~~~~~~~~~~~~~~~
 
 Since WebAssembly is designed with size in mind the linker defaults to
 ``--gc-sections`` which means that all unused functions and data segments will
@@ -103,6 +124,18 @@
 - Any symbol which is to be exported.
 - Any symbol transitively referenced by the above.
 
+Weak Undefined Functions
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+On native platforms, calls to weak undefined functions end up as calls to the
+null function pointer.  With WebAssembly, direct calls must reference a defined
+function (with the correct signature).  In order to handle this case the linker
+will generate function a stub containing only the ``unreachable`` instruction
+and use this for any direct references to an undefined weak function.
+
+For example a runtime call to a weak undefined function ``foo`` will up trapping
+on ``unreachable`` inside and linker-generated function called
+``undefined:foo``.
 
 Missing features
 ----------------
@@ -112,3 +145,5 @@
 - No support for creating shared libraries.  The spec for shared libraries in
   WebAssembly is still in flux:
   https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
+
+.. _linking: https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md
diff --git a/docs/conf.py b/docs/conf.py
index 62404b2..dd65859 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -48,9 +48,9 @@
 # built documents.
 #
 # The short version.
-version = '8'
+version = '9'
 # The full version, including alpha/beta/rc tags.
-release = '8'
+release = '9'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/docs/getting_started.rst b/docs/getting_started.rst
index 97c3d1b..a174f65 100644
--- a/docs/getting_started.rst
+++ b/docs/getting_started.rst
@@ -28,23 +28,15 @@
 .. _libc++: http://libcxx.llvm.org/
 .. _Python 2.4: http://python.org/download/
 
-2. Check out LLVM::
+2. Check out LLVM and subprojects (including lld)::
 
-     $ cd path/to/llvm-project
-     $ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
-
-3. Check out lld::
-
-     $ cd llvm/tools
-     $ svn co http://llvm.org/svn/llvm-project/lld/trunk lld
-
-  * lld can also be checked out to ``path/to/llvm-project`` and built as an external
-    project.
+     $ git clone https://github.com/llvm/llvm-project.git
 
 4. Build LLVM and lld::
 
-     $ cd path/to/llvm-build/llvm (out of source build required)
-     $ cmake -G "Unix Makefiles" path/to/llvm-project/llvm
+     $ cd llvm-project
+     $ mkdir build && cd build
+     $ cmake -G "Unix Makefiles" -DLLVM_ENABLE_PROJECTS=lld ../llvm
      $ make
 
   * If you want to build with clang and it is not the default compiler or
@@ -71,23 +63,12 @@
 .. _Visual Studio 12 (2013) or later: http://www.microsoft.com/visualstudio/11/en-us
 .. _Python 2.4: http://python.org/download/
 
-#. Check out LLVM::
-
-     $ cd path/to/llvm-project
-     $ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
-
-#. Check out lld::
-
-     $ cd llvm/tools
-     $ svn co http://llvm.org/svn/llvm-project/lld/trunk lld
-
-  * lld can also be checked out to ``path/to/llvm-project`` and built as an external
-    project.
+#. Check out LLVM as above.
 
 #. Generate Visual Studio project files::
 
-     $ cd path/to/llvm-build/llvm (out of source build required)
-     $ cmake -G "Visual Studio 11" path/to/llvm-project/llvm
+     $ cd llvm-project/build (out of source build required)
+     $ cmake -G "Visual Studio 11" -DLLVM_ENABLE_PROJECTS=lld ../llvm
 
 #. Build
 
diff --git a/docs/index.rst b/docs/index.rst
index 2821ce4..8b3f70e 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,7 +1,7 @@
 LLD - The LLVM Linker
 =====================
 
-LLD is a linker from the LLVM project. That is a drop-in replacement
+LLD is a linker from the LLVM project that is a drop-in replacement
 for system linkers and runs much faster than them. It also provides
 features that are useful for toolchain developers.
 
@@ -17,7 +17,7 @@
 Features
 --------
 
-- LLD is a drop-in replacement for the GNU linkers. That accepts the
+- LLD is a drop-in replacement for the GNU linkers that accepts the
   same command line arguments and linker scripts as GNU.
 
   We are currently working closely with the FreeBSD project to make
@@ -30,29 +30,27 @@
   <https://www.freebsd.org/news/status/report-2016-10-2016-12.html#Using-LLVM%27s-LLD-Linker-as-FreeBSD%27s-System-Linker>`_.
 
 - LLD is very fast. When you link a large program on a multicore
-  machine, you can expect that LLD runs more than twice as fast as GNU
+  machine, you can expect that LLD runs more than twice as fast as the GNU
   gold linker. Your milage may vary, though.
 
 - It supports various CPUs/ABIs including x86-64, x86, x32, AArch64,
   ARM, MIPS 32/64 big/little-endian, PowerPC, PowerPC 64 and AMDGPU.
-  Among these, x86-64 is the most well-supported target and have
-  reached production quality. AArch64 and MIPS seem decent too. x86
-  should be OK but not well tested yet. ARM support is being developed
-  actively.
+  Among these, x86-64, AArch64, and ARM (>= v6) are production quality.
+  MIPS seems decent too. x86 should be OK but is not well tested yet.
 
 - It is always a cross-linker, meaning that it always supports all the
   above targets however it was built. In fact, we don't provide a
   build-time option to enable/disable each target. This should make it
   easy to use our linker as part of a cross-compile toolchain.
 
-- You can embed LLD to your program to eliminate dependency to
+- You can embed LLD in your program to eliminate dependencies on
   external linkers. All you have to do is to construct object files
   and command line arguments just like you would do to invoke an
   external linker and then call the linker's main function,
   ``lld::elf::link``, from your code.
 
 - It is small. We are using LLVM libObject library to read from object
-  files, so it is not completely a fair comparison, but as of February
+  files, so it is not a completely fair comparison, but as of February
   2017, LLD/ELF consists only of 21k lines of C++ code while GNU gold
   consists of 198k lines of C++ code.
 
@@ -102,13 +100,13 @@
 details, see `Getting Started with the LLVM System
 <http://llvm.org/docs/GettingStarted.html>`_.
 
-If you haven't checkout out LLVM, the easiest way to build LLD is to
-checkout the entire LLVM projects/sub-projects from a git mirror and
+If you haven't checked out LLVM, the easiest way to build LLD is to
+check out the entire LLVM projects/sub-projects from a git mirror and
 build that tree. You need `cmake` and of course a C++ compiler.
 
 .. code-block:: console
 
-  $ git clone https://github.com/llvm-project/llvm-project-20170507 llvm-project
+  $ git clone https://github.com/llvm/llvm-project llvm-project
   $ mkdir build
   $ cd build
   $ cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=lld -DCMAKE_INSTALL_PREFIX=/usr/local ../llvm-project/llvm
@@ -175,4 +173,5 @@
    AtomLLD
    WebAssembly
    windows_support
+   missingkeyfunction
    ReleaseNotes
diff --git a/docs/ld.lld.1 b/docs/ld.lld.1
index d1ce4a3..591e165 100644
--- a/docs/ld.lld.1
+++ b/docs/ld.lld.1
@@ -1,5 +1,6 @@
-.\" This file is distributed under the University of Illinois Open Source
-.\" License. See LICENSE.TXT for details.
+.\" Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+.\" See https://llvm.org/LICENSE.txt for license information.
+.\" SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 .\"
 .\" This man page documents only lld's ELF linking support, obtained originally
 .\" from FreeBSD.
@@ -45,6 +46,9 @@
 .It Fl -allow-multiple-definition
 Do not error if a symbol is defined multiple times.
 The first definition will be used.
+.It Fl -allow-shlib-undefined
+Allow unresolved references in shared libraries.
+This option is enabled by default when linking a shared library.
 .It Fl -apply-dynamic-relocs
 Apply link-time values for dynamic relocations.
 .It Fl -as-needed
@@ -241,6 +245,9 @@
 .It Fl -Map Ns = Ns Ar file , Fl M Ar file
 Print a link map to
 .Ar file .
+.It Fl -no-allow-shlib-undefined
+Do not allow unresolved references in shared libraries.
+This option is enabled by default when linking an executable.
 .It Fl -no-as-needed
 Always set
 .Dv DT_NEEDED
@@ -311,6 +318,8 @@
 .Ar file .
 .It Fl -opt-remarks-with-hotness
 Include hotness information in the optimization remarks file.
+.It Fl -pic-veneer
+Always generate position independent thunks.
 .It Fl -pie
 Create a position independent executable.
 .It Fl -print-gc-sections
diff --git a/docs/missingkeyfunction.rst b/docs/missingkeyfunction.rst
new file mode 100644
index 0000000..54ad325
--- /dev/null
+++ b/docs/missingkeyfunction.rst
@@ -0,0 +1,84 @@
+Missing Key Function
+====================
+
+If your build failed with a linker error something like this::
+
+  foo.cc:28: error: undefined reference to 'vtable for C'
+  the vtable symbol may be undefined because the class is missing its key function (see https://lld.llvm.org/missingkeyfunction)
+
+it's likely that your class C has a key function (defined by the ABI as the first
+non-pure, non-inline, virtual method), but you haven't actually defined it.
+
+When a class has a key function, the compiler emits the vtable (and some other
+things as well) only in the translation unit that defines that key function. Thus,
+if you're missing the key function, you'll also be missing the vtable. If no other
+function calls your missing method, you won't see any undefined reference errors
+for it, but you will see undefined references to the vtable symbol.
+
+When a class has no non-pure, non-inline, virtual methods, there is no key
+method, and the compiler is forced to emit the vtable in every translation unit
+that references the class. In this case, it is emitted in a COMDAT section,
+which allows the linker to eliminate all duplicate copies. This is still
+wasteful in terms of object file size and link time, so it's always advisable to
+ensure there is at least one eligible method that can serve as the key function.
+
+Here are the most common mistakes that lead to this error:
+
+Failing to define a virtual destructor
+--------------------------------------
+
+Say you have a base class declared in a header file::
+
+  class B {
+  public:
+    B();
+    virtual ~B();
+    ...
+  };
+
+Here, ``~B`` is the first non-pure, non-inline, virtual method, so it is the key
+method. If you forget to define ``B::~B`` in your source file, the compiler will
+not emit the vtable for ``B``, and you'll get an undefined reference to "vtable
+for B".
+
+This is just an example of the more general mistake of forgetting to define the
+key function, but it's quite common because virtual destructors are likely to be
+the first eligible key function and it's easy to forget to implement them. It's
+also more likely that you won't have any direct references to the destructor, so
+you won't see any undefined reference errors that point directly to the problem.
+
+The solution in this case is to implement the missing method.
+
+Forgetting to declare a virtual method in an abstract class as pure
+-------------------------------------------------------------------
+
+Say you have an abstract base class declared in a header file::
+
+  class A {
+  public:
+    A();
+    virtual ~A() {}
+    virtual int foo() = 0;
+    ...
+    virtual int bar();
+    ...
+  };
+
+This base class is intended to be abstract, but you forgot to mark one of the
+methods pure. Here, ``A::bar``, being non-pure, is nominated as the key function,
+and as a result, the vtable for ``A`` is not emitted, because the compiler is
+waiting for a translation unit that defines ``A::bar``.
+
+The solution in this case is to add the missing ``= 0`` to the declaration of
+``A::bar``.
+
+Key method is defined, but the linker doesn't see it
+----------------------------------------------------
+
+It's also possible that you have defined the key function somewhere, but the
+object file containing the definition of that method isn't being linked into
+your application.
+
+The solution in this case is to check your dependencies to make sure that
+the object file or the library file containing the key function is given to
+the linker.
diff --git a/docs/open_projects.rst b/docs/open_projects.rst
index eeb9f9f..36edca4 100644
--- a/docs/open_projects.rst
+++ b/docs/open_projects.rst
@@ -3,8 +3,6 @@
 Open Projects
 =============
 
-.. include:: ../include/lld/Core/TODO.txt
-
 Documentation TODOs
 ~~~~~~~~~~~~~~~~~~~
 
diff --git a/docs/windows_support.rst b/docs/windows_support.rst
index a0a2c4d..c9723c4 100644
--- a/docs/windows_support.rst
+++ b/docs/windows_support.rst
@@ -20,8 +20,8 @@
 almost all command line options that the linker shipped with Microsoft Visual
 C++ (link.exe) supports.
 
-The current status is that LLD can link itself on Windows x86/x64
-using Visual C++ 2013 as the compiler.
+The current status is that LLD is used to link production builds of large
+real-world binaries such as Firefox and Chromium.
 
 Development status
 ==================
diff --git a/include/lld/Common/Args.h b/include/lld/Common/Args.h
index 769d484..d943646 100644
--- a/include/lld/Common/Args.h
+++ b/include/lld/Common/Args.h
@@ -1,9 +1,8 @@
 //===- Args.h ---------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -11,6 +10,7 @@
 #define LLD_ARGS_H
 
 #include "lld/Common/LLVM.h"
+#include "llvm/Support/CodeGen.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include <vector>
 
@@ -22,7 +22,11 @@
 
 namespace lld {
 namespace args {
+
+llvm::CodeGenOpt::Level getCGOptLevel(int OptLevelLTO);
+
 int getInteger(llvm::opt::InputArgList &Args, unsigned Key, int Default);
+
 std::vector<StringRef> getStrings(llvm::opt::InputArgList &Args, int Id);
 
 uint64_t getZOptionValue(llvm::opt::InputArgList &Args, int Id, StringRef Key,
diff --git a/include/lld/Common/Driver.h b/include/lld/Common/Driver.h
index f6d9293..745ef72 100644
--- a/include/lld/Common/Driver.h
+++ b/include/lld/Common/Driver.h
@@ -1,9 +1,8 @@
 //===- lld/Common/Driver.h - Linker Driver Emulator -----------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/Common/ErrorHandler.h b/include/lld/Common/ErrorHandler.h
index c169f7b..bd9c257 100644
--- a/include/lld/Common/ErrorHandler.h
+++ b/include/lld/Common/ErrorHandler.h
@@ -1,9 +1,8 @@
 //===- ErrorHandler.h -------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/include/lld/Common/LLVM.h b/include/lld/Common/LLVM.h
index 95a2aa9..944bb41 100644
--- a/include/lld/Common/LLVM.h
+++ b/include/lld/Common/LLVM.h
@@ -1,9 +1,8 @@
 //===--- LLVM.h - Import various common LLVM datatypes ----------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/include/lld/Common/Memory.h b/include/lld/Common/Memory.h
index 699f7c1..78f6e24 100644
--- a/include/lld/Common/Memory.h
+++ b/include/lld/Common/Memory.h
@@ -1,9 +1,8 @@
 //===- Memory.h -------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/include/lld/Common/Reproduce.h b/include/lld/Common/Reproduce.h
index 0f425de..ac7a822 100644
--- a/include/lld/Common/Reproduce.h
+++ b/include/lld/Common/Reproduce.h
@@ -1,9 +1,8 @@
 //===- Reproduce.h - Utilities for creating reproducers ---------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/Common/Strings.h b/include/lld/Common/Strings.h
index 566030e..efc9245 100644
--- a/include/lld/Common/Strings.h
+++ b/include/lld/Common/Strings.h
@@ -1,9 +1,8 @@
 //===- Strings.h ------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/Common/TargetOptionsCommandFlags.h b/include/lld/Common/TargetOptionsCommandFlags.h
index 2eaecb7..9345e61 100644
--- a/include/lld/Common/TargetOptionsCommandFlags.h
+++ b/include/lld/Common/TargetOptionsCommandFlags.h
@@ -1,9 +1,8 @@
 //===-- TargetOptionsCommandFlags.h ----------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -16,8 +15,8 @@
 #include "llvm/Target/TargetOptions.h"
 
 namespace lld {
-llvm::TargetOptions InitTargetOptionsFromCodeGenFlags();
-llvm::Optional<llvm::CodeModel::Model> GetCodeModelFromCMModel();
-std::string GetCPUStr();
-std::vector<std::string> GetMAttrs();
+llvm::TargetOptions initTargetOptionsFromCodeGenFlags();
+llvm::Optional<llvm::CodeModel::Model> getCodeModelFromCMModel();
+std::string getCPUStr();
+std::vector<std::string> getMAttrs();
 }
diff --git a/include/lld/Common/Threads.h b/include/lld/Common/Threads.h
index 1425abd..e356fcd 100644
--- a/include/lld/Common/Threads.h
+++ b/include/lld/Common/Threads.h
@@ -1,9 +1,8 @@
 //===- Threads.h ------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/include/lld/Common/Timer.h b/include/lld/Common/Timer.h
index 6654af6..e2b6951 100644
--- a/include/lld/Common/Timer.h
+++ b/include/lld/Common/Timer.h
@@ -1,9 +1,8 @@
 //===- Timer.h ----------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/Common/Version.h b/include/lld/Common/Version.h
index 23a10ed..9571aa2 100644
--- a/include/lld/Common/Version.h
+++ b/include/lld/Common/Version.h
@@ -1,9 +1,8 @@
 //===- lld/Common/Version.h - LLD Version Number ----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/include/lld/Core/AbsoluteAtom.h b/include/lld/Core/AbsoluteAtom.h
index ed25297..5214b41 100644
--- a/include/lld/Core/AbsoluteAtom.h
+++ b/include/lld/Core/AbsoluteAtom.h
@@ -1,9 +1,8 @@
 //===- Core/AbsoluteAtom.h - An absolute Atom -----------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/Core/ArchiveLibraryFile.h b/include/lld/Core/ArchiveLibraryFile.h
index 2c736e7..0abef40 100644
--- a/include/lld/Core/ArchiveLibraryFile.h
+++ b/include/lld/Core/ArchiveLibraryFile.h
@@ -1,9 +1,8 @@
 //===- Core/ArchiveLibraryFile.h - Models static library ------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/Core/Atom.h b/include/lld/Core/Atom.h
index 149c3d5..4d3d27a 100644
--- a/include/lld/Core/Atom.h
+++ b/include/lld/Core/Atom.h
@@ -1,9 +1,8 @@
 //===- Core/Atom.h - A node in linking graph --------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/Core/DefinedAtom.h b/include/lld/Core/DefinedAtom.h
index ba10b45..4b1de7f 100644
--- a/include/lld/Core/DefinedAtom.h
+++ b/include/lld/Core/DefinedAtom.h
@@ -1,9 +1,8 @@
 //===- Core/DefinedAtom.h - An Atom with content --------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/Core/Error.h b/include/lld/Core/Error.h
index 36a3672..c18fe96 100644
--- a/include/lld/Core/Error.h
+++ b/include/lld/Core/Error.h
@@ -1,9 +1,8 @@
 //===- Error.h - system_error extensions for lld ----------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/include/lld/Core/File.h b/include/lld/Core/File.h
index 54f5335..492f359 100644
--- a/include/lld/Core/File.h
+++ b/include/lld/Core/File.h
@@ -1,9 +1,8 @@
 //===- Core/File.h - A Container of Atoms ---------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/Core/Instrumentation.h b/include/lld/Core/Instrumentation.h
index 939d645..602a37a 100644
--- a/include/lld/Core/Instrumentation.h
+++ b/include/lld/Core/Instrumentation.h
@@ -1,9 +1,8 @@
 //===- include/Core/Instrumentation.h - Instrumentation API ---------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/include/lld/Core/LinkingContext.h b/include/lld/Core/LinkingContext.h
index 52ab1a2..e090ff9 100644
--- a/include/lld/Core/LinkingContext.h
+++ b/include/lld/Core/LinkingContext.h
@@ -1,9 +1,8 @@
 //===- lld/Core/LinkingContext.h - Linker Target Info Interface -*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/Core/Node.h b/include/lld/Core/Node.h
index c304824..a224793 100644
--- a/include/lld/Core/Node.h
+++ b/include/lld/Core/Node.h
@@ -1,9 +1,8 @@
 //===- lld/Core/Node.h - Input file class -----------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/include/lld/Core/Pass.h b/include/lld/Core/Pass.h
index bfe3f9b..57d5a40 100644
--- a/include/lld/Core/Pass.h
+++ b/include/lld/Core/Pass.h
@@ -1,9 +1,8 @@
 //===------ Core/Pass.h - Base class for linker passes ----------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/Core/PassManager.h b/include/lld/Core/PassManager.h
index f2ef10f..02499d0 100644
--- a/include/lld/Core/PassManager.h
+++ b/include/lld/Core/PassManager.h
@@ -1,9 +1,8 @@
 //===- lld/Core/PassManager.h - Manage linker passes ----------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/Core/Reader.h b/include/lld/Core/Reader.h
index 6cf6282..a2d7912 100644
--- a/include/lld/Core/Reader.h
+++ b/include/lld/Core/Reader.h
@@ -1,9 +1,8 @@
 //===- lld/Core/Reader.h - Abstract File Format Reading Interface ---------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/Core/Reference.h b/include/lld/Core/Reference.h
index 1d3003c..191e0f0 100644
--- a/include/lld/Core/Reference.h
+++ b/include/lld/Core/Reference.h
@@ -1,9 +1,8 @@
 //===- Core/References.h - A Reference to Another Atom ----------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/Core/Resolver.h b/include/lld/Core/Resolver.h
index 5157c9f..9ab2195 100644
--- a/include/lld/Core/Resolver.h
+++ b/include/lld/Core/Resolver.h
@@ -1,9 +1,8 @@
 //===- Core/Resolver.h - Resolves Atom References -------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/Core/SharedLibraryAtom.h b/include/lld/Core/SharedLibraryAtom.h
index 7fec7a3..171d154 100644
--- a/include/lld/Core/SharedLibraryAtom.h
+++ b/include/lld/Core/SharedLibraryAtom.h
@@ -1,9 +1,8 @@
 //===- Core/SharedLibraryAtom.h - A Shared Library Atom -------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/Core/SharedLibraryFile.h b/include/lld/Core/SharedLibraryFile.h
index 53bf967..846d1f2 100644
--- a/include/lld/Core/SharedLibraryFile.h
+++ b/include/lld/Core/SharedLibraryFile.h
@@ -1,9 +1,8 @@
 //===- Core/SharedLibraryFile.h - Models shared libraries as Atoms --------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/Core/Simple.h b/include/lld/Core/Simple.h
index feeed6a..f211beb 100644
--- a/include/lld/Core/Simple.h
+++ b/include/lld/Core/Simple.h
@@ -1,9 +1,8 @@
 //===- lld/Core/Simple.h - Simple implementations of Atom and File --------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/include/lld/Core/SymbolTable.h b/include/lld/Core/SymbolTable.h
index 156c56e..c7502a4 100644
--- a/include/lld/Core/SymbolTable.h
+++ b/include/lld/Core/SymbolTable.h
@@ -1,9 +1,8 @@
 //===- Core/SymbolTable.h - Main Symbol Table -----------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/Core/TODO.txt b/include/lld/Core/TODO.txt
deleted file mode 100644
index 2aa61ff..0000000
--- a/include/lld/Core/TODO.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-include/lld/Core
-~~~~~~~~~~~~~~~~
-
-* The yaml reader/writer interfaces should be changed to return
-  an explanatory string if there is an error.  The existing error_code
-  abstraction only works for returning low level OS errors.  It does not
-  work for describing formatting issues.
-
-* We need to add more attributes to File.  In particular, we need cpu
-  and OS information (like target triples).  We should also provide explicit
-  support for `LLVM IR module flags metadata`__.
-
-.. __: http://llvm.org/docs/LangRef.html#module_flags
-.. _Clang: http://clang.llvm.org/docs/InternalsManual.html#Diagnostics
diff --git a/include/lld/Core/UndefinedAtom.h b/include/lld/Core/UndefinedAtom.h
index f45d6ec..a40db36 100644
--- a/include/lld/Core/UndefinedAtom.h
+++ b/include/lld/Core/UndefinedAtom.h
@@ -1,9 +1,8 @@
 //===- Core/UndefinedAtom.h - An Undefined Atom ---------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/Core/Writer.h b/include/lld/Core/Writer.h
index 1cdfabe..0de5fca 100644
--- a/include/lld/Core/Writer.h
+++ b/include/lld/Core/Writer.h
@@ -1,9 +1,8 @@
 //===- lld/Core/Writer.h - Abstract File Format Interface -----------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/ReaderWriter/MachOLinkingContext.h b/include/lld/ReaderWriter/MachOLinkingContext.h
index fde6588..f48ad77 100644
--- a/include/lld/ReaderWriter/MachOLinkingContext.h
+++ b/include/lld/ReaderWriter/MachOLinkingContext.h
@@ -1,9 +1,8 @@
 //===- lld/ReaderWriter/MachOLinkingContext.h -----------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/ReaderWriter/YamlContext.h b/include/lld/ReaderWriter/YamlContext.h
index b97d21f..dc133e3 100644
--- a/include/lld/ReaderWriter/YamlContext.h
+++ b/include/lld/ReaderWriter/YamlContext.h
@@ -1,9 +1,8 @@
 //===- lld/ReaderWriter/YamlContext.h - object used in YAML I/O context ---===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/Core/DefinedAtom.cpp b/lib/Core/DefinedAtom.cpp
index 177cae7..3c1eece 100644
--- a/lib/Core/DefinedAtom.cpp
+++ b/lib/Core/DefinedAtom.cpp
@@ -1,9 +1,8 @@
 //===- DefinedAtom.cpp ------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/Core/Error.cpp b/lib/Core/Error.cpp
index 6fc76f7..f138a81 100644
--- a/lib/Core/Error.cpp
+++ b/lib/Core/Error.cpp
@@ -1,9 +1,8 @@
 //===- Error.cpp - system_error extensions for lld --------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/Core/File.cpp b/lib/Core/File.cpp
index 30ded09..ce33923 100644
--- a/lib/Core/File.cpp
+++ b/lib/Core/File.cpp
@@ -1,9 +1,8 @@
 //===- Core/File.cpp - A Container of Atoms -------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/Core/LinkingContext.cpp b/lib/Core/LinkingContext.cpp
index 0f225c3..911ae60 100644
--- a/lib/Core/LinkingContext.cpp
+++ b/lib/Core/LinkingContext.cpp
@@ -1,9 +1,8 @@
 //===- lib/Core/LinkingContext.cpp - Linker Context Object Interface ------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/Core/Reader.cpp b/lib/Core/Reader.cpp
index 5d8bbbb..3592d87 100644
--- a/lib/Core/Reader.cpp
+++ b/lib/Core/Reader.cpp
@@ -1,9 +1,8 @@
 //===- lib/Core/Reader.cpp ------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/Core/Resolver.cpp b/lib/Core/Resolver.cpp
index 9c51c6c..7e6d95f 100644
--- a/lib/Core/Resolver.cpp
+++ b/lib/Core/Resolver.cpp
@@ -1,9 +1,8 @@
 //===- Core/Resolver.cpp - Resolves Atom References -----------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/Core/SymbolTable.cpp b/lib/Core/SymbolTable.cpp
index 51ae8d1..55cc27c 100644
--- a/lib/Core/SymbolTable.cpp
+++ b/lib/Core/SymbolTable.cpp
@@ -1,9 +1,8 @@
 //===- Core/SymbolTable.cpp - Main Symbol Table ---------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/Core/Writer.cpp b/lib/Core/Writer.cpp
index 51f95bc..12788b1 100644
--- a/lib/Core/Writer.cpp
+++ b/lib/Core/Writer.cpp
@@ -1,9 +1,8 @@
 //===- lib/Core/Writer.cpp ------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/Driver/DarwinLdDriver.cpp b/lib/Driver/DarwinLdDriver.cpp
index bbac230..f0cb513 100644
--- a/lib/Driver/DarwinLdDriver.cpp
+++ b/lib/Driver/DarwinLdDriver.cpp
@@ -1,9 +1,8 @@
 //===- lib/Driver/DarwinLdDriver.cpp --------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/lib/ReaderWriter/FileArchive.cpp b/lib/ReaderWriter/FileArchive.cpp
index 2f52d9d..b09bf34 100644
--- a/lib/ReaderWriter/FileArchive.cpp
+++ b/lib/ReaderWriter/FileArchive.cpp
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/FileArchive.cpp -----------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/ArchHandler.cpp b/lib/ReaderWriter/MachO/ArchHandler.cpp
index cb20907..c101f3b 100644
--- a/lib/ReaderWriter/MachO/ArchHandler.cpp
+++ b/lib/ReaderWriter/MachO/ArchHandler.cpp
@@ -1,9 +1,8 @@
 //===- lib/FileFormat/MachO/ArchHandler.cpp -------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/ArchHandler.h b/lib/ReaderWriter/MachO/ArchHandler.h
index 80840b5..83646c0 100644
--- a/lib/ReaderWriter/MachO/ArchHandler.h
+++ b/lib/ReaderWriter/MachO/ArchHandler.h
@@ -1,9 +1,8 @@
 //===- lib/FileFormat/MachO/ArchHandler.h ---------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/ArchHandler_arm.cpp b/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
index 2f663c6..06c98ac 100644
--- a/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
+++ b/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
@@ -1,9 +1,8 @@
 //===- lib/FileFormat/MachO/ArchHandler_arm.cpp ---------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp b/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
index b9c815c..a424edf 100644
--- a/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
+++ b/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
@@ -1,9 +1,8 @@
 //===- lib/FileFormat/MachO/ArchHandler_arm64.cpp -------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/ArchHandler_x86.cpp b/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
index a2c6809..6ea8e8c 100644
--- a/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
+++ b/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
@@ -1,9 +1,8 @@
 //===- lib/FileFormat/MachO/ArchHandler_x86.cpp ---------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp b/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
index fba3d53..316b5bb 100644
--- a/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
+++ b/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
@@ -1,9 +1,8 @@
 //===- lib/FileFormat/MachO/ArchHandler_x86_64.cpp ------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/Atoms.h b/lib/ReaderWriter/MachO/Atoms.h
index 573efca..b8bca19 100644
--- a/lib/ReaderWriter/MachO/Atoms.h
+++ b/lib/ReaderWriter/MachO/Atoms.h
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/MachO/Atoms.h ---------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/CompactUnwindPass.cpp b/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
index fa0aaa1..02eba36 100644
--- a/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
+++ b/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/MachO/CompactUnwindPass.cpp -------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/lib/ReaderWriter/MachO/DebugInfo.h b/lib/ReaderWriter/MachO/DebugInfo.h
index 28e41bf..959e10f 100644
--- a/lib/ReaderWriter/MachO/DebugInfo.h
+++ b/lib/ReaderWriter/MachO/DebugInfo.h
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/MachO/File.h ----------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/ExecutableAtoms.h b/lib/ReaderWriter/MachO/ExecutableAtoms.h
index ab14e6d..ce94be4 100644
--- a/lib/ReaderWriter/MachO/ExecutableAtoms.h
+++ b/lib/ReaderWriter/MachO/ExecutableAtoms.h
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/MachO/ExecutableAtoms.h ---------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/File.h b/lib/ReaderWriter/MachO/File.h
index 2bdd634..1cc1c41 100644
--- a/lib/ReaderWriter/MachO/File.h
+++ b/lib/ReaderWriter/MachO/File.h
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/MachO/File.h ----------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/FlatNamespaceFile.h b/lib/ReaderWriter/MachO/FlatNamespaceFile.h
index 7ccd4f1..1885eff 100644
--- a/lib/ReaderWriter/MachO/FlatNamespaceFile.h
+++ b/lib/ReaderWriter/MachO/FlatNamespaceFile.h
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/MachO/FlatNamespaceFile.h -------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/GOTPass.cpp b/lib/ReaderWriter/MachO/GOTPass.cpp
index 49e6f88..bc66d49 100644
--- a/lib/ReaderWriter/MachO/GOTPass.cpp
+++ b/lib/ReaderWriter/MachO/GOTPass.cpp
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/MachO/GOTPass.cpp -----------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/lib/ReaderWriter/MachO/LayoutPass.cpp b/lib/ReaderWriter/MachO/LayoutPass.cpp
index 9058e4f..2718dfc 100644
--- a/lib/ReaderWriter/MachO/LayoutPass.cpp
+++ b/lib/ReaderWriter/MachO/LayoutPass.cpp
@@ -1,9 +1,8 @@
 //===-- ReaderWriter/MachO/LayoutPass.cpp - Layout atoms ------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/LayoutPass.h b/lib/ReaderWriter/MachO/LayoutPass.h
index c18777e..904e16b 100644
--- a/lib/ReaderWriter/MachO/LayoutPass.h
+++ b/lib/ReaderWriter/MachO/LayoutPass.h
@@ -1,9 +1,8 @@
 //===------ lib/ReaderWriter/MachO/LayoutPass.h - Handles Layout of atoms -===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/MachOLinkingContext.cpp b/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
index 6158396..1e8630a 100644
--- a/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
+++ b/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/MachO/MachOLinkingContext.cpp ---------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/MachONormalizedFile.h b/lib/ReaderWriter/MachO/MachONormalizedFile.h
index 7eeb8ad..583c765 100644
--- a/lib/ReaderWriter/MachO/MachONormalizedFile.h
+++ b/lib/ReaderWriter/MachO/MachONormalizedFile.h
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/MachO/MachONormalizedFile.h -----------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp b/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
index 7c2e833..38b3653 100644
--- a/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
+++ b/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp ---------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h b/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h
index ee9e174..aeb04ef 100644
--- a/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h
+++ b/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h ------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp b/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
index 7ef0237..ed3dfd4 100644
--- a/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
+++ b/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp ---------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
index e93ca86..0b73484 100644
--- a/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
+++ b/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp ------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
index 473de89..879f07f 100644
--- a/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
+++ b/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp --------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp b/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
index 92a646d..7f53faa 100644
--- a/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
+++ b/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp -----------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/MachOPasses.h b/lib/ReaderWriter/MachO/MachOPasses.h
index cd01d4a..93cd3e4 100644
--- a/lib/ReaderWriter/MachO/MachOPasses.h
+++ b/lib/ReaderWriter/MachO/MachOPasses.h
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/MachO/MachOPasses.h -------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/ObjCPass.cpp b/lib/ReaderWriter/MachO/ObjCPass.cpp
index 23c71e0..df121f0 100644
--- a/lib/ReaderWriter/MachO/ObjCPass.cpp
+++ b/lib/ReaderWriter/MachO/ObjCPass.cpp
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/MachO/ObjCPass.cpp -------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/lib/ReaderWriter/MachO/SectCreateFile.h b/lib/ReaderWriter/MachO/SectCreateFile.h
index 49e65f6..7bb98e1 100644
--- a/lib/ReaderWriter/MachO/SectCreateFile.h
+++ b/lib/ReaderWriter/MachO/SectCreateFile.h
@@ -1,9 +1,8 @@
 //===---- lib/ReaderWriter/MachO/SectCreateFile.h ---------------*- c++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/MachO/ShimPass.cpp b/lib/ReaderWriter/MachO/ShimPass.cpp
index 8a2d2e9..b0775ad 100644
--- a/lib/ReaderWriter/MachO/ShimPass.cpp
+++ b/lib/ReaderWriter/MachO/ShimPass.cpp
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/MachO/ShimPass.cpp -------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/lib/ReaderWriter/MachO/StubsPass.cpp b/lib/ReaderWriter/MachO/StubsPass.cpp
index 04c586d..e8f3541 100644
--- a/lib/ReaderWriter/MachO/StubsPass.cpp
+++ b/lib/ReaderWriter/MachO/StubsPass.cpp
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/MachO/StubsPass.cpp ---------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/lib/ReaderWriter/MachO/TLVPass.cpp b/lib/ReaderWriter/MachO/TLVPass.cpp
index e362e50..89b655e 100644
--- a/lib/ReaderWriter/MachO/TLVPass.cpp
+++ b/lib/ReaderWriter/MachO/TLVPass.cpp
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/MachO/TLVPass.cpp -----------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/lib/ReaderWriter/MachO/WriterMachO.cpp b/lib/ReaderWriter/MachO/WriterMachO.cpp
index c457e7b..60e0e9d 100644
--- a/lib/ReaderWriter/MachO/WriterMachO.cpp
+++ b/lib/ReaderWriter/MachO/WriterMachO.cpp
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/MachO/WriterMachO.cpp -----------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp b/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
index 5954868..5feff2a 100644
--- a/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
+++ b/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
@@ -1,9 +1,8 @@
 //===- lib/ReaderWriter/YAML/ReaderWriterYAML.cpp -------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 1b90833..64aa1f7 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -14,7 +14,9 @@
 endif()
 
 llvm_canonicalize_cmake_booleans(
-  HAVE_LIBZ)
+  HAVE_LIBZ
+  LLVM_LIBXML2_ENABLED
+  )
 
 configure_lit_site_cfg(
   ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
diff --git a/test/COFF/arm-thumb-thunks-pdb.s b/test/COFF/arm-thumb-thunks-pdb.s
new file mode 100644
index 0000000..9e972a7
--- /dev/null
+++ b/test/COFF/arm-thumb-thunks-pdb.s
@@ -0,0 +1,18 @@
+// REQUIRES: arm
+// RUN: llvm-mc -filetype=obj -triple=thumbv7-windows %s -o %t.obj
+// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -debug -pdb:%t.pdb -verbose 2>&1 | FileCheck %s --check-prefix=VERBOSE
+
+// VERBOSE: Added 1 thunks with margin {{.*}} in {{.*}} passes
+
+    .syntax unified
+    .globl main
+    .globl func1
+    .text
+main:
+    bne func1
+    bx lr
+    .section .text$a, "xr"
+    .space 0x100000
+    .section .text$b, "xr"
+func1:
+    bx lr
diff --git a/test/COFF/arm64-branch-range.test b/test/COFF/arm64-branch-range.test
deleted file mode 100644
index 0b581e9..0000000
--- a/test/COFF/arm64-branch-range.test
+++ /dev/null
@@ -1,16 +0,0 @@
-// REQUIRES: aarch64
-
-// RUN: echo -e '.globl _start\n _start:\n bl too_far26\n' > %t.main26.s
-// RUN: echo -e '.globl _start\n _start:\n b.ne too_far19\n' > %t.main19.s
-// RUN: echo -e '.globl _start\n _start:\n tbz x0, #0, too_far14\n' > %t.main14.s
-
-// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %t.main26.s -o %t.main26.obj
-// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %t.main19.s -o %t.main19.obj
-// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %t.main14.s -o %t.main14.obj
-// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %S/Inputs/far-arm64-abs.s -o %t.far.obj
-
-// RUN: not lld-link -base:0x10000 -entry:_start -subsystem:console %t.main26.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s
-// RUN: not lld-link -base:0x10000 -entry:_start -subsystem:console %t.main19.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s
-// RUN: not lld-link -base:0x10000 -entry:_start -subsystem:console %t.main14.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s
-
-// CHECK: relocation out of range
diff --git a/test/COFF/arm64-relocs-imports.test b/test/COFF/arm64-relocs-imports.test
index e2c00f1..d9799ed 100644
--- a/test/COFF/arm64-relocs-imports.test
+++ b/test/COFF/arm64-relocs-imports.test
@@ -45,12 +45,13 @@
 # BEFORE:       90:       20 1a 09 30     adr x0, #74565
 # BEFORE:       94:       01 00 00 54     b.ne    #0
 # BEFORE:       98:       00 00 00 36     tbz     w0, #0, #0
+# BEFORE:       9c:       01 00 00 00     udf #1
 
 # AFTER: Disassembly of section .text:
 # AFTER:  140001000:      fe 0f 1f f8     str     x30, [sp, #-16]!
 # AFTER:  140001004:      00 00 00 b0     adrp    x0, #4096
 # AFTER:  140001008:      00 18 00 91     add     x0, x0, #6
-# AFTER:  14000100c:      24 00 00 94     bl      #144
+# AFTER:  14000100c:      25 00 00 94     bl      #148
 # AFTER:  140001010:      00 21 40 39     ldrb    w0, [x8, #8]
 # AFTER:  140001014:      00 11 40 79     ldrh    w0, [x8, #8]
 # AFTER:  140001018:      00 09 40 b9     ldr     w0, [x8, #8]
@@ -84,11 +85,12 @@
 # AFTER:  140001088:      00 c4 41 f9     ldr     x0, [x0, #904]
 # AFTER:  14000108c:      03 00 00 00     udf #3
 # AFTER:  140001090:      e0 95 09 30     adr     x0, #78525
-# AFTER:  140001094:      41 00 00 54     b.ne    #8
-# AFTER:  140001098:      20 00 00 36     tbz     w0, #0, #4
-# AFTER:  14000109c:      10 00 00 b0     adrp    x16, #4096
-# AFTER:  1400010a0:      10 2a 40 f9     ldr     x16, [x16, #80]
-# AFTER:  1400010a4:      00 02 1f d6     br      x16
+# AFTER:  140001094:      61 00 00 54     b.ne    #12
+# AFTER:  140001098:      40 00 00 36     tbz     w0, #0, #8
+# AFTER:  14000109c:      61 ff ff ff     <unknown>
+# AFTER:  1400010a0:      10 00 00 b0     adrp    x16, #4096
+# AFTER:  1400010a4:      10 2a 40 f9     ldr     x16, [x16, #80]
+# AFTER:  1400010a8:      00 02 1f d6     br      x16
 
 --- !COFF
 header:
@@ -98,7 +100,7 @@
   - Name:            .text
     Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
     Alignment:       4
-    SectionData:     FE0F1FF80000009000080091000000940001403900014079000140B9000140F90001003900010079000100B9000100F90001403D0001407D000140BD000140FD0001C03D0001003D0001007D000100BD000100FD0001803D000540F9201A01B000FC4FF9E0031F2AFE0741F8C0035FD6080000000000000001000000010000000000009100004091000040f901000000201a09300100005400000036
+    SectionData:     FE0F1FF80000009000080091000000940001403900014079000140B9000140F90001003900010079000100B9000100F90001403D0001407D000140BD000140FD0001C03D0001003D0001007D000100BD000100FD0001803D000540F9201A01B000FC4FF9E0031F2AFE0741F8C0035FD6080000000000000001000000010000000000009100004091000040f901000000201a0930010000540000003601000000
     Relocations:
       - VirtualAddress:  4
         SymbolName:      .Lstr
@@ -202,6 +204,9 @@
       - VirtualAddress:  152
         SymbolName:      function
         Type:            IMAGE_REL_ARM64_BRANCH14
+      - VirtualAddress:  156
+        SymbolName:      main
+        Type:            IMAGE_REL_ARM64_REL32
   - Name:            .data
     Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
     Alignment:       4
diff --git a/test/COFF/arm64-thunks.s b/test/COFF/arm64-thunks.s
new file mode 100644
index 0000000..4900454
--- /dev/null
+++ b/test/COFF/arm64-thunks.s
@@ -0,0 +1,27 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %s -o %t.obj
+// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s
+// RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s
+
+// VERBOSE: Added 1 thunks with margin {{.*}} in 1 passes
+
+    .globl main
+    .globl func1
+    .text
+main:
+    tbz w0, #0, func1
+    ret
+    .section .text$a, "xr"
+    .space 0x8000
+    .section .text$b, "xr"
+func1:
+    ret
+
+// DISASM: 0000000140001000 .text:
+// DISASM: 140001000:      40 00 00 36     tbz     w0, #0, #8 <.text+0x8>
+// DISASM: 140001004:      c0 03 5f d6     ret
+// DISASM: 140001008:      50 00 00 90     adrp    x16, #32768
+// DISASM: 14000100c:      10 52 00 91     add     x16, x16, #20
+// DISASM: 140001010:      00 02 1f d6     br      x16
+
+// DISASM: 140009014:      c0 03 5f d6     ret
diff --git a/test/COFF/armnt-rel32.yaml b/test/COFF/armnt-rel32.yaml
new file mode 100644
index 0000000..fa385c5
--- /dev/null
+++ b/test/COFF/armnt-rel32.yaml
@@ -0,0 +1,47 @@
+# REQUIRES: arm
+
+# RUN: yaml2obj < %s > %t.obj
+# RUN: llvm-objdump -s %t.obj | FileCheck %s -check-prefix BEFORE
+# RUN: lld-link /entry:function /subsystem:console /out:%t.exe %t.obj
+# RUN: llvm-objdump -s %t.exe | FileCheck %s -check-prefix AFTER
+
+# BEFORE: Contents of section .text:
+# BEFORE:    0000 704700bf 01000000 01000000
+
+# AFTER: Contents of section .text:
+# AFTER:   401000 704700bf faffffff f50f0000
+
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_ARMNT
+  Characteristics: []
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     704700BF0100000001000000
+    Relocations:
+      - VirtualAddress:  4
+        SymbolName:      function
+        Type:            IMAGE_REL_ARM_REL32
+      - VirtualAddress:  8
+        SymbolName:      data
+        Type:            IMAGE_REL_ARM_REL32
+  - Name:            .rdata
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    SectionData:     00
+symbols:
+  - Name:            function
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            data
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/test/COFF/associative-comdat-empty.test b/test/COFF/associative-comdat-empty.test
new file mode 100644
index 0000000..c4ee8b7
--- /dev/null
+++ b/test/COFF/associative-comdat-empty.test
@@ -0,0 +1,56 @@
+# RUN: yaml2obj < %s > %t.obj
+# RUN: not lld-link /include:symbol /dll /noentry /nodefaultlib %t.obj /out:%t.exe 2>&1 | FileCheck %s
+
+# Tests an associative comdat being associated with an empty section errors.
+# CHECK: lld-link: error: {{.*}}: associative comdat .text$ac1 (sec 1) has invalid reference to section .text$nm (sec 2)
+# CHECK-NOT: lld-link: error:
+
+--- !COFF
+header:          
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [  ]
+sections:        
+  - Name:            '.text$ac1'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       1
+    SectionData:     '01000000'
+  - Name:            '.text$nm'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       1
+    SectionData:     '01000000'
+symbols:         
+  - Name:            '.text$ac1'
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition: 
+      Length:          4
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        3099354981
+      Number:          2
+      Selection:       IMAGE_COMDAT_SELECT_ASSOCIATIVE
+  - Name:            '.text$nm'
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition: 
+      Length:          0
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        3099354981
+      Number:          4
+      Selection:       IMAGE_COMDAT_SELECT_ANY
+  - Name:            assocsym
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+...
+
+
diff --git a/test/COFF/associative-comdat-order.test b/test/COFF/associative-comdat-order.test
new file mode 100644
index 0000000..c7756f3
--- /dev/null
+++ b/test/COFF/associative-comdat-order.test
@@ -0,0 +1,97 @@
+# Tests that an associative comdat being associated with another
+# associated comdat later in the file produces an error.
+# RUN: sed -e s/ASSOC1/2/ -e s/ASSOC2/3/ %s | yaml2obj > %t.obj
+# RUN: not lld-link /include:symbol /dll /noentry /nodefaultlib %t.obj /out:%t.exe 2>&1 | FileCheck --check-prefix=FORWARD %s
+# FORWARD: lld-link: error: {{.*}}: associative comdat .text$ac1 (sec 1) has invalid reference to section .text$ac2 (sec 2)
+# FORWARD-NOT: lld-link: error:
+
+# Tests that an associative comdat being associated with another
+# associated comdat earlier in the file works.
+# RUN: sed -e s/ASSOC1/3/ -e s/ASSOC2/1/ %s | yaml2obj > %t.obj
+
+# RUN: lld-link /include:symbol /dll /noentry /nodefaultlib %t.obj /out:%t.exe
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=BACKWARD %s
+# BACKWARD: Contents of section .text:
+# BACKWARD:   180001000 01000000 02000000 03000000 ............
+
+# RUN: lld-link /dll /noentry /nodefaultlib %t.obj /out:%t.exe
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=BACKWARDDROP %s
+# BACKWARDDROP-NOT: Contents of section .text:
+
+--- !COFF
+header:          
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [  ]
+sections:        
+  - Name:            '.text$ac1'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       1
+    SectionData:     '01000000'
+  - Name:            '.text$ac2'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       1
+    SectionData:     '02000000'
+  - Name:            '.text$nm'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       1
+    SectionData:     '03000000'
+symbols:         
+  - Name:            '.text$ac1'
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition: 
+      Length:          4
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        3099354981
+      Number:          ASSOC1
+      Selection:       IMAGE_COMDAT_SELECT_ASSOCIATIVE
+  - Name:            '.text$ac2'
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition: 
+      Length:          4
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        3099354981
+      Number:          ASSOC2
+      Selection:       IMAGE_COMDAT_SELECT_ASSOCIATIVE
+  - Name:            '.text$nm'
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition: 
+      Length:          4
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        3099354981
+      Number:          4
+      Selection:       IMAGE_COMDAT_SELECT_ANY
+  - Name:            symbol
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            assocsym2
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            assocsym
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+...
+
diff --git a/test/COFF/color-diagnostics.test b/test/COFF/color-diagnostics.test
new file mode 100644
index 0000000..a231f1f
--- /dev/null
+++ b/test/COFF/color-diagnostics.test
@@ -0,0 +1,18 @@
+# Windows command prompt doesn't support ANSI escape sequences.
+# REQUIRES: shell
+
+# RUN: not lld-link -xyz --color-diagnostics /nosuchfile 2>&1 \
+# RUN:   | FileCheck -check-prefix=COLOR %s
+# RUN: not lld-link -xyz --color-diagnostics=always /nosuchfile 2>&1 \
+# RUN:   | FileCheck -check-prefix=COLOR %s
+
+# COLOR: {{lld-link: .\[0;1;35mwarning: .\[0mignoring unknown argument: -xyz}}
+# COLOR: {{lld-link: .\[0;1;31merror: .\[0mcould not open /nosuchfile}}
+
+# RUN: not lld-link /nosuchfile 2>&1 | FileCheck -check-prefix=NOCOLOR %s
+# RUN: not lld-link -color-diagnostics=never /nosuchfile 2>&1 \
+# RUN:   | FileCheck -check-prefix=NOCOLOR %s
+# RUN: not lld-link -color-diagnostics=always -no-color-diagnostics \
+# RUN:   /nosuchfile 2>&1 | FileCheck -check-prefix=NOCOLOR %s
+
+# NOCOLOR: lld-link: error: could not open /nosuchfile
diff --git a/test/COFF/comdat-selection-associative-largest.s b/test/COFF/comdat-selection-associative-largest.s
new file mode 100644
index 0000000..301aaec
--- /dev/null
+++ b/test/COFF/comdat-selection-associative-largest.s
@@ -0,0 +1,45 @@
+# REQUIRES: x86
+
+# Tests handling of several comdats with "largest" selection type that each
+# has an associative comdat.
+
+# Create obj files.
+# RUN: sed -e s/TYPE/.byte/  -e s/SIZE/1/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.1.obj
+# RUN: sed -e s/TYPE/.short/ -e s/SIZE/2/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.2.obj
+# RUN: sed -e s/TYPE/.long/  -e s/SIZE/4/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.4.obj
+
+        .section .text$ac, "", associative, symbol
+assocsym:
+        .long SIZE
+
+        .section .text$nm, "", largest, symbol
+        .globl symbol
+symbol:
+        TYPE SIZE
+
+# Pass the obj files in different orders and check that only the associative
+# comdat of the largest obj file makes it into the output, independent of
+# the order of the obj files on the command line.
+
+# FIXME: Make these pass when /opt:noref is passed.
+
+# RUN: lld-link /include:symbol /dll /noentry /nodefaultlib %t.1.obj %t.2.obj %t.4.obj /out:%t.exe
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=ALL124 %s
+# ALL124: Contents of section .text:
+# ALL124:   180001000 04000000 04000000 ....
+
+# RUN: lld-link /include:symbol /dll /noentry /nodefaultlib %t.4.obj %t.2.obj %t.1.obj /out:%t.exe
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=ALL421 %s
+# ALL421: Contents of section .text:
+# ALL421:   180001000 04000000 04000000 ....
+
+# RUN: lld-link /include:symbol /dll /noentry /nodefaultlib %t.2.obj %t.4.obj %t.1.obj /out:%t.exe
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=ALL241 %s
+# ALL241: Contents of section .text:
+# ALL241:   180001000 04000000 04000000 ....
+
+# RUN: lld-link /include:symbol /dll /noentry /nodefaultlib %t.2.obj %t.1.obj /out:%t.exe
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=JUST21 %s
+# JUST21: Contents of section .text:
+# JUST21:   180001000 02000000 0200 ....
+
diff --git a/test/COFF/comdat-selection.s b/test/COFF/comdat-selection.s
new file mode 100644
index 0000000..4926173
--- /dev/null
+++ b/test/COFF/comdat-selection.s
@@ -0,0 +1,98 @@
+# REQUIRES: x86
+
+# Tests handling of the comdat selection type.
+# (Except associative which is tested in associative-comdat.s and
+# comdat-selection-associate-largest.s instead.)
+
+# Create obj files with each selection type.
+# RUN: sed -e s/SEL/discard/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.discard.obj
+# RUN: sed -e s/SEL/discard/ -e s/.long/.short/ -e s/1/2/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.discard.short.2.obj
+# RUN: sed -e s/SEL/one_only/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.one_only.obj
+# RUN: sed -e s/SEL/same_size/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.same_size.obj
+# RUN: sed -e s/SEL/same_size/ -e s/.long/.short/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.same_size.short.obj
+# RUN: sed -e s/SEL/same_contents/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.same_contents.obj
+# RUN: sed -e s/SEL/same_contents/ -e s/.long/.short/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.same_contents.short.obj
+# RUN: sed -e s/SEL/same_contents/ -e s/1/2/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.same_contents.2.obj
+# RUN: sed -e s/SEL/largest/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.largest.obj
+# RUN: sed -e s/SEL/largest/ -e s/.long/.short/ -e s/1/2/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.largest.short.2.obj
+# RUN: sed -e s/SEL/newest/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.newest.obj
+
+        .section .text$nm, "", SEL, symbol
+        .globl symbol
+symbol:
+        .long 1
+
+# First, pass each selection type twice. All should link fine except for
+# one_only which should report a duplicate symbol error and newest which
+# link.exe (and hence lld-link) doesn't understand.
+
+# RUN: cp %t.discard.obj %t.obj && lld-link /dll /noentry /nodefaultlib %t.discard.obj %t.obj
+# RUN: cp %t.one_only.obj %t.obj && not lld-link /dll /noentry /nodefaultlib %t.one_only.obj %t.obj 2>&1 | FileCheck --check-prefix=ONEONE %s
+# ONEONE: lld-link: error: duplicate symbol: symbol
+# RUN: cp %t.same_size.obj %t.obj && lld-link /dll /noentry /nodefaultlib %t.same_size.obj %t.obj
+# RUN: cp %t.same_contents.obj %t.obj && lld-link /dll /noentry /nodefaultlib %t.same_contents.obj %t.obj
+# RUN: cp %t.largest.obj %t.obj && lld-link /dll /noentry /nodefaultlib %t.largest.obj %t.obj
+# RUN: cp %t.newest.obj %t.obj && not lld-link /dll /noentry /nodefaultlib %t.newest.obj %t.obj 2>&1 | FileCheck --check-prefix=NEWNEW %s
+# NEWNEW: lld-link: error: unknown comdat type 7 for symbol
+
+# /force doesn't affect errors about unknown comdat types.
+# RUN: cp %t.newest.obj %t.obj && not lld-link /force /dll /noentry /nodefaultlib %t.newest.obj %t.obj 2>&1 | FileCheck --check-prefix=NEWNEWFORCE %s
+# NEWNEWFORCE: lld-link: error: unknown comdat type 7 for symbol
+
+# Check that same_size, same_contents, largest do what they're supposed to.
+
+# Check that the "same_size" selection produces an error if passed two symbols
+# with different size.
+# RUN: not lld-link /dll /noentry /nodefaultlib %t.same_size.obj %t.same_size.short.obj 2>&1 | FileCheck --check-prefix=SAMESIZEDUPE %s
+# SAMESIZEDUPE: lld-link: error: duplicate symbol: symbol
+
+# Check that the "same_contents" selection produces an error if passed two
+# symbols with different contents.
+# RUN: not lld-link /dll /noentry /nodefaultlib %t.same_contents.obj %t.same_contents.2.obj 2>&1 | FileCheck --check-prefix=SAMECONTENTSDUPE1 %s
+# SAMECONTENTSDUPE1: lld-link: error: duplicate symbol: symbol
+# RUN: not lld-link /dll /noentry /nodefaultlib %t.same_contents.obj %t.same_contents.2.obj 2>&1 | FileCheck --check-prefix=SAMECONTENTSDUPE2 %s
+# SAMECONTENTSDUPE2: lld-link: error: duplicate symbol: symbol
+
+# Check that the "largest" selection picks the larger comdat (independent of
+# the order the .obj files are passed on the commandline).
+# RUN: lld-link /opt:noref /include:symbol /dll /noentry /nodefaultlib %t.largest.obj %t.largest.short.2.obj /out:%t.exe
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=LARGEST1 %s
+# LARGEST1: Contents of section .text:
+# LARGEST1:   180001000 01000000 ....
+
+# FIXME: Make this pass when /opt:noref is passed.
+# RUN: lld-link /include:symbol /dll /noentry /nodefaultlib %t.largest.short.2.obj %t.largest.obj /out:%t.exe
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=LARGEST2 %s
+# LARGEST2: Contents of section .text:
+# LARGEST2:   180001000 01000000 ....
+
+
+# Test linking the same symbol with different comdat selection types.
+# link.exe generally rejects this, except for "largest" which is allowed to
+# combine with everything (https://bugs.llvm.org/show_bug.cgi?id=40094#c7).
+# lld-link rejects all comdat selection type mismatches. Spot-test just a few
+# combinations.
+
+# RUN: not lld-link /dll /noentry /nodefaultlib %t.discard.obj %t.one_only.obj 2>&1 | FileCheck --check-prefix=DISCARDONE %s
+# DISCARDONE: lld-link: error: conflicting comdat type for symbol: 2 in
+# RUN: lld-link /force /dll /noentry /nodefaultlib %t.discard.obj %t.one_only.obj 2>&1 | FileCheck --check-prefix=DISCARDONEFORCE %s
+# DISCARDONEFORCE: lld-link: warning: conflicting comdat type for symbol: 2 in
+
+# RUN: not lld-link /dll /noentry /nodefaultlib %t.same_contents.obj %t.same_size.obj 2>&1 | FileCheck --check-prefix=CONTENTSSIZE %s
+# CONTENTSSIZE: lld-link: error: conflicting comdat type for symbol: 4 in
+
+# Check that linking one 'discard' and one 'largest' has the effect of
+# 'largest'.
+# RUN: lld-link /dll /noentry /nodefaultlib %t.discard.short.2.obj %t.largest.obj
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=DISCARDLARGEST %s
+# DISCARDLARGEST: Contents of section .text:
+# DISCARDLARGEST:   180001000 01000000 ....
+# RUN: lld-link /dll /noentry /nodefaultlib %t.largest.obj %t.discard.short.2.obj
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=LARGESTDISCARD %s
+# LARGESTDISCARD: Contents of section .text:
+# LARGESTDISCARD:   180001000 01000000 ....
+
+
+# These cases are accepted by link.exe but not by lld-link.
+# RUN: not lld-link /dll /noentry /nodefaultlib %t.largest.obj %t.one_only.obj 2>&1 | FileCheck --check-prefix=LARGESTONE %s
+# LARGESTONE: lld-link: error: conflicting comdat type for symbol: 6 in
diff --git a/test/COFF/crt-dyn-initializer-order.test b/test/COFF/crt-dyn-initializer-order.test
index 963b065..40f2e0c 100644
--- a/test/COFF/crt-dyn-initializer-order.test
+++ b/test/COFF/crt-dyn-initializer-order.test
@@ -1,100 +1,100 @@
-# // a.cpp

-# #include <iostream>

-# #include <vector>

-# 

-# template <int Magic> struct TemplatedObject {

-#   static std::vector<TemplatedObject<Magic> *> Instances;

-#   TemplatedObject() { Instances.push_back(this); }

-# };

-# 

-# using Object = TemplatedObject<0>;

-# template <> std::vector<Object *> Object::Instances{};

-# Object idle{};

-# 

-# int main() {

-#   if (Object::Instances.size() == 0)

-#     std::cout << "It's broken" << std::endl;

-#   else

-#     std::cout << "It works!" << std::endl;

-#   return 0;

-# }

-# // using `clang-cl /c a.cpp | lld-link a.obj` works

-# // using `cl /c a.cpp | lld-link a.obj` fails without lld/COFF/Writer.cpp/Writer::sortSectionChunks()

-

-# RUN: yaml2obj %s > %t.obj

-# RUN: yaml2obj %S/Inputs/crt-dyn-initializer-order_1.yaml > %t1.obj

-# RUN: yaml2obj %S/Inputs/crt-dyn-initializer-order_2.yaml > %t2.obj

-

-# CHECK: Name: .CRT

-# CHECK: Characteristics [

-# CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA

-# CHECK-NEXT: IMAGE_SCN_MEM_READ

-# CHECK-NEXT: ]

-# CHECK-NEXT: SectionData (

-

-# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj %t1.obj %t2.obj 

-# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE1

-# CASE1-NEXT: 01020304 55701011 1205

-

-# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj %t2.obj %t1.obj 

-# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE2

-# CASE2-NEXT: 01020304 10111255 7005

-

-# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t1.obj %t2.obj %t.obj 

-# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE3

-# CASE3-NEXT: 01557010 11120203 0405

-

-# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t1.obj %t.obj %t2.obj 

-# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE4

-# CASE4-NEXT: 01557002 03041011 1205

-

-# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t2.obj %t1.obj %t.obj 

-# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE5

-# CASE5-NEXT: 01101112 55700203 0405

-

-# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t2.obj %t.obj %t1.obj

-# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE6

-# CASE6-NEXT: 01101112 02030455 7005

-

-# CHECK-NEXT: )

-

---- !COFF

-header:

-  Machine:         IMAGE_FILE_MACHINE_AMD64

-  Characteristics: [  ]

-sections:

-  - Name:            '.CRT$XCA'

-    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]

-    Alignment:       1

-    SectionData:     01

-  - Name:            '.CRT$XCU'

-    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]

-    Alignment:       1

-    SectionData:     02

-  - Name:            '.CRT$XCU'

-    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_LNK_COMDAT ]

-    Alignment:       1

-    SectionData:     03

-  - Name:            '.CRT$XCU'

-    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]

-    Alignment:       1

-    SectionData:     04

-  - Name:            '.CRT$XCZ'

-    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]

-    Alignment:       1

-    SectionData:     05

-symbols:

-  - Name:            '.CRT$XCU'

-    Value:           0

-    SectionNumber:   3

-    SimpleType:      IMAGE_SYM_TYPE_NULL

-    ComplexType:     IMAGE_SYM_DTYPE_NULL

-    StorageClass:    IMAGE_SYM_CLASS_STATIC

-    SectionDefinition:

-      Length:          1

-      NumberOfRelocations: 0

-      NumberOfLinenumbers: 0

-      CheckSum:        1

-      Number:          2

-      Selection:       IMAGE_COMDAT_SELECT_ASSOCIATIVE

-...

+# // a.cpp
+# #include <iostream>
+# #include <vector>
+#
+# template <int Magic> struct TemplatedObject {
+#   static std::vector<TemplatedObject<Magic> *> Instances;
+#   TemplatedObject() { Instances.push_back(this); }
+# };
+#
+# using Object = TemplatedObject<0>;
+# template <> std::vector<Object *> Object::Instances{};
+# Object idle{};
+#
+# int main() {
+#   if (Object::Instances.size() == 0)
+#     std::cout << "It's broken" << std::endl;
+#   else
+#     std::cout << "It works!" << std::endl;
+#   return 0;
+# }
+# // using `clang-cl /c a.cpp | lld-link a.obj` works
+# // using `cl /c a.cpp | lld-link a.obj` fails without lld/COFF/Writer.cpp/Writer::sortSectionChunks()
+
+# RUN: yaml2obj %s > %t.obj
+# RUN: yaml2obj %S/Inputs/crt-dyn-initializer-order_1.yaml > %t1.obj
+# RUN: yaml2obj %S/Inputs/crt-dyn-initializer-order_2.yaml > %t2.obj
+
+# CHECK: Name: .CRT
+# CHECK: Characteristics [
+# CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
+# CHECK-NEXT: IMAGE_SCN_MEM_READ
+# CHECK-NEXT: ]
+# CHECK-NEXT: SectionData (
+
+# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj %t1.obj %t2.obj
+# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE1
+# CASE1-NEXT: 01020304 55701011 1205
+
+# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj %t2.obj %t1.obj
+# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE2
+# CASE2-NEXT: 01020304 10111255 7005
+
+# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t1.obj %t2.obj %t.obj
+# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE3
+# CASE3-NEXT: 01557010 11120203 0405
+
+# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t1.obj %t.obj %t2.obj
+# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE4
+# CASE4-NEXT: 01557002 03041011 1205
+
+# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t2.obj %t1.obj %t.obj
+# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE5
+# CASE5-NEXT: 01101112 55700203 0405
+
+# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t2.obj %t.obj %t1.obj
+# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE6
+# CASE6-NEXT: 01101112 02030455 7005
+
+# CHECK-NEXT: )
+
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [  ]
+sections:
+  - Name:            '.CRT$XCA'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    SectionData:     01
+  - Name:            '.CRT$XCU'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    SectionData:     02
+  - Name:            '.CRT$XCU'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_LNK_COMDAT ]
+    Alignment:       1
+    SectionData:     03
+  - Name:            '.CRT$XCU'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    SectionData:     04
+  - Name:            '.CRT$XCZ'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    SectionData:     05
+symbols:
+  - Name:            '.CRT$XCU'
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          1
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        1
+      Number:          2
+      Selection:       IMAGE_COMDAT_SELECT_ASSOCIATIVE
+...
diff --git a/test/COFF/ignore-many.test b/test/COFF/ignore-many.test
new file mode 100644
index 0000000..3139810
--- /dev/null
+++ b/test/COFF/ignore-many.test
@@ -0,0 +1,16 @@
+Tests /ignore with more than one argument.
+
+RUN: yaml2obj %S/ignore4217.yaml > %t1.obj
+RUN: yaml2obj %S/Inputs/pdb-type-server-missing-2.yaml > %t2.obj
+RUN: echo foo > %t3.order
+
+RUN: lld-link /entry:main /out:%t.exe %t1.obj %t2.obj /order:@%t3.order /debug 2>&1 | FileCheck -check-prefix=WARNINGS %s
+RUN: lld-link /entry:main /out:%t.exe %t1.obj %t2.obj /order:@%t3.order /debug /ignore:4217,4099,4037 2>&1 | FileCheck -allow-empty -check-prefix=SUPPRESSED %s
+
+WARNINGS: locally defined symbol imported
+WARNINGS: missing symbol: foo
+WARNINGS: warning: Cannot use debug info for
+
+SUPPRESSED-NOT: locally defined symbol imported
+SUPPRESSED-NOT: missing symbol: foo
+SUPPRESSED-NOT: warning: Cannot use debug info for
diff --git a/test/COFF/imports.test b/test/COFF/imports.test
index 64f3900..f54bdfd 100644
--- a/test/COFF/imports.test
+++ b/test/COFF/imports.test
@@ -34,3 +34,16 @@
 IMPORT-NEXT:   Symbol:  (50)
 IMPORT-NEXT:   Symbol: MessageBoxA (1)
 IMPORT-NEXT: }
+
+# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /merge:.rdata=.text \
+# RUN:   %p/Inputs/hello64.obj %p/Inputs/std64.lib /include:ExitProcess
+# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=MERGE %s
+
+MERGE:      Import {
+MERGE-NEXT:   Name: std64.dll
+MERGE-NEXT:   ImportLookupTableRVA: 0x1090
+MERGE-NEXT:   ImportAddressTableRVA: 0x10B0
+MERGE-NEXT:   Symbol: ExitProcess (0)
+MERGE-NEXT:   Symbol:  (50)
+MERGE-NEXT:   Symbol: MessageBoxA (1)
+MERGE-NEXT: }
diff --git a/test/COFF/line-error.yaml b/test/COFF/line-error.yaml
new file mode 100644
index 0000000..55fb723
--- /dev/null
+++ b/test/COFF/line-error.yaml
@@ -0,0 +1,160 @@
+# RUN: yaml2obj %s -o %t.obj

+# RUN: not lld-link %t.obj /subsystem:console 2>&1 | FileCheck %s

+

+# CHECK: lld-link: error: undefined symbol: function

+# CHECK-NEXT: >>> referenced by {{.*}}line-error.yaml.tmp.obj:(caller1)

+# CHECK-NEXT: >>> referenced by E:\file.cpp:1935

+# CHECK-NEXT: >>>               {{.*}}line-error.yaml.tmp.obj:(caller22)

+

+--- !COFF

+header:          

+  Machine:         IMAGE_FILE_MACHINE_AMD64

+  Characteristics: [  ]

+sections:        

+  - Name:            .text

+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]

+    Alignment:       16

+    SectionData:     488B0500000000488B51284881C2D80000004889C148FF2500000000

+    Relocations:     

+      - VirtualAddress:  3

+        SymbolName:      function

+        Type:            IMAGE_REL_AMD64_REL32

+  - Name:            .text

+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]

+    Alignment:       16

+    SectionData:     488B0500000000488B51084881C2D80000004889C148FF2500000000

+    Relocations:     

+      - VirtualAddress:  3

+        SymbolName:      function

+        Type:            IMAGE_REL_AMD64_REL32

+  - Name:            '.debug$S'

+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]

+    Alignment:       4

+    Subsections:     

+      - !FileChecksums

+        Checksums:       

+          - FileName:        'E:\file.cpp'

+            Kind:            MD5

+            Checksum:        D72EDEF8B8E50C364A330F9CB3CD904B

+      - !StringTable

+        Strings:         

+          - 'E:\file.cpp'

+  - Name:            '.debug$S'

+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]

+    Alignment:       4

+    Subsections:     

+      - !Lines

+        CodeSize:        28

+        Flags:           [  ]

+        RelocOffset:     0

+        RelocSegment:    0

+        Blocks:          []

+    Relocations:     

+      - VirtualAddress:  12

+        SymbolName:      caller1

+        Type:            IMAGE_REL_AMD64_SECREL

+  - Name:            '.debug$S'

+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]

+    Alignment:       4

+    Subsections:     

+      - !Lines

+        CodeSize:        28

+        Flags:           [  ]

+        RelocOffset:     0

+        RelocSegment:    0

+        Blocks:          

+          - FileName:        'E:\file.cpp'

+            Lines:           

+              - Offset:          11

+                LineStart:       1935

+                IsStatement:     false

+                EndDelta:        0

+            Columns:         []

+    Relocations:     

+      - VirtualAddress:  12

+        SymbolName:      caller22

+        Type:            IMAGE_REL_AMD64_SECREL

+symbols:

+  - Name:            .text

+    Value:           0

+    SectionNumber:   1

+    SimpleType:      IMAGE_SYM_TYPE_NULL

+    ComplexType:     IMAGE_SYM_DTYPE_NULL

+    StorageClass:    IMAGE_SYM_CLASS_STATIC

+    SectionDefinition: 

+      Length:          28

+      NumberOfRelocations: 2

+      NumberOfLinenumbers: 0

+      CheckSum:        2430089736

+      Number:          1

+      Selection:       IMAGE_COMDAT_SELECT_NODUPLICATES

+  - Name:            caller1

+    Value:           0

+    SectionNumber:   1

+    SimpleType:      IMAGE_SYM_TYPE_NULL

+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION

+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL    

+  - Name:            .text

+    Value:           0

+    SectionNumber:   2

+    SimpleType:      IMAGE_SYM_TYPE_NULL

+    ComplexType:     IMAGE_SYM_DTYPE_NULL

+    StorageClass:    IMAGE_SYM_CLASS_STATIC

+    SectionDefinition: 

+      Length:          28

+      NumberOfRelocations: 2

+      NumberOfLinenumbers: 0

+      CheckSum:        3449717304

+      Number:          2

+      Selection:       IMAGE_COMDAT_SELECT_NODUPLICATES

+  - Name:            caller22

+    Value:           0

+    SectionNumber:   2

+    SimpleType:      IMAGE_SYM_TYPE_NULL

+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION

+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL    

+  - Name:            '.debug$S'

+    Value:           0

+    SectionNumber:   3

+    SimpleType:      IMAGE_SYM_TYPE_NULL

+    ComplexType:     IMAGE_SYM_DTYPE_NULL

+    StorageClass:    IMAGE_SYM_CLASS_STATIC

+    SectionDefinition: 

+      Length:          767204

+      NumberOfRelocations: 0

+      NumberOfLinenumbers: 0

+      CheckSum:        4280093374

+      Number:          3

+  - Name:            '.debug$S'

+    Value:           0

+    SectionNumber:   4

+    SimpleType:      IMAGE_SYM_TYPE_NULL

+    ComplexType:     IMAGE_SYM_DTYPE_NULL

+    StorageClass:    IMAGE_SYM_CLASS_STATIC

+    SectionDefinition: 

+      Length:          296

+      NumberOfRelocations: 1

+      NumberOfLinenumbers: 0

+      CheckSum:        1957793731

+      Number:          1

+      Selection:       IMAGE_COMDAT_SELECT_ASSOCIATIVE

+  - Name:            '.debug$S'

+    Value:           0

+    SectionNumber:   5

+    SimpleType:      IMAGE_SYM_TYPE_NULL

+    ComplexType:     IMAGE_SYM_DTYPE_NULL

+    StorageClass:    IMAGE_SYM_CLASS_STATIC

+    SectionDefinition: 

+      Length:          276

+      NumberOfRelocations: 1

+      NumberOfLinenumbers: 0

+      CheckSum:        1957793731

+      Number:          2

+      Selection:       IMAGE_COMDAT_SELECT_ASSOCIATIVE

+  - Name:            function

+    Value:           0

+    SectionNumber:   0

+    SimpleType:      IMAGE_SYM_TYPE_NULL

+    ComplexType:     IMAGE_SYM_DTYPE_NULL

+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL

+...

diff --git a/test/COFF/lto-lazy-reference.ll b/test/COFF/lto-lazy-reference.ll
index 1e92873..428a7b8 100644
--- a/test/COFF/lto-lazy-reference.ll
+++ b/test/COFF/lto-lazy-reference.ll
@@ -9,6 +9,10 @@
 target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
 target triple = "i686-pc-windows-msvc18.0.0"
 
+; Define fltused, since we don't link against the MS C runtime but are
+; using floats.
+@_fltused = dllexport global i32 0, align 4
+
 define double @main(double %x) {
 entry:
   ; When compiled, this defines the __real@40800000 symbol, which already has a
diff --git a/test/COFF/lto-new-symbol.ll b/test/COFF/lto-new-symbol.ll
index 5223f73..dadd495 100644
--- a/test/COFF/lto-new-symbol.ll
+++ b/test/COFF/lto-new-symbol.ll
@@ -5,6 +5,10 @@
 target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-pc-windows-msvc"
 
+; Define fltused, since we don't link against the MS C runtime but are
+; using floats.
+@_fltused = dllexport global i32 0, align 4
+
 define void @foo(<4 x i32>* %p, <4 x float>* %q, i1 %t) nounwind {
 entry:
   br label %loop
diff --git a/test/COFF/pdb-relative-source-lines.test b/test/COFF/pdb-relative-source-lines.test
index 865d7a6..5470567 100644
--- a/test/COFF/pdb-relative-source-lines.test
+++ b/test/COFF/pdb-relative-source-lines.test
@@ -37,26 +37,26 @@
 RUN: ./lld-link -debug "-pdbsourcepath:/usr/src" -entry:main -nodefaultlib -out:out.exe -pdb:out.pdb pdb_lines_1_relative.obj pdb_lines_2_relative.obj
 RUN: llvm-pdbutil pdb2yaml -modules -module-files -module-syms -subsections=lines,fc %t/out.pdb | FileCheck --check-prefix=POSIX %s
 
-CHECK-LABEL:  - Module:          'c:\src{{[\\/]}}pdb_lines_1_relative.obj'
-CHECK-NEXT:     ObjFile:         'c:\src{{[\\/]}}pdb_lines_1_relative.obj'
+CHECK-LABEL:  - Module:          'c:\src\pdb_lines_1_relative.obj'
+CHECK-NEXT:     ObjFile:         'c:\src\pdb_lines_1_relative.obj'
 CHECK:          SourceFiles:
-CHECK-NEXT:       - 'c:\src{{[\\/]}}pdb_lines_1.c'
-CHECK-NEXT:       - 'c:\src{{[\\/]}}foo.h'
+CHECK-NEXT:       - 'c:\src\pdb_lines_1.c'
+CHECK-NEXT:       - 'c:\src\foo.h'
 CHECK:          Subsections:
-CHECK:                - FileName:        'c:\src{{[\\/]}}pdb_lines_1.c'
-CHECK:                - FileName:        'c:\src{{[\\/]}}foo.h'
+CHECK:                - FileName:        'c:\src\pdb_lines_1.c'
+CHECK:                - FileName:        'c:\src\foo.h'
 CHECK:            - !FileChecksums
-CHECK:                - FileName:        'c:\src{{[\\/]}}pdb_lines_1.c'
-CHECK:                - FileName:        'c:\src{{[\\/]}}foo.h'
+CHECK:                - FileName:        'c:\src\pdb_lines_1.c'
+CHECK:                - FileName:        'c:\src\foo.h'
 
-CHECK-LABEL:  - Module:          'c:\src{{[\\/]}}pdb_lines_2_relative.obj'
-CHECK-NEXT:     ObjFile:         'c:\src{{[\\/]}}pdb_lines_2_relative.obj'
+CHECK-LABEL:  - Module:          'c:\src\pdb_lines_2_relative.obj'
+CHECK-NEXT:     ObjFile:         'c:\src\pdb_lines_2_relative.obj'
 CHECK:          SourceFiles:
-CHECK-NEXT:       - 'c:\src{{[\\/]}}pdb_lines_2.c'
+CHECK-NEXT:       - 'c:\src\pdb_lines_2.c'
 CHECK:          Subsections:
-CHECK:                - FileName:        'c:\src{{[\\/]}}pdb_lines_2.c'
+CHECK:                - FileName:        'c:\src\pdb_lines_2.c'
 CHECK:            - !FileChecksums
-CHECK:                - FileName:        'c:\src{{[\\/]}}pdb_lines_2.c'
+CHECK:                - FileName:        'c:\src\pdb_lines_2.c'
 
 CHECK-LABEL:  - Kind:            S_ENVBLOCK
 CHECK-NEXT:     EnvBlockSym:     
@@ -64,33 +64,33 @@
 CHECK-NEXT:         - cwd
 CHECK-NEXT:         - 'c:\src'
 CHECK-NEXT:         - exe
-CHECK-NEXT:         - 'c:\src{{[\\/]}}lld-link'
+CHECK-NEXT:         - 'c:\src\lld-link'
 CHECK-NEXT:         - pdb 
-CHECK-NEXT:         - 'c:\src{{[\\/]}}out.pdb'
+CHECK-NEXT:         - 'c:\src\out.pdb'
 CHECK-NEXT:         - cmd
 CHECK-NEXT:         - '-debug -pdbsourcepath:c:\src -entry:main -nodefaultlib -out:out.exe -pdb:out.pdb pdb_lines_1_relative.obj pdb_lines_2_relative.obj'
 
 
-POSIX-LABEL:  - Module:          '/usr/src{{[\\/]}}pdb_lines_1_relative.obj'
-POSIX-NEXT:     ObjFile:         '/usr/src{{[\\/]}}pdb_lines_1_relative.obj'
+POSIX-LABEL:  - Module:          '/usr/src/pdb_lines_1_relative.obj'
+POSIX-NEXT:     ObjFile:         '/usr/src/pdb_lines_1_relative.obj'
 POSIX:          SourceFiles:
-POSIX-NEXT:       - '/usr/src{{[\\/]}}pdb_lines_1.c'
-POSIX-NEXT:       - '/usr/src{{[\\/]}}foo.h'
+POSIX-NEXT:       - '/usr/src/pdb_lines_1.c'
+POSIX-NEXT:       - '/usr/src/foo.h'
 POSIX:          Subsections:
-POSIX:                - FileName:        '/usr/src{{[\\/]}}pdb_lines_1.c'
-POSIX:                - FileName:        '/usr/src{{[\\/]}}foo.h'
+POSIX:                - FileName:        '/usr/src/pdb_lines_1.c'
+POSIX:                - FileName:        '/usr/src/foo.h'
 POSIX:            - !FileChecksums
-POSIX:                - FileName:        '/usr/src{{[\\/]}}pdb_lines_1.c'
-POSIX:                - FileName:        '/usr/src{{[\\/]}}foo.h'
+POSIX:                - FileName:        '/usr/src/pdb_lines_1.c'
+POSIX:                - FileName:        '/usr/src/foo.h'
 
-POSIX-LABEL:  - Module:          '/usr/src{{[\\/]}}pdb_lines_2_relative.obj'
-POSIX-NEXT:     ObjFile:         '/usr/src{{[\\/]}}pdb_lines_2_relative.obj'
+POSIX-LABEL:  - Module:          '/usr/src/pdb_lines_2_relative.obj'
+POSIX-NEXT:     ObjFile:         '/usr/src/pdb_lines_2_relative.obj'
 POSIX:          SourceFiles:
-POSIX-NEXT:       - '/usr/src{{[\\/]}}pdb_lines_2.c'
+POSIX-NEXT:       - '/usr/src/pdb_lines_2.c'
 POSIX:          Subsections:
-POSIX:                - FileName:        '/usr/src{{[\\/]}}pdb_lines_2.c'
+POSIX:                - FileName:        '/usr/src/pdb_lines_2.c'
 POSIX:            - !FileChecksums
-POSIX:                - FileName:        '/usr/src{{[\\/]}}pdb_lines_2.c'
+POSIX:                - FileName:        '/usr/src/pdb_lines_2.c'
 
 POSIX-LABEL:  - Kind:            S_ENVBLOCK
 POSIX-NEXT:     EnvBlockSym:     
@@ -98,8 +98,8 @@
 POSIX-NEXT:         - cwd
 POSIX-NEXT:         - '/usr/src'
 POSIX-NEXT:         - exe
-POSIX-NEXT:         - '/usr/src{{[\\/]}}lld-link'
+POSIX-NEXT:         - '/usr/src/lld-link'
 POSIX-NEXT:         - pdb 
-POSIX-NEXT:         - '/usr/src{{[\\/]}}out.pdb'
+POSIX-NEXT:         - '/usr/src/out.pdb'
 POSIX-NEXT:         - cmd
 POSIX-NEXT:         - '-debug -pdbsourcepath:/usr/src -entry:main -nodefaultlib -out:out.exe -pdb:out.pdb pdb_lines_1_relative.obj pdb_lines_2_relative.obj'
diff --git a/test/COFF/pdb-tpi-hash-size.test b/test/COFF/pdb-tpi-hash-size.test
new file mode 100644
index 0000000..3635a5c
--- /dev/null
+++ b/test/COFF/pdb-tpi-hash-size.test
@@ -0,0 +1,10 @@
+# RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj
+# RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj
+# RUN: rm -f %t.dll %t.pdb
+# RUN: lld-link /debug /pdb:%t.pdb /dll /out:%t.dll \
+# RUN:   /entry:main /nodefaultlib %t1.obj %t2.obj
+
+# RUN: llvm-pdbutil dump -types -type-extras %t.pdb | FileCheck %s
+
+CHECK:      Hash Key Size: 4
+CHECK-NEXT: Num Hash Buckets: 262143
diff --git a/test/COFF/pdb-type-server-missing.yaml b/test/COFF/pdb-type-server-missing.yaml
index 7766a48..1a8c9a0 100644
--- a/test/COFF/pdb-type-server-missing.yaml
+++ b/test/COFF/pdb-type-server-missing.yaml
@@ -4,13 +4,22 @@
 
 # RUN: yaml2obj %s -o %t1.obj
 # RUN: yaml2obj %p/Inputs/pdb-type-server-missing-2.yaml -o %t2.obj
-# RUN: lld-link %t1.obj %t2.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s
+# RUN: lld-link %t1.obj %t2.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s -check-prefix=WARN
+# RUN: lld-link %t1.obj %t2.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main /ignore:4099 2>&1 | FileCheck %s -check-prefix=IGNORE -allow-empty
+# RUN: not lld-link %t1.obj %t2.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main /WX 2>&1 | FileCheck %s -check-prefix=ERR
+# RUN: lld-link %t1.obj %t2.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main /ignore:4099 /WX 2>&1 | FileCheck %s -check-prefix=IGNORE-ERR -allow-empty
 
-# CHECK: warning: Cannot use debug info for {{.*}}.obj
-# CHECK-NEXT: {{N|n}}o such file or directory
+# WARN: warning: Cannot use debug info for '{{.*}}.obj' [LNK4099]
+# WARN-NEXT: {{N|n}}o such file or directory
 
-# CHECK: warning: Cannot use debug info for {{.*}}.obj
-# CHECK-NEXT: {{N|n}}o such file or directory
+# IGNORE-NOT: warning: Cannot use debug info for '{{.*}}.obj' [LNK4099]
+# IGNORE-NOT: {{N|n}}o such file or directory
+
+# ERR: error: Cannot use debug info for '{{.*}}.obj' [LNK4099]
+# ERR-NEXT: {{N|n}}o such file or directory
+
+# IGNORE-ERR-NOT: error: Cannot use debug info for '{{.*}}.obj' [LNK4099]
+# IGNORE-ERR-NOT: {{N|n}}o such file or directory
 
 --- !COFF
 header:
diff --git a/test/COFF/pdb.test b/test/COFF/pdb.test
index 5788b51..745000c 100644
--- a/test/COFF/pdb.test
+++ b/test/COFF/pdb.test
@@ -142,40 +142,40 @@
 RAW:                          Types (TPI Stream)
 RAW-NEXT: ============================================================
 RAW-NEXT:   Showing 5 records
-RAW-NEXT:   0x1000 | LF_ARGLIST [size = 8, hash = 0xEC0]
-RAW-NEXT:   0x1001 | LF_PROCEDURE [size = 16, hash = 0x7BC]
+RAW-NEXT:   0x1000 | LF_ARGLIST [size = 8, hash = 0x32484]
+RAW-NEXT:   0x1001 | LF_PROCEDURE [size = 16, hash = 0x27EE9]
 RAW-NEXT:            return type = 0x0074 (int), # args = 0, param list = 0x1000
 RAW-NEXT:            calling conv = cdecl, options = None
-RAW-NEXT:   0x1002 | LF_POINTER [size = 12, hash = 0x884]
+RAW-NEXT:   0x1002 | LF_POINTER [size = 12, hash = 0x39732]
 RAW-NEXT:            referent = 0x1001, mode = pointer, opts = None, kind = ptr64
-RAW-NEXT:   0x1003 | LF_ARGLIST [size = 12, hash = 0x936]
+RAW-NEXT:   0x1003 | LF_ARGLIST [size = 12, hash = 0x1FC10]
 RAW-NEXT:            <no type>: ``
-RAW-NEXT:   0x1004 | LF_PROCEDURE [size = 16, hash = 0x852]
+RAW-NEXT:   0x1004 | LF_PROCEDURE [size = 16, hash = 0x1BD3]
 RAW-NEXT:            return type = 0x0074 (int), # args = 0, param list = 0x1003
 RAW-NEXT:            calling conv = cdecl, options = None
 RAW:                          Types (IPI Stream)
 RAW-NEXT: ============================================================
 RAW-NEXT:   Showing 12 records
-RAW-NEXT:   0x1000 | LF_FUNC_ID [size = 20, hash = 0x330]
+RAW-NEXT:   0x1000 | LF_FUNC_ID [size = 20, hash = 0x38E5A]
 RAW-NEXT:            name = main, type = 0x1004, parent scope = <no type>
-RAW-NEXT:   0x1001 | LF_FUNC_ID [size = 16, hash = 0x120]
+RAW-NEXT:   0x1001 | LF_FUNC_ID [size = 16, hash = 0xD08E]
 RAW-NEXT:            name = foo, type = 0x1001, parent scope = <no type>
-RAW-NEXT:   0x1002 | LF_STRING_ID [size = 16, hash = 0x757] ID: <no type>, String: D:\b
-RAW-NEXT:   0x1003 | LF_STRING_ID [size = 36, hash = 0xC3A] ID: <no type>, String: C:\vs14\VC\BIN\amd64\cl.exe
-RAW-NEXT:   0x1004 | LF_STRING_ID [size = 260, hash = 0x433] ID: <no type>, String: -Z7 -c -MT -IC:\vs14\VC\INCLUDE -IC:\vs14\VC\ATLMFC\INCLUDE -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10150.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared"
-RAW-NEXT:   0x1005 | LF_SUBSTR_LIST [size = 12, hash = 0x759]
+RAW-NEXT:   0x1002 | LF_STRING_ID [size = 16, hash = 0x3EBD9] ID: <no type>, String: D:\b
+RAW-NEXT:   0x1003 | LF_STRING_ID [size = 36, hash = 0xD327] ID: <no type>, String: C:\vs14\VC\BIN\amd64\cl.exe
+RAW-NEXT:   0x1004 | LF_STRING_ID [size = 260, hash = 0x2FA6A]  ID: <no type>, String: -Z7 -c -MT -IC:\vs14\VC\INCLUDE -IC:\vs14\VC\ATLMFC\INCLUDE -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10150.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared"
+RAW-NEXT:   0x1005 | LF_SUBSTR_LIST [size = 12, hash = 0x6053]
 RAW-NEXT:            0x1004: `-Z7 -c -MT -IC:\vs14\VC\INCLUDE -IC:\vs14\VC\ATLMFC\INCLUDE -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10150.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared"`
-RAW-NEXT:   0x1006 | LF_STRING_ID [size = 132, hash = 0xF57] ID: 0x1005, String:  -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X
-RAW-NEXT:   0x1007 | LF_STRING_ID [size = 24, hash = 0x2D1] ID: <no type>, String: ret42-main.c
-RAW-NEXT:   0x1008 | LF_STRING_ID [size = 24, hash = 0xB8B] ID: <no type>, String: D:\b\vc140.pdb
-RAW-NEXT:   0x1009 | LF_BUILDINFO [size = 28, hash = 0xA8C]
+RAW-NEXT:   0x1006 | LF_STRING_ID [size = 132, hash = 0xCAC7] ID: 0x1005, String:  -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X
+RAW-NEXT:   0x1007 | LF_STRING_ID [size = 24, hash = 0x21783] ID: <no type>, String: ret42-main.c
+RAW-NEXT:   0x1008 | LF_STRING_ID [size = 24, hash = 0x1DB87] ID: <no type>, String: D:\b\vc140.pdb
+RAW-NEXT:   0x1009 | LF_BUILDINFO [size = 28, hash = 0x5E91]
 RAW-NEXT:            0x1002: `D:\b`
 RAW-NEXT:            0x1003: `C:\vs14\VC\BIN\amd64\cl.exe`
 RAW-NEXT:            0x1007: `ret42-main.c`
 RAW-NEXT:            0x1008: `D:\b\vc140.pdb`
 RAW-NEXT:            0x1006: ` -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X`
-RAW-NEXT:   0x100A | LF_STRING_ID [size = 20, hash = 0x39C] ID: <no type>, String: ret42-sub.c
-RAW-NEXT:   0x100B | LF_BUILDINFO [size = 28, hash = 0xAD7]
+RAW-NEXT:   0x100A | LF_STRING_ID [size = 20, hash = 0x7C68] ID: <no type>, String: ret42-sub.c
+RAW-NEXT:   0x100B | LF_BUILDINFO [size = 28, hash = 0x254D2]
 RAW-NEXT:            0x1002: `D:\b`
 RAW-NEXT:            0x1003: `C:\vs14\VC\BIN\amd64\cl.exe`
 RAW-NEXT:            0x100A: `ret42-sub.c`
diff --git a/test/COFF/precomp-link.test b/test/COFF/precomp-link.test
index f7be26c..7ba747e 100644
--- a/test/COFF/precomp-link.test
+++ b/test/COFF/precomp-link.test
@@ -1,42 +1,42 @@
-RUN: lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj %S/Inputs/precomp.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf

-RUN: llvm-pdbutil dump -types %t.pdb | FileCheck %s

-

-RUN: lld-link %S/Inputs/precomp.obj %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf

-RUN: llvm-pdbutil dump -types %t.pdb | FileCheck %s

-

-RUN: lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-invalid.obj %S/Inputs/precomp.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf 2>&1 | FileCheck %s -check-prefix FAILURE

-

-RUN: not lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf 2>&1 | FileCheck %s -check-prefix FAILURE-MISSING-PRECOMPOBJ

-

-FAILURE: warning: Cannot use debug info for 'precomp-invalid.obj'

-FAILURE-NEXT: failed to load reference '{{.*}}precomp.obj': The signature does not match; the file(s) might be out of date.

-

-FAILURE-MISSING-PRECOMPOBJ: warning: Cannot use debug info for 'precomp-a.obj'

-FAILURE-MISSING-PRECOMPOBJ-NEXT: failed to load reference 'precomp.obj': The path to this file must be provided on the command-line

-

-CHECK: Types (TPI Stream)

-CHECK-NOT: LF_PRECOMP

-CHECK-NOT: LF_ENDPRECOMP

-

-// precomp.h

-#pragma once

-int Function(char A);

-

-// precomp.cpp

-#include "precomp.h"

-

-// a.cpp

-#include "precomp.h"

-int main(void) {

-  Function('a');

-  return 0;

-}

-

-// b.cpp

-#include "precomp.h"

-int Function(char a) {

-  return (int)a;

-}

-

-// cl.exe precomp.cpp /Z7 /Ycprecomp.h /c

-// cl.exe a.cpp b.cpp /Z7 /Yuprecomp.h /c

+RUN: lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj %S/Inputs/precomp.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf
+RUN: llvm-pdbutil dump -types %t.pdb | FileCheck %s
+
+RUN: lld-link %S/Inputs/precomp.obj %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf
+RUN: llvm-pdbutil dump -types %t.pdb | FileCheck %s
+
+RUN: lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-invalid.obj %S/Inputs/precomp.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf 2>&1 | FileCheck %s -check-prefix FAILURE
+
+RUN: not lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf 2>&1 | FileCheck %s -check-prefix FAILURE-MISSING-PRECOMPOBJ
+
+FAILURE: warning: Cannot use debug info for 'precomp-invalid.obj' [LNK4099]
+FAILURE-NEXT: failed to load reference '{{.*}}precomp.obj': The signature does not match; the file(s) might be out of date.
+
+FAILURE-MISSING-PRECOMPOBJ: warning: Cannot use debug info for 'precomp-a.obj' [LNK4099]
+FAILURE-MISSING-PRECOMPOBJ-NEXT: failed to load reference '{{.*}}precomp.obj': The path to this file must be provided on the command-line
+
+CHECK: Types (TPI Stream)
+CHECK-NOT: LF_PRECOMP
+CHECK-NOT: LF_ENDPRECOMP
+
+// precomp.h
+#pragma once
+int Function(char A);
+
+// precomp.cpp
+#include "precomp.h"
+
+// a.cpp
+#include "precomp.h"
+int main(void) {
+  Function('a');
+  return 0;
+}
+
+// b.cpp
+#include "precomp.h"
+int Function(char a) {
+  return (int)a;
+}
+
+// cl.exe precomp.cpp /Z7 /Ycprecomp.h /c
+// cl.exe a.cpp b.cpp /Z7 /Yuprecomp.h /c
diff --git a/test/COFF/s_udt.s b/test/COFF/s_udt.s
index 8ad342e..900948a 100644
--- a/test/COFF/s_udt.s
+++ b/test/COFF/s_udt.s
@@ -27,450 +27,450 @@
 # CHECK-NEXT: ============================================================
 # CHECK:      {{.*}} | S_GPROC32 [size = 44] `main`
 # CHECK-NEXT:          parent = 0, end = 252, addr = 0001:0000, code size = 52
-# CHECK-NEXT:          type = `0x1002 (int (int, char**))`, debug start = 0, debug end = 0, flags = none

+# CHECK-NEXT:          type = `0x1002 (int (int, char**))`, debug start = 0, debug end = 0, flags = none
 # CHECK-NOT:  {{.*}} | S_END
 # CHECK:      {{.*}} | S_UDT [size = 28] `main::LocalTypedef`
 # CHECK-NEXT:          original type = 0x1004
-# CHECK:      {{.*}} | S_END [size = 4]

-

-# source code to re-generate:

-# clang-cl /Z7 /GS- /GR- /c foo.cpp

-#

-# struct Struct {

-#   int x;

-# };

-# 

-# using IntTypedef = int;

-# using StructTypedef = Struct;

-# Struct S;

-# StructTypedef SS;

-# IntTypedef I;

-# 

-# int main(int argc, char **argv) {

-#   using LocalTypedef = Struct*;

-#   LocalTypedef SPtr;

-#   return I + S.x + SS.x + SPtr->x;

+# CHECK:      {{.*}} | S_END [size = 4]
+
+# source code to re-generate:
+# clang-cl /Z7 /GS- /GR- /c foo.cpp
+#
+# struct Struct {
+#   int x;
+# };
+#
+# using IntTypedef = int;
+# using StructTypedef = Struct;
+# Struct S;
+# StructTypedef SS;
+# IntTypedef I;
+#
+# int main(int argc, char **argv) {
+#   using LocalTypedef = Struct*;
+#   LocalTypedef SPtr;
+#   return I + S.x + SS.x + SPtr->x;
 # }
 
-	.text

-	.def	 @feat.00;

-	.scl	3;

-	.type	0;

-	.endef

-	.globl	@feat.00

-.set @feat.00, 0

-	.intel_syntax noprefix

-	.def	 main;

-	.scl	2;

-	.type	32;

-	.endef

-	.globl	main                    # -- Begin function main

-	.p2align	4, 0x90

-main:                                   # @main

-.Lfunc_begin0:

-	.cv_func_id 0

-	.cv_file	1 "D:\\src\\llvmbuild\\cl\\Debug\\x64\\foo.cpp" "2B62298EE3EEF94E1D81FDFE18BD46A6" 1

-	.cv_loc	0 1 12 0                # foo.cpp:12:0

-.seh_proc main

-# %bb.0:                                # %entry

-	sub	rsp, 32

-	.seh_stackalloc 32

-	.seh_endprologue

-	mov	dword ptr [rsp + 28], 0

-	mov	qword ptr [rsp + 16], rdx

-	mov	dword ptr [rsp + 12], ecx

-.Ltmp0:

-	.cv_loc	0 1 15 0                # foo.cpp:15:0

-	mov	ecx, dword ptr [rip + "?I@@3HA"]

-	add	ecx, dword ptr [rip + "?S@@3UStruct@@A"]

-	add	ecx, dword ptr [rip + "?SS@@3UStruct@@A"]

-	mov	rdx, qword ptr [rsp]

-	add	ecx, dword ptr [rdx]

-	mov	eax, ecx

-	add	rsp, 32

-	ret

-.Ltmp1:

-.Lfunc_end0:

-	.seh_handlerdata

-	.text

-	.seh_endproc

-                                        # -- End function

-	.bss

-	.globl	"?S@@3UStruct@@A"       # @"?S@@3UStruct@@A"

-	.p2align	2

-"?S@@3UStruct@@A":

-	.zero	4

-

-	.globl	"?SS@@3UStruct@@A"      # @"?SS@@3UStruct@@A"

-	.p2align	2

-"?SS@@3UStruct@@A":

-	.zero	4

-

-	.globl	"?I@@3HA"               # @"?I@@3HA"

-	.p2align	2

-"?I@@3HA":

-	.long	0                       # 0x0

-

-	.section	.drectve,"yn"

-	.ascii	" /DEFAULTLIB:libcmt.lib"

-	.ascii	" /DEFAULTLIB:oldnames.lib"

-	.section	.debug$S,"dr"

-	.p2align	2

-	.long	4                       # Debug section magic

-	.long	241

-	.long	.Ltmp3-.Ltmp2           # Subsection size

-.Ltmp2:

-	.short	.Ltmp5-.Ltmp4           # Record length

-.Ltmp4:

-	.short	4412                    # Record kind: S_COMPILE3

-	.long	1                       # Flags and language

-	.short	208                     # CPUType

-	.short	8                       # Frontend version

-	.short	0

-	.short	0

-	.short	0

-	.short	8000                    # Backend version

-	.short	0

-	.short	0

-	.short	0

-	.asciz	"clang version 8.0.0 "  # Null-terminated compiler version string

-.Ltmp5:

-.Ltmp3:

-	.p2align	2

-	.long	241                     # Symbol subsection for main

-	.long	.Ltmp7-.Ltmp6           # Subsection size

-.Ltmp6:

-	.short	.Ltmp9-.Ltmp8           # Record length

-.Ltmp8:

-	.short	4423                    # Record kind: S_GPROC32_ID

-	.long	0                       # PtrParent

-	.long	0                       # PtrEnd

-	.long	0                       # PtrNext

-	.long	.Lfunc_end0-main        # Code size

-	.long	0                       # Offset after prologue

-	.long	0                       # Offset before epilogue

-	.long	4099                    # Function type index

-	.secrel32	main            # Function section relative address

-	.secidx	main                    # Function section index

-	.byte	0                       # Flags

-	.asciz	"main"                  # Function name

-.Ltmp9:

-	.short	.Ltmp11-.Ltmp10         # Record length

-.Ltmp10:

-	.short	4114                    # Record kind: S_FRAMEPROC

-	.long	32                      # FrameSize

-	.long	0                       # Padding

-	.long	0                       # Offset of padding

-	.long	0                       # Bytes of callee saved registers

-	.long	0                       # Exception handler offset

-	.short	0                       # Exception handler section

-	.long	81920                   # Flags (defines frame register)

-.Ltmp11:

-	.short	.Ltmp13-.Ltmp12         # Record length

-.Ltmp12:

-	.short	4414                    # Record kind: S_LOCAL

-	.long	116                     # TypeIndex

-	.short	1                       # Flags

-	.asciz	"argc"

-.Ltmp13:

-	.cv_def_range	 .Ltmp0 .Ltmp1, "B\021\f\000\000\000"

-	.short	.Ltmp15-.Ltmp14         # Record length

-.Ltmp14:

-	.short	4414                    # Record kind: S_LOCAL

-	.long	4096                    # TypeIndex

-	.short	1                       # Flags

-	.asciz	"argv"

-.Ltmp15:

-	.cv_def_range	 .Ltmp0 .Ltmp1, "B\021\020\000\000\000"

-	.short	.Ltmp17-.Ltmp16         # Record length

-.Ltmp16:

-	.short	4414                    # Record kind: S_LOCAL

-	.long	4101                    # TypeIndex

-	.short	0                       # Flags

-	.asciz	"SPtr"

-.Ltmp17:

-	.cv_def_range	 .Ltmp0 .Ltmp1, "B\021\000\000\000\000"

-	.short	.Ltmp19-.Ltmp18         # Record length

-.Ltmp18:

-	.short	4360                    # Record kind: S_UDT

-	.long	4101                    # Type

-	.asciz	"main::LocalTypedef"

-.Ltmp19:

-	.short	2                       # Record length

-	.short	4431                    # Record kind: S_PROC_ID_END

-.Ltmp7:

-	.p2align	2

-	.cv_linetable	0, main, .Lfunc_end0

-	.long	241                     # Symbol subsection for globals

-	.long	.Ltmp21-.Ltmp20         # Subsection size

-.Ltmp20:

-	.short	.Ltmp23-.Ltmp22         # Record length

-.Ltmp22:

-	.short	4365                    # Record kind: S_GDATA32

-	.long	4103                    # Type

-	.secrel32	"?S@@3UStruct@@A" # DataOffset

-	.secidx	"?S@@3UStruct@@A"       # Segment

-	.asciz	"S"                     # Name

-.Ltmp23:

-	.short	.Ltmp25-.Ltmp24         # Record length

-.Ltmp24:

-	.short	4365                    # Record kind: S_GDATA32

-	.long	4100                    # Type

-	.secrel32	"?SS@@3UStruct@@A" # DataOffset

-	.secidx	"?SS@@3UStruct@@A"      # Segment

-	.asciz	"SS"                    # Name

-.Ltmp25:

-	.short	.Ltmp27-.Ltmp26         # Record length

-.Ltmp26:

-	.short	4365                    # Record kind: S_GDATA32

-	.long	116                     # Type

-	.secrel32	"?I@@3HA"       # DataOffset

-	.secidx	"?I@@3HA"               # Segment

-	.asciz	"I"                     # Name

-.Ltmp27:

-.Ltmp21:

-	.p2align	2

-	.long	241

-	.long	.Ltmp29-.Ltmp28         # Subsection size

-.Ltmp28:

-	.short	.Ltmp31-.Ltmp30         # Record length

-.Ltmp30:

-	.short	4360                    # Record kind: S_UDT

-	.long	4103                    # Type

-	.asciz	"Struct"

-.Ltmp31:

-	.short	.Ltmp33-.Ltmp32         # Record length

-.Ltmp32:

-	.short	4360                    # Record kind: S_UDT

-	.long	4100                    # Type

-	.asciz	"StructTypedef"

-.Ltmp33:

-	.short	.Ltmp35-.Ltmp34         # Record length

-.Ltmp34:

-	.short	4360                    # Record kind: S_UDT

-	.long	116                     # Type

-	.asciz	"IntTypedef"

-.Ltmp35:

-.Ltmp29:

-	.p2align	2

-	.cv_filechecksums               # File index to string table offset subsection

-	.cv_stringtable                 # String table

-	.long	241

-	.long	.Ltmp37-.Ltmp36         # Subsection size

-.Ltmp36:

-	.short	6                       # Record length

-	.short	4428                    # Record kind: S_BUILDINFO

-	.long	4108                    # LF_BUILDINFO index

-.Ltmp37:

-	.p2align	2

-	.section	.debug$T,"dr"

-	.p2align	2

-	.long	4                       # Debug section magic

-	# Pointer (0x1000) {

-	#   TypeLeafKind: LF_POINTER (0x1002)

-	#   PointeeType: char* (0x670)

-	#   PtrType: Near64 (0xC)

-	#   PtrMode: Pointer (0x0)

-	#   IsFlat: 0

-	#   IsConst: 0

-	#   IsVolatile: 0

-	#   IsUnaligned: 0

-	#   IsRestrict: 0

-	#   IsThisPtr&: 0

-	#   IsThisPtr&&: 0

-	#   SizeOf: 8

-	# }

-	.byte	0x0a, 0x00, 0x02, 0x10

-	.byte	0x70, 0x06, 0x00, 0x00

-	.byte	0x0c, 0x00, 0x01, 0x00

-	# ArgList (0x1001) {

-	#   TypeLeafKind: LF_ARGLIST (0x1201)

-	#   NumArgs: 2

-	#   Arguments [

-	#     ArgType: int (0x74)

-	#     ArgType: char** (0x1000)

-	#   ]

-	# }

-	.byte	0x0e, 0x00, 0x01, 0x12

-	.byte	0x02, 0x00, 0x00, 0x00

-	.byte	0x74, 0x00, 0x00, 0x00

-	.byte	0x00, 0x10, 0x00, 0x00

-	# Procedure (0x1002) {

-	#   TypeLeafKind: LF_PROCEDURE (0x1008)

-	#   ReturnType: int (0x74)

-	#   CallingConvention: NearC (0x0)

-	#   FunctionOptions [ (0x0)

-	#   ]

-	#   NumParameters: 2

-	#   ArgListType: (int, char**) (0x1001)

-	# }

-	.byte	0x0e, 0x00, 0x08, 0x10

-	.byte	0x74, 0x00, 0x00, 0x00

-	.byte	0x00, 0x00, 0x02, 0x00

-	.byte	0x01, 0x10, 0x00, 0x00

-	# FuncId (0x1003) {

-	#   TypeLeafKind: LF_FUNC_ID (0x1601)

-	#   ParentScope: 0x0

-	#   FunctionType: int (int, char**) (0x1002)

-	#   Name: main

-	# }

-	.byte	0x12, 0x00, 0x01, 0x16

-	.byte	0x00, 0x00, 0x00, 0x00

-	.byte	0x02, 0x10, 0x00, 0x00

-	.byte	0x6d, 0x61, 0x69, 0x6e

-	.byte	0x00, 0xf3, 0xf2, 0xf1

-	# Struct (0x1004) {

-	#   TypeLeafKind: LF_STRUCTURE (0x1505)

-	#   MemberCount: 0

-	#   Properties [ (0x280)

-	#     ForwardReference (0x80)

-	#     HasUniqueName (0x200)

-	#   ]

-	#   FieldList: 0x0

-	#   DerivedFrom: 0x0

-	#   VShape: 0x0

-	#   SizeOf: 0

-	#   Name: Struct

-	#   LinkageName: .?AUStruct@@

-	# }

-	.byte	0x2a, 0x00, 0x05, 0x15

-	.byte	0x00, 0x00, 0x80, 0x02

-	.byte	0x00, 0x00, 0x00, 0x00

-	.byte	0x00, 0x00, 0x00, 0x00

-	.byte	0x00, 0x00, 0x00, 0x00

-	.byte	0x00, 0x00, 0x53, 0x74

-	.byte	0x72, 0x75, 0x63, 0x74

-	.byte	0x00, 0x2e, 0x3f, 0x41

-	.byte	0x55, 0x53, 0x74, 0x72

-	.byte	0x75, 0x63, 0x74, 0x40

-	.byte	0x40, 0x00, 0xf2, 0xf1

-	# Pointer (0x1005) {

-	#   TypeLeafKind: LF_POINTER (0x1002)

-	#   PointeeType: Struct (0x1004)

-	#   PtrType: Near64 (0xC)

-	#   PtrMode: Pointer (0x0)

-	#   IsFlat: 0

-	#   IsConst: 0

-	#   IsVolatile: 0

-	#   IsUnaligned: 0

-	#   IsRestrict: 0

-	#   IsThisPtr&: 0

-	#   IsThisPtr&&: 0

-	#   SizeOf: 8

-	# }

-	.byte	0x0a, 0x00, 0x02, 0x10

-	.byte	0x04, 0x10, 0x00, 0x00

-	.byte	0x0c, 0x00, 0x01, 0x00

-	# FieldList (0x1006) {

-	#   TypeLeafKind: LF_FIELDLIST (0x1203)

-	#   DataMember {

-	#     TypeLeafKind: LF_MEMBER (0x150D)

-	#     AccessSpecifier: Public (0x3)

-	#     Type: int (0x74)

-	#     FieldOffset: 0x0

-	#     Name: x

-	#   }

-	# }

-	.byte	0x0e, 0x00, 0x03, 0x12

-	.byte	0x0d, 0x15, 0x03, 0x00

-	.byte	0x74, 0x00, 0x00, 0x00

-	.byte	0x00, 0x00, 0x78, 0x00

-	# Struct (0x1007) {

-	#   TypeLeafKind: LF_STRUCTURE (0x1505)

-	#   MemberCount: 1

-	#   Properties [ (0x200)

-	#     HasUniqueName (0x200)

-	#   ]

-	#   FieldList: <field list> (0x1006)

-	#   DerivedFrom: 0x0

-	#   VShape: 0x0

-	#   SizeOf: 4

-	#   Name: Struct

-	#   LinkageName: .?AUStruct@@

-	# }

-	.byte	0x2a, 0x00, 0x05, 0x15

-	.byte	0x01, 0x00, 0x00, 0x02

-	.byte	0x06, 0x10, 0x00, 0x00

-	.byte	0x00, 0x00, 0x00, 0x00

-	.byte	0x00, 0x00, 0x00, 0x00

-	.byte	0x04, 0x00, 0x53, 0x74

-	.byte	0x72, 0x75, 0x63, 0x74

-	.byte	0x00, 0x2e, 0x3f, 0x41

-	.byte	0x55, 0x53, 0x74, 0x72

-	.byte	0x75, 0x63, 0x74, 0x40

-	.byte	0x40, 0x00, 0xf2, 0xf1

-	# StringId (0x1008) {

-	#   TypeLeafKind: LF_STRING_ID (0x1605)

-	#   Id: 0x0

-	#   StringData: D:\src\llvmbuild\cl\Debug\x64\foo.cpp

-	# }

-	.byte	0x2e, 0x00, 0x05, 0x16

-	.byte	0x00, 0x00, 0x00, 0x00

-	.byte	0x44, 0x3a, 0x5c, 0x73

-	.byte	0x72, 0x63, 0x5c, 0x6c

-	.byte	0x6c, 0x76, 0x6d, 0x62

-	.byte	0x75, 0x69, 0x6c, 0x64

-	.byte	0x5c, 0x63, 0x6c, 0x5c

-	.byte	0x44, 0x65, 0x62, 0x75

-	.byte	0x67, 0x5c, 0x78, 0x36

-	.byte	0x34, 0x5c, 0x66, 0x6f

-	.byte	0x6f, 0x2e, 0x63, 0x70

-	.byte	0x70, 0x00, 0xf2, 0xf1

-	# UdtSourceLine (0x1009) {

-	#   TypeLeafKind: LF_UDT_SRC_LINE (0x1606)

-	#   UDT: Struct (0x1007)

-	#   SourceFile: D:\src\llvmbuild\cl\Debug\x64\foo.cpp (0x1008)

-	#   LineNumber: 1

-	# }

-	.byte	0x0e, 0x00, 0x06, 0x16

-	.byte	0x07, 0x10, 0x00, 0x00

-	.byte	0x08, 0x10, 0x00, 0x00

-	.byte	0x01, 0x00, 0x00, 0x00

-	# StringId (0x100A) {

-	#   TypeLeafKind: LF_STRING_ID (0x1605)

-	#   Id: 0x0

-	#   StringData: D:\\src\\llvmbuild\\cl\\Debug\\x64

-	# }

-	.byte	0x2a, 0x00, 0x05, 0x16

-	.byte	0x00, 0x00, 0x00, 0x00

-	.byte	0x44, 0x3a, 0x5c, 0x5c

-	.byte	0x73, 0x72, 0x63, 0x5c

-	.byte	0x5c, 0x6c, 0x6c, 0x76

-	.byte	0x6d, 0x62, 0x75, 0x69

-	.byte	0x6c, 0x64, 0x5c, 0x5c

-	.byte	0x63, 0x6c, 0x5c, 0x5c

-	.byte	0x44, 0x65, 0x62, 0x75

-	.byte	0x67, 0x5c, 0x5c, 0x78

-	.byte	0x36, 0x34, 0x00, 0xf1

-	# StringId (0x100B) {

-	#   TypeLeafKind: LF_STRING_ID (0x1605)

-	#   Id: 0x0

-	#   StringData: foo.cpp

-	# }

-	.byte	0x0e, 0x00, 0x05, 0x16

-	.byte	0x00, 0x00, 0x00, 0x00

-	.byte	0x66, 0x6f, 0x6f, 0x2e

-	.byte	0x63, 0x70, 0x70, 0x00

-	# BuildInfo (0x100C) {

-	#   TypeLeafKind: LF_BUILDINFO (0x1603)

-	#   NumArgs: 5

-	#   Arguments [

-	#     ArgType: D:\\src\\llvmbuild\\cl\\Debug\\x64 (0x100A)

-	#     ArgType: 0x0

-	#     ArgType: foo.cpp (0x100B)

-	#     ArgType: 0x0

-	#     ArgType: 0x0

-	#   ]

-	# }

-	.byte	0x1a, 0x00, 0x03, 0x16

-	.byte	0x05, 0x00, 0x0a, 0x10

-	.byte	0x00, 0x00, 0x00, 0x00

-	.byte	0x00, 0x00, 0x0b, 0x10

-	.byte	0x00, 0x00, 0x00, 0x00

-	.byte	0x00, 0x00, 0x00, 0x00

-	.byte	0x00, 0x00, 0xf2, 0xf1

-

-	.addrsig

-	.addrsig_sym "?S@@3UStruct@@A"

-	.addrsig_sym "?SS@@3UStruct@@A"

-	.addrsig_sym "?I@@3HA"

+	.text
+	.def	 @feat.00;
+	.scl	3;
+	.type	0;
+	.endef
+	.globl	@feat.00
+.set @feat.00, 0
+	.intel_syntax noprefix
+	.def	 main;
+	.scl	2;
+	.type	32;
+	.endef
+	.globl	main                    # -- Begin function main
+	.p2align	4, 0x90
+main:                                   # @main
+.Lfunc_begin0:
+	.cv_func_id 0
+	.cv_file	1 "D:\\src\\llvmbuild\\cl\\Debug\\x64\\foo.cpp" "2B62298EE3EEF94E1D81FDFE18BD46A6" 1
+	.cv_loc	0 1 12 0                # foo.cpp:12:0
+.seh_proc main
+# %bb.0:                                # %entry
+	sub	rsp, 32
+	.seh_stackalloc 32
+	.seh_endprologue
+	mov	dword ptr [rsp + 28], 0
+	mov	qword ptr [rsp + 16], rdx
+	mov	dword ptr [rsp + 12], ecx
+.Ltmp0:
+	.cv_loc	0 1 15 0                # foo.cpp:15:0
+	mov	ecx, dword ptr [rip + "?I@@3HA"]
+	add	ecx, dword ptr [rip + "?S@@3UStruct@@A"]
+	add	ecx, dword ptr [rip + "?SS@@3UStruct@@A"]
+	mov	rdx, qword ptr [rsp]
+	add	ecx, dword ptr [rdx]
+	mov	eax, ecx
+	add	rsp, 32
+	ret
+.Ltmp1:
+.Lfunc_end0:
+	.seh_handlerdata
+	.text
+	.seh_endproc
+                                        # -- End function
+	.bss
+	.globl	"?S@@3UStruct@@A"       # @"?S@@3UStruct@@A"
+	.p2align	2
+"?S@@3UStruct@@A":
+	.zero	4
+
+	.globl	"?SS@@3UStruct@@A"      # @"?SS@@3UStruct@@A"
+	.p2align	2
+"?SS@@3UStruct@@A":
+	.zero	4
+
+	.globl	"?I@@3HA"               # @"?I@@3HA"
+	.p2align	2
+"?I@@3HA":
+	.long	0                       # 0x0
+
+	.section	.drectve,"yn"
+	.ascii	" /DEFAULTLIB:libcmt.lib"
+	.ascii	" /DEFAULTLIB:oldnames.lib"
+	.section	.debug$S,"dr"
+	.p2align	2
+	.long	4                       # Debug section magic
+	.long	241
+	.long	.Ltmp3-.Ltmp2           # Subsection size
+.Ltmp2:
+	.short	.Ltmp5-.Ltmp4           # Record length
+.Ltmp4:
+	.short	4412                    # Record kind: S_COMPILE3
+	.long	1                       # Flags and language
+	.short	208                     # CPUType
+	.short	8                       # Frontend version
+	.short	0
+	.short	0
+	.short	0
+	.short	8000                    # Backend version
+	.short	0
+	.short	0
+	.short	0
+	.asciz	"clang version 8.0.0 "  # Null-terminated compiler version string
+.Ltmp5:
+.Ltmp3:
+	.p2align	2
+	.long	241                     # Symbol subsection for main
+	.long	.Ltmp7-.Ltmp6           # Subsection size
+.Ltmp6:
+	.short	.Ltmp9-.Ltmp8           # Record length
+.Ltmp8:
+	.short	4423                    # Record kind: S_GPROC32_ID
+	.long	0                       # PtrParent
+	.long	0                       # PtrEnd
+	.long	0                       # PtrNext
+	.long	.Lfunc_end0-main        # Code size
+	.long	0                       # Offset after prologue
+	.long	0                       # Offset before epilogue
+	.long	4099                    # Function type index
+	.secrel32	main            # Function section relative address
+	.secidx	main                    # Function section index
+	.byte	0                       # Flags
+	.asciz	"main"                  # Function name
+.Ltmp9:
+	.short	.Ltmp11-.Ltmp10         # Record length
+.Ltmp10:
+	.short	4114                    # Record kind: S_FRAMEPROC
+	.long	32                      # FrameSize
+	.long	0                       # Padding
+	.long	0                       # Offset of padding
+	.long	0                       # Bytes of callee saved registers
+	.long	0                       # Exception handler offset
+	.short	0                       # Exception handler section
+	.long	81920                   # Flags (defines frame register)
+.Ltmp11:
+	.short	.Ltmp13-.Ltmp12         # Record length
+.Ltmp12:
+	.short	4414                    # Record kind: S_LOCAL
+	.long	116                     # TypeIndex
+	.short	1                       # Flags
+	.asciz	"argc"
+.Ltmp13:
+	.cv_def_range	 .Ltmp0 .Ltmp1, "B\021\f\000\000\000"
+	.short	.Ltmp15-.Ltmp14         # Record length
+.Ltmp14:
+	.short	4414                    # Record kind: S_LOCAL
+	.long	4096                    # TypeIndex
+	.short	1                       # Flags
+	.asciz	"argv"
+.Ltmp15:
+	.cv_def_range	 .Ltmp0 .Ltmp1, "B\021\020\000\000\000"
+	.short	.Ltmp17-.Ltmp16         # Record length
+.Ltmp16:
+	.short	4414                    # Record kind: S_LOCAL
+	.long	4101                    # TypeIndex
+	.short	0                       # Flags
+	.asciz	"SPtr"
+.Ltmp17:
+	.cv_def_range	 .Ltmp0 .Ltmp1, "B\021\000\000\000\000"
+	.short	.Ltmp19-.Ltmp18         # Record length
+.Ltmp18:
+	.short	4360                    # Record kind: S_UDT
+	.long	4101                    # Type
+	.asciz	"main::LocalTypedef"
+.Ltmp19:
+	.short	2                       # Record length
+	.short	4431                    # Record kind: S_PROC_ID_END
+.Ltmp7:
+	.p2align	2
+	.cv_linetable	0, main, .Lfunc_end0
+	.long	241                     # Symbol subsection for globals
+	.long	.Ltmp21-.Ltmp20         # Subsection size
+.Ltmp20:
+	.short	.Ltmp23-.Ltmp22         # Record length
+.Ltmp22:
+	.short	4365                    # Record kind: S_GDATA32
+	.long	4103                    # Type
+	.secrel32	"?S@@3UStruct@@A" # DataOffset
+	.secidx	"?S@@3UStruct@@A"       # Segment
+	.asciz	"S"                     # Name
+.Ltmp23:
+	.short	.Ltmp25-.Ltmp24         # Record length
+.Ltmp24:
+	.short	4365                    # Record kind: S_GDATA32
+	.long	4100                    # Type
+	.secrel32	"?SS@@3UStruct@@A" # DataOffset
+	.secidx	"?SS@@3UStruct@@A"      # Segment
+	.asciz	"SS"                    # Name
+.Ltmp25:
+	.short	.Ltmp27-.Ltmp26         # Record length
+.Ltmp26:
+	.short	4365                    # Record kind: S_GDATA32
+	.long	116                     # Type
+	.secrel32	"?I@@3HA"       # DataOffset
+	.secidx	"?I@@3HA"               # Segment
+	.asciz	"I"                     # Name
+.Ltmp27:
+.Ltmp21:
+	.p2align	2
+	.long	241
+	.long	.Ltmp29-.Ltmp28         # Subsection size
+.Ltmp28:
+	.short	.Ltmp31-.Ltmp30         # Record length
+.Ltmp30:
+	.short	4360                    # Record kind: S_UDT
+	.long	4103                    # Type
+	.asciz	"Struct"
+.Ltmp31:
+	.short	.Ltmp33-.Ltmp32         # Record length
+.Ltmp32:
+	.short	4360                    # Record kind: S_UDT
+	.long	4100                    # Type
+	.asciz	"StructTypedef"
+.Ltmp33:
+	.short	.Ltmp35-.Ltmp34         # Record length
+.Ltmp34:
+	.short	4360                    # Record kind: S_UDT
+	.long	116                     # Type
+	.asciz	"IntTypedef"
+.Ltmp35:
+.Ltmp29:
+	.p2align	2
+	.cv_filechecksums               # File index to string table offset subsection
+	.cv_stringtable                 # String table
+	.long	241
+	.long	.Ltmp37-.Ltmp36         # Subsection size
+.Ltmp36:
+	.short	6                       # Record length
+	.short	4428                    # Record kind: S_BUILDINFO
+	.long	4108                    # LF_BUILDINFO index
+.Ltmp37:
+	.p2align	2
+	.section	.debug$T,"dr"
+	.p2align	2
+	.long	4                       # Debug section magic
+	# Pointer (0x1000) {
+	#   TypeLeafKind: LF_POINTER (0x1002)
+	#   PointeeType: char* (0x670)
+	#   PtrType: Near64 (0xC)
+	#   PtrMode: Pointer (0x0)
+	#   IsFlat: 0
+	#   IsConst: 0
+	#   IsVolatile: 0
+	#   IsUnaligned: 0
+	#   IsRestrict: 0
+	#   IsThisPtr&: 0
+	#   IsThisPtr&&: 0
+	#   SizeOf: 8
+	# }
+	.byte	0x0a, 0x00, 0x02, 0x10
+	.byte	0x70, 0x06, 0x00, 0x00
+	.byte	0x0c, 0x00, 0x01, 0x00
+	# ArgList (0x1001) {
+	#   TypeLeafKind: LF_ARGLIST (0x1201)
+	#   NumArgs: 2
+	#   Arguments [
+	#     ArgType: int (0x74)
+	#     ArgType: char** (0x1000)
+	#   ]
+	# }
+	.byte	0x0e, 0x00, 0x01, 0x12
+	.byte	0x02, 0x00, 0x00, 0x00
+	.byte	0x74, 0x00, 0x00, 0x00
+	.byte	0x00, 0x10, 0x00, 0x00
+	# Procedure (0x1002) {
+	#   TypeLeafKind: LF_PROCEDURE (0x1008)
+	#   ReturnType: int (0x74)
+	#   CallingConvention: NearC (0x0)
+	#   FunctionOptions [ (0x0)
+	#   ]
+	#   NumParameters: 2
+	#   ArgListType: (int, char**) (0x1001)
+	# }
+	.byte	0x0e, 0x00, 0x08, 0x10
+	.byte	0x74, 0x00, 0x00, 0x00
+	.byte	0x00, 0x00, 0x02, 0x00
+	.byte	0x01, 0x10, 0x00, 0x00
+	# FuncId (0x1003) {
+	#   TypeLeafKind: LF_FUNC_ID (0x1601)
+	#   ParentScope: 0x0
+	#   FunctionType: int (int, char**) (0x1002)
+	#   Name: main
+	# }
+	.byte	0x12, 0x00, 0x01, 0x16
+	.byte	0x00, 0x00, 0x00, 0x00
+	.byte	0x02, 0x10, 0x00, 0x00
+	.byte	0x6d, 0x61, 0x69, 0x6e
+	.byte	0x00, 0xf3, 0xf2, 0xf1
+	# Struct (0x1004) {
+	#   TypeLeafKind: LF_STRUCTURE (0x1505)
+	#   MemberCount: 0
+	#   Properties [ (0x280)
+	#     ForwardReference (0x80)
+	#     HasUniqueName (0x200)
+	#   ]
+	#   FieldList: 0x0
+	#   DerivedFrom: 0x0
+	#   VShape: 0x0
+	#   SizeOf: 0
+	#   Name: Struct
+	#   LinkageName: .?AUStruct@@
+	# }
+	.byte	0x2a, 0x00, 0x05, 0x15
+	.byte	0x00, 0x00, 0x80, 0x02
+	.byte	0x00, 0x00, 0x00, 0x00
+	.byte	0x00, 0x00, 0x00, 0x00
+	.byte	0x00, 0x00, 0x00, 0x00
+	.byte	0x00, 0x00, 0x53, 0x74
+	.byte	0x72, 0x75, 0x63, 0x74
+	.byte	0x00, 0x2e, 0x3f, 0x41
+	.byte	0x55, 0x53, 0x74, 0x72
+	.byte	0x75, 0x63, 0x74, 0x40
+	.byte	0x40, 0x00, 0xf2, 0xf1
+	# Pointer (0x1005) {
+	#   TypeLeafKind: LF_POINTER (0x1002)
+	#   PointeeType: Struct (0x1004)
+	#   PtrType: Near64 (0xC)
+	#   PtrMode: Pointer (0x0)
+	#   IsFlat: 0
+	#   IsConst: 0
+	#   IsVolatile: 0
+	#   IsUnaligned: 0
+	#   IsRestrict: 0
+	#   IsThisPtr&: 0
+	#   IsThisPtr&&: 0
+	#   SizeOf: 8
+	# }
+	.byte	0x0a, 0x00, 0x02, 0x10
+	.byte	0x04, 0x10, 0x00, 0x00
+	.byte	0x0c, 0x00, 0x01, 0x00
+	# FieldList (0x1006) {
+	#   TypeLeafKind: LF_FIELDLIST (0x1203)
+	#   DataMember {
+	#     TypeLeafKind: LF_MEMBER (0x150D)
+	#     AccessSpecifier: Public (0x3)
+	#     Type: int (0x74)
+	#     FieldOffset: 0x0
+	#     Name: x
+	#   }
+	# }
+	.byte	0x0e, 0x00, 0x03, 0x12
+	.byte	0x0d, 0x15, 0x03, 0x00
+	.byte	0x74, 0x00, 0x00, 0x00
+	.byte	0x00, 0x00, 0x78, 0x00
+	# Struct (0x1007) {
+	#   TypeLeafKind: LF_STRUCTURE (0x1505)
+	#   MemberCount: 1
+	#   Properties [ (0x200)
+	#     HasUniqueName (0x200)
+	#   ]
+	#   FieldList: <field list> (0x1006)
+	#   DerivedFrom: 0x0
+	#   VShape: 0x0
+	#   SizeOf: 4
+	#   Name: Struct
+	#   LinkageName: .?AUStruct@@
+	# }
+	.byte	0x2a, 0x00, 0x05, 0x15
+	.byte	0x01, 0x00, 0x00, 0x02
+	.byte	0x06, 0x10, 0x00, 0x00
+	.byte	0x00, 0x00, 0x00, 0x00
+	.byte	0x00, 0x00, 0x00, 0x00
+	.byte	0x04, 0x00, 0x53, 0x74
+	.byte	0x72, 0x75, 0x63, 0x74
+	.byte	0x00, 0x2e, 0x3f, 0x41
+	.byte	0x55, 0x53, 0x74, 0x72
+	.byte	0x75, 0x63, 0x74, 0x40
+	.byte	0x40, 0x00, 0xf2, 0xf1
+	# StringId (0x1008) {
+	#   TypeLeafKind: LF_STRING_ID (0x1605)
+	#   Id: 0x0
+	#   StringData: D:\src\llvmbuild\cl\Debug\x64\foo.cpp
+	# }
+	.byte	0x2e, 0x00, 0x05, 0x16
+	.byte	0x00, 0x00, 0x00, 0x00
+	.byte	0x44, 0x3a, 0x5c, 0x73
+	.byte	0x72, 0x63, 0x5c, 0x6c
+	.byte	0x6c, 0x76, 0x6d, 0x62
+	.byte	0x75, 0x69, 0x6c, 0x64
+	.byte	0x5c, 0x63, 0x6c, 0x5c
+	.byte	0x44, 0x65, 0x62, 0x75
+	.byte	0x67, 0x5c, 0x78, 0x36
+	.byte	0x34, 0x5c, 0x66, 0x6f
+	.byte	0x6f, 0x2e, 0x63, 0x70
+	.byte	0x70, 0x00, 0xf2, 0xf1
+	# UdtSourceLine (0x1009) {
+	#   TypeLeafKind: LF_UDT_SRC_LINE (0x1606)
+	#   UDT: Struct (0x1007)
+	#   SourceFile: D:\src\llvmbuild\cl\Debug\x64\foo.cpp (0x1008)
+	#   LineNumber: 1
+	# }
+	.byte	0x0e, 0x00, 0x06, 0x16
+	.byte	0x07, 0x10, 0x00, 0x00
+	.byte	0x08, 0x10, 0x00, 0x00
+	.byte	0x01, 0x00, 0x00, 0x00
+	# StringId (0x100A) {
+	#   TypeLeafKind: LF_STRING_ID (0x1605)
+	#   Id: 0x0
+	#   StringData: D:\\src\\llvmbuild\\cl\\Debug\\x64
+	# }
+	.byte	0x2a, 0x00, 0x05, 0x16
+	.byte	0x00, 0x00, 0x00, 0x00
+	.byte	0x44, 0x3a, 0x5c, 0x5c
+	.byte	0x73, 0x72, 0x63, 0x5c
+	.byte	0x5c, 0x6c, 0x6c, 0x76
+	.byte	0x6d, 0x62, 0x75, 0x69
+	.byte	0x6c, 0x64, 0x5c, 0x5c
+	.byte	0x63, 0x6c, 0x5c, 0x5c
+	.byte	0x44, 0x65, 0x62, 0x75
+	.byte	0x67, 0x5c, 0x5c, 0x78
+	.byte	0x36, 0x34, 0x00, 0xf1
+	# StringId (0x100B) {
+	#   TypeLeafKind: LF_STRING_ID (0x1605)
+	#   Id: 0x0
+	#   StringData: foo.cpp
+	# }
+	.byte	0x0e, 0x00, 0x05, 0x16
+	.byte	0x00, 0x00, 0x00, 0x00
+	.byte	0x66, 0x6f, 0x6f, 0x2e
+	.byte	0x63, 0x70, 0x70, 0x00
+	# BuildInfo (0x100C) {
+	#   TypeLeafKind: LF_BUILDINFO (0x1603)
+	#   NumArgs: 5
+	#   Arguments [
+	#     ArgType: D:\\src\\llvmbuild\\cl\\Debug\\x64 (0x100A)
+	#     ArgType: 0x0
+	#     ArgType: foo.cpp (0x100B)
+	#     ArgType: 0x0
+	#     ArgType: 0x0
+	#   ]
+	# }
+	.byte	0x1a, 0x00, 0x03, 0x16
+	.byte	0x05, 0x00, 0x0a, 0x10
+	.byte	0x00, 0x00, 0x00, 0x00
+	.byte	0x00, 0x00, 0x0b, 0x10
+	.byte	0x00, 0x00, 0x00, 0x00
+	.byte	0x00, 0x00, 0x00, 0x00
+	.byte	0x00, 0x00, 0xf2, 0xf1
+
+	.addrsig
+	.addrsig_sym "?S@@3UStruct@@A"
+	.addrsig_sym "?SS@@3UStruct@@A"
+	.addrsig_sym "?I@@3HA"
diff --git a/test/ELF/Inputs/gdb-index-invalid-ranges.obj.s b/test/ELF/Inputs/gdb-index-invalid-ranges.obj.s
new file mode 100644
index 0000000..d7e0bd2
--- /dev/null
+++ b/test/ELF/Inputs/gdb-index-invalid-ranges.obj.s
@@ -0,0 +1,2 @@
+main:
+  callq f1
diff --git a/test/ELF/Inputs/gnu-ifunc-canon-ro-abs.s b/test/ELF/Inputs/gnu-ifunc-canon-ro-abs.s
new file mode 100644
index 0000000..3c09bd6
--- /dev/null
+++ b/test/ELF/Inputs/gnu-ifunc-canon-ro-abs.s
@@ -0,0 +1,2 @@
+.rodata
+.8byte ifunc
diff --git a/test/ELF/Inputs/gnu-ifunc-canon-ro-pcrel.s b/test/ELF/Inputs/gnu-ifunc-canon-ro-pcrel.s
new file mode 100644
index 0000000..c173d3d
--- /dev/null
+++ b/test/ELF/Inputs/gnu-ifunc-canon-ro-pcrel.s
@@ -0,0 +1,2 @@
+.rodata
+.4byte ifunc - .
diff --git a/test/ELF/Inputs/gnu-ifunc-canon-rw-addend.s b/test/ELF/Inputs/gnu-ifunc-canon-rw-addend.s
new file mode 100644
index 0000000..7f369d3
--- /dev/null
+++ b/test/ELF/Inputs/gnu-ifunc-canon-rw-addend.s
@@ -0,0 +1,2 @@
+.data
+.8byte ifunc + 1
diff --git a/test/ELF/Inputs/i386-static-tls-model1.s b/test/ELF/Inputs/i386-static-tls-model1.s
new file mode 100644
index 0000000..d287fb6
--- /dev/null
+++ b/test/ELF/Inputs/i386-static-tls-model1.s
@@ -0,0 +1,9 @@
+.section ".tdata", "awT", @progbits
+.globl var
+var:
+
+.section .foo, "aw"
+.global _start
+_start:
+ movl $var@tpoff, %edx # R_386_TLS_LE_32
+ movl %gs:0, %ecx
diff --git a/test/ELF/Inputs/i386-static-tls-model2.s b/test/ELF/Inputs/i386-static-tls-model2.s
new file mode 100644
index 0000000..2c01cee
--- /dev/null
+++ b/test/ELF/Inputs/i386-static-tls-model2.s
@@ -0,0 +1,9 @@
+.section ".tdata", "awT", @progbits
+.globl var
+var:
+
+.section .foo, "aw"
+.global _start
+_start: 
+ movl %gs:0, %eax
+ addl var@gotntpoff(%ebx), %eax # R_386_TLS_GOTIE
diff --git a/test/ELF/Inputs/i386-static-tls-model3.s b/test/ELF/Inputs/i386-static-tls-model3.s
new file mode 100644
index 0000000..fd18fce
--- /dev/null
+++ b/test/ELF/Inputs/i386-static-tls-model3.s
@@ -0,0 +1,9 @@
+.section ".tdata", "awT", @progbits
+.globl var
+var:
+
+.section .foo, "aw"
+.global _start
+_start:
+ movl %gs:0, %eax
+ addl var@indntpoff, %eax # R_386_TLS_IE
diff --git a/test/ELF/Inputs/i386-static-tls-model4.s b/test/ELF/Inputs/i386-static-tls-model4.s
new file mode 100644
index 0000000..6006518
--- /dev/null
+++ b/test/ELF/Inputs/i386-static-tls-model4.s
@@ -0,0 +1,9 @@
+.section ".tdata", "awT", @progbits
+.globl var
+var:
+
+.section .foo, "aw"
+.global _start
+_start:
+ movl %gs:0, %eax
+ leal var@ntpoff(%eax), %eax # R_386_TLS_LE
diff --git a/test/ELF/Inputs/ppc64-sort-small-cm-relocs-input2.s b/test/ELF/Inputs/ppc64-sort-small-cm-relocs-input2.s
new file mode 100644
index 0000000..b903f9b
--- /dev/null
+++ b/test/ELF/Inputs/ppc64-sort-small-cm-relocs-input2.s
@@ -0,0 +1,23 @@
+    .text
+
+    .global set
+    .type set,@function
+set:
+.Lgep:
+    addis 2, 12, .TOC.-.Lgep@ha
+    addi 2, 2, .TOC.-.Lgep@l
+.Llep:
+    .localentry	set, .Llep-.Lgep
+    addis 5, 2, .LC0@toc@ha
+    addis 6, 2, .LC1@toc@ha
+    ld 5, .LC0@toc@l(5)
+    ld 6, .LC1@toc@l(6)
+    stw 3, 0(5)
+    stw 4, 0(6)
+    blr
+
+    .section .toc,"aw",@progbits
+.LC0:
+    .tc c[TC],c
+.LC1:
+    .tc d[TC],d
diff --git a/test/ELF/Inputs/ppc64-sort-small-cm-relocs-input3.s b/test/ELF/Inputs/ppc64-sort-small-cm-relocs-input3.s
new file mode 100644
index 0000000..733bbb3
--- /dev/null
+++ b/test/ELF/Inputs/ppc64-sort-small-cm-relocs-input3.s
@@ -0,0 +1,41 @@
+    .text
+    .global getA
+    .type getA,@function
+getA:
+.LgepA:
+    addis 2, 12, .TOC.-.LgepA@ha
+    addi 2, 2, .TOC.-.LgepA@l
+.LlepA:
+    .localentry getA, .LlepA-.LgepA
+    ld 3, .LC0@toc(2)
+    lwa 3, 0(3)
+    blr
+
+    .global getB
+    .type getB,@function
+getB:
+.LgepB:
+    addis 2, 12, .TOC.-.LgepB@ha
+    addi 2, 2, .TOC.-.LgepB@l
+.LlepB:
+    .localentry getB, .LlepB-.LgepB
+    ld 3, .LC1@toc(2)
+    lwa 3, 0(3)
+    blr
+
+    .section .toc,"aw",@progbits
+.LC0:
+    .tc a[TC],a
+.LConst1:
+    .quad 0xa
+.LC1:
+    .tc b[TC],b
+.Lconst2:
+    .quad 0xaabbccddeeff
+
+    .type b,@object
+    .data
+    .global b
+b:
+    .long 22
+    .size b, 4
diff --git a/test/ELF/Inputs/ppc64-sort-small-cm-relocs-input4.s b/test/ELF/Inputs/ppc64-sort-small-cm-relocs-input4.s
new file mode 100644
index 0000000..90f6e0f
--- /dev/null
+++ b/test/ELF/Inputs/ppc64-sort-small-cm-relocs-input4.s
@@ -0,0 +1,18 @@
+    .text
+    .global getRodata
+    .type getRodata,@function
+getRodata:
+.Lgep:
+    addis 2, 12, .TOC.-.Lgep@ha
+    addi 2, 2, .TOC.-.Lgep@l
+.Llep:
+    .localentry     getRodata, .Llep-.Lgep
+    lwa 3, .LC0@toc(2)
+    blr
+
+    .section        .rodata,"aMS",@progbits,8
+    .quad _start
+
+    .section        .toc,"aw",@progbits
+.LC0:
+    .tc .rodata[TC], .rodata
diff --git a/test/ELF/Inputs/print-icf.s b/test/ELF/Inputs/print-icf.s
index a67bee2..df9bcbc 100644
--- a/test/ELF/Inputs/print-icf.s
+++ b/test/ELF/Inputs/print-icf.s
@@ -1,9 +1,9 @@
-.section .text.f6, "ax"

-f6:

-  mov $60, %rax

-  mov $42, %rdi

-  syscall

-

-  .section .text.f7, "ax"

-f7:

-  mov $0, %rax

+.section .text.f6, "ax"
+f6:
+  mov $60, %rax
+  mov $42, %rdi
+  syscall
+
+  .section .text.f7, "ax"
+f7:
+  mov $0, %rax
diff --git a/test/ELF/Inputs/wrap-with-archive.s b/test/ELF/Inputs/wrap-with-archive.s
new file mode 100644
index 0000000..93aaddc
--- /dev/null
+++ b/test/ELF/Inputs/wrap-with-archive.s
@@ -0,0 +1,5 @@
+.global __executable_start
+.global __wrap_get_executable_start
+
+__wrap_get_executable_start:	
+	movabs $__executable_start,%rdx
diff --git a/test/ELF/Inputs/x86-64-pcrel.s b/test/ELF/Inputs/x86-64-pcrel.s
new file mode 100644
index 0000000..dea824a
--- /dev/null
+++ b/test/ELF/Inputs/x86-64-pcrel.s
@@ -0,0 +1,8 @@
+.globl foo
+foo:
+
+.word _start - foo
+.fill 14,1,0xcc
+
+.byte _start - foo
+.fill 15,1,0xcc
diff --git a/test/ELF/aarch64-cortex-a53-843419-tlsrelax.s b/test/ELF/aarch64-cortex-a53-843419-tlsrelax.s
index bff72d3..2db5c7e 100644
--- a/test/ELF/aarch64-cortex-a53-843419-tlsrelax.s
+++ b/test/ELF/aarch64-cortex-a53-843419-tlsrelax.s
@@ -26,9 +26,9 @@
 // CHECK: _start:
 // CHECK-NEXT:   210ff8:        41 d0 3b d5     mrs     x1, TPIDR_EL0
 // CHECK-NEXT:   210ffc:        00 00 a0 d2     movz    x0, #0, lsl #16
-// CHECK-NEXT:   211000:        01 02 80 f2     movk    x1, #16
+// CHECK-NEXT:   211000:        01 08 80 f2     movk    x1, #64
 // CHECK-NEXT:   211004:        00 00 a0 d2     movz    x0, #0, lsl #16
-// CHECK-NEXT:   211008:        01 02 80 f2     movk    x1, #16
+// CHECK-NEXT:   211008:        01 08 80 f2     movk    x1, #64
 // CHECK-NEXT:   21100c:        c0 03 5f d6     ret
 
  .type  v,@object
diff --git a/test/ELF/aarch64-gnu-ifunc-address-pie.s b/test/ELF/aarch64-gnu-ifunc-address-pie.s
new file mode 100644
index 0000000..53cede9
--- /dev/null
+++ b/test/ELF/aarch64-gnu-ifunc-address-pie.s
@@ -0,0 +1,47 @@
+# REQUIRES: aarch64
+# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
+# RUN: ld.lld -pie %t.o -o %tout
+# RUN: llvm-objdump -D %tout | FileCheck %s
+# RUN: llvm-readobj -r %tout | FileCheck %s -check-prefix=CHECK-RELOCS
+
+# Test that when we take the address of a preemptible ifunc using -fpie, we can
+# handle the case when the ifunc is in the same translation unit as the address
+# taker. In this case the compiler knows that ifunc is not defined in a shared
+# library so it can use a non got generating relative reference.
+.text
+.globl myfunc
+.type myfunc,@gnu_indirect_function
+myfunc:
+.globl myfunc_resolver
+.type myfunc_resolver,@function
+myfunc_resolver:
+ ret
+
+.text
+.globl main
+.type main,@function
+main:
+ adrp x8, myfunc
+ add  x8, x8, :lo12: myfunc
+ ret
+
+# CHECK: 0000000000010000 myfunc_resolver:
+# CHECK-NEXT:    10000:	c0 03 5f d6 	ret
+# CHECK: 0000000000010004 main:
+# CHECK-NEXT:    10004:	08 00 00 90 	adrp	x8, #0
+# x8 = 0x10000
+# CHECK-NEXT:    10008:	08 41 00 91 	add	x8, x8, #16
+# x8 = 0x10010 = .plt for myfunc
+# CHECK-NEXT:    1000c:	c0 03 5f d6 	ret
+# CHECK-NEXT: Disassembly of section .plt:
+# CHECK-NEXT: 0000000000010010 myfunc:
+# CHECK-NEXT:    10010:	90 00 00 90 	adrp	x16, #65536
+# CHECK-NEXT:    10014:	11 02 40 f9 	ldr	x17, [x16]
+# CHECK-NEXT:    10018:	10 02 00 91 	add	x16, x16, #0
+# CHECK-NEXT:    1001c:	20 02 1f d6 	br	x17
+
+# CHECK-RELOCS: Relocations [
+# CHECK-RELOCS-NEXT:   Section {{.*}} .rela.plt {
+# CHECK-RELOCS-NEXT:     0x20000 R_AARCH64_IRELATIVE - 0x10000
+# CHECK-RELOCS-NEXT:   }
+# CHECK-RELOCS-NEXT: ]
diff --git a/test/ELF/aarch64-gnu-ifunc-address.s b/test/ELF/aarch64-gnu-ifunc-address.s
new file mode 100644
index 0000000..e0e4daf
--- /dev/null
+++ b/test/ELF/aarch64-gnu-ifunc-address.s
@@ -0,0 +1,37 @@
+# REQUIRES: aarch64
+# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
+# RUN: ld.lld -shared %t.o -o %tout
+# RUN: llvm-objdump -D %tout | FileCheck %s
+# RUN: llvm-readobj -r %tout | FileCheck %s --check-prefix=CHECK-RELOCS
+
+# Test that when we take the address of a preemptible ifunc in a shared object
+# we get R_AARCH64_GLOB_DAT to the symbol as it could be defined in another
+# link unit and preempt our definition.
+.text
+.globl myfunc
+.type myfunc,@gnu_indirect_function
+myfunc:
+ ret
+
+.text
+.globl main
+.type main,@function
+main:
+ adrp x8, :got:myfunc
+ ldr  x8, [x8, :got_lo12:myfunc]
+ ret
+# CHECK:   0000000000010004 main:
+# x8 = 0x20000
+# CHECK-NEXT:    10004: 88 00 00 90     adrp    x8, #65536
+# x8 = 0x200a0 = .got entry for myfunc with R_AARCH64_GLOB_DAT
+# CHECK-NEXT:    10008: 08 51 40 f9     ldr     x8, [x8, #160]
+# CHECK-NEXT:    1000c: c0 03 5f d6     ret
+
+# CHECK: Disassembly of section .got:
+# CHECK-NEXT: 00000000000200a0 .got:
+
+# CHECK-RELOCS: Relocations [
+# CHECK-RELOCS-NEXT:   Section {{.*}} .rela.dyn {
+# CHECK-RELOCS-NEXT:     0x200A0 R_AARCH64_GLOB_DAT myfunc 0x0
+# CHECK-RELOCS-NEXT:   }
+# CHECK-RELOCS-NEXT: ]
diff --git a/test/ELF/aarch64-gnu-ifunc2.s b/test/ELF/aarch64-gnu-ifunc2.s
index 2caff3f..f83a3b3 100644
--- a/test/ELF/aarch64-gnu-ifunc2.s
+++ b/test/ELF/aarch64-gnu-ifunc2.s
@@ -9,8 +9,8 @@
 # CHECK-NEXT:   210000:
 
 # CHECK:      main:
-# adrp x8, 0x230000, 0x230000 == address in .got
-# CHECK-NEXT:   210004: {{.*}} adrp    x8, #131072
+# adrp x8, 0x220000, 0x220000 == address in .got.plt
+# CHECK-NEXT:   210004: {{.*}} adrp    x8, #65536
 # CHECK-NEXT:   210008: {{.*}} ldr     x8, [x8]
 # CHECK-NEXT:   21000c: {{.*}} ret
 
@@ -26,11 +26,6 @@
 # CHECK-NEXT: .got.plt:
 # CHECK-NEXT:   220000:
 
-# CHECK:      Disassembly of section .got:
-# CHECK-NEXT: .got:
-# 0x210010 == address in .plt
-# CHECK-NEXT:   230000: 10 00 21 00
-
 # RELOC:      Relocations [
 # RELOC-NEXT:   Section {{.*}} .rela.plt {
 # RELOC-NEXT:     0x220000 R_AARCH64_IRELATIVE - 0x210000
diff --git a/test/ELF/aarch64-gnu-ifunc3.s b/test/ELF/aarch64-gnu-ifunc3.s
index 11d5631..5d863e2 100644
--- a/test/ELF/aarch64-gnu-ifunc3.s
+++ b/test/ELF/aarch64-gnu-ifunc3.s
@@ -11,6 +11,9 @@
 .globl myfunc
 .type myfunc,@gnu_indirect_function
 myfunc:
+.globl myfunc_resolver
+.type myfunc_resolver,@function
+myfunc_resolver:
  ret
 
 .text
@@ -22,7 +25,7 @@
  ret
 
 # CHECK: Disassembly of section .text:
-# CHECK-NEXT: myfunc:
+# CHECK-NEXT: myfunc_resolver:
 # CHECK-NEXT:   210000:	c0 03 5f d6 	ret
 # CHECK: _start:
 # adrp x8, 0x210000 + 0x10 from add == .plt entry
@@ -30,7 +33,7 @@
 # CHECK-NEXT:   210008:	08 41 00 91 	add	x8, x8, #16
 # CHECK-NEXT:   21000c:	c0 03 5f d6 	ret
 # CHECK-NEXT: Disassembly of section .plt:
-# CHECK-NEXT: .plt:
+# CHECK-NEXT: myfunc:
 # adrp x16, 0x220000, 0x220000 == address in .got.plt
 # CHECK-NEXT:   210010:	90 00 00 90 	adrp	x16, #65536
 # CHECK-NEXT:   210014:	11 02 40 f9 	ldr	x17, [x16]
diff --git a/test/ELF/aarch64-tls-gdle.s b/test/ELF/aarch64-tls-gdle.s
index e91d397..882ec8c 100644
--- a/test/ELF/aarch64-tls-gdle.s
+++ b/test/ELF/aarch64-tls-gdle.s
@@ -5,15 +5,15 @@
 # RUN: llvm-objdump -d %tout | FileCheck %s
 # RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s
 
-#Local-Dynamic to Initial-Exec relax creates no
+#Local-Dynamic to Local-Exec relax creates no
 #RELOC:      Relocations [
 #RELOC-NEXT: ]
 
-# TCB size = 0x16 and foo is first element from TLS register.
+# TCB size = 64 and foo is first element from TLS register.
 # CHECK: Disassembly of section .text:
 # CHECK: _start:
 # CHECK:  210000:	00 00 a0 d2	movz	x0, #0, lsl #16
-# CHECK:  210004:	00 02 80 f2 	movk	x0, #16
+# CHECK:  210004:	00 08 80 f2 	movk	x0, #64
 # CHECK:  210008:	1f 20 03 d5 	nop
 # CHECK:  21000c:	1f 20 03 d5 	nop
 
diff --git a/test/ELF/aarch64-tls-iele.s b/test/ELF/aarch64-tls-iele.s
index 9fec4ee..0229d66 100644
--- a/test/ELF/aarch64-tls-iele.s
+++ b/test/ELF/aarch64-tls-iele.s
@@ -9,13 +9,13 @@
 # RELOC:      Relocations [
 # RELOC-NEXT: ]
 
-# TCB size = 0x16 and foo is first element from TLS register.
+# TCB size = 64 and foo is first element from TLS register.
 # CHECK: Disassembly of section .text:
 # CHECK: _start:
 # CHECK-NEXT: 210000:  00 00 a0 d2   movz   x0, #0, lsl #16
-# CHECK-NEXT: 210004:  80 02 80 f2   movk   x0, #20
+# CHECK-NEXT: 210004:  80 08 80 f2   movk   x0, #68
 # CHECK-NEXT: 210008:  00 00 a0 d2   movz   x0, #0, lsl #16
-# CHECK-NEXT: 21000c:  00 02 80 f2   movk   x0, #16
+# CHECK-NEXT: 21000c:  00 08 80 f2   movk   x0, #64
 
 .section .tdata
 .align 2
diff --git a/test/ELF/aarch64-tls-le.s b/test/ELF/aarch64-tls-le.s
index 85cd3be..49c322f 100644
--- a/test/ELF/aarch64-tls-le.s
+++ b/test/ELF/aarch64-tls-le.s
@@ -4,7 +4,7 @@
 # RUN: llvm-objdump -d %tout | FileCheck %s
 # RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s
 
-#Local-Dynamic to Initial-Exec relax creates no
+#Local-Dynamic to Local-Exec relax creates no
 #RELOC:      Relocations [
 #RELOC-NEXT: ]
 
@@ -17,12 +17,12 @@
  add x0, x0, :tprel_hi12:v2
  add x0, x0, :tprel_lo12_nc:v2
 
-# TCB size = 0x16 and foo is first element from TLS register.
+# TCB size = 64 and foo is first element from TLS register.
 #CHECK: Disassembly of section .text:
 #CHECK: _start:
 #CHECK:  210000: 40 d0 3b d5     mrs     x0, TPIDR_EL0
 #CHECK:  210004: 00 00 40 91     add     x0, x0, #0, lsl #12
-#CHECK:  210008: 00 40 00 91     add     x0, x0, #16
+#CHECK:  210008: 00 00 01 91     add     x0, x0, #64
 #CHECK:  21000c: 40 d0 3b d5     mrs     x0, TPIDR_EL0
 #CHECK:  210010: 00 fc 7f 91     add     x0, x0, #4095, lsl #12
 #CHECK:  210014: 00 e0 3f 91     add     x0, x0, #4088
@@ -36,9 +36,9 @@
 .word  0
 .size  v1, 4
 
-# The current offset from the thread pointer is 20. Raise it to just below the
+# The current offset from the thread pointer is 68. Raise it to just below the
 # 24-bit limit.
-.space (0xfffff8 - 20)
+.space (0xfffff8 - 68)
 
 .type   v2,@object
 .globl  v2
diff --git a/test/ELF/aarch64-tlsld-ldst.s b/test/ELF/aarch64-tlsld-ldst.s
index 3144ca5..8ebdc2f 100644
--- a/test/ELF/aarch64-tlsld-ldst.s
+++ b/test/ELF/aarch64-tlsld-ldst.s
@@ -26,27 +26,27 @@
 
 // CHECK: _start:
 // CHECK-NEXT:    210000:       48 d0 3b d5     mrs     x8, TPIDR_EL0
-// 0x0 + c10 = 0xc10       = tcb (16-bytes) + var0
-// CHECK-NEXT:    210004:       08 01 40 91     add     x8, x8, #0, lsl #12
-// CHECK-NEXT:    210008:       14 05 c3 3d     ldr     q20, [x8, #3088]
-// 0x1000 + 0x820 = 0x1820 = tcb + var1
-// CHECK-NEXT:    21000c:       08 05 40 91     add     x8, x8, #1, lsl #12
-// CHECK-NEXT:    210010:       00 11 44 f9     ldr     x0, [x8, #2080]
-// 0x2000 + 0x428 = 0x2428 = tcb + var2
-// CHECK-NEXT:    210014:       08 09 40 91     add     x8, x8, #2, lsl #12
-// CHECK-NEXT:    210018:       00 29 44 b9     ldr     w0, [x8, #1064]
-// 0x3000 + 0x2c  = 0x302c = tcb + var3
-// CHECK-NEXT:    21001c:       08 0d 40 91     add     x8, x8, #3, lsl #12
-// CHECK-NEXT:    210020:       00 59 40 79     ldrh    w0, [x8, #44]
-// 0x3000 + 0xc2e = 0x32ce = tcb + var4
-// CHECK-NEXT:    210024:       08 0d 40 91     add     x8, x8, #3, lsl #12
-// CHECK-NEXT:    210028:       00 b9 70 39     ldrb    w0, [x8, #3118]
+// 0x0 + c40 = 0xc40       = tcb (64-bytes) + var0
+// CHECK-NEXT:    210004:       08 01 40 91     add x8, x8, #0, lsl #12
+// CHECK-NEXT:    210008:       14 11 c3 3d     ldr q20, [x8, #3136]
+// 0x1000 + 0x850 = 0x1850 = tcb + var1
+// CHECK-NEXT:    21000c:       08 05 40 91     add x8, x8, #1, lsl #12
+// CHECK-NEXT:    210010:       00 29 44 f9     ldr x0, [x8, #2128]
+// 0x2000 + 0x458 = 0x2458 = tcb + var2
+// CHECK-NEXT:    210014:       08 09 40 91     add x8, x8, #2, lsl #12
+// CHECK-NEXT:    210018:       00 59 44 b9     ldr w0, [x8, #1112]
+// 0x3000 + 0x5c  = 0x305c = tcb + var3
+// CHECK-NEXT:    21001c:       08 0d 40 91     add x8, x8, #3, lsl #12
+// CHECK-NEXT:    210020:       00 b9 40 79     ldrh  w0, [x8, #92]
+// 0x3000 + 0xc5e = 0x3c5e = tcb + var4
+// CHECK-NEXT:    210024:       08 0d 40 91     add x8, x8, #3, lsl #12
+// CHECK-NEXT:    210028:       00 79 71 39     ldrb  w0, [x8, #3166]
 
-// CHECK-SYMS:      0000000000000c00     0 TLS     GLOBAL DEFAULT    2 var0
-// CHECK-SYMS-NEXT: 0000000000001810     4 TLS     GLOBAL DEFAULT    2 var1
-// CHECK-SYMS-NEXT: 0000000000002418     2 TLS     GLOBAL DEFAULT    2 var2
-// CHECK-SYMS-NEXT: 000000000000301c     1 TLS     GLOBAL DEFAULT    2 var3
-// CHECK-SYMS-NEXT: 0000000000003c1e     0 TLS     GLOBAL DEFAULT    2 var4
+// CHECK-SYMS:      0000000000000c00    16 TLS     GLOBAL DEFAULT    2 var0
+// CHECK-SYMS-NEXT: 0000000000001810     8 TLS     GLOBAL DEFAULT    2 var1
+// CHECK-SYMS-NEXT: 0000000000002418     4 TLS     GLOBAL DEFAULT    2 var2
+// CHECK-SYMS-NEXT: 000000000000301c     2 TLS     GLOBAL DEFAULT    2 var3
+// CHECK-SYMS-NEXT: 0000000000003c1e     1 TLS     GLOBAL DEFAULT    2 var4
 
         .globl var0
         .globl var1
@@ -59,12 +59,12 @@
         .type var3,@object
 
 .section .tbss,"awT",@nobits
-        .balign 16
+        .balign 64
         .space 1024 * 3
 var0:
         .quad 0
         .quad 0
-        .size var1, 16
+        .size var0, 16
         .space 1024 * 3
 var1:
         .quad 0
@@ -72,14 +72,14 @@
         .space 1024 * 3
 var2:
         .word 0
-        .size var1, 4
+        .size var2, 4
 
         .space 1024 * 3
 var3:
         .hword 0
-        .size var2, 2
+        .size var3, 2
         .space 1024 * 3
 var4:
         .byte 0
-        .size var3, 1
+        .size var4, 1
         .space 1024 * 3
diff --git a/test/ELF/allow-shlib-undefined.s b/test/ELF/allow-shlib-undefined.s
index abb0351..5b09681 100644
--- a/test/ELF/allow-shlib-undefined.s
+++ b/test/ELF/allow-shlib-undefined.s
@@ -1,26 +1,30 @@
 # REQUIRES: x86
-# --allow-shlib-undefined and --no-allow-shlib-undefined are fully
-# ignored in linker implementation.
-# --allow-shlib-undefined is set by default
-# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
-# RUN: %p/Inputs/allow-shlib-undefined.s -o %t
-# RUN: ld.lld -shared %t -o %t.so
-# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
 
-# Executable: should link with DSO containing undefined symbols in any case.
-# RUN: ld.lld %t1 %t.so -o %t2
-# RUN: ld.lld --no-allow-shlib-undefined %t1 %t.so -o %t2
-# RUN: ld.lld --allow-shlib-undefined %t1 %t.so -o %t2
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
+# RUN:   %p/Inputs/allow-shlib-undefined.s -o %t1.o
+# RUN: ld.lld -shared %t1.o -o %t.so
+
+# RUN: ld.lld --allow-shlib-undefined %t.o %t.so -o /dev/null
+# RUN: not ld.lld --no-allow-shlib-undefined %t.o %t.so -o /dev/null 2>&1 | FileCheck %s
+# Executable defaults to --no-allow-shlib-undefined
+# RUN: not ld.lld %t.o %t.so -o /dev/null 2>&1 | FileCheck %s
+# -shared defaults to --allow-shlib-undefined
+# RUN: ld.lld -shared %t.o %t.so -o /dev/null
+
+# RUN: echo | llvm-mc -filetype=obj -triple=x86_64-unknown-linux -o %tempty.o
+# RUN: ld.lld -shared %tempty.o -o %tempty.so
+# RUN: ld.lld -shared %t1.o %tempty.so -o %t2.so
+# RUN: ld.lld --no-allow-shlib-undefined %t.o %t2.so -o /dev/null
 
 # DSO with undefines:
 # should link with or without any of these options.
-# RUN: ld.lld -shared %t -o %t.so
-# RUN: ld.lld -shared --allow-shlib-undefined %t -o %t.so
-# RUN: ld.lld -shared --no-allow-shlib-undefined %t -o %t.so
-
-# Executable still should not link when have undefines inside.
-# RUN: not ld.lld %t -o %t.so
+# RUN: ld.lld -shared %t1.o -o /dev/null
+# RUN: ld.lld -shared --allow-shlib-undefined %t1.o -o /dev/null
+# RUN: ld.lld -shared --no-allow-shlib-undefined %t1.o -o /dev/null
 
 .globl _start
 _start:
   callq _shared@PLT
+
+# CHECK: undefined reference to _unresolved
diff --git a/test/ELF/archive-thin-missing-member.s b/test/ELF/archive-thin-missing-member.s
new file mode 100644
index 0000000..d96fbc4
--- /dev/null
+++ b/test/ELF/archive-thin-missing-member.s
@@ -0,0 +1,24 @@
+# REQUIRES: x86
+
+# RUN: rm -f %t-no-syms.a
+# RUN: rm -f %t-syms.a
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: llvm-ar rcTS %t-no-syms.a %t.o
+# RUN: llvm-ar rcT %t-syms.a %t.o
+# RUN: rm %t.o
+
+# Test error when loading symbols from missing thin archive member.
+# RUN: not ld.lld %t-no-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR1
+# ERR1: {{.*}}-no-syms.a: could not get the buffer for a child of the archive: '{{.*}}.o': {{[Nn]}}o such file or directory
+
+# Test error when thin archive has symbol table but member is missing.
+# RUN: not ld.lld -m elf_amd64_fbsd %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2
+# ERR2: {{.*}}-syms.a: could not get the buffer for the member defining symbol _start: '{{.*}}.o': {{[Nn]}}o such file or directory
+
+# Test error when thin archive is linked using --whole-archive but member is missing.
+# RUN: not ld.lld --whole-archive %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR3
+# ERR3: {{.*}}-syms.a: could not get the buffer for a child of the archive: '{{.*}}.o': {{[Nn]}}o such file or directory
+
+.global _start
+_start:
+    nop
diff --git a/test/ELF/arm-extreme-range-pi-thunk.s b/test/ELF/arm-extreme-range-pi-thunk.s
new file mode 100644
index 0000000..5daf388
--- /dev/null
+++ b/test/ELF/arm-extreme-range-pi-thunk.s
@@ -0,0 +1,82 @@
+// REQUIRES: arm
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: echo "SECTIONS {" > %t.script
+// RUN: echo "          .text_low 0x130 : { *(.text) }" >> %t.script
+// RUN: echo "          .text_high 0xf0000000 : AT(0x1000) { *(.text_high) }" >> %t.script
+// RUN: echo "       } " >> %t.script
+// RUN: ld.lld --script %t.script --pie --static %t -o %t2 2>&1
+// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s
+
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t3
+// RUN: ld.lld --script %t.script --pie %t3 -o %t4 2>&1
+// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t4 | FileCheck -check-prefix=CHECK-THUMB %s
+
+// Check that we can create Arm and Thumb v7a Position Independent Thunks that
+// can span the address space without triggering overflow errors. We use an
+// AT(0x1000) for .text_high to avoid creating an almost 4Gb size file.
+ .syntax unified
+ .text
+ .global _start
+ .type _start, %function
+_start:
+ bl high
+ bx lr
+
+ .section .text_high, "ax", %progbits
+ .global high
+ .type high, %function
+high:
+ bl _start
+ bx lr
+
+// ARMv7a instructions and relocations.
+
+// CHECK: Disassembly of section .text_low:
+// CHECK-NEXT: _start:
+// CHECK-NEXT:      130:        00 00 00 eb     bl      #0 <__ARMV7PILongThunk_high>
+// CHECK-NEXT:      134:        1e ff 2f e1     bx      lr
+
+// CHECK: __ARMV7PILongThunk_high:
+// CHECK-NEXT:      138:        b8 ce 0f e3     movw    r12, #65208
+// CHECK-NEXT:      13c:        ff cf 4e e3     movt    r12, #61439
+// 0x140 + 0xEFFF0000 + 0x0000FEB8 + 8 = 0xf0000000 = high
+// CHECK-NEXT:      140:        0f c0 8c e0     add     r12, r12, pc
+// CHECK-NEXT:      144:        1c ff 2f e1     bx      r12
+
+// CHECK: Disassembly of section .text_high:
+// CHECK-NEXT: high:
+// CHECK-NEXT: f0000000:        00 00 00 eb     bl      #0 <__ARMV7PILongThunk__start>
+// CHECK-NEXT: f0000004:        1e ff 2f e1     bx      lr
+
+// CHECK: __ARMV7PILongThunk__start:
+// CHECK-NEXT: f0000008:        18 c1 00 e3     movw    r12, #280
+// CHECK-NEXT: f000000c:        00 c0 41 e3     movt    r12, #4096
+// 0xf0000010 + 0x10000000 + 0x0000118 + 8 = bits32(0x100000130),0x130 = _start
+// CHECK-NEXT: f0000010:        0f c0 8c e0     add     r12, r12, pc
+// CHECK-NEXT: f0000014:        1c ff 2f e1     bx      r12
+
+// Thumbv7a instructions and relocations
+// CHECK-THUMB: Disassembly of section .text_low:
+// CHECK-THUMB-NEXT: _start:
+// CHECK-THUMB-NEXT:      130:  00 f0 02 f8     bl      #4
+// CHECK-THUMB-NEXT:      134:  70 47   bx      lr
+// CHECK-THUMB-NEXT:      136:  d4 d4   bmi     #-88
+
+// CHECK-THUMB: __ThumbV7PILongThunk_high:
+// CHECK-THUMB-NEXT:      138:  4f f6 bd 6c     movw    r12, #65213
+// CHECK-THUMB-NEXT:      13c:  ce f6 ff 7c     movt    r12, #61439
+// 0x140 + 0xEFFF0000 + 0x0000FEBD + 4 = 0xf0000001 = high
+// CHECK-THUMB-NEXT:      140:  fc 44   add     r12, pc
+// CHECK-THUMB-NEXT:      142:  60 47   bx      r12
+
+// CHECK-THUMB: Disassembly of section .text_high:
+// CHECK-THUMB-NEXT: high:
+// CHECK-THUMB-NEXT: f0000000:  00 f0 02 f8     bl      #4
+// CHECK-THUMB-NEXT: f0000004:  70 47   bx      lr
+
+// CHECK-THUMB: __ThumbV7PILongThunk__start:
+// CHECK-THUMB-NEXT: f0000008:  40 f2 1d 1c     movw    r12, #285
+// CHECK-THUMB-NEXT: f000000c:  c1 f2 00 0c     movt    r12, #4096
+// 0xf0000010 + 0x10000000 + 0x000011d +4 = bits32(0x100000131),0x131 = _start
+// CHECK-THUMB-NEXT: f0000010:  fc 44   add     r12, pc
+// CHECK-THUMB-NEXT: f0000012:  60 47   bx      r12
diff --git a/test/ELF/arm-force-pi-thunk.s b/test/ELF/arm-force-pi-thunk.s
new file mode 100644
index 0000000..2c88de0
--- /dev/null
+++ b/test/ELF/arm-force-pi-thunk.s
@@ -0,0 +1,87 @@
+// REQUIRES: arm
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: echo "SECTIONS { \
+// RUN:       . = SIZEOF_HEADERS; \
+// RUN:       .text_low : { *(.text_low) *(.text_low2) } \
+// RUN:       .text_high 0x2000000 : { *(.text_high) *(.text_high2) } \
+// RUN:       } " > %t.script
+// RUN: ld.lld --pic-veneer --script %t.script %t -o %t2 2>&1
+// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck %s
+
+// Test that we can force generation of position independent thunks even when
+// inputs are not pic.
+
+ .syntax unified
+ .section .text_low, "ax", %progbits
+ .thumb
+ .globl _start
+_start: bx lr
+ .globl low_target
+ .type low_target, %function
+low_target:
+ bl high_target
+ bl high_target2
+
+ .section .text_low2, "ax", %progbits
+ .thumb
+ .globl low_target2
+ .type low_target2, %function
+low_target2:
+ bl high_target
+ bl high_target2
+
+// CHECK: Disassembly of section .text_low:
+// CHECK-NEXT: _start:
+// CHECK-NEXT:       94:        70 47   bx      lr
+// CHECK: low_target:
+// CHECK-NEXT:       96:        00 f0 03 f8     bl      #6
+// CHECK-NEXT:       9a:        00 f0 07 f8     bl      #14
+// CHECK-NEXT:       9e:        d4 d4   bmi     #-88
+// CHECK: __ThumbV7PILongThunk_high_target:
+// CHECK-NEXT:       a0:        4f f6 55 7c     movw    r12, #65365
+// CHECK-NEXT:       a4:        c0 f2 ff 1c     movt    r12, #511
+// CHECK-NEXT:       a8:        fc 44   add     r12, pc
+// CHECK-NEXT:       aa:        60 47   bx      r12
+// CHECK: __ThumbV7PILongThunk_high_target2:
+// CHECK-NEXT:       ac:        4f f6 69 7c     movw    r12, #65385
+// CHECK-NEXT:       b0:        c0 f2 ff 1c     movt    r12, #511
+// CHECK-NEXT:       b4:        fc 44   add     r12, pc
+// CHECK-NEXT:       b6:        60 47   bx      r12
+// CHECK: low_target2:
+// CHECK-NEXT:       b8:        ff f7 f2 ff     bl      #-28
+// CHECK-NEXT:       bc:        ff f7 f6 ff     bl      #-20
+
+
+ .section .text_high, "ax", %progbits
+ .thumb
+ .globl high_target
+ .type high_target, %function
+high_target:
+ bl low_target
+ bl low_target2
+
+ .section .text_high2, "ax", %progbits
+ .thumb
+ .globl high_target2
+ .type high_target2, %function
+high_target2:
+ bl low_target
+ bl low_target2
+
+// CHECK: Disassembly of section .text_high:
+// CHECK-NEXT: high_target:
+// CHECK-NEXT:  2000000:        00 f0 02 f8     bl      #4
+// CHECK-NEXT:  2000004:        00 f0 06 f8     bl      #12
+// CHECK: __ThumbV7PILongThunk_low_target:
+// CHECK-NEXT:  2000008:        40 f2 83 0c     movw    r12, #131
+// CHECK-NEXT:  200000c:        cf f6 00 6c     movt    r12, #65024
+// CHECK-NEXT:  2000010:        fc 44   add     r12, pc
+// CHECK-NEXT:  2000012:        60 47   bx      r12
+// CHECK: __ThumbV7PILongThunk_low_target2:
+// CHECK-NEXT:  2000014:        40 f2 99 0c     movw    r12, #153
+// CHECK-NEXT:  2000018:        cf f6 00 6c     movt    r12, #65024
+// CHECK-NEXT:  200001c:        fc 44   add     r12, pc
+// CHECK-NEXT:  200001e:        60 47   bx      r12
+// CHECK: high_target2:
+// CHECK-NEXT:  2000020:        ff f7 f2 ff     bl      #-28
+// CHECK-NEXT:  2000024:        ff f7 f6 ff     bl      #-20
diff --git a/test/ELF/arm-gnu-ifunc.s b/test/ELF/arm-gnu-ifunc.s
index 8a7cb0a..92f87b5 100644
--- a/test/ELF/arm-gnu-ifunc.s
+++ b/test/ELF/arm-gnu-ifunc.s
@@ -35,6 +35,8 @@
 // CHECK-NEXT:     Address: 0x100F4
 // CHECK-NEXT:     Offset: 0xF4
 // CHECK-NEXT:     Size: 16
+// CHECK-NEXT:     Link:
+// CHECK-NEXT:     Info: 4
 // CHECK:          Name: .plt
 // CHECK-NEXT:     Type: SHT_PROGBITS
 // CHECK-NEXT:     Flags [
@@ -44,7 +46,8 @@
 // CHECK-NEXT:     Address: 0x11020
 // CHECK-NEXT:     Offset: 0x1020
 // CHECK-NEXT:     Size: 32
-// CHECK:          Name: .got
+// CHECK:          Index: 4
+// CHECK-NEXT:     Name: .got
 // CHECK-NEXT:     Type: SHT_PROGBITS
 // CHECK-NEXT:     Flags [
 // CHECK-NEXT:       SHF_ALLOC
diff --git a/test/ELF/arm-thunk-multipass-plt.s b/test/ELF/arm-thunk-multipass-plt.s
new file mode 100644
index 0000000..90ec3a5
--- /dev/null
+++ b/test/ELF/arm-thunk-multipass-plt.s
@@ -0,0 +1,94 @@
+// REQUIRES: arm
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv5-none-linux-gnueabi %s -o %t
+// RUN: ld.lld %t -o %t2 --shared 2>&1
+// RUN: llvm-objdump --start-address=7340044 --stop-address=7340048 --triple=armv5-none-linux-gnueabi -d %t2 | FileCheck %s
+// RUN: llvm-objdump --start-address=8388620 --stop-address=8388624 --triple=thumbv5-none-linux-gnueabi -d %t2 | FileCheck %s -check-prefix=CHECK-CALL
+// RUN: llvm-objdump --start-address=13631520 --stop-address=13631584 --triple=armv5-none-linux-gnueabi -d %t2 | FileCheck %s -check-prefix=CHECK-PLT
+// When we create a thunk to a PLT entry the relocation is redirected to the
+// Thunk, changing its expression to a non-PLT equivalent. If the thunk
+// becomes unusable we need to restore the relocation expression to the PLT
+// form so that when we create a new thunk it targets the PLT.
+
+// Test case that checks the case:
+// - Thunk is created on pass 1 to a PLT entry for preemptible
+// - Some other Thunk added in the same pass moves the thunk to
+// preemptible out of range of its caller.
+// - New Thunk is created on pass 2 to PLT entry for preemptible
+
+        .globl preemptible
+        .globl preemptible2
+.section .text.01, "ax", %progbits
+.balign 0x100000
+        .thumb
+        .globl needsplt
+        .type needsplt, %function
+needsplt:
+        bl preemptible
+        .section .text.02, "ax", %progbits
+        .space (1024 * 1024)
+
+        .section .text.03, "ax", %progbits
+        .space (1024 * 1024)
+
+        .section .text.04, "ax", %progbits
+        .space (1024 * 1024)
+
+        .section .text.05, "ax", %progbits
+        .space (1024 * 1024)
+
+        .section .text.06, "ax", %progbits
+        .space (1024 * 1024)
+
+        .section .text.07, "ax", %progbits
+        .space (1024 * 1024)
+// 0x70000c + 8 + 0x60002c = 0xd00040 = preemptible@plt
+// CHECK: 000000000070000c __ARMV5PILongThunk_preemptible:
+// CHECK-NEXT:   70000c:        0b 00 18 ea     b       #6291500
+
+        .section .text.08, "ax", %progbits
+        .space (1024 * 1024) - 4
+
+        .section .text.10, "ax", %progbits
+        .balign 2
+        bl preemptible
+        bl preemptible2
+// 0x80000c + 4 - 100004 = 0x70000c = __ARMv5PILongThunk_preemptible
+// CHECK-CALL: 80000c:   ff f6 fe ef     blx     #-1048580
+        .balign 2
+        .globl preemptible
+        .type preemptible, %function
+preemptible:
+        bx lr
+        .globl preemptible2
+        .type preemptible2, %function
+preemptible2:
+        bx lr
+
+
+        .section .text.11, "ax", %progbits
+        .space (5 * 1024 * 1024)
+
+
+// CHECK-PLT: Disassembly of section .plt:
+// CHECK-PLT-NEXT: 0000000000d00020 $a:
+// CHECK-PLT-NEXT:   d00020:    04 e0 2d e5     str     lr, [sp, #-4]!
+// CHECK-PLT-NEXT:   d00024:    00 e6 8f e2     add     lr, pc, #0, #12
+// CHECK-PLT-NEXT:   d00028:    00 ea 8e e2     add     lr, lr, #0, #20
+// CHECK-PLT-NEXT:   d0002c:    dc ff be e5     ldr     pc, [lr, #4060]!
+// CHECK-PLT: 0000000000d00030 $d:
+// CHECK-PLT-NEXT:   d00030:    d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECK-PLT-NEXT:   d00034:    d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECK-PLT-NEXT:   d00038:    d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECK-PLT-NEXT:   d0003c:    d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECK-PLT: 0000000000d00040 $a:
+// CHECK-PLT-NEXT:   d00040:    00 c6 8f e2     add     r12, pc, #0, #12
+// CHECK-PLT-NEXT:   d00044:    00 ca 8c e2     add     r12, r12, #0, #20
+// CHECK-PLT-NEXT:   d00048:    c4 ff bc e5     ldr     pc, [r12, #4036]!
+// CHECK-PLT: 0000000000d0004c $d:
+// CHECK-PLT-NEXT:   d0004c:    d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECK-PLT: 0000000000d00050 $a:
+// CHECK-PLT-NEXT:   d00050:    00 c6 8f e2     add     r12, pc, #0, #12
+// CHECK-PLT-NEXT:   d00054:    00 ca 8c e2     add     r12, r12, #0, #20
+// CHECK-PLT-NEXT:   d00058:    b8 ff bc e5     ldr     pc, [r12, #4024]!
+// CHECK-PLT: 0000000000d0005c $d:
+// CHECK-PLT-NEXT:   d0005c:    d4 d4 d4 d4     .word   0xd4d4d4d4
diff --git a/test/ELF/arm-tls-le32.s b/test/ELF/arm-tls-le32.s
index 7834ded..f9a5fa9 100644
--- a/test/ELF/arm-tls-le32.s
+++ b/test/ELF/arm-tls-le32.s
@@ -69,9 +69,9 @@
 
 // CHECK: Disassembly of section .text:
 // CHECK-NEXT: _start:
-// offset of x from Thread pointer = (TcbSize + 0x0 = 0x8)
-// CHECK-NEXT:   11000:         08 00 00 00
-// offset of z from Thread pointer = (TcbSize + 0x8 = 0x10)
-// CHECK-NEXT:   11004:         10 00 00 00
-// offset of y from Thread pointer = (TcbSize + 0x4 = 0xc)
-// CHECK-NEXT:   11008:         0c 00 00 00
+// offset of x from Thread pointer = (TcbSize + 0x0 = 0x20)
+// CHECK-NEXT:   11000:         20 00 00 00
+// offset of z from Thread pointer = (TcbSize + 0x8 = 0x28)
+// CHECK-NEXT:   11004:         28 00 00 00
+// offset of y from Thread pointer = (TcbSize + 0x4 = 0x24)
+// CHECK-NEXT:   11008:         24 00 00 00
diff --git a/test/ELF/arm-tls-norelax-ie-le.s b/test/ELF/arm-tls-norelax-ie-le.s
index be8af97..11c3e4f 100644
--- a/test/ELF/arm-tls-norelax-ie-le.s
+++ b/test/ELF/arm-tls-norelax-ie-le.s
@@ -37,5 +37,5 @@
  .type x2, %object
 
 // CHECK: Contents of section .got:
-// x1 at offset 8 from TP, x2 at offset c from TP. Offsets include TCB size of 8
-// CHECK-NEXT: 13064 08000000 0c000000
+// x1 at offset 0x20 from TP, x2 at offset 0x24 from TP. Offsets include TCB size of 0x20
+// CHECK-NEXT: 13064 20000000 24000000
diff --git a/test/ELF/as-needed-in-regular.s b/test/ELF/as-needed-in-regular.s
new file mode 100644
index 0000000..2ba646f
--- /dev/null
+++ b/test/ELF/as-needed-in-regular.s
@@ -0,0 +1,24 @@
+# REQUIRES: x86
+
+# RUN: echo '.globl a; .type a, @function; .type a, @function; a: ret' | \
+# RUN:   llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %ta.o
+# RUN: ld.lld %ta.o --shared --soname=a.so -o %ta.so
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o --as-needed %ta.so -o %t
+# RUN: llvm-readelf -d %t | FileCheck %s
+# RUN: ld.lld %t.o --as-needed %ta.so --gc-sections -o %t
+# RUN: llvm-readelf -d %t | FileCheck %s
+
+# The order of %ta.so and %t.o does not matter.
+
+# RUN: ld.lld --as-needed %ta.so %t.o -o %t
+# RUN: llvm-readelf -d %t | FileCheck %s
+# RUN: ld.lld --as-needed %ta.so %t.o --gc-sections -o %t
+# RUN: llvm-readelf -d %t | FileCheck %s
+
+# CHECK: a.so
+
+.global _start
+_start:
+  jmp a@PLT
diff --git a/test/ELF/as-needed-not-in-regular.s b/test/ELF/as-needed-not-in-regular.s
new file mode 100644
index 0000000..cd7efa6
--- /dev/null
+++ b/test/ELF/as-needed-not-in-regular.s
@@ -0,0 +1,32 @@
+# REQUIRES: x86
+
+# RUN: echo '.globl a1, a2; .type a1, @function; .type a2, @function; a1: a2: ret' | \
+# RUN:   llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %ta.o
+# RUN: ld.lld %ta.o --shared --soname=a.so -o %ta.so
+
+# RUN: echo '.globl b; .type b, @function; b: jmp a1@PLT' | \
+# RUN:   llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %tb.o
+# RUN: ld.lld %tb.o %ta.so --shared --soname=b.so -o %tb.so
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o %tb.so --as-needed %ta.so -o %t
+# RUN: llvm-readelf -d %t | FileCheck %s
+
+# RUN: ld.lld %t.o %tb.so --as-needed %ta.so --gc-sections -o %t
+# RUN: llvm-readelf -d %t | FileCheck %s
+
+# The symbol a1 (defined in a.so) is not referenced by a regular object,
+# the reference to a2 is weak, don't add a DT_NEEDED entry for a.so.
+# CHECK-NOT: a.so
+
+# RUN: ld.lld %t.o %tb.so --as-needed %ta.so --no-as-needed %ta.so -o %t
+# RUN: llvm-readelf -d %t | FileCheck %s -check-prefix=NEEDED
+
+# a.so is needed because one of its occurrences is needed.
+# NEEDED: a.so
+
+.global _start
+.weak a2
+_start:
+  jmp b@PLT
+  jmp a2
diff --git a/test/ELF/as-needed-weak.s b/test/ELF/as-needed-weak.s
index f009c72..1c38fd2 100644
--- a/test/ELF/as-needed-weak.s
+++ b/test/ELF/as-needed-weak.s
@@ -10,9 +10,10 @@
 
 # CHECK-NOT: libfoo
 
-# CHECK:      Symbol table of .hash for image:
-# CHECK-NEXT: Num Buc:    Value          Size   Type   Bind Vis      Ndx Name
-# CHECK-NEXT:   1   1: 0000000000000000     0 FUNC    WEAK   DEFAULT UND foo@
+# CHECK:      Symbol table '.dynsym' contains 2 entries:
+# CHECK-NEXT: Num:    Value          Size Type    Bind   Vis     Ndx Name
+# CHECK-NEXT:   0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT UND
+# CHECK-NEXT:   1: 0000000000000000     0 FUNC    WEAK   DEFAULT UND foo
 
 .globl _start
 .weak foo
diff --git a/test/ELF/bss-start-common.s b/test/ELF/bss-start-common.s
index cedf6a8..3a32f85 100644
--- a/test/ELF/bss-start-common.s
+++ b/test/ELF/bss-start-common.s
@@ -4,7 +4,7 @@
 # RUN: llvm-objdump -t -section-headers %t2 | FileCheck %s
 
 # CHECK: Sections:
-# CHECK: Idx Name          Size      Address          Type
+# CHECK: Idx Name          Size     VMA          Type
 # CHECK:   2 .bss          00000004 0000000000201000 BSS
 # CHECK: SYMBOL TABLE:
 # CHECK: 0000000000201000  .bss 00000000 __bss_start
diff --git a/test/ELF/bsymbolic-undef.s b/test/ELF/bsymbolic-undef.s
index 1269cb4..9708027 100644
--- a/test/ELF/bsymbolic-undef.s
+++ b/test/ELF/bsymbolic-undef.s
@@ -5,7 +5,7 @@
 
 # CHECK:      DynamicSymbols [
 # CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name: @
+# CHECK-NEXT:     Name:
 # CHECK-NEXT:     Value: 0x0
 # CHECK-NEXT:     Size: 0
 # CHECK-NEXT:     Binding: Local (0x0)
@@ -14,7 +14,7 @@
 # CHECK-NEXT:     Section: Undefined (0x0)
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name: undef@
+# CHECK-NEXT:     Name: undef
 # CHECK-NEXT:     Value: 0x0
 # CHECK-NEXT:     Size: 0
 # CHECK-NEXT:     Binding: Global (0x1)
diff --git a/test/ELF/comdat-linkonce.s b/test/ELF/comdat-linkonce.s
index 8721f58..8b1d4b3 100644
--- a/test/ELF/comdat-linkonce.s
+++ b/test/ELF/comdat-linkonce.s
@@ -4,7 +4,12 @@
 // RUN: ld.lld -shared %t.o %t2.o -o %t
 // RUN: ld.lld -shared %t2.o %t.o -o %t
 
-.section .gnu.linkonce.t.zed
+.section .gnu.linkonce.t.__x86.get_pc_thunk.bx
 .globl abc
 abc:
 nop
+
+.section .gnu.linkonce.t.__i686.get_pc_thunk.bx
+.globl def
+def:
+nop
diff --git a/test/ELF/common-gc2.s b/test/ELF/common-gc2.s
index 165bf62..21bff88 100644
--- a/test/ELF/common-gc2.s
+++ b/test/ELF/common-gc2.s
@@ -3,8 +3,8 @@
 # RUN: ld.lld -gc-sections -export-dynamic %t -o %t1
 # RUN: llvm-readobj --dyn-symbols %t1 | FileCheck %s
 
-# CHECK: Name: bar@
-# CHECK: Name: foo@
+# CHECK: Name: bar
+# CHECK: Name: foo
 
 .comm foo,4,4
 .comm bar,4,4
diff --git a/test/ELF/dont-export-hidden.s b/test/ELF/dont-export-hidden.s
index 161e342..651c024 100644
--- a/test/ELF/dont-export-hidden.s
+++ b/test/ELF/dont-export-hidden.s
@@ -19,7 +19,7 @@
 
 // CHECK:      DynamicSymbols [
 // CHECK-NEXT:   Symbol {
-// CHECK-NEXT:     Name: @
+// CHECK-NEXT:     Name:
 // CHECK-NEXT:     Value: 0x0
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Local
diff --git a/test/ELF/driver.test b/test/ELF/driver.test
index 585800a..cc3e789 100644
--- a/test/ELF/driver.test
+++ b/test/ELF/driver.test
@@ -60,6 +60,7 @@
 # ERR9: cannot open output file utput=/no/such/file
 
 # RUN: not ld.lld %t -z foo 2>&1 | FileCheck -check-prefix=ERR10 %s
+# RUN: not ld.lld %t -z foo --version 2>&1 | FileCheck -check-prefix=ERR10 %s
 # ERR10: unknown -z value: foo
 
 ## Check we report "unknown -z value" error even with -v.
diff --git a/test/ELF/dynamic-list-preempt.s b/test/ELF/dynamic-list-preempt.s
index 2bb10a3..daed27a 100644
--- a/test/ELF/dynamic-list-preempt.s
+++ b/test/ELF/dynamic-list-preempt.s
@@ -16,7 +16,7 @@
 
 # DYNSYMS:      DynamicSymbols [
 # DYNSYMS-NEXT:   Symbol {
-# DYNSYMS-NEXT:     Name: @ (0)
+# DYNSYMS-NEXT:     Name:
 # DYNSYMS-NEXT:     Value: 0x0
 # DYNSYMS-NEXT:     Size: 0
 # DYNSYMS-NEXT:     Binding: Local
@@ -25,7 +25,7 @@
 # DYNSYMS-NEXT:     Section: Undefined
 # DYNSYMS-NEXT:   }
 # DYNSYMS-NEXT:   Symbol {
-# DYNSYMS-NEXT:     Name: bar@
+# DYNSYMS-NEXT:     Name: bar
 # DYNSYMS-NEXT:     Value:
 # DYNSYMS-NEXT:     Size:
 # DYNSYMS-NEXT:     Binding: Global
@@ -34,7 +34,7 @@
 # DYNSYMS-NEXT:     Section:
 # DYNSYMS-NEXT:   }
 # DYNSYMS-NEXT:   Symbol {
-# DYNSYMS-NEXT:     Name: ext@
+# DYNSYMS-NEXT:     Name: ext
 # DYNSYMS-NEXT:     Value:
 # DYNSYMS-NEXT:     Size:
 # DYNSYMS-NEXT:     Binding: Global
@@ -43,7 +43,7 @@
 # DYNSYMS-NEXT:     Section:
 # DYNSYMS-NEXT:   }
 # DYNSYMS-NEXT:   Symbol {
-# DYNSYMS-NEXT:     Name: foo@
+# DYNSYMS-NEXT:     Name: foo
 # DYNSYMS-NEXT:     Value:
 # DYNSYMS-NEXT:     Size:
 # DYNSYMS-NEXT:     Binding: Global
diff --git a/test/ELF/dynamic-list-wildcard.s b/test/ELF/dynamic-list-wildcard.s
index cd7ed71..09a78af 100644
--- a/test/ELF/dynamic-list-wildcard.s
+++ b/test/ELF/dynamic-list-wildcard.s
@@ -8,7 +8,7 @@
 
 # CHECK:      DynamicSymbols [
 # CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name:	 @ (0)
+# CHECK-NEXT:     Name:
 # CHECK-NEXT:     Value:	 0x0
 # CHECK-NEXT:     Size:	 0
 # CHECK-NEXT:     Binding:	 Local (0x0)
@@ -17,7 +17,7 @@
 # CHECK-NEXT:     Section:	 Undefined (0x0)
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name:	 foo1@ (1)
+# CHECK-NEXT:     Name:	 foo1
 # CHECK-NEXT:     Value:	 0x1000
 # CHECK-NEXT:     Size:	 0
 # CHECK-NEXT:     Binding:	 Global (0x1)
@@ -26,7 +26,7 @@
 # CHECK-NEXT:     Section:	 .text (0x4)
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name:	 foo11@ (6)
+# CHECK-NEXT:     Name:	 foo11
 # CHECK-NEXT:     Value:	 0x1001
 # CHECK-NEXT:     Size:	 0
 # CHECK-NEXT:     Binding:	 Global (0x1)
diff --git a/test/ELF/dynamic-list.s b/test/ELF/dynamic-list.s
index 888508e..f6addcb 100644
--- a/test/ELF/dynamic-list.s
+++ b/test/ELF/dynamic-list.s
@@ -23,7 +23,7 @@
 
 # CHECK:      DynamicSymbols [
 # CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name: @
+# CHECK-NEXT:     Name:
 # CHECK-NEXT:     Value: 0x0
 # CHECK-NEXT:     Size: 0
 # CHECK-NEXT:     Binding: Local
@@ -32,7 +32,7 @@
 # CHECK-NEXT:     Section: Undefined
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name: foo1@
+# CHECK-NEXT:     Name: foo1
 # CHECK-NEXT:     Value: 0x201000
 # CHECK-NEXT:     Size: 0
 # CHECK-NEXT:     Binding: Global (0x1)
@@ -54,7 +54,7 @@
 
 # CHECK2:      DynamicSymbols [
 # CHECK2-NEXT:   Symbol {
-# CHECK2-NEXT:     Name: @
+# CHECK2-NEXT:     Name:
 # CHECK2-NEXT:     Value: 0x0
 # CHECK2-NEXT:     Size: 0
 # CHECK2-NEXT:     Binding: Local
@@ -63,7 +63,7 @@
 # CHECK2-NEXT:     Section: Undefined
 # CHECK2-NEXT:   }
 # CHECK2-NEXT:   Symbol {
-# CHECK2-NEXT:     Name: foo1@
+# CHECK2-NEXT:     Name: foo1
 # CHECK2-NEXT:     Value: 0x201000
 # CHECK2-NEXT:     Size: 0
 # CHECK2-NEXT:     Binding: Global (0x1)
@@ -72,7 +72,7 @@
 # CHECK2-NEXT:     Section: .text (0x4)
 # CHECK2-NEXT:   }
 # CHECK2-NEXT:   Symbol {
-# CHECK2-NEXT:     Name: foo2@
+# CHECK2-NEXT:     Name: foo2
 # CHECK2-NEXT:     Value: 0x201001
 # CHECK2-NEXT:     Size: 0
 # CHECK2-NEXT:     Binding: Global (0x1)
@@ -81,7 +81,7 @@
 # CHECK2-NEXT:     Section: .text (0x4)
 # CHECK2-NEXT:   }
 # CHECK2-NEXT:   Symbol {
-# CHECK2-NEXT:     Name: foo31@
+# CHECK2-NEXT:     Name: foo31
 # CHECK2-NEXT:     Value: 0x201002
 # CHECK2-NEXT:     Size: 0
 # CHECK2-NEXT:     Binding: Global (0x1)
@@ -104,7 +104,7 @@
 
 # CHECK3:      DynamicSymbols [
 # CHECK3-NEXT:   Symbol {
-# CHECK3-NEXT:     Name: @
+# CHECK3-NEXT:     Name:
 # CHECK3-NEXT:     Value: 0x0
 # CHECK3-NEXT:     Size: 0
 # CHECK3-NEXT:     Binding: Local
@@ -113,7 +113,7 @@
 # CHECK3-NEXT:     Section: Undefined
 # CHECK3-NEXT:   }
 # CHECK3-NEXT:   Symbol {
-# CHECK3-NEXT:     Name: _start@
+# CHECK3-NEXT:     Name: _start
 # CHECK3-NEXT:     Value: 0x201003
 # CHECK3-NEXT:     Size: 0
 # CHECK3-NEXT:     Binding: Global (0x1)
@@ -122,7 +122,7 @@
 # CHECK3-NEXT:     Section: .text (0x4)
 # CHECK3-NEXT:   }
 # CHECK3-NEXT:   Symbol {
-# CHECK3-NEXT:     Name: foo1@
+# CHECK3-NEXT:     Name: foo1
 # CHECK3-NEXT:     Value: 0x201000
 # CHECK3-NEXT:     Size: 0
 # CHECK3-NEXT:     Binding: Global (0x1)
@@ -131,7 +131,7 @@
 # CHECK3-NEXT:     Section: .text (0x4)
 # CHECK3-NEXT:   }
 # CHECK3-NEXT:   Symbol {
-# CHECK3-NEXT:     Name: foo2@
+# CHECK3-NEXT:     Name: foo2
 # CHECK3-NEXT:     Value: 0x201001
 # CHECK3-NEXT:     Size: 0
 # CHECK3-NEXT:     Binding: Global (0x1)
@@ -140,7 +140,7 @@
 # CHECK3-NEXT:     Section: .text (0x4)
 # CHECK3-NEXT:   }
 # CHECK3-NEXT:   Symbol {
-# CHECK3-NEXT:     Name: foo31@
+# CHECK3-NEXT:     Name: foo31
 # CHECK3-NEXT:     Value: 0x201002
 # CHECK3-NEXT:     Size: 0
 # CHECK3-NEXT:     Binding: Global (0x1)
diff --git a/test/ELF/dynsym-no-rosegment.s b/test/ELF/dynsym-no-rosegment.s
index 947f526..c378bbc 100644
--- a/test/ELF/dynsym-no-rosegment.s
+++ b/test/ELF/dynsym-no-rosegment.s
@@ -5,7 +5,7 @@
 
 # CHECK:      DynamicSymbols [
 # CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name: @ (0)
+# CHECK-NEXT:     Name:
 # CHECK-NEXT:     Value: 0x0
 # CHECK-NEXT:     Size: 0
 # CHECK-NEXT:     Binding: Local
@@ -14,7 +14,7 @@
 # CHECK-NEXT:     Section: Undefined
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name: undef@
+# CHECK-NEXT:     Name: undef
 # CHECK-NEXT:     Value: 0x0
 # CHECK-NEXT:     Size: 0
 # CHECK-NEXT:     Binding: Global
diff --git a/test/ELF/dynsym-pie.s b/test/ELF/dynsym-pie.s
index b162d27..6a7f4f1 100644
--- a/test/ELF/dynsym-pie.s
+++ b/test/ELF/dynsym-pie.s
@@ -50,7 +50,7 @@
 
 # CHECK:      DynamicSymbols [
 # CHECK-NEXT:  Symbol {
-# CHECK-NEXT:    Name: @
+# CHECK-NEXT:    Name:
 # CHECK-NEXT:    Value: 0x0
 # CHECK-NEXT:    Size: 0
 # CHECK-NEXT:    Binding: Local
diff --git a/test/ELF/edata-etext.s b/test/ELF/edata-etext.s
index 52070cb..5c83256 100644
--- a/test/ELF/edata-etext.s
+++ b/test/ELF/edata-etext.s
@@ -12,13 +12,12 @@
 ## 3) Address of _end is different from _edata because of 2.
 ## 4) Addresses of _edata == edata, _end == end and _etext == etext.
 # CHECK:      Sections:
-# CHECK-NEXT:  Idx Name          Size      Address          Type
+# CHECK-NEXT:  Idx Name          Size     VMA              Type
 # CHECK-NEXT:    0               00000000 0000000000000000
 # CHECK-NEXT:    1 .text         00000001 0000000000201000 TEXT
 # CHECK-NEXT:    2 .data         00000002 0000000000202000 DATA
 # CHECK-NEXT:    3 .bss          00000006 0000000000202004 BSS
 # CHECK:      SYMBOL TABLE:
-# CHECK-NEXT:  0000000000000000         *UND* 00000000
 # CHECK-NEXT:  0000000000202002         .data 00000000 _edata
 # CHECK-NEXT:  000000000020200a         .bss  00000000 _end
 # CHECK-NEXT:  0000000000201001         .text 00000000 _etext
diff --git a/test/ELF/empty-ver.s b/test/ELF/empty-ver.s
index 3412f31..d923607 100644
--- a/test/ELF/empty-ver.s
+++ b/test/ELF/empty-ver.s
@@ -29,7 +29,7 @@
 // CHECK-NEXT:   Symbols [
 // CHECK-NEXT:     Symbol {
 // CHECK-NEXT:       Version: 0
-// CHECK-NEXT:       Name: @
+// CHECK-NEXT:       Name:
 // CHECK-NEXT:     }
 // CHECK-NEXT:     Symbol {
 // CHECK-NEXT:       Version: 2
diff --git a/test/ELF/empty-ver2.s b/test/ELF/empty-ver2.s
index 2aceee1..f4b288e 100644
--- a/test/ELF/empty-ver2.s
+++ b/test/ELF/empty-ver2.s
@@ -8,11 +8,11 @@
 # CHECK:       Symbols [
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Version: 0
-# CHECK-NEXT:     Name: @
+# CHECK-NEXT:     Name:
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Version: 1
-# CHECK-NEXT:     Name: bar@@
+# CHECK-NEXT:     Name: bar@
 # CHECK-NEXT:   }
 # CHECK-NEXT: ]
 
diff --git a/test/ELF/emulation-aarch64.s b/test/ELF/emulation-aarch64.s
index b9a6428..c0edc9a 100644
--- a/test/ELF/emulation-aarch64.s
+++ b/test/ELF/emulation-aarch64.s
@@ -30,5 +30,28 @@
 # AARCH64-NEXT:   Flags [ (0x0)
 # AARCH64-NEXT:   ]
 
+# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %taarch64fbsd
+# RUN: echo 'OUTPUT_FORMAT(elf64-aarch64-freebsd)' > %taarch64fbsd.script
+# RUN: ld.lld %taarch64fbsd.script %taarch64fbsd -o %t2aarch64fbsd
+# RUN: llvm-readobj -file-headers %t2aarch64fbsd | FileCheck --check-prefix=AARCH64-FBSD %s
+# AARCH64-FBSD:      ElfHeader {
+# AARCH64-FBSD-NEXT:   Ident {
+# AARCH64-FBSD-NEXT:     Magic: (7F 45 4C 46)
+# AARCH64-FBSD-NEXT:     Class: 64-bit (0x2)
+# AARCH64-FBSD-NEXT:     DataEncoding: LittleEndian (0x1)
+# AARCH64-FBSD-NEXT:     FileVersion: 1
+# AARCH64-FBSD-NEXT:     OS/ABI: FreeBSD (0x9)
+# AARCH64-FBSD-NEXT:     ABIVersion: 0
+# AARCH64-FBSD-NEXT:     Unused: (00 00 00 00 00 00 00)
+# AARCH64-FBSD-NEXT:   }
+# AARCH64-FBSD-NEXT:   Type: Executable (0x2)
+# AARCH64-FBSD-NEXT:   Machine: EM_AARCH64 (0xB7)
+# AARCH64-FBSD-NEXT:   Version: 1
+# AARCH64-FBSD-NEXT:   Entry:
+# AARCH64-FBSD-NEXT:   ProgramHeaderOffset: 0x40
+# AARCH64-FBSD-NEXT:   SectionHeaderOffset:
+# AARCH64-FBSD-NEXT:   Flags [ (0x0)
+# AARCH64-FBSD-NEXT:   ]
+
 .globl _start
 _start:
diff --git a/test/ELF/emulation-mips.s b/test/ELF/emulation-mips.s
index 42d0dd9..6d7a119 100644
--- a/test/ELF/emulation-mips.s
+++ b/test/ELF/emulation-mips.s
@@ -7,6 +7,9 @@
 # RUN: echo 'OUTPUT_FORMAT(elf32-tradbigmips)' > %tmips.script
 # RUN: ld.lld %tmips.script -e _start %tmips -o %t4mips
 # RUN: llvm-readobj -file-headers %t4mips | FileCheck --check-prefix=MIPS %s
+# RUN: echo 'OUTPUT_FORMAT(elf32-bigmips)' > %tmips2.script
+# RUN: ld.lld %tmips2.script -e _start %tmips -o %t5mips
+# RUN: llvm-readobj -file-headers %t5mips | FileCheck --check-prefix=MIPS %s
 # MIPS:      ElfHeader {
 # MIPS-NEXT:   Ident {
 # MIPS-NEXT:     Magic: (7F 45 4C 46)
diff --git a/test/ELF/emulation-ppc.s b/test/ELF/emulation-ppc.s
index 12e8478..4c8beb1 100644
--- a/test/ELF/emulation-ppc.s
+++ b/test/ELF/emulation-ppc.s
@@ -35,6 +35,38 @@
 # PPC64-NEXT:   StringTableSectionIndex:
 # PPC64-NEXT: }
 
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-freebsd %s -o %tppc64fbsd
+# RUN: echo 'OUTPUT_FORMAT(elf64-powerpc-freebsd)' > %tppc64fbsd.script
+# RUN: ld.lld %tppc64fbsd.script  %tppc64fbsd -o %t2ppc64fbsd
+# RUN: llvm-readobj -file-headers %t2ppc64fbsd | FileCheck --check-prefix=PPC64-FBSD %s
+
+# PPC64-FBSD:      ElfHeader {
+# PPC64-FBSD-NEXT:   Ident {
+# PPC64-FBSD-NEXT:     Magic: (7F 45 4C 46)
+# PPC64-FBSD-NEXT:     Class: 64-bit (0x2)
+# PPC64-FBSD-NEXT:     DataEncoding: BigEndian (0x2)
+# PPC64-FBSD-NEXT:     FileVersion: 1
+# PPC64-FBSD-NEXT:     OS/ABI: FreeBSD (0x9)
+# PPC64-FBSD-NEXT:     ABIVersion: 0
+# PPC64-FBSD-NEXT:     Unused: (00 00 00 00 00 00 00)
+# PPC64-FBSD-NEXT:   }
+# PPC64-FBSD-NEXT:   Type: Executable (0x2)
+# PPC64-FBSD-NEXT:   Machine: EM_PPC64 (0x15)
+# PPC64-FBSD-NEXT:   Version: 1
+# PPC64-FBSD-NEXT:   Entry:
+# PPC64-FBSD-NEXT:   ProgramHeaderOffset: 0x40
+# PPC64-FBSD-NEXT:   SectionHeaderOffset:
+# PPC64-FBSD-NEXT:   Flags [ (0x2)
+# PPC64-FBSD-NEXT:     0x2
+# PPC64-FBSD-NEXT:   ]
+# PPC64-FBSD-NEXT:   HeaderSize: 64
+# PPC64-FBSD-NEXT:   ProgramHeaderEntrySize: 56
+# PPC64-FBSD-NEXT:   ProgramHeaderCount:
+# PPC64-FBSD-NEXT:   SectionHeaderEntrySize: 64
+# PPC64-FBSD-NEXT:   SectionHeaderCount:
+# PPC64-FBSD-NEXT:   StringTableSectionIndex:
+# PPC64-FBSD-NEXT: }
+
 # RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %tppc64le
 # RUN: ld.lld -m elf64lppc %tppc64le -o %t2ppc64le
 # RUN: llvm-readobj -file-headers %t2ppc64le | FileCheck --check-prefix=PPC64LE %s
@@ -71,5 +103,42 @@
 # PPC64LE-NEXT:   StringTableSectionIndex:
 # PPC64LE-NEXT: }
 
+# RUN: llvm-mc -filetype=obj -triple=powerpc-unknown-linux %s -o %tppc32
+# RUN: ld.lld -m elf32ppc %tppc32 -o %t2ppc32
+# RUN: llvm-readobj -file-headers %t2ppc32 | FileCheck --check-prefix=PPC32 %s
+# RUN: ld.lld %tppc32 -o %t3ppc32
+# RUN: llvm-readobj -file-headers %t3ppc32 | FileCheck --check-prefix=PPC32 %s
+# RUN: echo 'OUTPUT_FORMAT(elf32-powerpc)' > %tppc32.script
+# RUN: ld.lld %tppc32.script  %tppc32 -o %t4ppc32
+# RUN: llvm-readobj -file-headers %t4ppc32 | FileCheck --check-prefix=PPC32 %s
+# RUN: ld.lld -m elf32ppclinux %tppc32 -o %t5ppc32
+# RUN: llvm-readobj -file-headers %t5ppc32 | FileCheck --check-prefix=PPC32 %s
+
+# PPC32:      ElfHeader {
+# PPC32-NEXT:   Ident {
+# PPC32-NEXT:     Magic: (7F 45 4C 46)
+# PPC32-NEXT:     Class: 32-bit (0x1)
+# PPC32-NEXT:     DataEncoding: BigEndian (0x2)
+# PPC32-NEXT:     FileVersion: 1
+# PPC32-NEXT:     OS/ABI: SystemV (0x0)
+# PPC32-NEXT:     ABIVersion: 0
+# PPC32-NEXT:     Unused: (00 00 00 00 00 00 00)
+# PPC32-NEXT:   }
+# PPC32-NEXT:   Type: Executable (0x2)
+# PPC32-NEXT:   Machine: EM_PPC (0x14)
+# PPC32-NEXT:   Version: 1
+# PPC32-NEXT:   Entry:
+# PPC32-NEXT:   ProgramHeaderOffset: 0x34
+# PPC32-NEXT:   SectionHeaderOffset:
+# PPC32-NEXT:   Flags [ (0x0)
+# PPC32-NEXT:   ]
+# PPC32-NEXT:   HeaderSize: 52
+# PPC32-NEXT:   ProgramHeaderEntrySize: 32
+# PPC32-NEXT:   ProgramHeaderCount:
+# PPC32-NEXT:   SectionHeaderEntrySize: 40
+# PPC32-NEXT:   SectionHeaderCount:
+# PPC32-NEXT:   StringTableSectionIndex:
+# PPC32-NEXT: }
+
 .globl _start
 _start:
diff --git a/test/ELF/emulation-x86.s b/test/ELF/emulation-x86.s
index 65d807c..02b8943 100644
--- a/test/ELF/emulation-x86.s
+++ b/test/ELF/emulation-x86.s
@@ -7,6 +7,9 @@
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.sysv
 # RUN: ld.lld -m elf_amd64_fbsd %t.sysv -o %t.freebsd
 # RUN: llvm-readobj -file-headers %t.freebsd | FileCheck --check-prefix=AMD64 %s
+# RUN: echo 'OUTPUT_FORMAT(elf64-x86-64-freebsd)' > %t4x64.script
+# RUN: ld.lld %t4x64.script %tx64 -o %t4x64
+# RUN: llvm-readobj -file-headers %t4x64 | FileCheck --check-prefix=AMD64 %s
 # AMD64:      ElfHeader {
 # AMD64-NEXT:   Ident {
 # AMD64-NEXT:     Magic: (7F 45 4C 46)
@@ -137,10 +140,13 @@
 # X86-NEXT: }
 
 # RUN: llvm-mc -filetype=obj -triple=i686-unknown-freebsd %s -o %tx86fbsd
-# RUN: ld.lld -m elf_i386_fbsd %tx86fbsd -o %t2x86_fbsd
-# RUN: llvm-readobj -file-headers %t2x86_fbsd | FileCheck --check-prefix=X86FBSD %s
+# RUN: ld.lld -m elf_i386_fbsd %tx86fbsd -o %t2x86fbsd
+# RUN: llvm-readobj -file-headers %t2x86fbsd | FileCheck --check-prefix=X86FBSD %s
 # RUN: ld.lld %tx86fbsd -o %t3x86fbsd
 # RUN: llvm-readobj -file-headers %t3x86fbsd | FileCheck --check-prefix=X86FBSD %s
+# RUN: echo 'OUTPUT_FORMAT(elf32-i386-freebsd)' > %t4x86fbsd.script
+# RUN: ld.lld %t4x86fbsd.script %tx86fbsd -o %t4x86fbsd
+# RUN: llvm-readobj -file-headers %t4x86fbsd | FileCheck --check-prefix=X86FBSD %s
 # X86FBSD:      ElfHeader {
 # X86FBSD-NEXT:   Ident {
 # X86FBSD-NEXT:     Magic: (7F 45 4C 46)
diff --git a/test/ELF/gc-sections-linker-defined-symbol.s b/test/ELF/gc-sections-linker-defined-symbol.s
index 796f7b3..e570116 100644
--- a/test/ELF/gc-sections-linker-defined-symbol.s
+++ b/test/ELF/gc-sections-linker-defined-symbol.s
@@ -4,7 +4,7 @@
 # RUN: ld.lld %t.o -o %t.so --gc-sections -shared
 # RUN: llvm-readobj --dyn-symbols %t.so | FileCheck %s
 
-# CHECK:      Name: _end@
+# CHECK:      Name: _end
 # CHECK-NEXT: Value:
 # CHECK-NEXT: Size:
 # CHECK-NEXT: Binding: Global
diff --git a/test/ELF/gdb-index-dwarf5-low-high.s b/test/ELF/gdb-index-dwarf5-low-high.s
new file mode 100644
index 0000000..94b713c
--- /dev/null
+++ b/test/ELF/gdb-index-dwarf5-low-high.s
@@ -0,0 +1,49 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld --gdb-index %t.o -o %t
+# RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s
+
+# CHECK:       Address area offset = 0x28, has 1 entries:
+# CHECK-NEXT:    Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0
+
+  .text
+  .globl main
+main:                            # @main
+.Lfunc_begin0:
+  retq
+.Lfunc_end0:
+  .section  .debug_abbrev,"",@progbits
+  .byte  1                       # Abbreviation Code
+  .byte  17                      # DW_TAG_compile_unit
+  .byte  0                       # DW_CHILDREN_no
+  .byte  115                     # DW_AT_addr_base
+  .byte  23                      # DW_FORM_sec_offset
+  .byte  17                      # DW_AT_low_pc
+  .byte  27                      # DW_FORM_addrx
+  .byte  18                      # DW_AT_high_pc
+  .byte  6                       # DW_FORM_data4
+  .byte  0                       # EOM(1)
+  .byte  0                       # EOM(2)
+  .byte  0                       # EOM(3)
+  
+  .section  .debug_info,"",@progbits
+.Lcu_begin0:
+  .long  .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+  .short  5                      # DWARF version number
+  .byte  1                       # DWARF Unit Type
+  .byte  8                       # Address Size (in bytes)
+  .long  .debug_abbrev           # Offset Into Abbrev. Section
+  .byte  1                       # Abbrev [1] 0xc:0x2b DW_TAG_compile_unit
+  .long  .Laddr_table_base0      # DW_AT_addr_base
+  .byte  0                       # DW_AT_low_pc
+  .long  .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+.Ldebug_info_end0:
+
+  .section  .debug_addr,"",@progbits
+  .long  12
+  .short  5
+  .byte  8
+  .byte  0
+.Laddr_table_base0:
+  .quad  .Lfunc_begin0
diff --git a/test/ELF/gdb-index-invalid-ranges.s b/test/ELF/gdb-index-invalid-ranges.s
new file mode 100644
index 0000000..1aac98d
--- /dev/null
+++ b/test/ELF/gdb-index-invalid-ranges.s
@@ -0,0 +1,42 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: not ld.lld --gdb-index -e main %t.o -o %t 2>&1 | FileCheck %s
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/gdb-index-invalid-ranges.obj.s -o %t2.o
+# RUN: llvm-ar rc %t.a %t.o
+# RUN: not ld.lld --gdb-index -e main %t2.o %t.a -o %t 2>&1 | FileCheck --check-prefix=ARCHIVE %s
+
+# CHECK: ld.lld: error: {{.*}}gdb-index-invalid-ranges.s.tmp.o:(.debug_info): decoding address ranges: invalid range list entry at offset 0x10
+# ARCHIVE: ld.lld: error: {{.*}}gdb-index-invalid-ranges.s.tmp.a(gdb-index-invalid-ranges.s.tmp.o):(.debug_info): decoding address ranges: invalid range list entry at offset 0x10
+
+.section .text.foo1,"ax",@progbits
+.globl f1
+.Lfunc_begin0:
+f1:
+ nop
+.Lfunc_end0:
+
+.section .debug_abbrev,"",@progbits
+.byte 1                       # Abbreviation Code
+.byte 17                      # DW_TAG_compile_unit
+.byte 0                       # DW_CHILDREN_no
+.byte 85                      # DW_AT_ranges
+.byte 23                      # DW_FORM_sec_offset
+.byte 0                       # EOM(1)
+.byte 0                       # EOM(2)
+.byte 0                       # EOM(3)
+
+.section .debug_info,"",@progbits
+.Lcu_begin0:
+.long .Lunit_end0-.Lunit_begin0 # Length of Unit
+.Lunit_begin0:
+.short 4                      # DWARF version number
+.long .debug_abbrev           # Offset Into Abbrev. Section
+.byte 8                       # Address Size (in bytes)
+.byte 1                       # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit
+.long .Ldebug_ranges0         # DW_AT_ranges
+.Lunit_end0:
+
+.section .debug_ranges,"",@progbits
+.Ldebug_ranges0:
+.quad .Lfunc_begin0
+.quad .Lfunc_end0
diff --git a/test/ELF/gnu-hash-table-copy.s b/test/ELF/gnu-hash-table-copy.s
index 9d91163..cdd96e3 100644
--- a/test/ELF/gnu-hash-table-copy.s
+++ b/test/ELF/gnu-hash-table-copy.s
@@ -13,10 +13,10 @@
 
 # CHECK:      Symbol table '.dynsym' contains 4 entries:
 # CHECK-NEXT:    Num:    Value          Size Type    Bind   Vis      Ndx   Name
-# CHECK-NEXT:      0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND   @
-# CHECK-NEXT:      1: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  UND   foo@
-# CHECK-DAG:        : {{.*}}               4 OBJECT  GLOBAL DEFAULT {{.*}} bar@
-# CHECK-DAG:        : {{.*}}               0 FUNC    GLOBAL DEFAULT  UND   zed@
+# CHECK-NEXT:      0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
+# CHECK-NEXT:      1: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  UND   foo
+# CHECK-DAG:        : {{.*}}               4 OBJECT  GLOBAL DEFAULT {{.*}} bar
+# CHECK-DAG:        : {{.*}}               0 FUNC    GLOBAL DEFAULT  UND   zed
 
 # CHECK: First Hashed Symbol Index: 2
 
diff --git a/test/ELF/gnu-hash-table-rwsegment.s b/test/ELF/gnu-hash-table-rwsegment.s
index b1a50fb..ab1b252 100644
--- a/test/ELF/gnu-hash-table-rwsegment.s
+++ b/test/ELF/gnu-hash-table-rwsegment.s
@@ -8,8 +8,8 @@
 # CHECK-NEXT:   Num Buckets: 1
 # CHECK-NEXT:   First Hashed Symbol Index: 1
 # CHECK-NEXT:   Num Mask Words: 1
-# CHECK-NEXT:   Shift Count: 6
-# CHECK-NEXT:   Bloom Filter: [0x400000000004204]
+# CHECK-NEXT:   Shift Count: 26
+# CHECK-NEXT:   Bloom Filter: [0x400000000000204]
 # CHECK-NEXT:   Buckets: [1]
 # CHECK-NEXT:   Values: [0xB8860BA, 0xB887389]
 # CHECK-NEXT: }
diff --git a/test/ELF/gnu-hash-table.s b/test/ELF/gnu-hash-table.s
index 642b445..052a5bb 100644
--- a/test/ELF/gnu-hash-table.s
+++ b/test/ELF/gnu-hash-table.s
@@ -49,7 +49,7 @@
 
 # EMPTY:      DynamicSymbols [
 # EMPTY:        Symbol {
-# EMPTY:          Name: foo@
+# EMPTY:          Name: foo
 # EMPTY-NEXT:     Value: 0x0
 # EMPTY-NEXT:     Size: 0
 # EMPTY-NEXT:     Binding: Global
@@ -62,7 +62,7 @@
 # EMPTY-NEXT:   Num Buckets: 1
 # EMPTY-NEXT:   First Hashed Symbol Index: 2
 # EMPTY-NEXT:   Num Mask Words: 1
-# EMPTY-NEXT:   Shift Count: 6
+# EMPTY-NEXT:   Shift Count: 26
 # EMPTY-NEXT:   Bloom Filter: [0x0]
 # EMPTY-NEXT:   Buckets: [0]
 # EMPTY-NEXT:   Values: []
@@ -87,32 +87,32 @@
 # I386:      ]
 # I386:      DynamicSymbols [
 # I386:        Symbol {
-# I386:          Name: @
+# I386:          Name:
 # I386:          Binding: Local
 # I386:          Section: Undefined
 # I386:        }
 # I386:        Symbol {
-# I386:          Name: baz@
+# I386:          Name: baz
 # I386:          Binding: Global
 # I386:          Section: Undefined
 # I386:        }
 # I386:        Symbol {
-# I386:          Name: xyz@
+# I386:          Name: xyz
 # I386:          Binding: Global
 # I386:          Section: Undefined
 # I386:        }
 # I386:        Symbol {
-# I386:          Name: zed@
+# I386:          Name: zed
 # I386:          Binding: Weak
 # I386:          Section: Undefined
 # I386:        }
 # I386:        Symbol {
-# I386:          Name: bar@
+# I386:          Name: bar
 # I386:          Binding: Global
 # I386:          Section: .text
 # I386:        }
 # I386:        Symbol {
-# I386:          Name: foo@
+# I386:          Name: foo
 # I386:          Binding: Global
 # I386:          Section: .text
 # I386:        }
@@ -121,8 +121,8 @@
 # I386-NEXT:   Num Buckets: 1
 # I386-NEXT:   First Hashed Symbol Index: 4
 # I386-NEXT:   Num Mask Words: 1
-# I386-NEXT:   Shift Count: 6
-# I386-NEXT:   Bloom Filter: [0x4004204]
+# I386-NEXT:   Shift Count: 26
+# I386-NEXT:   Bloom Filter: [0x4000204]
 # I386-NEXT:   Buckets: [4]
 # I386-NEXT:   Values: [0xB8860BA, 0xB887389]
 # I386-NEXT: }
@@ -147,32 +147,32 @@
 # X86_64:      ]
 # X86_64:      DynamicSymbols [
 # X86_64:        Symbol {
-# X86_64:          Name: @
+# X86_64:          Name:
 # X86_64:          Binding: Local
 # X86_64:          Section: Undefined
 # X86_64:        }
 # X86_64:        Symbol {
-# X86_64:          Name: baz@
+# X86_64:          Name: baz
 # X86_64:          Binding: Global
 # X86_64:          Section: Undefined
 # X86_64:        }
 # X86_64:        Symbol {
-# X86_64:          Name: xyz@
+# X86_64:          Name: xyz
 # X86_64:          Binding: Global
 # X86_64:          Section: Undefined
 # X86_64:        }
 # X86_64:        Symbol {
-# X86_64:          Name: zed@
+# X86_64:          Name: zed
 # X86_64:          Binding: Weak
 # X86_64:          Section: Undefined
 # X86_64:        }
 # X86_64:        Symbol {
-# X86_64:          Name: bar@
+# X86_64:          Name: bar
 # X86_64:          Binding: Global
 # X86_64:          Section: .text
 # X86_64:        }
 # X86_64:        Symbol {
-# X86_64:          Name: foo@
+# X86_64:          Name: foo
 # X86_64:          Binding: Global
 # X86_64:          Section: .text
 # X86_64:        }
@@ -181,8 +181,8 @@
 # X86_64-NEXT:   Num Buckets: 1
 # X86_64-NEXT:   First Hashed Symbol Index: 4
 # X86_64-NEXT:   Num Mask Words: 1
-# X86_64-NEXT:   Shift Count: 6
-# X86_64-NEXT:   Bloom Filter: [0x400000000004204]
+# X86_64-NEXT:   Shift Count: 26
+# X86_64-NEXT:   Bloom Filter: [0x400000000000204]
 # X86_64-NEXT:   Buckets: [4]
 # X86_64-NEXT:   Values: [0xB8860BA, 0xB887389]
 # X86_64-NEXT: }
@@ -207,32 +207,32 @@
 # PPC64:      ]
 # PPC64:      DynamicSymbols [
 # PPC64:        Symbol {
-# PPC64:          Name: @
+# PPC64:          Name:
 # PPC64:          Binding: Local
 # PPC64:          Section: Undefined
 # PPC64:        }
 # PPC64:        Symbol {
-# PPC64:          Name: baz@
+# PPC64:          Name: baz
 # PPC64:          Binding: Global
 # PPC64:          Section: Undefined
 # PPC64:        }
 # PPC64:        Symbol {
-# PPC64:          Name: xyz@
+# PPC64:          Name: xyz
 # PPC64:          Binding: Global
 # PPC64:          Section: Undefined
 # PPC64:        }
 # PPC64:        Symbol {
-# PPC64:          Name: zed@
+# PPC64:          Name: zed
 # PPC64:          Binding: Weak
 # PPC64:          Section: Undefined
 # PPC64:        }
 # PPC64:        Symbol {
-# PPC64:          Name: bar@
+# PPC64:          Name: bar
 # PPC64:          Binding: Global
 # PPC64:          Section: .text
 # PPC64:        }
 # PPC64:        Symbol {
-# PPC64:          Name: foo@
+# PPC64:          Name: foo
 # PPC64:          Binding: Global
 # PPC64:          Section: .text
 # PPC64:        }
@@ -241,8 +241,8 @@
 # PPC64-NEXT:   Num Buckets: 1
 # PPC64-NEXT:   First Hashed Symbol Index: 4
 # PPC64-NEXT:   Num Mask Words: 1
-# PPC64-NEXT:   Shift Count: 6
-# PPC64-NEXT:   Bloom Filter: [0x400000000004204]
+# PPC64-NEXT:   Shift Count: 26
+# PPC64-NEXT:   Bloom Filter: [0x400000000000204]
 # PPC64-NEXT:   Buckets: [4]
 # PPC64-NEXT:   Values: [0xB8860BA, 0xB887389]
 # PPC64-NEXT: }
diff --git a/test/ELF/gnu-ifunc-canon.s b/test/ELF/gnu-ifunc-canon.s
new file mode 100644
index 0000000..c14e137
--- /dev/null
+++ b/test/ELF/gnu-ifunc-canon.s
@@ -0,0 +1,92 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/gnu-ifunc-canon-ro-pcrel.s -o %t-ro-pcrel.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/gnu-ifunc-canon-ro-abs.s -o %t-ro-abs.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/gnu-ifunc-canon-rw-addend.s -o %t-rw-addend.o
+// RUN: ld.lld %t.o -o %t1
+// RUN: llvm-readobj -relocs %t1 | FileCheck --check-prefix=IREL2 %s
+// RUN: ld.lld %t.o %t-ro-pcrel.o -o %t2
+// RUN: llvm-readobj -relocs %t2 | FileCheck --check-prefix=IREL1 %s
+// RUN: ld.lld %t.o %t-ro-abs.o -o %t3
+// RUN: llvm-readobj -relocs %t3 | FileCheck --check-prefix=IREL1 %s
+// RUN: ld.lld %t.o %t-rw-addend.o -o %t4
+// RUN: llvm-readobj -relocs %t4 | FileCheck --check-prefix=IREL1 %s
+// RUN: llvm-objdump -s %t4 | FileCheck --check-prefix=DUMP %s
+// RUN: ld.lld %t.o %t-rw-addend.o -o %t4a -z retpolineplt
+// RUN: llvm-readobj -relocs %t4a | FileCheck --check-prefix=IREL1 %s
+// RUN: llvm-objdump -s %t4a | FileCheck --check-prefix=DUMP2 %s
+// RUN: ld.lld %t-ro-pcrel.o %t.o -o %t5
+// RUN: llvm-readobj -relocs %t5 | FileCheck --check-prefix=IREL1 %s
+// RUN: ld.lld %t-ro-abs.o %t.o -o %t6
+// RUN: llvm-readobj -relocs %t6 | FileCheck --check-prefix=IREL1 %s
+// RUN: ld.lld %t-rw-addend.o %t.o -o %t7
+// RUN: llvm-readobj -relocs %t7 | FileCheck --check-prefix=IREL1 %s
+// RUN: ld.lld %t.o -o %t8 -pie
+// RUN: llvm-readobj -relocs %t8 | FileCheck --check-prefix=IREL2 %s
+// RUN: ld.lld %t.o %t-ro-pcrel.o -o %t9 -pie
+// RUN: llvm-readobj -relocs %t9 | FileCheck --check-prefix=IREL1-REL2 %s
+// RUN: ld.lld %t.o %t-rw-addend.o -o %t10 -pie
+// RUN: llvm-readobj -relocs %t10 | FileCheck --check-prefix=IREL1-REL3 %s
+// RUN: ld.lld %t-ro-pcrel.o %t.o -o %t11 -pie
+// RUN: llvm-readobj -relocs %t11 | FileCheck --check-prefix=IREL1-REL2 %s
+// RUN: ld.lld %t-rw-addend.o %t.o -o %t12 -pie
+// RUN: llvm-readobj -relocs %t12 | FileCheck --check-prefix=IREL1-REL3 %s
+
+// Two relocs, one for the GOT and the other for .data.
+// IREL2-NOT: R_X86_64_
+// IREL2: .rela.plt
+// IREL2-NEXT: R_X86_64_IRELATIVE
+// IREL2-NEXT: R_X86_64_IRELATIVE
+// IREL2-NOT: R_X86_64_
+
+// One reloc for the canonical PLT.
+// IREL1-NOT: R_X86_64_
+// IREL1: .rela.plt
+// IREL1-NEXT: R_X86_64_IRELATIVE
+// IREL1-NOT: R_X86_64_
+
+// One reloc for the canonical PLT and two RELATIVE relocations pointing to it,
+// one in the GOT and one in .data.
+// IREL1-REL2-NOT: R_X86_64_
+// IREL1-REL2: .rela.dyn
+// IREL1-REL2-NEXT: R_X86_64_RELATIVE
+// IREL1-REL2-NEXT: R_X86_64_RELATIVE
+// IREL1-REL2: .rela.plt
+// IREL1-REL2-NEXT: R_X86_64_IRELATIVE
+// IREL1-REL2-NOT: R_X86_64_
+
+// One reloc for the canonical PLT and three RELATIVE relocations pointing to it,
+// one in the GOT and two in .data.
+// IREL1-REL3-NOT: R_X86_64_
+// IREL1-REL3: .rela.dyn
+// IREL1-REL3-NEXT: R_X86_64_RELATIVE
+// IREL1-REL3-NEXT: R_X86_64_RELATIVE
+// IREL1-REL3-NEXT: R_X86_64_RELATIVE
+// IREL1-REL3: .rela.plt
+// IREL1-REL3-NEXT: R_X86_64_IRELATIVE
+// IREL1-REL3-NOT: R_X86_64_
+
+// Make sure the static relocations look right, both with and without headers.
+// DUMP: Contents of section .plt:
+// DUMP-NEXT: 201010
+// DUMP: Contents of section .data:
+// DUMP-NEXT: 202000 10102000 00000000 11102000 00000000
+// DUMP: Contents of section .got:
+// DUMP-NEXT: 203000 10102000 00000000
+
+// DUMP2: Contents of section .plt:
+// DUMP2-NEXT: 201010
+// DUMP2: Contents of section .data:
+// DUMP2-NEXT: 202000 40102000 00000000 41102000 00000000
+// DUMP2: Contents of section .got:
+// DUMP2-NEXT: 203000 40102000 00000000
+
+lea ifunc@gotpcrel(%rip), %rbx
+
+.type ifunc STT_GNU_IFUNC
+.globl ifunc
+ifunc:
+ret
+
+.data
+.8byte ifunc
diff --git a/test/ELF/gnu-ifunc-dyntags.s b/test/ELF/gnu-ifunc-dyntags.s
index 81bd338..79a4a89 100644
--- a/test/ELF/gnu-ifunc-dyntags.s
+++ b/test/ELF/gnu-ifunc-dyntags.s
@@ -7,7 +7,7 @@
 ## Check we produce DT_PLTREL/DT_JMPREL/DT_PLTGOT and DT_PLTRELSZ tags
 ## when there are no other relocations except R_*_IRELATIVE.
 
-# CHECK:  Name          Size      Address
+# CHECK:  Name          Size   VMA
 # CHECK:  .rela.plt   00000030 0000000000000210
 # CHECK:  .got.plt    00000010 0000000000002000
 
diff --git a/test/ELF/gnu-ifunc-empty.s b/test/ELF/gnu-ifunc-empty.s
new file mode 100644
index 0000000..9079853
--- /dev/null
+++ b/test/ELF/gnu-ifunc-empty.s
@@ -0,0 +1,16 @@
+// REQUIRES: x86
+
+// Verifies that .rela_iplt_{start,end} point to a dummy section
+// if .rela.iplt does not exist.
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld -static %t.o -o %t.exe
+// RUN: llvm-objdump -syms %t.exe | FileCheck %s
+
+// CHECK: 0000000000200000 .text 00000000 .hidden __rela_iplt_end
+// CHECK: 0000000000200000 .text 00000000 .hidden __rela_iplt_start
+
+.globl _start
+_start:
+ movl $__rela_iplt_start, %edx
+ movl $__rela_iplt_end, %edx
diff --git a/test/ELF/gnu-ifunc-i386.s b/test/ELF/gnu-ifunc-i386.s
index bfc1587..ac41dbd 100644
--- a/test/ELF/gnu-ifunc-i386.s
+++ b/test/ELF/gnu-ifunc-i386.s
@@ -70,28 +70,46 @@
 // CHECK-NEXT: }
 // CHECK-NEXT: Symbol {
 // CHECK-NEXT:   Name: bar
+// CHECK-NEXT:   Value: 0x401030
+// CHECK-NEXT:   Size: 0
+// CHECK-NEXT:   Binding: Global
+// CHECK-NEXT:   Type: Function
+// CHECK-NEXT:   Other: 0
+// CHECK-NEXT:   Section: .plt
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT:   Name: bar_resolver
 // CHECK-NEXT:   Value: 0x401001
 // CHECK-NEXT:   Size: 0
 // CHECK-NEXT:   Binding: Global
-// CHECK-NEXT:   Type: GNU_IFunc
+// CHECK-NEXT:   Type: Function
 // CHECK-NEXT:   Other: 0
 // CHECK-NEXT:   Section: .text
 // CHECK-NEXT: }
 // CHECK-NEXT: Symbol {
 // CHECK-NEXT:   Name: foo
+// CHECK-NEXT:   Value: 0x401020
+// CHECK-NEXT:   Size: 0
+// CHECK-NEXT:   Binding: Global
+// CHECK-NEXT:   Type: Function
+// CHECK-NEXT:   Other: 0
+// CHECK-NEXT:   Section: .plt
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT:   Name: foo_resolver
 // CHECK-NEXT:   Value: 0x401000
 // CHECK-NEXT:   Size: 0
 // CHECK-NEXT:   Binding: Global
-// CHECK-NEXT:   Type: GNU_IFunc
+// CHECK-NEXT:   Type: Function
 // CHECK-NEXT:   Other: 0
 // CHECK-NEXT:   Section: .text
 // CHECK-NEXT: }
 // CHECK-NEXT:]
 
 // DISASM: Disassembly of section .text:
-// DISASM-NEXT: foo:
+// DISASM-NEXT: foo_resolver:
 // DISASM-NEXT:    401000: c3 retl
-// DISASM: bar:
+// DISASM: bar_resolver:
 // DISASM-NEXT:    401001: c3 retl
 // DISASM:      _start:
 // DISASM-NEXT:    401002: e8 19 00 00 00 calll 25
@@ -99,10 +117,11 @@
 // DISASM-NEXT:    40100c: ba d4 00 40 00 movl $4194516, %edx
 // DISASM-NEXT:    401011: ba e4 00 40 00 movl $4194532, %edx
 // DISASM-NEXT: Disassembly of section .plt:
-// DISASM-NEXT: .plt:
+// DISASM-NEXT: foo:
 // DISASM-NEXT:    401020: ff 25 00 20 40 00 jmpl *4202496
 // DISASM-NEXT:    401026: 68 10 00 00 00 pushl $16
 // DISASM-NEXT:    40102b: e9 e0 ff ff ff jmp -32 <_start+0xe>
+// DISASM:      bar:
 // DISASM-NEXT:    401030: ff 25 04 20 40 00 jmpl *4202500
 // DISASM-NEXT:    401036: 68 18 00 00 00 pushl $24
 // DISASM-NEXT:    40103b: e9 d0 ff ff ff jmp -48 <_start+0xe>
@@ -111,11 +130,17 @@
 .type foo STT_GNU_IFUNC
 .globl foo
 foo:
+.type foo_resolver STT_FUNC
+.globl foo_resolver
+foo_resolver:
  ret
 
 .type bar STT_GNU_IFUNC
 .globl bar
 bar:
+.type bar_resolver STT_FUNC
+.globl bar_resolver
+bar_resolver:
  ret
 
 .globl _start
diff --git a/test/ELF/gnu-unique.s b/test/ELF/gnu-unique.s
index 06f3704..83f0f23 100644
--- a/test/ELF/gnu-unique.s
+++ b/test/ELF/gnu-unique.s
@@ -20,7 +20,7 @@
 .type symb, @gnu_unique_object
 symb:
 
-# GNU:        Name: symb@
+# GNU:        Name: symb
 # GNU-NEXT:   Value:
 # GNU-NEXT:   Size: 0
 # GNU-NEXT:   Binding: Unique
@@ -29,7 +29,7 @@
 # GNU-NEXT:   Section: .data
 # GNU-NEXT: }
 
-# NO:        Name: symb@
+# NO:        Name: symb
 # NO-NEXT:   Value:
 # NO-NEXT:   Size: 0
 # NO-NEXT:   Binding: Global
diff --git a/test/ELF/got32-i386.s b/test/ELF/got32-i386.s
index ff67a4b..0080e1b 100644
--- a/test/ELF/got32-i386.s
+++ b/test/ELF/got32-i386.s
@@ -16,7 +16,7 @@
 # CHECK:       _start:
 # CHECK-NEXT:   401001: 8b 1d {{.*}}  movl 4202496, %ebx
 # CHECK: Sections:
-# CHECK:  Name Size     Address
+# CHECK:  Name Size     VMA
 # CHECK:  .got 00000004 0000000000402000
 
 # RUN: not ld.lld %t.o -o %t -pie 2>&1 | FileCheck %s --check-prefix=ERR
diff --git a/test/ELF/got32x-i386.s b/test/ELF/got32x-i386.s
index 88e7e31..7d3a1fc 100644
--- a/test/ELF/got32x-i386.s
+++ b/test/ELF/got32x-i386.s
@@ -38,7 +38,7 @@
 # CHECK-NEXT:   40100d: 8b 80 {{.*}} movl -4(%eax), %eax
 # CHECK-NEXT:   401013: 8b 83 {{.*}} movl -4(%ebx), %eax
 # CHECK: Sections:
-# CHECK:  Name Size     Address
+# CHECK:  Name Size     VMA
 # CHECK:  .got 00000004 0000000000403000
 
 # RUN: not ld.lld %S/Inputs/i386-got32x-baseless.elf -o %t1 -pie 2>&1 | \
diff --git a/test/ELF/i386-static-tls-model.s b/test/ELF/i386-static-tls-model.s
new file mode 100644
index 0000000..a6dbc6d
--- /dev/null
+++ b/test/ELF/i386-static-tls-model.s
@@ -0,0 +1,20 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/i386-static-tls-model1.s -o %t.o
+# RUN: ld.lld %t.o -o %t1 -shared
+# RUN: llvm-readobj -dynamic-table %t1 | FileCheck %s
+
+# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/i386-static-tls-model2.s -o %t.o
+# RUN: ld.lld %t.o -o %t2 -shared
+# RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s
+
+# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/i386-static-tls-model3.s -o %t.o
+# RUN: ld.lld %t.o -o %t3 -shared
+# RUN: llvm-readobj -dynamic-table %t3 | FileCheck %s
+
+# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/i386-static-tls-model4.s -o %t.o
+# RUN: ld.lld %t.o -o %t4 -shared
+# RUN: llvm-readobj -dynamic-table %t4 | FileCheck %s
+
+# CHECK: DynamicSection [
+# CHECK: FLAGS STATIC_TLS
diff --git a/test/ELF/i386-tls-ie-shared.s b/test/ELF/i386-tls-ie-shared.s
index 9e5ed1b..0e9694f 100644
--- a/test/ELF/i386-tls-ie-shared.s
+++ b/test/ELF/i386-tls-ie-shared.s
@@ -14,8 +14,8 @@
 // GOTRELSHARED-NEXT:     SHF_ALLOC
 // GOTRELSHARED-NEXT:     SHF_WRITE
 // GOTRELSHARED-NEXT:   ]
-// GOTRELSHARED-NEXT:   Address: 0x2058
-// GOTRELSHARED-NEXT:   Offset: 0x2058
+// GOTRELSHARED-NEXT:   Address: 0x2060
+// GOTRELSHARED-NEXT:   Offset: 0x2060
 // GOTRELSHARED-NEXT:   Size: 16
 // GOTRELSHARED-NEXT:   Link: 0
 // GOTRELSHARED-NEXT:   Info: 0
@@ -32,36 +32,36 @@
 // GOTRELSHARED-NEXT:     0x102D R_386_RELATIVE - 0x0
 // GOTRELSHARED-NEXT:     0x1036 R_386_RELATIVE - 0x0
 // GOTRELSHARED-NEXT:     0x103F R_386_RELATIVE - 0x0
-// GOTRELSHARED-NEXT:     0x2058 R_386_TLS_TPOFF tlslocal0 0x0
-// GOTRELSHARED-NEXT:     0x205C R_386_TLS_TPOFF tlslocal1 0x0
-// GOTRELSHARED-NEXT:     0x2060 R_386_TLS_TPOFF tlsshared0 0x0
-// GOTRELSHARED-NEXT:     0x2064 R_386_TLS_TPOFF tlsshared1 0x0
+// GOTRELSHARED-NEXT:     0x2060 R_386_TLS_TPOFF tlslocal0 0x0
+// GOTRELSHARED-NEXT:     0x2064 R_386_TLS_TPOFF tlslocal1 0x0
+// GOTRELSHARED-NEXT:     0x2068 R_386_TLS_TPOFF tlsshared0 0x0
+// GOTRELSHARED-NEXT:     0x206C R_386_TLS_TPOFF tlsshared1 0x0
 // GOTRELSHARED-NEXT:   }
 // GOTRELSHARED-NEXT: ]
 // GOTRELSHARED:      0x6FFFFFFA RELCOUNT             8
 
 // DISASMSHARED:       Disassembly of section test:
 // DISASMSHARED-NEXT:  _start:
-// (.got)[0] = 0x2058 = 8280
-// (.got)[1] = 0x205C = 8284
-// (.got)[2] = 0x2060 = 8288
-// (.got)[3] = 0x2064 = 8292
-// DISASMSHARED-NEXT:  1000: 8b 0d 58 20 00 00   movl  8280, %ecx
-// DISASMSHARED-NEXT:  1006: 65 8b 01  movl  %gs:(%ecx), %eax
-// DISASMSHARED-NEXT:  1009: a1 58 20 00 00  movl  8280, %eax
-// DISASMSHARED-NEXT:  100e: 65 8b 00  movl  %gs:(%eax), %eax
-// DISASMSHARED-NEXT:  1011: 03 0d 58 20 00 00   addl  8280, %ecx
-// DISASMSHARED-NEXT:  1017: 65 8b 01  movl  %gs:(%ecx), %eax
-// DISASMSHARED-NEXT:  101a: 8b 0d 5c 20 00 00   movl  8284, %ecx
-// DISASMSHARED-NEXT:  1020: 65 8b 01  movl  %gs:(%ecx), %eax
-// DISASMSHARED-NEXT:  1023: a1 5c 20 00 00  movl  8284, %eax
-// DISASMSHARED-NEXT:  1028: 65 8b 00  movl  %gs:(%eax), %eax
-// DISASMSHARED-NEXT:  102b: 03 0d 5c 20 00 00   addl  8284, %ecx
-// DISASMSHARED-NEXT:  1031: 65 8b 01  movl  %gs:(%ecx), %eax
-// DISASMSHARED-NEXT:  1034: 8b 0d 60 20 00 00   movl  8288, %ecx
-// DISASMSHARED-NEXT:  103a: 65 8b 01  movl  %gs:(%ecx), %eax
-// DISASMSHARED-NEXT:  103d: 03 0d 64 20 00 00   addl  8292, %ecx
-// DISASMSHARED-NEXT:  1043: 65 8b 01  movl  %gs:(%ecx), %eax
+// (.got)[0] = 0x2060 = 8288
+// (.got)[1] = 0x2064 = 8292
+// (.got)[2] = 0x2068 = 8296
+// (.got)[3] = 0x206C = 8300
+// DISASMSHARED-NEXT:  1000: {{.*}} movl  8288, %ecx
+// DISASMSHARED-NEXT:  1006: {{.*}} movl  %gs:(%ecx), %eax
+// DISASMSHARED-NEXT:  1009: {{.*}} movl  8288, %eax
+// DISASMSHARED-NEXT:  100e: {{.*}} movl  %gs:(%eax), %eax
+// DISASMSHARED-NEXT:  1011: {{.*}} addl  8288, %ecx
+// DISASMSHARED-NEXT:  1017: {{.*}} movl  %gs:(%ecx), %eax
+// DISASMSHARED-NEXT:  101a: {{.*}} movl  8292, %ecx
+// DISASMSHARED-NEXT:  1020: {{.*}} movl  %gs:(%ecx), %eax
+// DISASMSHARED-NEXT:  1023: {{.*}} movl  8292, %eax
+// DISASMSHARED-NEXT:  1028: {{.*}} movl  %gs:(%eax), %eax
+// DISASMSHARED-NEXT:  102b: {{.*}} addl  8292, %ecx
+// DISASMSHARED-NEXT:  1031: {{.*}} movl  %gs:(%ecx), %eax
+// DISASMSHARED-NEXT:  1034: {{.*}} movl  8296, %ecx
+// DISASMSHARED-NEXT:  103a: {{.*}} movl  %gs:(%ecx), %eax
+// DISASMSHARED-NEXT:  103d: {{.*}} addl  8300, %ecx
+// DISASMSHARED-NEXT:  1043: {{.*}} movl  %gs:(%ecx), %eax
 
 .type tlslocal0,@object
 .section .tbss,"awT",@nobits
diff --git a/test/ELF/icf-symbol-type.s b/test/ELF/icf-symbol-type.s
index 9cc1c50..350f203 100644
--- a/test/ELF/icf-symbol-type.s
+++ b/test/ELF/icf-symbol-type.s
@@ -7,8 +7,8 @@
 # We used to mark bar as absolute.
 
 # CHECK: .text             PROGBITS        0000000000001000
-# CHECK: 0000000000001001 0 NOTYPE  GLOBAL DEFAULT   4 foo
 # CHECK: 0000000000001001 0 NOTYPE  GLOBAL DEFAULT   4 bar
+# CHECK: 0000000000001001 0 NOTYPE  GLOBAL DEFAULT   4 foo
 
 # The nop makes the test more interesting by making the offset of
 # text.f non zero.
diff --git a/test/ELF/invalid/invalid-soname.test b/test/ELF/invalid/invalid-soname.test
index 8641465..bf4b33c 100644
--- a/test/ELF/invalid/invalid-soname.test
+++ b/test/ELF/invalid/invalid-soname.test
@@ -14,5 +14,8 @@
   - Name:          .test
     Type:          SHT_DYNAMIC
     Flags:         [ SHF_ALLOC ]
-    Content:         "0e000000000000000000000000000001"
     Link:          .strtab
+    EntSize:       0x0000000000000010
+    Entries:       
+      - Tag:         DT_SONAME
+        Value:       0x0100000000000000
diff --git a/test/ELF/linkerscript/addr.test b/test/ELF/linkerscript/addr.test
index db0568e..2e68cc2 100644
--- a/test/ELF/linkerscript/addr.test
+++ b/test/ELF/linkerscript/addr.test
@@ -4,7 +4,7 @@
 # RUN: llvm-objdump -section-headers %t1 | FileCheck %s
 
 # CHECK:      Sections:
-# CHECK-NEXT: Idx Name          Size      Address          Type
+# CHECK-NEXT: Idx Name          Size     VMA              Type
 # CHECK-NEXT:   0               00000000 0000000000000000
 # CHECK-NEXT:   1 .text         00000000 0000000000001000 TEXT
 # CHECK-NEXT:   2 .foo.1        00000008 0000000000001000 DATA
diff --git a/test/ELF/linkerscript/align-empty.test b/test/ELF/linkerscript/align-empty.test
index 63fe328..06d3945 100644
--- a/test/ELF/linkerscript/align-empty.test
+++ b/test/ELF/linkerscript/align-empty.test
@@ -13,7 +13,7 @@
 }
 
 # CHECK:      Sections:
-# CHECK-NEXT: Idx Name          Size      Address
+# CHECK-NEXT: Idx Name          Size     VMA
 # CHECK-NEXT:   0               00000000 0000000000000000
 # CHECK-NEXT:   1 .dynsym       00000018 0000000000000190
 # CHECK-NEXT:   2 .gnu.hash     0000001c 00000000000001a8
diff --git a/test/ELF/linkerscript/align1.test b/test/ELF/linkerscript/align1.test
index 5804bf9..70d1141 100644
--- a/test/ELF/linkerscript/align1.test
+++ b/test/ELF/linkerscript/align1.test
@@ -13,7 +13,7 @@
 }
 
 # CHECK:      Sections:
-# CHECK-NEXT: Idx Name          Size      Address          Type
+# CHECK-NEXT: Idx Name          Size     VMA              Type
 # CHECK-NEXT:   0               00000000 0000000000000000
 # CHECK-NEXT:   1 .aaa          00000008 0000000000010000 DATA
 # CHECK-NEXT:   2 .bbb          00000008 0000000000011000 DATA
@@ -25,7 +25,7 @@
 # RUN: llvm-objdump -section-headers %t4 | FileCheck %s -check-prefix=ZERO
 
 # ZERO:      Sections:
-# ZERO-NEXT: Idx Name          Size      Address         Type
+# ZERO-NEXT: Idx Name          Size     VMA              Type
 # ZERO-NEXT:   0               00000000 0000000000000000
 # ZERO-NEXT:   1 .aaa          00000008 0000000000000123 DATA
 
diff --git a/test/ELF/linkerscript/align2.test b/test/ELF/linkerscript/align2.test
index a9003a4..56aba47 100644
--- a/test/ELF/linkerscript/align2.test
+++ b/test/ELF/linkerscript/align2.test
@@ -13,7 +13,7 @@
 }
 
 # CHECK:      Sections:
-# CHECK-NEXT: Idx Name          Size      Address          Type
+# CHECK-NEXT: Idx Name          Size     VMA              Type
 # CHECK-NEXT:   0               00000000 0000000000000000
 # CHECK-NEXT:   1 .aaa          00000008 0000000000010000 DATA
 # CHECK-NEXT:   2 .bbb          00000008 0000000000011000 DATA
diff --git a/test/ELF/linkerscript/align3.test b/test/ELF/linkerscript/align3.test
index 2a091fc..8c9146e 100644
--- a/test/ELF/linkerscript/align3.test
+++ b/test/ELF/linkerscript/align3.test
@@ -11,7 +11,7 @@
 }
 
 # CHECK:      Sections:
-# CHECK-NEXT: Idx Name          Size      Address          Type
+# CHECK-NEXT: Idx Name          Size     VMA              Type
 # CHECK-NEXT:   0               00000000 0000000000000000
 # CHECK-NEXT:   1 .aaa          00000008 0000000000010000 DATA
 # CHECK-NEXT:   2 .bbb          00000008 0000000000011000 DATA
diff --git a/test/ELF/linkerscript/align4.test b/test/ELF/linkerscript/align4.test
index 9440d60..834e843 100644
--- a/test/ELF/linkerscript/align4.test
+++ b/test/ELF/linkerscript/align4.test
@@ -4,7 +4,6 @@
 # RUN: llvm-objdump -t %t | FileCheck %s
 
 # CHECK-LABEL: SYMBOL TABLE:
-# CHECK-NEXT: 0000000000000000         *UND*           00000000
 # CHECK-NEXT: 0000000000014008         .text           00000000 _start
 # CHECK-NEXT: 0000000000010000         *ABS*           00000000 __code_base__
 # CHECK-NEXT: 0000000000001000         *ABS*           00000000 VAR
diff --git a/test/ELF/linkerscript/at2.test b/test/ELF/linkerscript/at2.test
index 82c9ae1..e45a716 100644
--- a/test/ELF/linkerscript/at2.test
+++ b/test/ELF/linkerscript/at2.test
@@ -48,7 +48,7 @@
 # CHECK-NEXT:   }
 
 # SECTIONS:      Sections:
-# SECTIONS-NEXT: Idx Name          Size      Address
+# SECTIONS-NEXT: Idx Name          Size     VMA
 # SECTIONS-NEXT:   0               00000000 0000000000000000
 # SECTIONS-NEXT:   1 .foo1         00000008 0000000000002000
 # SECTIONS-NEXT:   2 .foo2         00000008 0000000000002008
diff --git a/test/ELF/linkerscript/insert-after.test b/test/ELF/linkerscript/insert-after.test
index 4260cd7..005c150 100644
--- a/test/ELF/linkerscript/insert-after.test
+++ b/test/ELF/linkerscript/insert-after.test
@@ -16,7 +16,7 @@
 # RUN: ld.lld %t1.o -o %t1 --script %p/Inputs/insert-after.script --script %s
 # RUN: llvm-objdump -section-headers %t1 | FileCheck %s
 # CHECK:      Sections:
-# CHECK-NEXT: Idx Name          Size      Address          Type
+# CHECK-NEXT: Idx Name          Size     VMA              Type
 # CHECK-NEXT:   0               00000000 0000000000000000
 # CHECK-NEXT:   1 .text         00000008 0000000000000000 TEXT
 # CHECK-NEXT:   2 .foo.text     00000008 0000000000000008 TEXT
diff --git a/test/ELF/linkerscript/insert-before.test b/test/ELF/linkerscript/insert-before.test
index 52317be..24fdd69 100644
--- a/test/ELF/linkerscript/insert-before.test
+++ b/test/ELF/linkerscript/insert-before.test
@@ -16,7 +16,7 @@
 # RUN: ld.lld %t1.o -o %t1 --script %p/Inputs/insert-after.script --script %s
 # RUN: llvm-objdump -section-headers %t1 | FileCheck %s
 # CHECK:      Sections:
-# CHECK-NEXT: Idx Name          Size      Address          Type
+# CHECK-NEXT: Idx Name          Size     VMA         Type
 # CHECK-NEXT:   0               00000000 0000000000000000
 # CHECK-NEXT:   1 .foo.text     00000008 0000000000000000 TEXT
 # CHECK-NEXT:   2 .text         00000008 0000000000000008 TEXT
diff --git a/test/ELF/linkerscript/linkerscript.s b/test/ELF/linkerscript/linkerscript.s
index 39d2d46..5e1cf27 100644
--- a/test/ELF/linkerscript/linkerscript.s
+++ b/test/ELF/linkerscript/linkerscript.s
@@ -3,7 +3,7 @@
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
 # RUN:   %p/Inputs/libsearch-st.s -o %t2.o
 
-# RUN: echo "EXTERN( undef undef2 )" > %t.script
+# RUN: echo "EXTERN( undef undef2 \"undef3\" \"undef4@@other\")" > %t.script
 # RUN: ld.lld %t -o %t2 %t.script
 # RUN: llvm-readobj %t2 > /dev/null
 
diff --git a/test/ELF/linkerscript/locationcountererr2.s b/test/ELF/linkerscript/locationcountererr2.s
index 9efe86a..3a0c769 100644
--- a/test/ELF/linkerscript/locationcountererr2.s
+++ b/test/ELF/linkerscript/locationcountererr2.s
@@ -4,7 +4,7 @@
 # RUN: echo ". = 0x150; . = 0x10; .text : {} }" >> %t.script
 # RUN: ld.lld %t.o --script %t.script -o %t -shared
 # RUN: llvm-objdump -section-headers %t | FileCheck %s
-# CHECK:  Name   Size      Address
+# CHECK:  Name   Size   VMA
 # CHECK: .text 00000000 0000000000000010
 
 # RUN: echo "SECTIONS { . = 0x20; . = ASSERT(0x1, "foo"); }" > %t2.script
diff --git a/test/ELF/linkerscript/memory3.s b/test/ELF/linkerscript/memory3.s
index 6a24313..3a49137 100644
--- a/test/ELF/linkerscript/memory3.s
+++ b/test/ELF/linkerscript/memory3.s
@@ -14,7 +14,7 @@
 
 ## Check we place .text into first defined memory region with appropriate flags.
 # CHECK: Sections:
-# CHECK: Idx Name  Size      Address
+# CHECK: Idx Name  Size     VMA
 # CHECK:   0       00000000 0000000000000000
 # CHECK:   1 .text 00000001 0000000000001000
 
diff --git a/test/ELF/linkerscript/multi-sections-constraint.s b/test/ELF/linkerscript/multi-sections-constraint.s
index bfedd10..c1a253a 100644
--- a/test/ELF/linkerscript/multi-sections-constraint.s
+++ b/test/ELF/linkerscript/multi-sections-constraint.s
@@ -8,7 +8,7 @@
 # RUN: llvm-objdump -section-headers %t1 | FileCheck %s
 
 # CHECK:      Sections:
-# CHECK-NEXT: Idx Name          Size      Address          Type
+# CHECK-NEXT: Idx Name          Size      VMA          Type
 # CHECK: .aaa          00000010 0000000000002000 DATA
 
 
@@ -20,7 +20,7 @@
 # RUN: llvm-objdump -section-headers %t2 | FileCheck %s --check-prefix=REV
 
 # REV:      Sections:
-# REV-NEXT: Idx Name          Size      Address          Type
+# REV-NEXT: Idx Name          Size       VMA          Type
 # REV:  .aaa          00000010 0000000000001000 DATA
 
 .global _start
diff --git a/test/ELF/linkerscript/non-absolute2.test b/test/ELF/linkerscript/non-absolute2.test
index b606664..2d08354 100644
--- a/test/ELF/linkerscript/non-absolute2.test
+++ b/test/ELF/linkerscript/non-absolute2.test
@@ -9,7 +9,7 @@
 }
 
 # CHECK:       Sections:
-# CHECK-NEXT:  Idx Name          Size      Address
+# CHECK-NEXT:  Idx Name          Size     VMA
 # CHECK-NEXT:    0               00000000 0000000000000000
 # CHECK-NEXT:    1 .dynsym       00000030 0000000000001000
 # CHECK:         5 .text         00000000 000000000000106c
diff --git a/test/ELF/linkerscript/numbers.s b/test/ELF/linkerscript/numbers.s
index 98d7e33..ceb85fd 100644
--- a/test/ELF/linkerscript/numbers.s
+++ b/test/ELF/linkerscript/numbers.s
@@ -18,7 +18,7 @@
 # RUN: llvm-objdump -section-headers %t2 | FileCheck %s
 
 # CHECK:     Sections:
-# CHECK-NEXT: Idx Name          Size      Address
+# CHECK-NEXT: Idx Name          Size     VMA
 # CHECK-NEXT:   0               00000000 0000000000000000
 # CHECK-NEXT:   1 .hex1         00000008 0000000000001000
 # CHECK-NEXT:   2 .hex2         00000008 0000000000001010
@@ -67,7 +67,7 @@
 # RUN: ld.lld %t --script %t8.script -o %t6
 # RUN: llvm-objdump -section-headers %t6 | FileCheck -check-prefix=SECADDR %s
 # SECADDR:     Sections:
-# SECADDR-NEXT: Idx Name          Size      Address
+# SECADDR-NEXT: Idx Name          Size     VMA
 # SECADDR-NEXT:   0               00000000 0000000000000000
 # SECADDR-NEXT:   1 .hex1         00000008 0000000000000400
 # SECADDR-NEXT:   2 .hex2         00000008 0000000000000500
diff --git a/test/ELF/linkerscript/out-of-order.s b/test/ELF/linkerscript/out-of-order.s
index da8c103..fbab435 100644
--- a/test/ELF/linkerscript/out-of-order.s
+++ b/test/ELF/linkerscript/out-of-order.s
@@ -22,7 +22,7 @@
 # must take responsibility to make sure this does not happen.
 
 # CHECK:      Sections:
-# CHECK-NEXT: Idx Name          Size      Address          Type
+# CHECK-NEXT: Idx Name          Size     VMA              Type
 # CHECK-NEXT:   0               00000000 0000000000000000
 # CHECK-NEXT:   1 .data         00000008 0000000000004000
 # CHECK-NEXT:   2 .dynamic      00000060 0000000000004008
diff --git a/test/ELF/linkerscript/provide-shared2.s b/test/ELF/linkerscript/provide-shared2.s
index 8a3200b..3c55d2f 100644
--- a/test/ELF/linkerscript/provide-shared2.s
+++ b/test/ELF/linkerscript/provide-shared2.s
@@ -6,7 +6,7 @@
 # RUN: ld.lld -o %t --script %t.script %t.o %t2.so
 # RUN: llvm-readelf --dyn-symbols %t | FileCheck  %s
 
-# CHECK: 1 1: 000000000000002a 0 NOTYPE GLOBAL DEFAULT ABS foo@
+# CHECK: 1: 000000000000002a 0 NOTYPE GLOBAL DEFAULT ABS foo
 
 .global _start
 _start:
diff --git a/test/ELF/linkerscript/repsection-va.s b/test/ELF/linkerscript/repsection-va.s
index 8a50fc0..5da94d0 100644
--- a/test/ELF/linkerscript/repsection-va.s
+++ b/test/ELF/linkerscript/repsection-va.s
@@ -5,7 +5,7 @@
 # RUN: ld.lld -o %t1 --script %t.script %t
 # RUN: llvm-objdump -section-headers %t1 | FileCheck %s
 # CHECK:      Sections:
-# CHECK-NEXT: Idx Name          Size      Address          Type
+# CHECK-NEXT: Idx Name          Size     VMA          Type
 # CHECK-NOT: .foo
 # CHECK:  .foo          00000008 {{.*}} DATA
 # CHECK-NOT: .foo
diff --git a/test/ELF/linkerscript/sections-gc2.s b/test/ELF/linkerscript/sections-gc2.s
index e2941aa..7b1fa8d 100644
--- a/test/ELF/linkerscript/sections-gc2.s
+++ b/test/ELF/linkerscript/sections-gc2.s
@@ -8,7 +8,7 @@
 # RUN: ld.lld -T %t.script -o %t.so %t.o --gc-sections
 # RUN: llvm-objdump -h %t.so | FileCheck %s
 
-# CHECK: Idx Name          Size      Address          Type
+# CHECK: Idx Name          Size      VMA          Type
 # CHECK-NEXT:  0
 # CHECK-NEXT:    used_in_reloc
 # CHECK-NEXT:    .text
diff --git a/test/ELF/linkerscript/segment-none.s b/test/ELF/linkerscript/segment-none.s
index 36d09e7..8573974 100644
--- a/test/ELF/linkerscript/segment-none.s
+++ b/test/ELF/linkerscript/segment-none.s
@@ -23,7 +23,7 @@
 
 # CHECK: Section to Segment mapping:
 # CHECK-NEXT: Segment Sections...
-# CHECK-NOT: .foo
+# CHECK: None {{.*}}.foo
 
 # DEFINED: Section to Segment mapping:
 # DEFINED-NEXT: Segment Sections...
diff --git a/test/ELF/linkerscript/sizeof.s b/test/ELF/linkerscript/sizeof.s
index 4618f79..0d7106f 100644
--- a/test/ELF/linkerscript/sizeof.s
+++ b/test/ELF/linkerscript/sizeof.s
@@ -18,7 +18,6 @@
 # CHECK-NEXT:    2 .bbb          00000010
 # CHECK-NEXT:    3 .ccc          00000018
 # CHECK:      SYMBOL TABLE:
-# CHECK-NEXT:  0000000000000000 *UND* 00000000
 # CHECK-NEXT:                   .text 00000000 _start
 # CHECK-NEXT:  0000000000000008 *ABS* 00000000 _aaa
 # CHECK-NEXT:  0000000000000010 *ABS* 00000000 _bbb
diff --git a/test/ELF/linkerscript/sizeofheaders.s b/test/ELF/linkerscript/sizeofheaders.s
index 3cc7074..6a82442 100644
--- a/test/ELF/linkerscript/sizeofheaders.s
+++ b/test/ELF/linkerscript/sizeofheaders.s
@@ -9,7 +9,6 @@
 # RUN: llvm-objdump -t %t1 | FileCheck %s
 
 #CHECK:      SYMBOL TABLE:
-#CHECK-NEXT:  0000000000000000 *UND* 00000000
 #CHECK-NEXT:  00000000000000e8 .text 00000000 _start
 #CHECK-NEXT:  00000000000000e8 *ABS* 00000000 _size
 
diff --git a/test/ELF/linkerscript/symbol-assignexpr.s b/test/ELF/linkerscript/symbol-assignexpr.s
index 3be7d05..56e0827 100644
--- a/test/ELF/linkerscript/symbol-assignexpr.s
+++ b/test/ELF/linkerscript/symbol-assignexpr.s
@@ -25,7 +25,6 @@
 # RUN: llvm-objdump -t %t1 | FileCheck %s
 
 # CHECK:      SYMBOL TABLE:
-# CHECK-NEXT: 0000000000000000 *UND* 00000000
 # CHECK-NEXT: 0000000000000000 .text 00000000 _start
 # CHECK-NEXT: 0000000000005678 *ABS* 00000000 bar
 # CHECK-NEXT: 0000000000009abc *ABS* 00000000 baz
diff --git a/test/ELF/linkerscript/symbol-location.s b/test/ELF/linkerscript/symbol-location.s
new file mode 100644
index 0000000..323d237
--- /dev/null
+++ b/test/ELF/linkerscript/symbol-location.s
@@ -0,0 +1,15 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "foo = 1;" > %t.script
+# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | FileCheck %s
+
+## Here we check that symbol 'foo' location is reported properly.
+
+# CHECK: error: relocation R_X86_64_PLT32 cannot refer to absolute symbol: foo
+# CHECK: >>> defined in {{.*}}.script:1
+# CHECK: >>> referenced by {{.*}}.o:(.text+0x1)
+
+.text
+.globl _start
+_start:
+ call foo@PLT
diff --git a/test/ELF/linkerscript/symbol-memoryexpr.s b/test/ELF/linkerscript/symbol-memoryexpr.s
index cdd821d..9214ba8 100644
--- a/test/ELF/linkerscript/symbol-memoryexpr.s
+++ b/test/ELF/linkerscript/symbol-memoryexpr.s
@@ -13,7 +13,6 @@
 # RUN: llvm-objdump -t %t1 | FileCheck %s
 
 # CHECK:      SYMBOL TABLE:
-# CHECK-NEXT: 0000000000000000 *UND* 00000000
 # CHECK-NEXT: 0000000000008000 .text 00000000 _start
 # CHECK-NEXT: 0000000000008000 *ABS* 00000000 origin
 # CHECK-NEXT: 0000000000040000 *ABS* 00000000 length
diff --git a/test/ELF/linkerscript/symbol-only.test b/test/ELF/linkerscript/symbol-only.test
index f2fefdc..9951e9c 100644
--- a/test/ELF/linkerscript/symbol-only.test
+++ b/test/ELF/linkerscript/symbol-only.test
@@ -12,7 +12,7 @@
 }
 
 # CHECK:      Sections:
-# CHECK-NEXT: Idx Name          Size      Address
+# CHECK-NEXT: Idx Name          Size     VMA
 # CHECK-NEXT:   0               00000000 0000000000000000
 # CHECK:          abc           00000000 [[ADDR:[0-9a-f]*]]
 # CHECK:          bar           00000000 0000000000001000
diff --git a/test/ELF/linkerscript/va.s b/test/ELF/linkerscript/va.s
index c305f06..bbf55cb 100644
--- a/test/ELF/linkerscript/va.s
+++ b/test/ELF/linkerscript/va.s
@@ -5,7 +5,7 @@
 # RUN: ld.lld -o %t1 --script %t.script %t
 # RUN: llvm-objdump -section-headers %t1 | FileCheck %s
 # CHECK:      Sections:
-# CHECK-NEXT: Idx Name          Size      Address
+# CHECK-NEXT: Idx Name          Size     VMA
 # CHECK-NEXT:   0               00000000 0000000000000000
 # CHECK-NEXT:   1 .foo          00000004 0000000000000000
 # CHECK-NEXT:   2 .boo          00000004 0000000000000004
diff --git a/test/ELF/linkerscript/version-script.s b/test/ELF/linkerscript/version-script.s
index df666e1..67a0fd6 100644
--- a/test/ELF/linkerscript/version-script.s
+++ b/test/ELF/linkerscript/version-script.s
@@ -14,11 +14,11 @@
 # CHECK:      Symbols [
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Version: 0
-# CHECK-NEXT:     Name: @
+# CHECK-NEXT:     Name:
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Version: 0
-# CHECK-NEXT:     Name: und@
+# CHECK-NEXT:     Name: und
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Version: 2
@@ -41,7 +41,7 @@
 # UNDEF:      Symbols [
 # UNDEF-NEXT:   Symbol {
 # UNDEF-NEXT:     Version: 0
-# UNDEF-NEXT:     Name: @
+# UNDEF-NEXT:     Name:
 # UNDEF-NEXT:   }
 # UNDEF-NEXT:   Symbol {
 # UNDEF-NEXT:     Version: 2
diff --git a/test/ELF/local-dynamic.s b/test/ELF/local-dynamic.s
index c122074..0adad2b 100644
--- a/test/ELF/local-dynamic.s
+++ b/test/ELF/local-dynamic.s
@@ -65,7 +65,7 @@
 
 // CHECK: DynamicSymbols [
 // CHECK-NEXT:   Symbol {
-// CHECK-NEXT:     Name: @
+// CHECK-NEXT:     Name:
 // CHECK-NEXT:     Value: 0x0
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Local
@@ -74,7 +74,7 @@
 // CHECK-NEXT:     Section: Undefined
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Symbol {
-// CHECK-NEXT:     Name: _start@
+// CHECK-NEXT:     Name: _start
 // CHECK-NEXT:     Value:
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Global
diff --git a/test/ELF/local-ver-preemptible.s b/test/ELF/local-ver-preemptible.s
index b99f700..80d78c4 100644
--- a/test/ELF/local-ver-preemptible.s
+++ b/test/ELF/local-ver-preemptible.s
@@ -14,8 +14,8 @@
 
 # CHECK:      Symbol table '.dynsym' contains 2 entries:
 # CHECK-NEXT:   Num:    Value          Size Type    Bind   Vis      Ndx Name
-# CHECK-NEXT:     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND @
-# CHECK-NEXT:     1: 0000000000201020     0 FUNC    GLOBAL DEFAULT  UND foo@
+# CHECK-NEXT:     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
+# CHECK-NEXT:     1: 0000000000201020     0 FUNC    GLOBAL DEFAULT  UND foo
 
 .globl _start
 _start:
diff --git a/test/ELF/lto/dynamic-list.ll b/test/ELF/lto/dynamic-list.ll
index c5473d8..84b667b 100644
--- a/test/ELF/lto/dynamic-list.ll
+++ b/test/ELF/lto/dynamic-list.ll
@@ -4,7 +4,7 @@
 ; RUN: ld.lld -o %t --dynamic-list %t.list -pie %t.o
 ; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
 
-; CHECK:      Name:     foo@
+; CHECK:      Name:     foo
 ; CHECK-NEXT: Value:    0x1010
 ; CHECK-NEXT: Size:     1
 ; CHECK-NEXT: Binding:  Global (0x1)
diff --git a/test/ELF/lto/shlib-undefined.ll b/test/ELF/lto/shlib-undefined.ll
index 6d37bfa..eec40cc 100644
--- a/test/ELF/lto/shlib-undefined.ll
+++ b/test/ELF/lto/shlib-undefined.ll
@@ -6,7 +6,7 @@
 ; RUN: ld.lld -o %t %t.o %t2.so
 ; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
 
-; CHECK:      Name:     __progname@
+; CHECK:      Name:     __progname
 ; CHECK-NEXT: Value:    0x201010
 ; CHECK-NEXT: Size:     1
 ; CHECK-NEXT: Binding:  Global (0x1)
diff --git a/test/ELF/lto/undefined-puts.ll b/test/ELF/lto/undefined-puts.ll
index 6c3dc76..f34abe6 100644
--- a/test/ELF/lto/undefined-puts.ll
+++ b/test/ELF/lto/undefined-puts.ll
@@ -25,4 +25,4 @@
 
 ; CHECK: DynamicSymbols [
 ; CHECK: Symbol {
-; CHECK:    Name: puts@
+; CHECK:    Name: puts
diff --git a/test/ELF/lto/version-script.ll b/test/ELF/lto/version-script.ll
index 35a36b5..eae5a35 100644
--- a/test/ELF/lto/version-script.ll
+++ b/test/ELF/lto/version-script.ll
@@ -21,7 +21,7 @@
 
 ; DSO: DynamicSymbols [
 ; DSO:   Symbol {
-; DSO:     Name: @ (0)
+; DSO:     Name:
 ; DSO:     Value: 0x0
 ; DSO:     Size: 0
 ; DSO:     Binding: Local
diff --git a/test/ELF/mips-dynamic.s b/test/ELF/mips-dynamic.s
index ebc2625..2852b50 100644
--- a/test/ELF/mips-dynamic.s
+++ b/test/ELF/mips-dynamic.s
@@ -97,9 +97,9 @@
 # DSO-NEXT:     Size: 8
 # DSO:      ]
 # DSO:      DynamicSymbols [
-# DSO:          Name: @
-# DSO:          Name: __start@
-# DSO:          Name: _foo@
+# DSO:          Name:
+# DSO:          Name: __start
+# DSO:          Name: _foo
 # DSO:      ]
 # DSO:      DynamicSection [
 # DSO-NEXT:   Tag        Type                 Name/Value
diff --git a/test/ELF/mips-dynsym-sort.s b/test/ELF/mips-dynsym-sort.s
index d1b935b..3f98b7c 100644
--- a/test/ELF/mips-dynsym-sort.s
+++ b/test/ELF/mips-dynsym-sort.s
@@ -36,7 +36,7 @@
 # the MIPS rules. v2 comes first as it is not in the GOT.
 # v1 and v3 are sorted according to their order in the GOT.
 # CHECK: DynamicSymbols [
-# CHECK:     Name: v2@
-# CHECK:     Name: v3@
-# CHECK:     Name: v1@
+# CHECK:     Name: v2
+# CHECK:     Name: v3
+# CHECK:     Name: v1
 # CHECK: ]
diff --git a/test/ELF/mips-got-and-copy.s b/test/ELF/mips-got-and-copy.s
index f4640bf..fed23d1 100644
--- a/test/ELF/mips-got-and-copy.s
+++ b/test/ELF/mips-got-and-copy.s
@@ -32,7 +32,7 @@
 # CHECK-NEXT:       Value: 0x[[DATA0]]
 # CHECK-NEXT:       Type: Object
 # CHECK-NEXT:       Section: .bss
-# CHECK-NEXT:       Name: data0@
+# CHECK-NEXT:       Name: data0
 # CHECK-NEXT:     }
 # CHECK-NEXT:     Entry {
 # CHECK-NEXT:       Address:
@@ -41,7 +41,7 @@
 # CHECK-NEXT:       Value: 0x[[DATA1]]
 # CHECK-NEXT:       Type: Object
 # CHECK-NEXT:       Section: .bss
-# CHECK-NEXT:       Name: data1@
+# CHECK-NEXT:       Name: data1
 # CHECK-NEXT:     }
 # CHECK-NEXT:   ]
 # CHECK-NEXT:   Number of TLS and multi-GOT entries: 0
diff --git a/test/ELF/mips-got-extsym.s b/test/ELF/mips-got-extsym.s
index ea57d77..b5063a8 100644
--- a/test/ELF/mips-got-extsym.s
+++ b/test/ELF/mips-got-extsym.s
@@ -43,7 +43,7 @@
 # CHECK-NEXT:     Value: 0x0
 # CHECK-NEXT:     Type: None
 # CHECK-NEXT:     Section: Undefined
-# CHECK-NEXT:     Name: _foo@
+# CHECK-NEXT:     Name: _foo
 # CHECK-NEXT:   }
 # CHECK-NEXT: ]
 
diff --git a/test/ELF/mips-got16.s b/test/ELF/mips-got16.s
index cf0847d..53734ed 100644
--- a/test/ELF/mips-got16.s
+++ b/test/ELF/mips-got16.s
@@ -96,7 +96,7 @@
 # GOT-NEXT:       Value: 0x0
 # GOT-NEXT:       Type: None
 # GOT-NEXT:       Section: Undefined
-# GOT-NEXT:       Name: foo@
+# GOT-NEXT:       Name: foo
 # GOT-NEXT:     }
 # GOT-NEXT:   ]
 # GOT-NEXT:   Number of TLS and multi-GOT entries: 0
diff --git a/test/ELF/mips-micro-jal.s b/test/ELF/mips-micro-jal.s
index 18d41cf..f41d7dc 100644
--- a/test/ELF/mips-micro-jal.s
+++ b/test/ELF/mips-micro-jal.s
@@ -57,9 +57,7 @@
 # EB-NEXT:    20022:       45 f9           jalrs16 $25
 # EB-NEXT:    20024:       0f 83           move    $gp, $3
 # EB-NEXT:    20026:       0c 00           nop
-# EB-NEXT:    20028:       00 00 00 00     nop
-# EB-NEXT:    2002c:       00 00 00 00     nop
-
+# EB-NEXT:                 ...
 # EB-NEXT:    20030:       79 00 3f f7     addiupc $2, 65500
 # EB-NEXT:    20034:       ff 22 00 00     lw      $25, 0($2)
 # EB-NEXT:    20038:       45 99           jr16    $25
@@ -76,9 +74,7 @@
 # EL-NEXT:    20022:       f9 45           jalrs16 $25
 # EL-NEXT:    20024:       83 0f           move    $gp, $3
 # EL-NEXT:    20026:       00 0c           nop
-# EL-NEXT:    20028:       00 00 00 00     nop
-# EL-NEXT:    2002c:       00 00 00 00     nop
-
+# EL-NEXT:                 ...
 # EL-NEXT:    20030:       00 79 f7 3f     addiupc $2, 65500
 # EL-NEXT:    20034:       22 ff 00 00     lw      $25, 0($2)
 # EL-NEXT:    20038:       99 45           jr16    $25
@@ -127,9 +123,7 @@
 # MIXED-NEXT:    20032:       45 f9           jalrs16 $25
 # MIXED-NEXT:    20034:       0f 83           move    $gp, $3
 # MIXED-NEXT:    20036:       0c 00           nop
-# MIXED-NEXT:    20038:       00 00 00 00     nop
-# MIXED-NEXT:    2003c:       00 00 00 00     nop
-
+# MIXED-NEXT:                 ...
 # MIXED-NEXT:    20040:       79 00 3f f3     addiupc $2, 65484
 # MIXED-NEXT:    20044:       ff 22 00 00     lw      $25, 0($2)
 # MIXED-NEXT:    20048:       45 99           jr16    $25
diff --git a/test/ELF/mips-micro-plt.s b/test/ELF/mips-micro-plt.s
index 6dcd6fb..24e90ae 100644
--- a/test/ELF/mips-micro-plt.s
+++ b/test/ELF/mips-micro-plt.s
@@ -80,7 +80,7 @@
 # CHECK-NEXT:       Value: 0x20041
 # CHECK-NEXT:       Type: Function
 # CHECK-NEXT:       Section: Undefined
-# CHECK-NEXT:       Name: foo0@
+# CHECK-NEXT:       Name: foo0
 # CHECK-NEXT:     }
 # CHECK-NEXT:   ]
 # CHECK-NEXT: }
diff --git a/test/ELF/mips-sto-plt.s b/test/ELF/mips-sto-plt.s
index b4d3ee3..4bd0d9e 100644
--- a/test/ELF/mips-sto-plt.s
+++ b/test/ELF/mips-sto-plt.s
@@ -9,7 +9,7 @@
 # RUN: llvm-readobj -dt -mips-plt-got %t.exe | FileCheck %s
 
 # CHECK:      Symbol {
-# CHECK:        Name: foo0@
+# CHECK:        Name: foo0
 # CHECK-NEXT:   Value: 0x0
 # CHECK-NEXT:   Size: 0
 # CHECK-NEXT:   Binding: Global
@@ -18,7 +18,7 @@
 # CHECK-NEXT:   Section: Undefined
 # CHECK-NEXT: }
 # CHECK-NEXT: Symbol {
-# CHECK-NEXT:   Name: foo1@
+# CHECK-NEXT:   Name: foo1
 # CHECK-NEXT:   Value: 0x[[FOO1:[0-9A-F]+]]
 # CHECK-NEXT:   Size: 0
 # CHECK-NEXT:   Binding: Global
diff --git a/test/ELF/msp430.s b/test/ELF/msp430.s
new file mode 100644
index 0000000..96820ac
--- /dev/null
+++ b/test/ELF/msp430.s
@@ -0,0 +1,43 @@
+; REQUIRES: msp430
+; RUN: llvm-mc -filetype=obj -triple=msp430-elf -o %t1.o %s
+; RUN: echo -e '.global _start\n _start: nop' | llvm-mc -filetype=obj -triple=msp430-elf -o %t2.o -
+; RUN: ld.lld -o %t.exe --Tdata=0x2000 --Ttext=0x8000 --defsym=_byte=0x21 %t2.o %t1.o
+; RUN: llvm-objdump -s -d %t.exe | FileCheck %s
+
+;; Check handling of basic msp430 relocation types.
+
+  .text
+  .global foo
+foo:
+;; R_MSP430_10_PCREL
+  jmp _start
+
+; CHECK:      Disassembly of section .text:
+; CHECK-NEXT: _start:
+; CHECK-NEXT: 8000: {{.*}} nop
+; CHECK:      foo:
+; CHECK-NEXT: 8004: {{.*}} jmp $-4
+
+;; R_MSP430_16_BYTE
+  call #_start
+
+; CHECK:      call #32768
+
+;; R_MSP430_16_PCREL_BYTE
+  mov #-1, _start
+
+; CHECK:      800a: {{.*}} mov #-1, -12
+
+  .data
+;; R_MSP430_8
+  .byte _byte
+;; R_MSP430_16
+  .word _start
+;; R_MSP430_32
+  .long _start
+
+; CHECK:      Contents of section .data:
+; CHECK-NEXT: 2000 21008000 800000
+
+; RUN: od -x %t.exe | FileCheck -check-prefix=TRAP %s
+; TRAP: 4343 4343 4343 4343 4343 4343 4343 4343
diff --git a/test/ELF/no-discard-this_module.s b/test/ELF/no-discard-this_module.s
new file mode 100644
index 0000000..3ce56d1
--- /dev/null
+++ b/test/ELF/no-discard-this_module.s
@@ -0,0 +1,41 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-linux-gnu -save-temp-labels %s -o %t
+// RUN: ld.lld %t -o %t2
+// RUN: llvm-readobj -s -sd -t %t2 | FileCheck %s
+
+.global _start
+_start:
+
+// This section and symbol is used by Linux kernel modules. Ensure it's not
+// accidentally discarded.
+.section .gnu.linkonce.this_module:
+__this_module:
+.byte 0x00
+
+// CHECK: Section {
+// CHECK:    Index:
+// CHECK:    Name: .gnu.linkonce.this_module
+// CHECK-NEXT:    Type: SHT_PROGBITS
+// CHECK-NEXT:    Flags [
+// CHECK-NEXT:    ]
+// CHECK-NEXT:    Address:
+// CHECK-NEXT:    Offset:
+// CHECK-NEXT:    Size:
+// CHECK-NEXT:    Link:
+// CHECK-NEXT:    Info:
+// CHECK-NEXT:    AddressAlignment:
+// CHECK-NEXT:    EntrySize:
+// CHECK-NEXT:    SectionData (
+// CHECK-NEXT:      0000: 00                                   |.|
+// CHECK-NEXT:    )
+// CHECK-NEXT:  }
+
+// CHECK:  Symbol {
+// CHECK:    Name: __this_module
+// CHECK-NEXT:    Value:
+// CHECK-NEXT:    Size:
+// CHECK-NEXT:    Binding: Local
+// CHECK-NEXT:    Type: None
+// CHECK-NEXT:    Other:
+// CHECK-NEXT:    Section: .gnu.linkonce.this_module:
+// CHECK-NEXT:  }
diff --git a/test/ELF/ppc64-bsymbolic-toc-restore.s b/test/ELF/ppc64-bsymbolic-toc-restore.s
index 49d347c..b7d9edd 100644
--- a/test/ELF/ppc64-bsymbolic-toc-restore.s
+++ b/test/ELF/ppc64-bsymbolic-toc-restore.s
@@ -53,7 +53,7 @@
 # CHECK-LABEL: caller
 # CHECK:         bl .+44
 # CHECK-NEXT:    mr 31, 3
-# CHECK-NEXT:    bl .+67108816
+# CHECK-NEXT:    bl .-48
 # CHECK-NEXT:    ld 2, 24(1)
 # CHECK-NEXT:    add 3, 3, 31
 # CHECK-NEXT:    addi 1, 1, 32
diff --git a/test/ELF/ppc64-call-reach.s b/test/ELF/ppc64-call-reach.s
index a02bfa8..e32497b 100644
--- a/test/ELF/ppc64-call-reach.s
+++ b/test/ELF/ppc64-call-reach.s
@@ -62,7 +62,7 @@
 # CHECK:  10010024: {{.*}}  b  .+33554428
 
 # NEGOFFSET-LABEL: test
-# NEGOFFSET:  10010014: {{.*}}  bl .+33554432
+# NEGOFFSET:  10010014: {{.*}}  bl .-33554432
 # NEGOFFSET:  10010024: {{.*}}  b  .+33554432
 
 # .branch_lt[0]
@@ -83,7 +83,7 @@
 # the offset is interpreted as a signed 26 bit value so 67108812 is actually
 # -52.
 # THUNK-LABEL: test:
-# THUNK: 10010034: {{.*}}  bl .+67108812
+# THUNK: 10010034: {{.*}}  bl .-52
 # THUNK: 10010044: {{.*}}  b .+67108812
 
 # The offset from the TOC to the .branch_lt section  is (-1 << 16) - 32768.
diff --git a/test/ELF/ppc64-dynamic-relocations.s b/test/ELF/ppc64-dynamic-relocations.s
index 2d9dfc6..a0484d4 100644
--- a/test/ELF/ppc64-dynamic-relocations.s
+++ b/test/ELF/ppc64-dynamic-relocations.s
@@ -25,7 +25,7 @@
 // There should be 2 reserved doublewords before the first entry. The dynamic
 // linker will fill those in with the address of the resolver entry point and
 // the dynamic object identifier.
-// DIS: Idx Name       Size      Address          Type
+// DIS: Idx Name       Size      VMA              Type
 // DIS:     .plt       00000018  0000000010030000 BSS
 
 // DT_PLTGOT should point to the start of the .plt section.
diff --git a/test/ELF/ppc64-error-missaligned-dq.s b/test/ELF/ppc64-error-missaligned-dq.s
index ea30ab8..68ad2e5 100644
--- a/test/ELF/ppc64-error-missaligned-dq.s
+++ b/test/ELF/ppc64-error-missaligned-dq.s
@@ -6,7 +6,7 @@
 # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
 # RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
 
-# CHECK: improper alignment for relocation R_PPC64_ADDR16_LO_DS: 0x8001 is not aligned to 16 bytes
+# CHECK: improper alignment for relocation R_PPC64_TOC16_LO_DS: 0x8001 is not aligned to 16 bytes
 
         .global test
         .p2align        4
diff --git a/test/ELF/ppc64-error-missaligned-ds.s b/test/ELF/ppc64-error-missaligned-ds.s
index 99a2c08..deee8f9 100644
--- a/test/ELF/ppc64-error-missaligned-ds.s
+++ b/test/ELF/ppc64-error-missaligned-ds.s
@@ -6,7 +6,7 @@
 # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
 # RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
 
-# CHECK: improper alignment for relocation R_PPC64_ADDR16_LO_DS: 0x8001 is not aligned to 4 bytes
+# CHECK: improper alignment for relocation R_PPC64_TOC16_LO_DS: 0x8001 is not aligned to 4 bytes
 
         .global test
         .p2align        4
diff --git a/test/ELF/ppc64-gd-to-ie.s b/test/ELF/ppc64-gd-to-ie.s
index 121032c..a11024a 100644
--- a/test/ELF/ppc64-gd-to-ie.s
+++ b/test/ELF/ppc64-gd-to-ie.s
@@ -69,10 +69,6 @@
         mtlr 0
         blr
 
-        .globl __tls_get_addr
-        .type __tls_get_addr,@function
-__tls_get_addr:
-
 
 # CheckGot: .got          00000018 00000000100200c0 DATA
 # .got is at 0x100200c0 so the toc-base is 100280c0.
diff --git a/test/ELF/ppc64-got-off.s b/test/ELF/ppc64-got-off.s
index 0a1a09e..d3dff22 100644
--- a/test/ELF/ppc64-got-off.s
+++ b/test/ELF/ppc64-got-off.s
@@ -8,6 +8,14 @@
 # RUN: ld.lld -shared --no-toc-optimize %t.o -o %t
 # RUN: llvm-objdump -d %t | FileCheck %s
 
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+# RUN: ld.lld -shared %t.o -o %t
+# RUN: llvm-objdump -d %t | FileCheck --check-prefix=OPT %s
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+# RUN: ld.lld -shared %t.o -o %t
+# RUN: llvm-objdump -d %t | FileCheck --check-prefix=OPT %s
+
         .abiversion 2
         .section ".text"
 
@@ -38,6 +46,15 @@
 # CHECK-NEXT:    li  6, 0
 # CHECK-NEXT:    ori 6, 6, 32776
 
+# OPT-LABEL: func
+# OPT:         nop
+# OPT-NEXT:    ld 3, -32760(2)
+# OPT-NEXT:    ld 4, -32760(2)
+# OPT-NEXT:    lis 5, -1
+# OPT-NEXT:    ori 5, 5, 32776
+# OPT-NEXT:    li  6, 0
+# OPT-NEXT:    ori 6, 6, 32776
+
 # Since the got entry for a is .got[1] and the TOC base points to
 # .got + 0x8000, the offset for a@got is -0x7FF8 --> -32760
 
diff --git a/test/ELF/ppc64-ifunc.s b/test/ELF/ppc64-ifunc.s
index 6f2d331..bd7f761 100644
--- a/test/ELF/ppc64-ifunc.s
+++ b/test/ELF/ppc64-ifunc.s
@@ -42,9 +42,9 @@
 # CHECK: _start:
 # CHECK-NEXT:     addis 2, 12, 2
 # CHECK-NEXT:     addi 2, 2, -32588
-# CHECK-NEXT:     bl .+67108812
+# CHECK-NEXT:     bl .-52
 # CHECK-NEXT:     ld 2, 24(1)
-# CHECK-NEXT:     bl .+67108824
+# CHECK-NEXT:     bl .-40
 # CHECK-NEXT:     ld 2, 24(1)
 
 # Check tocbase
diff --git a/test/ELF/ppc64-local-dynamic.s b/test/ELF/ppc64-local-dynamic.s
index 6ed3b0f..8a23863 100644
--- a/test/ELF/ppc64-local-dynamic.s
+++ b/test/ELF/ppc64-local-dynamic.s
@@ -113,7 +113,7 @@
 // Dis:     test:
 // Dis:        addis 3, 2, 0
 // Dis-NEXT:   addi 3, 3, -32760
-// Dis-NEXT:   bl .+67108804
+// Dis-NEXT:   bl .-60
 // Dis-NEXT:   ld 2, 24(1)
 // Dis-NEXT:   addis 3, 3, 0
 // Dis-NEXT:   lwa 3, -32768(3)
diff --git a/test/ELF/ppc64-plt-stub.s b/test/ELF/ppc64-plt-stub.s
index a644f48..95e28a5 100644
--- a/test/ELF/ppc64-plt-stub.s
+++ b/test/ELF/ppc64-plt-stub.s
@@ -22,7 +22,7 @@
 
 
 // CHECK:            _start:
-// CHECK:            bl .+67108824
+// CHECK:            bl .-40
         .text
         .abiversion 2
         .globl  _start
diff --git a/test/ELF/ppc64-rel-calls.s b/test/ELF/ppc64-rel-calls.s
index 4c79498..8423eb4 100644
--- a/test/ELF/ppc64-rel-calls.s
+++ b/test/ELF/ppc64-rel-calls.s
@@ -30,9 +30,8 @@
   nop
   blr
 
-# FIXME: The printing here is misleading, the branch offset here is negative.
-# CHECK: 1001000c:       {{.*}}     bl .+67108852
+# CHECK: 1001000c:       {{.*}}     bl .-12
 # CHECK: 10010010:       {{.*}}     nop
-# CHECK: 10010014:       {{.*}}     bl .+67108844
+# CHECK: 10010014:       {{.*}}     bl .-20
 # CHECK: 10010018:       {{.*}}     nop
 # CHECK: 1001001c:       {{.*}}     blr
diff --git a/test/ELF/ppc64-sort-small-cm-relocs.s b/test/ELF/ppc64-sort-small-cm-relocs.s
new file mode 100644
index 0000000..fbbecc7
--- /dev/null
+++ b/test/ELF/ppc64-sort-small-cm-relocs.s
@@ -0,0 +1,108 @@
+# REQUIRES: ppc
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-sort-small-cm-relocs-input2.s -o %t2.o
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-sort-small-cm-relocs-input3.s -o %t3.o
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-sort-small-cm-relocs-input4.s -o %t4.o
+
+# RUN: ld.lld %t1.o %t2.o %t3.o %t4.o -o %t -Map=%t.map
+# RUN: FileCheck %s < %t.map
+
+# Test an alternate link order.
+# RUN: ld.lld %t2.o %t3.o %t4.o %t1.o -o %t -Map=%t.map
+# RUN: FileCheck %s -check-prefix=ALTERNATE < %t.map
+
+# If a linker script has a sections command then allow that to override the
+# default sorting behavior.
+# RUN: echo "SECTIONS {          \
+# RUN:         .toc : {          \
+# RUN:            *ppc64-sort-small-cm-relocs.s.tmp4.o(.toc*) \
+# RUN:            *ppc64-sort-small-cm-relocs.s.tmp1.o(.toc*)  \
+# RUN:            *(.toc*)       \
+# RUN:          }                \
+# RUN:       } " > %t.script
+# RUN: ld.lld %t1.o %t2.o %t3.o %t4.o -o %t -script %t.script -Map=%t.map
+# RUN: FileCheck %s -check-prefix=SEC-CMD < %t.map
+
+# RUN: echo "SECTIONS { .text : {*(.text*)} } " > %t.script
+# RUN: ld.lld %t1.o %t2.o %t3.o %t4.o -o %t -script %t.script -Map=%t.map
+# RUN: FileCheck %s -check-prefix=SEC-CMD2 < %t.map
+
+# Default sort if the linker script does not have a sections command.
+# RUN: echo "" > %t.script
+# RUN: ld.lld %t1.o %t2.o %t3.o %t4.o -o %t -script %t.script -Map=%t.map
+# RUN: FileCheck %s -check-prefix=NOSEC < %t.map
+    .text
+
+    .global _start
+    .type _start,@function
+_start:
+    li 3, 55
+    blr
+
+    .type a,@object
+    .data
+    .global a
+a:
+    .long 10
+    .size a, 4
+
+    .type c,@object
+    .data
+    .global c
+c:
+    .long  55
+    .size  c, 4
+
+    .type   d,@object
+    .global d
+d:
+    .long 33
+    .size d, 4
+
+    # .toc section contains only some constants.
+    .section        .toc,"aw",@progbits
+    .quad 0xa1a1a1a1a1a1a1a1
+    .quad 0xb2b2b2b2b2b2b2b2
+
+# Input files tmp3.o and tmp4.o contain small code model relocs.
+
+# CHECK:      .got
+# CHECK-NEXT:         <internal>:(.got)
+# CHECK-NEXT: .toc
+# CHECK-NEXT:         {{.*}}3.o:(.toc)
+# CHECK-NEXT:         {{.*}}4.o:(.toc)
+# CHECK-NEXT:         {{.*}}1.o:(.toc)
+# CHECK-NEXT:         {{.*}}2.o:(.toc)
+
+# ALTERNATE:      .got
+# ALTERNATE-NEXT:         <internal>:(.got)
+# ALTERNATE-NEXT: .toc
+# ALTERNATE-NEXT:         {{.*}}3.o:(.toc)
+# ALTERNATE-NEXT:         {{.*}}4.o:(.toc)
+# ALTERNATE-NEXT:         {{.*}}2.o:(.toc)
+# ALTERNATE-NEXT:         {{.*}}1.o:(.toc)
+
+# SEC-CMD:      .got
+# SEC-CMD-NEXT:         <internal>:(.got)
+# SEC-CMD-NEXT: .toc
+# SEC-CMD-NEXT:         {{.*}}4.o:(.toc)
+# SEC-CMD-NEXT:         {{.*}}1.o:(.toc)
+# SEC-CMD-NEXT:         {{.*}}2.o:(.toc)
+# SEC-CMD-NEXT:         {{.*}}3.o:(.toc)
+
+# SEC-CMD2:      .got
+# SEC-CMD2-NEXT:         <internal>:(.got)
+# SEC-CMD2-NEXT: .toc
+# SEC-CMD2-NEXT:         {{.*}}1.o:(.toc)
+# SEC-CMD2-NEXT:         {{.*}}2.o:(.toc)
+# SEC-CMD2-NEXT:         {{.*}}3.o:(.toc)
+# SEC-CMD2-NEXT:         {{.*}}4.o:(.toc)
+
+# NOSEC:      .got
+# NOSEC-NEXT:         <internal>:(.got)
+# NOSEC-NEXT: .toc
+# NOSEC-NEXT:         {{.*}}3.o:(.toc)
+# NOSEC-NEXT:         {{.*}}4.o:(.toc)
+# NOSEC-NEXT:         {{.*}}1.o:(.toc)
+# NOSEC-NEXT:         {{.*}}2.o:(.toc)
+
diff --git a/test/ELF/ppc64-split-stack-adjust-overflow.s b/test/ELF/ppc64-split-stack-adjust-overflow.s
index bc958c7..874f45c 100644
--- a/test/ELF/ppc64-split-stack-adjust-overflow.s
+++ b/test/ELF/ppc64-split-stack-adjust-overflow.s
@@ -20,7 +20,7 @@
 # RUN: ld.lld %t1.o %t2.o -o %t --defsym __morestack=0x10010000 -split-stack-adjust-size 4096
 # RUN: llvm-objdump -d %t | FileCheck %s
 
-# OVERFLOW: error: {{.*}}.o:(function caller): split-stack prologue adjustment overflows
+# OVERFLOW: error: {{.*}}.o:(function caller: .text+0x8): split-stack prologue adjustment overflows
 
         .p2align    2
         .global caller
diff --git a/test/ELF/ppc64-tls-gd-le.s b/test/ELF/ppc64-tls-gd-le.s
index 7907d11..78bffb2 100644
--- a/test/ELF/ppc64-tls-gd-le.s
+++ b/test/ELF/ppc64-tls-gd-le.s
@@ -50,10 +50,6 @@
 .Lfunc_end0:
 	.size	_start, .Lfunc_end0-.Lfunc_begin0
 
-.globl __tls_get_addr
-.type __tls_get_addr,@function
-__tls_get_addr:
-
                                         # -- End function
 	.type	a,@object               # @a
 	.section	.tdata,"awT",@progbits
diff --git a/test/ELF/ppc64-tls-ld-le.s b/test/ELF/ppc64-tls-ld-le.s
index b684515..572de08 100644
--- a/test/ELF/ppc64-tls-ld-le.s
+++ b/test/ELF/ppc64-tls-ld-le.s
@@ -52,9 +52,7 @@
 .Lfunc_end0:
 	.size	_start, .Lfunc_end0-.Lfunc_begin0
                                         # -- End function
-.globl __tls_get_addr
-.type __tls_get_addr,@function
-__tls_get_addr:
+
 	.type	a,@object               # @a
 	.section	.tdata,"awT",@progbits
 	.p2align	2
diff --git a/test/ELF/ppc64-toc-restore-recursive-call.s b/test/ELF/ppc64-toc-restore-recursive-call.s
index 4bedcfe..d194ada 100644
--- a/test/ELF/ppc64-toc-restore-recursive-call.s
+++ b/test/ELF/ppc64-toc-restore-recursive-call.s
@@ -18,7 +18,7 @@
 # CHECK-NEXT: 10000:
 # CHECK-LABEL: recursive_func
 # CHECK-NEXT:  10014:
-# CHECK:       1003c: {{[0-9a-fA-F ]+}} bl .+67108804
+# CHECK:       1003c: {{.*}}  bl .-60
 # CHECK-NEXT:  ld 2, 24(1)
 
         .abiversion 2
diff --git a/test/ELF/ppc64-toc-restore.s b/test/ELF/ppc64-toc-restore.s
index d9e06ca..8c26207 100644
--- a/test/ELF/ppc64-toc-restore.s
+++ b/test/ELF/ppc64-toc-restore.s
@@ -32,10 +32,10 @@
 
 // CHECK: Disassembly of section .text:
 // CHECK: _start:
-// CHECK:     1001001c: {{.*}}  bl .+67108836
+// CHECK:     1001001c: {{.*}}  bl .-28
 // CHECK-NOT: 10010020: {{.*}}  nop
 // CHECK:     10010020: {{.*}}  ld 2, 24(1)
-// CHECK:     10010024: {{.*}}  bl .+67108848
+// CHECK:     10010024: {{.*}}  bl .-16
 // CHECK-NOT: 10010028: {{.*}}  nop
 // CHECK-NOT: 10010028: {{.*}}  ld 2, 24(1)
 
@@ -68,5 +68,5 @@
   bl foo
   nop
 // CHECK: last:
-// CHECK:      10010038: {{.*}}   bl .+67108808
+// CHECK:      10010038: {{.*}}   bl .-56
 // CHECK-NEXT: 1001003c: {{.*}}   ld 2, 24(1)
diff --git a/test/ELF/pr34872.s b/test/ELF/pr34872.s
index c6ca819..2991e94 100644
--- a/test/ELF/pr34872.s
+++ b/test/ELF/pr34872.s
@@ -3,7 +3,7 @@
 # RUN: llvm-mc %p/Inputs/undefined-error.s -filetype=obj \
 # RUN:    -triple=x86_64-pc-linux -o %t2.o
 # RUN: ld.lld -shared %t2.o -o %t2.so
-# RUN: not ld.lld %t2.so %t.o -o /dev/null 2>&1 | FileCheck %s
+# RUN: not ld.lld --allow-shlib-undefined %t2.so %t.o -o /dev/null 2>&1 | FileCheck %s
 
 # CHECK: undefined symbol: fmod
 # Check we're not emitting other diagnostics for this symbol.
diff --git a/test/ELF/progname.s b/test/ELF/progname.s
index ecd0fd8..228e3f6 100644
--- a/test/ELF/progname.s
+++ b/test/ELF/progname.s
@@ -17,7 +17,7 @@
 // RUN: ld.lld -dynamic-list %t.dynlist -o %t %t.o %t.so
 // RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
 
-// CHECK:      Name:     __progname@
+// CHECK:      Name:     __progname
 // CHECK-NEXT: Value:    0x201000
 // CHECK-NEXT: Size:     0
 // CHECK-NEXT: Binding:  Global (0x1)
diff --git a/test/ELF/protected-shared.s b/test/ELF/protected-shared.s
index e69b108..3501162 100644
--- a/test/ELF/protected-shared.s
+++ b/test/ELF/protected-shared.s
@@ -32,7 +32,7 @@
 
 // CHECK:      DynamicSymbols [
 // CHECK-NEXT:   Symbol {
-// CHECK-NEXT:     Name: @
+// CHECK-NEXT:     Name:
 // CHECK-NEXT:     Value: 0x0
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Local (0x0)
@@ -41,7 +41,7 @@
 // CHECK-NEXT:     Section: Undefined (0x0)
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Symbol {
-// CHECK-NEXT:     Name: foo@
+// CHECK-NEXT:     Name: foo
 // CHECK-NEXT:     Value: 0x0
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Global
diff --git a/test/ELF/relative-dynamic-reloc-ppc64.s b/test/ELF/relative-dynamic-reloc-ppc64.s
index 83190a2..d65ea27 100644
--- a/test/ELF/relative-dynamic-reloc-ppc64.s
+++ b/test/ELF/relative-dynamic-reloc-ppc64.s
@@ -32,7 +32,7 @@
 
 // CHECK:      DynamicSymbols [
 // CHECK-NEXT:   Symbol {
-// CHECK-NEXT:     Name: @
+// CHECK-NEXT:     Name:
 // CHECK-NEXT:     Value: 0x0
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Local
@@ -41,7 +41,7 @@
 // CHECK-NEXT:     Section: Undefined
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Symbol {
-// CHECK-NEXT:     Name: external@
+// CHECK-NEXT:     Name: external
 // CHECK-NEXT:     Value: 0x0
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Global
diff --git a/test/ELF/relative-dynamic-reloc.s b/test/ELF/relative-dynamic-reloc.s
index 0ed7e40..24d03f2 100644
--- a/test/ELF/relative-dynamic-reloc.s
+++ b/test/ELF/relative-dynamic-reloc.s
@@ -28,7 +28,7 @@
 
 // CHECK:      DynamicSymbols [
 // CHECK-NEXT:   Symbol {
-// CHECK-NEXT:     Name: @
+// CHECK-NEXT:     Name:
 // CHECK-NEXT:     Value: 0x0
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Local
@@ -37,7 +37,7 @@
 // CHECK-NEXT:     Section: Undefined
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Symbol {
-// CHECK-NEXT:     Name: external@
+// CHECK-NEXT:     Name: external
 // CHECK-NEXT:     Value: 0x0
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Global
diff --git a/test/ELF/relocatable.s b/test/ELF/relocatable.s
index 7235ea0..74ed920 100644
--- a/test/ELF/relocatable.s
+++ b/test/ELF/relocatable.s
@@ -53,7 +53,7 @@
 # CHECK-NEXT:  }
 
 # SECTION: Sections:
-# SECTION: Idx Name          Size      Address          Type
+# SECTION: Idx Name          Size     VMA              Type
 # SECTION:   0               00000000 0000000000000000
 # SECTION:   1 .text         00000056 0000000000000000 TEXT
 # SECTION:   2 .rela.text    00000090 0000000000000000
diff --git a/test/ELF/relocation-size-shared.s b/test/ELF/relocation-size-shared.s
index f60f092..1aa2222 100644
--- a/test/ELF/relocation-size-shared.s
+++ b/test/ELF/relocation-size-shared.s
@@ -28,20 +28,7 @@
 // DISASM-NEXT: 20100c: 00 00
 // DISASM-NEXT: 20100e: 00 00
 // DISASM-NEXT: 201010: 1b 00
-// DISASM-NEXT: 201012: 00 00
-// DISASM-NEXT: 201014: 00 00
-// DISASM-NEXT: 201016: 00 00
-// DISASM-NEXT: 201018: 00 00
-// DISASM-NEXT: 20101a: 00 00
-// DISASM-NEXT: 20101c: 00 00
-// DISASM-NEXT: 20101e: 00 00
-// DISASM-NEXT: 201020: 00 00
-// DISASM-NEXT: 201022: 00 00
-// DISASM-NEXT: 201024: 00 00
-// DISASM-NEXT: 201026: 00 00
-// DISASM-NEXT: 201028: 00 00
-// DISASM-NEXT: 20102a: 00 00
-// DISASM-NEXT: 20102c: 00 00
+// DISASM-NEXT: ...
 // DISASM-NEXT: 20102e: 00 00
 // DISASM:      _start:
 // DISASM-NEXT: 201030: 8b 04 25 19 00 00 00 movl 25, %eax
diff --git a/test/ELF/relocation-size.s b/test/ELF/relocation-size.s
index 525b1e1..c2554a4 100644
--- a/test/ELF/relocation-size.s
+++ b/test/ELF/relocation-size.s
@@ -57,18 +57,7 @@
 
 // DISASMSHARED:      Disassembly of section test:
 // DISASMSHARED-NEXT: _data:
-// DISASMSHARED-NEXT: 1000: 00 00
-// DISASMSHARED-NEXT: 1002: 00 00
-// DISASMSHARED-NEXT: 1004: 00 00
-// DISASMSHARED-NEXT: 1006: 00 00
-// DISASMSHARED-NEXT: 1008: 00 00
-// DISASMSHARED-NEXT: 100a: 00 00
-// DISASMSHARED-NEXT: 100c: 00 00
-// DISASMSHARED-NEXT: 100e: 00 00
-// DISASMSHARED-NEXT: 1010: 00 00
-// DISASMSHARED-NEXT: 1012: 00 00
-// DISASMSHARED-NEXT: 1014: 00 00
-// DISASMSHARED-NEXT: 1016: 00 00
+// DISASMSHARED-NEXT: ...
 // DISASMSHARED-NEXT: 1018: 19 00
 // DISASMSHARED-NEXT: 101a: 00 00
 // DISASMSHARED-NEXT: 101c: 00 00
diff --git a/test/ELF/relro-omagic.s b/test/ELF/relro-omagic.s
index ba0ca72..3f6b425 100644
--- a/test/ELF/relro-omagic.s
+++ b/test/ELF/relro-omagic.s
@@ -7,7 +7,7 @@
 # RUN: llvm-readobj --program-headers %t | FileCheck --check-prefix=NOPHDRS %s
 
 # NORELRO:      Sections:
-# NORELRO-NEXT: Idx Name          Size      Address          Type
+# NORELRO-NEXT: Idx Name          Size     VMA              Type
 # NORELRO-NEXT:   0               00000000 0000000000000000
 # NORELRO-NEXT:   1 .dynsym       00000048 0000000000200120
 # NORELRO-NEXT:   2 .hash         00000020 0000000000200168
diff --git a/test/ELF/retain-symbols-file.s b/test/ELF/retain-symbols-file.s
index 79d569d..0ab1977 100644
--- a/test/ELF/retain-symbols-file.s
+++ b/test/ELF/retain-symbols-file.s
@@ -11,7 +11,7 @@
 
 # CHECK:      DynamicSymbols [
 # CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name: @
+# CHECK-NEXT:     Name:
 # CHECK-NEXT:     Value:
 # CHECK-NEXT:     Size:
 # CHECK-NEXT:     Binding:
diff --git a/test/ELF/sectionstart-noallochdr.s b/test/ELF/sectionstart-noallochdr.s
index be8e0c5..b32d67c 100644
--- a/test/ELF/sectionstart-noallochdr.s
+++ b/test/ELF/sectionstart-noallochdr.s
@@ -5,7 +5,7 @@
 # RUN: llvm-objdump -section-headers %t1 | FileCheck %s
 
 # CHECK:      Sections:
-# CHECK-NEXT:  Idx Name          Size      Address          Type
+# CHECK-NEXT:  Idx Name          Size     VMA              Type
 # CHECK-NEXT:    0               00000000 0000000000000000
 # CHECK-NEXT:    1 .text         00000001 0000000000000010 TEXT
 # CHECK-NEXT:    2 .data         00000004 0000000000000020 DATA
diff --git a/test/ELF/sectionstart.s b/test/ELF/sectionstart.s
index be8b5f0..519831d 100644
--- a/test/ELF/sectionstart.s
+++ b/test/ELF/sectionstart.s
@@ -5,7 +5,7 @@
 # RUN: llvm-objdump -section-headers %t | FileCheck %s
 
 # CHECK:      Sections:
-# CHECK-NEXT:  Idx Name          Size      Address          Type
+# CHECK-NEXT:  Idx Name          Size     VMA              Type
 # CHECK-NEXT:    0               00000000 0000000000000000
 # CHECK-NEXT:    1 .text         00000001 0000000000100000 TEXT
 # CHECK-NEXT:    2 .data         00000004 0000000000110000 DATA
diff --git a/test/ELF/shared.s b/test/ELF/shared.s
index 1b93fef..e00dd99 100644
--- a/test/ELF/shared.s
+++ b/test/ELF/shared.s
@@ -181,7 +181,7 @@
 
 // CHECK:      DynamicSymbols [
 // CHECK-NEXT:   Symbol {
-// CHECK-NEXT:     Name: @
+// CHECK-NEXT:     Name:
 // CHECK-NEXT:     Value: 0x0
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Local
@@ -190,7 +190,7 @@
 // CHECK-NEXT:     Section: Undefined
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Symbol {
-// CHECK-NEXT:     Name: _start@
+// CHECK-NEXT:     Name: _start
 // CHECK-NEXT:     Value: 0x401000
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Global
@@ -199,7 +199,7 @@
 // CHECK-NEXT:     Section: .text
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Symbol {
-// CHECK-NEXT:     Name: bar@
+// CHECK-NEXT:     Name: bar
 // CHECK-NEXT:     Value: 0x0
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Global
@@ -208,7 +208,7 @@
 // CHECK-NEXT:     Section: Undefined
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Symbol {
-// CHECK-NEXT:     Name: zed@
+// CHECK-NEXT:     Name: zed
 // CHECK-NEXT:     Value: 0x0
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Global
@@ -220,7 +220,7 @@
 
 // DONT_EXPORT:      DynamicSymbols [
 // DONT_EXPORT-NEXT:   Symbol {
-// DONT_EXPORT-NEXT:     Name: @
+// DONT_EXPORT-NEXT:     Name:
 // DONT_EXPORT-NEXT:     Value: 0x0
 // DONT_EXPORT-NEXT:     Size: 0
 // DONT_EXPORT-NEXT:     Binding: Local (0x0)
@@ -229,7 +229,7 @@
 // DONT_EXPORT-NEXT:     Section: Undefined (0x0)
 // DONT_EXPORT-NEXT:   }
 // DONT_EXPORT-NEXT:   Symbol {
-// DONT_EXPORT-NEXT:     Name: bar@
+// DONT_EXPORT-NEXT:     Name: bar
 // DONT_EXPORT-NEXT:     Value: 0x0
 // DONT_EXPORT-NEXT:     Size: 0
 // DONT_EXPORT-NEXT:     Binding: Global
@@ -238,7 +238,7 @@
 // DONT_EXPORT-NEXT:     Section: Undefined
 // DONT_EXPORT-NEXT:   }
 // DONT_EXPORT-NEXT:   Symbol {
-// DONT_EXPORT-NEXT:     Name: zed@
+// DONT_EXPORT-NEXT:     Name: zed
 // DONT_EXPORT-NEXT:     Value: 0x0
 // DONT_EXPORT-NEXT:     Size: 0
 // DONT_EXPORT-NEXT:     Binding: Global
diff --git a/test/ELF/sht-group-empty.test b/test/ELF/sht-group-empty.test
new file mode 100644
index 0000000..46c77f3
--- /dev/null
+++ b/test/ELF/sht-group-empty.test
@@ -0,0 +1,55 @@
+# RUN: yaml2obj %s -o %t.o
+# RUN: ld.lld %t.o %t.o -o %t -r
+# RUN: llvm-readobj -s %t | FileCheck %s
+
+# CHECK:     Name: .text.foo
+# CHECK:     Name: .rela.text.foo
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .group
+    Type:            SHT_GROUP
+    Link:            .symtab
+    Info:            foo
+    Members:
+      - SectionOrType:    GRP_COMDAT
+      - SectionOrType:    .text.foo
+      - SectionOrType:    .text.bar
+      - SectionOrType:    .note
+  - Name:            .note
+    Type:            SHT_NOTE
+    Flags:           [ SHF_GROUP ]
+  - Name:            .text.foo
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+  - Name:            .text.bar
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+  - Name:            .rela.text.foo
+    Type:            SHT_RELA
+    Flags:           [ SHF_INFO_LINK, SHF_GROUP ]
+    Link:            .symtab
+    Info:            .text.foo
+    Relocations:
+      - Offset:          0x0000000000000000
+        Symbol:          foo
+        Type:            R_X86_64_64
+  - Name:            .rela.text.bar
+    Type:            SHT_RELA
+    Flags:           [ SHF_INFO_LINK, SHF_GROUP ]
+    Link:            .symtab
+    Info:            .text.bar
+    Relocations:
+      - Offset:          0x0000000000000000
+        Symbol:          bar
+        Type:            R_X86_64_64
+Symbols:
+  Global:
+    - Name:            foo
+    - Name:            bar
+
diff --git a/test/ELF/stdout.s b/test/ELF/stdout.s
new file mode 100644
index 0000000..fcce79f
--- /dev/null
+++ b/test/ELF/stdout.s
@@ -0,0 +1,18 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -o - > %t1
+# RUN: llvm-objdump -d %t1 | FileCheck %s
+
+# CHECK: 0000000000201000 _start:
+# CHECK: 201000: 90 nop
+
+# RUN: ld.lld %t.o -o %t2
+
+# FIXME: Add "RUN" in front of this line once the test passes on Windows
+# with it.
+# diff %t1 %t2
+
+.globl _start
+_start:
+  nop
diff --git a/test/ELF/tls-dynamic-i686.s b/test/ELF/tls-dynamic-i686.s
index 1b13f26..dc651d0 100644
--- a/test/ELF/tls-dynamic-i686.s
+++ b/test/ELF/tls-dynamic-i686.s
@@ -56,8 +56,8 @@
 // CHECK-NEXT:   SHF_ALLOC
 // CHECK-NEXT:   SHF_WRITE
 // CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x3068
-// CHECK-NEXT: Offset: 0x3068
+// CHECK-NEXT: Address: 0x3070
+// CHECK-NEXT: Offset: 0x3070
 // CHECK-NEXT: Size: 32
 // CHECK-NEXT: Link: 0
 // CHECK-NEXT: Info: 0
@@ -66,13 +66,13 @@
 
 // CHECK: Relocations [
 // CHECK:      Section ({{.+}}) .rel.dyn {
-// CHECK-NEXT: 0x3078 R_386_TLS_DTPMOD32 - 0x0
-// CHECK-NEXT: 0x3068 R_386_TLS_DTPMOD32 tls0 0x0
-// CHECK-NEXT: 0x306C R_386_TLS_DTPOFF32 tls0 0x0
-// CHECK-NEXT: 0x3080 R_386_TLS_TPOFF tls0 0x0
-// CHECK-NEXT: 0x3070 R_386_TLS_DTPMOD32 tls1 0x0
-// CHECK-NEXT: 0x3074 R_386_TLS_DTPOFF32 tls1 0x0
-// CHECK-NEXT: 0x3084 R_386_TLS_TPOFF tls1 0x0
+// CHECK-NEXT: 0x3080 R_386_TLS_DTPMOD32 - 0x0
+// CHECK-NEXT: 0x3070 R_386_TLS_DTPMOD32 tls0 0x0
+// CHECK-NEXT: 0x3074 R_386_TLS_DTPOFF32 tls0 0x0
+// CHECK-NEXT: 0x3088 R_386_TLS_TPOFF tls0 0x0
+// CHECK-NEXT: 0x3078 R_386_TLS_DTPMOD32 tls1 0x0
+// CHECK-NEXT: 0x307C R_386_TLS_DTPOFF32 tls1 0x0
+// CHECK-NEXT: 0x308C R_386_TLS_TPOFF tls1 0x0
 // CHECK-NEXT: }
 
 // DIS:      Disassembly of section .text:
@@ -80,20 +80,20 @@
 // General dynamic model:
 // -32 and -24 are first and second GOT entries offsets.
 // Each one is a pair of records.
-// DIS-NEXT: 1000: 8d 04 1d e0 ff ff ff  leal -32(,%ebx), %eax
-// DIS-NEXT: 1007: e8 64 00 00 00        calll 100
-// DIS-NEXT: 100c: 8d 04 1d e8 ff ff ff  leal -24(,%ebx), %eax
-// DIS-NEXT: 1013: e8 58 00 00 00        calll 88
+// DIS-NEXT: 1000: {{.*}} leal -32(,%ebx), %eax
+// DIS-NEXT: 1007: {{.*}} calll 100
+// DIS-NEXT: 100c: {{.*}} leal -24(,%ebx), %eax
+// DIS-NEXT: 1013: {{.*}} calll 88
 // Local dynamic model:
 // -16 is a local module tls index offset.
-// DIS-NEXT: 1018: 8d 83 f0 ff ff ff leal -16(%ebx), %eax
-// DIS-NEXT: 101e: e8 4d 00 00 00    calll 77
-// DIS-NEXT: 1023: 8d 90 08 00 00 00 leal 8(%eax), %edx
-// DIS-NEXT: 1029: 8d 83 f0 ff ff ff leal -16(%ebx), %eax
-// DIS-NEXT: 102f: e8 3c 00 00 00    calll 60
-// DIS-NEXT: 1034: 8d 90 0c 00 00 00 leal 12(%eax), %edx
+// DIS-NEXT: 1018: {{.*}} leal -16(%ebx), %eax
+// DIS-NEXT: 101e: {{.*}} calll 77
+// DIS-NEXT: 1023: {{.*}} leal 8(%eax), %edx
+// DIS-NEXT: 1029: {{.*}} leal -16(%ebx), %eax
+// DIS-NEXT: 102f: {{.*}} calll 60
+// DIS-NEXT: 1034: {{.*}} leal 12(%eax), %edx
 // Initial exec model:
-// DIS-NEXT: 103a: 65 a1 00 00 00 00 movl %gs:0, %eax
-// DIS-NEXT: 1040: 03 83 f8 ff ff ff addl -8(%ebx), %eax
-// DIS-NEXT: 1046: 65 a1 00 00 00 00 movl %gs:0, %eax
-// DIS-NEXT: 104c: 03 83 fc ff ff ff addl -4(%ebx), %eax
+// DIS-NEXT: 103a: {{.*}} movl %gs:0, %eax
+// DIS-NEXT: 1040: {{.*}} addl -8(%ebx), %eax
+// DIS-NEXT: 1046: {{.*}} movl %gs:0, %eax
+// DIS-NEXT: 104c: {{.*}} addl -4(%ebx), %eax
diff --git a/test/ELF/tls-dynamic.s b/test/ELF/tls-dynamic.s
index 167f768..c4190a2 100644
--- a/test/ELF/tls-dynamic.s
+++ b/test/ELF/tls-dynamic.s
@@ -48,28 +48,28 @@
 // CHECK-NEXT:       SHF_ALLOC
 // CHECK-NEXT:       SHF_WRITE
 // CHECK-NEXT:     ]
-// CHECK-NEXT:     Address: 0x30D0
+// CHECK-NEXT:     Address: 0x30E0
 // CHECK-NEXT:     Offset:
 // CHECK-NEXT:     Size: 40
 
 // CHECK:      Relocations [
 // CHECK:        Section ({{.+}}) .rela.dyn {
-// CHECK-NEXT:     0x30D0 R_X86_64_DTPMOD64 - 0x0
-// CHECK-NEXT:     0x30E0 R_X86_64_DTPMOD64 c 0x0
-// CHECK-NEXT:     0x30E8 R_X86_64_DTPOFF64 c 0x0
-// CHECK-NEXT:     0x30F0 R_X86_64_TPOFF64 c 0x0
+// CHECK-NEXT:     0x30E0 R_X86_64_DTPMOD64 - 0x0
+// CHECK-NEXT:     0x30F0 R_X86_64_DTPMOD64 c 0x0
+// CHECK-NEXT:     0x30F8 R_X86_64_DTPOFF64 c 0x0
+// CHECK-NEXT:     0x3100 R_X86_64_TPOFF64 c 0x0
 // CHECK-NEXT:   }
 
-// 4297 = (0x20D0 + -4) - (0x1000 + 3) // PC relative offset to got entry.
-// 4285 = (0x20D0 + -4) - (0x100c + 3) // PC relative offset to got entry.
-// 4267 = (0x20E0 + -4) - (0x102e + 3) // PC relative offset to got entry.
-// 4263 = (0x20F0 + -4) - (0x1042 + 3) // PC relative offset to got entry.
+// 8409 = (0x30E0 + -4) - (0x1000 + 3) // PC relative offset to got entry.
+// 8397 = (0x30F0 + -4) - (0x100c + 3) // PC relative offset to got entry.
+// 8379 = (0x30F8 + -4) - (0x102e + 3) // PC relative offset to got entry.
+// 8375 = (0x3100 + -4) - (0x1042 + 3) // PC relative offset to got entry.
 
 // DIS:      Disassembly of section .text:
 // DIS-NEXT: .text:
-// DIS-NEXT:     1000: {{.+}} leaq    8393(%rip), %rdi
+// DIS-NEXT:     1000: {{.+}} leaq    8409(%rip), %rdi
 // DIS-NEXT:     1007: {{.+}} callq
-// DIS-NEXT:     100c: {{.+}} leaq    8381(%rip), %rdi
+// DIS-NEXT:     100c: {{.+}} leaq    8397(%rip), %rdi
 // DIS-NEXT:     1013: {{.+}} callq
 // DIS-NEXT:     1018: {{.+}} leaq    (%rax), %rcx
 // DIS-NEXT:     101f: {{.+}} leaq    4(%rax), %rcx
@@ -77,10 +77,10 @@
 // DIS-NEXT:     1028: 00 00
 // DIS-NEXT:     102a: 00 00
 // DIS-NEXT:     102c: 00 00
-// DIS-NEXT:     102e: {{.+}} leaq    8363(%rip), %rdi
+// DIS-NEXT:     102e: {{.+}} leaq    8379(%rip), %rdi
 // DIS-NEXT:     1035: {{.+}} callq
 // DIS-NEXT:     103b: {{.+}} leaq    (%rax), %rcx
-// DIS-NEXT:     1042: {{.+}} movq    8359(%rip), %rax
+// DIS-NEXT:     1042: {{.+}} movq    8375(%rip), %rax
 // DIS-NEXT:     1049: {{.+}} movq    %fs:(%rax), %rax
 // DIS-NEXT:     104d: {{.+}} movabsq $0, %rax
 // DIS-NEXT:     1057: {{.+}} movabsq $4, %rax
diff --git a/test/ELF/tls-got.s b/test/ELF/tls-got.s
index bedaaeb..d9de24e 100644
--- a/test/ELF/tls-got.s
+++ b/test/ELF/tls-got.s
@@ -15,7 +15,7 @@
 // CHECK-NEXT:   SHF_WRITE
 // CHECK-NEXT: ]
 // CHECK-NEXT: Address: [[ADDR:.*]]
-// CHECK-NEXT: Offset: 0x20B0
+// CHECK-NEXT: Offset: 0x20C0
 // CHECK-NEXT: Size: 16
 // CHECK-NEXT: Link: 0
 // CHECK-NEXT: Info: 0
@@ -25,23 +25,23 @@
 
 // CHECK:      Relocations [
 // CHECK-NEXT:   Section (4) .rela.dyn {
-// CHECK-NEXT:     0x2020B8 R_X86_64_TPOFF64 tls0 0x0
-// CHECK-NEXT:     0x2020B0 R_X86_64_TPOFF64 tls1 0x0
+// CHECK-NEXT:     0x2020C8 R_X86_64_TPOFF64 tls0 0x0
+// CHECK-NEXT:     [[ADDR]] R_X86_64_TPOFF64 tls1 0x0
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]
 
-//0x201000 + 4265 + 7 = 0x2020B0
-//0x20100A + 4263 + 7 = 0x2020B8
-//0x201014 + 4253 + 7 = 0x2020B8
+//0x201000 + 4281 + 7 = 0x2020C0
+//0x20100A + 4279 + 7 = 0x2020C8
+//0x201014 + 4269 + 7 = 0x2020C8
 //DISASM:      Disassembly of section .text:
 //DISASM-NEXT: main:
-//DISASM-NEXT: 201000: 48 8b 05 a9 10 00 00 movq 4265(%rip), %rax
-//DISASM-NEXT: 201007: 64 8b 00 movl %fs:(%rax), %eax
-//DISASM-NEXT: 20100a: 48 8b 05 a7 10 00 00 movq 4263(%rip), %rax
-//DISASM-NEXT: 201011: 64 8b 00 movl %fs:(%rax), %eax
-//DISASM-NEXT: 201014: 48 8b 05 9d 10 00 00 movq 4253(%rip), %rax
-//DISASM-NEXT: 20101b: 64 8b 00 movl %fs:(%rax), %eax
-//DISASM-NEXT: 20101e: c3 retq
+//DISASM-NEXT: 201000: {{.*}} movq 4281(%rip), %rax
+//DISASM-NEXT: 201007: {{.*}} movl %fs:(%rax), %eax
+//DISASM-NEXT: 20100a: {{.*}} movq 4279(%rip), %rax
+//DISASM-NEXT: 201011: {{.*}} movl %fs:(%rax), %eax
+//DISASM-NEXT: 201014: {{.*}} movq 4269(%rip), %rax
+//DISASM-NEXT: 20101b: {{.*}} movl %fs:(%rax), %eax
+//DISASM-NEXT: 20101e: {{.*}} retq
 
 .section .tdata,"awT",@progbits
 
diff --git a/test/ELF/tls-initial-exec-local.s b/test/ELF/tls-initial-exec-local.s
index e65fb29..67fe909 100644
--- a/test/ELF/tls-initial-exec-local.s
+++ b/test/ELF/tls-initial-exec-local.s
@@ -10,21 +10,21 @@
 // CHECK-NEXT:   SHF_ALLOC (0x2)
 // CHECK-NEXT:   SHF_WRITE (0x1)
 // CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x2090
+// CHECK-NEXT: Address: 0x20A0
 
 // CHECK:      Relocations [
 // CHECK-NEXT:   Section ({{.*}}) .rela.dyn {
-// CHECK-NEXT:     0x2090 R_X86_64_TPOFF64 - 0x0
-// CHECK-NEXT:     0x2098 R_X86_64_TPOFF64 - 0x4
+// CHECK-NEXT:     0x20A0 R_X86_64_TPOFF64 - 0x0
+// CHECK-NEXT:     0x20A8 R_X86_64_TPOFF64 - 0x4
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]
 
-// 0x1007 + 4233 = 0x2090
-// 0x100e + 4234 = 0x2098
+// 0x1007 + 4249 = 0x20A0
+// 0x100e + 4250 = 0x20A8
 // DISASM:      Disassembly of section .text:
 // DISASM-NEXT: .text:
-// DISASM-NEXT:  1000: {{.*}} addq      4233(%rip), %rax
-// DISASM-NEXT:  1007: {{.*}} addq      4234(%rip), %rax
+// DISASM-NEXT:  1000: {{.*}} addq 4249(%rip), %rax
+// DISASM-NEXT:  1007: {{.*}} addq 4250(%rip), %rax
 
         addq    foo@GOTTPOFF(%rip), %rax
         addq    bar@GOTTPOFF(%rip), %rax
diff --git a/test/ELF/tls-opt-iele-i686-nopic.s b/test/ELF/tls-opt-iele-i686-nopic.s
index 704928b..9b97264 100644
--- a/test/ELF/tls-opt-iele-i686-nopic.s
+++ b/test/ELF/tls-opt-iele-i686-nopic.s
@@ -14,8 +14,8 @@
 // GOTREL-NEXT:     SHF_ALLOC
 // GOTREL-NEXT:     SHF_WRITE
 // GOTREL-NEXT:   ]
-// GOTREL-NEXT:   Address: 0x402058
-// GOTREL-NEXT:   Offset: 0x2058
+// GOTREL-NEXT:   Address:  0x402060
+// GOTREL-NEXT:   Offset: 0x2060
 // GOTREL-NEXT:   Size: 8
 // GOTREL-NEXT:   Link: 0
 // GOTREL-NEXT:   Info: 0
@@ -24,8 +24,8 @@
 // GOTREL-NEXT: }
 // GOTREL:      Relocations [
 // GOTREL-NEXT: Section ({{.*}}) .rel.dyn {
-// GOTREL-NEXT:   0x402058 R_386_TLS_TPOFF tlsshared0 0x0
-// GOTREL-NEXT:   0x40205C R_386_TLS_TPOFF tlsshared1 0x0
+// GOTREL-NEXT:   0x402060 R_386_TLS_TPOFF tlsshared0 0x0
+// GOTREL-NEXT:   0x402064 R_386_TLS_TPOFF tlsshared1 0x0
 // GOTREL-NEXT:  }
 // GOTREL-NEXT: ]
 
@@ -33,24 +33,24 @@
 // DISASM-NEXT: _start:
 // 4294967288 = 0xFFFFFFF8
 // 4294967292 = 0xFFFFFFFC
-// 4202584 = (.got)[0] = 0x402058
-// 4202588 = (.got)[1] = 0x40205C
-// DISASM-NEXT: 401000: c7 c1 f8 ff ff ff movl $4294967288, %ecx
-// DISASM-NEXT: 401006: 65 8b 01          movl %gs:(%ecx), %eax
-// DISASM-NEXT: 401009: b8 f8 ff ff ff    movl $4294967288, %eax
-// DISASM-NEXT: 40100e: 65 8b 00          movl %gs:(%eax), %eax
-// DISASM-NEXT: 401011: 81 c1 f8 ff ff ff addl $4294967288, %ecx
-// DISASM-NEXT: 401017: 65 8b 01          movl %gs:(%ecx), %eax
-// DISASM-NEXT: 40101a: c7 c1 fc ff ff ff movl $4294967292, %ecx
-// DISASM-NEXT: 401020: 65 8b 01          movl %gs:(%ecx), %eax
-// DISASM-NEXT: 401023: b8 fc ff ff ff    movl $4294967292, %eax
-// DISASM-NEXT: 401028: 65 8b 00          movl %gs:(%eax), %eax
-// DISASM-NEXT: 40102b: 81 c1 fc ff ff ff addl $4294967292, %ecx
-// DISASM-NEXT: 401031: 65 8b 01          movl %gs:(%ecx), %eax
-// DISASM-NEXT: 401034: 8b 0d 58 20 40 00 movl 4202584, %ecx
-// DISASM-NEXT: 40103a: 65 8b 01          movl %gs:(%ecx), %eax
-// DISASM-NEXT: 40103d: 03 0d 5c 20 40 00 addl 4202588, %ecx
-// DISASM-NEXT: 401043: 65 8b 01          movl %gs:(%ecx), %eax
+// 4202592 = (.got)[0] = 0x402060
+// 4202596 = (.got)[1] = 0x402064
+// DISASM-NEXT: 401000: {{.*}} movl $4294967288, %ecx
+// DISASM-NEXT: 401006: {{.*}} movl %gs:(%ecx), %eax
+// DISASM-NEXT: 401009: {{.*}} movl $4294967288, %eax
+// DISASM-NEXT: 40100e: {{.*}} movl %gs:(%eax), %eax
+// DISASM-NEXT: 401011: {{.*}} addl $4294967288, %ecx
+// DISASM-NEXT: 401017: {{.*}} movl %gs:(%ecx), %eax
+// DISASM-NEXT: 40101a: {{.*}} movl $4294967292, %ecx
+// DISASM-NEXT: 401020: {{.*}} movl %gs:(%ecx), %eax
+// DISASM-NEXT: 401023: {{.*}} movl $4294967292, %eax
+// DISASM-NEXT: 401028: {{.*}} movl %gs:(%eax), %eax
+// DISASM-NEXT: 40102b: {{.*}} addl $4294967292, %ecx
+// DISASM-NEXT: 401031: {{.*}} movl %gs:(%ecx), %eax
+// DISASM-NEXT: 401034: {{.*}} movl 4202592, %ecx
+// DISASM-NEXT: 40103a: {{.*}} movl %gs:(%ecx), %eax
+// DISASM-NEXT: 40103d: {{.*}} addl 4202596, %ecx
+// DISASM-NEXT: 401043: {{.*}} movl %gs:(%ecx), %eax
 
 .type tlslocal0,@object
 .section .tbss,"awT",@nobits
diff --git a/test/ELF/tls-opt-x86_64-noplt.s b/test/ELF/tls-opt-x86_64-noplt.s
new file mode 100644
index 0000000..69ec498
--- /dev/null
+++ b/test/ELF/tls-opt-x86_64-noplt.s
@@ -0,0 +1,88 @@
+// REQUIRES: x86
+
+// Checks whether the TLS optimizations match the cases in Chapter 11 of
+// https://raw.githubusercontent.com/wiki/hjl-tools/x86-psABI/x86-64-psABI-1.0.pdf
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/tls-opt-gdie.s -o %tso.o
+// RUN: ld.lld -shared %tso.o -o %t.so
+// RUN: ld.lld %t.o %t.so -o %t1
+// RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=RELOC %s
+// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
+
+// RELOC:      Relocations [
+// RELOC-NEXT:  Section {{.*}} .rela.dyn {
+// RELOC-NEXT:    0x2020C0 R_X86_64_TPOFF64 tlsshared0 0x0
+// RELOC-NEXT:    0x2020C8 R_X86_64_TPOFF64 tlsshared1 0x0
+// RELOC-NEXT:  }
+// RELOC-NEXT: ]
+
+// DISASM:      _start:
+
+// Table 11.5: GD -> IE Code Transition (LP64)
+// DISASM-NEXT: 201000: 64 48 8b 04 25 00 00 00 00      movq %fs:0, %rax
+// DISASM-NEXT: 201009: 48 03 05 b0 10 00 00            addq 4272(%rip), %rax
+// DISASM-NEXT: 201010: 64 48 8b 04 25 00 00 00 00      movq %fs:0, %rax
+// DISASM-NEXT: 201019: 48 03 05 a8 10 00 00            addq 4264(%rip), %rax
+
+// Table 11.7: GD -> LE Code Transition (LP64)
+// DISASM-NEXT: 201020: 64 48 8b 04 25 00 00 00 00      movq %fs:0, %rax
+// DISASM-NEXT: 201029: 48 8d 80 f8 ff ff ff            leaq -8(%rax), %rax
+// DISASM-NEXT: 201030: 64 48 8b 04 25 00 00 00 00      movq %fs:0, %rax
+// DISASM-NEXT: 201039: 48 8d 80 fc ff ff ff            leaq -4(%rax), %rax
+
+
+// Table 11.9: LD -> LE Code Transition (LP64)
+// DISASM-NEXT: 201040: 66 66 66 66 64 48 8b 04 25 00 00 00 00  movq %fs:0, %rax
+// DISASM-NEXT: 20104d: 66 66 66 66 64 48 8b 04 25 00 00 00 00  movq %fs:0, %rax
+
+.type tls0,@object
+.section .tbss,"awT",@nobits
+.globl tls0
+.align 4
+tls0:
+ .long 0
+ .size tls0, 4
+
+.type  tls1,@object
+.globl tls1
+.align 4
+tls1:
+ .long 0
+ .size tls1, 4
+
+.section .text
+.globl _start
+_start:
+ // Table 11.5: GD -> IE Code Transition (LP64)
+ .byte  0x66
+ leaq   tlsshared0@tlsgd(%rip),%rdi
+ .byte  0x66
+ rex64
+ call   *__tls_get_addr@GOTPCREL(%rip)
+
+ .byte  0x66
+ leaq   tlsshared1@tlsgd(%rip),%rdi
+ .byte  0x66
+ rex64
+ call   *__tls_get_addr@GOTPCREL(%rip)
+
+ // Table 11.7: GD -> LE Code Transition (LP64)
+ .byte  0x66
+ leaq   tls0@tlsgd(%rip),%rdi
+ .byte  0x66
+ rex64
+ call   *__tls_get_addr@GOTPCREL(%rip)
+
+ .byte  0x66
+ leaq   tls1@tlsgd(%rip),%rdi
+ .byte  0x66
+ rex64
+ call   *__tls_get_addr@GOTPCREL(%rip)
+
+ // Table 11.9: LD -> LE Code Transition (LP64)
+ leaq   tls0@tlsld(%rip),%rdi
+ call   *__tls_get_addr@GOTPCREL(%rip)
+
+ leaq   tls1@tlsld(%rip),%rdi
+ call   *__tls_get_addr@GOTPCREL(%rip)
diff --git a/test/ELF/trace.s b/test/ELF/trace.s
index 4374d93..43876ad 100644
--- a/test/ELF/trace.s
+++ b/test/ELF/trace.s
@@ -6,4 +6,4 @@
 # CHECK: {{.*}}.foo.o
 
 ## Check --trace alias
-# RUN: ld.lld -shared %t.foo.o -o %t.so -t 2>&1 | FileCheck %s
+# RUN: ld.lld -shared %t.foo.o -o %t.so --trace 2>&1 | FileCheck %s
diff --git a/test/ELF/undef-version-script.s b/test/ELF/undef-version-script.s
index 712589e..7ef4b7a 100644
--- a/test/ELF/undef-version-script.s
+++ b/test/ELF/undef-version-script.s
@@ -6,7 +6,7 @@
 
 # CHECK:      DynamicSymbols [
 # CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name: @
+# CHECK-NEXT:     Name:
 # CHECK-NEXT:     Value: 0x0
 # CHECK-NEXT:     Size: 0
 # CHECK-NEXT:     Binding: Local (0x0)
@@ -15,7 +15,7 @@
 # CHECK-NEXT:     Section: Undefined (0x0)
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name: bar@
+# CHECK-NEXT:     Name: bar
 # CHECK-NEXT:     Value: 0x0
 # CHECK-NEXT:     Size: 0
 # CHECK-NEXT:     Binding: Weak (0x2)
@@ -24,7 +24,7 @@
 # CHECK-NEXT:     Section: Undefined (0x0)
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name: foo@
+# CHECK-NEXT:     Name: foo
 # CHECK-NEXT:     Value: 0x0
 # CHECK-NEXT:     Size: 0
 # CHECK-NEXT:     Binding: Global (0x1)
diff --git a/test/ELF/undef.s b/test/ELF/undef.s
index a511723..e6277e3 100644
--- a/test/ELF/undef.s
+++ b/test/ELF/undef.s
@@ -20,6 +20,9 @@
 # CHECK: >>> referenced by undef.s
 # CHECK: >>>               {{.*}}:(.text+0x10)
 
+# CHECK: error: undefined symbol: vtable for Foo
+# CHECK: the vtable symbol may be undefined because the class is missing its key function (see https://lld.llvm.org/missingkeyfunction)
+
 # CHECK: error: undefined symbol: zed2
 # CHECK: >>> referenced by {{.*}}.o:(.text+0x0) in archive {{.*}}2.a
 
@@ -60,3 +63,4 @@
   call bar
   call zed1
   call _Z3fooi
+  call _ZTV3Foo
diff --git a/test/ELF/undefined-opt.s b/test/ELF/undefined-opt.s
index 9e93e0f..2689954 100644
--- a/test/ELF/undefined-opt.s
+++ b/test/ELF/undefined-opt.s
@@ -40,7 +40,7 @@
 # TWO-UNDEFINED: Name: zed
 # TWO-UNDEFINED: ]
 # Now the same logic but linker script is used to set undefines
-# RUN: echo "EXTERN( bar abs )" > %t.script
+# RUN: echo "EXTERN( bar \"abs\" )" > %t.script
 # RUN: ld.lld -o %t3 %t.o %tar.a %t.script
 # RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TWO-UNDEFINED %s
 
diff --git a/test/ELF/unresolved-symbols.s b/test/ELF/unresolved-symbols.s
index 69da3e6..0415972 100644
--- a/test/ELF/unresolved-symbols.s
+++ b/test/ELF/unresolved-symbols.s
@@ -27,21 +27,21 @@
 # ERRUND: >>> referenced by {{.*}}:(.text+0x1)
 
 ## Also ignore all should not produce error for symbols from DSOs.
-# RUN: ld.lld %t1.o %t.so -o %t1_3 --unresolved-symbols=ignore-all
+# RUN: ld.lld %t1.o %t.so -o %t1_3 --allow-shlib-undefined --unresolved-symbols=ignore-all
 # RUN: llvm-readobj %t1_3 > /dev/null 2>&1
 
 ## Ignoring undefines in objects should not produce error for symbol from object.
 # RUN: ld.lld %t1.o %t2.o -o %t2 --unresolved-symbols=ignore-in-object-files
 # RUN: llvm-readobj %t2 > /dev/null 2>&1
 ## And still should not should produce for undefines from DSOs.
-# RUN: ld.lld %t1.o %t.so -o /dev/null --unresolved-symbols=ignore-in-object-files
+# RUN: ld.lld %t1.o %t.so -o /dev/null --allow-shlib-undefined --unresolved-symbols=ignore-in-object-files
 # RUN: llvm-readobj %t2 > /dev/null 2>&1
 
 ## Ignoring undefines in shared should produce error for symbol from object.
 # RUN: not ld.lld %t2.o -o /dev/null --unresolved-symbols=ignore-in-shared-libs 2>&1 | \
 # RUN:   FileCheck -check-prefix=ERRUND %s
 ## And should not produce errors for symbols from DSO.
-# RUN: ld.lld %t1.o %t.so -o %t3_1 --unresolved-symbols=ignore-in-shared-libs
+# RUN: ld.lld %t1.o %t.so -o %t3_1 --allow-shlib-undefined --unresolved-symbols=ignore-in-shared-libs
 # RUN: llvm-readobj %t3_1 > /dev/null 2>&1
 
 ## Ignoring undefines in shared libs should not produce error for symbol from object
diff --git a/test/ELF/verdef-defaultver.s b/test/ELF/verdef-defaultver.s
index c8444c4..db50e7c 100644
--- a/test/ELF/verdef-defaultver.s
+++ b/test/ELF/verdef-defaultver.s
@@ -8,7 +8,7 @@
 
 # DSO:      DynamicSymbols [
 # DSO-NEXT:    Symbol {
-# DSO-NEXT:      Name: @
+# DSO-NEXT:      Name:
 # DSO-NEXT:      Value: 0x0
 # DSO-NEXT:      Size: 0
 # DSO-NEXT:      Binding: Local
@@ -61,7 +61,7 @@
 # DSO-NEXT:    Symbols [
 # DSO-NEXT:      Symbol {
 # DSO-NEXT:        Version: 0
-# DSO-NEXT:        Name: @
+# DSO-NEXT:        Name:
 # DSO-NEXT:      }
 # DSO-NEXT:      Symbol {
 # DSO-NEXT:        Version: 2
@@ -112,7 +112,7 @@
 
 # EXE:      DynamicSymbols [
 # EXE-NEXT:    Symbol {
-# EXE-NEXT:      Name: @
+# EXE-NEXT:      Name:
 # EXE-NEXT:      Value: 0x0
 # EXE-NEXT:      Size: 0
 # EXE-NEXT:      Binding: Local
@@ -156,7 +156,7 @@
 # EXE-NEXT:    Symbols [
 # EXE-NEXT:      Symbol {
 # EXE-NEXT:        Version: 0
-# EXE-NEXT:        Name: @
+# EXE-NEXT:        Name:
 # EXE-NEXT:      }
 # EXE-NEXT:      Symbol {
 # EXE-NEXT:        Version: 2
diff --git a/test/ELF/verdef.s b/test/ELF/verdef.s
index b5d12ee..9fc5bdd 100644
--- a/test/ELF/verdef.s
+++ b/test/ELF/verdef.s
@@ -14,7 +14,7 @@
 # DSO-NEXT:   Symbols [
 # DSO-NEXT:     Symbol {
 # DSO-NEXT:       Version: 0
-# DSO-NEXT:       Name: @
+# DSO-NEXT:       Name:
 # DSO-NEXT:     }
 # DSO-NEXT:     Symbol {
 # DSO-NEXT:       Version: 2
@@ -76,7 +76,7 @@
 # MAIN-NEXT:   Symbols [
 # MAIN-NEXT:     Symbol {
 # MAIN-NEXT:       Version: 0
-# MAIN-NEXT:       Name: @
+# MAIN-NEXT:       Name:
 # MAIN-NEXT:     }
 # MAIN-NEXT:     Symbol {
 # MAIN-NEXT:       Version: 2
diff --git a/test/ELF/verneed.s b/test/ELF/verneed.s
index 6e87f04..e8b65c4 100644
--- a/test/ELF/verneed.s
+++ b/test/ELF/verneed.s
@@ -76,7 +76,7 @@
 
 # CHECK:      DynamicSymbols [
 # CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name: @
+# CHECK-NEXT:     Name:
 # CHECK-NEXT:     Value: 0x0
 # CHECK-NEXT:     Size: 0
 # CHECK-NEXT:     Binding: Local (0x0)
@@ -125,7 +125,7 @@
 # CHECK-NEXT:    Symbols [
 # CHECK-NEXT:      Symbol {
 # CHECK-NEXT:        Version: 0
-# CHECK-NEXT:        Name: @
+# CHECK-NEXT:        Name:
 # CHECK-NEXT:      }
 # CHECK-NEXT:      Symbol {
 # CHECK-NEXT:        Version: 2
diff --git a/test/ELF/version-script-complex-wildcards.s b/test/ELF/version-script-complex-wildcards.s
index ce001d0..1ba3478 100644
--- a/test/ELF/version-script-complex-wildcards.s
+++ b/test/ELF/version-script-complex-wildcards.s
@@ -4,14 +4,14 @@
 # RUN: echo "FOO { global: extern \"C++\" { ab[c]*; }; };" > %t.script
 # RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
 # RUN: llvm-readobj -V %t.so | FileCheck %s --check-prefix=ABC
-# ABC: Name: _Z3abbi@
+# ABC: Name: _Z3abbi
 # ABC: Name: _Z3abci@@FOO
 
 # RUN: echo "FOO { global: extern \"C++\" { ab[b]*; }; };" > %t1.script
 # RUN: ld.lld --version-script %t1.script -shared %t.o -o %t1.so
 # RUN: llvm-readobj -V %t1.so | FileCheck %s --check-prefix=ABB
 # ABB: Name: _Z3abbi@@FOO
-# ABB: Name: _Z3abci@
+# ABB: Name: _Z3abci
 
 # RUN: echo "FOO { global: extern \"C++\" { ab[a-b]*; }; };" > %t2.script
 # RUN: ld.lld --version-script %t2.script -shared %t.o -o %t2.so
@@ -34,8 +34,8 @@
 # RUN: echo "FOO { global: extern \"C++\" { ab[^a-c]*; }; };" > %t6.script
 # RUN: ld.lld --version-script %t6.script -shared %t.o -o %t6.so
 # RUN: llvm-readobj -V %t6.so | FileCheck %s --check-prefix=NO
-# NO:  Name: _Z3abbi@
-# NO:  Name: _Z3abci@
+# NO:  Name: _Z3abbi
+# NO:  Name: _Z3abci
 
 # RUN: echo "FOO { global: extern \"C++\" { ab[^c-z]*; }; };" > %t7.script
 # RUN: ld.lld --version-script %t7.script -shared %t.o -o %t7.so
diff --git a/test/ELF/version-script-extern-undefined.s b/test/ELF/version-script-extern-undefined.s
index 518b122..8bff405 100644
--- a/test/ELF/version-script-extern-undefined.s
+++ b/test/ELF/version-script-extern-undefined.s
@@ -8,11 +8,11 @@
 # CHECK:      Symbols [
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Version: 0
-# CHECK-NEXT:     Name: @
+# CHECK-NEXT:     Name:
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Version: 1
-# CHECK-NEXT:     Name: _Z3abbi@
+# CHECK-NEXT:     Name: _Z3abbi
 # CHECK-NEXT:   }
 # CHECK-NEXT: ]
 
diff --git a/test/ELF/version-script-extern-wildcards.s b/test/ELF/version-script-extern-wildcards.s
index 472fc1f..27660b2 100644
--- a/test/ELF/version-script-extern-wildcards.s
+++ b/test/ELF/version-script-extern-wildcards.s
@@ -8,7 +8,7 @@
 
 # CHECK:  Version symbols {
 # CHECK:   Symbols [
-# CHECK:    Name: _Z3bari@
+# CHECK:    Name: _Z3bari
 # CHECK:    Name: _Z3fooi@@FOO
 # CHECK:    Name: _Z3zedi@@BAR
 
diff --git a/test/ELF/version-script-extern.s b/test/ELF/version-script-extern.s
index 16f4003..682afb0 100644
--- a/test/ELF/version-script-extern.s
+++ b/test/ELF/version-script-extern.s
@@ -12,7 +12,7 @@
 
 # DSO:      DynamicSymbols [
 # DSO-NEXT:    Symbol {
-# DSO-NEXT:      Name: @
+# DSO-NEXT:      Name:
 # DSO-NEXT:      Value: 0x0
 # DSO-NEXT:      Size: 0
 # DSO-NEXT:      Binding: Local
@@ -74,7 +74,7 @@
 # DSO-NEXT:    Symbols [
 # DSO-NEXT:      Symbol {
 # DSO-NEXT:        Version: 0
-# DSO-NEXT:        Name: @
+# DSO-NEXT:        Name:
 # DSO-NEXT:      }
 # DSO-NEXT:      Symbol {
 # DSO-NEXT:        Version: 3
diff --git a/test/ELF/version-script-extern2.s b/test/ELF/version-script-extern2.s
index 834bbe1..245cb00 100644
--- a/test/ELF/version-script-extern2.s
+++ b/test/ELF/version-script-extern2.s
@@ -8,7 +8,7 @@
 # CHECK:      Symbols [
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Version: 0
-# CHECK-NEXT:     Name: @
+# CHECK-NEXT:     Name:
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Version: 2
diff --git a/test/ELF/version-script-hide-so-symbol.s b/test/ELF/version-script-hide-so-symbol.s
index b4f58be..c84e37a 100644
--- a/test/ELF/version-script-hide-so-symbol.s
+++ b/test/ELF/version-script-hide-so-symbol.s
@@ -12,7 +12,7 @@
 
 # CHECK:      DynamicSymbols [
 # CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name: @ (0)
+# CHECK-NEXT:     Name:
 # CHECK-NEXT:     Value: 0x0
 # CHECK-NEXT:     Size: 0
 # CHECK-NEXT:     Binding: Local
diff --git a/test/ELF/version-script-locals-extern.s b/test/ELF/version-script-locals-extern.s
index 12e8771..ca1d717 100644
--- a/test/ELF/version-script-locals-extern.s
+++ b/test/ELF/version-script-locals-extern.s
@@ -7,11 +7,11 @@
 # ABB:      Symbols [
 # ABB-NEXT:   Symbol {
 # ABB-NEXT:     Version: 0
-# ABB-NEXT:     Name: @
+# ABB-NEXT:     Name:
 # ABB-NEXT:   }
 # ABB-NEXT:   Symbol {
 # ABB-NEXT:     Version: 1
-# ABB-NEXT:     Name: _Z3abci@
+# ABB-NEXT:     Name: _Z3abci
 # ABB-NEXT:   }
 # ABB-NEXT: ]
 
@@ -26,11 +26,11 @@
 # ABC:      Symbols [
 # ABC-NEXT:   Symbol {
 # ABC-NEXT:     Version: 0
-# ABC-NEXT:     Name: @
+# ABC-NEXT:     Name:
 # ABC-NEXT:   }
 # ABC-NEXT:   Symbol {
 # ABC-NEXT:     Version: 1
-# ABC-NEXT:     Name: _Z3abbi@
+# ABC-NEXT:     Name: _Z3abbi
 # ABC-NEXT:   }
 # ABC-NEXT: ]
 
diff --git a/test/ELF/version-script-symver2.s b/test/ELF/version-script-symver2.s
index 5961d9a..8441e19 100644
--- a/test/ELF/version-script-symver2.s
+++ b/test/ELF/version-script-symver2.s
@@ -7,7 +7,7 @@
 # CHECK:      Symbols [
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Version: 0
-# CHECK-NEXT:     Name: @
+# CHECK-NEXT:     Name:
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Version: 3
diff --git a/test/ELF/version-script-weak.s b/test/ELF/version-script-weak.s
index cc3df8d..887d6f9 100644
--- a/test/ELF/version-script-weak.s
+++ b/test/ELF/version-script-weak.s
@@ -14,7 +14,7 @@
 # CHECK-NEXT:   }
 # CHECK-NEXT: ]
 # CHECK:      Symbol {
-# CHECK:        Name: foo@
+# CHECK:        Name: foo
 # CHECK-NEXT:   Value: 0x0
 # CHECK-NEXT:   Size: 0
 # CHECK-NEXT:   Binding: Weak
diff --git a/test/ELF/version-script.s b/test/ELF/version-script.s
index 75083ac..5f2f3c4 100644
--- a/test/ELF/version-script.s
+++ b/test/ELF/version-script.s
@@ -50,7 +50,7 @@
 
 # DSO:      DynamicSymbols [
 # DSO-NEXT:   Symbol {
-# DSO-NEXT:     Name: @
+# DSO-NEXT:     Name:
 # DSO-NEXT:     Value: 0x0
 # DSO-NEXT:     Size: 0
 # DSO-NEXT:     Binding: Local (0x0)
@@ -59,7 +59,7 @@
 # DSO-NEXT:     Section: Undefined (0x0)
 # DSO-NEXT:   }
 # DSO-NEXT:   Symbol {
-# DSO-NEXT:     Name: bar@
+# DSO-NEXT:     Name: bar
 # DSO-NEXT:     Value: 0x0
 # DSO-NEXT:     Size: 0
 # DSO-NEXT:     Binding: Global (0x1)
@@ -68,7 +68,7 @@
 # DSO-NEXT:     Section: Undefined (0x0)
 # DSO-NEXT:   }
 # DSO-NEXT:   Symbol {
-# DSO-NEXT:     Name: foo1@
+# DSO-NEXT:     Name: foo1
 # DSO-NEXT:     Value: 0x1000
 # DSO-NEXT:     Size: 0
 # DSO-NEXT:     Binding: Global (0x1)
@@ -77,7 +77,7 @@
 # DSO-NEXT:     Section: .text
 # DSO-NEXT:   }
 # DSO-NEXT:   Symbol {
-# DSO-NEXT:     Name: foo3@
+# DSO-NEXT:     Name: foo3
 # DSO-NEXT:     Value: 0x1007
 # DSO-NEXT:     Size: 0
 # DSO-NEXT:     Binding: Global (0x1)
@@ -89,7 +89,7 @@
 
 # DSO2:      DynamicSymbols [
 # DSO2-NEXT:   Symbol {
-# DSO2-NEXT:     Name: @
+# DSO2-NEXT:     Name:
 # DSO2-NEXT:     Value: 0x0
 # DSO2-NEXT:     Size: 0
 # DSO2-NEXT:     Binding: Local (0x0)
@@ -98,7 +98,7 @@
 # DSO2-NEXT:     Section: Undefined (0x0)
 # DSO2-NEXT:   }
 # DSO2-NEXT:   Symbol {
-# DSO2-NEXT:     Name: bar@
+# DSO2-NEXT:     Name: bar
 # DSO2-NEXT:     Value: 0x0
 # DSO2-NEXT:     Size: 0
 # DSO2-NEXT:     Binding: Global (0x1)
@@ -110,7 +110,7 @@
 
 # VERDSO:      DynamicSymbols [
 # VERDSO-NEXT:   Symbol {
-# VERDSO-NEXT:     Name: @
+# VERDSO-NEXT:     Name:
 # VERDSO-NEXT:     Value: 0x0
 # VERDSO-NEXT:     Size: 0
 # VERDSO-NEXT:     Binding: Local
@@ -119,7 +119,7 @@
 # VERDSO-NEXT:     Section: Undefined
 # VERDSO-NEXT:   }
 # VERDSO-NEXT:   Symbol {
-# VERDSO-NEXT:     Name: bar@
+# VERDSO-NEXT:     Name: bar
 # VERDSO-NEXT:     Value: 0x0
 # VERDSO-NEXT:     Size: 0
 # VERDSO-NEXT:     Binding: Global
@@ -158,7 +158,7 @@
 
 # ALL:      DynamicSymbols [
 # ALL-NEXT:   Symbol {
-# ALL-NEXT:     Name: @
+# ALL-NEXT:     Name:
 # ALL-NEXT:     Value: 0x0
 # ALL-NEXT:     Size: 0
 # ALL-NEXT:     Binding: Local
@@ -167,7 +167,7 @@
 # ALL-NEXT:     Section: Undefined
 # ALL-NEXT:   }
 # ALL-NEXT:  Symbol {
-# ALL-NEXT:    Name: _start@
+# ALL-NEXT:    Name: _start
 # ALL-NEXT:    Value:
 # ALL-NEXT:    Size: 0
 # ALL-NEXT:    Binding: Global
@@ -176,7 +176,7 @@
 # ALL-NEXT:    Section: .text
 # ALL-NEXT:  }
 # ALL-NEXT:  Symbol {
-# ALL-NEXT:    Name: bar@
+# ALL-NEXT:    Name: bar
 # ALL-NEXT:    Value:
 # ALL-NEXT:    Size: 0
 # ALL-NEXT:    Binding: Global
@@ -185,7 +185,7 @@
 # ALL-NEXT:    Section: Undefined
 # ALL-NEXT:  }
 # ALL-NEXT:  Symbol {
-# ALL-NEXT:    Name: foo1@
+# ALL-NEXT:    Name: foo1
 # ALL-NEXT:    Value:
 # ALL-NEXT:    Size: 0
 # ALL-NEXT:    Binding: Global
@@ -194,7 +194,7 @@
 # ALL-NEXT:    Section: .text
 # ALL-NEXT:  }
 # ALL-NEXT:  Symbol {
-# ALL-NEXT:    Name: foo2@
+# ALL-NEXT:    Name: foo2
 # ALL-NEXT:    Value:
 # ALL-NEXT:    Size: 0
 # ALL-NEXT:    Binding: Global
@@ -203,7 +203,7 @@
 # ALL-NEXT:    Section: .text
 # ALL-NEXT:  }
 # ALL-NEXT:  Symbol {
-# ALL-NEXT:    Name: foo3@
+# ALL-NEXT:    Name: foo3
 # ALL-NEXT:    Value:
 # ALL-NEXT:    Size: 0
 # ALL-NEXT:    Binding: Global
diff --git a/test/ELF/version-wildcard.test b/test/ELF/version-wildcard.test
index ac0b7ed..f9a4331 100644
--- a/test/ELF/version-wildcard.test
+++ b/test/ELF/version-wildcard.test
@@ -7,7 +7,7 @@
 
 # CHECK: DynamicSymbols [
 # CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name: @
+# CHECK-NEXT:     Name:
 # CHECK-NEXT:     Value: 0x0
 # CHECK-NEXT:     Size: 0
 # CHECK-NEXT:     Binding: Local
@@ -52,7 +52,7 @@
 
 # MIX:      DynamicSymbols [
 # MIX-NEXT:   Symbol {
-# MIX-NEXT:     Name: @
+# MIX-NEXT:     Name:
 # MIX-NEXT:     Value: 0x0
 # MIX-NEXT:     Size: 0
 # MIX-NEXT:     Binding: Local
diff --git a/test/ELF/visibility.s b/test/ELF/visibility.s
index 0582d71..b9e9b55 100644
--- a/test/ELF/visibility.s
+++ b/test/ELF/visibility.s
@@ -82,7 +82,7 @@
 
 // CHECK:      DynamicSymbols [
 // CHECK-NEXT:   Symbol {
-// CHECK-NEXT:     Name: @
+// CHECK-NEXT:     Name:
 // CHECK-NEXT:     Value: 0x0
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Local
diff --git a/test/ELF/weak-undef-export.s b/test/ELF/weak-undef-export.s
index 164bc17..561a057 100644
--- a/test/ELF/weak-undef-export.s
+++ b/test/ELF/weak-undef-export.s
@@ -8,7 +8,7 @@
 
 # CHECK:      DynamicSymbols [
 # CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name: @ (0)
+# CHECK-NEXT:     Name:
 # CHECK-NEXT:     Value: 0x0
 # CHECK-NEXT:     Size: 0
 # CHECK-NEXT:     Binding: Local (0x0)
@@ -17,7 +17,7 @@
 # CHECK-NEXT:     Section: Undefined (0x0)
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name: foo@ (1)
+# CHECK-NEXT:     Name: foo
 # CHECK-NEXT:     Value: 0x0
 # CHECK-NEXT:     Size: 0
 # CHECK-NEXT:     Binding: Weak (0x2)
diff --git a/test/ELF/weak-undef.s b/test/ELF/weak-undef.s
index 09c2a4c..e7905c3 100644
--- a/test/ELF/weak-undef.s
+++ b/test/ELF/weak-undef.s
@@ -5,7 +5,7 @@
 
 # CHECK:      DynamicSymbols [
 # CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name: @
+# CHECK-NEXT:     Name:
 # CHECK-NEXT:     Value: 0x0
 # CHECK-NEXT:     Size: 0
 # CHECK-NEXT:     Binding: Local (0x0)
@@ -14,7 +14,7 @@
 # CHECK-NEXT:     Section: Undefined (0x0)
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name: foo@
+# CHECK-NEXT:     Name: foo
 # CHECK-NEXT:     Value: 0x0
 # CHECK-NEXT:     Size: 0
 # CHECK-NEXT:     Binding: Weak
diff --git a/test/ELF/wrap-no-real.s b/test/ELF/wrap-no-real.s
index d6bda77..2dba291 100644
--- a/test/ELF/wrap-no-real.s
+++ b/test/ELF/wrap-no-real.s
@@ -18,8 +18,7 @@
 // RUN: llvm-objdump -t %t | FileCheck -check-prefix=SYM %s
 
 
-// SYM:      0000000000000000  *UND*     00000000
-// SYM-NEXT: 0000000000202000  .dynamic  00000000 .hidden _DYNAMIC
+// SYM:      0000000000202000  .dynamic  00000000 .hidden _DYNAMIC
 // SYM-NEXT: 0000000000011000  *ABS*     00000000 __real_foo
 // SYM-NEXT: 0000000000011010  *ABS*     00000000 __wrap_foo
 // SYM-NEXT: 0000000000201000  .text     00000000 _start
diff --git a/test/ELF/wrap-with-archive.s b/test/ELF/wrap-with-archive.s
new file mode 100644
index 0000000..1bfbdce
--- /dev/null
+++ b/test/ELF/wrap-with-archive.s
@@ -0,0 +1,13 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/wrap-with-archive.s -o %t2
+// RUN: llvm-ar rcs %t3 %t2
+// RUN: ld.lld -o %t4 %t %t3 -wrap get_executable_start
+
+// Regression test for https://bugs.llvm.org/show_bug.cgi?id=40134
+	
+.global get_executable_start
+.global _start
+
+_start:
+	jmp get_executable_start
diff --git a/test/ELF/x86-64-pcrel.s b/test/ELF/x86-64-pcrel.s
new file mode 100644
index 0000000..8129c9c
--- /dev/null
+++ b/test/ELF/x86-64-pcrel.s
@@ -0,0 +1,23 @@
+// REQUIRES: x86
+
+// This is a test for R_X86_64_PC8 and R_X86_64_PC16.
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/x86-64-pcrel.s -o %t2.o
+// RUN: ld.lld -o %t.exe %t1.o %t2.o
+// RUN: llvm-objdump -s %t.exe | FileCheck %s
+
+// CHECK:      Contents of section .text:
+// CHECK-NEXT: 2000cccc cccccccc cccccccc cccccccc
+// CHECK-NEXT: 20cccccc cccccccc cccccccc cccccccc
+// CHECK-NEXT: e0ffcccc cccccccc cccccccc cccccccc
+// CHECK-NEXT: e0cccccc cccccccc cccccccc cccccccc
+
+.globl _start
+_start:
+
+.word foo - _start
+.fill 14,1,0xcc
+
+.byte foo - _start
+.fill 15,1,0xcc
diff --git a/test/ELF/x86-64-reloc-error2.s b/test/ELF/x86-64-reloc-error2.s
index 81f033f..230241b 100644
--- a/test/ELF/x86-64-reloc-error2.s
+++ b/test/ELF/x86-64-reloc-error2.s
@@ -4,7 +4,7 @@
 
 ## Check we are able to find a function symbol that encloses
 ## a given location when reporting error messages.
-# CHECK: {{.*}}.o:(function func): relocation R_X86_64_32S out of range: -281474974609408 is not in [-2147483648, 2147483647]
+# CHECK: {{.*}}.o:(function func: .text.func+0x3): relocation R_X86_64_32S out of range: -281474974609408 is not in [-2147483648, 2147483647]
 
 # This mergeable section will be garbage collected. We had a crash issue in that case. Test it.
 .section .rodata.str1,"aMS",@progbits,1
diff --git a/test/ELF/x86-64-reloc-range-debug-loc.s b/test/ELF/x86-64-reloc-range-debug-loc.s
index 8be4df3..08a4960 100644
--- a/test/ELF/x86-64-reloc-range-debug-loc.s
+++ b/test/ELF/x86-64-reloc-range-debug-loc.s
@@ -5,7 +5,7 @@
 
 ## Check we are able to report file and location from debug information
 ## when reporting such kind of errors.
-# CHECK: error: test.s:3: relocation R_X86_64_32 out of range: 68719476736 is not in [0, 4294967295]
+# CHECK: error: test.s:3:(.text+0x1): relocation R_X86_64_32 out of range: 68719476736 is not in [0, 4294967295]
 
 .section .text,"ax",@progbits
 foo:
diff --git a/test/ELF/x86-64-retpoline-znow-static-iplt.s b/test/ELF/x86-64-retpoline-znow-static-iplt.s
index 0321f6e..70355c0 100644
--- a/test/ELF/x86-64-retpoline-znow-static-iplt.s
+++ b/test/ELF/x86-64-retpoline-znow-static-iplt.s
@@ -8,7 +8,7 @@
 # CHECK-NEXT:  201001:       callq   42
 
 #Static IPLT header due to -z retpolineplt
-# CHECK:      {{^}}.plt:
+# CHECK:       0000000000201010 .plt:
 # CHECK-NEXT:  201010:       callq   11 <.plt+0x10>
 # CHECK-NEXT:  201015:       pause
 # CHECK-NEXT:  201017:       lfence
diff --git a/test/ELF/x86-64-static-tls-model.s b/test/ELF/x86-64-static-tls-model.s
new file mode 100644
index 0000000..9781d79
--- /dev/null
+++ b/test/ELF/x86-64-static-tls-model.s
@@ -0,0 +1,18 @@
+# REQUIRES: x86
+
+## In this test R_X86_64_GOTTPOFF is a IE relocation (static TLS model),
+## test check we add STATIC_TLS flag.
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t1 -shared
+# RUN: llvm-readobj -dynamic-table %t1 | FileCheck %s
+
+# CHECK: DynamicSection [
+# CHECK: FLAGS STATIC_TLS
+
+.section ".tdata", "awT", @progbits
+.globl var
+var:
+
+movq var@GOTTPOFF(%rip), %rax # R_X86_64_GOTTPOFF
+movl %fs:0(%rax), %eax
diff --git a/test/MinGW/driver.test b/test/MinGW/driver.test
index 3222bb1..f944994 100644
--- a/test/MinGW/driver.test
+++ b/test/MinGW/driver.test
@@ -151,3 +151,9 @@
 
 RUN: ld.lld -### -m i386pep foo.o -Llibpath | FileCheck -check-prefix LIBPATH %s
 LIBPATH: -libpath:libpath
+
+RUN: ld.lld -### -m i386pep foo.o --no-insert-timestamp | FileCheck -check-prefix NOTIMESTAMP %s
+RUN: ld.lld -### -m i386pep foo.o --insert-timestamp --no-insert-timestamp | FileCheck -check-prefix NOTIMESTAMP %s
+NOTIMESTAMP: -timestamp:0
+RUN: ld.lld -### -m i386pep foo.o --no-insert-timestamp --insert-timestamp | FileCheck -check-prefix TIMESTAMP %s
+TIMESTAMP-NOT: -timestamp:0
diff --git a/test/lit.cfg.py b/test/lit.cfg.py
index 9989a1c..350b40a 100644
--- a/test/lit.cfg.py
+++ b/test/lit.cfg.py
@@ -45,13 +45,18 @@
 
 llvm_config.add_tool_substitutions(tool_patterns)
 
+# LLD tests tend to be flaky on NetBSD, so add some retries.
+# We don't do this on other platforms because it's slower.
+if platform.system() in ['NetBSD']:
+    config.test_retry_attempts = 2
+
 # When running under valgrind, we mangle '-vg' onto the end of the triple so we
 # can check it with XFAIL and XTARGET.
 if lit_config.useValgrind:
     config.target_triple += '-vg'
 
 # Running on ELF based *nix
-if platform.system() in ['FreeBSD', 'Linux']:
+if platform.system() in ['FreeBSD', 'NetBSD', 'Linux']:
     config.available_features.add('system-linker-elf')
 
 # Set if host-cxxabi's demangler can handle target's symbols.
@@ -67,6 +72,7 @@
                           'AVR': 'avr',
                           'Hexagon': 'hexagon',
                           'Mips': 'mips',
+                          'MSP430': 'msp430',
                           'PowerPC': 'ppc',
                           'RISCV': 'riscv',
                           'Sparc': 'sparc',
@@ -81,11 +87,11 @@
 # Indirectly check if the mt.exe Microsoft utility exists by searching for
 # cvtres, which always accompanies it.  Alternatively, check if we can use
 # libxml2 to merge manifests.
-if (lit.util.which('cvtres', config.environment['PATH'])) or \
-        (config.llvm_libxml2_enabled == '1'):
+if (lit.util.which('cvtres', config.environment['PATH']) or 
+        config.llvm_libxml2_enabled):
     config.available_features.add('manifest_tool')
 
-if (config.llvm_libxml2_enabled == '1'):
+if config.llvm_libxml2_enabled:
     config.available_features.add('libxml2')
 
 if config.have_dia_sdk:
diff --git a/test/lit.site.cfg.py.in b/test/lit.site.cfg.py.in
index 7475ac7..07ffc23 100644
--- a/test/lit.site.cfg.py.in
+++ b/test/lit.site.cfg.py.in
@@ -7,7 +7,7 @@
 config.llvm_obj_root = "@LLVM_BINARY_DIR@"
 config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
 config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
-config.llvm_libxml2_enabled = "@LLVM_LIBXML2_ENABLED@"
+config.llvm_libxml2_enabled = @LLVM_LIBXML2_ENABLED@
 config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
 config.lld_obj_root = "@LLD_BINARY_DIR@"
 config.lld_libs_dir = "@LLVM_LIBRARY_OUTPUT_INTDIR@"
diff --git a/test/wasm/Inputs/globals.yaml b/test/wasm/Inputs/globals.yaml
index c08a304..6f63226 100644
--- a/test/wasm/Inputs/globals.yaml
+++ b/test/wasm/Inputs/globals.yaml
@@ -29,12 +29,12 @@
         Locals:
         Body:            2381808080000B
     Relocations:
-      - Type:            R_WEBASSEMBLY_GLOBAL_INDEX_LEB
+      - Type:            R_WASM_GLOBAL_INDEX_LEB
         Index:           1
         Offset:          0x00000004
   - Type:            CUSTOM
     Name:            linking
-    Version:         1
+    Version:         2
     SymbolTable:
       - Index:           0
         Kind:            GLOBAL
diff --git a/test/wasm/Inputs/undefined-globals.yaml b/test/wasm/Inputs/undefined-globals.yaml
index 440a538..fd5a236 100644
--- a/test/wasm/Inputs/undefined-globals.yaml
+++ b/test/wasm/Inputs/undefined-globals.yaml
@@ -27,12 +27,12 @@
         Locals:
         Body:            2381808080000B
     Relocations:
-      - Type:            R_WEBASSEMBLY_GLOBAL_INDEX_LEB
+      - Type:            R_WASM_GLOBAL_INDEX_LEB
         Index:           1
         Offset:          0x00000004
   - Type:            CUSTOM
     Name:            linking
-    Version:         1
+    Version:         2
     SymbolTable:
       - Index:           0
         Kind:            GLOBAL
diff --git a/test/wasm/alias.ll b/test/wasm/alias.ll
index d91f4b1..358582e 100644
--- a/test/wasm/alias.ll
+++ b/test/wasm/alias.ll
@@ -25,7 +25,7 @@
 ; CHECK-NEXT:     FunctionTypes:   [ 0, 0 ]
 ; CHECK-NEXT:   - Type:            TABLE
 ; CHECK-NEXT:     Tables:
-; CHECK-NEXT:       - ElemType:        ANYFUNC
+; CHECK-NEXT:       - ElemType:        FUNCREF
 ; CHECK-NEXT:         Limits:
 ; CHECK-NEXT:           Flags:           [ HAS_MAX ]
 ; CHECK-NEXT:           Initial:         0x00000001
diff --git a/test/wasm/archive-weak-undefined.ll b/test/wasm/archive-weak-undefined.ll
new file mode 100644
index 0000000..0285724
--- /dev/null
+++ b/test/wasm/archive-weak-undefined.ll
@@ -0,0 +1,19 @@
+; RUN: llc -filetype=obj %s -o %t.o
+; RUN: llc -filetype=obj %S/Inputs/ret32.ll -o %t.a1.o
+; RUN: rm -f %t.a
+; RUN: llvm-ar rcs %t.a %t.a1.o
+; RUN: wasm-ld %t.o %t.a -o %t.wasm
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+declare extern_weak i32 @ret32()
+
+define void @_start() {
+entry:
+  %call1 = call i32 @ret32()
+  ret void
+}
+
+; CHECK: Name: 'undefined:ret32'
+; CHECK-NOT: Name: ret32
diff --git a/test/wasm/archive.ll b/test/wasm/archive.ll
index beea272..f2eee96 100644
--- a/test/wasm/archive.ll
+++ b/test/wasm/archive.ll
@@ -33,10 +33,10 @@
 ; TODO(ncw): Update LLD so that the symbol table is written out for
 ;   non-relocatable output (with an option to strip it)
 
-; CHECK:      00000004 T _start
-; CHECK-NEXT: 00000002 T archive2_symbol
+; CHECK:      00000016 T _start
+; CHECK-NEXT: 0000000a T archive2_symbol
 ; CHECK-NEXT: 00000001 T bar
-; CHECK-NEXT: 00000003 T foo
+; CHECK-NEXT: 0000000d T foo
 ; CHECK-NEXT:          U missing_func
 
 ; Verify that symbols from unused objects don't appear in the symbol table
diff --git a/test/wasm/call-indirect.ll b/test/wasm/call-indirect.ll
index 1b9e172..7f8fe47 100644
--- a/test/wasm/call-indirect.ll
+++ b/test/wasm/call-indirect.ll
@@ -60,7 +60,7 @@
 ; CHECK-NEXT:     FunctionTypes:   [ 3, 0, 3, 1, 3, 4 ]
 ; CHECK-NEXT:   - Type:            TABLE
 ; CHECK-NEXT:     Tables:
-; CHECK-NEXT:       - ElemType:        ANYFUNC
+; CHECK-NEXT:       - ElemType:        FUNCREF
 ; CHECK-NEXT:         Limits:
 ; CHECK-NEXT:           Flags:           [ HAS_MAX ]
 ; CHECK-NEXT:           Initial:         0x00000003
diff --git a/test/wasm/cxx-mangling.ll b/test/wasm/cxx-mangling.ll
index e1f4ea4..9732d21 100644
--- a/test/wasm/cxx-mangling.ll
+++ b/test/wasm/cxx-mangling.ll
@@ -58,8 +58,8 @@
 ; CHECK-NEXT:       - Index:           0
 ; CHECK-NEXT:         Name:            __wasm_call_ctors
 ; CHECK-NEXT:       - Index:           1
-; DEMANGLE-NEXT:      Name:            'undefined function bar(int)'
-; MANGLE-NEXT:        Name:            undefined function _Z3bari
+; DEMANGLE-NEXT:      Name:            'undefined:bar(int)'
+; MANGLE-NEXT:        Name:            'undefined:_Z3bari'
 ; CHECK-NEXT:       - Index:           2
 ; DEMANGLE-NEXT:      Name:            'foo(int)'
 ; MANGLE-NEXT:        Name:            _Z3fooi
diff --git a/test/wasm/data-layout.ll b/test/wasm/data-layout.ll
index b01c13a..2edbec6 100644
--- a/test/wasm/data-layout.ll
+++ b/test/wasm/data-layout.ll
@@ -84,11 +84,11 @@
 
 ; RELOC:       - Type:            DATA
 ; RELOC-NEXT:     Relocations:
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_I32
-; RELOC-NEXT:         Index:           6
-; RELOC-NEXT:         Offset:          0x00000018
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_I32
+; RELOC-NEXT:       - Type:            R_WASM_MEMORY_ADDR_I32
 ; RELOC-NEXT:         Index:           3
+; RELOC-NEXT:         Offset:          0x00000018
+; RELOC-NEXT:       - Type:            R_WASM_MEMORY_ADDR_I32
+; RELOC-NEXT:         Index:           4
 ; RELOC-NEXT:         Offset:          0x0000002E
 ; RELOC-NEXT:         Addend:          4
 ; RELOC-NEXT:     Segments:
@@ -148,7 +148,7 @@
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:         Segment:         2
 ; RELOC-NEXT:         Size:            4
-; RELOC:            - Index:           6
+; RELOC-NEXT:       - Index:           3
 ; RELOC-NEXT:         Kind:            DATA
 ; RELOC-NEXT:         Name:            hello_str
 ; RELOC-NEXT:         Flags:           [  ]
diff --git a/test/wasm/export-table.test b/test/wasm/export-table.test
index 58775b9..e2d05f0 100644
--- a/test/wasm/export-table.test
+++ b/test/wasm/export-table.test
@@ -6,7 +6,7 @@
 
 # CHECK:        - Type:            TABLE
 # CHECK-NEXT:     Tables:
-# CHECK-NEXT:       - ElemType:        ANYFUNC
+# CHECK-NEXT:       - ElemType:        FUNCREF
 # CHECK-NEXT:         Limits:
 # CHECK-NEXT:           Flags:           [ HAS_MAX ]
 # CHECK-NEXT:           Initial:         0x00000001
diff --git a/test/wasm/export.ll b/test/wasm/export.ll
index 519aafe..48b66ee 100644
--- a/test/wasm/export.ll
+++ b/test/wasm/export.ll
@@ -3,13 +3,29 @@
 ; RUN: wasm-ld --export=hidden_function -o %t.wasm %t.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
+@llvm.used = appending global [1 x i8*] [i8* bitcast (i32 ()* @used_function to i8*)], section "llvm.metadata"
+
 target triple = "wasm32-unknown-unknown"
 
+; Not exported by default, but forced via commandline
 define hidden i32 @hidden_function() local_unnamed_addr {
 entry:
   ret i32 0
 }
 
+; Not exported by default
+define i32 @default_function() local_unnamed_addr {
+entry:
+  ret i32 0
+}
+
+; Exported because its part of llvm.used
+define i32 @used_function() local_unnamed_addr {
+entry:
+  ret i32 0
+}
+
+; Exported by default
 define void @_start() local_unnamed_addr {
 entry:
   ret void
@@ -17,6 +33,8 @@
 
 ; CHECK-ERROR: error: symbol exported via --export not found: missing
 
+; CHECK-NOT: - Name: default_function
+
 ; CHECK:        - Type:            EXPORT
 ; CHECK-NEXT:     Exports:
 ; CHECK-NEXT:       - Name:            memory
@@ -31,7 +49,10 @@
 ; CHECK-NEXT:       - Name:            hidden_function
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           1
-; CHECK-NEXT:       - Name:            _start
+; CHECK-NEXT:       - Name:            used_function
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           2
+; CHECK-NEXT:       - Name:            _start
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Index:           3
 ; CHECK-NEXT:   - Type:            CODE
diff --git a/test/wasm/fatal-warnings.ll b/test/wasm/fatal-warnings.ll
index 0007dc2..d338420 100644
--- a/test/wasm/fatal-warnings.ll
+++ b/test/wasm/fatal-warnings.ll
@@ -1,7 +1,7 @@
 ; RUN: llc -filetype=obj %s -o %t.main.o
 ; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
-; RUN: lld -flavor wasm -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-WARN
-; RUN: not lld -flavor wasm --fatal-warnings -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-FATAL
+; RUN: wasm-ld -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-WARN
+; RUN: not wasm-ld --fatal-warnings -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-FATAL
 
 ; CHECK-WARN: warning: function signature mismatch: ret32
 ; CHECK-FATAL: error: function signature mismatch: ret32
diff --git a/test/wasm/import-module.ll b/test/wasm/import-module.ll
new file mode 100644
index 0000000..9a47319
--- /dev/null
+++ b/test/wasm/import-module.ll
@@ -0,0 +1,21 @@
+; RUN: llc -filetype=obj %s -o %t.o
+; RUN: wasm-ld --allow-undefined -o %t.wasm %t.o
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+target triple = "wasm32-unknown-unknown-wasm"
+
+define void @_start() {
+  call void @foo();
+  ret void
+}
+
+declare void @foo() #0
+
+attributes #0 = { "wasm-import-module"="bar" }
+
+; CHECK:        - Type:            IMPORT
+; CHECK-NEXT:     Imports:         
+; CHECK-NEXT:       - Module:          bar
+; CHECK-NEXT:         Field:           foo
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         SigIndex:        0
diff --git a/test/wasm/import-names.ll b/test/wasm/import-names.ll
new file mode 100644
index 0000000..a3953d3
--- /dev/null
+++ b/test/wasm/import-names.ll
@@ -0,0 +1,27 @@
+; RUN: llc -filetype=obj %s -o %t.o
+; RUN: wasm-ld --allow-undefined -o %t.wasm %t.o
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+declare void @f0() #0
+
+define void @_start() {
+    call void @f0()
+    ret void
+}
+
+attributes #0 = { "wasm-import-module"="somewhere" "wasm-import-name"="something" }
+
+; CHECK:        - Type:            IMPORT
+; CHECK-NEXT:     Imports:
+; CHECK-NEXT:       - Module:          somewhere
+; CHECK-NEXT:         Field:           something
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         SigIndex:        0
+
+; CHECK:        - Type:            CUSTOM
+; CHECK-NEXT:     Name:            name
+; CHECK-NEXT:     FunctionNames:
+; CHECK-NEXT:       - Index:           0
+; CHECK-NEXT:         Name:            f0
diff --git a/test/wasm/import-table.test b/test/wasm/import-table.test
index ae42311..440509b 100644
--- a/test/wasm/import-table.test
+++ b/test/wasm/import-table.test
@@ -10,7 +10,7 @@
 # CHECK-NEXT:        Field:           __indirect_function_table
 # CHECK-NEXT:        Kind:            TABLE
 # CHECK-NEXT:        Table:
-# CHECK-NEXT:          ElemType:        ANYFUNC
+# CHECK-NEXT:          ElemType:        FUNCREF
 # CHECK-NEXT:          Limits:
 # CHECK-NEXT:            Initial:         0x00000001
 
diff --git a/test/wasm/init-fini.ll b/test/wasm/init-fini.ll
index 9a7f535..b17020b 100644
--- a/test/wasm/init-fini.ll
+++ b/test/wasm/init-fini.ll
@@ -163,64 +163,64 @@
 ; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
 ; RELOC-NEXT:         Function:        7
 ; RELOC-NEXT:       - Index:           6
-; RELOC-NEXT:         Kind:            FUNCTION
-; RELOC-NEXT:         Name:            .Lcall_dtors.101
-; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:         Function:        8
-; RELOC-NEXT:       - Index:           7
-; RELOC-NEXT:         Kind:            FUNCTION
-; RELOC-NEXT:         Name:            .Lregister_call_dtors.101
-; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:         Function:        9
-; RELOC-NEXT:       - Index:           8
 ; RELOC-NEXT:         Kind:            DATA
 ; RELOC-NEXT:         Name:            __dso_handle
 ; RELOC-NEXT:         Flags:           [ BINDING_WEAK, VISIBILITY_HIDDEN, UNDEFINED ]
-; RELOC-NEXT:       - Index:           9
-; RELOC-NEXT:         Kind:            FUNCTION
-; RELOC-NEXT:         Name:            .Lcall_dtors.1001
-; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:         Function:        10
-; RELOC-NEXT:       - Index:           10
-; RELOC-NEXT:         Kind:            FUNCTION
-; RELOC-NEXT:         Name:            .Lregister_call_dtors.1001
-; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:         Function:        11
-; RELOC-NEXT:       - Index:           11
-; RELOC-NEXT:         Kind:            FUNCTION
-; RELOC-NEXT:         Name:            .Lcall_dtors.4000
-; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:         Function:        12
-; RELOC-NEXT:       - Index:           12
+; RELOC-NEXT:       - Index:           7
 ; RELOC-NEXT:         Kind:            FUNCTION
 ; RELOC-NEXT:         Name:            externDtor
 ; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN, UNDEFINED ]
 ; RELOC-NEXT:         Function:        0
-; RELOC-NEXT:       - Index:           13
-; RELOC-NEXT:         Kind:            FUNCTION
-; RELOC-NEXT:         Name:            .Lregister_call_dtors.4000
-; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:         Function:        13
-; RELOC-NEXT:       - Index:           14
+; RELOC-NEXT:       - Index:           8
 ; RELOC-NEXT:         Kind:            FUNCTION
 ; RELOC-NEXT:         Name:            externCtor
 ; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN, UNDEFINED ]
 ; RELOC-NEXT:         Function:        1
-; RELOC-NEXT:       - Index:           15
+; RELOC-NEXT:       - Index:           9
 ; RELOC-NEXT:         Kind:            FUNCTION
 ; RELOC-NEXT:         Name:            myctor
 ; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
 ; RELOC-NEXT:         Function:        14
-; RELOC-NEXT:       - Index:           16
+; RELOC-NEXT:       - Index:           10
 ; RELOC-NEXT:         Kind:            FUNCTION
 ; RELOC-NEXT:         Name:            mydtor
 ; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
 ; RELOC-NEXT:         Function:        15
-; RELOC-NEXT:       - Index:           17
+; RELOC-NEXT:       - Index:           11
 ; RELOC-NEXT:         Kind:            GLOBAL
 ; RELOC-NEXT:         Name:            __stack_pointer
 ; RELOC-NEXT:         Flags:           [ UNDEFINED ]
 ; RELOC-NEXT:         Global:          0
+; RELOC-NEXT:       - Index:           12
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            .Lcall_dtors.101
+; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Function:        8
+; RELOC-NEXT:       - Index:           13
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            .Lregister_call_dtors.101
+; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Function:        9
+; RELOC-NEXT:       - Index:           14
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            .Lcall_dtors.1001
+; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Function:        10
+; RELOC-NEXT:       - Index:           15
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            .Lregister_call_dtors.1001
+; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Function:        11
+; RELOC-NEXT:       - Index:           16
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            .Lcall_dtors.4000
+; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Function:        12
+; RELOC-NEXT:       - Index:           17
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            .Lregister_call_dtors.4000
+; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Function:        13
 ; RELOC-NEXT:       - Index:           18
 ; RELOC-NEXT:         Kind:            FUNCTION
 ; RELOC-NEXT:         Name:            .Lcall_dtors.101
@@ -251,36 +251,36 @@
 ; RELOC-NEXT:         Name:            .Lregister_call_dtors.2002
 ; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
 ; RELOC-NEXT:         Function:        21
-; RELOC-NEXT:     InitFunctions:
+; RELOC-NEXT:     InitFunctions:   
 ; RELOC-NEXT:       - Priority:        101
 ; RELOC-NEXT:         Symbol:          0
 ; RELOC-NEXT:       - Priority:        101
 ; RELOC-NEXT:         Symbol:          1
 ; RELOC-NEXT:       - Priority:        101
-; RELOC-NEXT:         Symbol:          7
+; RELOC-NEXT:         Symbol:          13
 ; RELOC-NEXT:       - Priority:        101
-; RELOC-NEXT:         Symbol:          15
+; RELOC-NEXT:         Symbol:          9
 ; RELOC-NEXT:       - Priority:        101
 ; RELOC-NEXT:         Symbol:          19
 ; RELOC-NEXT:       - Priority:        202
-; RELOC-NEXT:         Symbol:          15
+; RELOC-NEXT:         Symbol:          9
 ; RELOC-NEXT:       - Priority:        202
 ; RELOC-NEXT:         Symbol:          21
 ; RELOC-NEXT:       - Priority:        1001
 ; RELOC-NEXT:         Symbol:          0
 ; RELOC-NEXT:       - Priority:        1001
-; RELOC-NEXT:         Symbol:          10
-; RELOC-NEXT:       - Priority:        2002
 ; RELOC-NEXT:         Symbol:          15
 ; RELOC-NEXT:       - Priority:        2002
+; RELOC-NEXT:         Symbol:          9
+; RELOC-NEXT:       - Priority:        2002
 ; RELOC-NEXT:         Symbol:          23
 ; RELOC-NEXT:       - Priority:        4000
-; RELOC-NEXT:         Symbol:          14
+; RELOC-NEXT:         Symbol:          8
 ; RELOC-NEXT:       - Priority:        4000
-; RELOC-NEXT:         Symbol:          13
+; RELOC-NEXT:         Symbol:          17
 ; RELOC-NEXT:   - Type:            CUSTOM
 ; RELOC-NEXT:     Name:            name
-; RELOC-NEXT:     FunctionNames:
+; RELOC-NEXT:     FunctionNames:   
 ; RELOC-NEXT:       - Index:           0
 ; RELOC-NEXT:         Name:            externDtor
 ; RELOC-NEXT:       - Index:           1
diff --git a/test/wasm/local-symbols.ll b/test/wasm/local-symbols.ll
index 6d1a324..dd92b4e 100644
--- a/test/wasm/local-symbols.ll
+++ b/test/wasm/local-symbols.ll
@@ -36,7 +36,7 @@
 ; CHECK-NEXT:     FunctionTypes:   [ 0, 1, 0 ]
 ; CHECK-NEXT:   - Type:            TABLE
 ; CHECK-NEXT:     Tables:
-; CHECK-NEXT:       - ElemType:        ANYFUNC
+; CHECK-NEXT:       - ElemType:        FUNCREF
 ; CHECK-NEXT:         Limits:
 ; CHECK-NEXT:           Flags:           [ HAS_MAX ]
 ; CHECK-NEXT:           Initial:         0x00000001
diff --git a/test/wasm/locals-duplicate.test b/test/wasm/locals-duplicate.test
index 8da0b22..34a5cad 100644
--- a/test/wasm/locals-duplicate.test
+++ b/test/wasm/locals-duplicate.test
@@ -20,7 +20,7 @@
 ; CHECK-NEXT:                        1, 1, 1 ]
 ; CHECK-NEXT:   - Type:            TABLE
 ; CHECK-NEXT:     Tables:
-; CHECK-NEXT:       - ElemType:        ANYFUNC
+; CHECK-NEXT:       - ElemType:        FUNCREF
 ; CHECK-NEXT:         Limits:
 ; CHECK-NEXT:           Flags:           [ HAS_MAX ]
 ; CHECK-NEXT:           Initial:         0x00000007
@@ -253,7 +253,7 @@
 ; RELOC-NEXT:                        0, 0 ]
 ; RELOC-NEXT:   - Type:            TABLE
 ; RELOC-NEXT:     Tables:
-; RELOC-NEXT:       - ElemType:        ANYFUNC
+; RELOC-NEXT:       - ElemType:        FUNCREF
 ; RELOC-NEXT:         Limits:
 ; RELOC-NEXT:           Flags:           [ HAS_MAX ]
 ; RELOC-NEXT:           Initial:         0x00000007
@@ -269,41 +269,41 @@
 ; RELOC-NEXT:         Functions:       [ 0, 1, 2, 9, 10, 11 ]
 ; RELOC-NEXT:   - Type:            CODE
 ; RELOC-NEXT:     Relocations:
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT:         Index:           4
-; RELOC-NEXT:         Offset:          0x00000013
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT:         Index:           6
-; RELOC-NEXT:         Offset:          0x0000001C
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT:         Index:           8
-; RELOC-NEXT:         Offset:          0x00000025
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT:         Index:           0
-; RELOC-NEXT:         Offset:          0x0000002E
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT:         Index:           1
-; RELOC-NEXT:         Offset:          0x00000037
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT:         Index:           2
-; RELOC-NEXT:         Offset:          0x00000040
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT:         Index:           16
-; RELOC-NEXT:         Offset:          0x00000058
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_SLEB
+; RELOC-NEXT:       - Type:            R_WASM_MEMORY_ADDR_SLEB
 ; RELOC-NEXT:         Index:           18
+; RELOC-NEXT:         Offset:          0x00000013
+; RELOC-NEXT:       - Type:            R_WASM_MEMORY_ADDR_SLEB
+; RELOC-NEXT:         Index:           3
+; RELOC-NEXT:         Offset:          0x0000001C
+; RELOC-NEXT:       - Type:            R_WASM_MEMORY_ADDR_SLEB
+; RELOC-NEXT:         Index:           19
+; RELOC-NEXT:         Offset:          0x00000025
+; RELOC-NEXT:       - Type:            R_WASM_TABLE_INDEX_SLEB
+; RELOC-NEXT:         Index:           16
+; RELOC-NEXT:         Offset:          0x0000002E
+; RELOC-NEXT:       - Type:            R_WASM_TABLE_INDEX_SLEB
+; RELOC-NEXT:         Index:           0
+; RELOC-NEXT:         Offset:          0x00000037
+; RELOC-NEXT:       - Type:            R_WASM_TABLE_INDEX_SLEB
+; RELOC-NEXT:         Index:           17
+; RELOC-NEXT:         Offset:          0x00000040
+; RELOC-NEXT:       - Type:            R_WASM_MEMORY_ADDR_SLEB
+; RELOC-NEXT:         Index:           10
+; RELOC-NEXT:         Offset:          0x00000058
+; RELOC-NEXT:       - Type:            R_WASM_MEMORY_ADDR_SLEB
+; RELOC-NEXT:         Index:           22
 ; RELOC-NEXT:         Offset:          0x00000061
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT:         Index:           20
+; RELOC-NEXT:       - Type:            R_WASM_MEMORY_ADDR_SLEB
+; RELOC-NEXT:         Index:           23
 ; RELOC-NEXT:         Offset:          0x0000006A
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT:         Index:           12
+; RELOC-NEXT:       - Type:            R_WASM_TABLE_INDEX_SLEB
+; RELOC-NEXT:         Index:           8
 ; RELOC-NEXT:         Offset:          0x00000073
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT:         Index:           13
+; RELOC-NEXT:       - Type:            R_WASM_TABLE_INDEX_SLEB
+; RELOC-NEXT:         Index:           20
 ; RELOC-NEXT:         Offset:          0x0000007C
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT:         Index:           14
+; RELOC-NEXT:       - Type:            R_WASM_TABLE_INDEX_SLEB
+; RELOC-NEXT:         Index:           21
 ; RELOC-NEXT:         Offset:          0x00000085
 ; RELOC-NEXT:     Functions:
 ; RELOC-NEXT:       - Index:           0
@@ -382,149 +382,149 @@
 ; RELOC-NEXT:         Content:         '0000000000000000'
 ; RELOC-NEXT:   - Type:            CUSTOM
 ; RELOC-NEXT:     Name:            linking
-; RELOC-NEXT:     Version:         1
+; RELOC-NEXT:     Version:         2
 ; RELOC-NEXT:     SymbolTable:
 ; RELOC-NEXT:       - Index:           0
 ; RELOC-NEXT:         Kind:            FUNCTION
-; RELOC-NEXT:         Name:            colliding_func1
-; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:         Function:        0
-; RELOC-NEXT:       - Index:           1
-; RELOC-NEXT:         Kind:            FUNCTION
 ; RELOC-NEXT:         Name:            colliding_func2
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:         Function:        1
-; RELOC-NEXT:       - Index:           2
-; RELOC-NEXT:         Kind:            FUNCTION
-; RELOC-NEXT:         Name:            colliding_func3
-; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:         Function:        2
-; RELOC-NEXT:       - Index:           3
+; RELOC-NEXT:       - Index:           1
 ; RELOC-NEXT:         Kind:            FUNCTION
 ; RELOC-NEXT:         Name:            get_global1A
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:         Function:        3
-; RELOC-NEXT:       - Index:           4
-; RELOC-NEXT:         Kind:            DATA
-; RELOC-NEXT:         Name:            colliding_global1
-; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:         Segment:         0
-; RELOC-NEXT:         Size:            4
-; RELOC-NEXT:       - Index:           5
+; RELOC-NEXT:       - Index:           2
 ; RELOC-NEXT:         Kind:            FUNCTION
 ; RELOC-NEXT:         Name:            get_global2A
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:         Function:        4
-; RELOC-NEXT:       - Index:           6
+; RELOC-NEXT:       - Index:           3
 ; RELOC-NEXT:         Kind:            DATA
 ; RELOC-NEXT:         Name:            colliding_global2
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:         Segment:         1
 ; RELOC-NEXT:         Size:            4
-; RELOC-NEXT:       - Index:           7
+; RELOC-NEXT:       - Index:           4
 ; RELOC-NEXT:         Kind:            FUNCTION
 ; RELOC-NEXT:         Name:            get_global3A
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:         Function:        5
-; RELOC-NEXT:       - Index:           8
-; RELOC-NEXT:         Kind:            DATA
-; RELOC-NEXT:         Name:            colliding_global3
-; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:         Segment:         2
-; RELOC-NEXT:         Size:            4
-; RELOC-NEXT:       - Index:           9
+; RELOC-NEXT:       - Index:           5
 ; RELOC-NEXT:         Kind:            FUNCTION
 ; RELOC-NEXT:         Name:            get_func1A
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:         Function:        6
-; RELOC-NEXT:       - Index:           10
+; RELOC-NEXT:       - Index:           6
 ; RELOC-NEXT:         Kind:            FUNCTION
 ; RELOC-NEXT:         Name:            get_func2A
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:         Function:        7
-; RELOC-NEXT:       - Index:           11
+; RELOC-NEXT:       - Index:           7
 ; RELOC-NEXT:         Kind:            FUNCTION
 ; RELOC-NEXT:         Name:            get_func3A
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:         Function:        8
-; RELOC-NEXT:       - Index:           12
+; RELOC-NEXT:       - Index:           8
 ; RELOC-NEXT:         Kind:            FUNCTION
 ; RELOC-NEXT:         Name:            colliding_func1
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:         Function:        9
-; RELOC-NEXT:       - Index:           13
-; RELOC-NEXT:         Kind:            FUNCTION
-; RELOC-NEXT:         Name:            colliding_func2
-; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:         Function:        10
-; RELOC-NEXT:       - Index:           14
-; RELOC-NEXT:         Kind:            FUNCTION
-; RELOC-NEXT:         Name:            colliding_func3
-; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:         Function:        11
-; RELOC-NEXT:       - Index:           15
+; RELOC-NEXT:       - Index:           9
 ; RELOC-NEXT:         Kind:            FUNCTION
 ; RELOC-NEXT:         Name:            get_global1B
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:         Function:        12
-; RELOC-NEXT:       - Index:           16
+; RELOC-NEXT:       - Index:           10
 ; RELOC-NEXT:         Kind:            DATA
 ; RELOC-NEXT:         Name:            colliding_global1
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:         Segment:         0
 ; RELOC-NEXT:         Offset:          4
 ; RELOC-NEXT:         Size:            4
-; RELOC-NEXT:       - Index:           17
+; RELOC-NEXT:       - Index:           11
 ; RELOC-NEXT:         Kind:            FUNCTION
 ; RELOC-NEXT:         Name:            get_global2B
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:         Function:        13
+; RELOC-NEXT:       - Index:           12
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            get_global3B
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        14
+; RELOC-NEXT:       - Index:           13
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            get_func1B
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        15
+; RELOC-NEXT:       - Index:           14
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            get_func2B
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        16
+; RELOC-NEXT:       - Index:           15
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            get_func3B
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        17
+; RELOC-NEXT:       - Index:           16
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            colliding_func1
+; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Function:        0
+; RELOC-NEXT:       - Index:           17
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            colliding_func3
+; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Function:        2
 ; RELOC-NEXT:       - Index:           18
 ; RELOC-NEXT:         Kind:            DATA
+; RELOC-NEXT:         Name:            colliding_global1
+; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Segment:         0
+; RELOC-NEXT:         Size:            4
+; RELOC-NEXT:       - Index:           19
+; RELOC-NEXT:         Kind:            DATA
+; RELOC-NEXT:         Name:            colliding_global3
+; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Segment:         2
+; RELOC-NEXT:         Size:            4
+; RELOC-NEXT:       - Index:           20
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            colliding_func2
+; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Function:        10
+; RELOC-NEXT:       - Index:           21
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            colliding_func3
+; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Function:        11
+; RELOC-NEXT:       - Index:           22
+; RELOC-NEXT:         Kind:            DATA
 ; RELOC-NEXT:         Name:            colliding_global2
 ; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
 ; RELOC-NEXT:         Segment:         1
 ; RELOC-NEXT:         Offset:          4
 ; RELOC-NEXT:         Size:            4
-; RELOC-NEXT:       - Index:           19
-; RELOC-NEXT:         Kind:            FUNCTION
-; RELOC-NEXT:         Name:            get_global3B
-; RELOC-NEXT:         Flags:           [  ]
-; RELOC-NEXT:         Function:        14
-; RELOC-NEXT:       - Index:           20
+; RELOC-NEXT:       - Index:           23
 ; RELOC-NEXT:         Kind:            DATA
 ; RELOC-NEXT:         Name:            colliding_global3
 ; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
 ; RELOC-NEXT:         Segment:         2
 ; RELOC-NEXT:         Offset:          4
 ; RELOC-NEXT:         Size:            4
-; RELOC-NEXT:       - Index:           21
-; RELOC-NEXT:         Kind:            FUNCTION
-; RELOC-NEXT:         Name:            get_func1B
-; RELOC-NEXT:         Flags:           [  ]
-; RELOC-NEXT:         Function:        15
-; RELOC-NEXT:       - Index:           22
-; RELOC-NEXT:         Kind:            FUNCTION
-; RELOC-NEXT:         Name:            get_func2B
-; RELOC-NEXT:         Flags:           [  ]
-; RELOC-NEXT:         Function:        16
-; RELOC-NEXT:       - Index:           23
-; RELOC-NEXT:         Kind:            FUNCTION
-; RELOC-NEXT:         Name:            get_func3B
-; RELOC-NEXT:         Flags:           [  ]
-; RELOC-NEXT:         Function:        17
 ; RELOC-NEXT:     SegmentInfo:
 ; RELOC-NEXT:       - Index:           0
 ; RELOC-NEXT:         Name:            .bss.colliding_global1
-; RELOC-NEXT:         Alignment:       4
+; RELOC-NEXT:         Alignment:       2
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:       - Index:           1
 ; RELOC-NEXT:         Name:            .bss.colliding_global2
-; RELOC-NEXT:         Alignment:       4
+; RELOC-NEXT:         Alignment:       2
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:       - Index:           2
 ; RELOC-NEXT:         Name:            .bss.colliding_global3
-; RELOC-NEXT:         Alignment:       4
+; RELOC-NEXT:         Alignment:       2
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:   - Type:            CUSTOM
 ; RELOC-NEXT:     Name:            name
diff --git a/test/wasm/lto/opt-level.ll b/test/wasm/lto/opt-level.ll
index b7e6a4c..f6156e7 100644
--- a/test/wasm/lto/opt-level.ll
+++ b/test/wasm/lto/opt-level.ll
@@ -7,11 +7,11 @@
 ; RUN: obj2yaml %t2a | FileCheck --check-prefix=CHECK-O2 %s
 
 ; Reject invalid optimization levels.
-; RUN: not ld.lld -o %t3 -e main --lto-O6 %t.o 2>&1 | \
+; RUN: not wasm-ld -o %t3 -e main --lto-O6 %t.o 2>&1 | \
 ; RUN:   FileCheck --check-prefix=INVALID %s
 ; INVALID: invalid optimization level for LTO: 6
 
-; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --lto-O-1 %t.o 2>&1 | \
+; RUN: not wasm-ld -o %t3 -m elf_x86_64 -e main --lto-O-1 %t.o 2>&1 | \
 ; RUN:   FileCheck --check-prefix=INVALIDNEGATIVE %s
 ; INVALIDNEGATIVE: invalid optimization level for LTO: 4294967295
 
diff --git a/test/wasm/lto/relocatable-undefined.ll b/test/wasm/lto/relocatable-undefined.ll
new file mode 100644
index 0000000..b9780ee
--- /dev/null
+++ b/test/wasm/lto/relocatable-undefined.ll
@@ -0,0 +1,36 @@
+; RUN: llvm-as %s -o %t.o
+; RUN: wasm-ld -r -o %t.wasm %t.o
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+@missing_data = external global i32
+declare i32 @missing_func() local_unnamed_addr
+
+define i32 @foo() {
+entry:
+  %0 = call i32 @missing_func()
+  %1 = load i32, i32* @missing_data, align 4
+  ret i32 %1
+}
+
+
+; CHECK:        - Type:            CUSTOM
+; CHECK-NEXT:     Name:            linking
+; CHECK-NEXT:     Version:         2
+; CHECK-NEXT:     SymbolTable:     
+; CHECK-NEXT:       - Index:           0
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            missing_func
+; CHECK-NEXT:         Flags:           [ UNDEFINED ]
+; CHECK-NEXT:         Function:        0
+; CHECK-NEXT:       - Index:           1
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            foo
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        1
+; CHECK-NEXT:       - Index:           2
+; CHECK-NEXT:         Kind:            DATA
+; CHECK-NEXT:         Name:            missing_data
+; CHECK-NEXT:         Flags:           [ UNDEFINED ]
diff --git a/test/wasm/lto/weak-undefined.ll b/test/wasm/lto/weak-undefined.ll
new file mode 100644
index 0000000..5eb405a
--- /dev/null
+++ b/test/wasm/lto/weak-undefined.ll
@@ -0,0 +1,20 @@
+; RUN: llvm-as %s -o %t.o
+; RUN: wasm-ld %t.o -o %t.wasm
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+; Test that undefined weak external functions are handled in the LTO case
+; We had a bug where stub function generation was failing because functions
+; that are in bitcode (pre-LTO) don't have signatures assigned.
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+declare extern_weak i32 @foo()
+
+define void @_start() #0 {
+entry:
+    %call2 = call i32 @foo()
+    ret void
+}
+
+; CHECK: Name:            'undefined:foo'
diff --git a/test/wasm/lto/weak.ll b/test/wasm/lto/weak.ll
index 03a017c..61705d0 100644
--- a/test/wasm/lto/weak.ll
+++ b/test/wasm/lto/weak.ll
@@ -12,5 +12,8 @@
 ; CHECK:        Symbol {
 ; CHECK-NEXT:     Name: f
 ; CHECK-NEXT:     Type: FUNCTION (0x0)
-; CHECK-NEXT:     Flags: 0x1
+; CHECK-NEXT:     Flags [ (0x1)
+; CHECK-NEXT:       BINDING_WEAK (0x1)
+; CHECK-NEXT:     ]
+; CHECK-NEXT:     ElementIndex: 0x0
 ; CHECK-NEXT:   }
diff --git a/test/wasm/many-functions.ll b/test/wasm/many-functions.ll
index 02ad9aa..2e1bbaf 100644
--- a/test/wasm/many-functions.ll
+++ b/test/wasm/many-functions.ll
@@ -18,394 +18,394 @@
 
 ; CHECK:        - Type:            CODE
 ; CHECK-NEXT:     Relocations:
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000008
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000014
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000020
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000002C
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000038
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000044
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000050
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000005C
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000068
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000074
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000080
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000008C
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000098
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000000A4
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000000B0
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000000BC
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000000C8
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000000D4
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000000E0
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000000EC
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000000F8
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000104
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000110
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000011C
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000128
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000134
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000140
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000014C
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000158
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000164
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000170
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000017C
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000188
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000194
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000001A0
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000001AC
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000001B8
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000001C4
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000001D0
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000001DC
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000001E8
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000001F4
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000200
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000020C
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000218
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000224
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000230
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000023C
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000248
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000254
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000260
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000026C
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000278
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000284
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000290
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000029C
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000002A8
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000002B4
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000002C0
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000002CC
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000002D8
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000002E4
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000002F0
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000002FC
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000308
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000314
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000320
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000032C
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000338
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000344
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000350
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000035C
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000368
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000374
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000380
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000038C
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000398
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000003A4
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000003B0
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000003BC
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000003C8
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000003D4
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000003E0
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000003EC
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000003F8
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000404
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000410
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000041C
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000428
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000434
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000440
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000044C
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000458
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000464
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000470
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000047C
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000488
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000494
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000004A0
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000004AC
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000004B8
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000004C4
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000004D0
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000004DC
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000004E8
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000004F4
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000500
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000050C
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000518
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000524
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000530
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000053C
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000548
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000554
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000560
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000056C
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000578
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000584
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000590
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000059C
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000005A8
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000005B4
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000005C0
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000005CC
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000005D8
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000005E4
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000005F0
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           129
 ; CHECK-NEXT:         Offset:          0x000005FC
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
 ; CHECK-NEXT:         Index:           129
 ; CHECK-NEXT:         Offset:          0x00000608
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_FUNCTION_INDEX_LEB
+; CHECK-NEXT:       - Type:            R_WASM_FUNCTION_INDEX_LEB
 ; CHECK-NEXT:         Index:           131
 ; CHECK-NEXT:         Offset:          0x00000611
 ; CHECK-NEXT:     Functions:
@@ -815,7 +815,7 @@
 ; CHECK-NEXT:         Content:         '01000000'
 ; CHECK-NEXT:   - Type:            CUSTOM
 ; CHECK-NEXT:     Name:            linking
-; CHECK-NEXT:     Version:         1
+; CHECK-NEXT:     Version:         2
 ; CHECK-NEXT:     SymbolTable:
 ; CHECK-NEXT:       - Index:           0
 ; CHECK-NEXT:         Kind:            FUNCTION
@@ -1482,9 +1482,9 @@
 ; CHECK-NEXT:     SegmentInfo:
 ; CHECK-NEXT:       - Index:           0
 ; CHECK-NEXT:         Name:            .data.g0
-; CHECK-NEXT:         Alignment:       4
+; CHECK-NEXT:         Alignment:       2
 ; CHECK-NEXT:         Flags:           [ ]
 ; CHECK-NEXT:       - Index:           1
 ; CHECK-NEXT:         Name:            .data.foo
-; CHECK-NEXT:         Alignment:       4
+; CHECK-NEXT:         Alignment:       2
 ; CHECK-NEXT:         Flags:           [ ]
diff --git a/test/wasm/reloc-addend.ll b/test/wasm/reloc-addend.ll
index f678a3d..fc00b8e 100644
--- a/test/wasm/reloc-addend.ll
+++ b/test/wasm/reloc-addend.ll
@@ -13,7 +13,7 @@
 
 ; CHECK:        - Type:            DATA
 ; CHECK-NEXT:     Relocations:     
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_I32
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_I32
 ; CHECK-NEXT:         Index:           0
 ; CHECK-NEXT:         Offset:          0x0000013D
 ; CHECK-NEXT:         Addend:          64
diff --git a/test/wasm/relocatable.ll b/test/wasm/relocatable.ll
index 4e8a887..ab2d37b 100644
--- a/test/wasm/relocatable.ll
+++ b/test/wasm/relocatable.ll
@@ -63,7 +63,7 @@
 ; CHECK-NEXT:     FunctionTypes:   [ 2, 1, 1 ]
 ; CHECK-NEXT:   - Type:            TABLE
 ; CHECK-NEXT:     Tables:
-; CHECK-NEXT:       - ElemType:        ANYFUNC
+; CHECK-NEXT:       - ElemType:        FUNCREF
 ; CHECK-NEXT:         Limits:
 ; CHECK-NEXT:           Flags:           [ HAS_MAX ]
 ; CHECK-NEXT:           Initial:         0x00000004
@@ -79,19 +79,19 @@
 ; CHECK-NEXT:         Functions:       [ 4, 1, 2 ]
 ; CHECK-NEXT:   - Type:            CODE
 ; CHECK-NEXT:     Relocations:
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_SLEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_SLEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000004
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_FUNCTION_INDEX_LEB
+; CHECK-NEXT:       - Type:            R_WASM_FUNCTION_INDEX_LEB
 ; CHECK-NEXT:         Index:           2
 ; CHECK-NEXT:         Offset:          0x0000000A
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_FUNCTION_INDEX_LEB
+; CHECK-NEXT:       - Type:            R_WASM_FUNCTION_INDEX_LEB
 ; CHECK-NEXT:         Index:           4
 ; CHECK-NEXT:         Offset:          0x00000013
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_FUNCTION_INDEX_LEB
+; CHECK-NEXT:       - Type:            R_WASM_FUNCTION_INDEX_LEB
 ; CHECK-NEXT:         Index:           5
 ; CHECK-NEXT:         Offset:          0x0000001A
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_SLEB
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_SLEB
 ; CHECK-NEXT:         Index:           7
 ; CHECK-NEXT:         Offset:          0x00000026
 ; CHECK-NEXT:     Functions:
@@ -106,16 +106,16 @@
 ; CHECK-NEXT:         Body:          419C808080000B
 ; CHECK-NEXT:   - Type:            DATA
 ; CHECK-NEXT:     Relocations:
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_TABLE_INDEX_I32
+; CHECK-NEXT:       - Type:            R_WASM_TABLE_INDEX_I32
 ; CHECK-NEXT:         Index:           3
 ; CHECK-NEXT:         Offset:          0x00000012
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_TABLE_INDEX_I32
+; CHECK-NEXT:       - Type:            R_WASM_TABLE_INDEX_I32
 ; CHECK-NEXT:         Index:           4
 ; CHECK-NEXT:         Offset:          0x0000001B
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_TABLE_INDEX_I32
+; CHECK-NEXT:       - Type:            R_WASM_TABLE_INDEX_I32
 ; CHECK-NEXT:         Index:           5
 ; CHECK-NEXT:         Offset:          0x00000024
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_I32
+; CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_I32
 ; CHECK-NEXT:         Index:           12
 ; CHECK-NEXT:         Offset:          0x0000002D
 ; CHECK-NEXT:     Segments:
@@ -157,7 +157,7 @@
 ; CHECK-NEXT:         Content:         '616263'
 ; CHECK-NEXT:   - Type:            CUSTOM
 ; CHECK-NEXT:     Name:            linking
-; CHECK-NEXT:     Version:         1
+; CHECK-NEXT:     Version:         2
 ; CHECK-NEXT:     SymbolTable:
 ; CHECK-NEXT:       - Index:           0
 ; CHECK-NEXT:         Kind:            FUNCTION
@@ -232,27 +232,27 @@
 ; CHECK-NEXT:     SegmentInfo:
 ; CHECK-NEXT:       - Index:           0
 ; CHECK-NEXT:         Name:            .rodata.hello_str
-; CHECK-NEXT:         Alignment:       1
+; CHECK-NEXT:         Alignment:       0
 ; CHECK-NEXT:         Flags:           [  ]
 ; CHECK-NEXT:       - Index:           1
 ; CHECK-NEXT:         Name:            .data.func_addr1
-; CHECK-NEXT:         Alignment:       4
+; CHECK-NEXT:         Alignment:       2
 ; CHECK-NEXT:         Flags:           [  ]
 ; CHECK-NEXT:       - Index:           2
 ; CHECK-NEXT:         Name:            .data.func_addr2
-; CHECK-NEXT:         Alignment:       4
+; CHECK-NEXT:         Alignment:       2
 ; CHECK-NEXT:         Flags:           [  ]
 ; CHECK-NEXT:       - Index:           3
 ; CHECK-NEXT:         Name:            .data.func_addr3
-; CHECK-NEXT:         Alignment:       4
+; CHECK-NEXT:         Alignment:       2
 ; CHECK-NEXT:         Flags:           [  ]
 ; CHECK-NEXT:       - Index:           4
 ; CHECK-NEXT:         Name:            .data.data_addr1
-; CHECK-NEXT:         Alignment:       8
+; CHECK-NEXT:         Alignment:       3
 ; CHECK-NEXT:         Flags:           [  ]
 ; CHECK-NEXT:       - Index:           5
 ; CHECK-NEXT:         Name:            .rodata.data_comdat
-; CHECK-NEXT:         Alignment:       1
+; CHECK-NEXT:         Alignment:       0
 ; CHECK-NEXT:         Flags:           [  ]
 ; CHECK-NEXT:     Comdats:
 ; CHECK-NEXT:       - Name:            func_comdat
diff --git a/test/wasm/shared.ll b/test/wasm/shared.ll
index 088c650..f3abd11 100644
--- a/test/wasm/shared.ll
+++ b/test/wasm/shared.ll
@@ -42,7 +42,7 @@
 ; CHECK-NEXT:         Field:           __indirect_function_table
 ; CHECK-NEXT:         Kind:            TABLE
 ; CHECK-NEXT:         Table:
-; CHECK-NEXT:           ElemType:        ANYFUNC
+; CHECK-NEXT:           ElemType:        FUNCREF
 ; CHECK-NEXT:           Limits:
 ; CHECK-NEXT:             Initial:         0x00000002
 ; CHECK-NEXT:       - Module:          env
@@ -66,7 +66,7 @@
 ; CHECK:        - Type:            ELEM
 ; CHECK-NEXT:     Segments:
 ; CHECK-NEXT:       - Offset:
-; CHECK-NEXT:           Opcode:          GET_GLOBAL
+; CHECK-NEXT:           Opcode:          GLOBAL_GET
 ; CHECK-NEXT:           Index:           2
 ; CHECK-NEXT:         Functions:       [ 2, 0 ]
 
@@ -77,6 +77,6 @@
 ; CHECK-NEXT:       - SectionOffset:   6
 ; CHECK-NEXT:         MemoryIndex:     0
 ; CHECK-NEXT:         Offset:
-; CHECK-NEXT:           Opcode:          GET_GLOBAL
+; CHECK-NEXT:           Opcode:          GLOBAL_GET
 ; CHECK-NEXT:           Index:           1
 ; CHECK-NEXT:         Content:         '0000000001000000'
diff --git a/test/wasm/stack-pointer.ll b/test/wasm/stack-pointer.ll
index 888c938..30501ba 100644
--- a/test/wasm/stack-pointer.ll
+++ b/test/wasm/stack-pointer.ll
@@ -31,7 +31,7 @@
 ; CHECK-NEXT:     FunctionTypes:   [ 0 ]
 ; CHECK-NEXT:   - Type:            TABLE
 ; CHECK-NEXT:     Tables:
-; CHECK-NEXT:       - ElemType:        ANYFUNC
+; CHECK-NEXT:       - ElemType:        FUNCREF
 ; CHECK-NEXT:         Limits:
 ; CHECK-NEXT:           Flags:           [ HAS_MAX ]
 ; CHECK-NEXT:           Initial:         0x00000001
@@ -41,7 +41,7 @@
 ; CHECK-NEXT:       - Initial:         0x00000000
 ; CHECK-NEXT:   - Type:            CODE
 ; CHECK-NEXT:     Relocations:
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_GLOBAL_INDEX_LEB
+; CHECK-NEXT:       - Type:            R_WASM_GLOBAL_INDEX_LEB
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000004
 ; CHECK-NEXT:     Functions:
@@ -50,7 +50,7 @@
 ; CHECK-NEXT:         Body:            23808080800041106B1A41000B
 ; CHECK-NEXT:   - Type:            CUSTOM
 ; CHECK-NEXT:     Name:            linking
-; CHECK-NEXT:     Version:         1
+; CHECK-NEXT:     Version:         2
 ; CHECK-NEXT:     SymbolTable:
 ; CHECK-NEXT:       - Index:           0
 ; CHECK-NEXT:         Kind:            FUNCTION
diff --git a/test/wasm/trace-symbol.ll b/test/wasm/trace-symbol.ll
new file mode 100644
index 0000000..649b425
--- /dev/null
+++ b/test/wasm/trace-symbol.ll
@@ -0,0 +1,23 @@
+; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
+; RUN: llc -filetype=obj -o %t.o %s
+; RUN: wasm-ld -o %t.wasm %t.o %t.ret32.o -y ret32 -y _start 2>&1 | FileCheck %s -check-prefix=BOTH
+
+; check alias
+; RUN: wasm-ld -o %t.wasm %t.o %t.ret32.o -trace-symbol=_start 2>&1 | FileCheck %s -check-prefixes=JUST-START
+
+target triple = "wasm32-unknown-unknown"
+
+declare i32 @ret32(float %arg)
+
+define void @_start() {
+entry:
+  %call1 = call i32 @ret32(float 0.0)
+  ret void
+}
+
+; BOTH: .o: definition of _start
+; BOTH: .o: reference to ret32
+; BOTH: .ret32.o: definition of ret32
+
+; JUST-START: .o: definition of _start
+; JUST-START-NOT: ret32
diff --git a/test/wasm/trace.test b/test/wasm/trace.test
new file mode 100644
index 0000000..023a2cc
--- /dev/null
+++ b/test/wasm/trace.test
@@ -0,0 +1,8 @@
+RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.foo.o
+
+# Check -t
+RUN: wasm-ld %t.foo.o -o %t.t.out.wasm -t 2>&1 | FileCheck %s
+CHECK: {{.*}}.foo.o
+
+# Check --trace alias
+RUN: wasm-ld %t.foo.o -o %t.trace.out.wasm --trace 2>&1 | FileCheck %s
diff --git a/test/wasm/undefined-weak-call.ll b/test/wasm/undefined-weak-call.ll
index 920379e..9f1c39b 100644
--- a/test/wasm/undefined-weak-call.ll
+++ b/test/wasm/undefined-weak-call.ll
@@ -45,7 +45,7 @@
 ; CHECK-NEXT:     FunctionTypes:   [ 0, 0, 0, 1, 2 ]
 ; CHECK-NEXT:   - Type:            TABLE
 ; CHECK-NEXT:     Tables:
-; CHECK-NEXT:       - ElemType:        ANYFUNC
+; CHECK-NEXT:       - ElemType:        FUNCREF
 ; CHECK-NEXT:         Limits:
 ; CHECK-NEXT:           Flags:           [ HAS_MAX ]
 ; CHECK-NEXT:           Initial:         0x00000001
@@ -110,11 +110,11 @@
 ; CHECK-NEXT:       - Index:           0
 ; CHECK-NEXT:         Name:            __wasm_call_ctors
 ; CHECK-NEXT:       - Index:           1
-; CHECK-NEXT:         Name:            undefined function weakFunc1
+; CHECK-NEXT:         Name:            'undefined:weakFunc1'
 ; CHECK-NEXT:       - Index:           2
-; CHECK-NEXT:         Name:            undefined function weakFunc2
+; CHECK-NEXT:         Name:            'undefined:weakFunc2'
 ; CHECK-NEXT:       - Index:           3
-; CHECK-NEXT:         Name:            undefined function weakFunc3
+; CHECK-NEXT:         Name:            'undefined:weakFunc3'
 ; CHECK-NEXT:       - Index:           4
 ; CHECK-NEXT:         Name:            callWeakFuncs
 ; CHECK-NEXT: ...
diff --git a/test/wasm/weak-alias-overide.ll b/test/wasm/weak-alias-overide.ll
index 496900b..7fefad0 100644
--- a/test/wasm/weak-alias-overide.ll
+++ b/test/wasm/weak-alias-overide.ll
@@ -35,7 +35,7 @@
 ; CHECK-NEXT:     FunctionTypes:   [ 0, 1, 0, 1, 1, 1, 1, 1 ]
 ; CHECK-NEXT:   - Type:            TABLE
 ; CHECK-NEXT:     Tables:
-; CHECK-NEXT:       - ElemType:        ANYFUNC
+; CHECK-NEXT:       - ElemType:        FUNCREF
 ; CHECK-NEXT:         Limits:
 ; CHECK-NEXT:           Flags:           [ HAS_MAX ]
 ; CHECK-NEXT:           Initial:         0x00000003
diff --git a/test/wasm/weak-alias.ll b/test/wasm/weak-alias.ll
index 49f2885..45d5294 100644
--- a/test/wasm/weak-alias.ll
+++ b/test/wasm/weak-alias.ll
@@ -32,7 +32,7 @@
 ; CHECK-NEXT:     FunctionTypes:   [ 0, 0, 1, 1, 1, 1, 1 ]
 ; CHECK-NEXT:   - Type:            TABLE
 ; CHECK-NEXT:     Tables:
-; CHECK-NEXT:       - ElemType:        ANYFUNC
+; CHECK-NEXT:       - ElemType:        FUNCREF
 ; CHECK-NEXT:         Limits:
 ; CHECK-NEXT:           Flags:           [ HAS_MAX ]
 ; CHECK-NEXT:           Initial:         0x00000002
@@ -170,7 +170,7 @@
 ; RELOC-NEXT:     FunctionTypes:   [ 0, 1, 1, 1, 1, 1 ]
 ; RELOC-NEXT:   - Type:            TABLE
 ; RELOC-NEXT:     Tables:
-; RELOC-NEXT:       - ElemType:        ANYFUNC
+; RELOC-NEXT:       - ElemType:        FUNCREF
 ; RELOC-NEXT:         Limits:
 ; RELOC-NEXT:           Flags:           [ HAS_MAX ]
 ; RELOC-NEXT:           Initial:         0x00000002
@@ -186,43 +186,43 @@
 ; RELOC-NEXT:         Functions:       [ 1 ]
 ; RELOC-NEXT:   - Type:            CODE
 ; RELOC-NEXT:     Relocations:
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_FUNCTION_INDEX_LEB
-; RELOC-NEXT:         Index:           4
-; RELOC-NEXT:         Offset:          0x00000004
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_FUNCTION_INDEX_LEB
+; RELOC-NEXT:       - Type:            R_WASM_FUNCTION_INDEX_LEB
 ; RELOC-NEXT:         Index:           1
+; RELOC-NEXT:         Offset:          0x00000004
+; RELOC-NEXT:       - Type:            R_WASM_FUNCTION_INDEX_LEB
+; RELOC-NEXT:         Index:           2
 ; RELOC-NEXT:         Offset:          0x00000013
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_FUNCTION_INDEX_LEB
-; RELOC-NEXT:         Index:           4
+; RELOC-NEXT:       - Type:            R_WASM_FUNCTION_INDEX_LEB
+; RELOC-NEXT:         Index:           1
 ; RELOC-NEXT:         Offset:          0x0000001C
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_GLOBAL_INDEX_LEB
+; RELOC-NEXT:       - Type:            R_WASM_GLOBAL_INDEX_LEB
 ; RELOC-NEXT:         Index:           6
 ; RELOC-NEXT:         Offset:          0x00000027
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_GLOBAL_INDEX_LEB
+; RELOC-NEXT:       - Type:            R_WASM_GLOBAL_INDEX_LEB
 ; RELOC-NEXT:         Index:           6
 ; RELOC-NEXT:         Offset:          0x00000032
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT:         Index:           4
+; RELOC-NEXT:       - Type:            R_WASM_TABLE_INDEX_SLEB
+; RELOC-NEXT:         Index:           1
 ; RELOC-NEXT:         Offset:          0x0000003A
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_FUNCTION_INDEX_LEB
-; RELOC-NEXT:         Index:           4
+; RELOC-NEXT:       - Type:            R_WASM_FUNCTION_INDEX_LEB
+; RELOC-NEXT:         Index:           1
 ; RELOC-NEXT:         Offset:          0x00000043
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_GLOBAL_INDEX_LEB
+; RELOC-NEXT:       - Type:            R_WASM_GLOBAL_INDEX_LEB
 ; RELOC-NEXT:         Index:           6
 ; RELOC-NEXT:         Offset:          0x00000050
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_GLOBAL_INDEX_LEB
+; RELOC-NEXT:       - Type:            R_WASM_GLOBAL_INDEX_LEB
 ; RELOC-NEXT:         Index:           6
 ; RELOC-NEXT:         Offset:          0x0000005D
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_GLOBAL_INDEX_LEB
+; RELOC-NEXT:       - Type:            R_WASM_GLOBAL_INDEX_LEB
 ; RELOC-NEXT:         Index:           6
 ; RELOC-NEXT:         Offset:          0x00000068
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT:         Index:           1
+; RELOC-NEXT:       - Type:            R_WASM_TABLE_INDEX_SLEB
+; RELOC-NEXT:         Index:           2
 ; RELOC-NEXT:         Offset:          0x00000070
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_FUNCTION_INDEX_LEB
-; RELOC-NEXT:         Index:           1
+; RELOC-NEXT:       - Type:            R_WASM_FUNCTION_INDEX_LEB
+; RELOC-NEXT:         Index:           2
 ; RELOC-NEXT:         Offset:          0x00000079
-; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_GLOBAL_INDEX_LEB
+; RELOC-NEXT:       - Type:            R_WASM_GLOBAL_INDEX_LEB
 ; RELOC-NEXT:         Index:           6
 ; RELOC-NEXT:         Offset:          0x00000086
 ; RELOC-NEXT:     Functions:
@@ -250,7 +250,7 @@
 ; RELOC-NEXT:         Body:            23808080800041106B220024808080800020004181808080003602081081808080002101200041106A24808080800020010B
 ; RELOC-NEXT:   - Type:            CUSTOM
 ; RELOC-NEXT:     Name:            linking
-; RELOC-NEXT:     Version:         1
+; RELOC-NEXT:     Version:         2
 ; RELOC-NEXT:     SymbolTable:
 ; RELOC-NEXT:       - Index:           0
 ; RELOC-NEXT:         Kind:            FUNCTION
@@ -259,24 +259,24 @@
 ; RELOC-NEXT:         Function:        0
 ; RELOC-NEXT:       - Index:           1
 ; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            alias_fn
+; RELOC-NEXT:         Flags:           [ BINDING_WEAK ]
+; RELOC-NEXT:         Function:        1
+; RELOC-NEXT:       - Index:           2
+; RELOC-NEXT:         Kind:            FUNCTION
 ; RELOC-NEXT:         Name:            direct_fn
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:         Function:        1
-; RELOC-NEXT:       - Index:           2
+; RELOC-NEXT:       - Index:           3
 ; RELOC-NEXT:         Kind:            FUNCTION
 ; RELOC-NEXT:         Name:            call_direct
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:         Function:        2
-; RELOC-NEXT:       - Index:           3
+; RELOC-NEXT:       - Index:           4
 ; RELOC-NEXT:         Kind:            FUNCTION
 ; RELOC-NEXT:         Name:            call_alias
 ; RELOC-NEXT:         Flags:           [  ]
 ; RELOC-NEXT:         Function:        3
-; RELOC-NEXT:       - Index:           4
-; RELOC-NEXT:         Kind:            FUNCTION
-; RELOC-NEXT:         Name:            alias_fn
-; RELOC-NEXT:         Flags:           [ BINDING_WEAK ]
-; RELOC-NEXT:         Function:        1
 ; RELOC-NEXT:       - Index:           5
 ; RELOC-NEXT:         Kind:            FUNCTION
 ; RELOC-NEXT:         Name:            call_alias_ptr
diff --git a/test/wasm/weak-symbols.ll b/test/wasm/weak-symbols.ll
index 7af4323..41ade7c 100644
--- a/test/wasm/weak-symbols.ll
+++ b/test/wasm/weak-symbols.ll
@@ -32,7 +32,7 @@
 ; CHECK-NEXT:     FunctionTypes:   [ 0, 0, 1, 1, 1 ]
 ; CHECK-NEXT:   - Type:            TABLE
 ; CHECK-NEXT:     Tables:
-; CHECK-NEXT:       - ElemType:        ANYFUNC
+; CHECK-NEXT:       - ElemType:        FUNCREF
 ; CHECK-NEXT:         Limits:
 ; CHECK-NEXT:           Flags:           [ HAS_MAX ]
 ; CHECK-NEXT:           Initial:         0x00000002
diff --git a/test/wasm/weak-undefined.ll b/test/wasm/weak-undefined.ll
index 2f2451a..41e992e 100644
--- a/test/wasm/weak-undefined.ll
+++ b/test/wasm/weak-undefined.ll
@@ -43,7 +43,7 @@
 ; CHECK-NEXT:     FunctionTypes:   [ 0, 1, 1, 0 ]
 ; CHECK-NEXT:   - Type:            TABLE
 ; CHECK-NEXT:     Tables:
-; CHECK-NEXT:       - ElemType:        ANYFUNC
+; CHECK-NEXT:       - ElemType:        FUNCREF
 ; CHECK-NEXT:         Limits:
 ; CHECK-NEXT:           Flags:           [ HAS_MAX ]
 ; CHECK-NEXT:           Initial:         0x00000001
diff --git a/tools/lld/lld.cpp b/tools/lld/lld.cpp
index c749d45..c6be7f8 100644
--- a/tools/lld/lld.cpp
+++ b/tools/lld/lld.cpp
@@ -1,9 +1,8 @@
 //===- tools/lld/lld.cpp - Linker Driver Dispatcher -----------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/unittests/DriverTests/DarwinLdDriverTest.cpp b/unittests/DriverTests/DarwinLdDriverTest.cpp
index e2e634a..8066670 100644
--- a/unittests/DriverTests/DarwinLdDriverTest.cpp
+++ b/unittests/DriverTests/DarwinLdDriverTest.cpp
@@ -1,9 +1,8 @@
 //===- lld/unittest/DarwinLdDriverTest.cpp --------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/unittests/MachOTests/MachONormalizedFileBinaryReaderTests.cpp b/unittests/MachOTests/MachONormalizedFileBinaryReaderTests.cpp
index 336bbdb..aad5f8a 100644
--- a/unittests/MachOTests/MachONormalizedFileBinaryReaderTests.cpp
+++ b/unittests/MachOTests/MachONormalizedFileBinaryReaderTests.cpp
@@ -1,9 +1,8 @@
 //===- lld/unittest/MachOTests/MachONormalizedFileBinaryReaderTests.cpp ---===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/MachOTests/MachONormalizedFileBinaryWriterTests.cpp b/unittests/MachOTests/MachONormalizedFileBinaryWriterTests.cpp
index 210fecb..d0cdd50 100644
--- a/unittests/MachOTests/MachONormalizedFileBinaryWriterTests.cpp
+++ b/unittests/MachOTests/MachONormalizedFileBinaryWriterTests.cpp
@@ -1,9 +1,8 @@
 //===- lld/unittest/MachOTests/MachONormalizedFileBinaryWriterTests.cpp ---===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp b/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp
index a0176bb..cf9a845 100644
--- a/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp
+++ b/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp
@@ -1,9 +1,8 @@
 //===- lld/unittest/MachOTests/MachONormalizedFileToAtomsTests.cpp --------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/MachOTests/MachONormalizedFileYAMLTests.cpp b/unittests/MachOTests/MachONormalizedFileYAMLTests.cpp
index 6bbde72..6ceb197 100644
--- a/unittests/MachOTests/MachONormalizedFileYAMLTests.cpp
+++ b/unittests/MachOTests/MachONormalizedFileYAMLTests.cpp
@@ -1,9 +1,8 @@
 //===- lld/unittest/MachOTests/MachONormalizedFileYAMLTests.cpp -----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/utils/benchmark.py b/utils/benchmark.py
index f1deb06..8ca6cca 100755
--- a/utils/benchmark.py
+++ b/utils/benchmark.py
@@ -1,9 +1,8 @@
 #!/usr/bin/env python
 #
-#                     The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 #
 # ==------------------------------------------------------------------------==#
 
diff --git a/wasm/Config.h b/wasm/Config.h
index 0857a64..c5f22eb 100644
--- a/wasm/Config.h
+++ b/wasm/Config.h
@@ -1,9 +1,8 @@
 //===- Config.h -------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -39,6 +38,7 @@
   bool StripAll;
   bool StripDebug;
   bool StackFirst;
+  bool Trace;
   uint32_t GlobalBase;
   uint32_t InitialMemory;
   uint32_t MaxMemory;
diff --git a/wasm/Driver.cpp b/wasm/Driver.cpp
index fab4c0c..40e88f2 100644
--- a/wasm/Driver.cpp
+++ b/wasm/Driver.cpp
@@ -1,9 +1,8 @@
 //===- Driver.cpp ---------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -287,44 +286,6 @@
   return Arg->getValue();
 }
 
-static const uint8_t UnreachableFn[] = {
-    0x03 /* ULEB length */, 0x00 /* ULEB num locals */,
-    0x00 /* opcode unreachable */, 0x0b /* opcode end */
-};
-
-// For weak undefined functions, there may be "call" instructions that reference
-// the symbol. In this case, we need to synthesise a dummy/stub function that
-// will abort at runtime, so that relocations can still provided an operand to
-// the call instruction that passes Wasm validation.
-static void handleWeakUndefines() {
-  for (Symbol *Sym : Symtab->getSymbols()) {
-    if (!Sym->isUndefined() || !Sym->isWeak())
-      continue;
-    auto *FuncSym = dyn_cast<FunctionSymbol>(Sym);
-    if (!FuncSym)
-      continue;
-
-    // It is possible for undefined functions not to have a signature (eg. if
-    // added via "--undefined"), but weak undefined ones do have a signature.
-    assert(FuncSym->Signature);
-    const WasmSignature &Sig = *FuncSym->Signature;
-
-    // Add a synthetic dummy for weak undefined functions.  These dummies will
-    // be GC'd if not used as the target of any "call" instructions.
-    std::string SymName = toString(*Sym);
-    StringRef DebugName = Saver.save("undefined function " + SymName);
-    auto *Func = make<SyntheticFunction>(Sig, Sym->getName(), DebugName);
-    Func->setBody(UnreachableFn);
-    // Ensure it compares equal to the null pointer, and so that table relocs
-    // don't pull in the stub body (only call-operand relocs should do that).
-    Func->setTableIndex(0);
-    Symtab->SyntheticFunctions.emplace_back(Func);
-    // Hide our dummy to prevent export.
-    uint32_t Flags = WASM_SYMBOL_VISIBILITY_HIDDEN;
-    replaceSymbol<DefinedFunction>(Sym, Sym->getName(), Flags, nullptr, Func);
-  }
-}
-
 // Some Config members do not directly correspond to any particular
 // command line options, but computed based on other Config values.
 // This function initialize such members. See Config.h for the details
@@ -363,6 +324,7 @@
   Config->StripAll = Args.hasArg(OPT_strip_all);
   Config->StripDebug = Args.hasArg(OPT_strip_debug);
   Config->StackFirst = Args.hasArg(OPT_stack_first);
+  Config->Trace = Args.hasArg(OPT_trace);
   Config->ThinLTOCacheDir = Args.getLastArgValue(OPT_thinlto_cache_dir);
   Config->ThinLTOCachePolicy = CHECK(
       parseCachePruningPolicy(Args.getLastArgValue(OPT_thinlto_cache_policy)),
@@ -434,7 +396,9 @@
 static UndefinedGlobal *
 createUndefinedGlobal(StringRef Name, llvm::wasm::WasmGlobalType *Type) {
   auto *Sym =
-      cast<UndefinedGlobal>(Symtab->addUndefinedGlobal(Name, 0, nullptr, Type));
+      cast<UndefinedGlobal>(Symtab->addUndefinedGlobal(Name, Name,
+                                                       DefaultModule, 0,
+                                                       nullptr, Type));
   Config->AllowUndefinedSymbols.insert(Sym->getName());
   Sym->IsUsedInRegularObj = true;
   return Sym;
@@ -548,6 +512,10 @@
     Config->AllowUndefined = true;
   }
 
+  // Handle --trace-symbol.
+  for (auto *Arg : Args.filtered(OPT_trace_symbol))
+    Symtab->trace(Arg->getValue());
+
   if (!Config->Relocatable)
     createSyntheticSymbols();
 
@@ -579,9 +547,6 @@
 
   Symbol *EntrySym = nullptr;
   if (!Config->Relocatable) {
-    // Add synthetic dummies for weak undefined functions.
-    handleWeakUndefines();
-
     if (!Config->Shared && !Config->Entry.empty()) {
       EntrySym = handleUndefined(Config->Entry);
       if (EntrySym && EntrySym->isDefined())
@@ -605,6 +570,11 @@
   if (errorCount())
     return;
 
+  // Add synthetic dummies for weak undefined functions.  Must happen
+  // after LTO otherwise functions may not yet have signatures.
+  if (!Config->Relocatable)
+    Symtab->handleWeakUndefines();
+
   if (EntrySym)
     EntrySym->setHidden(false);
 
diff --git a/wasm/InputChunks.cpp b/wasm/InputChunks.cpp
index 1145c67..238c111 100644
--- a/wasm/InputChunks.cpp
+++ b/wasm/InputChunks.cpp
@@ -1,9 +1,8 @@
 //===- InputChunks.cpp ----------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -23,7 +22,7 @@
 using namespace lld;
 using namespace lld::wasm;
 
-static StringRef ReloctTypeToString(uint8_t RelocType) {
+static StringRef reloctTypeToString(uint8_t RelocType) {
   switch (RelocType) {
 #define WASM_RELOC(NAME, REL)                                                  \
   case REL:                                                                    \
@@ -52,21 +51,21 @@
     uint32_t Offset = Rel.Offset - getInputSectionOffset();
     const uint8_t *Loc = data().data() + Offset;
     switch (Rel.Type) {
-    case R_WEBASSEMBLY_TYPE_INDEX_LEB:
-    case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
-    case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
-    case R_WEBASSEMBLY_EVENT_INDEX_LEB:
-    case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
+    case R_WASM_TYPE_INDEX_LEB:
+    case R_WASM_FUNCTION_INDEX_LEB:
+    case R_WASM_GLOBAL_INDEX_LEB:
+    case R_WASM_EVENT_INDEX_LEB:
+    case R_WASM_MEMORY_ADDR_LEB:
       ExistingValue = decodeULEB128(Loc, &BytesRead);
       break;
-    case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
-    case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
+    case R_WASM_TABLE_INDEX_SLEB:
+    case R_WASM_MEMORY_ADDR_SLEB:
       ExistingValue = static_cast<uint32_t>(decodeSLEB128(Loc, &BytesRead));
       break;
-    case R_WEBASSEMBLY_TABLE_INDEX_I32:
-    case R_WEBASSEMBLY_MEMORY_ADDR_I32:
-    case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
-    case R_WEBASSEMBLY_SECTION_OFFSET_I32:
+    case R_WASM_TABLE_INDEX_I32:
+    case R_WASM_MEMORY_ADDR_I32:
+    case R_WASM_FUNCTION_OFFSET_I32:
+    case R_WASM_SECTION_OFFSET_I32:
       ExistingValue = static_cast<uint32_t>(read32le(Loc));
       break;
     default:
@@ -77,7 +76,7 @@
       warn("expected LEB at relocation site be 5-byte padded");
     uint32_t ExpectedValue = File->calcExpectedValue(Rel);
     if (ExpectedValue != ExistingValue)
-      warn("unexpected existing value for " + ReloctTypeToString(Rel.Type) +
+      warn("unexpected existing value for " + reloctTypeToString(Rel.Type) +
            ": existing=" + Twine(ExistingValue) +
            " expected=" + Twine(ExpectedValue));
   }
@@ -103,27 +102,27 @@
   for (const WasmRelocation &Rel : Relocations) {
     uint8_t *Loc = Buf + Rel.Offset + Off;
     uint32_t Value = File->calcNewValue(Rel);
-    LLVM_DEBUG(dbgs() << "apply reloc: type=" << ReloctTypeToString(Rel.Type)
+    LLVM_DEBUG(dbgs() << "apply reloc: type=" << reloctTypeToString(Rel.Type)
                       << " addend=" << Rel.Addend << " index=" << Rel.Index
                       << " value=" << Value << " offset=" << Rel.Offset
                       << "\n");
 
     switch (Rel.Type) {
-    case R_WEBASSEMBLY_TYPE_INDEX_LEB:
-    case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
-    case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
-    case R_WEBASSEMBLY_EVENT_INDEX_LEB:
-    case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
+    case R_WASM_TYPE_INDEX_LEB:
+    case R_WASM_FUNCTION_INDEX_LEB:
+    case R_WASM_GLOBAL_INDEX_LEB:
+    case R_WASM_EVENT_INDEX_LEB:
+    case R_WASM_MEMORY_ADDR_LEB:
       encodeULEB128(Value, Loc, 5);
       break;
-    case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
-    case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
+    case R_WASM_TABLE_INDEX_SLEB:
+    case R_WASM_MEMORY_ADDR_SLEB:
       encodeSLEB128(static_cast<int32_t>(Value), Loc, 5);
       break;
-    case R_WEBASSEMBLY_TABLE_INDEX_I32:
-    case R_WEBASSEMBLY_MEMORY_ADDR_I32:
-    case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
-    case R_WEBASSEMBLY_SECTION_OFFSET_I32:
+    case R_WASM_TABLE_INDEX_I32:
+    case R_WASM_MEMORY_ADDR_I32:
+    case R_WASM_FUNCTION_OFFSET_I32:
+    case R_WASM_SECTION_OFFSET_I32:
       write32le(Loc, Value);
       break;
     default:
@@ -149,11 +148,11 @@
     writeUleb128(OS, File->calcNewIndex(Rel), "reloc index");
 
     switch (Rel.Type) {
-    case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
-    case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
-    case R_WEBASSEMBLY_MEMORY_ADDR_I32:
-    case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
-    case R_WEBASSEMBLY_SECTION_OFFSET_I32:
+    case R_WASM_MEMORY_ADDR_LEB:
+    case R_WASM_MEMORY_ADDR_SLEB:
+    case R_WASM_MEMORY_ADDR_I32:
+    case R_WASM_FUNCTION_OFFSET_I32:
+    case R_WASM_SECTION_OFFSET_I32:
       writeSleb128(OS, File->calcNewAddend(Rel), "reloc addend");
       break;
     }
@@ -179,14 +178,14 @@
 static unsigned writeCompressedReloc(uint8_t *Buf, const WasmRelocation &Rel,
                                      uint32_t Value) {
   switch (Rel.Type) {
-  case R_WEBASSEMBLY_TYPE_INDEX_LEB:
-  case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
-  case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
-  case R_WEBASSEMBLY_EVENT_INDEX_LEB:
-  case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
+  case R_WASM_TYPE_INDEX_LEB:
+  case R_WASM_FUNCTION_INDEX_LEB:
+  case R_WASM_GLOBAL_INDEX_LEB:
+  case R_WASM_EVENT_INDEX_LEB:
+  case R_WASM_MEMORY_ADDR_LEB:
     return encodeULEB128(Value, Buf);
-  case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
-  case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
+  case R_WASM_TABLE_INDEX_SLEB:
+  case R_WASM_MEMORY_ADDR_SLEB:
     return encodeSLEB128(static_cast<int32_t>(Value), Buf);
   default:
     llvm_unreachable("unexpected relocation type");
@@ -195,13 +194,13 @@
 
 static unsigned getRelocWidthPadded(const WasmRelocation &Rel) {
   switch (Rel.Type) {
-  case R_WEBASSEMBLY_TYPE_INDEX_LEB:
-  case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
-  case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
-  case R_WEBASSEMBLY_EVENT_INDEX_LEB:
-  case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
-  case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
-  case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
+  case R_WASM_TYPE_INDEX_LEB:
+  case R_WASM_FUNCTION_INDEX_LEB:
+  case R_WASM_GLOBAL_INDEX_LEB:
+  case R_WASM_EVENT_INDEX_LEB:
+  case R_WASM_MEMORY_ADDR_LEB:
+  case R_WASM_TABLE_INDEX_SLEB:
+  case R_WASM_MEMORY_ADDR_SLEB:
     return 5;
   default:
     llvm_unreachable("unexpected relocation type");
diff --git a/wasm/InputChunks.h b/wasm/InputChunks.h
index a3bcbb2..20b8f01 100644
--- a/wasm/InputChunks.h
+++ b/wasm/InputChunks.h
@@ -1,9 +1,8 @@
 //===- InputChunks.h --------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/wasm/InputEvent.h b/wasm/InputEvent.h
index d7c1262..52afc93 100644
--- a/wasm/InputEvent.h
+++ b/wasm/InputEvent.h
@@ -1,9 +1,8 @@
 //===- InputEvent.h ---------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/wasm/InputFiles.cpp b/wasm/InputFiles.cpp
index e5da23d..2a5c10e 100644
--- a/wasm/InputFiles.cpp
+++ b/wasm/InputFiles.cpp
@@ -1,9 +1,8 @@
 //===- InputFiles.cpp -----------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -66,7 +65,7 @@
 // relocation and returns relocated index (i.e. translates from the input
 // symbol/type space to the output symbol/type space).
 uint32_t ObjFile::calcNewIndex(const WasmRelocation &Reloc) const {
-  if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB) {
+  if (Reloc.Type == R_WASM_TYPE_INDEX_LEB) {
     assert(TypeIsUsed[Reloc.Index]);
     return TypeMap[Reloc.Index];
   }
@@ -77,12 +76,12 @@
 // relocation and returns updated addend by offset in the output section.
 uint32_t ObjFile::calcNewAddend(const WasmRelocation &Reloc) const {
   switch (Reloc.Type) {
-  case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
-  case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
-  case R_WEBASSEMBLY_MEMORY_ADDR_I32:
-  case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
+  case R_WASM_MEMORY_ADDR_LEB:
+  case R_WASM_MEMORY_ADDR_SLEB:
+  case R_WASM_MEMORY_ADDR_I32:
+  case R_WASM_FUNCTION_OFFSET_I32:
     return Reloc.Addend;
-  case R_WEBASSEMBLY_SECTION_OFFSET_I32:
+  case R_WASM_SECTION_OFFSET_I32:
     return getSectionSymbol(Reloc.Index)->Section->OutputOffset + Reloc.Addend;
   default:
     llvm_unreachable("unexpected relocation type");
@@ -94,14 +93,14 @@
 // location.  It is useful for catching bugs in the compiler and linker.
 uint32_t ObjFile::calcExpectedValue(const WasmRelocation &Reloc) const {
   switch (Reloc.Type) {
-  case R_WEBASSEMBLY_TABLE_INDEX_I32:
-  case R_WEBASSEMBLY_TABLE_INDEX_SLEB: {
+  case R_WASM_TABLE_INDEX_I32:
+  case R_WASM_TABLE_INDEX_SLEB: {
     const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index];
     return TableEntries[Sym.Info.ElementIndex];
   }
-  case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
-  case R_WEBASSEMBLY_MEMORY_ADDR_I32:
-  case R_WEBASSEMBLY_MEMORY_ADDR_LEB: {
+  case R_WASM_MEMORY_ADDR_SLEB:
+  case R_WASM_MEMORY_ADDR_I32:
+  case R_WASM_MEMORY_ADDR_LEB: {
     const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index];
     if (Sym.isUndefined())
       return 0;
@@ -110,19 +109,19 @@
     return Segment.Data.Offset.Value.Int32 + Sym.Info.DataRef.Offset +
            Reloc.Addend;
   }
-  case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
+  case R_WASM_FUNCTION_OFFSET_I32:
     if (auto *Sym = dyn_cast<DefinedFunction>(getFunctionSymbol(Reloc.Index))) {
       return Sym->Function->getFunctionInputOffset() +
              Sym->Function->getFunctionCodeOffset() + Reloc.Addend;
     }
     return 0;
-  case R_WEBASSEMBLY_SECTION_OFFSET_I32:
+  case R_WASM_SECTION_OFFSET_I32:
     return Reloc.Addend;
-  case R_WEBASSEMBLY_TYPE_INDEX_LEB:
+  case R_WASM_TYPE_INDEX_LEB:
     return Reloc.Index;
-  case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
-  case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
-  case R_WEBASSEMBLY_EVENT_INDEX_LEB: {
+  case R_WASM_FUNCTION_INDEX_LEB:
+  case R_WASM_GLOBAL_INDEX_LEB:
+  case R_WASM_EVENT_INDEX_LEB: {
     const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index];
     return Sym.Info.ElementIndex;
   }
@@ -134,32 +133,32 @@
 // Translate from the relocation's index into the final linked output value.
 uint32_t ObjFile::calcNewValue(const WasmRelocation &Reloc) const {
   switch (Reloc.Type) {
-  case R_WEBASSEMBLY_TABLE_INDEX_I32:
-  case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
+  case R_WASM_TABLE_INDEX_I32:
+  case R_WASM_TABLE_INDEX_SLEB:
     return getFunctionSymbol(Reloc.Index)->getTableIndex();
-  case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
-  case R_WEBASSEMBLY_MEMORY_ADDR_I32:
-  case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
+  case R_WASM_MEMORY_ADDR_SLEB:
+  case R_WASM_MEMORY_ADDR_I32:
+  case R_WASM_MEMORY_ADDR_LEB:
     if (auto *Sym = dyn_cast<DefinedData>(getDataSymbol(Reloc.Index)))
       if (Sym->isLive())
         return Sym->getVirtualAddress() + Reloc.Addend;
     return 0;
-  case R_WEBASSEMBLY_TYPE_INDEX_LEB:
+  case R_WASM_TYPE_INDEX_LEB:
     return TypeMap[Reloc.Index];
-  case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
+  case R_WASM_FUNCTION_INDEX_LEB:
     return getFunctionSymbol(Reloc.Index)->getFunctionIndex();
-  case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
+  case R_WASM_GLOBAL_INDEX_LEB:
     return getGlobalSymbol(Reloc.Index)->getGlobalIndex();
-  case R_WEBASSEMBLY_EVENT_INDEX_LEB:
+  case R_WASM_EVENT_INDEX_LEB:
     return getEventSymbol(Reloc.Index)->getEventIndex();
-  case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
+  case R_WASM_FUNCTION_OFFSET_I32:
     if (auto *Sym = dyn_cast<DefinedFunction>(getFunctionSymbol(Reloc.Index))) {
       if (Sym->isLive())
         return Sym->Function->OutputOffset +
                Sym->Function->getFunctionCodeOffset() + Reloc.Addend;
     }
     return 0;
-  case R_WEBASSEMBLY_SECTION_OFFSET_I32:
+  case R_WASM_SECTION_OFFSET_I32:
     return getSectionSymbol(Reloc.Index)->Section->OutputOffset + Reloc.Addend;
   default:
     llvm_unreachable("unknown relocation type");
@@ -240,6 +239,8 @@
       CustomSections.emplace_back(make<InputSection>(Section, this));
       CustomSections.back()->setRelocations(Section.Relocations);
       CustomSectionsByIndex[SectionIndex] = CustomSections.back();
+      if (Section.Name == "producers")
+        ProducersSection = &Section;
     }
     SectionIndex++;
   }
@@ -377,11 +378,15 @@
 
   switch (Sym.Info.Kind) {
   case WASM_SYMBOL_TYPE_FUNCTION:
-    return Symtab->addUndefinedFunction(Name, Flags, this, Sym.Signature);
+    return Symtab->addUndefinedFunction(Name, Sym.Info.ImportName,
+                                        Sym.Info.ImportModule, Flags, this,
+                                        Sym.Signature);
   case WASM_SYMBOL_TYPE_DATA:
     return Symtab->addUndefinedData(Name, Flags, this);
   case WASM_SYMBOL_TYPE_GLOBAL:
-    return Symtab->addUndefinedGlobal(Name, Flags, this, Sym.GlobalType);
+    return Symtab->addUndefinedGlobal(Name, Sym.Info.ImportName,
+                                      Sym.Info.ImportModule, Flags, this,
+                                      Sym.GlobalType);
   case WASM_SYMBOL_TYPE_SECTION:
     llvm_unreachable("section symbols cannot be undefined");
   }
@@ -445,7 +450,8 @@
 
   if (ObjSym.isUndefined()) {
     if (ObjSym.isExecutable())
-      return Symtab->addUndefinedFunction(Name, Flags, &F, nullptr);
+      return Symtab->addUndefinedFunction(Name, Name, DefaultModule, Flags, &F,
+                                          nullptr);
     return Symtab->addUndefinedData(Name, Flags, &F);
   }
 
diff --git a/wasm/InputFiles.h b/wasm/InputFiles.h
index bcda9cc..07d72de 100644
--- a/wasm/InputFiles.h
+++ b/wasm/InputFiles.h
@@ -1,9 +1,8 @@
 //===- InputFiles.h ---------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -99,6 +98,7 @@
 
   const WasmSection *CodeSection = nullptr;
   const WasmSection *DataSection = nullptr;
+  const WasmSection *ProducersSection = nullptr;
 
   // Maps input type indices to output type indices
   std::vector<uint32_t> TypeMap;
@@ -139,7 +139,7 @@
 };
 
 // Will report a fatal() error if the input buffer is not a valid bitcode
-// or was object file.
+// or wasm object file.
 InputFile *createObjectFile(MemoryBufferRef MB);
 
 // Opens a given file.
diff --git a/wasm/InputGlobal.h b/wasm/InputGlobal.h
index 3b20600..e008d2e 100644
--- a/wasm/InputGlobal.h
+++ b/wasm/InputGlobal.h
@@ -1,9 +1,8 @@
 //===- InputGlobal.h --------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/wasm/LTO.cpp b/wasm/LTO.cpp
index 96a947e..19b23d5 100644
--- a/wasm/LTO.cpp
+++ b/wasm/LTO.cpp
@@ -1,9 +1,8 @@
 //===- LTO.cpp ------------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -11,6 +10,7 @@
 #include "Config.h"
 #include "InputFiles.h"
 #include "Symbols.h"
+#include "lld/Common/Args.h"
 #include "lld/Common/ErrorHandler.h"
 #include "lld/Common/Strings.h"
 #include "lld/Common/TargetOptionsCommandFlags.h"
@@ -41,7 +41,7 @@
 
 static std::unique_ptr<lto::LTO> createLTO() {
   lto::Config C;
-  C.Options = InitTargetOptionsFromCodeGenFlags();
+  C.Options = initTargetOptionsFromCodeGenFlags();
 
   // Always emit a section per function/data with LTO.
   C.Options.FunctionSections = true;
@@ -53,7 +53,8 @@
   C.DisableVerify = Config->DisableVerify;
   C.DiagHandler = diagnosticHandler;
   C.OptLevel = Config->LTOO;
-  C.MAttrs = GetMAttrs();
+  C.MAttrs = getMAttrs();
+  C.CGOptLevel = args::getCGOptLevel(Config->LTOO);
 
   if (Config->Relocatable)
     C.RelocModel = None;
@@ -79,8 +80,9 @@
 
 static void undefine(Symbol *S) {
   if (auto F = dyn_cast<DefinedFunction>(S))
-    replaceSymbol<UndefinedFunction>(F, F->getName(), 0, F->getFile(),
-                                     F->Signature);
+    replaceSymbol<UndefinedFunction>(F, F->getName(), F->getName(),
+                                     DefaultModule, 0,
+                                     F->getFile(), F->Signature);
   else if (isa<DefinedData>(S))
     replaceSymbol<UndefinedData>(S, S->getName(), 0, S->getFile());
   else
diff --git a/wasm/LTO.h b/wasm/LTO.h
index cf726de..37fea7a 100644
--- a/wasm/LTO.h
+++ b/wasm/LTO.h
@@ -1,9 +1,8 @@
 //===- LTO.h ----------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -23,6 +22,7 @@
 
 #include "lld/Common/LLVM.h"
 #include "llvm/ADT/SmallString.h"
+#include "Writer.h"
 #include <memory>
 #include <vector>
 
diff --git a/wasm/MarkLive.cpp b/wasm/MarkLive.cpp
index 3bbd114..5d4b379 100644
--- a/wasm/MarkLive.cpp
+++ b/wasm/MarkLive.cpp
@@ -1,9 +1,8 @@
 //===- MarkLive.cpp -------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -72,7 +71,7 @@
     InputChunk *C = Q.pop_back_val();
 
     for (const WasmRelocation Reloc : C->getRelocations()) {
-      if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB)
+      if (Reloc.Type == R_WASM_TYPE_INDEX_LEB)
         continue;
       Symbol *Sym = C->File->getSymbol(Reloc.Index);
 
@@ -83,9 +82,9 @@
       // zero is only reachable via "call", not via "call_indirect".  The stub
       // functions used for weak-undefined symbols have this behaviour (compare
       // equal to null pointer, only reachable via direct call).
-      if (Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_SLEB ||
-          Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_I32) {
-        FunctionSymbol *FuncSym = cast<FunctionSymbol>(Sym);
+      if (Reloc.Type == R_WASM_TABLE_INDEX_SLEB ||
+          Reloc.Type == R_WASM_TABLE_INDEX_I32) {
+        auto *FuncSym = cast<FunctionSymbol>(Sym);
         if (FuncSym->hasTableIndex() && FuncSym->getTableIndex() == 0)
           continue;
       }
diff --git a/wasm/MarkLive.h b/wasm/MarkLive.h
index 0b58f15..7b88cb4 100644
--- a/wasm/MarkLive.h
+++ b/wasm/MarkLive.h
@@ -1,9 +1,8 @@
 //===- MarkLive.h -----------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/wasm/Options.td b/wasm/Options.td
index 3ed55b4..591d624 100644
--- a/wasm/Options.td
+++ b/wasm/Options.td
@@ -93,6 +93,10 @@
 
 def threads: F<"threads">, HelpText<"Run the linker multi-threaded">;
 
+def trace: F<"trace">, HelpText<"Print the names of the input files">;
+
+defm trace_symbol: Eq<"trace-symbol", "Trace references to symbols">;
+
 defm undefined: Eq<"undefined", "Force undefined symbol during linking">;
 
 def v: Flag<["-"], "v">, HelpText<"Display the version number">;
@@ -160,6 +164,8 @@
 def: Flag<["-"], "r">, Alias<relocatable>;
 def: Flag<["-"], "s">, Alias<strip_all>, HelpText<"Alias for --strip-all">;
 def: Flag<["-"], "S">, Alias<strip_debug>, HelpText<"Alias for --strip-debug">;
+def: Flag<["-"], "t">, Alias<trace>, HelpText<"Alias for --trace">;
+def: JoinedOrSeparate<["-"], "y">, Alias<trace_symbol>, HelpText<"Alias for --trace-symbol">;
 def: JoinedOrSeparate<["-"], "u">, Alias<undefined>;
 
 // LTO-related options.
diff --git a/wasm/OutputSections.cpp b/wasm/OutputSections.cpp
index 38d32d2..70ef9f8 100644
--- a/wasm/OutputSections.cpp
+++ b/wasm/OutputSections.cpp
@@ -1,9 +1,8 @@
 //===- OutputSections.cpp -------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -142,7 +141,7 @@
     if (Config->Pic) {
       assert(Segments.size() <= 1 &&
              "Currenly only a single data segment is supported in PIC mode");
-      InitExpr.Opcode = WASM_OPCODE_GET_GLOBAL;
+      InitExpr.Opcode = WASM_OPCODE_GLOBAL_GET;
       InitExpr.Value.Global = WasmSym::MemoryBase->getGlobalIndex();
     } else {
       InitExpr.Opcode = WASM_OPCODE_I32_CONST;
diff --git a/wasm/OutputSections.h b/wasm/OutputSections.h
index 6c5baa3..a1853cb 100644
--- a/wasm/OutputSections.h
+++ b/wasm/OutputSections.h
@@ -1,9 +1,8 @@
 //===- OutputSections.h -----------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/wasm/OutputSegment.h b/wasm/OutputSegment.h
index d5c89cd..782b43b 100644
--- a/wasm/OutputSegment.h
+++ b/wasm/OutputSegment.h
@@ -1,9 +1,8 @@
 //===- OutputSegment.h ------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -26,7 +25,7 @@
   void addInputSegment(InputSegment *InSeg) {
     Alignment = std::max(Alignment, InSeg->getAlignment());
     InputSegments.push_back(InSeg);
-    Size = llvm::alignTo(Size, InSeg->getAlignment());
+    Size = llvm::alignTo(Size, 1ULL << InSeg->getAlignment());
     InSeg->OutputSeg = this;
     InSeg->OutputSegmentOffset = Size;
     Size += InSeg->getSize();
diff --git a/wasm/SymbolTable.cpp b/wasm/SymbolTable.cpp
index c798319..35ac2c5 100644
--- a/wasm/SymbolTable.cpp
+++ b/wasm/SymbolTable.cpp
@@ -1,9 +1,8 @@
 //===- SymbolTable.cpp ----------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -29,6 +28,8 @@
 
 void SymbolTable::addFile(InputFile *File) {
   log("Processing: " + toString(File));
+  if (Config->Trace)
+    message(toString(File));
   File->parse();
 
   // LLVM bitcode file
@@ -74,21 +75,43 @@
 }
 
 Symbol *SymbolTable::find(StringRef Name) {
-  return SymMap.lookup(CachedHashStringRef(Name));
+  auto It = SymMap.find(CachedHashStringRef(Name));
+  if (It == SymMap.end() || It->second == -1)
+    return nullptr;
+  return SymVector[It->second];
 }
 
-std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, InputFile *File) {
-  bool Inserted = false;
-  Symbol *&Sym = SymMap[CachedHashStringRef(Name)];
-  if (!Sym) {
-    Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
-    Sym->IsUsedInRegularObj = false;
-    SymVector.emplace_back(Sym);
-    Inserted = true;
+std::pair<Symbol *, bool> SymbolTable::insertName(StringRef Name) {
+  bool Trace = false;
+  auto P = SymMap.insert({CachedHashStringRef(Name), (int)SymVector.size()});
+  int &SymIndex = P.first->second;
+  bool IsNew = P.second;
+  if (SymIndex == -1) {
+    SymIndex = SymVector.size();
+    Trace = true;
+    IsNew = true;
   }
+
+  if (!IsNew)
+    return {SymVector[SymIndex], false};
+
+  Symbol *Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
+  Sym->IsUsedInRegularObj = false;
+  Sym->Traced = Trace;
+  SymVector.emplace_back(Sym);
+  return {Sym, true};
+}
+
+std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name,
+                                              const InputFile *File) {
+  Symbol *S;
+  bool WasInserted;
+  std::tie(S, WasInserted) = insertName(Name);
+
   if (!File || File->kind() == InputFile::ObjectKind)
-    Sym->IsUsedInRegularObj = true;
-  return {Sym, Inserted};
+    S->IsUsedInRegularObj = true;
+
+  return {S, WasInserted};
 }
 
 static void reportTypeError(const Symbol *Existing, const InputFile *File,
@@ -242,10 +265,12 @@
 
   if (shouldReplace(S, File, Flags)) {
     // If the new defined function doesn't have signture (i.e. bitcode
-    // functions) but the old symbols does then preserve the old signature
+    // functions) but the old symbol does then preserve the old signature
     const WasmSignature *OldSig = nullptr;
     if (auto* F = dyn_cast<FunctionSymbol>(S))
       OldSig = F->Signature;
+    if (auto *L = dyn_cast<LazySymbol>(S))
+      OldSig = L->Signature;
     auto NewSym = replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function);
     if (!NewSym->Signature)
       NewSym->Signature = OldSig;
@@ -314,8 +339,9 @@
   return S;
 }
 
-Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags,
-                                          InputFile *File,
+Symbol *SymbolTable::addUndefinedFunction(StringRef Name, StringRef ImportName,
+                                          StringRef ImportModule,
+                                          uint32_t Flags, InputFile *File,
                                           const WasmSignature *Sig) {
   LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name <<
              " [" << (Sig ? toString(*Sig) : "none") << "]\n");
@@ -325,7 +351,8 @@
   std::tie(S, WasInserted) = insert(Name, File);
 
   if (WasInserted)
-    replaceSymbol<UndefinedFunction>(S, Name, Flags, File, Sig);
+    replaceSymbol<UndefinedFunction>(S, Name, ImportName, ImportModule, Flags,
+                                     File, Sig);
   else if (auto *Lazy = dyn_cast<LazySymbol>(S))
     Lazy->fetch();
   else
@@ -351,7 +378,8 @@
   return S;
 }
 
-Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, uint32_t Flags,
+Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, StringRef ImportName,
+                                        StringRef ImportModule, uint32_t Flags,
                                         InputFile *File,
                                         const WasmGlobalType *Type) {
   LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << Name << "\n");
@@ -361,7 +389,8 @@
   std::tie(S, WasInserted) = insert(Name, File);
 
   if (WasInserted)
-    replaceSymbol<UndefinedGlobal>(S, Name, Flags, File, Type);
+    replaceSymbol<UndefinedGlobal>(S, Name, ImportName, ImportModule, Flags,
+                                   File, Type);
   else if (auto *Lazy = dyn_cast<LazySymbol>(S))
     Lazy->fetch();
   else if (S->isDefined())
@@ -378,17 +407,94 @@
   std::tie(S, WasInserted) = insert(Name, nullptr);
 
   if (WasInserted) {
-    replaceSymbol<LazySymbol>(S, Name, File, *Sym);
+    replaceSymbol<LazySymbol>(S, Name, 0, File, *Sym);
     return;
   }
 
-  // If there is an existing undefined symbol, load a new one from the archive.
-  if (S->isUndefined()) {
-    LLVM_DEBUG(dbgs() << "replacing existing undefined\n");
-    File->addMember(Sym);
+  if (!S->isUndefined())
+    return;
+
+  // The existing symbol is undefined, load a new one from the archive,
+  // unless the the existing symbol is weak in which case replace the undefined
+  // symbols with a LazySymbol.
+  if (S->isWeak()) {
+    const WasmSignature *OldSig = nullptr;
+    // In the case of an UndefinedFunction we need to preserve the expected
+    // signature.
+    if (auto *F = dyn_cast<UndefinedFunction>(S))
+      OldSig = F->Signature;
+    LLVM_DEBUG(dbgs() << "replacing existing weak undefined symbol\n");
+    auto NewSym = replaceSymbol<LazySymbol>(S, Name, WASM_SYMBOL_BINDING_WEAK,
+                                            File, *Sym);
+    NewSym->Signature = OldSig;
+    return;
   }
+
+  LLVM_DEBUG(dbgs() << "replacing existing undefined\n");
+  File->addMember(Sym);
 }
 
 bool SymbolTable::addComdat(StringRef Name) {
   return Comdats.insert(CachedHashStringRef(Name)).second;
 }
+
+// Set a flag for --trace-symbol so that we can print out a log message
+// if a new symbol with the same name is inserted into the symbol table.
+void SymbolTable::trace(StringRef Name) {
+  SymMap.insert({CachedHashStringRef(Name), -1});
+}
+
+static const uint8_t UnreachableFn[] = {
+    0x03 /* ULEB length */, 0x00 /* ULEB num locals */,
+    0x00 /* opcode unreachable */, 0x0b /* opcode end */
+};
+
+// Replace the given symbol body with an unreachable function.
+// This is used by handleWeakUndefines in order to generate a callable
+// equivalent of an undefined function.
+InputFunction *SymbolTable::replaceWithUnreachable(Symbol *Sym,
+                                                   const WasmSignature &Sig,
+                                                   StringRef DebugName) {
+  auto *Func = make<SyntheticFunction>(Sig, Sym->getName(), DebugName);
+  Func->setBody(UnreachableFn);
+  SyntheticFunctions.emplace_back(Func);
+  replaceSymbol<DefinedFunction>(Sym, Sym->getName(), Sym->getFlags(), nullptr, Func);
+  return Func;
+}
+
+// For weak undefined functions, there may be "call" instructions that reference
+// the symbol. In this case, we need to synthesise a dummy/stub function that
+// will abort at runtime, so that relocations can still provided an operand to
+// the call instruction that passes Wasm validation.
+void SymbolTable::handleWeakUndefines() {
+  for (Symbol *Sym : getSymbols()) {
+    if (!Sym->isUndefWeak())
+      continue;
+
+    const WasmSignature *Sig = nullptr;
+
+    if (auto *FuncSym = dyn_cast<FunctionSymbol>(Sym)) {
+      // It is possible for undefined functions not to have a signature (eg. if
+      // added via "--undefined"), but weak undefined ones do have a signature.
+      assert(FuncSym->Signature);
+      Sig = FuncSym->Signature;
+    } else if (auto *LazySym = dyn_cast<LazySymbol>(Sym)) {
+      // Lazy symbols may not be functions and therefore can have a null
+      // signature.
+      Sig = LazySym->Signature;
+    }
+
+    if (!Sig)
+      continue;
+
+    // Add a synthetic dummy for weak undefined functions.  These dummies will
+    // be GC'd if not used as the target of any "call" instructions.
+    StringRef DebugName = Saver.save("undefined:" + toString(*Sym));
+    InputFunction* Func = replaceWithUnreachable(Sym, *Sig, DebugName);
+    // Ensure it compares equal to the null pointer, and so that table relocs
+    // don't pull in the stub body (only call-operand relocs should do that).
+    Func->setTableIndex(0);
+    // Hide our dummy to prevent export.
+    Sym->setHidden(true);
+  }
+}
diff --git a/wasm/SymbolTable.h b/wasm/SymbolTable.h
index 5e38e30..f03980d 100644
--- a/wasm/SymbolTable.h
+++ b/wasm/SymbolTable.h
@@ -1,9 +1,8 @@
 //===- SymbolTable.h --------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -47,8 +46,11 @@
   void reportRemainingUndefines();
 
   ArrayRef<Symbol *> getSymbols() const { return SymVector; }
+
   Symbol *find(StringRef Name);
 
+  void trace(StringRef Name);
+
   Symbol *addDefinedFunction(StringRef Name, uint32_t Flags, InputFile *File,
                              InputFunction *Function);
   Symbol *addDefinedData(StringRef Name, uint32_t Flags, InputFile *File,
@@ -59,11 +61,13 @@
   Symbol *addDefinedEvent(StringRef Name, uint32_t Flags, InputFile *File,
                           InputEvent *E);
 
-  Symbol *addUndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File,
-                               const WasmSignature *Signature);
+  Symbol *addUndefinedFunction(StringRef Name, StringRef ImportName,
+                               StringRef ImportModule, uint32_t Flags,
+                               InputFile *File, const WasmSignature *Signature);
   Symbol *addUndefinedData(StringRef Name, uint32_t Flags, InputFile *File);
-  Symbol *addUndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
-                             const WasmGlobalType *Type);
+  Symbol *addUndefinedGlobal(StringRef Name, StringRef ImportName,
+                             StringRef ImportModule,  uint32_t Flags,
+                             InputFile *File, const WasmGlobalType *Type);
 
   void addLazy(ArchiveFile *F, const llvm::object::Archive::Symbol *Sym);
 
@@ -75,10 +79,19 @@
   DefinedFunction *addSyntheticFunction(StringRef Name, uint32_t Flags,
                                         InputFunction *Function);
 
-private:
-  std::pair<Symbol *, bool> insert(StringRef Name, InputFile *File);
+  void handleWeakUndefines();
 
-  llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> SymMap;
+private:
+  std::pair<Symbol *, bool> insert(StringRef Name, const InputFile *File);
+  std::pair<Symbol *, bool> insertName(StringRef Name);
+
+  InputFunction *replaceWithUnreachable(Symbol *Sym, const WasmSignature &Sig,
+                                        StringRef DebugName);
+
+  // Maps symbol names to index into the SymVector.  -1 means that symbols
+  // is to not yet in the vector but it should have tracing enabled if it is
+  // ever added.
+  llvm::DenseMap<llvm::CachedHashStringRef, int> SymMap;
   std::vector<Symbol *> SymVector;
 
   llvm::DenseSet<llvm::CachedHashStringRef> Comdats;
diff --git a/wasm/Symbols.cpp b/wasm/Symbols.cpp
index 4bef976..60030be 100644
--- a/wasm/Symbols.cpp
+++ b/wasm/Symbols.cpp
@@ -1,9 +1,8 @@
 //===- Symbols.cpp --------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -117,7 +116,7 @@
   if (Config->ExportDynamic && !isHidden())
     return true;
 
-  return false;
+  return Flags & WASM_SYMBOL_EXPORTED;
 }
 
 uint32_t FunctionSymbol::getFunctionIndex() const {
@@ -294,3 +293,16 @@
   }
   llvm_unreachable("invalid symbol kind");
 }
+
+// Print out a log message for --trace-symbol.
+void lld::wasm::printTraceSymbol(Symbol *Sym) {
+  std::string S;
+  if (Sym->isUndefined())
+    S = ": reference to ";
+  else if (Sym->isLazy())
+    S = ": lazy definition of ";
+  else
+    S = ": definition of ";
+
+  message(toString(Sym->getFile()) + S + Sym->getName());
+}
diff --git a/wasm/Symbols.h b/wasm/Symbols.h
index 11ee665..fd501ed 100644
--- a/wasm/Symbols.h
+++ b/wasm/Symbols.h
@@ -1,9 +1,8 @@
 //===- Symbols.h ------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -64,12 +63,21 @@
   bool isWeak() const;
   bool isHidden() const;
 
+  // True if this is an undefined weak symbol. This only works once
+  // all input files have been added.
+  bool isUndefWeak() const {
+    // See comment on lazy symbols for details.
+    return isWeak() && (isUndefined() || isLazy());
+  }
+
   // Returns the symbol name.
   StringRef getName() const { return Name; }
 
   // Returns the file from which this symbol was created.
   InputFile *getFile() const { return File; }
 
+  uint32_t getFlags() const { return Flags; }
+
   InputChunk *getChunk() const;
 
   // Indicates that the section or import for this symbol will be included in
@@ -94,10 +102,14 @@
   unsigned IsUsedInRegularObj : 1;
   unsigned ForceExport : 1;
 
+  // True if this symbol is specified by --trace-symbol option.
+  unsigned Traced : 1;
+
 protected:
   Symbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F)
-      : IsUsedInRegularObj(false), ForceExport(false), Name(Name),
-        SymbolKind(K), Flags(Flags), File(F), Referenced(!Config->GcSections) {}
+      : IsUsedInRegularObj(false), ForceExport(false), Traced(false),
+        Name(Name), SymbolKind(K), Flags(Flags), File(F),
+        Referenced(!Config->GcSections) {}
 
   StringRef Name;
   Kind SymbolKind;
@@ -149,13 +161,19 @@
 
 class UndefinedFunction : public FunctionSymbol {
 public:
-  UndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File = nullptr,
+  UndefinedFunction(StringRef Name, StringRef ImportName,
+                    StringRef ImportModule, uint32_t Flags,
+                    InputFile *File = nullptr,
                     const WasmSignature *Type = nullptr)
-      : FunctionSymbol(Name, UndefinedFunctionKind, Flags, File, Type) {}
+      : FunctionSymbol(Name, UndefinedFunctionKind, Flags, File, Type),
+        ImportName(ImportName), ImportModule(ImportModule) {}
 
   static bool classof(const Symbol *S) {
     return S->kind() == UndefinedFunctionKind;
   }
+
+  StringRef ImportName;
+  StringRef ImportModule;
 };
 
 class SectionSymbol : public Symbol {
@@ -261,13 +279,18 @@
 
 class UndefinedGlobal : public GlobalSymbol {
 public:
-  UndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File = nullptr,
+  UndefinedGlobal(StringRef Name, StringRef ImportName, StringRef ImportModule,
+                  uint32_t Flags, InputFile *File = nullptr,
                   const WasmGlobalType *Type = nullptr)
-      : GlobalSymbol(Name, UndefinedGlobalKind, Flags, File, Type) {}
+      : GlobalSymbol(Name, UndefinedGlobalKind, Flags, File, Type),
+        ImportName(ImportName), ImportModule(ImportModule) {}
 
   static bool classof(const Symbol *S) {
     return S->kind() == UndefinedGlobalKind;
   }
+
+  StringRef ImportName;
+  StringRef ImportModule;
 };
 
 // Wasm events are features that suspend the current execution and transfer the
@@ -314,15 +337,31 @@
   InputEvent *Event;
 };
 
+// LazySymbol represents a symbol that is not yet in the link, but we know where
+// to find it if needed. If the resolver finds both Undefined and Lazy for the
+// same name, it will ask the Lazy to load a file.
+//
+// A special complication is the handling of weak undefined symbols. They should
+// not load a file, but we have to remember we have seen both the weak undefined
+// and the lazy. We represent that with a lazy symbol with a weak binding. This
+// means that code looking for undefined symbols normally also has to take lazy
+// symbols into consideration.
 class LazySymbol : public Symbol {
 public:
-  LazySymbol(StringRef Name, InputFile *File,
+  LazySymbol(StringRef Name, uint32_t Flags, InputFile *File,
              const llvm::object::Archive::Symbol &Sym)
-      : Symbol(Name, LazyKind, 0, File), ArchiveSymbol(Sym) {}
+      : Symbol(Name, LazyKind, Flags, File), ArchiveSymbol(Sym) {}
 
   static bool classof(const Symbol *S) { return S->kind() == LazyKind; }
   void fetch();
 
+  // Lazy symbols can have a signature because they can replace an
+  // UndefinedFunction which which case we need to be able to preserve the
+  // signture.
+  // TODO(sbc): This repetition of the signature field is inelegant.  Revisit
+  // the use of class hierarchy to represent symbol taxonomy.
+  const WasmSignature *Signature = nullptr;
+
 private:
   llvm::object::Archive::Symbol ArchiveSymbol;
 };
@@ -376,6 +415,8 @@
   alignas(SectionSymbol) char I[sizeof(SectionSymbol)];
 };
 
+void printTraceSymbol(Symbol *Sym);
+
 template <typename T, typename... ArgT>
 T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
   static_assert(std::is_trivially_destructible<T>(),
@@ -391,6 +432,13 @@
   T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
   S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
   S2->ForceExport = SymCopy.ForceExport;
+  S2->Traced = SymCopy.Traced;
+
+  // Print out a log message if --trace-symbol was specified.
+  // This is for debugging.
+  if (S2->Traced)
+    printTraceSymbol(S2);
+
   return S2;
 }
 
diff --git a/wasm/Writer.cpp b/wasm/Writer.cpp
index 710f9cc..213beca 100644
--- a/wasm/Writer.cpp
+++ b/wasm/Writer.cpp
@@ -1,9 +1,8 @@
 //===- Writer.cpp ---------------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -21,6 +20,7 @@
 #include "lld/Common/Strings.h"
 #include "lld/Common/Threads.h"
 #include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/BinaryFormat/Wasm.h"
 #include "llvm/Object/WasmTraits.h"
@@ -39,8 +39,9 @@
 using namespace lld;
 using namespace lld::wasm;
 
-static constexpr int kStackAlignment = 16;
-static constexpr const char *kFunctionTableName = "__indirect_function_table";
+static constexpr int StackAlignment = 16;
+static constexpr const char *FunctionTableName = "__indirect_function_table";
+const char *lld::wasm::DefaultModule = "env";
 
 namespace {
 
@@ -95,6 +96,7 @@
   void createRelocSections();
   void createLinkingSection();
   void createNameSection();
+  void createProducersSection();
 
   void writeHeader();
   void writeSections();
@@ -155,7 +157,7 @@
 
   if (Config->ImportMemory) {
     WasmImport Import;
-    Import.Module = "env";
+    Import.Module = DefaultModule;
     Import.Field = "memory";
     Import.Kind = WASM_EXTERNAL_MEMORY;
     Import.Memory.Flags = 0;
@@ -172,18 +174,27 @@
   if (Config->ImportTable) {
     uint32_t TableSize = TableBase + IndirectFunctions.size();
     WasmImport Import;
-    Import.Module = "env";
-    Import.Field = kFunctionTableName;
+    Import.Module = DefaultModule;
+    Import.Field = FunctionTableName;
     Import.Kind = WASM_EXTERNAL_TABLE;
-    Import.Table.ElemType = WASM_TYPE_ANYFUNC;
+    Import.Table.ElemType = WASM_TYPE_FUNCREF;
     Import.Table.Limits = {0, TableSize, 0};
     writeImport(OS, Import);
   }
 
   for (const Symbol *Sym : ImportedSymbols) {
     WasmImport Import;
-    Import.Module = "env";
-    Import.Field = Sym->getName();
+    if (auto *F = dyn_cast<UndefinedFunction>(Sym)) {
+      Import.Field = F->ImportName;
+      Import.Module = F->ImportModule;
+    } else if (auto *G = dyn_cast<UndefinedGlobal>(Sym)) {
+      Import.Field = G->ImportName;
+      Import.Module = G->ImportModule;
+    } else {
+      Import.Field = Sym->getName();
+      Import.Module = DefaultModule;
+    }
+
     if (auto *FunctionSym = dyn_cast<FunctionSymbol>(Sym)) {
       Import.Kind = WASM_EXTERNAL_FUNCTION;
       Import.SigIndex = lookupType(*FunctionSym->Signature);
@@ -304,7 +315,7 @@
 
   writeUleb128(OS, 1, "table count");
   WasmLimits Limits = {WASM_LIMITS_FLAG_HAS_MAX, TableSize, TableSize};
-  writeTableType(OS, WasmTable{WASM_TYPE_ANYFUNC, Limits});
+  writeTableType(OS, WasmTable{WASM_TYPE_FUNCREF, Limits});
 }
 
 void Writer::createExportSection() {
@@ -327,7 +338,8 @@
       StringRef Name = Section->getName();
       // These custom sections are known the linker and synthesized rather than
       // blindly copied
-      if (Name == "linking" || Name == "name" || Name.startswith("reloc."))
+      if (Name == "linking" || Name == "name" || Name == "producers" ||
+          Name.startswith("reloc."))
         continue;
       // .. or it is a debug section
       if (StripDebug && Name.startswith(".debug_"))
@@ -364,7 +376,7 @@
   writeUleb128(OS, 0, "table index");
   WasmInitExpr InitExpr;
   if (Config->Pic) {
-    InitExpr.Opcode = WASM_OPCODE_GET_GLOBAL;
+    InitExpr.Opcode = WASM_OPCODE_GLOBAL_GET;
     InitExpr.Value.Global = WasmSym::TableBase->getGlobalIndex();
   } else {
     InitExpr.Opcode = WASM_OPCODE_I32_CONST;
@@ -441,6 +453,13 @@
     Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
   if (Sym->isUndefined())
     Flags |= WASM_SYMBOL_UNDEFINED;
+  if (auto *F = dyn_cast<UndefinedFunction>(Sym)) {
+    if (F->getName() != F->ImportName)
+      Flags |= WASM_SYMBOL_EXPLICIT_NAME;
+  } else if (auto *G = dyn_cast<UndefinedGlobal>(Sym)) {
+    if (G->getName() != G->ImportName)
+      Flags |= WASM_SYMBOL_EXPLICIT_NAME;
+  }
   return Flags;
 }
 
@@ -477,7 +496,7 @@
   raw_ostream &OS = Section->getStream();
 
   writeUleb128(OS, MemSize, "MemSize");
-  writeUleb128(OS, int(log2(MemAlign)), "MemAlign");
+  writeUleb128(OS, MemAlign, "MemAlign");
   writeUleb128(OS, IndirectFunctions.size(), "TableSize");
   writeUleb128(OS, 0, "TableAlign");
   writeUleb128(OS, 0, "Needed");  // TODO: Support "needed" shared libraries
@@ -506,15 +525,18 @@
 
       if (auto *F = dyn_cast<FunctionSymbol>(Sym)) {
         writeUleb128(Sub.OS, F->getFunctionIndex(), "index");
-        if (Sym->isDefined())
+        if (Sym->isDefined() ||
+            (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0)
           writeStr(Sub.OS, Sym->getName(), "sym name");
       } else if (auto *G = dyn_cast<GlobalSymbol>(Sym)) {
         writeUleb128(Sub.OS, G->getGlobalIndex(), "index");
-        if (Sym->isDefined())
+        if (Sym->isDefined() ||
+            (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0)
           writeStr(Sub.OS, Sym->getName(), "sym name");
       } else if (auto *E = dyn_cast<EventSymbol>(Sym)) {
         writeUleb128(Sub.OS, E->getEventIndex(), "index");
-        if (Sym->isDefined())
+        if (Sym->isDefined() ||
+            (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0)
           writeStr(Sub.OS, Sym->getName(), "sym name");
       } else if (isa<DataSymbol>(Sym)) {
         writeStr(Sub.OS, Sym->getName(), "sym name");
@@ -633,6 +655,45 @@
   Sub.writeTo(Section->getStream());
 }
 
+void Writer::createProducersSection() {
+  SmallVector<std::pair<std::string, std::string>, 8> Languages;
+  SmallVector<std::pair<std::string, std::string>, 8> Tools;
+  SmallVector<std::pair<std::string, std::string>, 8> SDKs;
+  for (ObjFile *File : Symtab->ObjectFiles) {
+    const WasmProducerInfo &Info = File->getWasmObj()->getProducerInfo();
+    for (auto &Producers : {std::make_pair(&Info.Languages, &Languages),
+                            std::make_pair(&Info.Tools, &Tools),
+                            std::make_pair(&Info.SDKs, &SDKs)})
+      for (auto &Producer : *Producers.first)
+        if (Producers.second->end() ==
+            std::find_if(Producers.second->begin(), Producers.second->end(),
+                         [&](std::pair<std::string, std::string> Seen) {
+                           return Seen.first == Producer.first;
+                         }))
+          Producers.second->push_back(Producer);
+  }
+  int FieldCount =
+      int(!Languages.empty()) + int(!Tools.empty()) + int(!SDKs.empty());
+  if (FieldCount == 0)
+    return;
+  SyntheticSection *Section =
+      createSyntheticSection(WASM_SEC_CUSTOM, "producers");
+  auto &OS = Section->getStream();
+  writeUleb128(OS, FieldCount, "field count");
+  for (auto &Field :
+       {std::make_pair("language", Languages),
+        std::make_pair("processed-by", Tools), std::make_pair("sdk", SDKs)}) {
+    if (Field.second.empty())
+      continue;
+    writeStr(OS, Field.first, "field name");
+    writeUleb128(OS, Field.second.size(), "number of entries");
+    for (auto &Entry : Field.second) {
+      writeStr(OS, Entry.first, "producer name");
+      writeStr(OS, Entry.second, "producer version");
+    }
+  }
+}
+
 void Writer::writeHeader() {
   memcpy(Buffer->getBufferStart(), Header.data(), Header.size());
 }
@@ -663,9 +724,9 @@
   auto PlaceStack = [&]() {
     if (Config->Relocatable || Config->Shared)
       return;
-    MemoryPtr = alignTo(MemoryPtr, kStackAlignment);
-    if (Config->ZStackSize != alignTo(Config->ZStackSize, kStackAlignment))
-      error("stack size must be " + Twine(kStackAlignment) + "-byte aligned");
+    MemoryPtr = alignTo(MemoryPtr, StackAlignment);
+    if (Config->ZStackSize != alignTo(Config->ZStackSize, StackAlignment))
+      error("stack size must be " + Twine(StackAlignment) + "-byte aligned");
     log("mem: stack size  = " + Twine(Config->ZStackSize));
     log("mem: stack base  = " + Twine(MemoryPtr));
     MemoryPtr += Config->ZStackSize;
@@ -691,7 +752,7 @@
   MemAlign = 0;
   for (OutputSegment *Seg : Segments) {
     MemAlign = std::max(MemAlign, Seg->Alignment);
-    MemoryPtr = alignTo(MemoryPtr, Seg->Alignment);
+    MemoryPtr = alignTo(MemoryPtr, 1ULL << Seg->Alignment);
     Seg->StartVA = MemoryPtr;
     log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", Seg->Name,
                 MemoryPtr, Seg->Size, Seg->Alignment));
@@ -772,9 +833,13 @@
     createLinkingSection();
     createRelocSections();
   }
+
   if (!Config->StripDebug && !Config->StripAll)
     createNameSection();
 
+  if (!Config->StripAll)
+    createProducersSection();
+
   for (OutputSection *S : OutputSections) {
     S->setOffset(FileSize);
     S->finalizeContents();
@@ -814,7 +879,7 @@
     Exports.push_back(WasmExport{"memory", WASM_EXTERNAL_MEMORY, 0});
 
   if (!Config->Relocatable && Config->ExportTable)
-    Exports.push_back(WasmExport{kFunctionTableName, WASM_EXTERNAL_TABLE, 0});
+    Exports.push_back(WasmExport{FunctionTableName, WASM_EXTERNAL_TABLE, 0});
 
   unsigned FakeGlobalIndex = NumImportedGlobals + InputGlobals.size();
 
@@ -858,40 +923,42 @@
   StringMap<uint32_t> SectionSymbolIndices;
 
   unsigned SymbolIndex = SymtabEntries.size();
-  for (ObjFile *File : Symtab->ObjectFiles) {
-    LLVM_DEBUG(dbgs() << "Symtab entries: " << File->getName() << "\n");
-    for (Symbol *Sym : File->getSymbols()) {
-      if (Sym->getFile() != File)
-        continue;
 
-      if (auto *S = dyn_cast<SectionSymbol>(Sym)) {
-        StringRef Name = S->getName();
-        if (CustomSectionMapping.count(Name) == 0)
-          continue;
+  auto AddSymbol = [&](Symbol *Sym) {
+    if (auto *S = dyn_cast<SectionSymbol>(Sym)) {
+      StringRef Name = S->getName();
+      if (CustomSectionMapping.count(Name) == 0)
+        return;
 
-        auto SSI = SectionSymbolIndices.find(Name);
-        if (SSI != SectionSymbolIndices.end()) {
-          Sym->setOutputSymbolIndex(SSI->second);
-          continue;
-        }
-
-        SectionSymbolIndices[Name] = SymbolIndex;
-        CustomSectionSymbols[Name] = cast<SectionSymbol>(Sym);
-
-        Sym->markLive();
+      auto SSI = SectionSymbolIndices.find(Name);
+      if (SSI != SectionSymbolIndices.end()) {
+        Sym->setOutputSymbolIndex(SSI->second);
+        return;
       }
 
-      // (Since this is relocatable output, GC is not performed so symbols must
-      // be live.)
-      assert(Sym->isLive());
-      Sym->setOutputSymbolIndex(SymbolIndex++);
-      SymtabEntries.emplace_back(Sym);
-    }
-  }
+      SectionSymbolIndices[Name] = SymbolIndex;
+      CustomSectionSymbols[Name] = cast<SectionSymbol>(Sym);
 
-  // For the moment, relocatable output doesn't contain any synthetic functions,
-  // so no need to look through the Symtab for symbols not referenced by
-  // Symtab->ObjectFiles.
+      Sym->markLive();
+    }
+
+    // (Since this is relocatable output, GC is not performed so symbols must
+    // be live.)
+    assert(Sym->isLive());
+    Sym->setOutputSymbolIndex(SymbolIndex++);
+    SymtabEntries.emplace_back(Sym);
+  };
+
+  for (Symbol *Sym : Symtab->getSymbols())
+    if (!Sym->isLazy())
+      AddSymbol(Sym);
+
+  for (ObjFile *File : Symtab->ObjectFiles) {
+    LLVM_DEBUG(dbgs() << "Local symtab entries: " << File->getName() << "\n");
+    for (Symbol *Sym : File->getSymbols())
+      if (Sym->isLocal())
+        AddSymbol(Sym);
+  }
 }
 
 uint32_t Writer::lookupType(const WasmSignature &Sig) {
@@ -967,14 +1034,14 @@
     ObjFile *File = Chunk->File;
     ArrayRef<WasmSignature> Types = File->getWasmObj()->types();
     for (const WasmRelocation &Reloc : Chunk->getRelocations()) {
-      if (Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_I32 ||
-          Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_SLEB) {
+      if (Reloc.Type == R_WASM_TABLE_INDEX_I32 ||
+          Reloc.Type == R_WASM_TABLE_INDEX_SLEB) {
         FunctionSymbol *Sym = File->getFunctionSymbol(Reloc.Index);
         if (Sym->hasTableIndex() || !Sym->hasFunctionIndex())
           continue;
         Sym->setTableIndex(TableIndex++);
         IndirectFunctions.emplace_back(Sym);
-      } else if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB) {
+      } else if (Reloc.Type == R_WASM_TYPE_INDEX_LEB) {
         // Mark target type as live
         File->TypeMap[Reloc.Index] = registerType(Types[Reloc.Index]);
         File->TypeIsUsed[Reloc.Index] = true;
diff --git a/wasm/Writer.h b/wasm/Writer.h
index a931ba9..ebbd109 100644
--- a/wasm/Writer.h
+++ b/wasm/Writer.h
@@ -1,9 +1,8 @@
 //===- Writer.h -------------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -15,6 +14,8 @@
 
 void writeResult();
 
+extern const char *DefaultModule;
+
 } // namespace wasm
 } // namespace lld
 
diff --git a/wasm/WriterUtils.cpp b/wasm/WriterUtils.cpp
index 6af152a..599b42b 100644
--- a/wasm/WriterUtils.cpp
+++ b/wasm/WriterUtils.cpp
@@ -1,9 +1,8 @@
 //===- WriterUtils.cpp ----------------------------------------------------===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -83,7 +82,7 @@
   case WASM_OPCODE_I64_CONST:
     writeSleb128(OS, InitExpr.Value.Int64, "literal (i64)");
     break;
-  case WASM_OPCODE_GET_GLOBAL:
+  case WASM_OPCODE_GLOBAL_GET:
     writeUleb128(OS, InitExpr.Value.Global, "literal (global index)");
     break;
   default:
@@ -120,7 +119,7 @@
 }
 
 void wasm::writeTableType(raw_ostream &OS, const llvm::wasm::WasmTable &Type) {
-  writeU8(OS, WASM_TYPE_ANYFUNC, "table type");
+  writeU8(OS, WASM_TYPE_FUNCREF, "table type");
   writeLimits(OS, Type.Limits);
 }
 
diff --git a/wasm/WriterUtils.h b/wasm/WriterUtils.h
index 7fc4b5a..389f997 100644
--- a/wasm/WriterUtils.h
+++ b/wasm/WriterUtils.h
@@ -1,9 +1,8 @@
 //===- WriterUtils.h --------------------------------------------*- C++ -*-===//
 //
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//