Merge 861196015 for LLVM update to 333878

Change-Id: I87e5ea27d2c64708ab338200f6d39a7fd332c86e
diff --git a/COFF/Chunks.cpp b/COFF/Chunks.cpp
index 451e18a..ab6160c 100644
--- a/COFF/Chunks.cpp
+++ b/COFF/Chunks.cpp
@@ -31,8 +31,7 @@
 
 SectionChunk::SectionChunk(ObjFile *F, const coff_section *H)
     : Chunk(SectionKind), Repl(this), Header(H), File(F),
-      Relocs(File->getCOFFObj()->getRelocations(Header)),
-      NumRelocs(std::distance(Relocs.begin(), Relocs.end())) {
+      Relocs(File->getCOFFObj()->getRelocations(Header)) {
   // Initialize SectionName.
   File->getCOFFObj()->getSectionName(Header, SectionName);
 
@@ -163,7 +162,7 @@
                                uint64_t S, uint64_t P) const {
   // Pointer to thumb code must have the LSB set.
   uint64_t SX = S;
-  if (OS && (OS->getPermissions() & IMAGE_SCN_MEM_EXECUTE))
+  if (OS && (OS->Header.Characteristics & IMAGE_SCN_MEM_EXECUTE))
     SX |= 1;
   switch (Type) {
   case IMAGE_REL_ARM_ADDR32:    add32(Off, SX + Config->ImageBase); break;
@@ -182,11 +181,11 @@
 // Interpret the existing immediate value as a byte offset to the
 // target symbol, then update the instruction with the immediate as
 // the page offset from the current instruction to the target.
-static void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P) {
+static void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P, int Shift) {
   uint32_t Orig = read32le(Off);
   uint64_t Imm = ((Orig >> 29) & 0x3) | ((Orig >> 3) & 0x1FFFFC);
   S += Imm;
-  Imm = (S >> 12) - (P >> 12);
+  Imm = (S >> Shift) - (P >> Shift);
   uint32_t ImmLo = (Imm & 0x3) << 29;
   uint32_t ImmHi = (Imm & 0x1FFFFC) << 3;
   uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3);
@@ -248,13 +247,34 @@
     applyArm64Ldr(Off, (S - OS->getRVA()) & 0xfff);
 }
 
+static void applyArm64Branch26(uint8_t *Off, int64_t V) {
+  if (!isInt<28>(V))
+    fatal("relocation out of range");
+  or32(Off, (V & 0x0FFFFFFC) >> 2);
+}
+
+static void applyArm64Branch19(uint8_t *Off, int64_t V) {
+  if (!isInt<21>(V))
+    fatal("relocation out of range");
+  or32(Off, (V & 0x001FFFFC) << 3);
+}
+
+static void applyArm64Branch14(uint8_t *Off, int64_t V) {
+  if (!isInt<16>(V))
+    fatal("relocation out of range");
+  or32(Off, (V & 0x0000FFFC) << 3);
+}
+
 void SectionChunk::applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS,
                                  uint64_t S, uint64_t P) const {
   switch (Type) {
-  case IMAGE_REL_ARM64_PAGEBASE_REL21: applyArm64Addr(Off, S, P); break;
+  case IMAGE_REL_ARM64_PAGEBASE_REL21: applyArm64Addr(Off, S, P, 12); break;
+  case IMAGE_REL_ARM64_REL21:          applyArm64Addr(Off, S, P, 0); break;
   case IMAGE_REL_ARM64_PAGEOFFSET_12A: applyArm64Imm(Off, S & 0xfff, 0); break;
   case IMAGE_REL_ARM64_PAGEOFFSET_12L: applyArm64Ldr(Off, S & 0xfff); break;
-  case IMAGE_REL_ARM64_BRANCH26:       or32(Off, ((S - P) & 0x0FFFFFFC) >> 2); break;
+  case IMAGE_REL_ARM64_BRANCH26:       applyArm64Branch26(Off, S - P); break;
+  case IMAGE_REL_ARM64_BRANCH19:       applyArm64Branch19(Off, S - P); break;
+  case IMAGE_REL_ARM64_BRANCH14:       applyArm64Branch14(Off, S - P); break;
   case IMAGE_REL_ARM64_ADDR32:         add32(Off, S + Config->ImageBase); break;
   case IMAGE_REL_ARM64_ADDR32NB:       add32(Off, S); break;
   case IMAGE_REL_ARM64_ADDR64:         add64(Off, S + Config->ImageBase); break;
@@ -262,6 +282,7 @@
   case IMAGE_REL_ARM64_SECREL_LOW12A:  applySecRelLow12A(this, Off, OS, S); break;
   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;
   default:
     fatal("unsupported relocation type 0x" + Twine::utohexstr(Type));
   }
@@ -272,7 +293,8 @@
     return;
   // Copy section contents from source object file to output file.
   ArrayRef<uint8_t> A = getContents();
-  memcpy(Buf + OutputSectionOff, A.data(), A.size());
+  if (!A.empty())
+    memcpy(Buf + OutputSectionOff, A.data(), A.size());
 
   // Apply relocations.
   size_t InputSize = getSize();
@@ -388,8 +410,8 @@
   return !(Header->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA);
 }
 
-uint32_t SectionChunk::getPermissions() const {
-  return Header->Characteristics & PermMask;
+uint32_t SectionChunk::getOutputCharacteristics() const {
+  return Header->Characteristics & (PermMask | TypeMask);
 }
 
 bool SectionChunk::isCOMDAT() const {
@@ -416,6 +438,7 @@
 }
 
 void SectionChunk::replace(SectionChunk *Other) {
+  Alignment = std::max(Alignment, Other->Alignment);
   Other->Repl = Repl;
   Other->Live = false;
 }
@@ -426,7 +449,7 @@
   Alignment = std::min(uint64_t(32), PowerOf2Ceil(Sym.getValue()));
 }
 
-uint32_t CommonChunk::getPermissions() const {
+uint32_t CommonChunk::getOutputCharacteristics() const {
   return IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ |
          IMAGE_SCN_MEM_WRITE;
 }
@@ -471,7 +494,7 @@
 void ImportThunkChunkARM64::writeTo(uint8_t *Buf) const {
   int64_t Off = ImpSymbol->getRVA() & 0xfff;
   memcpy(Buf + OutputSectionOff, ImportThunkARM64, sizeof(ImportThunkARM64));
-  applyArm64Addr(Buf + OutputSectionOff, ImpSymbol->getRVA(), RVA);
+  applyArm64Addr(Buf + OutputSectionOff, ImpSymbol->getRVA(), RVA, 12);
   applyArm64Ldr(Buf + OutputSectionOff + 4, Off);
 }
 
@@ -601,7 +624,7 @@
   }
 }
 
-uint32_t MergeChunk::getPermissions() const {
+uint32_t MergeChunk::getOutputCharacteristics() const {
   return IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA;
 }
 
diff --git a/COFF/Chunks.h b/COFF/Chunks.h
index b95869a..9e89653 100644
--- a/COFF/Chunks.h
+++ b/COFF/Chunks.h
@@ -38,9 +38,11 @@
 class OutputSection;
 class Symbol;
 
-// Mask for section types (code, data, bss, disacardable, etc.)
-// and permissions (writable, readable or executable).
-const uint32_t PermMask = 0xFF0000F0;
+// Mask for permissions (discardable, writable, readable, executable, etc).
+const uint32_t PermMask = 0xFE000000;
+
+// Mask for section types (code, data, bss).
+const uint32_t TypeMask = 0x000000E0;
 
 // A Chunk represents a chunk of data that will occupy space in the
 // output (if the resolver chose that). It may or may not be backed by
@@ -75,7 +77,7 @@
   virtual bool hasData() const { return true; }
 
   // Returns readable/writable/executable bits.
-  virtual uint32_t getPermissions() const { return 0; }
+  virtual uint32_t getOutputCharacteristics() const { return 0; }
 
   // Returns the section name if this is a section chunk.
   // It is illegal to call this function on non-section chunks.
@@ -142,7 +144,7 @@
   ArrayRef<uint8_t> getContents() const;
   void writeTo(uint8_t *Buf) const override;
   bool hasData() const override;
-  uint32_t getPermissions() const override;
+  uint32_t getOutputCharacteristics() const override;
   StringRef getSectionName() const override { return SectionName; }
   void getBaserels(std::vector<Baserel> *Res) override;
   bool isCOMDAT() const;
@@ -213,11 +215,11 @@
   // The COMDAT leader symbol if this is a COMDAT chunk.
   DefinedRegular *Sym = nullptr;
 
+  ArrayRef<coff_relocation> Relocs;
+
 private:
   StringRef SectionName;
   std::vector<SectionChunk *> AssocChildren;
-  llvm::iterator_range<const coff_relocation *> Relocs;
-  size_t NumRelocs;
 
   // Used by the garbage collector.
   bool Live;
@@ -242,7 +244,7 @@
   static void addSection(SectionChunk *C);
   void finalizeContents() override;
 
-  uint32_t getPermissions() const override;
+  uint32_t getOutputCharacteristics() const override;
   StringRef getSectionName() const override { return ".rdata"; }
   size_t getSize() const override;
   void writeTo(uint8_t *Buf) const override;
@@ -260,7 +262,7 @@
   CommonChunk(const COFFSymbolRef Sym);
   size_t getSize() const override { return Sym.getValue(); }
   bool hasData() const override { return false; }
-  uint32_t getPermissions() const override;
+  uint32_t getOutputCharacteristics() const override;
   StringRef getSectionName() const override { return ".bss"; }
 
 private:
diff --git a/COFF/Config.h b/COFF/Config.h
index 1a03a24..3ccccb6 100644
--- a/COFF/Config.h
+++ b/COFF/Config.h
@@ -92,6 +92,7 @@
   std::string ImportName;
   bool DoGC = true;
   bool DoICF = true;
+  bool TailMerge;
   bool Relocatable = true;
   bool Force = false;
   bool Debug = false;
@@ -100,6 +101,7 @@
   bool ShowTiming = false;
   unsigned DebugTypes = static_cast<unsigned>(DebugType::None);
   std::vector<std::string> NatvisFiles;
+  llvm::SmallString<128> PDBAltPath;
   llvm::SmallString<128> PDBPath;
   std::vector<llvm::StringRef> Argv;
 
@@ -127,10 +129,10 @@
   Symbol *SEHCount = nullptr;
 
   // Used for /opt:lldlto=N
-  unsigned LTOOptLevel = 2;
+  unsigned LTOO = 2;
 
   // Used for /opt:lldltojobs=N
-  unsigned LTOJobs = 0;
+  unsigned ThinLTOJobs = 0;
   // Used for /opt:lldltopartitions=N
   unsigned LTOPartitions = 1;
 
@@ -179,6 +181,7 @@
   uint32_t MinorImageVersion = 0;
   uint32_t MajorOSVersion = 6;
   uint32_t MinorOSVersion = 0;
+  uint32_t Timestamp = 0;
   bool DynamicBase = true;
   bool AllowBind = true;
   bool NxCompat = true;
@@ -191,7 +194,9 @@
   bool WarnMissingOrderSymbol = true;
   bool WarnLocallyDefinedImported = true;
   bool Incremental = true;
+  bool IntegrityCheck = false;
   bool KillAt = false;
+  bool Repro = false;
 };
 
 extern Configuration *Config;
diff --git a/COFF/DLL.h b/COFF/DLL.h
index ad31278..c5d6e7c 100644
--- a/COFF/DLL.h
+++ b/COFF/DLL.h
@@ -76,6 +76,11 @@
 public:
   EdataContents();
   std::vector<Chunk *> Chunks;
+
+  uint64_t getRVA() { return Chunks[0]->getRVA(); }
+  uint64_t getSize() {
+    return Chunks.back()->getRVA() + Chunks.back()->getSize() - getRVA();
+  }
 };
 
 } // namespace coff
diff --git a/COFF/Driver.cpp b/COFF/Driver.cpp
index 02b2208..64a7d72 100644
--- a/COFF/Driver.cpp
+++ b/COFF/Driver.cpp
@@ -97,7 +97,7 @@
 // Create a std::future that opens and maps a file using the best strategy for
 // the host platform.
 static std::future<MBErrPair> createFutureForFile(std::string Path) {
-#if LLVM_ON_WIN32
+#if _WIN32
   // On Windows, file I/O is relatively slow so it is best to do this
   // asynchronously.
   auto Strategy = std::launch::async;
@@ -105,7 +105,9 @@
   auto Strategy = std::launch::deferred;
 #endif
   return std::async(Strategy, [=]() {
-    auto MBOrErr = MemoryBuffer::getFile(Path);
+    auto MBOrErr = MemoryBuffer::getFile(Path,
+                                         /*FileSize*/ -1,
+                                         /*RequiresNullTerminator*/ false);
     if (!MBOrErr)
       return MBErrPair{nullptr, MBOrErr.getError()};
     return MBErrPair{std::move(*MBOrErr), std::error_code()};
@@ -557,16 +559,17 @@
 
   if (!Config->Incremental) {
     HandleError(writeImportLibrary(LibName, Path, Exports, Config->Machine,
-                                   false, Config->MinGW));
+                                   Config->MinGW));
     return;
   }
 
   // If the import library already exists, replace it only if the contents
   // have changed.
-  ErrorOr<std::unique_ptr<MemoryBuffer>> OldBuf = MemoryBuffer::getFile(Path);
+  ErrorOr<std::unique_ptr<MemoryBuffer>> OldBuf = MemoryBuffer::getFile(
+      Path, /*FileSize*/ -1, /*RequiresNullTerminator*/ false);
   if (!OldBuf) {
     HandleError(writeImportLibrary(LibName, Path, Exports, Config->Machine,
-                                   false, Config->MinGW));
+                                   Config->MinGW));
     return;
   }
 
@@ -577,12 +580,13 @@
           EC.message());
 
   if (Error E = writeImportLibrary(LibName, TmpName, Exports, Config->Machine,
-                                   false, Config->MinGW)) {
+                                   Config->MinGW)) {
     HandleError(std::move(E));
     return;
   }
 
-  std::unique_ptr<MemoryBuffer> NewBuf = check(MemoryBuffer::getFile(TmpName));
+  std::unique_ptr<MemoryBuffer> NewBuf = check(MemoryBuffer::getFile(
+      TmpName, /*FileSize*/ -1, /*RequiresNullTerminator*/ false));
   if ((*OldBuf)->getBuffer() != NewBuf->getBuffer()) {
     OldBuf->reset();
     HandleError(errorCodeToError(sys::fs::rename(TmpName, Path)));
@@ -621,9 +625,18 @@
 
   for (COFFShortExport E1 : M.Exports) {
     Export E2;
+    // In simple cases, only Name is set. Renamed exports are parsed
+    // and set as "ExtName = Name". If Name has the form "OtherDll.Func",
+    // it shouldn't be a normal exported function but a forward to another
+    // DLL instead. This is supported by both MS and GNU linkers.
+    if (E1.ExtName != E1.Name && StringRef(E1.Name).contains('.')) {
+      E2.Name = Saver.save(E1.ExtName);
+      E2.ForwardTo = Saver.save(E1.Name);
+      Config->Exports.push_back(E2);
+      continue;
+    }
     E2.Name = Saver.save(E1.Name);
-    if (E1.isWeak())
-      E2.ExtName = Saver.save(E1.ExtName);
+    E2.ExtName = Saver.save(E1.ExtName);
     E2.Ordinal = E1.Ordinal;
     E2.Noname = E1.Noname;
     E2.Data = E1.Data;
@@ -936,6 +949,8 @@
   if (ShouldCreatePDB) {
     if (auto *Arg = Args.getLastArg(OPT_pdb))
       Config->PDBPath = Arg->getValue();
+    if (auto *Arg = Args.getLastArg(OPT_pdbaltpath))
+      Config->PDBAltPath = Arg->getValue();
     if (Args.hasArg(OPT_natvis))
       Config->NatvisFiles = Args.getAllArgValues(OPT_natvis);
   }
@@ -1018,6 +1033,23 @@
     parseSubsystem(Arg->getValue(), &Config->Subsystem, &Config->MajorOSVersion,
                    &Config->MinorOSVersion);
 
+  // Handle /timestamp
+  if (llvm::opt::Arg *Arg = Args.getLastArg(OPT_timestamp, OPT_repro)) {
+    if (Arg->getOption().getID() == OPT_repro) {
+      Config->Timestamp = 0;
+      Config->Repro = true;
+    } else {
+      Config->Repro = false;
+      StringRef Value(Arg->getValue());
+      if (Value.getAsInteger(0, Config->Timestamp))
+        fatal(Twine("invalid timestamp: ") + Value +
+              ".  Expected 32-bit integer");
+    }
+  } else {
+    Config->Repro = false;
+    Config->Timestamp = time(nullptr);
+  }
+
   // Handle /alternatename
   for (auto *Arg : Args.filtered(OPT_alternatename))
     parseAlternateName(Arg->getValue());
@@ -1034,6 +1066,7 @@
   bool DoGC = !Args.hasArg(OPT_debug) || Args.hasArg(OPT_profile);
   unsigned ICFLevel =
       Args.hasArg(OPT_profile) ? 0 : 1; // 0: off, 1: limited, 2: on
+  unsigned TailMerge = 1;
   for (auto *Arg : Args.filtered(OPT_opt)) {
     std::string Str = StringRef(Arg->getValue()).lower();
     SmallVector<StringRef, 1> Vec;
@@ -1047,14 +1080,18 @@
         ICFLevel = 2;
       } else if (S == "noicf") {
         ICFLevel = 0;
+      } else if (S == "lldtailmerge") {
+        TailMerge = 2;
+      } else if (S == "nolldtailmerge") {
+        TailMerge = 0;
       } else if (S.startswith("lldlto=")) {
         StringRef OptLevel = S.substr(7);
-        if (OptLevel.getAsInteger(10, Config->LTOOptLevel) ||
-            Config->LTOOptLevel > 3)
+        if (OptLevel.getAsInteger(10, Config->LTOO) || Config->LTOO > 3)
           error("/opt:lldlto: invalid optimization level: " + OptLevel);
       } else if (S.startswith("lldltojobs=")) {
         StringRef Jobs = S.substr(11);
-        if (Jobs.getAsInteger(10, Config->LTOJobs) || Config->LTOJobs == 0)
+        if (Jobs.getAsInteger(10, Config->ThinLTOJobs) ||
+            Config->ThinLTOJobs == 0)
           error("/opt:lldltojobs: invalid job count: " + Jobs);
       } else if (S.startswith("lldltopartitions=")) {
         StringRef N = S.substr(17);
@@ -1075,6 +1112,7 @@
     ICFLevel = 0;
   Config->DoGC = DoGC;
   Config->DoICF = ICFLevel > 0;
+  Config->TailMerge = (TailMerge == 1 && Config->DoICF) || TailMerge == 2;
 
   // Handle /lldsavetemps
   if (Args.hasArg(OPT_lldsavetemps))
@@ -1102,6 +1140,14 @@
   for (auto *Arg : Args.filtered(OPT_merge))
     parseMerge(Arg->getValue());
 
+  // Add default section merging rules after user rules. User rules take
+  // precedence, but we will emit a warning if there is a conflict.
+  parseMerge(".idata=.rdata");
+  parseMerge(".didat=.rdata");
+  parseMerge(".edata=.rdata");
+  parseMerge(".xdata=.rdata");
+  parseMerge(".bss=.data");
+
   // Handle /section
   for (auto *Arg : Args.filtered(OPT_section))
     parseSection(Arg->getValue());
@@ -1150,8 +1196,11 @@
       Args.hasFlag(OPT_incremental, OPT_incremental_no,
                    !Config->DoGC && !Config->DoICF && !Args.hasArg(OPT_order) &&
                        !Args.hasArg(OPT_profile));
+  Config->IntegrityCheck =
+      Args.hasFlag(OPT_integritycheck, OPT_integritycheck_no, false);
   Config->NxCompat = Args.hasFlag(OPT_nxcompat, OPT_nxcompat_no, true);
-  Config->TerminalServerAware = Args.hasFlag(OPT_tsaware, OPT_tsaware_no, true);
+  Config->TerminalServerAware =
+      !Config->DLL && Args.hasFlag(OPT_tsaware, OPT_tsaware_no, true);
   Config->DebugDwarf = Args.hasArg(OPT_debug_dwarf);
   Config->DebugGHashes = Args.hasArg(OPT_debug_ghash);
 
@@ -1301,10 +1350,19 @@
         getOutputPath((*Args.filtered(OPT_INPUT).begin())->getValue());
   }
 
-  // Put the PDB next to the image if no /pdb flag was passed.
-  if (ShouldCreatePDB && Config->PDBPath.empty()) {
-    Config->PDBPath = Config->OutputFile;
-    sys::path::replace_extension(Config->PDBPath, ".pdb");
+  if (ShouldCreatePDB) {
+    // Put the PDB next to the image if no /pdb flag was passed.
+    if (Config->PDBPath.empty()) {
+      Config->PDBPath = Config->OutputFile;
+      sys::path::replace_extension(Config->PDBPath, ".pdb");
+    }
+
+    // The embedded PDB path should be the absolute path to the PDB if no
+    // /pdbaltpath flag was passed.
+    if (Config->PDBAltPath.empty()) {
+      Config->PDBAltPath = Config->PDBPath;
+      sys::fs::make_absolute(Config->PDBAltPath);
+    }
   }
 
   // Set default image base if /base is not given.
@@ -1414,7 +1472,7 @@
       E.Name = Def->getName();
       E.Sym = Def;
       if (Def->getChunk() &&
-          !(Def->getChunk()->getPermissions() & IMAGE_SCN_MEM_EXECUTE))
+          !(Def->getChunk()->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE))
         E.Data = true;
       Config->Exports.push_back(E);
     });
diff --git a/COFF/DriverUtils.cpp b/COFF/DriverUtils.cpp
index 0b705f4..9875119 100644
--- a/COFF/DriverUtils.cpp
+++ b/COFF/DriverUtils.cpp
@@ -185,6 +185,10 @@
   std::tie(From, To) = S.split('=');
   if (From.empty() || To.empty())
     fatal("/merge: invalid argument: " + S);
+  if (From == ".rsrc" || To == ".rsrc")
+    fatal("/merge: cannot merge '.rsrc' with any section");
+  if (From == ".reloc" || To == ".reloc")
+    fatal("/merge: cannot merge '.reloc' with any section");
   auto Pair = Config->Merge.insert(std::make_pair(From, To));
   bool Inserted = Pair.second;
   if (!Inserted) {
@@ -752,6 +756,28 @@
 
 COFFOptTable::COFFOptTable() : OptTable(InfoTable, true) {}
 
+// Set color diagnostics according to --color-diagnostics={auto,always,never}
+// or --no-color-diagnostics flags.
+static void handleColorDiagnostics(opt::InputArgList &Args) {
+  auto *Arg = Args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq,
+                              OPT_no_color_diagnostics);
+  if (!Arg)
+    return;
+  if (Arg->getOption().getID() == OPT_color_diagnostics) {
+    errorHandler().ColorDiagnostics = true;
+  } else if (Arg->getOption().getID() == OPT_no_color_diagnostics) {
+    errorHandler().ColorDiagnostics = false;
+  } else {
+    StringRef S = Arg->getValue();
+    if (S == "always")
+      errorHandler().ColorDiagnostics = true;
+    else if (S == "never")
+      errorHandler().ColorDiagnostics = false;
+    else if (S != "auto")
+      error("unknown option: --color-diagnostics=" + S);
+  }
+}
+
 static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &Args) {
   if (auto *Arg = Args.getLastArg(OPT_rsp_quoting)) {
     StringRef S = Arg->getValue();
@@ -795,6 +821,9 @@
 
   if (MissingCount)
     fatal(Twine(Args.getArgString(MissingIndex)) + ": missing argument");
+
+  handleColorDiagnostics(Args);
+
   for (auto *Arg : Args.filtered(OPT_UNKNOWN))
     warn("ignoring unknown argument: " + Arg->getSpelling());
   return Args;
diff --git a/COFF/ICF.cpp b/COFF/ICF.cpp
index 77c05b7..6297209 100644
--- a/COFF/ICF.cpp
+++ b/COFF/ICF.cpp
@@ -45,6 +45,8 @@
 private:
   void segregate(size_t Begin, size_t End, bool Constant);
 
+  bool assocEquals(const SectionChunk *A, const SectionChunk *B);
+
   bool equalsConstant(const SectionChunk *A, const SectionChunk *B);
   bool equalsVariable(const SectionChunk *A, const SectionChunk *B);
 
@@ -65,8 +67,8 @@
 
 // Returns a hash value for S.
 uint32_t ICF::getHash(SectionChunk *C) {
-  return hash_combine(C->getPermissions(), C->SectionName, C->NumRelocs,
-                      C->Alignment, uint32_t(C->Header->SizeOfRawData),
+  return hash_combine(C->getOutputCharacteristics(), C->SectionName,
+                      C->Relocs.size(), uint32_t(C->Header->SizeOfRawData),
                       C->Checksum, C->getContents());
 }
 
@@ -77,21 +79,27 @@
 // 2017) says that /opt:icf folds both functions and read-only data.
 // Despite that, the MSVC linker folds only functions. We found
 // a few instances of programs that are not safe for data merging.
-// Therefore, we merge only functions just like the MSVC tool. However, we merge
-// identical .xdata sections, because the address of unwind information is
-// insignificant to the user program and the Visual C++ linker does this.
+// Therefore, we merge only functions just like the MSVC tool. However, we also
+// merge read-only sections in a couple of cases where the address of the
+// section is insignificant to the user program and the behaviour matches that
+// of the Visual C++ linker.
 bool ICF::isEligible(SectionChunk *C) {
   // Non-comdat chunks, dead chunks, and writable chunks are not elegible.
-  bool Writable = C->getPermissions() & llvm::COFF::IMAGE_SCN_MEM_WRITE;
+  bool Writable = C->getOutputCharacteristics() & llvm::COFF::IMAGE_SCN_MEM_WRITE;
   if (!C->isCOMDAT() || !C->isLive() || Writable)
     return false;
 
   // Code sections are eligible.
-  if (C->getPermissions() & llvm::COFF::IMAGE_SCN_MEM_EXECUTE)
+  if (C->getOutputCharacteristics() & llvm::COFF::IMAGE_SCN_MEM_EXECUTE)
     return true;
 
-  // .xdata unwind info sections are eligble.
-  return C->getSectionName().split('$').first == ".xdata";
+  // .pdata and .xdata unwind info sections are eligible.
+  StringRef OutSecName = C->getSectionName().split('$').first;
+  if (OutSecName == ".pdata" || OutSecName == ".xdata")
+    return true;
+
+  // So are vtables.
+  return C->Sym && C->Sym->getName().startswith("??_7");
 }
 
 // Split an equivalence class into smaller classes.
@@ -120,10 +128,23 @@
   }
 }
 
+// Returns true if two sections' associative children are equal.
+bool ICF::assocEquals(const SectionChunk *A, const SectionChunk *B) {
+  auto ChildClasses = [&](const SectionChunk *SC) {
+    std::vector<uint32_t> Classes;
+    for (const SectionChunk *C : SC->children())
+      if (!C->SectionName.startswith(".debug") &&
+          C->SectionName != ".gfids$y" && C->SectionName != ".gljmp$y")
+        Classes.push_back(C->Class[Cnt % 2]);
+    return Classes;
+  };
+  return ChildClasses(A) == ChildClasses(B);
+}
+
 // Compare "non-moving" part of two sections, namely everything
 // except relocation targets.
 bool ICF::equalsConstant(const SectionChunk *A, const SectionChunk *B) {
-  if (A->NumRelocs != B->NumRelocs)
+  if (A->Relocs.size() != B->Relocs.size())
     return false;
 
   // Compare relocations.
@@ -146,10 +167,11 @@
     return false;
 
   // Compare section attributes and contents.
-  return A->getPermissions() == B->getPermissions() &&
-         A->SectionName == B->SectionName && A->Alignment == B->Alignment &&
+  return A->getOutputCharacteristics() == B->getOutputCharacteristics() &&
+         A->SectionName == B->SectionName &&
          A->Header->SizeOfRawData == B->Header->SizeOfRawData &&
-         A->Checksum == B->Checksum && A->getContents() == B->getContents();
+         A->Checksum == B->Checksum && A->getContents() == B->getContents() &&
+         assocEquals(A, B);
 }
 
 // Compare "moving" part of two sections, namely relocation targets.
@@ -165,7 +187,9 @@
         return D1->getChunk()->Class[Cnt % 2] == D2->getChunk()->Class[Cnt % 2];
     return false;
   };
-  return std::equal(A->Relocs.begin(), A->Relocs.end(), B->Relocs.begin(), Eq);
+  return std::equal(A->Relocs.begin(), A->Relocs.end(), B->Relocs.begin(),
+                    Eq) &&
+         assocEquals(A, B);
 }
 
 // Find the first Chunk after Begin that has a different class from Begin.
diff --git a/COFF/InputFiles.cpp b/COFF/InputFiles.cpp
index 78bfe34..9e2345b 100644
--- a/COFF/InputFiles.cpp
+++ b/COFF/InputFiles.cpp
@@ -170,8 +170,8 @@
   // CodeView needs a linker support. We need to interpret and debug
   // info, and then write it to a separate .pdb file.
 
-  // Ignore debug info unless /debug is given.
-  if (!Config->Debug && Name.startswith(".debug"))
+  // Ignore DWARF debug info unless /debug is given.
+  if (!Config->Debug && Name.startswith(".debug_"))
     return nullptr;
 
   if (Sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE)
@@ -190,8 +190,8 @@
     GuardLJmpChunks.push_back(C);
   else if (Name == ".sxdata")
     SXDataChunks.push_back(C);
-  else if (Config->DoICF && Sec->NumberOfRelocations == 0 && Name == ".rdata" &&
-           LeaderName.startswith("??_C@"))
+  else if (Config->TailMerge && Sec->NumberOfRelocations == 0 &&
+           Name == ".rdata" && LeaderName.startswith("??_C@"))
     // COFF sections that look like string literal sections (i.e. no
     // relocations, in .rdata, leader symbol name matches the MSVC name mangling
     // for string literals) are subject to string tail merging.
@@ -326,14 +326,13 @@
   if (SectionNumber == llvm::COFF::IMAGE_SYM_DEBUG)
     return nullptr;
 
-  // Reserved sections numbers don't have contents.
   if (llvm::COFF::isReservedSectionNumber(SectionNumber))
-    fatal("broken object file: " + toString(this));
+    fatal(toString(this) + ": " + Name +
+          " should not refer to special section " + Twine(SectionNumber));
 
-  // This symbol references a section which is not present in the section
-  // header.
   if ((uint32_t)SectionNumber >= SparseChunks.size())
-    fatal("broken object file: " + toString(this));
+    fatal(toString(this) + ": " + Name +
+          " should not refer to non-existent section " + Twine(SectionNumber));
 
   // Handle comdat leader symbols.
   if (const coff_aux_section_definition *Def = ComdatDefs[SectionNumber]) {
@@ -465,7 +464,7 @@
     } else {
       Sym = Symtab->addRegular(this, SymName);
     }
-    SymbolBodies.push_back(Sym);
+    Symbols.push_back(Sym);
   }
   Directives = Obj->getCOFFLinkerOpts();
 }
diff --git a/COFF/InputFiles.h b/COFF/InputFiles.h
index 3ee5780..9f4db45 100644
--- a/COFF/InputFiles.h
+++ b/COFF/InputFiles.h
@@ -201,8 +201,7 @@
 // for details about the format.
 class ImportFile : public InputFile {
 public:
-  explicit ImportFile(MemoryBufferRef M)
-      : InputFile(ImportKind, M), Live(!Config->DoGC) {}
+  explicit ImportFile(MemoryBufferRef M) : InputFile(ImportKind, M) {}
 
   static bool classof(const InputFile *F) { return F->kind() == ImportKind; }
 
@@ -221,12 +220,15 @@
   Chunk *Location = nullptr;
 
   // We want to eliminate dllimported symbols if no one actually refers them.
-  // This "Live" bit is used to keep track of which import library members
+  // These "Live" bits are used to keep track of which import library members
   // are actually in use.
   //
   // If the Live bit is turned off by MarkLive, Writer will ignore dllimported
-  // symbols provided by this import library member.
-  bool Live;
+  // symbols provided by this import library member. We also track whether the
+  // imported symbol is used separately from whether the thunk is used in order
+  // to avoid creating unnecessary thunks.
+  bool Live = !Config->DoGC;
+  bool ThunkLive = !Config->DoGC;
 };
 
 // Used for LTO.
@@ -234,7 +236,7 @@
 public:
   explicit BitcodeFile(MemoryBufferRef M) : InputFile(BitcodeKind, M) {}
   static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; }
-  ArrayRef<Symbol *> getSymbols() { return SymbolBodies; }
+  ArrayRef<Symbol *> getSymbols() { return Symbols; }
   MachineTypes getMachineType() override;
   static std::vector<BitcodeFile *> Instances;
   std::unique_ptr<llvm::lto::InputFile> Obj;
@@ -242,7 +244,7 @@
 private:
   void parse() override;
 
-  std::vector<Symbol *> SymbolBodies;
+  std::vector<Symbol *> Symbols;
 };
 } // namespace coff
 
diff --git a/COFF/LTO.cpp b/COFF/LTO.cpp
index 56ca8c0..93f7ba3 100644
--- a/COFF/LTO.cpp
+++ b/COFF/LTO.cpp
@@ -12,6 +12,7 @@
 #include "InputFiles.h"
 #include "Symbols.h"
 #include "lld/Common/ErrorHandler.h"
+#include "lld/Common/Strings.h"
 #include "lld/Common/TargetOptionsCommandFlags.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
@@ -40,53 +41,32 @@
 using namespace lld;
 using namespace lld::coff;
 
-static void diagnosticHandler(const DiagnosticInfo &DI) {
-  SmallString<128> ErrStorage;
-  raw_svector_ostream OS(ErrStorage);
-  DiagnosticPrinterRawOStream DP(OS);
-  DI.print(DP);
-  warn(ErrStorage);
-}
-
-static void checkError(Error E) {
-  handleAllErrors(std::move(E),
-                  [&](ErrorInfoBase &EIB) { error(EIB.message()); });
-}
-
-static void saveBuffer(StringRef Buffer, const Twine &Path) {
-  std::error_code EC;
-  raw_fd_ostream OS(Path.str(), EC, sys::fs::OpenFlags::F_None);
-  if (EC)
-    error("cannot create " + Path + ": " + EC.message());
-  OS << Buffer;
-}
-
 static std::unique_ptr<lto::LTO> createLTO() {
-  lto::Config Conf;
-  Conf.Options = InitTargetOptionsFromCodeGenFlags();
+  lto::Config C;
+  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.
-  Conf.Options.FunctionSections = true;
-  Conf.Options.DataSections = true;
+  C.Options.FunctionSections = true;
+  C.Options.DataSections = true;
 
   // Use static reloc model on 32-bit x86 because it usually results in more
   // compact code, and because there are also known code generation bugs when
   // using the PIC model (see PR34306).
   if (Config->Machine == COFF::IMAGE_FILE_MACHINE_I386)
-    Conf.RelocModel = Reloc::Static;
+    C.RelocModel = Reloc::Static;
   else
-    Conf.RelocModel = Reloc::PIC_;
-  Conf.DisableVerify = true;
-  Conf.DiagHandler = diagnosticHandler;
-  Conf.OptLevel = Config->LTOOptLevel;
+    C.RelocModel = Reloc::PIC_;
+  C.DisableVerify = true;
+  C.DiagHandler = diagnosticHandler;
+  C.OptLevel = Config->LTOO;
   if (Config->SaveTemps)
-    checkError(Conf.addSaveTemps(std::string(Config->OutputFile) + ".",
-                                 /*UseInputModulePath*/ true));
+    checkError(C.addSaveTemps(std::string(Config->OutputFile) + ".",
+                              /*UseInputModulePath*/ true));
   lto::ThinBackend Backend;
-  if (Config->LTOJobs != 0)
-    Backend = lto::createInProcessThinBackend(Config->LTOJobs);
-  return llvm::make_unique<lto::LTO>(std::move(Conf), Backend,
+  if (Config->ThinLTOJobs != 0)
+    Backend = lto::createInProcessThinBackend(Config->ThinLTOJobs);
+  return llvm::make_unique<lto::LTO>(std::move(C), Backend,
                                      Config->LTOPartitions);
 }
 
@@ -125,7 +105,7 @@
 // and return the resulting objects.
 std::vector<StringRef> BitcodeCompiler::compile() {
   unsigned MaxTasks = LTOObj->getMaxTasks();
-  Buff.resize(MaxTasks);
+  Buf.resize(MaxTasks);
   Files.resize(MaxTasks);
 
   // The /lldltocache option specifies the path to a directory in which to cache
@@ -141,7 +121,7 @@
   checkError(LTOObj->run(
       [&](size_t Task) {
         return llvm::make_unique<lto::NativeObjectStream>(
-            llvm::make_unique<raw_svector_ostream>(Buff[Task]));
+            llvm::make_unique<raw_svector_ostream>(Buf[Task]));
       },
       Cache));
 
@@ -150,15 +130,15 @@
 
   std::vector<StringRef> Ret;
   for (unsigned I = 0; I != MaxTasks; ++I) {
-    if (Buff[I].empty())
+    if (Buf[I].empty())
       continue;
     if (Config->SaveTemps) {
       if (I == 0)
-        saveBuffer(Buff[I], Config->OutputFile + ".lto.obj");
+        saveBuffer(Buf[I], Config->OutputFile + ".lto.obj");
       else
-        saveBuffer(Buff[I], Config->OutputFile + Twine(I) + ".lto.obj");
+        saveBuffer(Buf[I], Config->OutputFile + Twine(I) + ".lto.obj");
     }
-    Ret.emplace_back(Buff[I].data(), Buff[I].size());
+    Ret.emplace_back(Buf[I].data(), Buf[I].size());
   }
 
   for (std::unique_ptr<MemoryBuffer> &File : Files)
diff --git a/COFF/LTO.h b/COFF/LTO.h
index a444aa7..f009246 100644
--- a/COFF/LTO.h
+++ b/COFF/LTO.h
@@ -48,7 +48,7 @@
 
 private:
   std::unique_ptr<llvm::lto::LTO> LTOObj;
-  std::vector<SmallString<0>> Buff;
+  std::vector<SmallString<0>> Buf;
   std::vector<std::unique_ptr<MemoryBuffer>> Files;
 };
 }
diff --git a/COFF/MarkLive.cpp b/COFF/MarkLive.cpp
index d5d6ecf..57ae450 100644
--- a/COFF/MarkLive.cpp
+++ b/COFF/MarkLive.cpp
@@ -48,7 +48,7 @@
     else if (auto *Sym = dyn_cast<DefinedImportData>(B))
       Sym->File->Live = true;
     else if (auto *Sym = dyn_cast<DefinedImportThunk>(B))
-      Sym->WrappedSym->File->Live = true;
+      Sym->WrappedSym->File->Live = Sym->WrappedSym->File->ThunkLive = true;
   };
 
   // Add GC root chunks.
diff --git a/COFF/MinGW.cpp b/COFF/MinGW.cpp
index b7a4716..2ca0058 100644
--- a/COFF/MinGW.cpp
+++ b/COFF/MinGW.cpp
@@ -138,7 +138,7 @@
        << "@" << E.Ordinal;
     if (auto *Def = dyn_cast_or_null<Defined>(E.Sym)) {
       if (Def && Def->getChunk() &&
-          !(Def->getChunk()->getPermissions() & IMAGE_SCN_MEM_EXECUTE))
+          !(Def->getChunk()->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE))
         OS << " DATA";
     }
     OS << "\n";
diff --git a/COFF/Options.td b/COFF/Options.td
index 243671d..9051b0b 100644
--- a/COFF/Options.td
+++ b/COFF/Options.td
@@ -20,6 +20,10 @@
 def aligncomm : P<"aligncomm", "Set common symbol alignment">;
 def alternatename : P<"alternatename", "Define weak alias">;
 def base    : P<"base", "Base address of the program">;
+def color_diagnostics: Flag<["--"], "color-diagnostics">,
+  HelpText<"Use colors in diagnostics">;
+def color_diagnostics_eq: Joined<["--"], "color-diagnostics=">,
+  HelpText<"Use colors in diagnostics; one of 'always', 'never', 'auto'">;
 def defaultlib : P<"defaultlib", "Add the library to the list of input files">;
 def delayload : P<"delayload", "Delay loaded DLL name">;
 def entry   : P<"entry", "Name of entry point symbol">;
@@ -46,11 +50,15 @@
 def order   : P<"order", "Put functions in order">;
 def out     : P<"out", "Path to file to write output">;
 def natvis : P<"natvis", "Path to natvis file to embed in the PDB">;
+def no_color_diagnostics: F<"no-color-diagnostics">,
+  HelpText<"Do not use colors in diagnostics">;
 def pdb : P<"pdb", "PDB file path">;
+def pdbaltpath : P<"pdbaltpath", "PDB file path to embed in the image">;
 def section : P<"section", "Specify section attributes">;
 def stack   : P<"stack", "Size of the stack">;
 def stub    : P<"stub", "Specify DOS stub file">;
 def subsystem : P<"subsystem", "Specify subsystem">;
+def timestamp : P<"timestamp", "Specify the PE header timestamp">;
 def version : P<"version", "Specify a version number in the PE header">;
 def wholearchive_file : P<"wholearchive", "Include all object files from this archive">;
 
@@ -75,12 +83,14 @@
     HelpText<"Use module-definition file">;
 
 def debug : F<"debug">, HelpText<"Embed a symbol table in the image">;
+def debug_full : F<"debug:full">, Alias<debug>;
 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 profile : F<"profile">;
+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">;
@@ -107,7 +117,10 @@
                        "Disable 64-bit ASLR">;
 defm incremental : B<"incremental",
                      "Keep original import library if contents are unchanged",
-                     "Replace import library file even if contents are unchanged">;
+                     "Overwrite import library even if contents are unchanged">;
+defm integritycheck : B<"integritycheck",
+                        "Set FORCE_INTEGRITY bit in PE header",
+                        "No effect (default)">;
 defm largeaddressaware : B<"largeaddressaware",
                            "Enable large addresses (default on 64-bit)",
                            "Disable large addresses (default on 32-bit)">;
@@ -163,7 +176,6 @@
 def errorreport : QF<"errorreport">;
 def idlout : QF<"idlout">;
 def maxilksize : QF<"maxilksize">;
-def pdbaltpath : QF<"pdbaltpath">;
 def tlbid : QF<"tlbid">;
 def tlbout : QF<"tlbout">;
 def verbose_all : QF<"verbose">;
diff --git a/COFF/PDB.cpp b/COFF/PDB.cpp
index 91131c6..6dc2cdd 100644
--- a/COFF/PDB.cpp
+++ b/COFF/PDB.cpp
@@ -125,9 +125,6 @@
   void addSections(ArrayRef<OutputSection *> OutputSections,
                    ArrayRef<uint8_t> SectionTable);
 
-  void addSectionContrib(pdb::DbiModuleDescriptorBuilder &LinkerModule,
-                         OutputSection *OS, Chunk *C);
-
   /// Write the PDB to disk.
   void commit();
 
@@ -208,8 +205,8 @@
   DebugH = DebugH.drop_front(sizeof(object::debug_h_header));
   return Header->Magic == COFF::DEBUG_HASHES_SECTION_MAGIC &&
          Header->Version == 0 &&
-         Header->HashAlgorithm == uint16_t(GlobalTypeHashAlg::SHA1) &&
-         (DebugH.size() % 20 == 0);
+         Header->HashAlgorithm == uint16_t(GlobalTypeHashAlg::SHA1_8) &&
+         (DebugH.size() % 8 == 0);
 }
 
 static Optional<ArrayRef<uint8_t>> getDebugH(ObjFile *File) {
@@ -780,6 +777,32 @@
                            ".debug$S");
 }
 
+static pdb::SectionContrib createSectionContrib(const Chunk *C, uint32_t Modi) {
+  OutputSection *OS = C->getOutputSection();
+  pdb::SectionContrib SC;
+  memset(&SC, 0, sizeof(SC));
+  SC.ISect = OS->SectionIndex;
+  SC.Off = C->getRVA() - OS->getRVA();
+  SC.Size = C->getSize();
+  if (auto *SecChunk = dyn_cast<SectionChunk>(C)) {
+    SC.Characteristics = SecChunk->Header->Characteristics;
+    SC.Imod = SecChunk->File->ModuleDBI->getModuleIndex();
+    ArrayRef<uint8_t> Contents = SecChunk->getContents();
+    JamCRC CRC(0);
+    ArrayRef<char> CharContents = makeArrayRef(
+        reinterpret_cast<const char *>(Contents.data()), Contents.size());
+    CRC.update(CharContents);
+    SC.DataCrc = CRC.getCRC();
+  } else {
+    SC.Characteristics = OS->Header.Characteristics;
+    // FIXME: When we start creating DBI for import libraries, use those here.
+    SC.Imod = Modi;
+  }
+  SC.RelocCrc = 0; // FIXME
+
+  return SC;
+}
+
 void PDBLinker::addObjFile(ObjFile *File) {
   // Add a module descriptor for every object file. We need to put an absolute
   // path to the object into the PDB. If this is a plain object, we make its
@@ -794,6 +817,17 @@
   File->ModuleDBI = &ExitOnErr(Builder.getDbiBuilder().addModuleInfo(Name));
   File->ModuleDBI->setObjFileName(Path);
 
+  auto Chunks = File->getChunks();
+  uint32_t Modi = File->ModuleDBI->getModuleIndex();
+  for (Chunk *C : Chunks) {
+    auto *SecChunk = dyn_cast<SectionChunk>(C);
+    if (!SecChunk || !SecChunk->isLive())
+      continue;
+    pdb::SectionContrib SC = createSectionContrib(SecChunk, Modi);
+    File->ModuleDBI->setFirstSectionContrib(SC);
+    break;
+  }
+
   // Before we can process symbol substreams from .debug$S, we need to process
   // type information, file checksums, and the string table.  Add type info to
   // the PDB first, so that we can get the map from object file type and item
@@ -832,9 +866,6 @@
     for (const DebugSubsectionRecord &SS : Subsections) {
       switch (SS.kind()) {
       case DebugSubsectionKind::StringTable: {
-        auto Data = SS.getRecordData();
-        ArrayRef<uint8_t> Buffer;
-        cantFail(Data.readLongestContiguousChunk(0, Buffer));
         assert(!CVStrTab.valid() &&
                "Encountered multiple string table subsections!");
         ExitOnErr(CVStrTab.initialize(SS.getRecordData()));
@@ -981,6 +1012,23 @@
   }
 }
 
+static codeview::CPUType toCodeViewMachine(COFF::MachineTypes Machine) {
+  switch (Machine) {
+  case COFF::IMAGE_FILE_MACHINE_AMD64:
+    return codeview::CPUType::X64;
+  case COFF::IMAGE_FILE_MACHINE_ARM:
+    return codeview::CPUType::ARM7;
+  case COFF::IMAGE_FILE_MACHINE_ARM64:
+    return codeview::CPUType::ARM64;
+  case COFF::IMAGE_FILE_MACHINE_ARMNT:
+    return codeview::CPUType::ARMNT;
+  case COFF::IMAGE_FILE_MACHINE_I386:
+    return codeview::CPUType::Intel80386;
+  default:
+    llvm_unreachable("Unsupported CPU Type");
+  }
+}
+
 static void addCommonLinkerModuleSymbols(StringRef Path,
                                          pdb::DbiModuleDescriptorBuilder &Mod,
                                          BumpPtrAllocator &Allocator) {
@@ -991,7 +1039,7 @@
   ONS.Name = "* Linker *";
   ONS.Signature = 0;
 
-  CS.Machine = Config->is64() ? CPUType::X64 : CPUType::Intel80386;
+  CS.Machine = toCodeViewMachine(Config->Machine);
   // Interestingly, if we set the string to 0.0.0.0, then when trying to view
   // local variables WinDbg emits an error that private symbols are not present.
   // By setting this to a valid MSVC linker version string, local variables are
@@ -1042,7 +1090,7 @@
                                          BumpPtrAllocator &Allocator) {
   SectionSym Sym(SymbolRecordKind::SectionSym);
   Sym.Alignment = 12; // 2^12 = 4KB
-  Sym.Characteristics = OS.getCharacteristics();
+  Sym.Characteristics = OS.Header.Characteristics;
   Sym.Length = OS.getVirtualSize();
   Sym.Name = OS.Name;
   Sym.Rva = OS.getRVA();
@@ -1088,31 +1136,12 @@
   pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
   DbiBuilder.setAge(BuildId.PDB70.Age);
   DbiBuilder.setVersionHeader(pdb::PdbDbiV70);
-}
-
-void PDBLinker::addSectionContrib(pdb::DbiModuleDescriptorBuilder &LinkerModule,
-                                  OutputSection *OS, Chunk *C) {
-  pdb::SectionContrib SC;
-  memset(&SC, 0, sizeof(SC));
-  SC.ISect = OS->SectionIndex;
-  SC.Off = C->getRVA() - OS->getRVA();
-  SC.Size = C->getSize();
-  if (auto *SecChunk = dyn_cast<SectionChunk>(C)) {
-    SC.Characteristics = SecChunk->Header->Characteristics;
-    SC.Imod = SecChunk->File->ModuleDBI->getModuleIndex();
-    ArrayRef<uint8_t> Contents = SecChunk->getContents();
-    JamCRC CRC(0);
-    ArrayRef<char> CharContents = makeArrayRef(
-        reinterpret_cast<const char *>(Contents.data()), Contents.size());
-    CRC.update(CharContents);
-    SC.DataCrc = CRC.getCRC();
-  } else {
-    SC.Characteristics = OS->getCharacteristics();
-    // FIXME: When we start creating DBI for import libraries, use those here.
-    SC.Imod = LinkerModule.getModuleIndex();
-  }
-  SC.RelocCrc = 0; // FIXME
-  Builder.getDbiBuilder().addSectionContrib(SC);
+  DbiBuilder.setMachineType(Config->Machine);
+  // Technically we are not link.exe 14.11, but there are known cases where
+  // debugging tools on Windows expect Microsoft-specific version numbers or
+  // they fail to work at all.  Since we know we produce PDBs that are
+  // compatible with LINK 14.11, we set that version number here.
+  DbiBuilder.setBuildNumber(14, 11);
 }
 
 void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections,
@@ -1130,8 +1159,11 @@
   // Add section contributions. They must be ordered by ascending RVA.
   for (OutputSection *OS : OutputSections) {
     addLinkerModuleSectionSymbol(LinkerModule, *OS, Alloc);
-    for (Chunk *C : OS->getChunks())
-      addSectionContrib(LinkerModule, OS, C);
+    for (Chunk *C : OS->getChunks()) {
+      pdb::SectionContrib SC =
+          createSectionContrib(C, LinkerModule.getModuleIndex());
+      Builder.getDbiBuilder().addSectionContrib(SC);
+    }
   }
 
   // Add Section Map stream.
@@ -1150,3 +1182,145 @@
   // Write to a file.
   ExitOnErr(Builder.commit(Config->PDBPath));
 }
+
+static Expected<StringRef>
+getFileName(const DebugStringTableSubsectionRef &Strings,
+            const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID) {
+  auto Iter = Checksums.getArray().at(FileID);
+  if (Iter == Checksums.getArray().end())
+    return make_error<CodeViewError>(cv_error_code::no_records);
+  uint32_t Offset = Iter->FileNameOffset;
+  return Strings.getString(Offset);
+}
+
+static uint32_t getSecrelReloc() {
+  switch (Config->Machine) {
+  case AMD64:
+    return COFF::IMAGE_REL_AMD64_SECREL;
+  case I386:
+    return COFF::IMAGE_REL_I386_SECREL;
+  case ARMNT:
+    return COFF::IMAGE_REL_ARM_SECREL;
+  case ARM64:
+    return COFF::IMAGE_REL_ARM64_SECREL;
+  default:
+    llvm_unreachable("unknown machine type");
+  }
+}
+
+// Try to find a line table for the given offset Addr into the given chunk C.
+// If a line table was found, the line table, the string and checksum tables
+// that are used to interpret the line table, and the offset of Addr in the line
+// table are stored in the output arguments. Returns whether a line table was
+// found.
+static bool findLineTable(const SectionChunk *C, uint32_t Addr,
+                          DebugStringTableSubsectionRef &CVStrTab,
+                          DebugChecksumsSubsectionRef &Checksums,
+                          DebugLinesSubsectionRef &Lines,
+                          uint32_t &OffsetInLinetable) {
+  ExitOnError ExitOnErr;
+  uint32_t SecrelReloc = getSecrelReloc();
+
+  for (SectionChunk *DbgC : C->File->getDebugChunks()) {
+    if (DbgC->getSectionName() != ".debug$S")
+      continue;
+
+    // Build a mapping of SECREL relocations in DbgC that refer to C.
+    DenseMap<uint32_t, uint32_t> Secrels;
+    for (const coff_relocation &R : DbgC->Relocs) {
+      if (R.Type != SecrelReloc)
+        continue;
+
+      if (auto *S = dyn_cast_or_null<DefinedRegular>(
+              C->File->getSymbols()[R.SymbolTableIndex]))
+        if (S->getChunk() == C)
+          Secrels[R.VirtualAddress] = S->getValue();
+    }
+
+    ArrayRef<uint8_t> Contents =
+        consumeDebugMagic(DbgC->getContents(), ".debug$S");
+    DebugSubsectionArray Subsections;
+    BinaryStreamReader Reader(Contents, support::little);
+    ExitOnErr(Reader.readArray(Subsections, Contents.size()));
+
+    for (const DebugSubsectionRecord &SS : Subsections) {
+      switch (SS.kind()) {
+      case DebugSubsectionKind::StringTable: {
+        assert(!CVStrTab.valid() &&
+               "Encountered multiple string table subsections!");
+        ExitOnErr(CVStrTab.initialize(SS.getRecordData()));
+        break;
+      }
+      case DebugSubsectionKind::FileChecksums:
+        assert(!Checksums.valid() &&
+               "Encountered multiple checksum subsections!");
+        ExitOnErr(Checksums.initialize(SS.getRecordData()));
+        break;
+      case DebugSubsectionKind::Lines: {
+        ArrayRef<uint8_t> Bytes;
+        auto Ref = SS.getRecordData();
+        ExitOnErr(Ref.readLongestContiguousChunk(0, Bytes));
+        size_t OffsetInDbgC = Bytes.data() - DbgC->getContents().data();
+
+        // Check whether this line table refers to C.
+        auto I = Secrels.find(OffsetInDbgC);
+        if (I == Secrels.end())
+          break;
+
+        // Check whether this line table covers Addr in C.
+        DebugLinesSubsectionRef LinesTmp;
+        ExitOnErr(LinesTmp.initialize(BinaryStreamReader(Ref)));
+        uint32_t OffsetInC = I->second + LinesTmp.header()->RelocOffset;
+        if (Addr < OffsetInC || Addr >= OffsetInC + LinesTmp.header()->CodeSize)
+          break;
+
+        assert(!Lines.header() &&
+               "Encountered multiple line tables for function!");
+        ExitOnErr(Lines.initialize(BinaryStreamReader(Ref)));
+        OffsetInLinetable = Addr - OffsetInC;
+        break;
+      }
+      default:
+        break;
+      }
+
+      if (CVStrTab.valid() && Checksums.valid() && Lines.header())
+        return true;
+    }
+  }
+
+  return false;
+}
+
+// Use CodeView line tables to resolve a file and line number for the given
+// offset into the given chunk and return them, or {"", 0} if a line table was
+// not found.
+std::pair<StringRef, uint32_t> coff::getFileLine(const SectionChunk *C,
+                                                 uint32_t Addr) {
+  ExitOnError ExitOnErr;
+
+  DebugStringTableSubsectionRef CVStrTab;
+  DebugChecksumsSubsectionRef Checksums;
+  DebugLinesSubsectionRef Lines;
+  uint32_t OffsetInLinetable;
+
+  if (!findLineTable(C, Addr, CVStrTab, Checksums, Lines, OffsetInLinetable))
+    return {"", 0};
+
+  uint32_t NameIndex;
+  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);
+      NameIndex = Entry.NameIndex;
+      LineNumber = LI.getStartLine();
+    }
+  }
+  StringRef Filename = ExitOnErr(getFileName(CVStrTab, Checksums, NameIndex));
+  return {Filename, LineNumber};
+}
diff --git a/COFF/PDB.h b/COFF/PDB.h
index defd7d2..a98d129 100644
--- a/COFF/PDB.h
+++ b/COFF/PDB.h
@@ -22,12 +22,16 @@
 namespace lld {
 namespace coff {
 class OutputSection;
+class SectionChunk;
 class SymbolTable;
 
 void createPDB(SymbolTable *Symtab,
                llvm::ArrayRef<OutputSection *> OutputSections,
                llvm::ArrayRef<uint8_t> SectionTable,
                const llvm::codeview::DebugInfo &BuildId);
+
+std::pair<llvm::StringRef, uint32_t> getFileLine(const SectionChunk *C,
+                                                 uint32_t Addr);
 }
 }
 
diff --git a/COFF/SymbolTable.cpp b/COFF/SymbolTable.cpp
index 32420df..6b07c35 100644
--- a/COFF/SymbolTable.cpp
+++ b/COFF/SymbolTable.cpp
@@ -11,6 +11,7 @@
 #include "Config.h"
 #include "Driver.h"
 #include "LTO.h"
+#include "PDB.h"
 #include "Symbols.h"
 #include "lld/Common/ErrorHandler.h"
 #include "lld/Common/Memory.h"
@@ -37,8 +38,9 @@
   if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) {
     Config->Machine = MT;
   } else if (MT != IMAGE_FILE_MACHINE_UNKNOWN && Config->Machine != MT) {
-    fatal(toString(File) + ": machine type " + machineToStr(MT) +
+    error(toString(File) + ": machine type " + machineToStr(MT) +
           " conflicts with " + machineToStr(Config->Machine));
+    return;
   }
 
   if (auto *F = dyn_cast<ObjFile>(File)) {
@@ -64,6 +66,66 @@
     error(S);
 }
 
+// Returns the name of the symbol in SC whose value is <= Addr that is closest
+// to Addr. This is generally the name of the global variable or function whose
+// definition contains Addr.
+static StringRef getSymbolName(SectionChunk *SC, uint32_t Addr) {
+  DefinedRegular *Candidate = nullptr;
+
+  for (Symbol *S : SC->File->getSymbols()) {
+    auto *D = dyn_cast_or_null<DefinedRegular>(S);
+    if (!D || D->getChunk() != SC || D->getValue() > Addr ||
+        (Candidate && D->getValue() < Candidate->getValue()))
+      continue;
+
+    Candidate = D;
+  }
+
+  if (!Candidate)
+    return "";
+  return Candidate->getName();
+}
+
+static std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex) {
+  struct Location {
+    StringRef SymName;
+    std::pair<StringRef, uint32_t> FileLine;
+  };
+  std::vector<Location> Locations;
+
+  for (Chunk *C : File->getChunks()) {
+    auto *SC = dyn_cast<SectionChunk>(C);
+    if (!SC)
+      continue;
+    for (const coff_relocation &R : SC->Relocs) {
+      if (R.SymbolTableIndex != SymIndex)
+        continue;
+      std::pair<StringRef, uint32_t> FileLine =
+          getFileLine(SC, R.VirtualAddress);
+      StringRef SymName = getSymbolName(SC, R.VirtualAddress);
+      if (!FileLine.first.empty() || !SymName.empty())
+        Locations.push_back({SymName, FileLine});
+    }
+  }
+
+  if (Locations.empty())
+    return "\n>>> referenced by " + toString(File) + "\n";
+
+  std::string Out;
+  llvm::raw_string_ostream OS(Out);
+  for (Location Loc : Locations) {
+    OS << "\n>>> referenced by ";
+    if (!Loc.FileLine.first.empty())
+      OS << Loc.FileLine.first << ":" << Loc.FileLine.second
+         << "\n>>>               ";
+    OS << toString(File);
+    if (!Loc.SymName.empty())
+      OS << ":(" << Loc.SymName << ')';
+  }
+  OS << '\n';
+  return OS.str();
+}
+
 void SymbolTable::reportRemainingUndefines() {
   SmallPtrSet<Symbol *, 8> Undefs;
   DenseMap<Symbol *, Symbol *> LocalImports;
@@ -127,11 +189,14 @@
   }
 
   for (ObjFile *File : ObjFile::Instances) {
+    size_t SymIndex = -1ull;
     for (Symbol *Sym : File->getSymbols()) {
+      ++SymIndex;
       if (!Sym)
         continue;
       if (Undefs.count(Sym))
-        errorOrWarn(toString(File) + ": undefined symbol: " + Sym->getName());
+        errorOrWarn("undefined symbol: " + Sym->getName() +
+                    getSymbolLocations(File, SymIndex));
       if (Config->WarnLocallyDefinedImported)
         if (Symbol *Imp = LocalImports.lookup(Sym))
           warn(toString(File) + ": locally defined symbol imported: " +
diff --git a/COFF/Symbols.cpp b/COFF/Symbols.cpp
index fedb337..7c8b7d5 100644
--- a/COFF/Symbols.cpp
+++ b/COFF/Symbols.cpp
@@ -58,7 +58,7 @@
   if (auto *Imp = dyn_cast<DefinedImportData>(this))
     return Imp->File->Live;
   if (auto *Imp = dyn_cast<DefinedImportThunk>(this))
-    return Imp->WrappedSym->File->Live;
+    return Imp->WrappedSym->File->ThunkLive;
   // Assume any other kind of symbol is live.
   return true;
 }
diff --git a/COFF/Writer.cpp b/COFF/Writer.cpp
index 6f173de..dff87c5 100644
--- a/COFF/Writer.cpp
+++ b/COFF/Writer.cpp
@@ -121,14 +121,8 @@
 
 class CVDebugRecordChunk : public Chunk {
 public:
-  CVDebugRecordChunk() {
-    PDBAbsPath = Config->PDBPath;
-    if (!PDBAbsPath.empty())
-      llvm::sys::fs::make_absolute(PDBAbsPath);
-  }
-
   size_t getSize() const override {
-    return sizeof(codeview::DebugInfo) + PDBAbsPath.size() + 1;
+    return sizeof(codeview::DebugInfo) + Config->PDBAltPath.size() + 1;
   }
 
   void writeTo(uint8_t *B) const override {
@@ -138,12 +132,11 @@
 
     // variable sized field (PDB Path)
     char *P = reinterpret_cast<char *>(B + OutputSectionOff + sizeof(*BuildId));
-    if (!PDBAbsPath.empty())
-      memcpy(P, PDBAbsPath.data(), PDBAbsPath.size());
-    P[PDBAbsPath.size()] = '\0';
+    if (!Config->PDBAltPath.empty())
+      memcpy(P, Config->PDBAltPath.data(), Config->PDBAltPath.size());
+    P[Config->PDBAltPath.size()] = '\0';
   }
 
-  SmallString<128> PDBAbsPath;
   mutable codeview::DebugInfo *BuildId = nullptr;
 };
 
@@ -158,19 +151,19 @@
   void createMiscChunks();
   void createImportTables();
   void createExportTable();
+  void mergeSections();
   void assignAddresses();
   void removeEmptySections();
   void createSymbolAndStringTable();
   void openFile(StringRef OutputPath);
   template <typename PEHeaderTy> void writeHeader();
-  void createSEHTable(OutputSection *RData);
-  void createGuardCFTables(OutputSection *RData);
-  void createGLJmpTable(OutputSection *RData);
+  void createSEHTable();
+  void createGuardCFTables();
   void markSymbolsForRVATable(ObjFile *File,
                               ArrayRef<SectionChunk *> SymIdxChunks,
                               SymbolRVASet &TableSymbols);
-  void maybeAddRVATable(OutputSection *RData, SymbolRVASet TableSymbols,
-                        StringRef TableSym, StringRef CountSym);
+  void maybeAddRVATable(SymbolRVASet TableSymbols, StringRef TableSym,
+                        StringRef CountSym);
   void setSectionPermissions();
   void writeSections();
   void writeBuildId();
@@ -180,9 +173,8 @@
   size_t addEntryToStringTable(StringRef Str);
 
   OutputSection *findSection(StringRef Name);
-  OutputSection *createSection(StringRef Name);
-  void addBaserels(OutputSection *Dest);
-  void addBaserelBlocks(OutputSection *Dest, std::vector<Baserel> &V);
+  void addBaserels();
+  void addBaserelBlocks(std::vector<Baserel> &V);
 
   uint32_t getSizeOfInitializedData();
   std::map<StringRef, std::vector<DefinedImportData *>> binImports();
@@ -194,8 +186,7 @@
   IdataContents Idata;
   DelayLoadContents DelayIdata;
   EdataContents Edata;
-  RVATableChunk *GuardFidsTable = nullptr;
-  RVATableChunk *SEHTable = nullptr;
+  bool SetNoSEHCharacteristic = false;
 
   DebugDirectoryChunk *DebugDirectory = nullptr;
   std::vector<Chunk *> DebugRecords;
@@ -207,6 +198,28 @@
   uint32_t PointerToSymbolTable = 0;
   uint64_t SizeOfImage;
   uint64_t SizeOfHeaders;
+
+  OutputSection *TextSec;
+  OutputSection *RdataSec;
+  OutputSection *DataSec;
+  OutputSection *PdataSec;
+  OutputSection *IdataSec;
+  OutputSection *EdataSec;
+  OutputSection *DidatSec;
+  OutputSection *RsrcSec;
+  OutputSection *RelocSec;
+
+  // The first and last .pdata sections in the output file.
+  //
+  // We need to keep track of the location of .pdata in whichever section it
+  // gets merged into so that we can sort its contents and emit a correct data
+  // directory entry for the exception table. This is also the case for some
+  // other sections (such as .edata) but because the contents of those sections
+  // are entirely linker-generated we can keep track of their locations using
+  // the chunks that the linker creates. All .pdata chunks come from input
+  // files, so we need to keep track of them separately.
+  Chunk *FirstPdata = nullptr;
+  Chunk *LastPdata;
 };
 } // anonymous namespace
 
@@ -223,12 +236,16 @@
   C->setOutputSection(this);
 }
 
-void OutputSection::addPermissions(uint32_t C) {
-  Header.Characteristics |= C & PermMask;
+void OutputSection::setPermissions(uint32_t C) {
+  Header.Characteristics &= ~PermMask;
+  Header.Characteristics |= C;
 }
 
-void OutputSection::setPermissions(uint32_t C) {
-  Header.Characteristics = C & PermMask;
+void OutputSection::merge(OutputSection *Other) {
+  for (Chunk *C : Other->Chunks)
+    C->setOutputSection(this);
+  Chunks.insert(Chunks.end(), Other->Chunks.begin(), Other->Chunks.end());
+  Other->Chunks.clear();
 }
 
 // Write the section header to a given buffer.
@@ -318,8 +335,7 @@
   createMiscChunks();
   createImportTables();
   createExportTable();
-  if (Config->Relocatable)
-    createSection(".reloc");
+  mergeSections();
   assignAddresses();
   removeEmptySections();
   setSectionPermissions();
@@ -356,17 +372,12 @@
     fatal("failed to write the output file: " + toString(std::move(E)));
 }
 
-static StringRef getOutputSection(StringRef Name) {
+static StringRef getOutputSectionName(StringRef Name) {
   StringRef S = Name.split('$').first;
 
   // Treat a later period as a separator for MinGW, for sections like
   // ".ctors.01234".
-  S = S.substr(0, S.find('.', 1));
-
-  auto It = Config->Merge.find(S);
-  if (It == Config->Merge.end())
-    return S;
-  return It->second;
+  return S.substr(0, S.find('.', 1));
 }
 
 // For /order.
@@ -386,8 +397,39 @@
 
 // Create output section objects and add them to OutputSections.
 void Writer::createSections() {
-  // First, bin chunks by name.
-  std::map<StringRef, std::vector<Chunk *>> Map;
+  // First, create the builtin sections.
+  const uint32_t DATA = IMAGE_SCN_CNT_INITIALIZED_DATA;
+  const uint32_t BSS = IMAGE_SCN_CNT_UNINITIALIZED_DATA;
+  const uint32_t CODE = IMAGE_SCN_CNT_CODE;
+  const uint32_t DISCARDABLE = IMAGE_SCN_MEM_DISCARDABLE;
+  const uint32_t R = IMAGE_SCN_MEM_READ;
+  const uint32_t W = IMAGE_SCN_MEM_WRITE;
+  const uint32_t X = IMAGE_SCN_MEM_EXECUTE;
+
+  SmallDenseMap<std::pair<StringRef, uint32_t>, OutputSection *> Sections;
+  auto CreateSection = [&](StringRef Name, uint32_t OutChars) {
+    OutputSection *&Sec = Sections[{Name, OutChars}];
+    if (!Sec) {
+      Sec = make<OutputSection>(Name, OutChars);
+      OutputSections.push_back(Sec);
+    }
+    return Sec;
+  };
+
+  // Try to match the section order used by link.exe.
+  TextSec = CreateSection(".text", CODE | R | X);
+  CreateSection(".bss", BSS | R | W);
+  RdataSec = CreateSection(".rdata", DATA | R);
+  DataSec = CreateSection(".data", DATA | R | W);
+  PdataSec = CreateSection(".pdata", DATA | R);
+  IdataSec = CreateSection(".idata", DATA | R);
+  EdataSec = CreateSection(".edata", DATA | R);
+  DidatSec = CreateSection(".didat", DATA | R);
+  RsrcSec = CreateSection(".rsrc", DATA | R);
+  RelocSec = CreateSection(".reloc", DATA | DISCARDABLE | R);
+
+  // 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->isLive()) {
@@ -395,7 +437,7 @@
         SC->printDiscardedMessage();
       continue;
     }
-    Map[C->getSectionName()].push_back(C);
+    Map[{C->getSectionName(), C->getOutputCharacteristics()}].push_back(C);
   }
 
   // Process an /order option.
@@ -407,32 +449,54 @@
   // '$' 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.
-  SmallDenseMap<StringRef, OutputSection *> Sections;
   for (auto Pair : Map) {
-    StringRef Name = getOutputSection(Pair.first);
-    OutputSection *&Sec = Sections[Name];
-    if (!Sec) {
-      Sec = make<OutputSection>(Name);
-      OutputSections.push_back(Sec);
-    }
+    StringRef Name = getOutputSectionName(Pair.first.first);
+    uint32_t OutChars = Pair.first.second;
+
+    // In link.exe, there is a special case for the I386 target where .CRT
+    // sections are treated as if they have output characteristics DATA | R if
+    // their characteristics are DATA | R | W. This implements the same special
+    // case for all architectures.
+    if (Name == ".CRT")
+      OutChars = DATA | R;
+
+    OutputSection *Sec = CreateSection(Name, OutChars);
     std::vector<Chunk *> &Chunks = Pair.second;
-    for (Chunk *C : Chunks) {
+    for (Chunk *C : Chunks)
       Sec->addChunk(C);
-      Sec->addPermissions(C->getPermissions());
-    }
   }
+
+  // Finally, move some output sections to the end.
+  auto SectionOrder = [&](OutputSection *S) {
+    // .reloc should come last of all since it refers to RVAs of data in the
+    // previous sections.
+    if (S == RelocSec)
+      return 3;
+    // Move DISCARDABLE (or non-memory-mapped) sections to the end of file because
+    // the loader cannot handle holes.
+    if (S->Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
+      return 2;
+    // .rsrc should come at the end of the non-discardable sections because its
+    // size may change by the Win32 UpdateResources() function, causing
+    // subsequent sections to move (see https://crbug.com/827082).
+    if (S == RsrcSec)
+      return 1;
+    return 0;
+  };
+  std::stable_sort(OutputSections.begin(), OutputSections.end(),
+                   [&](OutputSection *S, OutputSection *T) {
+                     return SectionOrder(S) < SectionOrder(T);
+                   });
 }
 
 void Writer::createMiscChunks() {
-  OutputSection *RData = createSection(".rdata");
-
   for (auto &P : MergeChunk::Instances)
-    RData->addChunk(P.second);
+    RdataSec->addChunk(P.second);
 
   // Create thunks for locally-dllimported symbols.
   if (!Symtab->LocalImportChunks.empty()) {
     for (Chunk *C : Symtab->LocalImportChunks)
-      RData->addChunk(C);
+      RdataSec->addChunk(C);
   }
 
   // Create Debug Information Chunks
@@ -447,18 +511,18 @@
     BuildId = CVChunk;
     DebugRecords.push_back(CVChunk);
 
-    RData->addChunk(DebugDirectory);
+    RdataSec->addChunk(DebugDirectory);
     for (Chunk *C : DebugRecords)
-      RData->addChunk(C);
+      RdataSec->addChunk(C);
   }
 
   // Create SEH table. x86-only.
   if (Config->Machine == I386)
-    createSEHTable(RData);
+    createSEHTable();
 
   // Create /guard:cf tables if requested.
   if (Config->GuardCF != GuardCFLevel::Off)
-    createGuardCFTables(RData);
+    createGuardCFTables();
 }
 
 // Create .idata section for the DLL-imported symbol table.
@@ -479,15 +543,10 @@
     std::string DLL = StringRef(File->DLLName).lower();
     if (Config->DLLOrder.count(DLL) == 0)
       Config->DLLOrder[DLL] = Config->DLLOrder.size();
-  }
-
-  OutputSection *Text = createSection(".text");
-  for (ImportFile *File : ImportFile::Instances) {
-    if (!File->Live)
-      continue;
 
     if (DefinedImportThunk *Thunk = File->ThunkSym)
-      Text->addChunk(Thunk->getChunk());
+      if (File->ThunkLive)
+        TextSec->addChunk(Thunk->getChunk());
 
     if (Config->DelayLoads.count(StringRef(File->DLLName).lower())) {
       if (!File->ThunkSym)
@@ -499,33 +558,27 @@
     }
   }
 
-  if (!Idata.empty()) {
-    OutputSection *Sec = createSection(".idata");
+  if (!Idata.empty())
     for (Chunk *C : Idata.getChunks())
-      Sec->addChunk(C);
-  }
+      IdataSec->addChunk(C);
 
   if (!DelayIdata.empty()) {
     Defined *Helper = cast<Defined>(Config->DelayLoadHelper);
     DelayIdata.create(Helper);
-    OutputSection *Sec = createSection(".didat");
     for (Chunk *C : DelayIdata.getChunks())
-      Sec->addChunk(C);
-    Sec = createSection(".data");
+      DidatSec->addChunk(C);
     for (Chunk *C : DelayIdata.getDataChunks())
-      Sec->addChunk(C);
-    Sec = createSection(".text");
+      DataSec->addChunk(C);
     for (Chunk *C : DelayIdata.getCodeChunks())
-      Sec->addChunk(C);
+      TextSec->addChunk(C);
   }
 }
 
 void Writer::createExportTable() {
   if (Config->Exports.empty())
     return;
-  OutputSection *Sec = createSection(".edata");
   for (Chunk *C : Edata.Chunks)
-    Sec->addChunk(C);
+    EdataSec->addChunk(C);
 }
 
 // The Windows loader doesn't seem to like empty sections,
@@ -549,19 +602,28 @@
 }
 
 Optional<coff_symbol16> Writer::createSymbol(Defined *Def) {
-  // Relative symbols are unrepresentable in a COFF symbol table.
-  if (isa<DefinedSynthetic>(Def))
+  coff_symbol16 Sym;
+  switch (Def->kind()) {
+  case Symbol::DefinedAbsoluteKind:
+    Sym.Value = Def->getRVA();
+    Sym.SectionNumber = IMAGE_SYM_ABSOLUTE;
+    break;
+  case Symbol::DefinedSyntheticKind:
+    // Relative symbols are unrepresentable in a COFF symbol table.
     return None;
-
-  // Don't write dead symbols or symbols in codeview sections to the symbol
-  // table.
-  if (!Def->isLive())
-    return None;
-  if (auto *D = dyn_cast<DefinedRegular>(Def))
-    if (D->getChunk()->isCodeView())
+  default: {
+    // Don't write symbols that won't be written to the output to the symbol
+    // table.
+    OutputSection *OS = Def->getChunk()->getOutputSection();
+    if (!OS)
       return None;
 
-  coff_symbol16 Sym;
+    Sym.Value = Def->getRVA() - OS->getRVA();
+    Sym.SectionNumber = OS->SectionIndex;
+    break;
+  }
+  }
+
   StringRef Name = Def->getName();
   if (Name.size() > COFF::NameSize) {
     Sym.Name.Offset.Zeroes = 0;
@@ -580,25 +642,6 @@
     Sym.StorageClass = IMAGE_SYM_CLASS_EXTERNAL;
   }
   Sym.NumberOfAuxSymbols = 0;
-
-  switch (Def->kind()) {
-  case Symbol::DefinedAbsoluteKind:
-    Sym.Value = Def->getRVA();
-    Sym.SectionNumber = IMAGE_SYM_ABSOLUTE;
-    break;
-  default: {
-    uint64_t RVA = Def->getRVA();
-    OutputSection *Sec = nullptr;
-    for (OutputSection *S : OutputSections) {
-      if (S->getRVA() > RVA)
-        break;
-      Sec = S;
-    }
-    Sym.Value = RVA - Sec->getRVA();
-    Sym.SectionNumber = Sec->SectionIndex;
-    break;
-  }
-  }
   return Sym;
 }
 
@@ -614,7 +657,7 @@
   for (OutputSection *Sec : OutputSections) {
     if (Sec->Name.size() <= COFF::NameSize)
       continue;
-    if ((Sec->getPermissions() & IMAGE_SCN_MEM_DISCARDABLE) == 0)
+    if ((Sec->Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0)
       continue;
     Sec->setStringTableOff(addEntryToStringTable(Sec->Name));
   }
@@ -644,6 +687,37 @@
   FileSize = alignTo(FileOff, SectorSize);
 }
 
+void Writer::mergeSections() {
+  if (!PdataSec->getChunks().empty()) {
+    FirstPdata = PdataSec->getChunks().front();
+    LastPdata = PdataSec->getChunks().back();
+  }
+
+  for (auto &P : Config->Merge) {
+    StringRef ToName = P.second;
+    if (P.first == ToName)
+      continue;
+    StringSet<> Names;
+    while (1) {
+      if (!Names.insert(ToName).second)
+        fatal("/merge: cycle found for section '" + P.first + "'");
+      auto I = Config->Merge.find(ToName);
+      if (I == Config->Merge.end())
+        break;
+      ToName = I->second;
+    }
+    OutputSection *From = findSection(P.first);
+    OutputSection *To = findSection(ToName);
+    if (!From)
+      continue;
+    if (!To) {
+      From->Name = ToName;
+      continue;
+    }
+    To->merge(From);
+  }
+}
+
 // Visits all sections to assign incremental, non-overlapping RVAs and
 // file offsets.
 void Writer::assignAddresses() {
@@ -655,15 +729,10 @@
   SizeOfHeaders = alignTo(SizeOfHeaders, SectorSize);
   uint64_t RVA = PageSize; // The first page is kept unmapped.
   FileSize = SizeOfHeaders;
-  // Move DISCARDABLE (or non-memory-mapped) sections to the end of file because
-  // the loader cannot handle holes.
-  std::stable_partition(
-      OutputSections.begin(), OutputSections.end(), [](OutputSection *S) {
-        return (S->getPermissions() & IMAGE_SCN_MEM_DISCARDABLE) == 0;
-      });
+
   for (OutputSection *Sec : OutputSections) {
-    if (Sec->Name == ".reloc")
-      addBaserels(Sec);
+    if (Sec == RelocSec)
+      addBaserels();
     uint64_t RawSize = 0, VirtualSize = 0;
     Sec->Header.VirtualAddress = RVA;
     for (Chunk *C : Sec->getChunks()) {
@@ -780,24 +849,25 @@
     PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION;
   if (Config->GuardCF != GuardCFLevel::Off)
     PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_GUARD_CF;
-  if (Config->Machine == I386 && !SEHTable &&
-      !Symtab->findUnderscore("_load_config_used"))
+  if (Config->IntegrityCheck)
+    PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY;
+  if (SetNoSEHCharacteristic)
     PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_SEH;
   if (Config->TerminalServerAware)
     PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE;
   PE->NumberOfRvaAndSize = NumberfOfDataDirectory;
-  if (OutputSection *Text = findSection(".text")) {
-    PE->BaseOfCode = Text->getRVA();
-    PE->SizeOfCode = Text->getRawSize();
+  if (TextSec->getVirtualSize()) {
+    PE->BaseOfCode = TextSec->getRVA();
+    PE->SizeOfCode = TextSec->getRawSize();
   }
   PE->SizeOfInitializedData = getSizeOfInitializedData();
 
   // Write data directory
   auto *Dir = reinterpret_cast<data_directory *>(Buf);
   Buf += sizeof(*Dir) * NumberfOfDataDirectory;
-  if (OutputSection *Sec = findSection(".edata")) {
-    Dir[EXPORT_TABLE].RelativeVirtualAddress = Sec->getRVA();
-    Dir[EXPORT_TABLE].Size = Sec->getVirtualSize();
+  if (!Config->Exports.empty()) {
+    Dir[EXPORT_TABLE].RelativeVirtualAddress = Edata.getRVA();
+    Dir[EXPORT_TABLE].Size = Edata.getSize();
   }
   if (!Idata.empty()) {
     Dir[IMPORT_TABLE].RelativeVirtualAddress = Idata.getDirRVA();
@@ -805,17 +875,18 @@
     Dir[IAT].RelativeVirtualAddress = Idata.getIATRVA();
     Dir[IAT].Size = Idata.getIATSize();
   }
-  if (OutputSection *Sec = findSection(".rsrc")) {
-    Dir[RESOURCE_TABLE].RelativeVirtualAddress = Sec->getRVA();
-    Dir[RESOURCE_TABLE].Size = Sec->getVirtualSize();
+  if (RsrcSec->getVirtualSize()) {
+    Dir[RESOURCE_TABLE].RelativeVirtualAddress = RsrcSec->getRVA();
+    Dir[RESOURCE_TABLE].Size = RsrcSec->getVirtualSize();
   }
-  if (OutputSection *Sec = findSection(".pdata")) {
-    Dir[EXCEPTION_TABLE].RelativeVirtualAddress = Sec->getRVA();
-    Dir[EXCEPTION_TABLE].Size = Sec->getVirtualSize();
+  if (FirstPdata) {
+    Dir[EXCEPTION_TABLE].RelativeVirtualAddress = FirstPdata->getRVA();
+    Dir[EXCEPTION_TABLE].Size =
+        LastPdata->getRVA() + LastPdata->getSize() - FirstPdata->getRVA();
   }
-  if (OutputSection *Sec = findSection(".reloc")) {
-    Dir[BASE_RELOCATION_TABLE].RelativeVirtualAddress = Sec->getRVA();
-    Dir[BASE_RELOCATION_TABLE].Size = Sec->getVirtualSize();
+  if (RelocSec->getVirtualSize()) {
+    Dir[BASE_RELOCATION_TABLE].RelativeVirtualAddress = RelocSec->getRVA();
+    Dir[BASE_RELOCATION_TABLE].Size = RelocSec->getVirtualSize();
   }
   if (Symbol *Sym = Symtab->findUnderscore("_tls_used")) {
     if (Defined *B = dyn_cast<Defined>(Sym)) {
@@ -884,7 +955,11 @@
       "failed to open " + Path);
 }
 
-void Writer::createSEHTable(OutputSection *RData) {
+void Writer::createSEHTable() {
+  // Set the no SEH characteristic on x86 binaries unless we find exception
+  // handlers.
+  SetNoSEHCharacteristic = true;
+
   SymbolRVASet Handlers;
   for (ObjFile *File : ObjFile::Instances) {
     // FIXME: We should error here instead of earlier unless /safeseh:no was
@@ -895,7 +970,13 @@
     markSymbolsForRVATable(File, File->getSXDataChunks(), Handlers);
   }
 
-  maybeAddRVATable(RData, std::move(Handlers), "__safe_se_handler_table",
+  // Remove the "no SEH" characteristic if all object files were built with
+  // safeseh, we found some exception handlers, and there is a load config in
+  // the object.
+  SetNoSEHCharacteristic =
+      Handlers.empty() || !Symtab->findUnderscore("_load_config_used");
+
+  maybeAddRVATable(std::move(Handlers), "__safe_se_handler_table",
                    "__safe_se_handler_count");
 }
 
@@ -930,7 +1011,7 @@
       if (auto *D = dyn_cast_or_null<Defined>(Ref)) {
         Chunk *RefChunk = D->getChunk();
         OutputSection *OS = RefChunk ? RefChunk->getOutputSection() : nullptr;
-        if (OS && OS->getPermissions() & IMAGE_SCN_MEM_EXECUTE)
+        if (OS && OS->Header.Characteristics & IMAGE_SCN_MEM_EXECUTE)
           addSymbolToRVASet(UsedSymbols, D);
       }
     }
@@ -940,7 +1021,7 @@
 // Create the guard function id table. This is a table of RVAs of all
 // address-taken functions. It is sorted and uniqued, just like the safe SEH
 // table.
-void Writer::createGuardCFTables(OutputSection *RData) {
+void Writer::createGuardCFTables() {
   SymbolRVASet AddressTakenSyms;
   SymbolRVASet LongJmpTargets;
   for (ObjFile *File : ObjFile::Instances) {
@@ -961,12 +1042,12 @@
   if (Config->Entry)
     addSymbolToRVASet(AddressTakenSyms, cast<Defined>(Config->Entry));
 
-  maybeAddRVATable(RData, std::move(AddressTakenSyms), "__guard_fids_table",
+  maybeAddRVATable(std::move(AddressTakenSyms), "__guard_fids_table",
                    "__guard_fids_count");
 
   // Add the longjmp target table unless the user told us not to.
   if (Config->GuardCF == GuardCFLevel::Full)
-    maybeAddRVATable(RData, std::move(LongJmpTargets), "__guard_longjmp_table",
+    maybeAddRVATable(std::move(LongJmpTargets), "__guard_longjmp_table",
                      "__guard_longjmp_count");
 
   // Set __guard_flags, which will be used in the load config to indicate that
@@ -1023,14 +1104,13 @@
 // Replace the absolute table symbol with a synthetic symbol pointing to
 // TableChunk so that we can emit base relocations for it and resolve section
 // relative relocations.
-void Writer::maybeAddRVATable(OutputSection *RData,
-                              SymbolRVASet TableSymbols,
-                              StringRef TableSym, StringRef CountSym) {
+void Writer::maybeAddRVATable(SymbolRVASet TableSymbols, StringRef TableSym,
+                              StringRef CountSym) {
   if (TableSymbols.empty())
     return;
 
   RVATableChunk *TableChunk = make<RVATableChunk>(std::move(TableSymbols));
-  RData->addChunk(TableChunk);
+  RdataSec->addChunk(TableChunk);
 
   Symbol *T = Symtab->findUnderscore(TableSym);
   Symbol *C = Symtab->findUnderscore(CountSym);
@@ -1044,8 +1124,9 @@
   for (auto &P : Config->Section) {
     StringRef Name = P.first;
     uint32_t Perm = P.second;
-    if (auto *Sec = findSection(Name))
-      Sec->setPermissions(Perm);
+    for (OutputSection *Sec : OutputSections)
+      if (Sec->Name == Name)
+        Sec->setPermissions(Perm);
   }
 }
 
@@ -1061,7 +1142,7 @@
     // Fill gaps between functions in .text with INT3 instructions
     // instead of leaving as NUL bytes (which can be interpreted as
     // ADD instructions).
-    if (Sec->getPermissions() & IMAGE_SCN_CNT_CODE)
+    if (Sec->Header.Characteristics & IMAGE_SCN_CNT_CODE)
       memset(SecBuf, 0xCC, Sec->getRawSize());
     for_each(parallel::par, Sec->getChunks().begin(), Sec->getChunks().end(),
              [&](Chunk *C) { C->writeTo(SecBuf); });
@@ -1103,26 +1184,31 @@
       reinterpret_cast<const char *>(Buffer->getBufferStart()),
       Buffer->getBufferSize());
 
-  uint32_t Hash = static_cast<uint32_t>(xxHash64(OutputFileData));
+  uint32_t Timestamp = Config->Timestamp;
+  if (Config->Repro)
+    Timestamp = static_cast<uint32_t>(xxHash64(OutputFileData));
 
   if (DebugDirectory)
-    DebugDirectory->setTimeDateStamp(Hash);
+    DebugDirectory->setTimeDateStamp(Timestamp);
 
   uint8_t *Buf = Buffer->getBufferStart();
   Buf += DOSStubSize + sizeof(PEMagic);
   object::coff_file_header *CoffHeader =
       reinterpret_cast<coff_file_header *>(Buf);
-  CoffHeader->TimeDateStamp = Hash;
+  CoffHeader->TimeDateStamp = Timestamp;
 }
 
 // Sort .pdata section contents according to PE/COFF spec 5.5.
 void Writer::sortExceptionTable() {
-  OutputSection *Sec = findSection(".pdata");
-  if (!Sec)
+  if (!FirstPdata)
     return;
   // We assume .pdata contains function table entries only.
-  uint8_t *Begin = Buffer->getBufferStart() + Sec->getFileOff();
-  uint8_t *End = Begin + Sec->getVirtualSize();
+  auto BufAddr = [&](Chunk *C) {
+    return Buffer->getBufferStart() + C->getOutputSection()->getFileOff() +
+           C->getRVA() - C->getOutputSection()->getRVA();
+  };
+  uint8_t *Begin = BufAddr(FirstPdata);
+  uint8_t *End = BufAddr(LastPdata) + LastPdata->getSize();
   if (Config->Machine == AMD64) {
     struct Entry { ulittle32_t Begin, End, Unwind; };
     sort(parallel::par, (Entry *)Begin, (Entry *)End,
@@ -1148,55 +1234,31 @@
 uint32_t Writer::getSizeOfInitializedData() {
   uint32_t Res = 0;
   for (OutputSection *S : OutputSections)
-    if (S->getPermissions() & IMAGE_SCN_CNT_INITIALIZED_DATA)
+    if (S->Header.Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
       Res += S->getRawSize();
   return Res;
 }
 
-// Returns an existing section or create a new one if not found.
-OutputSection *Writer::createSection(StringRef Name) {
-  if (auto *Sec = findSection(Name))
-    return Sec;
-  const auto DATA = IMAGE_SCN_CNT_INITIALIZED_DATA;
-  const auto BSS = IMAGE_SCN_CNT_UNINITIALIZED_DATA;
-  const auto CODE = IMAGE_SCN_CNT_CODE;
-  const auto DISCARDABLE = IMAGE_SCN_MEM_DISCARDABLE;
-  const auto R = IMAGE_SCN_MEM_READ;
-  const auto W = IMAGE_SCN_MEM_WRITE;
-  const auto X = IMAGE_SCN_MEM_EXECUTE;
-  uint32_t Perms = StringSwitch<uint32_t>(Name)
-                       .Case(".bss", BSS | R | W)
-                       .Case(".data", DATA | R | W)
-                       .Cases(".didat", ".edata", ".idata", ".rdata", DATA | R)
-                       .Case(".reloc", DATA | DISCARDABLE | R)
-                       .Case(".text", CODE | R | X)
-                       .Default(0);
-  if (!Perms)
-    llvm_unreachable("unknown section name");
-  auto Sec = make<OutputSection>(Name);
-  Sec->addPermissions(Perms);
-  OutputSections.push_back(Sec);
-  return Sec;
-}
-
-// Dest is .reloc section. Add contents to that section.
-void Writer::addBaserels(OutputSection *Dest) {
+// Add base relocations to .reloc section.
+void Writer::addBaserels() {
+  if (!Config->Relocatable)
+    return;
   std::vector<Baserel> V;
   for (OutputSection *Sec : OutputSections) {
-    if (Sec == Dest)
+    if (Sec == RelocSec)
       continue;
     // Collect all locations for base relocations.
     for (Chunk *C : Sec->getChunks())
       C->getBaserels(&V);
     // Add the addresses to .reloc section.
     if (!V.empty())
-      addBaserelBlocks(Dest, V);
+      addBaserelBlocks(V);
     V.clear();
   }
 }
 
 // Add addresses to .reloc section. Note that addresses are grouped by page.
-void Writer::addBaserelBlocks(OutputSection *Dest, std::vector<Baserel> &V) {
+void Writer::addBaserelBlocks(std::vector<Baserel> &V) {
   const uint32_t Mask = ~uint32_t(PageSize - 1);
   uint32_t Page = V[0].RVA & Mask;
   size_t I = 0, J = 1;
@@ -1204,11 +1266,11 @@
     uint32_t P = V[J].RVA & Mask;
     if (P == Page)
       continue;
-    Dest->addChunk(make<BaserelChunk>(Page, &V[I], &V[0] + J));
+    RelocSec->addChunk(make<BaserelChunk>(Page, &V[I], &V[0] + J));
     I = J;
     Page = P;
   }
   if (I == J)
     return;
-  Dest->addChunk(make<BaserelChunk>(Page, &V[I], &V[0] + J));
+  RelocSec->addChunk(make<BaserelChunk>(Page, &V[I], &V[0] + J));
 }
diff --git a/COFF/Writer.h b/COFF/Writer.h
index 1dc1e61..d37276c 100644
--- a/COFF/Writer.h
+++ b/COFF/Writer.h
@@ -30,13 +30,14 @@
 // non-overlapping file offsets and RVAs.
 class OutputSection {
 public:
-  OutputSection(llvm::StringRef N) : Name(N), Header({}) {}
+  OutputSection(llvm::StringRef N, uint32_t Chars) : Name(N) {
+    Header.Characteristics = Chars;
+  }
   void addChunk(Chunk *C);
+  void merge(OutputSection *Other);
   ArrayRef<Chunk *> getChunks() { return Chunks; }
   void addPermissions(uint32_t C);
   void setPermissions(uint32_t C);
-  uint32_t getPermissions() { return Header.Characteristics & PermMask; }
-  uint32_t getCharacteristics() { return Header.Characteristics; }
   uint64_t getRVA() { return Header.VirtualAddress; }
   uint64_t getFileOff() { return Header.PointerToRawData; }
   void writeHeaderTo(uint8_t *Buf);
@@ -59,7 +60,7 @@
   uint32_t SectionIndex = 0;
 
   llvm::StringRef Name;
-  llvm::object::coff_section Header;
+  llvm::object::coff_section Header = {};
 
 private:
   uint32_t StringTableOff = 0;
diff --git a/Common/Args.cpp b/Common/Args.cpp
index 680cf5b..ff77bfc 100644
--- a/Common/Args.cpp
+++ b/Common/Args.cpp
@@ -18,13 +18,17 @@
 using namespace lld;
 
 int lld::args::getInteger(opt::InputArgList &Args, unsigned Key, int Default) {
-  int V = Default;
-  if (auto *Arg = Args.getLastArg(Key)) {
-    StringRef S = Arg->getValue();
-    if (!to_integer(S, V, 10))
-      error(Arg->getSpelling() + ": number expected, but got '" + S + "'");
-  }
-  return V;
+  auto *A = Args.getLastArg(Key);
+  if (!A)
+    return Default;
+
+  int V;
+  if (to_integer(A->getValue(), V, 10))
+    return V;
+
+  StringRef Spelling = Args.getArgString(A->getIndex());
+  error(Spelling + ": number expected, but got '" + A->getValue() + "'");
+  return 0;
 }
 
 std::vector<StringRef> lld::args::getStrings(opt::InputArgList &Args, int Id) {
diff --git a/Common/ErrorHandler.cpp b/Common/ErrorHandler.cpp
index 18affce..6dacc2c 100644
--- a/Common/ErrorHandler.cpp
+++ b/Common/ErrorHandler.cpp
@@ -12,7 +12,8 @@
 #include "lld/Common/Threads.h"
 
 #include "llvm/ADT/Twine.h"
-#include "llvm/Support/Error.h"
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/raw_ostream.h"
 #include <mutex>
@@ -59,6 +60,19 @@
   _exit(Val);
 }
 
+void lld::diagnosticHandler(const DiagnosticInfo &DI) {
+  SmallString<128> S;
+  raw_svector_ostream OS(S);
+  DiagnosticPrinterRawOStream DP(OS);
+  DI.print(DP);
+  warn(S);
+}
+
+void lld::checkError(Error E) {
+  handleAllErrors(std::move(E),
+                  [&](ErrorInfoBase &EIB) { error(EIB.message()); });
+}
+
 void ErrorHandler::print(StringRef S, raw_ostream::Colors C) {
   *ErrorOS << LogName << ": ";
   if (ColorDiagnostics) {
diff --git a/Common/Strings.cpp b/Common/Strings.cpp
index 1fac65b..36f4f77 100644
--- a/Common/Strings.cpp
+++ b/Common/Strings.cpp
@@ -98,3 +98,12 @@
          std::all_of(S.begin() + 1, S.end(),
                      [](char C) { return C == '_' || isAlnum(C); });
 }
+
+// Write the contents of the a buffer to a file
+void lld::saveBuffer(StringRef Buffer, const Twine &Path) {
+  std::error_code EC;
+  raw_fd_ostream OS(Path.str(), EC, sys::fs::OpenFlags::F_None);
+  if (EC)
+    error("cannot create " + Path + ": " + EC.message());
+  OS << Buffer;
+}
diff --git a/Common/TargetOptionsCommandFlags.cpp b/Common/TargetOptionsCommandFlags.cpp
index 2d6819b..b46df36 100644
--- a/Common/TargetOptionsCommandFlags.cpp
+++ b/Common/TargetOptionsCommandFlags.cpp
@@ -8,7 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // This file exists as a place for global variables defined in LLVM's
-// CodeGen/CommandFlags.def. By putting the resulting object file in
+// CodeGen/CommandFlags.inc. By putting the resulting object file in
 // an archive and linking with it, the definitions will automatically be
 // included when needed and skipped when already present.
 //
@@ -16,12 +16,12 @@
 
 #include "lld/Common/TargetOptionsCommandFlags.h"
 
-#include "llvm/CodeGen/CommandFlags.def"
+#include "llvm/CodeGen/CommandFlags.inc"
 #include "llvm/Target/TargetOptions.h"
 
 // Define an externally visible version of
 // InitTargetOptionsFromCodeGenFlags, so that its functionality can be
-// used without having to include llvm/CodeGen/CommandFlags.def, which
+// used without having to include llvm/CodeGen/CommandFlags.inc, which
 // would lead to multiple definitions of the command line flags.
 llvm::TargetOptions lld::InitTargetOptionsFromCodeGenFlags() {
   return ::InitTargetOptionsFromCodeGenFlags();
diff --git a/ELF/Arch/AArch64.cpp b/ELF/Arch/AArch64.cpp
index 2307ed1..c7b3c08 100644
--- a/ELF/Arch/AArch64.cpp
+++ b/ELF/Arch/AArch64.cpp
@@ -34,7 +34,7 @@
   AArch64();
   RelExpr getRelExpr(RelType Type, const Symbol &S,
                      const uint8_t *Loc) const override;
-  bool isPicRel(RelType Type) const override;
+  RelType getDynRel(RelType Type) const override;
   void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
   void writePltHeader(uint8_t *Buf) const override;
   void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
@@ -89,6 +89,11 @@
     return R_TLSDESC_CALL;
   case R_AARCH64_TLSLE_ADD_TPREL_HI12:
   case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
+  case R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC:
+  case R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC:
+  case R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC:
+  case R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC:
+  case R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC:
     return R_TLS;
   case R_AARCH64_CALL26:
   case R_AARCH64_CONDBR19:
@@ -144,8 +149,10 @@
   }
 }
 
-bool AArch64::isPicRel(RelType Type) const {
-  return Type == R_AARCH64_ABS32 || Type == R_AARCH64_ABS64;
+RelType AArch64::getDynRel(RelType Type) const {
+  if (Type == R_AARCH64_ABS32 || Type == R_AARCH64_ABS64)
+    return Type;
+  return R_AARCH64_NONE;
 }
 
 void AArch64::writeGotPlt(uint8_t *Buf, const Symbol &) const {
@@ -287,28 +294,30 @@
     checkInt(Loc, Val, 21, Type);
     or32le(Loc, (Val & 0x1FFFFC) << 3);
     break;
-  case R_AARCH64_LD64_GOT_LO12_NC:
-  case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
-  case R_AARCH64_TLSDESC_LD64_LO12:
-    checkAlignment(Loc, Val, 8, Type);
-    or32le(Loc, (Val & 0xFF8) << 7);
-    break;
   case R_AARCH64_LDST8_ABS_LO12_NC:
+  case R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC:
     or32AArch64Imm(Loc, getBits(Val, 0, 11));
     break;
   case R_AARCH64_LDST16_ABS_LO12_NC:
+  case R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC:
     checkAlignment(Loc, Val, 2, Type);
     or32AArch64Imm(Loc, getBits(Val, 1, 11));
     break;
   case R_AARCH64_LDST32_ABS_LO12_NC:
+  case R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC:
     checkAlignment(Loc, Val, 4, Type);
     or32AArch64Imm(Loc, getBits(Val, 2, 11));
     break;
   case R_AARCH64_LDST64_ABS_LO12_NC:
+  case R_AARCH64_LD64_GOT_LO12_NC:
+  case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
+  case R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC:
+  case R_AARCH64_TLSDESC_LD64_LO12:
     checkAlignment(Loc, Val, 8, Type);
     or32AArch64Imm(Loc, getBits(Val, 3, 11));
     break;
   case R_AARCH64_LDST128_ABS_LO12_NC:
+  case R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC:
     checkAlignment(Loc, Val, 16, Type);
     or32AArch64Imm(Loc, getBits(Val, 4, 11));
     break;
diff --git a/ELF/Arch/ARM.cpp b/ELF/Arch/ARM.cpp
index 9927430..d99be9b 100644
--- a/ELF/Arch/ARM.cpp
+++ b/ELF/Arch/ARM.cpp
@@ -29,7 +29,6 @@
   uint32_t calcEFlags() const override;
   RelExpr getRelExpr(RelType Type, const Symbol &S,
                      const uint8_t *Loc) const override;
-  bool isPicRel(RelType Type) const override;
   RelType getDynRel(RelType Type) const override;
   int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override;
   void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
@@ -162,18 +161,10 @@
   }
 }
 
-bool ARM::isPicRel(RelType Type) const {
-  return (Type == R_ARM_TARGET1 && !Config->Target1Rel) ||
-         (Type == R_ARM_ABS32);
-}
-
 RelType ARM::getDynRel(RelType Type) const {
-  if (Type == R_ARM_TARGET1 && !Config->Target1Rel)
+  if ((Type == R_ARM_ABS32) || (Type == R_ARM_TARGET1 && !Config->Target1Rel))
     return R_ARM_ABS32;
-  if (Type == R_ARM_ABS32)
-    return Type;
-  // Keep it going with a dummy value so that we can find more reloc errors.
-  return R_ARM_ABS32;
+  return R_ARM_NONE;
 }
 
 void ARM::writeGotPlt(uint8_t *Buf, const Symbol &) const {
diff --git a/ELF/Arch/Mips.cpp b/ELF/Arch/Mips.cpp
index a8e54a8..f2a1aea 100644
--- a/ELF/Arch/Mips.cpp
+++ b/ELF/Arch/Mips.cpp
@@ -32,7 +32,6 @@
   RelExpr getRelExpr(RelType Type, const Symbol &S,
                      const uint8_t *Loc) const override;
   int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override;
-  bool isPicRel(RelType Type) const override;
   RelType getDynRel(RelType Type) const override;
   void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
   void writePltHeader(uint8_t *Buf) const override;
@@ -184,12 +183,10 @@
   }
 }
 
-template <class ELFT> bool MIPS<ELFT>::isPicRel(RelType Type) const {
-  return Type == R_MIPS_32 || Type == R_MIPS_64;
-}
-
 template <class ELFT> RelType MIPS<ELFT>::getDynRel(RelType Type) const {
-  return RelativeRel;
+  if (Type == R_MIPS_32 || Type == R_MIPS_64)
+    return RelativeRel;
+  return R_MIPS_NONE;
 }
 
 template <class ELFT>
@@ -661,14 +658,21 @@
 
 // Return true if the symbol is a PIC function.
 template <class ELFT> bool elf::isMipsPIC(const Defined *Sym) {
-  typedef typename ELFT::Ehdr Elf_Ehdr;
-  if (!Sym->Section || !Sym->isFunc())
+  if (!Sym->isFunc())
     return false;
 
-  auto *Sec = cast<InputSectionBase>(Sym->Section);
-  const Elf_Ehdr *Hdr = Sec->template getFile<ELFT>()->getObj().getHeader();
-  return (Sym->StOther & STO_MIPS_MIPS16) == STO_MIPS_PIC ||
-         (Hdr->e_flags & EF_MIPS_PIC);
+  if (Sym->StOther & STO_MIPS_PIC)
+    return true;
+
+  if (!Sym->Section)
+    return false;
+
+  ObjFile<ELFT> *File =
+      cast<InputSectionBase>(Sym->Section)->template getFile<ELFT>();
+  if (!File)
+    return false;
+
+  return File->getObj().getHeader()->e_flags & EF_MIPS_PIC;
 }
 
 template <class ELFT> TargetInfo *elf::getMipsTargetInfo() {
diff --git a/ELF/Arch/PPC64.cpp b/ELF/Arch/PPC64.cpp
index d3c2dbd..1d5d939 100644
--- a/ELF/Arch/PPC64.cpp
+++ b/ELF/Arch/PPC64.cpp
@@ -43,10 +43,13 @@
   uint32_t calcEFlags() const override;
   RelExpr getRelExpr(RelType Type, const Symbol &S,
                      const uint8_t *Loc) const override;
+  void writePltHeader(uint8_t *Buf) const override;
   void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
                 int32_t Index, unsigned RelOff) const override;
   void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
   void writeGotHeader(uint8_t *Buf) const override;
+  bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
+                  uint64_t BranchAddr, const Symbol &S) const override;
 };
 } // namespace
 
@@ -63,16 +66,24 @@
 static uint16_t applyPPCHighesta(uint64_t V) { return (V + 0x8000) >> 48; }
 
 PPC64::PPC64() {
-  PltRel = GotRel = R_PPC64_GLOB_DAT;
+  GotRel = R_PPC64_GLOB_DAT;
+  PltRel = R_PPC64_JMP_SLOT;
   RelativeRel = R_PPC64_RELATIVE;
+  IRelativeRel = R_PPC64_IRELATIVE;
   GotEntrySize = 8;
+  PltEntrySize = 4;
   GotPltEntrySize = 8;
-  PltEntrySize = 32;
-  PltHeaderSize = 0;
   GotBaseSymInGotPlt = false;
   GotBaseSymOff = 0x8000;
-  if (Config->EKind == ELF64LEKind)
-    GotHeaderEntriesNum = 1;
+  GotHeaderEntriesNum = 1;
+  GotPltHeaderEntriesNum = 2;
+  PltHeaderSize = 60;
+  NeedsThunks = true;
+
+  TlsModuleIndexRel = R_PPC64_DTPMOD64;
+  TlsOffsetRel = R_PPC64_DTPREL64;
+
+  TlsGotRel = R_PPC64_TPREL64;
 
   // We need 64K pages (at least under glibc/Linux, the loader won't
   // set different permissions on a finer granularity than that).
@@ -87,42 +98,59 @@
   // And because the lowest non-zero 256M boundary is 0x10000000, PPC64 linkers
   // use 0x10000000 as the starting address.
   DefaultImageBase = 0x10000000;
+
+  TrapInstr =
+      (Config->IsLE == sys::IsLittleEndianHost) ? 0x7fe00008 : 0x0800e07f;
 }
 
 static uint32_t getEFlags(InputFile *File) {
-  // Get the e_flag from the input file and if it is unspecified, then set it to
-  // the e_flag appropriate for the ABI.
-
-  // We are currently handling both ELF64LE and ELF64BE but eventually will
-  // remove BE support once v2 ABI support is complete.
+  // Get the e_flag from the input file and issue an error if incompatible
+  // e_flag encountered.
+  uint32_t EFlags;
   switch (Config->EKind) {
   case ELF64BEKind:
-    if (uint32_t EFlags =
-        cast<ObjFile<ELF64BE>>(File)->getObj().getHeader()->e_flags)
-      return EFlags;
-    return 1;
+    EFlags = cast<ObjFile<ELF64BE>>(File)->getObj().getHeader()->e_flags;
+    break;
   case ELF64LEKind:
-    if (uint32_t EFlags =
-        cast<ObjFile<ELF64LE>>(File)->getObj().getHeader()->e_flags)
-      return EFlags;
-    return 2;
+    EFlags = cast<ObjFile<ELF64LE>>(File)->getObj().getHeader()->e_flags;
+    break;
   default:
     llvm_unreachable("unknown Config->EKind");
   }
+  if (EFlags > 2) {
+    error("incompatible e_flags: " +  toString(File));
+    return 0;
+  }
+  return EFlags;
 }
 
 uint32_t PPC64::calcEFlags() const {
   assert(!ObjectFiles.empty());
-  uint32_t Ret = getEFlags(ObjectFiles[0]);
 
-  // Verify that all input files have the same e_flags.
-  for (InputFile *F : makeArrayRef(ObjectFiles).slice(1)) {
-    if (Ret == getEFlags(F))
+  uint32_t NonZeroFlag;
+  for (InputFile *F : makeArrayRef(ObjectFiles)) {
+    NonZeroFlag = getEFlags(F);
+    if (NonZeroFlag)
+      break;
+  }
+
+  // Verify that all input files have either the same e_flags, or zero.
+  for (InputFile *F : makeArrayRef(ObjectFiles)) {
+    uint32_t Flag = getEFlags(F);
+    if (Flag == 0 || Flag == NonZeroFlag)
       continue;
-    error("incompatible e_flags: " + toString(F));
+    error(toString(F) + ": ABI version " + Twine(Flag) +
+          " is not compatible with ABI version " + Twine(NonZeroFlag) +
+          " output");
     return 0;
   }
-  return Ret;
+
+  if (NonZeroFlag == 1) {
+    error("PPC64 V1 ABI not supported");
+    return 0;
+  }
+
+  return 2;
 }
 
 RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
@@ -138,55 +166,97 @@
   case R_PPC64_TOC:
     return R_PPC_TOC;
   case R_PPC64_REL24:
-    return R_PPC_PLT_OPD;
+    return R_PPC_CALL_PLT;
   case R_PPC64_REL16_LO:
   case R_PPC64_REL16_HA:
+  case R_PPC64_REL32:
+  case R_PPC64_REL64:
     return R_PC;
+  case R_PPC64_GOT_TLSGD16:
+  case R_PPC64_GOT_TLSGD16_HA:
+  case R_PPC64_GOT_TLSGD16_HI:
+  case R_PPC64_GOT_TLSGD16_LO:
+    return R_TLSGD_GOT;
+  case R_PPC64_GOT_TLSLD16:
+  case R_PPC64_GOT_TLSLD16_HA:
+  case R_PPC64_GOT_TLSLD16_HI:
+  case R_PPC64_GOT_TLSLD16_LO:
+    return R_TLSLD_GOT;
+  case R_PPC64_GOT_TPREL16_HA:
+  case R_PPC64_GOT_TPREL16_LO_DS:
+  case R_PPC64_GOT_TPREL16_DS:
+  case R_PPC64_GOT_TPREL16_HI:
+    return R_GOT_OFF;
+  case R_PPC64_TLSGD:
+  case R_PPC64_TLSLD:
+  case R_PPC64_TLS:
+    return R_HINT;
   default:
     return R_ABS;
   }
 }
 
 void PPC64::writeGotHeader(uint8_t *Buf) const {
-  if (Config->EKind == ELF64LEKind)
-    write64(Buf, getPPC64TocBase());
+  write64(Buf, getPPC64TocBase());
+}
+
+void PPC64::writePltHeader(uint8_t *Buf) const {
+  // The generic resolver stub goes first.
+  write32(Buf +  0, 0x7c0802a6); // mflr r0
+  write32(Buf +  4, 0x429f0005); // bcl  20,4*cr7+so,8 <_glink+0x8>
+  write32(Buf +  8, 0x7d6802a6); // mflr r11
+  write32(Buf + 12, 0x7c0803a6); // mtlr r0
+  write32(Buf + 16, 0x7d8b6050); // subf r12, r11, r12
+  write32(Buf + 20, 0x380cffcc); // subi r0,r12,52
+  write32(Buf + 24, 0x7800f082); // srdi r0,r0,62,2
+  write32(Buf + 28, 0xe98b002c); // ld   r12,44(r11)
+  write32(Buf + 32, 0x7d6c5a14); // add  r11,r12,r11
+  write32(Buf + 36, 0xe98b0000); // ld   r12,0(r11)
+  write32(Buf + 40, 0xe96b0008); // ld   r11,8(r11)
+  write32(Buf + 44, 0x7d8903a6); // mtctr   r12
+  write32(Buf + 48, 0x4e800420); // bctr
+
+  // The 'bcl' instruction will set the link register to the address of the
+  // following instruction ('mflr r11'). Here we store the offset from that
+  // instruction  to the first entry in the GotPlt section.
+  int64_t GotPltOffset = InX::GotPlt->getVA() - (InX::Plt->getVA() + 8);
+  write64(Buf + 52, GotPltOffset);
 }
 
 void PPC64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
                      uint64_t PltEntryAddr, int32_t Index,
                      unsigned RelOff) const {
-  uint64_t Off = GotPltEntryAddr - getPPC64TocBase();
-
-  // FIXME: What we should do, in theory, is get the offset of the function
-  // descriptor in the .opd section, and use that as the offset from %r2 (the
-  // TOC-base pointer). Instead, we have the GOT-entry offset, and that will
-  // be a pointer to the function descriptor in the .opd section. Using
-  // this scheme is simpler, but requires an extra indirection per PLT dispatch.
-
-  write32(Buf, 0xf8410028);                       // std %r2, 40(%r1)
-  write32(Buf + 4, 0x3d620000 | applyPPCHa(Off)); // addis %r11, %r2, X@ha
-  write32(Buf + 8, 0xe98b0000 | applyPPCLo(Off)); // ld %r12, X@l(%r11)
-  write32(Buf + 12, 0xe96c0000);                  // ld %r11,0(%r12)
-  write32(Buf + 16, 0x7d6903a6);                  // mtctr %r11
-  write32(Buf + 20, 0xe84c0008);                  // ld %r2,8(%r12)
-  write32(Buf + 24, 0xe96c0010);                  // ld %r11,16(%r12)
-  write32(Buf + 28, 0x4e800420);                  // bctr
+ int32_t Offset = PltHeaderSize + Index * PltEntrySize;
+ // bl __glink_PLTresolve
+ write32(Buf, 0x48000000 | ((-Offset) & 0x03FFFFFc));
 }
 
 static std::pair<RelType, uint64_t> toAddr16Rel(RelType Type, uint64_t Val) {
   uint64_t V = Val - PPC64TocOffset;
   switch (Type) {
+  case R_PPC64_GOT_TLSGD16:
+  case R_PPC64_GOT_TLSLD16:
   case R_PPC64_TOC16:
     return {R_PPC64_ADDR16, V};
   case R_PPC64_TOC16_DS:
+  case R_PPC64_GOT_TPREL16_DS:
     return {R_PPC64_ADDR16_DS, V};
+  case R_PPC64_GOT_TLSGD16_HA:
+  case R_PPC64_GOT_TLSLD16_HA:
+  case R_PPC64_GOT_TPREL16_HA:
   case R_PPC64_TOC16_HA:
     return {R_PPC64_ADDR16_HA, V};
+  case R_PPC64_GOT_TLSGD16_HI:
+  case R_PPC64_GOT_TLSLD16_HI:
+  case R_PPC64_GOT_TPREL16_HI:
   case R_PPC64_TOC16_HI:
     return {R_PPC64_ADDR16_HI, V};
+  case R_PPC64_GOT_TLSGD16_LO:
+  case R_PPC64_GOT_TLSLD16_LO:
   case R_PPC64_TOC16_LO:
     return {R_PPC64_ADDR16_LO, V};
   case R_PPC64_TOC16_LO_DS:
+  case R_PPC64_GOT_TPREL16_LO_DS:
     return {R_PPC64_ADDR16_LO_DS, V};
   default:
     return {Type, Val};
@@ -262,6 +332,13 @@
   }
 }
 
+bool PPC64::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
+                       uint64_t BranchAddr, const Symbol &S) const {
+  // If a function is in the plt it needs to be called through
+  // a call stub.
+  return Type == R_PPC64_REL24 && S.isInPlt();
+}
+
 TargetInfo *elf::getPPC64TargetInfo() {
   static PPC64 Target;
   return &Target;
diff --git a/ELF/Arch/X86.cpp b/ELF/Arch/X86.cpp
index 87c84ad..19a0b60 100644
--- a/ELF/Arch/X86.cpp
+++ b/ELF/Arch/X86.cpp
@@ -73,9 +73,9 @@
   case R_386_TLS_LDO_32:
     return R_ABS;
   case R_386_TLS_GD:
-    return R_TLSGD;
+    return R_TLSGD_GOT_FROM_END;
   case R_386_TLS_LDM:
-    return R_TLSLD;
+    return R_TLSLD_GOT_FROM_END;
   case R_386_PLT32:
     return R_PLT_PC;
   case R_386_PC8:
@@ -255,7 +255,7 @@
     // R_386_{PC,}{8,16} are not part of the i386 psABI, but they are
     // being used for some 16-bit programs such as boot loaders, so
     // we want to support them.
-    checkUInt(Loc, Val, 8, Type);
+    checkIntUInt(Loc, Val, 8, Type);
     *Loc = Val;
     break;
   case R_386_PC8:
@@ -263,7 +263,7 @@
     *Loc = Val;
     break;
   case R_386_16:
-    checkUInt(Loc, Val, 16, Type);
+    checkIntUInt(Loc, Val, 16, Type);
     write16le(Loc, Val);
     break;
   case R_386_PC16:
diff --git a/ELF/Arch/X86_64.cpp b/ELF/Arch/X86_64.cpp
index a370508..8fd28d3 100644
--- a/ELF/Arch/X86_64.cpp
+++ b/ELF/Arch/X86_64.cpp
@@ -28,7 +28,7 @@
   X86_64();
   RelExpr getRelExpr(RelType Type, const Symbol &S,
                      const uint8_t *Loc) const override;
-  bool isPicRel(RelType Type) const override;
+  RelType getDynRel(RelType Type) const override;
   void writeGotPltHeader(uint8_t *Buf) const override;
   void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
   void writePltHeader(uint8_t *Buf) const override;
@@ -123,7 +123,7 @@
 template <class ELFT>
 void X86_64<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &S) const {
   // See comments in X86::writeGotPlt.
-  write32le(Buf, S.getPltVA() + 6);
+  write64le(Buf, S.getPltVA() + 6);
 }
 
 template <class ELFT> void X86_64<ELFT>::writePltHeader(uint8_t *Buf) const {
@@ -155,9 +155,11 @@
   write32le(Buf + 12, -getPltEntryOffset(Index) - 16);
 }
 
-template <class ELFT> bool X86_64<ELFT>::isPicRel(RelType Type) const {
-  return Type != R_X86_64_PC32 && Type != R_X86_64_32 &&
-         Type != R_X86_64_TPOFF32;
+template <class ELFT> RelType X86_64<ELFT>::getDynRel(RelType Type) const {
+  if (Type == R_X86_64_64 || Type == R_X86_64_PC64 || Type == R_X86_64_SIZE32 ||
+      Type == R_X86_64_SIZE64)
+    return Type;
+  return R_X86_64_NONE;
 }
 
 template <class ELFT>
@@ -459,6 +461,15 @@
   write32le(Loc - 1, Val + 1);
 }
 
+// These nonstandard PLT entries are to migtigate Spectre v2 security
+// vulnerability. In order to mitigate Spectre v2, we want to avoid indirect
+// branch instructions such as `jmp *GOTPLT(%rip)`. So, in the following PLT
+// entries, we use a CALL followed by MOV and RET to do the same thing as an
+// indirect jump. That instruction sequence is so-called "retpoline".
+//
+// We have two types of retpoline PLTs as a size optimization. If `-z now`
+// is specified, all dynamic symbols are resolved at load-time. Thus, when
+// that option is given, we can omit code for symbol lazy resolution.
 namespace {
 template <class ELFT> class Retpoline : public X86_64<ELFT> {
 public:
@@ -486,7 +497,7 @@
 
 template <class ELFT>
 void Retpoline<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &S) const {
-  write32le(Buf, S.getPltVA() + 17);
+  write64le(Buf, S.getPltVA() + 17);
 }
 
 template <class ELFT> void Retpoline<ELFT>::writePltHeader(uint8_t *Buf) const {
@@ -571,7 +582,7 @@
   write32le(Buf + 8, -TargetInfo::getPltEntryOffset(Index) - 12);
 }
 
-template <class ELFT> TargetInfo *getTargetInfo() {
+template <class ELFT> static TargetInfo *getTargetInfo() {
   if (Config->ZRetpolineplt) {
     if (Config->ZNow) {
       static RetpolineZNow<ELFT> T;
diff --git a/ELF/CMakeLists.txt b/ELF/CMakeLists.txt
index b9ff414..af2bed3 100644
--- a/ELF/CMakeLists.txt
+++ b/ELF/CMakeLists.txt
@@ -19,6 +19,7 @@
   Arch/SPARCV9.cpp
   Arch/X86.cpp
   Arch/X86_64.cpp
+  CallGraphSort.cpp
   Driver.cpp
   DriverUtils.cpp
   EhFrame.cpp
@@ -45,6 +46,7 @@
   LINK_COMPONENTS
   ${LLVM_TARGETS_TO_BUILD}
   BinaryFormat
+  BitWriter
   Core
   DebugInfoDWARF
   LTO
diff --git a/ELF/CallGraphSort.cpp b/ELF/CallGraphSort.cpp
new file mode 100644
index 0000000..33ac159
--- /dev/null
+++ b/ELF/CallGraphSort.cpp
@@ -0,0 +1,249 @@
+//===- CallGraphSort.cpp --------------------------------------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// Implementation of Call-Chain Clustering from: Optimizing Function Placement
+/// for Large-Scale Data-Center Applications
+/// https://research.fb.com/wp-content/uploads/2017/01/cgo2017-hfsort-final1.pdf
+///
+/// The goal of this algorithm is to improve runtime performance of the final
+/// executable by arranging code sections such that page table and i-cache
+/// misses are minimized.
+///
+/// Definitions:
+/// * Cluster
+///   * An ordered list of input sections which are layed out as a unit. At the
+///     beginning of the algorithm each input section has its own cluster and
+///     the weight of the cluster is the sum of the weight of all incomming
+///     edges.
+/// * Call-Chain Clustering (C³) Heuristic
+///   * Defines when and how clusters are combined. Pick the highest weighted
+///     input section then add it to its most likely predecessor if it wouldn't
+///     penalize it too much.
+/// * Density
+///   * The weight of the cluster divided by the size of the cluster. This is a
+///     proxy for the ammount of execution time spent per byte of the cluster.
+///
+/// It does so given a call graph profile by the following:
+/// * Build a weighted call graph from the call graph profile
+/// * Sort input sections by weight
+/// * For each input section starting with the highest weight
+///   * Find its most likely predecessor cluster
+///   * Check if the combined cluster would be too large, or would have too low
+///     a density.
+///   * If not, then combine the clusters.
+/// * Sort non-empty clusters by density
+///
+//===----------------------------------------------------------------------===//
+
+#include "CallGraphSort.h"
+#include "OutputSections.h"
+#include "SymbolTable.h"
+#include "Symbols.h"
+
+using namespace llvm;
+using namespace lld;
+using namespace lld::elf;
+
+namespace {
+struct Edge {
+  int From;
+  uint64_t Weight;
+};
+
+struct Cluster {
+  Cluster(int Sec, size_t S) {
+    Sections.push_back(Sec);
+    Size = S;
+  }
+
+  double getDensity() const {
+    if (Size == 0)
+      return 0;
+    return double(Weight) / double(Size);
+  }
+
+  std::vector<int> Sections;
+  size_t Size = 0;
+  uint64_t Weight = 0;
+  uint64_t InitialWeight = 0;
+  std::vector<Edge> Preds;
+};
+
+class CallGraphSort {
+public:
+  CallGraphSort();
+
+  DenseMap<const InputSectionBase *, int> run();
+
+private:
+  std::vector<Cluster> Clusters;
+  std::vector<const InputSectionBase *> Sections;
+
+  void groupClusters();
+};
+
+// Maximum ammount the combined cluster density can be worse than the original
+// cluster to consider merging.
+constexpr int MAX_DENSITY_DEGRADATION = 8;
+
+// Maximum cluster size in bytes.
+constexpr uint64_t MAX_CLUSTER_SIZE = 1024 * 1024;
+} // end anonymous namespace
+
+// Take the edge list in Config->CallGraphProfile, resolve symbol names to
+// Symbols, and generate a graph between InputSections with the provided
+// weights.
+CallGraphSort::CallGraphSort() {
+  llvm::MapVector<std::pair<const InputSectionBase *, const InputSectionBase *>,
+                  uint64_t> &Profile = Config->CallGraphProfile;
+  DenseMap<const InputSectionBase *, int> SecToCluster;
+
+  auto GetOrCreateNode = [&](const InputSectionBase *IS) -> int {
+    auto Res = SecToCluster.insert(std::make_pair(IS, Clusters.size()));
+    if (Res.second) {
+      Sections.push_back(IS);
+      Clusters.emplace_back(Clusters.size(), IS->getSize());
+    }
+    return Res.first->second;
+  };
+
+  // Create the graph.
+  for (const auto &C : Profile) {
+    const auto *FromSB = cast<InputSectionBase>(C.first.first->Repl);
+    const auto *ToSB = cast<InputSectionBase>(C.first.second->Repl);
+    uint64_t Weight = C.second;
+
+    // Ignore edges between input sections belonging to different output
+    // sections.  This is done because otherwise we would end up with clusters
+    // containing input sections that can't actually be placed adjacently in the
+    // output.  This messes with the cluster size and density calculations.  We
+    // would also end up moving input sections in other output sections without
+    // moving them closer to what calls them.
+    if (FromSB->getOutputSection() != ToSB->getOutputSection())
+      continue;
+
+    int From = GetOrCreateNode(FromSB);
+    int To = GetOrCreateNode(ToSB);
+
+    Clusters[To].Weight += Weight;
+
+    if (From == To)
+      continue;
+
+    // Add an edge
+    Clusters[To].Preds.push_back({From, Weight});
+  }
+  for (Cluster &C : Clusters)
+    C.InitialWeight = C.Weight;
+}
+
+// It's bad to merge clusters which would degrade the density too much.
+static bool isNewDensityBad(Cluster &A, Cluster &B) {
+  double NewDensity = double(A.Weight + B.Weight) / double(A.Size + B.Size);
+  if (NewDensity < A.getDensity() / MAX_DENSITY_DEGRADATION)
+    return true;
+  return false;
+}
+
+static void mergeClusters(Cluster &Into, Cluster &From) {
+  Into.Sections.insert(Into.Sections.end(), From.Sections.begin(),
+                       From.Sections.end());
+  Into.Size += From.Size;
+  Into.Weight += From.Weight;
+  From.Sections.clear();
+  From.Size = 0;
+  From.Weight = 0;
+}
+
+// Group InputSections into clusters using the Call-Chain Clustering heuristic
+// then sort the clusters by density.
+void CallGraphSort::groupClusters() {
+  std::vector<int> SortedSecs(Clusters.size());
+  std::vector<Cluster *> SecToCluster(Clusters.size());
+
+  for (int SI = 0, SE = Clusters.size(); SI != SE; ++SI) {
+    SortedSecs[SI] = SI;
+    SecToCluster[SI] = &Clusters[SI];
+  }
+
+  std::stable_sort(SortedSecs.begin(), SortedSecs.end(), [&](int A, int B) {
+    return Clusters[B].getDensity() < Clusters[A].getDensity();
+  });
+
+  for (int SI : SortedSecs) {
+    // Clusters[SI] is the same as SecToClusters[SI] here because it has not
+    // been merged into another cluster yet.
+    Cluster &C = Clusters[SI];
+
+    int BestPred = -1;
+    uint64_t BestWeight = 0;
+
+    for (Edge &E : C.Preds) {
+      if (BestPred == -1 || E.Weight > BestWeight) {
+        BestPred = E.From;
+        BestWeight = E.Weight;
+      }
+    }
+
+    // don't consider merging if the edge is unlikely.
+    if (BestWeight * 10 <= C.InitialWeight)
+      continue;
+
+    Cluster *PredC = SecToCluster[BestPred];
+    if (PredC == &C)
+      continue;
+
+    if (C.Size + PredC->Size > MAX_CLUSTER_SIZE)
+      continue;
+
+    if (isNewDensityBad(*PredC, C))
+      continue;
+
+    // NOTE: Consider using a disjoint-set to track section -> cluster mapping
+    // if this is ever slow.
+    for (int SI : C.Sections)
+      SecToCluster[SI] = PredC;
+
+    mergeClusters(*PredC, C);
+  }
+
+  // Remove empty or dead nodes. Invalidates all cluster indices.
+  llvm::erase_if(Clusters, [](const Cluster &C) {
+    return C.Size == 0 || C.Sections.empty();
+  });
+
+  // Sort by density.
+  std::stable_sort(Clusters.begin(), Clusters.end(),
+                   [](const Cluster &A, const Cluster &B) {
+                     return A.getDensity() > B.getDensity();
+                   });
+}
+
+DenseMap<const InputSectionBase *, int> CallGraphSort::run() {
+  groupClusters();
+
+  // Generate order.
+  llvm::DenseMap<const InputSectionBase *, int> OrderMap;
+  ssize_t CurOrder = 1;
+
+  for (const Cluster &C : Clusters)
+    for (int SecIndex : C.Sections)
+      OrderMap[Sections[SecIndex]] = CurOrder++;
+
+  return OrderMap;
+}
+
+// Sort sections by the profile data provided by -callgraph-profile-file
+//
+// This first builds a call graph based on the profile data then merges sections
+// according to the C³ huristic. All clusters are then sorted by a density
+// metric to further improve locality.
+DenseMap<const InputSectionBase *, int> elf::computeCallGraphProfileOrder() {
+  return CallGraphSort().run();
+}
diff --git a/ELF/CallGraphSort.h b/ELF/CallGraphSort.h
new file mode 100644
index 0000000..3f96dc8
--- /dev/null
+++ b/ELF/CallGraphSort.h
@@ -0,0 +1,23 @@
+//===- CallGraphSort.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_CALL_GRAPH_SORT_H
+#define LLD_ELF_CALL_GRAPH_SORT_H
+
+#include "llvm/ADT/DenseMap.h"
+
+namespace lld {
+namespace elf {
+class InputSectionBase;
+
+llvm::DenseMap<const InputSectionBase *, int> computeCallGraphProfileOrder();
+} // namespace elf
+} // namespace lld
+
+#endif
diff --git a/ELF/Config.h b/ELF/Config.h
index 2007992..60276f9 100644
--- a/ELF/Config.h
+++ b/ELF/Config.h
@@ -24,6 +24,7 @@
 namespace elf {
 
 class InputFile;
+class InputSectionBase;
 
 enum ELFKind {
   ELFNoneKind,
@@ -85,6 +86,8 @@
   llvm::StringRef Init;
   llvm::StringRef LTOAAPipeline;
   llvm::StringRef LTONewPmPasses;
+  llvm::StringRef LTOObjPath;
+  llvm::StringRef LTOSampleProfile;
   llvm::StringRef MapFile;
   llvm::StringRef OutputFile;
   llvm::StringRef OptRemarksFilename;
@@ -92,6 +95,9 @@
   llvm::StringRef SoName;
   llvm::StringRef Sysroot;
   llvm::StringRef ThinLTOCacheDir;
+  llvm::StringRef ThinLTOIndexOnlyArg;
+  std::pair<llvm::StringRef, llvm::StringRef> ThinLTOObjectSuffixReplace;
+  std::pair<llvm::StringRef, llvm::StringRef> ThinLTOPrefixReplace;
   std::string Rpath;
   std::vector<VersionDefinition> VersionDefinitions;
   std::vector<llvm::StringRef> AuxiliaryList;
@@ -103,6 +109,9 @@
   std::vector<SymbolVersion> VersionScriptGlobals;
   std::vector<SymbolVersion> VersionScriptLocals;
   std::vector<uint8_t> BuildIdVector;
+  llvm::MapVector<std::pair<const InputSectionBase *, const InputSectionBase *>,
+                  uint64_t>
+      CallGraphProfile;
   bool AllowMultipleDefinition;
   bool AndroidPackDynRelocs = false;
   bool ARMHasBlx = false;
@@ -131,6 +140,8 @@
   bool ICF;
   bool IgnoreDataAddressEquality;
   bool IgnoreFunctionAddressEquality;
+  bool LTODebugPassManager;
+  bool LTONewPassManager;
   bool MergeArmExidx;
   bool MipsN32Abi = false;
   bool NoinhibitExec;
@@ -149,15 +160,19 @@
   bool SysvHash = false;
   bool Target1Rel;
   bool Trace;
+  bool ThinLTOEmitImportsFiles;
+  bool ThinLTOIndexOnly;
   bool UndefinedVersion;
+  bool WarnBackrefs;
   bool WarnCommon;
   bool WarnMissingEntry;
   bool WarnSymbolOrdering;
   bool WriteAddends;
   bool ZCombreloc;
+  bool ZCopyreloc;
   bool ZExecstack;
   bool ZHazardplt;
-  bool ZNocopyreloc;
+  bool ZKeepTextSectionPrefix;
   bool ZNodelete;
   bool ZNodlopen;
   bool ZNow;
diff --git a/ELF/Driver.cpp b/ELF/Driver.cpp
index 4565fde..2e3a425 100644
--- a/ELF/Driver.cpp
+++ b/ELF/Driver.cpp
@@ -118,7 +118,8 @@
 
   std::pair<ELFKind, uint16_t> Ret =
       StringSwitch<std::pair<ELFKind, uint16_t>>(S)
-          .Cases("aarch64elf", "aarch64linux", {ELF64LEKind, EM_AARCH64})
+          .Cases("aarch64elf", "aarch64linux", "aarch64_elf64_le_vec",
+                 {ELF64LEKind, EM_AARCH64})
           .Cases("armelf", "armelf_linux_eabi", {ELF32LEKind, EM_ARM})
           .Case("elf32_x86_64", {ELF32LEKind, EM_X86_64})
           .Cases("elf32btsmip", "elf32btsmipn32", {ELF32BEKind, EM_MIPS})
@@ -313,6 +314,17 @@
   return false;
 }
 
+static bool getZFlag(opt::InputArgList &Args, StringRef K1, StringRef K2,
+                     bool Default) {
+  for (auto *Arg : Args.filtered_reverse(OPT_z)) {
+    if (K1 == Arg->getValue())
+      return true;
+    if (K2 == Arg->getValue())
+      return false;
+  }
+  return Default;
+}
+
 void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
   ELFOptTable Parser;
   opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));
@@ -572,6 +584,45 @@
   return {BuildIdKind::None, {}};
 }
 
+static void readCallGraph(MemoryBufferRef MB) {
+  // Build a map from symbol name to section
+  DenseMap<StringRef, const Symbol *> SymbolNameToSymbol;
+  for (InputFile *File : ObjectFiles)
+    for (Symbol *Sym : File->getSymbols())
+      SymbolNameToSymbol[Sym->getName()] = Sym;
+
+  for (StringRef L : args::getLines(MB)) {
+    SmallVector<StringRef, 3> Fields;
+    L.split(Fields, ' ');
+    if (Fields.size() != 3)
+      fatal("parse error");
+    uint64_t Count;
+    if (!to_integer(Fields[2], Count))
+      fatal("parse error");
+    const Symbol *FromSym = SymbolNameToSymbol.lookup(Fields[0]);
+    const Symbol *ToSym = SymbolNameToSymbol.lookup(Fields[1]);
+    if (Config->WarnSymbolOrdering) {
+      if (!FromSym)
+        warn("call graph file: no such symbol: " + Fields[0]);
+      if (!ToSym)
+        warn("call graph file: no such symbol: " + Fields[1]);
+    }
+    if (!FromSym || !ToSym || Count == 0)
+      continue;
+    warnUnorderableSymbol(FromSym);
+    warnUnorderableSymbol(ToSym);
+    const Defined *FromSymD = dyn_cast<Defined>(FromSym);
+    const Defined *ToSymD = dyn_cast<Defined>(ToSym);
+    if (!FromSymD || !ToSymD)
+      continue;
+    const auto *FromSB = dyn_cast_or_null<InputSectionBase>(FromSymD->Section);
+    const auto *ToSB = dyn_cast_or_null<InputSectionBase>(ToSymD->Section);
+    if (!FromSB || !ToSB)
+      continue;
+    Config->CallGraphProfile[std::make_pair(FromSB, ToSB)] += Count;
+  }
+}
+
 static bool getCompressDebugSections(opt::InputArgList &Args) {
   StringRef S = Args.getLastArgValue(OPT_compress_debug_sections, "none");
   if (S == "none")
@@ -583,12 +634,17 @@
   return true;
 }
 
-static int parseInt(StringRef S, opt::Arg *Arg) {
-  int V = 0;
-  if (!to_integer(S, V, 10))
-    error(Arg->getSpelling() + "=" + Arg->getValue() +
-          ": number expected, but got '" + S + "'");
-  return V;
+static std::pair<StringRef, StringRef> getOldNewOptions(opt::InputArgList &Args,
+                                                        unsigned Id) {
+  auto *Arg = Args.getLastArg(Id);
+  if (!Arg)
+    return {"", ""};
+
+  StringRef S = Arg->getValue();
+  std::pair<StringRef, StringRef> Ret = S.split(';');
+  if (Ret.second.empty())
+    error(Arg->getSpelling() + " expects 'old;new' format, but got " + S);
+  return Ret;
 }
 
 // Parse the symbol ordering file and warn for any duplicate entries.
@@ -617,6 +673,7 @@
   errorHandler().Verbose = Args.hasArg(OPT_verbose);
   errorHandler().FatalWarnings =
       Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false);
+  ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true);
 
   Config->AllowMultipleDefinition =
       Args.hasFlag(OPT_allow_multiple_definition,
@@ -657,9 +714,13 @@
       Args.hasArg(OPT_ignore_function_address_equality);
   Config->Init = Args.getLastArgValue(OPT_init, "_init");
   Config->LTOAAPipeline = Args.getLastArgValue(OPT_lto_aa_pipeline);
+  Config->LTODebugPassManager = Args.hasArg(OPT_lto_debug_pass_manager);
+  Config->LTONewPassManager = Args.hasArg(OPT_lto_new_pass_manager);
   Config->LTONewPmPasses = Args.getLastArgValue(OPT_lto_newpm_passes);
   Config->LTOO = args::getInteger(Args, OPT_lto_O, 2);
+  Config->LTOObjPath = Args.getLastArgValue(OPT_plugin_opt_obj_path_eq);
   Config->LTOPartitions = args::getInteger(Args, OPT_lto_partitions, 1);
+  Config->LTOSampleProfile = Args.getLastArgValue(OPT_lto_sample_profile);
   Config->MapFile = Args.getLastArgValue(OPT_Map);
   Config->MergeArmExidx =
       Args.hasFlag(OPT_merge_exidx_entries, OPT_no_merge_exidx_entries, true);
@@ -694,50 +755,51 @@
   Config->ThinLTOCachePolicy = CHECK(
       parseCachePruningPolicy(Args.getLastArgValue(OPT_thinlto_cache_policy)),
       "--thinlto-cache-policy: invalid cache policy");
+  Config->ThinLTOEmitImportsFiles =
+      Args.hasArg(OPT_plugin_opt_thinlto_emit_imports_files);
+  Config->ThinLTOIndexOnly = Args.hasArg(OPT_plugin_opt_thinlto_index_only) ||
+                             Args.hasArg(OPT_plugin_opt_thinlto_index_only_eq);
+  Config->ThinLTOIndexOnlyArg =
+      Args.getLastArgValue(OPT_plugin_opt_thinlto_index_only_eq);
   Config->ThinLTOJobs = args::getInteger(Args, OPT_thinlto_jobs, -1u);
-  ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true);
+  Config->ThinLTOObjectSuffixReplace =
+      getOldNewOptions(Args, OPT_plugin_opt_thinlto_object_suffix_replace_eq);
+  Config->ThinLTOPrefixReplace =
+      getOldNewOptions(Args, OPT_plugin_opt_thinlto_prefix_replace_eq);
   Config->Trace = Args.hasArg(OPT_trace);
   Config->Undefined = args::getStrings(Args, OPT_undefined);
   Config->UndefinedVersion =
       Args.hasFlag(OPT_undefined_version, OPT_no_undefined_version, true);
   Config->UnresolvedSymbols = getUnresolvedSymbolPolicy(Args);
+  Config->WarnBackrefs =
+      Args.hasFlag(OPT_warn_backrefs, OPT_no_warn_backrefs, false);
   Config->WarnCommon = Args.hasFlag(OPT_warn_common, OPT_no_warn_common, false);
   Config->WarnSymbolOrdering =
       Args.hasFlag(OPT_warn_symbol_ordering, OPT_no_warn_symbol_ordering, true);
-  Config->ZCombreloc = !hasZOption(Args, "nocombreloc");
-  Config->ZExecstack = hasZOption(Args, "execstack");
+  Config->ZCombreloc = getZFlag(Args, "combreloc", "nocombreloc", true);
+  Config->ZCopyreloc = getZFlag(Args, "copyreloc", "nocopyreloc", true);
+  Config->ZExecstack = getZFlag(Args, "execstack", "noexecstack", false);
   Config->ZHazardplt = hasZOption(Args, "hazardplt");
-  Config->ZNocopyreloc = hasZOption(Args, "nocopyreloc");
+  Config->ZKeepTextSectionPrefix = getZFlag(
+      Args, "keep-text-section-prefix", "nokeep-text-section-prefix", false);
   Config->ZNodelete = hasZOption(Args, "nodelete");
   Config->ZNodlopen = hasZOption(Args, "nodlopen");
-  Config->ZNow = hasZOption(Args, "now");
+  Config->ZNow = getZFlag(Args, "now", "lazy", false);
   Config->ZOrigin = hasZOption(Args, "origin");
-  Config->ZRelro = !hasZOption(Args, "norelro");
+  Config->ZRelro = getZFlag(Args, "relro", "norelro", true);
   Config->ZRetpolineplt = hasZOption(Args, "retpolineplt");
   Config->ZRodynamic = hasZOption(Args, "rodynamic");
   Config->ZStackSize = args::getZOptionValue(Args, OPT_z, "stack-size", 0);
-  Config->ZText = !hasZOption(Args, "notext");
+  Config->ZText = getZFlag(Args, "text", "notext", true);
   Config->ZWxneeded = hasZOption(Args, "wxneeded");
 
-  // Parse LTO plugin-related options for compatibility with gold.
-  for (auto *Arg : Args.filtered(OPT_plugin_opt)) {
-    StringRef S = Arg->getValue();
-    if (S == "disable-verify")
-      Config->DisableVerify = true;
-    else if (S == "save-temps")
-      Config->SaveTemps = true;
-    else if (S.startswith("O"))
-      Config->LTOO = parseInt(S.substr(1), Arg);
-    else if (S.startswith("lto-partitions="))
-      Config->LTOPartitions = parseInt(S.substr(15), Arg);
-    else if (S.startswith("jobs="))
-      Config->ThinLTOJobs = parseInt(S.substr(5), Arg);
-    else if (S.startswith("mcpu="))
-      parseClangOption(Saver.save("-" + S), Arg->getSpelling());
-    else if (!S.startswith("/") && !S.startswith("-fresolution=") &&
-             !S.startswith("-pass-through=") && !S.startswith("thinlto"))
-      parseClangOption(S, Arg->getSpelling());
-  }
+  // Parse LTO options.
+  if (auto *Arg = Args.getLastArg(OPT_plugin_opt_mcpu_eq))
+    parseClangOption(Saver.save("-mcpu=" + StringRef(Arg->getValue())),
+                     Arg->getSpelling());
+
+  for (auto *Arg : Args.filtered(OPT_plugin_opt))
+    parseClangOption(Arg->getValue(), Arg->getSpelling());
 
   // Parse -mllvm options.
   for (auto *Arg : Args.filtered(OPT_mllvm))
@@ -878,6 +940,10 @@
 }
 
 void LinkerDriver::createFiles(opt::InputArgList &Args) {
+  // For --{push,pop}-state.
+  std::vector<std::tuple<bool, bool, bool>> Stack;
+
+  // Iterate over argv to process input files and positional arguments.
   for (auto *Arg : Args) {
     switch (Arg->getOption().getUnaliasedOption().getID()) {
     case OPT_library:
@@ -928,11 +994,42 @@
         Files.back()->JustSymbols = true;
       }
       break;
+    case OPT_start_group:
+      if (InputFile::IsInGroup)
+        error("nested --start-group");
+      InputFile::IsInGroup = true;
+      break;
+    case OPT_end_group:
+      if (!InputFile::IsInGroup)
+        error("stray --end-group");
+      InputFile::IsInGroup = false;
+      ++InputFile::NextGroupId;
+      break;
     case OPT_start_lib:
+      if (InLib)
+        error("nested --start-lib");
+      if (InputFile::IsInGroup)
+        error("may not nest --start-lib in --start-group");
       InLib = true;
+      InputFile::IsInGroup = true;
       break;
     case OPT_end_lib:
+      if (!InLib)
+        error("stray --end-lib");
       InLib = false;
+      InputFile::IsInGroup = false;
+      ++InputFile::NextGroupId;
+      break;
+    case OPT_push_state:
+      Stack.emplace_back(Config->AsNeeded, Config->Static, InWholeArchive);
+      break;
+    case OPT_pop_state:
+      if (Stack.empty()) {
+        error("unbalanced --push-state/--pop-state");
+        break;
+      }
+      std::tie(Config->AsNeeded, Config->Static, InWholeArchive) = Stack.back();
+      Stack.pop_back();
       break;
     }
   }
@@ -1024,6 +1121,57 @@
             Sym->VersionId = VER_NDX_LOCAL;
 }
 
+// Force Sym to be entered in the output. Used for -u or equivalent.
+template <class ELFT> static void handleUndefined(StringRef Name) {
+  Symbol *Sym = Symtab->find(Name);
+  if (!Sym)
+    return;
+
+  // Since symbol S may not be used inside the program, LTO may
+  // eliminate it. Mark the symbol as "used" to prevent it.
+  Sym->IsUsedInRegularObj = true;
+
+  if (Sym->isLazy())
+    Symtab->fetchLazy<ELFT>(Sym);
+}
+
+template <class ELFT> static bool shouldDemote(Symbol &Sym) {
+  // If all references to a DSO happen to be weak, the DSO is not added to
+  // DT_NEEDED. If that happens, we need to eliminate shared symbols created
+  // from the DSO. Otherwise, they become dangling references that point to a
+  // non-existent DSO.
+  if (auto *S = dyn_cast<SharedSymbol>(&Sym))
+    return !S->getFile<ELFT>().IsNeeded;
+
+  // We are done processing archives, so lazy symbols that were used but not
+  // found can be converted to undefined. We could also just delete the other
+  // lazy symbols, but that seems to be more work than it is worth.
+  return Sym.isLazy() && Sym.IsUsedInRegularObj;
+}
+
+template <class ELFT> static void demoteSymbols() {
+  for (Symbol *Sym : Symtab->getSymbols()) {
+    if (shouldDemote<ELFT>(*Sym)) {
+      bool Used = Sym->Used;
+      replaceSymbol<Undefined>(Sym, nullptr, Sym->getName(), Sym->Binding,
+                               Sym->StOther, Sym->Type);
+      Sym->Used = Used;
+    }
+  }
+}
+
+// Record sections that define symbols mentioned in --keep-unique <symbol>
+// these sections are inelligible for ICF.
+static void findKeepUniqueSections(opt::InputArgList &Args) {
+  for (auto *Arg : Args.filtered(OPT_keep_unique)) {
+    StringRef Name = Arg->getValue();
+    if (auto *Sym = dyn_cast_or_null<Defined>(Symtab->find(Name)))
+      Sym->Section->KeepUnique = true;
+    else
+      warn("could not find symbol " + Name + " to keep unique");
+  }
+}
+
 // Do actual linking. Note that when this function is called,
 // all linker scripts have already been parsed.
 template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
@@ -1088,12 +1236,12 @@
 
   // Handle the `--undefined <sym>` options.
   for (StringRef S : Config->Undefined)
-    Symtab->fetchIfLazy<ELFT>(S);
+    handleUndefined<ELFT>(S);
 
   // If an entry symbol is in a static archive, pull out that file now
   // to complete the symbol table. After this, no new names except a
   // few linker-synthesized ones will be added to the symbol table.
-  Symtab->fetchIfLazy<ELFT>(Config->Entry);
+  handleUndefined<ELFT>(Config->Entry);
 
   // Return if there were name resolution errors.
   if (errorCount())
@@ -1133,10 +1281,18 @@
   for (auto *Arg : Args.filtered(OPT_wrap))
     Symtab->addSymbolWrap<ELFT>(Arg->getValue());
 
+  // Do link-time optimization if given files are LLVM bitcode files.
+  // This compiles bitcode files into real object files.
   Symtab->addCombinedLTOObject<ELFT>();
   if (errorCount())
     return;
 
+  // If -thinlto-index-only is given, we should create only "index
+  // files" and not object files. Index file creation is already done
+  // in addCombinedLTOObject, so we are done if that's the case.
+  if (Config->ThinLTOIndexOnly)
+    return;
+
   // Apply symbol renames for -wrap.
   Symtab->applySymbolWrap();
 
@@ -1183,11 +1339,20 @@
 
   // Do size optimizations: garbage collection, merging of SHF_MERGE sections
   // and identical code folding.
-  markLive<ELFT>();
   decompressSections();
+  splitSections<ELFT>();
+  markLive<ELFT>();
+  demoteSymbols<ELFT>();
   mergeSections();
-  if (Config->ICF)
+  if (Config->ICF) {
+    findKeepUniqueSections(Args);
     doIcf<ELFT>();
+  }
+
+  // Read the callgraph now that we know what was gced or icfed
+  if (auto *Arg = Args.getLastArg(OPT_call_graph_ordering_file))
+    if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
+      readCallGraph(*Buffer);
 
   // Write the result to the file.
   writeResult<ELFT>();
diff --git a/ELF/DriverUtils.cpp b/ELF/DriverUtils.cpp
index c768f92..35e3ba1 100644
--- a/ELF/DriverUtils.cpp
+++ b/ELF/DriverUtils.cpp
@@ -59,18 +59,18 @@
                               OPT_no_color_diagnostics);
   if (!Arg)
     return;
-  else if (Arg->getOption().getID() == OPT_color_diagnostics)
+  if (Arg->getOption().getID() == OPT_color_diagnostics) {
     errorHandler().ColorDiagnostics = true;
-  else if (Arg->getOption().getID() == OPT_no_color_diagnostics)
+  } else if (Arg->getOption().getID() == OPT_no_color_diagnostics) {
     errorHandler().ColorDiagnostics = false;
-  else {
+  } else {
     StringRef S = Arg->getValue();
     if (S == "always")
       errorHandler().ColorDiagnostics = true;
     else if (S == "never")
       errorHandler().ColorDiagnostics = false;
     else if (S != "auto")
-      error("unknown option: -color-diagnostics=" + S);
+      error("unknown option: --color-diagnostics=" + S);
   }
 }
 
@@ -88,6 +88,29 @@
   return cl::TokenizeGNUCommandLine;
 }
 
+// Gold LTO plugin takes a `--plugin-opt foo=bar` option as an alias for
+// `--plugin-opt=foo=bar`. We want to handle `--plugin-opt=foo=` as an
+// option name and `bar` as a value. Unfortunately, OptParser cannot
+// handle an option with a space in it.
+//
+// In this function, we concatenate command line arguments so that
+// `--plugin-opt <foo>` is converted to `--plugin-opt=<foo>`. This is a
+// bit hacky, but looks like it is still better than handling --plugin-opt
+// options by hand.
+static void concatLTOPluginOptions(SmallVectorImpl<const char *> &Args) {
+  SmallVector<const char *, 256> V;
+  for (size_t I = 0, E = Args.size(); I != E; ++I) {
+    StringRef S = Args[I];
+    if ((S == "-plugin-opt" || S == "--plugin-opt") && I + 1 != E) {
+      V.push_back(Saver.save(S + "=" + Args[I + 1]).data());
+      ++I;
+    } else {
+      V.push_back(Args[I]);
+    }
+  }
+  Args = std::move(V);
+}
+
 // Parses a given list of options.
 opt::InputArgList ELFOptTable::parse(ArrayRef<const char *> Argv) {
   // Make InputArgList from string vectors.
@@ -103,6 +126,7 @@
   // Expand response files (arguments in the form of @<filename>)
   // and then parse the argument again.
   cl::ExpandResponseFiles(Saver, getQuotingStyle(Args), Vec);
+  concatLTOPluginOptions(Vec);
   Args = this->ParseArgs(Vec, MissingIndex, MissingCount);
 
   handleColorDiagnostics(Args);
diff --git a/ELF/EhFrame.cpp b/ELF/EhFrame.cpp
index 159108e..20b32c0 100644
--- a/ELF/EhFrame.cpp
+++ b/ELF/EhFrame.cpp
@@ -20,17 +20,16 @@
 #include "Config.h"
 #include "InputSection.h"
 #include "Relocations.h"
+#include "Target.h"
 #include "lld/Common/ErrorHandler.h"
 #include "lld/Common/Strings.h"
 #include "llvm/BinaryFormat/Dwarf.h"
 #include "llvm/Object/ELF.h"
-#include "llvm/Support/Endian.h"
 
 using namespace llvm;
 using namespace llvm::ELF;
 using namespace llvm::dwarf;
 using namespace llvm::object;
-using namespace llvm::support::endian;
 
 using namespace lld;
 using namespace lld::elf;
@@ -72,7 +71,7 @@
   // First 4 bytes of CIE/FDE is the size of the record.
   // If it is 0xFFFFFFFF, the next 8 bytes contain the size instead,
   // but we do not support that format yet.
-  uint64_t V = read32(D.data(), Config->Endianness);
+  uint64_t V = read32(D.data());
   if (V == UINT32_MAX)
     failOn(D.data(), "CIE/FDE too large");
   uint64_t Size = V + 4;
diff --git a/ELF/Filesystem.cpp b/ELF/Filesystem.cpp
index 8d0b5d8..5cf240e 100644
--- a/ELF/Filesystem.cpp
+++ b/ELF/Filesystem.cpp
@@ -44,7 +44,7 @@
 // The calling thread returns almost immediately.
 void elf::unlinkAsync(StringRef Path) {
 // Removing a file is async on windows.
-#if defined(LLVM_ON_WIN32)
+#if defined(_WIN32)
   sys::fs::remove(Path);
 #else
   if (!ThreadsEnabled || !sys::fs::exists(Path) ||
diff --git a/ELF/ICF.cpp b/ELF/ICF.cpp
index ffd6029..f708d96 100644
--- a/ELF/ICF.cpp
+++ b/ELF/ICF.cpp
@@ -78,6 +78,7 @@
 #include "SymbolTable.h"
 #include "Symbols.h"
 #include "SyntheticSections.h"
+#include "Writer.h"
 #include "lld/Common/Threads.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/BinaryFormat/ELF.h"
@@ -162,7 +163,13 @@
 
 // Returns true if section S is subject of ICF.
 static bool isEligible(InputSection *S) {
-  if (!S->Live || !(S->Flags & SHF_ALLOC) || (S->Flags & SHF_WRITE))
+  if (!S->Live || S->KeepUnique || !(S->Flags & SHF_ALLOC))
+    return false;
+
+  // Don't merge writable sections. .data.rel.ro sections are marked as writable
+  // but are semantically read-only.
+  if ((S->Flags & SHF_WRITE) && S->Name != ".data.rel.ro" &&
+      !S->Name.startswith(".data.rel.ro."))
     return false;
 
   // Don't merge read only data sections unless
@@ -181,6 +188,12 @@
   if (S->Name == ".init" || S->Name == ".fini")
     return false;
 
+  // A user program may enumerate sections named with a C identifier using
+  // __start_* and __stop_* symbols. We cannot ICF any such sections because
+  // that could change program semantics.
+  if (isValidCIdentifier(S->Name))
+    return false;
+
   return true;
 }
 
@@ -296,6 +309,13 @@
       A->getSize() != B->getSize() || A->Data != B->Data)
     return false;
 
+  // If two sections have different output sections, we cannot merge them.
+  // FIXME: This doesn't do the right thing in the case where there is a linker
+  // script. We probably need to move output section assignment before ICF to
+  // get the correct behaviour here.
+  if (getOutputSectionName(A) != getOutputSectionName(B))
+    return false;
+
   if (A->AreRelocsRela)
     return constantEq(A, A->template relas<ELFT>(), B,
                       B->template relas<ELFT>());
@@ -362,17 +382,12 @@
 // vector. Therefore, Sections vector can be considered as contiguous
 // groups of sections, grouped by the class.
 //
-// This function calls Fn on every group that starts within [Begin, End).
-// Note that a group must start in that range but doesn't necessarily
-// have to end before End.
+// This function calls Fn on every group within [Begin, End).
 template <class ELFT>
 void ICF<ELFT>::forEachClassRange(size_t Begin, size_t End,
                                   std::function<void(size_t, size_t)> Fn) {
-  if (Begin > 0)
-    Begin = findBoundary(Begin - 1, End);
-
   while (Begin < End) {
-    size_t Mid = findBoundary(Begin, Sections.size());
+    size_t Mid = findBoundary(Begin, End);
     Fn(Begin, Mid);
     Begin = Mid;
   }
@@ -392,12 +407,23 @@
   Current = Cnt % 2;
   Next = (Cnt + 1) % 2;
 
-  // Split sections into 256 shards and call Fn in parallel.
-  size_t NumShards = 256;
+  // Shard into non-overlapping intervals, and call Fn in parallel.
+  // The sharding must be completed before any calls to Fn are made
+  // so that Fn can modify the Chunks in its shard without causing data
+  // races.
+  const size_t NumShards = 256;
   size_t Step = Sections.size() / NumShards;
-  parallelForEachN(0, NumShards, [&](size_t I) {
-    size_t End = (I == NumShards - 1) ? Sections.size() : (I + 1) * Step;
-    forEachClassRange(I * Step, End, Fn);
+  size_t Boundaries[NumShards + 1];
+  Boundaries[0] = 0;
+  Boundaries[NumShards] = Sections.size();
+
+  parallelForEachN(1, NumShards, [&](size_t I) {
+    Boundaries[I] = findBoundary((I - 1) * Step, Sections.size());
+  });
+
+  parallelForEachN(1, NumShards + 1, [&](size_t I) {
+    if (Boundaries[I - 1] < Boundaries[I])
+      forEachClassRange(Boundaries[I - 1], Boundaries[I], Fn);
   });
   ++Cnt;
 }
diff --git a/ELF/InputFiles.cpp b/ELF/InputFiles.cpp
index bb20c83..8e4fbe3 100644
--- a/ELF/InputFiles.cpp
+++ b/ELF/InputFiles.cpp
@@ -38,14 +38,23 @@
 using namespace lld;
 using namespace lld::elf;
 
+bool InputFile::IsInGroup;
+uint32_t InputFile::NextGroupId;
 std::vector<BinaryFile *> elf::BinaryFiles;
 std::vector<BitcodeFile *> elf::BitcodeFiles;
+std::vector<LazyObjFile *> elf::LazyObjFiles;
 std::vector<InputFile *> elf::ObjectFiles;
 std::vector<InputFile *> elf::SharedFiles;
 
 TarWriter *elf::Tar;
 
-InputFile::InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {}
+InputFile::InputFile(Kind K, MemoryBufferRef M)
+    : MB(M), GroupId(NextGroupId), FileKind(K) {
+  // All files within the same --{start,end}-group get the same group ID.
+  // Otherwise, a new file will get a new group ID.
+  if (!IsInGroup)
+    ++NextGroupId;
+}
 
 Optional<MemoryBufferRef> elf::readFile(StringRef Path) {
   // The --chroot option changes our virtual root directory.
@@ -55,7 +64,7 @@
 
   log(Path);
 
-  auto MBOrErr = MemoryBuffer::getFile(Path);
+  auto MBOrErr = MemoryBuffer::getFile(Path, -1, false);
   if (auto EC = MBOrErr.getError()) {
     error("cannot open " + Path + ": " + EC.message());
     return None;
@@ -122,7 +131,17 @@
                               Config->Wordsize);
 
   for (std::unique_ptr<DWARFCompileUnit> &CU : Dwarf->compile_units()) {
-    const DWARFDebugLine::LineTable *LT = Dwarf->getLineTableForUnit(CU.get());
+    auto Report = [](Error Err) {
+      handleAllErrors(std::move(Err),
+                      [](ErrorInfoBase &Info) { warn(Info.message()); });
+    };
+    Expected<const DWARFDebugLine::LineTable *> ExpectedLT =
+        Dwarf->getLineTableForUnit(CU.get(), Report);
+    const DWARFDebugLine::LineTable *LT = nullptr;
+    if (ExpectedLT)
+      LT = *ExpectedLT;
+    else
+      Report(ExpectedLT.takeError());
     if (!LT)
       continue;
     LineTables.push_back(LT);
@@ -390,7 +409,7 @@
     DenseSet<CachedHashStringRef> &ComdatGroups) {
   const ELFFile<ELFT> &Obj = this->getObj();
 
-  ArrayRef<Elf_Shdr> ObjSections = CHECK(this->getObj().sections(), this);
+  ArrayRef<Elf_Shdr> ObjSections = CHECK(Obj.sections(), this);
   uint64_t Size = ObjSections.size();
   this->Sections.resize(Size);
   this->SectionStringTable =
@@ -742,27 +761,28 @@
 }
 
 // Returns a buffer pointing to a member file containing a given symbol.
-std::pair<MemoryBufferRef, uint64_t>
-ArchiveFile::getMember(const Archive::Symbol *Sym) {
+InputFile *ArchiveFile::fetch(const Archive::Symbol &Sym) {
   Archive::Child C =
-      CHECK(Sym->getMember(), toString(this) +
-                                  ": could not get the member for symbol " +
-                                  Sym->getName());
+      CHECK(Sym.getMember(), toString(this) +
+                                 ": could not get the member for symbol " +
+                                 Sym.getName());
 
   if (!Seen.insert(C.getChildOffset()).second)
-    return {MemoryBufferRef(), 0};
+    return nullptr;
 
-  MemoryBufferRef Ret =
+  MemoryBufferRef MB =
       CHECK(C.getMemoryBufferRef(),
             toString(this) +
                 ": could not get the buffer for the member defining symbol " +
-                Sym->getName());
+                Sym.getName());
 
-  if (C.getParent()->isThin() && Tar)
-    Tar->append(relativeToRoot(CHECK(C.getFullName(), this)), Ret.getBuffer());
-  if (C.getParent()->isThin())
-    return {Ret, 0};
-  return {Ret, C.getChildOffset()};
+  if (Tar && C.getParent()->isThin())
+    Tar->append(relativeToRoot(CHECK(C.getFullName(), this)), MB.getBuffer());
+
+  InputFile *File = createObjectFile(
+      MB, getName(), C.getParent()->isThin() ? 0 : C.getChildOffset());
+  File->GroupId = GroupId;
+  return File;
 }
 
 template <class ELFT>
@@ -907,6 +927,11 @@
   std::vector<uint32_t> Versyms = parseVersyms(); // parse .gnu.version
   ArrayRef<Elf_Shdr> Sections = CHECK(this->getObj().sections(), this);
 
+  // System libraries can have a lot of symbols with versions. Using a
+  // fixed buffer for computing the versions name (foo@ver) can save a
+  // lot of allocations.
+  SmallString<0> VersionedNameBuffer;
+
   // Add symbols to the symbol table.
   ArrayRef<Elf_Sym> Syms = this->getGlobalELFSyms();
   for (size_t I = 0; I < Syms.size(); ++I) {
@@ -957,8 +982,9 @@
 
     StringRef VerName =
         this->StringTable.data() + Verdefs[Idx]->getAux()->vda_name;
-    Name = Saver.save(Name + "@" + VerName);
-    Symtab->addShared(Name, *this, Sym, Alignment, Idx);
+    VersionedNameBuffer.clear();
+    Name = (Name + "@" + VerName).toStringRef(VersionedNameBuffer);
+    Symtab->addShared(Saver.save(Name), *this, Sym, Alignment, Idx);
   }
 }
 
@@ -991,8 +1017,9 @@
   case Triple::x86_64:
     return EM_X86_64;
   default:
-    fatal(Path + ": could not infer e_machine from bitcode target triple " +
+    error(Path + ": could not infer e_machine from bitcode target triple " +
           T.str());
+    return EM_NONE;
   }
 }
 
@@ -1001,17 +1028,21 @@
     : InputFile(BitcodeKind, MB) {
   this->ArchiveName = ArchiveName;
 
-  // Here we pass a new MemoryBufferRef which is identified by ArchiveName
-  // (the fully resolved path of the archive) + member name + offset of the
-  // member in the archive.
-  // ThinLTO uses the MemoryBufferRef identifier to access its internal
-  // data structures and if two archives define two members with the same name,
-  // this causes a collision which result in only one of the objects being
-  // taken into consideration at LTO time (which very likely causes undefined
-  // symbols later in the link stage).
-  MemoryBufferRef MBRef(MB.getBuffer(),
-                        Saver.save(ArchiveName + MB.getBufferIdentifier() +
-                                   utostr(OffsetInArchive)));
+  std::string Path = MB.getBufferIdentifier().str();
+  if (Config->ThinLTOIndexOnly)
+    Path = replaceThinLTOSuffix(MB.getBufferIdentifier());
+
+  // ThinLTO assumes that all MemoryBufferRefs given to it have a unique
+  // name. If two archives define two members with the same name, this
+  // causes a collision which result in only one of the objects being taken
+  // into consideration at LTO time (which very likely causes undefined
+  // symbols later in the link stage). So we append file offset to make
+  // filename unique.
+  MemoryBufferRef MBRef(
+      MB.getBuffer(),
+      Saver.save(ArchiveName + Path +
+                 (ArchiveName.empty() ? "" : utostr(OffsetInArchive))));
+
   Obj = CHECK(lto::InputFile::create(MBRef), this);
 
   Triple T(Obj->getTargetTriple());
@@ -1035,7 +1066,7 @@
 static Symbol *createBitcodeSymbol(const std::vector<bool> &KeptComdats,
                                    const lto::InputFile::Symbol &ObjSym,
                                    BitcodeFile &F) {
-  StringRef NameRef = Saver.save(ObjSym.getName());
+  StringRef Name = Saver.save(ObjSym.getName());
   uint32_t Binding = ObjSym.isWeak() ? STB_WEAK : STB_GLOBAL;
 
   uint8_t Type = ObjSym.isTLS() ? STT_TLS : STT_NOTYPE;
@@ -1044,20 +1075,20 @@
 
   int C = ObjSym.getComdatIndex();
   if (C != -1 && !KeptComdats[C])
-    return Symtab->addUndefined<ELFT>(NameRef, Binding, Visibility, Type,
+    return Symtab->addUndefined<ELFT>(Name, Binding, Visibility, Type,
                                       CanOmitFromDynSym, &F);
 
   if (ObjSym.isUndefined())
-    return Symtab->addUndefined<ELFT>(NameRef, Binding, Visibility, Type,
+    return Symtab->addUndefined<ELFT>(Name, Binding, Visibility, Type,
                                       CanOmitFromDynSym, &F);
 
   if (ObjSym.isCommon())
-    return Symtab->addCommon(NameRef, ObjSym.getCommonSize(),
+    return Symtab->addCommon(Name, ObjSym.getCommonSize(),
                              ObjSym.getCommonAlignment(), Binding, Visibility,
                              STT_OBJECT, F);
 
-  return Symtab->addBitcode(NameRef, Binding, Visibility, Type,
-                            CanOmitFromDynSym, F);
+  return Symtab->addBitcode(Name, Binding, Visibility, Type, CanOmitFromDynSym,
+                            F);
 }
 
 template <class ELFT>
@@ -1113,11 +1144,6 @@
                      Data.size(), 0, STB_GLOBAL, nullptr, nullptr);
 }
 
-static bool isBitcode(MemoryBufferRef MB) {
-  using namespace sys::fs;
-  return identify_magic(MB.getBuffer()) == file_magic::bitcode;
-}
-
 InputFile *elf::createObjectFile(MemoryBufferRef MB, StringRef ArchiveName,
                                  uint64_t OffsetInArchive) {
   if (isBitcode(MB))
@@ -1153,9 +1179,9 @@
 }
 
 MemoryBufferRef LazyObjFile::getBuffer() {
-  if (Seen)
+  if (AddedToLink)
     return MemoryBufferRef();
-  Seen = true;
+  AddedToLink = true;
   return MB;
 }
 
@@ -1163,7 +1189,10 @@
   MemoryBufferRef MBRef = getBuffer();
   if (MBRef.getBuffer().empty())
     return nullptr;
-  return createObjectFile(MBRef, ArchiveName, OffsetInArchive);
+
+  InputFile *File = createObjectFile(MBRef, ArchiveName, OffsetInArchive);
+  File->GroupId = GroupId;
+  return File;
 }
 
 template <class ELFT> void LazyObjFile::parse() {
@@ -1216,6 +1245,18 @@
   }
 }
 
+std::string elf::replaceThinLTOSuffix(StringRef Path) {
+  StringRef Suffix = Config->ThinLTOObjectSuffixReplace.first;
+  StringRef Repl = Config->ThinLTOObjectSuffixReplace.second;
+
+  if (!Path.endswith(Suffix)) {
+    error("-thinlto-object-suffix-replace=" + Suffix + ";" + Repl +
+          " was given, but " + Path + " does not end with the suffix");
+    return "";
+  }
+  return (Path.drop_back(Suffix.size()) + Repl).str();
+}
+
 template void ArchiveFile::parse<ELF32LE>();
 template void ArchiveFile::parse<ELF32BE>();
 template void ArchiveFile::parse<ELF64LE>();
diff --git a/ELF/InputFiles.h b/ELF/InputFiles.h
index 8ec5953..072a5df 100644
--- a/ELF/InputFiles.h
+++ b/ELF/InputFiles.h
@@ -46,7 +46,6 @@
 
 using llvm::object::Archive;
 
-class Lazy;
 class Symbol;
 
 // If -reproduce option is given, all input files are written
@@ -113,6 +112,14 @@
   // True if this is an argument for --just-symbols. Usually false.
   bool JustSymbols = 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
+  // group ID. For more info, see checkDependency() in SymbolTable.cpp.
+  uint32_t GroupId;
+  static bool IsInGroup;
+  static uint32_t NextGroupId;
+
 protected:
   InputFile(Kind K, MemoryBufferRef M);
   std::vector<InputSectionBase *> Sections;
@@ -252,11 +259,11 @@
   template <class ELFT> void parse();
   MemoryBufferRef getBuffer();
   InputFile *fetch();
+  bool AddedToLink = false;
 
 private:
   template <class ELFT> void addElfSymbols();
 
-  bool Seen = false;
   uint64_t OffsetInArchive;
 };
 
@@ -267,11 +274,11 @@
   static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }
   template <class ELFT> void parse();
 
-  // Returns a memory buffer for a given symbol and the offset in the archive
-  // for the member. An empty memory buffer and an offset of zero
-  // is returned if we have already returned the same memory buffer.
-  // (So that we don't instantiate same members more than once.)
-  std::pair<MemoryBufferRef, uint64_t> getMember(const Archive::Symbol *Sym);
+  // Pulls out an object file that contains a definition for Sym and
+  // returns it. If the same file was instantiated before, this
+  // function returns a nullptr (so we don't instantiate the same file
+  // more than once.)
+  InputFile *fetch(const Archive::Symbol &Sym);
 
 private:
   std::unique_ptr<Archive> File;
@@ -344,8 +351,15 @@
                             uint64_t OffsetInArchive = 0);
 InputFile *createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName);
 
+inline bool isBitcode(MemoryBufferRef MB) {
+  return identify_magic(MB.getBuffer()) == llvm::file_magic::bitcode;
+}
+
+std::string replaceThinLTOSuffix(StringRef Path);
+
 extern std::vector<BinaryFile *> BinaryFiles;
 extern std::vector<BitcodeFile *> BitcodeFiles;
+extern std::vector<LazyObjFile *> LazyObjFiles;
 extern std::vector<InputFile *> ObjectFiles;
 extern std::vector<InputFile *> SharedFiles;
 
diff --git a/ELF/InputSection.cpp b/ELF/InputSection.cpp
index 49426e8..09bc39e 100644
--- a/ELF/InputSection.cpp
+++ b/ELF/InputSection.cpp
@@ -142,12 +142,8 @@
     return Offset == uint64_t(-1) ? OS->Size : Offset;
   }
   case Regular:
-    return cast<InputSection>(this->Repl)->OutSecOff + Offset;
-  case Synthetic: {
-    auto *IS = cast<InputSection>(this->Repl);
-    // For synthetic sections we treat offset -1 as the end of the section.
-    return IS->OutSecOff + (Offset == uint64_t(-1) ? IS->getSize() : Offset);
-  }
+  case Synthetic:
+    return cast<InputSection>(this)->getOffset(Offset);
   case EHFrame:
     // The file crtbeginT.o has relocations pointing to the start of an empty
     // .eh_frame that is known to be the first in the link. It does that to
@@ -156,8 +152,8 @@
   case Merge:
     const MergeInputSection *MS = cast<MergeInputSection>(this);
     if (InputSection *IS = MS->getParent())
-      return cast<InputSection>(IS->Repl)->OutSecOff + MS->getOffset(Offset);
-    return MS->getOffset(Offset);
+      return IS->getOffset(MS->getParentOffset(Offset));
+    return MS->getParentOffset(Offset);
   }
   llvm_unreachable("invalid section kind");
 }
@@ -177,7 +173,7 @@
     Sec = EH->getParent();
   else
     return cast<OutputSection>(this);
-  return Sec ? cast<InputSection>(Sec->Repl)->getParent() : nullptr;
+  return Sec ? Sec->getParent() : nullptr;
 }
 
 // Decompress section contents if required. Note that this function
@@ -329,7 +325,7 @@
     *To++ = Sections[Idx]->getOutputSection()->SectionIndex;
 }
 
-InputSectionBase *InputSection::getRelocatedSection() {
+InputSectionBase *InputSection::getRelocatedSection() const {
   if (!File || (Type != SHT_RELA && Type != SHT_REL))
     return nullptr;
   ArrayRef<InputSectionBase *> Sections = File->getSections();
@@ -380,17 +376,32 @@
         continue;
       }
 
-      if (RelTy::IsRela) {
-        P->r_addend =
-            Sym.getVA(getAddend<ELFT>(Rel)) - Section->getOutputSection()->Addr;
-      } else if (Config->Relocatable) {
-        const uint8_t *BufLoc = Sec->Data.begin() + Rel.r_offset;
-        Sec->Relocations.push_back({R_ABS, Type, Rel.r_offset,
-                                    Target->getImplicitAddend(BufLoc, Type),
-                                    &Sym});
-      }
-    }
+      int64_t Addend = getAddend<ELFT>(Rel);
+      const uint8_t *BufLoc = Sec->Data.begin() + Rel.r_offset;
+      if (!RelTy::IsRela)
+        Addend = Target->getImplicitAddend(BufLoc, Type);
 
+      if (Config->EMachine == EM_MIPS && Config->Relocatable &&
+          Target->getRelExpr(Type, Sym, BufLoc) == R_MIPS_GOTREL) {
+        // Some MIPS relocations depend on "gp" value. By default,
+        // this value has 0x7ff0 offset from a .got section. But
+        // relocatable files produced by a complier or a linker
+        // might redefine this default value and we must use it
+        // for a calculation of the relocation result. When we
+        // generate EXE or DSO it's trivial. Generating a relocatable
+        // output is more difficult case because the linker does
+        // not calculate relocations in this mode and loses
+        // individual "gp" values used by each input object file.
+        // As a workaround we add the "gp" value to the relocation
+        // addend and save it back to the file.
+        Addend += Sec->getFile<ELFT>()->MipsGp0;
+      }
+
+      if (RelTy::IsRela)
+        P->r_addend = Sym.getVA(Addend) - Section->getOutputSection()->Addr;
+      else if (Config->Relocatable)
+        Sec->Relocations.push_back({R_ABS, Type, Rel.r_offset, Addend, &Sym});
+    }
   }
 }
 
@@ -570,25 +581,27 @@
   case R_PLT:
     return Sym.getPltVA() + A;
   case R_PLT_PC:
-  case R_PPC_PLT_OPD:
+  case R_PPC_CALL_PLT:
     return Sym.getPltVA() + A - P;
-  case R_PPC_OPD: {
+  case R_PPC_CALL: {
     uint64_t SymVA = Sym.getVA(A);
     // If we have an undefined weak symbol, we might get here with a symbol
     // address of zero. That could overflow, but the code must be unreachable,
     // so don't bother doing anything at all.
     if (!SymVA)
       return 0;
-    if (Out::Opd) {
-      // If this is a local call, and we currently have the address of a
-      // function-descriptor, get the underlying code address instead.
-      uint64_t OpdStart = Out::Opd->Addr;
-      uint64_t OpdEnd = OpdStart + Out::Opd->Size;
-      bool InOpd = OpdStart <= SymVA && SymVA < OpdEnd;
-      if (InOpd)
-        SymVA = read64be(&Out::OpdBuf[SymVA - OpdStart]);
-    }
-    return SymVA - P;
+
+    // PPC64 V2 ABI describes two entry points to a function. The global entry
+    // point sets up the TOC base pointer. When calling a local function, the
+    // call should branch to the local entry point rather than the global entry
+    // point. Section 3.4.1 describes using the 3 most significant bits of the
+    // st_other field to find out how many instructions there are between the
+    // local and global entry point.
+    uint8_t StOther = (Sym.StOther >> 5) & 7;
+    if (StOther == 0 || StOther == 1)
+      return SymVA - P;
+
+    return SymVA - P + (1LL << StOther);
   }
   case R_PPC_TOC:
     return getPPC64TocBase() + A;
@@ -618,12 +631,16 @@
   case R_TLSDESC_PAGE:
     return getAArch64Page(InX::Got->getGlobalDynAddr(Sym) + A) -
            getAArch64Page(P);
-  case R_TLSGD:
+  case R_TLSGD_GOT:
+    return InX::Got->getGlobalDynOffset(Sym) + A;
+  case R_TLSGD_GOT_FROM_END:
     return InX::Got->getGlobalDynOffset(Sym) + A - InX::Got->getSize();
   case R_TLSGD_PC:
     return InX::Got->getGlobalDynAddr(Sym) + A - P;
-  case R_TLSLD:
+  case R_TLSLD_GOT_FROM_END:
     return InX::Got->getTlsIndexOff() + A - InX::Got->getSize();
+  case R_TLSLD_GOT:
+      return InX::Got->getTlsIndexOff() + A;
   case R_TLSLD_PC:
     return InX::Got->getTlsIndexVA() + A - P;
   }
@@ -710,10 +727,13 @@
   const unsigned Bits = Config->Wordsize * 8;
 
   for (const Relocation &Rel : Relocations) {
-    uint8_t *BufLoc = Buf + getOffset(Rel.Offset);
+    uint64_t Offset = Rel.Offset;
+    if (auto *Sec = dyn_cast<InputSection>(this))
+      Offset += Sec->OutSecOff;
+    uint8_t *BufLoc = Buf + Offset;
     RelType Type = Rel.Type;
 
-    uint64_t AddrLoc = getVA(Rel.Offset);
+    uint64_t AddrLoc = getOutputSection()->Addr + Offset;
     RelExpr Expr = Rel.Expr;
     uint64_t TargetVA = SignExtend64(
         getRelocTargetVA(Type, Rel.Addend, AddrLoc, *Rel.Sym, Expr), Bits);
@@ -739,11 +759,17 @@
     case R_RELAX_TLS_GD_TO_IE_END:
       Target->relaxTlsGdToIe(BufLoc, Type, TargetVA);
       break;
-    case R_PPC_PLT_OPD:
+    case R_PPC_CALL:
       // Patch a nop (0x60000000) to a ld.
-      if (BufLoc + 8 <= BufEnd && read32be(BufLoc + 4) == 0x60000000)
-        write32be(BufLoc + 4, 0xe8410028); // ld %r2, 40(%r1)
-      LLVM_FALLTHROUGH;
+      if (Rel.Sym->NeedsTocRestore) {
+        if (BufLoc + 8 > BufEnd || read32(BufLoc + 4) != 0x60000000) {
+          error(getErrorLocation(BufLoc) + "call lacks nop, can't restore toc");
+          break;
+        }
+        write32(BufLoc + 4, 0xe8410018); // ld %r2, 24(%r1)
+      }
+      Target->relocateOne(BufLoc, Type, TargetVA);
+      break;
     default:
       Target->relocateOne(BufLoc, Type, TargetVA);
       break;
@@ -822,10 +848,6 @@
 // .eh_frame is a sequence of CIE or FDE records.
 // This function splits an input section into records and returns them.
 template <class ELFT> void EhInputSection::split() {
-  // Early exit if already split.
-  if (!Pieces.empty())
-    return;
-
   if (AreRelocsRela)
     split<ELFT>(relas<ELFT>());
   else
@@ -920,9 +942,9 @@
   else
     splitNonStrings(Data, Entsize);
 
-  if (Config->GcSections && (Flags & SHF_ALLOC))
-    for (uint32_t Off : LiveOffsets)
-      getSectionPiece(Off)->Live = true;
+  OffsetMap.reserve(Pieces.size());
+  for (size_t I = 0, E = Pieces.size(); I != E; ++I)
+    OffsetMap[Pieces[I].InputOff] = I;
 }
 
 template <class It, class T, class Compare>
@@ -939,25 +961,33 @@
 }
 
 // Do binary search to get a section piece at a given input offset.
-SectionPiece *MergeInputSection::getSectionPiece(uint64_t Offset) {
-  if (Data.size() <= Offset)
-    fatal(toString(this) + ": entry is past the end of the section");
+static SectionPiece *findSectionPiece(MergeInputSection *Sec, uint64_t Offset) {
+  if (Sec->Data.size() <= Offset)
+    fatal(toString(Sec) + ": entry is past the end of the section");
 
   // Find the element this offset points to.
   auto I = fastUpperBound(
-      Pieces.begin(), Pieces.end(), Offset,
+      Sec->Pieces.begin(), Sec->Pieces.end(), Offset,
       [](const uint64_t &A, const SectionPiece &B) { return A < B.InputOff; });
   --I;
   return &*I;
 }
 
+SectionPiece *MergeInputSection::getSectionPiece(uint64_t Offset) {
+  // Find a piece starting at a given offset.
+  auto It = OffsetMap.find(Offset);
+  if (It != OffsetMap.end())
+    return &Pieces[It->second];
+
+  // If Offset is not at beginning of a section piece, it is not in the map.
+  // In that case we need to search from the original section piece vector.
+  return findSectionPiece(this, Offset);
+}
+
 // Returns the offset in an output section for a given input offset.
 // Because contents of a mergeable section is not contiguous in output,
 // it is not just an addition to a base output offset.
-uint64_t MergeInputSection::getOffset(uint64_t Offset) const {
-  if (!Live)
-    return 0;
-
+uint64_t MergeInputSection::getParentOffset(uint64_t Offset) const {
   // Find a string starting at a given offset.
   auto It = OffsetMap.find(Offset);
   if (It != OffsetMap.end())
@@ -965,20 +995,12 @@
 
   // If Offset is not at beginning of a section piece, it is not in the map.
   // In that case we need to search from the original section piece vector.
-  const SectionPiece &Piece = *getSectionPiece(Offset);
-  if (!Piece.Live)
-    return 0;
-
+  const SectionPiece &Piece =
+      *findSectionPiece(const_cast<MergeInputSection *>(this), Offset);
   uint64_t Addend = Offset - Piece.InputOff;
   return Piece.OutputOff + Addend;
 }
 
-void MergeInputSection::initOffsetMap() {
-  OffsetMap.reserve(Pieces.size());
-  for (size_t I = 0; I < Pieces.size(); ++I)
-    OffsetMap[Pieces[I].InputOff] = I;
-}
-
 template InputSection::InputSection(ObjFile<ELF32LE> &, const ELF32LE::Shdr &,
                                     StringRef);
 template InputSection::InputSection(ObjFile<ELF32BE> &, const ELF32BE::Shdr &,
diff --git a/ELF/InputSection.h b/ELF/InputSection.h
index 56b5412..7a83bf9 100644
--- a/ELF/InputSection.h
+++ b/ELF/InputSection.h
@@ -61,6 +61,9 @@
 
   unsigned Bss : 1;
 
+  // Set for sections that should not be folded by ICF.
+  unsigned KeepUnique : 1;
+
   // These corresponds to the fields in Elf_Shdr.
   uint32_t Alignment;
   uint64_t Flags;
@@ -78,15 +81,15 @@
   // section.
   uint64_t getOffset(uint64_t Offset) const;
 
-  uint64_t getVA(uint64_t Offset) const;
+  uint64_t getVA(uint64_t Offset = 0) const;
 
 protected:
   SectionBase(Kind SectionKind, StringRef Name, uint64_t Flags,
               uint64_t Entsize, uint64_t Alignment, uint32_t Type,
               uint32_t Info, uint32_t Link)
       : Name(Name), Repl(this), SectionKind(SectionKind), Live(false),
-        Bss(false), Alignment(Alignment), Flags(Flags), Entsize(Entsize),
-        Type(Type), Link(Link), Info(Info) {}
+        Bss(false), KeepUnique(false), Alignment(Alignment), Flags(Flags),
+        Entsize(Entsize), Type(Type), Link(Link), Info(Info) {}
 };
 
 // This corresponds to a section of an input file.
@@ -200,7 +203,7 @@
 // be found by looking at the next one).
 struct SectionPiece {
   SectionPiece(size_t Off, uint32_t Hash, bool Live)
-      : InputOff(Off), Hash(Hash), OutputOff(-1),
+      : InputOff(Off), Hash(Hash), OutputOff(0),
         Live(Live || !Config->GcSections) {}
 
   uint32_t InputOff;
@@ -223,19 +226,14 @@
   static bool classof(const SectionBase *S) { return S->kind() == Merge; }
   void splitIntoPieces();
 
-  // Mark the piece at a given offset live. Used by GC.
-  void markLiveAt(uint64_t Offset) {
-    if (this->Flags & llvm::ELF::SHF_ALLOC)
-      LiveOffsets.insert(Offset);
-  }
-
-  // Translate an offset in the input section to an offset
-  // in the output section.
-  uint64_t getOffset(uint64_t Offset) const;
+  // Translate an offset in the input section to an offset in the parent
+  // MergeSyntheticSection.
+  uint64_t getParentOffset(uint64_t Offset) const;
 
   // Splittable sections are handled as a sequence of data
   // rather than a single large blob of data.
   std::vector<SectionPiece> Pieces;
+  llvm::DenseMap<uint32_t, uint32_t> OffsetMap;
 
   // Returns I'th piece's data. This function is very hot when
   // string merging is enabled, so we want to inline.
@@ -254,15 +252,10 @@
   }
 
   SyntheticSection *getParent() const;
-  void initOffsetMap();
 
 private:
   void splitStrings(ArrayRef<uint8_t> A, size_t Size);
   void splitNonStrings(ArrayRef<uint8_t> A, size_t Size);
-
-  llvm::DenseMap<uint32_t, uint32_t> OffsetMap;
-
-  llvm::DenseSet<uint32_t> LiveOffsets;
 };
 
 struct EhSectionPiece {
@@ -312,6 +305,8 @@
   // beginning of the output section.
   template <class ELFT> void writeTo(uint8_t *Buf);
 
+  uint64_t getOffset(uint64_t Offset) const { return OutSecOff + Offset; }
+
   OutputSection *getParent() const;
 
   // This variable has two usages. Initially, it represents an index in the
@@ -322,7 +317,7 @@
 
   static bool classof(const SectionBase *S);
 
-  InputSectionBase *getRelocatedSection();
+  InputSectionBase *getRelocatedSection() const;
 
   template <class ELFT, class RelTy>
   void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
diff --git a/ELF/LTO.cpp b/ELF/LTO.cpp
index f3d6896..ee55e7c 100644
--- a/ELF/LTO.cpp
+++ b/ELF/LTO.cpp
@@ -20,6 +20,8 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/BinaryFormat/ELF.h"
+#include "llvm/Bitcode/BitcodeReader.h"
+#include "llvm/Bitcode/BitcodeWriter.h"
 #include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/LTO/Caching.h"
 #include "llvm/LTO/Config.h"
@@ -29,7 +31,6 @@
 #include "llvm/Support/Error.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 #include <cstddef>
 #include <memory>
@@ -44,71 +45,91 @@
 using namespace lld;
 using namespace lld::elf;
 
-// This is for use when debugging LTO.
-static void saveBuffer(StringRef Buffer, const Twine &Path) {
+// Creates an empty file to store a list of object files for final
+// linking of distributed ThinLTO.
+static std::unique_ptr<raw_fd_ostream> openFile(StringRef File) {
   std::error_code EC;
-  raw_fd_ostream OS(Path.str(), EC, sys::fs::OpenFlags::F_None);
-  if (EC)
-    error("cannot create " + Path + ": " + EC.message());
-  OS << Buffer;
+  auto Ret =
+      llvm::make_unique<raw_fd_ostream>(File, EC, sys::fs::OpenFlags::F_None);
+  if (EC) {
+    error("cannot open " + File + ": " + EC.message());
+    return nullptr;
+  }
+  return Ret;
 }
 
-static void diagnosticHandler(const DiagnosticInfo &DI) {
-  SmallString<128> ErrStorage;
-  raw_svector_ostream OS(ErrStorage);
-  DiagnosticPrinterRawOStream DP(OS);
-  DI.print(DP);
-  warn(ErrStorage);
+static std::string getThinLTOOutputFile(StringRef ModulePath) {
+  return lto::getThinLTOOutputFile(ModulePath,
+                                   Config->ThinLTOPrefixReplace.first,
+                                   Config->ThinLTOPrefixReplace.second);
 }
 
-static void checkError(Error E) {
-  handleAllErrors(std::move(E),
-                  [&](ErrorInfoBase &EIB) { error(EIB.message()); });
-}
-
-static std::unique_ptr<lto::LTO> createLTO() {
-  lto::Config Conf;
+static lto::Config createConfig() {
+  lto::Config C;
 
   // LLD supports the new relocations.
-  Conf.Options = InitTargetOptionsFromCodeGenFlags();
-  Conf.Options.RelaxELFRelocations = true;
+  C.Options = InitTargetOptionsFromCodeGenFlags();
+  C.Options.RelaxELFRelocations = true;
 
   // Always emit a section per function/datum with LTO.
-  Conf.Options.FunctionSections = true;
-  Conf.Options.DataSections = true;
+  C.Options.FunctionSections = true;
+  C.Options.DataSections = true;
 
   if (Config->Relocatable)
-    Conf.RelocModel = None;
+    C.RelocModel = None;
   else if (Config->Pic)
-    Conf.RelocModel = Reloc::PIC_;
+    C.RelocModel = Reloc::PIC_;
   else
-    Conf.RelocModel = Reloc::Static;
-  Conf.CodeModel = GetCodeModelFromCMModel();
-  Conf.DisableVerify = Config->DisableVerify;
-  Conf.DiagHandler = diagnosticHandler;
-  Conf.OptLevel = Config->LTOO;
-  Conf.CPU = GetCPUStr();
+    C.RelocModel = Reloc::Static;
+
+  C.CodeModel = GetCodeModelFromCMModel();
+  C.DisableVerify = Config->DisableVerify;
+  C.DiagHandler = diagnosticHandler;
+  C.OptLevel = Config->LTOO;
+  C.CPU = GetCPUStr();
 
   // Set up a custom pipeline if we've been asked to.
-  Conf.OptPipeline = Config->LTONewPmPasses;
-  Conf.AAPipeline = Config->LTOAAPipeline;
+  C.OptPipeline = Config->LTONewPmPasses;
+  C.AAPipeline = Config->LTOAAPipeline;
 
   // Set up optimization remarks if we've been asked to.
-  Conf.RemarksFilename = Config->OptRemarksFilename;
-  Conf.RemarksWithHotness = Config->OptRemarksWithHotness;
+  C.RemarksFilename = Config->OptRemarksFilename;
+  C.RemarksWithHotness = Config->OptRemarksWithHotness;
+
+  C.SampleProfile = Config->LTOSampleProfile;
+  C.UseNewPM = Config->LTONewPassManager;
+  C.DebugPassManager = Config->LTODebugPassManager;
 
   if (Config->SaveTemps)
-    checkError(Conf.addSaveTemps(std::string(Config->OutputFile) + ".",
-                                 /*UseInputModulePath*/ true));
-
-  lto::ThinBackend Backend;
-  if (Config->ThinLTOJobs != -1u)
-    Backend = lto::createInProcessThinBackend(Config->ThinLTOJobs);
-  return llvm::make_unique<lto::LTO>(std::move(Conf), Backend,
-                                     Config->LTOPartitions);
+    checkError(C.addSaveTemps(Config->OutputFile.str() + ".",
+                              /*UseInputModulePath*/ true));
+  return C;
 }
 
-BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) {
+BitcodeCompiler::BitcodeCompiler() {
+  // Initialize LTOObj.
+  lto::ThinBackend Backend;
+
+  if (Config->ThinLTOIndexOnly) {
+    StringRef Path = Config->ThinLTOIndexOnlyArg;
+    if (!Path.empty())
+      IndexFile = openFile(Path);
+
+    auto OnIndexWrite = [&](const std::string &Identifier) {
+      ObjectToIndexFileState[Identifier] = true;
+    };
+
+    Backend = lto::createWriteIndexesThinBackend(
+        Config->ThinLTOPrefixReplace.first, Config->ThinLTOPrefixReplace.second,
+        Config->ThinLTOEmitImportsFiles, IndexFile.get(), OnIndexWrite);
+  } else if (Config->ThinLTOJobs != -1U) {
+    Backend = lto::createInProcessThinBackend(Config->ThinLTOJobs);
+  }
+
+  LTOObj = llvm::make_unique<lto::LTO>(createConfig(), Backend,
+                                       Config->LTOPartitions);
+
+  // Initialize UsedStartStop.
   for (Symbol *Sym : Symtab->getSymbols()) {
     StringRef Name = Sym->getName();
     for (StringRef Prefix : {"__start_", "__stop_"})
@@ -126,17 +147,20 @@
 
 void BitcodeCompiler::add(BitcodeFile &F) {
   lto::InputFile &Obj = *F.Obj;
-  unsigned SymNum = 0;
-  std::vector<Symbol *> Syms = F.getSymbols();
+  bool IsExec = !Config->Shared && !Config->Relocatable;
+
+  if (Config->ThinLTOIndexOnly)
+    ObjectToIndexFileState.insert({Obj.getName(), false});
+
+  ArrayRef<Symbol *> Syms = F.getSymbols();
+  ArrayRef<lto::InputFile::Symbol> ObjSyms = Obj.symbols();
   std::vector<lto::SymbolResolution> Resols(Syms.size());
 
-  bool IsExecutable = !Config->Shared && !Config->Relocatable;
-
   // Provide a resolution to the LTO API for each symbol.
-  for (const lto::InputFile::Symbol &ObjSym : Obj.symbols()) {
-    Symbol *Sym = Syms[SymNum];
-    lto::SymbolResolution &R = Resols[SymNum];
-    ++SymNum;
+  for (size_t I = 0, E = Syms.size(); I != E; ++I) {
+    Symbol *Sym = Syms[I];
+    const lto::InputFile::Symbol &ObjSym = ObjSyms[I];
+    lto::SymbolResolution &R = Resols[I];
 
     // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile
     // reports two symbols for module ASM defined. Without this check, lld
@@ -156,7 +180,7 @@
                             UsedStartStop.count(ObjSym.getSectionName());
     const auto *DR = dyn_cast<Defined>(Sym);
     R.FinalDefinitionInLinkageUnit =
-        (IsExecutable || Sym->Visibility != STV_DEFAULT) && DR &&
+        (IsExec || Sym->Visibility != STV_DEFAULT) && DR &&
         // Skip absolute symbols from ELF objects, otherwise PC-rel relocations
         // will be generated by for them, triggering linker errors.
         // Symbol section is always null for bitcode symbols, hence the check
@@ -175,12 +199,28 @@
   checkError(LTOObj->add(std::move(F.Obj), Resols));
 }
 
+static void createEmptyIndex(StringRef ModulePath) {
+  std::string Path = replaceThinLTOSuffix(getThinLTOOutputFile(ModulePath));
+  if (Path.empty())
+    return;
+
+  std::unique_ptr<raw_fd_ostream> OS = openFile(Path + ".thinlto.bc");
+  if (!OS)
+    return;
+
+  ModuleSummaryIndex M(false);
+  M.setSkipModuleByDistributedBackend();
+  WriteIndexToFile(M, *OS);
+
+  if (Config->ThinLTOEmitImportsFiles)
+    openFile(Path + ".imports");
+}
+
 // Merge all the bitcode files we have seen, codegen the result
 // and return the resulting ObjectFile(s).
 std::vector<InputFile *> BitcodeCompiler::compile() {
-  std::vector<InputFile *> Ret;
   unsigned MaxTasks = LTOObj->getMaxTasks();
-  Buff.resize(MaxTasks);
+  Buf.resize(MaxTasks);
   Files.resize(MaxTasks);
 
   // The --thinlto-cache-dir option specifies the path to a directory in which
@@ -197,29 +237,60 @@
   checkError(LTOObj->run(
       [&](size_t Task) {
         return llvm::make_unique<lto::NativeObjectStream>(
-            llvm::make_unique<raw_svector_ostream>(Buff[Task]));
+            llvm::make_unique<raw_svector_ostream>(Buf[Task]));
       },
       Cache));
 
+  // Emit empty index files for non-indexed files
+  if (Config->ThinLTOIndexOnly) {
+    for (auto &Identifier : ObjectToIndexFileState)
+      if (!Identifier.getValue()) {
+        std::string Path = getThinLTOOutputFile(Identifier.getKey());
+        openFile(Path + ".thinlto.bc");
+
+        if (Config->ThinLTOEmitImportsFiles)
+          openFile(Path + ".imports");
+      }
+  }
+
+  // If LazyObjFile has not been added to link, emit empty index files.
+  // This is needed because this is what GNU gold plugin does and we have a
+  // distributed build system that depends on that behavior.
+  if (Config->ThinLTOIndexOnly) {
+    for (LazyObjFile *F : LazyObjFiles)
+      if (!F->AddedToLink && isBitcode(F->MB))
+        createEmptyIndex(F->getName());
+
+    if (!Config->LTOObjPath.empty())
+      saveBuffer(Buf[0], Config->LTOObjPath);
+
+    // ThinLTO with index only option is required to generate only the index
+    // files. After that, we exit from linker and ThinLTO backend runs in a
+    // distributed environment.
+    if (IndexFile)
+      IndexFile->close();
+    return {};
+  }
+
   if (!Config->ThinLTOCacheDir.empty())
     pruneCache(Config->ThinLTOCacheDir, Config->ThinLTOCachePolicy);
 
+  std::vector<InputFile *> Ret;
   for (unsigned I = 0; I != MaxTasks; ++I) {
-    if (Buff[I].empty())
+    if (Buf[I].empty())
       continue;
     if (Config->SaveTemps) {
       if (I == 0)
-        saveBuffer(Buff[I], Config->OutputFile + ".lto.o");
+        saveBuffer(Buf[I], Config->OutputFile + ".lto.o");
       else
-        saveBuffer(Buff[I], Config->OutputFile + Twine(I) + ".lto.o");
+        saveBuffer(Buf[I], Config->OutputFile + Twine(I) + ".lto.o");
     }
-    InputFile *Obj = createObjectFile(MemoryBufferRef(Buff[I], "lto.tmp"));
+    InputFile *Obj = createObjectFile(MemoryBufferRef(Buf[I], "lto.tmp"));
     Ret.push_back(Obj);
   }
 
   for (std::unique_ptr<MemoryBuffer> &File : Files)
     if (File)
       Ret.push_back(createObjectFile(*File));
-
   return Ret;
 }
diff --git a/ELF/LTO.h b/ELF/LTO.h
index 223af50..8803078 100644
--- a/ELF/LTO.h
+++ b/ELF/LTO.h
@@ -24,6 +24,7 @@
 #include "lld/Common/LLVM.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/Support/raw_ostream.h"
 #include <memory>
 #include <vector>
 
@@ -38,6 +39,7 @@
 
 class BitcodeFile;
 class InputFile;
+class LazyObjFile;
 
 class BitcodeCompiler {
 public:
@@ -49,9 +51,11 @@
 
 private:
   std::unique_ptr<llvm::lto::LTO> LTOObj;
-  std::vector<SmallString<0>> Buff;
+  std::vector<SmallString<0>> Buf;
   std::vector<std::unique_ptr<MemoryBuffer>> Files;
   llvm::DenseSet<StringRef> UsedStartStop;
+  std::unique_ptr<llvm::raw_fd_ostream> IndexFile;
+  llvm::StringMap<bool> ObjectToIndexFileState;
 };
 } // namespace elf
 } // namespace lld
diff --git a/ELF/LinkerScript.cpp b/ELF/LinkerScript.cpp
index d3a3d29..9cc836b 100644
--- a/ELF/LinkerScript.cpp
+++ b/ELF/LinkerScript.cpp
@@ -777,9 +777,8 @@
   if (PhdrEntry *L = Ctx->OutSec->PtLoad)
     L->LMAOffset = Ctx->LMAOffset;
 
-  // The Size previously denoted how many InputSections had been added to this
-  // section, and was used for sorting SHF_LINK_ORDER sections. Reset it to
-  // compute the actual size value.
+  // We can call this method multiple times during the creation of
+  // thunks and want to start over calculation each time.
   Sec->Size = 0;
 
   // We visited SectionsCommands from processSectionCommands to
@@ -788,9 +787,9 @@
   for (BaseCommand *Base : Sec->SectionCommands) {
     // This handles the assignments to symbol or to the dot.
     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
-      Cmd->Offset = Dot - Ctx->OutSec->Addr;
+      Cmd->Addr = Dot;
       assignSymbol(Cmd, true);
-      Cmd->Size = Dot - Ctx->OutSec->Addr - Cmd->Offset;
+      Cmd->Size = Dot - Cmd->Addr;
       continue;
     }
 
@@ -802,12 +801,6 @@
       continue;
     }
 
-    // Handle ASSERT().
-    if (auto *Cmd = dyn_cast<AssertCommand>(Base)) {
-      Cmd->Expression();
-      continue;
-    }
-
     // Handle a single input section description command.
     // It calculates and assigns the offsets for each section and also
     // updates the output section size.
@@ -875,6 +868,11 @@
     if (!Sec)
       continue;
 
+    // Handle align (e.g. ".foo : ALIGN(16) { ... }").
+    if (Sec->AlignExpr)
+      Sec->Alignment =
+          std::max<uint32_t>(Sec->Alignment, Sec->AlignExpr().getValue());
+
     // A live output section means that some input section was added to it. It
     // might have been removed (if it was empty synthetic section), but we at
     // least know the flags.
@@ -913,10 +911,6 @@
           error("memory region '" + Sec->LMARegionName + "' not declared");
       }
       Sec->MemRegion = findMemoryRegion(Sec);
-      // Handle align (e.g. ".foo : ALIGN(16) { ... }").
-      if (Sec->AlignExpr)
-        Sec->Alignment =
-            std::max<uint32_t>(Sec->Alignment, Sec->AlignExpr().getValue());
     }
   }
 
@@ -1049,15 +1043,11 @@
 
   for (BaseCommand *Base : SectionCommands) {
     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
+      Cmd->Addr = Dot;
       assignSymbol(Cmd, false);
+      Cmd->Size = Dot - Cmd->Addr;
       continue;
     }
-
-    if (auto *Cmd = dyn_cast<AssertCommand>(Base)) {
-      Cmd->Expression();
-      continue;
-    }
-
     assignOffsets(cast<OutputSection>(Base));
   }
   Ctx = nullptr;
@@ -1121,9 +1111,9 @@
   if (Symbol *Sym = Symtab->find(Name)) {
     if (auto *DS = dyn_cast<Defined>(Sym))
       return {DS->Section, false, DS->Value, Loc};
-    if (auto *SS = dyn_cast<SharedSymbol>(Sym))
-      if (!ErrorOnMissingSection || SS->CopyRelSec)
-        return {SS->CopyRelSec, false, 0, Loc};
+    if (isa<SharedSymbol>(Sym))
+      if (!ErrorOnMissingSection)
+        return {nullptr, false, 0, Loc};
   }
 
   error(Loc + ": symbol not found: " + Name);
diff --git a/ELF/LinkerScript.h b/ELF/LinkerScript.h
index f808849..3b790dd 100644
--- a/ELF/LinkerScript.h
+++ b/ELF/LinkerScript.h
@@ -75,7 +75,6 @@
   AssignmentKind, // . = expr or <sym> = expr
   OutputSectionKind,
   InputSectionKind,
-  AssertKind, // ASSERT(expr)
   ByteKind    // BYTE(expr), SHORT(expr), LONG(expr) or QUAD(expr)
 };
 
@@ -86,10 +85,8 @@
 
 // This represents ". = <expr>" or "<symbol> = <expr>".
 struct SymbolAssignment : BaseCommand {
-  SymbolAssignment(StringRef Name, Expr E, std::string Loc,
-                   std::string CommandString)
-      : BaseCommand(AssignmentKind), Name(Name), Expression(E), Location(Loc),
-        CommandString(CommandString) {}
+  SymbolAssignment(StringRef Name, Expr E, std::string Loc)
+      : BaseCommand(AssignmentKind), Name(Name), Expression(E), Location(Loc) {}
 
   static bool classof(const BaseCommand *C) {
     return C->Kind == AssignmentKind;
@@ -112,11 +109,11 @@
   // A string representation of this command. We use this for -Map.
   std::string CommandString;
 
-  // This is just an offset of this assignment command in the output section.
-  unsigned Offset;
+  // Address of this assignment command.
+  unsigned Addr;
 
-  // Size of this assignment command. This is usually 0, but if you move '.'
-  // or use a BYTE()-family command, this may be greater than 0."
+  // Size of this assignment command. This is usually 0, but if
+  // you move '.' this may be greater than 0.
   unsigned Size;
 };
 
@@ -179,15 +176,6 @@
   std::vector<std::pair<ThunkSection *, uint32_t>> ThunkSections;
 };
 
-// Represents an ASSERT().
-struct AssertCommand : BaseCommand {
-  AssertCommand(Expr E) : BaseCommand(AssertKind), Expression(E) {}
-
-  static bool classof(const BaseCommand *C) { return C->Kind == AssertKind; }
-
-  Expr Expression;
-};
-
 // Represents BYTE(), SHORT(), LONG(), or QUAD().
 struct ByteCommand : BaseCommand {
   ByteCommand(Expr E, unsigned Size, std::string CommandString)
@@ -200,7 +188,11 @@
   std::string CommandString;
 
   Expr Expression;
+
+  // This is just an offset of this assignment command in the output section.
   unsigned Offset;
+
+  // Size of this data command.
   unsigned Size;
 };
 
diff --git a/ELF/MapFile.cpp b/ELF/MapFile.cpp
index f5dcec8..c5984c9 100644
--- a/ELF/MapFile.cpp
+++ b/ELF/MapFile.cpp
@@ -38,58 +38,46 @@
 using namespace lld;
 using namespace lld::elf;
 
-typedef DenseMap<const SectionBase *, SmallVector<Symbol *, 4>> SymbolMapTy;
+typedef DenseMap<const SectionBase *, SmallVector<Defined *, 4>> SymbolMapTy;
 
 static const std::string Indent8 = "        ";          // 8 spaces
 static const std::string Indent16 = "                "; // 16 spaces
 
 // Print out the first three columns of a line.
-static void writeHeader(raw_ostream &OS, uint64_t Addr, uint64_t Size,
-                        uint64_t Align) {
-  int W = Config->Is64 ? 16 : 8;
-  OS << format("%0*llx %0*llx %5lld ", W, Addr, W, Size, Align);
+static void writeHeader(raw_ostream &OS, uint64_t VMA, uint64_t LMA,
+                        uint64_t Size, uint64_t Align) {
+  if (Config->Is64)
+    OS << format("%16llx %16llx %8llx %5lld ", VMA, LMA, Size, Align);
+  else
+    OS << format("%8llx %8llx %8llx %5lld ", VMA, LMA, Size, Align);
 }
 
 // Returns a list of all symbols that we want to print out.
-static std::vector<Symbol *> getSymbols() {
-  std::vector<Symbol *> V;
-  for (InputFile *File : ObjectFiles) {
-    for (Symbol *B : File->getSymbols()) {
-      if (auto *SS = dyn_cast<SharedSymbol>(B))
-        if (SS->CopyRelSec || SS->NeedsPltAddr)
-          V.push_back(SS);
+static std::vector<Defined *> getSymbols() {
+  std::vector<Defined *> V;
+  for (InputFile *File : ObjectFiles)
+    for (Symbol *B : File->getSymbols())
       if (auto *DR = dyn_cast<Defined>(B))
-        if (DR->File == File && !DR->isSection() && DR->Section &&
-            DR->Section->Live)
+        if (!DR->isSection() && DR->Section && DR->Section->Live &&
+            (DR->File == File || DR->NeedsPltAddr || DR->Section->Bss))
           V.push_back(DR);
-    }
-  }
   return V;
 }
 
 // Returns a map from sections to their symbols.
-static SymbolMapTy getSectionSyms(ArrayRef<Symbol *> Syms) {
+static SymbolMapTy getSectionSyms(ArrayRef<Defined *> Syms) {
   SymbolMapTy Ret;
-  for (Symbol *S : Syms) {
-    if (auto *DR = dyn_cast<Defined>(S)) {
-      Ret[DR->Section].push_back(S);
-      continue;
-    }
-
-    SharedSymbol *SS = cast<SharedSymbol>(S);
-    if (SS->CopyRelSec)
-      Ret[SS->CopyRelSec].push_back(S);
-    else
-      Ret[InX::Plt].push_back(S);
-  }
+  for (Defined *DR : Syms)
+    Ret[DR->Section].push_back(DR);
 
   // Sort symbols by address. We want to print out symbols in the
   // order in the output file rather than the order they appeared
   // in the input files.
   for (auto &It : Ret) {
-    SmallVectorImpl<Symbol *> &V = It.second;
-    std::sort(V.begin(), V.end(),
-              [](Symbol *A, Symbol *B) { return A->getVA() < B->getVA(); });
+    SmallVectorImpl<Defined *> &V = It.second;
+    std::stable_sort(V.begin(), V.end(), [](Defined *A, Defined *B) {
+      return A->getVA() < B->getVA();
+    });
   }
   return Ret;
 }
@@ -98,11 +86,14 @@
 // Demangling symbols (which is what toString() does) is slow, so
 // we do that in batch using parallel-for.
 static DenseMap<Symbol *, std::string>
-getSymbolStrings(ArrayRef<Symbol *> Syms) {
+getSymbolStrings(ArrayRef<Defined *> Syms) {
   std::vector<std::string> Str(Syms.size());
   parallelForEachN(0, Syms.size(), [&](size_t I) {
     raw_string_ostream OS(Str[I]);
-    writeHeader(OS, Syms[I]->getVA(), Syms[I]->getSize(), 0);
+    OutputSection *OSec = Syms[I]->getOutputSection();
+    uint64_t VMA = Syms[I]->getVA();
+    uint64_t LMA = OSec ? OSec->getLMA() + VMA - OSec->getVA(0) : 0;
+    writeHeader(OS, VMA, LMA, Syms[I]->getSize(), 1);
     OS << Indent16 << toString(*Syms[I]);
   });
 
@@ -143,7 +134,8 @@
 
   // Print out section pieces.
   for (EhSectionPiece &P : Pieces) {
-    writeHeader(OS, OSec->Addr + P.OutputOff, P.Size, 0);
+    writeHeader(OS, OSec->Addr + P.OutputOff, OSec->getLMA() + P.OutputOff,
+                P.Size, 1);
     OS << Indent8 << toString(P.Sec->File) << ":(" << P.Sec->Name << "+0x"
        << Twine::utohexstr(P.InputOff) + ")\n";
   }
@@ -162,18 +154,30 @@
   }
 
   // Collect symbol info that we want to print out.
-  std::vector<Symbol *> Syms = getSymbols();
+  std::vector<Defined *> Syms = getSymbols();
   SymbolMapTy SectionSyms = getSectionSyms(Syms);
   DenseMap<Symbol *, std::string> SymStr = getSymbolStrings(Syms);
 
   // Print out the header line.
   int W = Config->Is64 ? 16 : 8;
-  OS << left_justify("Address", W) << ' ' << left_justify("Size", W)
-     << " Align Out     In      Symbol\n";
+  OS << right_justify("VMA", W) << ' ' << right_justify("LMA", W)
+     << "     Size Align Out     In      Symbol\n";
 
-  // Print out file contents.
-  for (OutputSection *OSec : OutputSections) {
-    writeHeader(OS, OSec->Addr, OSec->Size, OSec->Alignment);
+  for (BaseCommand *Base : Script->SectionCommands) {
+    if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
+      if (Cmd->Provide && !Cmd->Sym)
+        continue;
+      //FIXME: calculate and print LMA.
+      writeHeader(OS, Cmd->Addr, 0, Cmd->Size, 1);
+      OS << Cmd->CommandString << '\n';
+      continue;
+    }
+
+    auto *OSec = dyn_cast<OutputSection>(Base);
+    if (!OSec)
+      continue;
+
+    writeHeader(OS, OSec->Addr, OSec->getLMA(), OSec->Size, OSec->Alignment);
     OS << OSec->Name << '\n';
 
     // Dump symbols for each input section.
@@ -185,7 +189,8 @@
             continue;
           }
 
-          writeHeader(OS, IS->getVA(0), IS->getSize(), IS->Alignment);
+          writeHeader(OS, IS->getVA(0), OSec->getLMA() + IS->getOffset(0),
+                      IS->getSize(), IS->Alignment);
           OS << Indent8 << toString(IS) << '\n';
           for (Symbol *Sym : SectionSyms[IS])
             OS << SymStr[Sym] << '\n';
@@ -194,13 +199,17 @@
       }
 
       if (auto *Cmd = dyn_cast<ByteCommand>(Base)) {
-        writeHeader(OS, OSec->Addr + Cmd->Offset, Cmd->Size, 1);
+        writeHeader(OS, OSec->Addr + Cmd->Offset, OSec->getLMA() + Cmd->Offset,
+                    Cmd->Size, 1);
         OS << Indent8 << Cmd->CommandString << '\n';
         continue;
       }
 
       if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
-        writeHeader(OS, OSec->Addr + Cmd->Offset, Cmd->Size, 1);
+        if (Cmd->Provide && !Cmd->Sym)
+          continue;
+        writeHeader(OS, Cmd->Addr, OSec->getLMA() + Cmd->Addr - OSec->getVA(0),
+                    Cmd->Size, 1);
         OS << Indent8 << Cmd->CommandString << '\n';
         continue;
       }
diff --git a/ELF/MarkLive.cpp b/ELF/MarkLive.cpp
index 6b80e8e..bacbf0e 100644
--- a/ELF/MarkLive.cpp
+++ b/ELF/MarkLive.cpp
@@ -159,10 +159,6 @@
   if (!EH.NumRelocations)
     return;
 
-  // Unfortunately we need to split .eh_frame early since some relocations in
-  // .eh_frame keep other section alive and some don't.
-  EH.split<ELFT>();
-
   if (EH.AreRelocsRela)
     scanEhFrameSection<ELFT>(EH, EH.template relas<ELFT>(), Fn);
   else
@@ -207,7 +203,7 @@
     // (splittable) sections, each piece of data has independent liveness bit.
     // So we explicitly tell it which offset is in use.
     if (auto *MS = dyn_cast<MergeInputSection>(Sec))
-      MS->markLiveAt(Offset);
+      MS->getSectionPiece(Offset)->Live = true;
 
     if (Sec->Live)
       return;
@@ -279,13 +275,18 @@
 
   // The -gc-sections option works only for SHF_ALLOC sections
   // (sections that are memory-mapped at runtime). So we can
-  // unconditionally make non-SHF_ALLOC sections alive.
+  // unconditionally make non-SHF_ALLOC sections alive except
+  // SHF_LINK_ORDER and SHT_REL/SHT_RELA sections.
   //
-  // Non SHF_ALLOC sections are not removed even if they are
+  // Usually, SHF_ALLOC sections are not removed even if they are
   // unreachable through relocations because reachability is not
   // a good signal whether they are garbage or not (e.g. there is
   // usually no section referring to a .comment section, but we
-  // want to keep it.)
+  // want to keep it.).
+  //
+  // Note on SHF_LINK_ORDER: Such sections contain metadata and they
+  // have a reverse dependency on the InputSection they are linked with.
+  // We are able to garbage collect them.
   //
   // Note on SHF_REL{,A}: Such sections reach here only when -r
   // or -emit-reloc were given. And they are subject of garbage
@@ -293,8 +294,9 @@
   // remove its relocation section.
   for (InputSectionBase *Sec : InputSections) {
     bool IsAlloc = (Sec->Flags & SHF_ALLOC);
+    bool IsLinkOrder = (Sec->Flags & SHF_LINK_ORDER);
     bool IsRel = (Sec->Type == SHT_REL || Sec->Type == SHT_RELA);
-    if (!IsAlloc && !IsRel)
+    if (!IsAlloc && !IsLinkOrder && !IsRel)
       Sec->Live = true;
   }
 
diff --git a/ELF/Options.td b/ELF/Options.td
index 82a2a1c..256dc5a 100644
--- a/ELF/Options.td
+++ b/ELF/Options.td
@@ -5,9 +5,10 @@
 class F<string name>: Flag<["--", "-"], name>;
 class J<string name>: Joined<["--", "-"], name>;
 
-multiclass Eq<string name> {
+multiclass Eq<string name, string help> {
   def NAME: Separate<["--", "-"], name>;
-  def NAME # _eq: Joined<["--", "-"], name # "=">, Alias<!cast<Separate>(NAME)>;
+  def NAME # _eq: Joined<["--", "-"], name # "=">, Alias<!cast<Separate>(NAME)>,
+    HelpText<help>;
 }
 
 multiclass B<string name, string help1, string help2> {
@@ -15,48 +16,46 @@
   def no_ # NAME: Flag<["--", "-"], "no-" # name>, HelpText<help2>;
 }
 
-defm auxiliary: Eq<"auxiliary">,
-  HelpText<"Set DT_AUXILIARY field to the specified name">;
+defm auxiliary: Eq<"auxiliary", "Set DT_AUXILIARY field to the specified name">;
 
 def Bsymbolic: F<"Bsymbolic">, HelpText<"Bind defined symbols locally">;
 
 def Bsymbolic_functions: F<"Bsymbolic-functions">,
   HelpText<"Bind defined function symbols locally">;
 
-def Bdynamic: F<"Bdynamic">, HelpText<"Link against shared libraries">;
+def Bdynamic: F<"Bdynamic">, HelpText<"Link against shared libraries (default)">;
 
 def Bstatic: F<"Bstatic">, HelpText<"Do not link against shared libraries">;
 
-def build_id: F<"build-id">, HelpText<"Generate build ID note">;
+def build_id: F<"build-id">, HelpText<"Alias for --build-id=fast">;
 
-def build_id_eq: J<"build-id=">, HelpText<"Generate build ID note">;
+def build_id_eq: J<"build-id=">, HelpText<"Generate build ID note">,
+  MetaVarName<"[fast,md5,sha,uuid,0x<hexstring>]">;
 
-defm check_sections : B<"check-sections",
-    "Check section addresses for overlaps",
+defm check_sections: B<"check-sections",
+    "Check section addresses for overlaps (default)",
     "Do not check section addresses for overlaps">;
 
-defm compress_debug_sections : Eq<"compress-debug-sections">,
-  HelpText<"Compress DWARF debug sections">;
+defm compress_debug_sections:
+  Eq<"compress-debug-sections", "Compress DWARF debug sections">,
+  MetaVarName<"[none,zlib]">;
 
-defm defsym: Eq<"defsym">, HelpText<"Define a symbol alias">;
+defm defsym: Eq<"defsym", "Define a symbol alias">, MetaVarName<"<symbol>=<value>">;
 
-defm library_path: Eq<"library-path">,
-  HelpText<"Add a directory to the library search path">, MetaVarName<"<dir>">;
+defm library_path:
+  Eq<"library-path", "Add a directory to the library search path">, MetaVarName<"<dir>">;
 
 def O: JoinedOrSeparate<["-"], "O">, HelpText<"Optimize output file size">;
 
-defm Tbss: Eq<"Tbss">,
-  HelpText<"Same as --section-start with .bss as the sectionname">;
+defm Tbss: Eq<"Tbss", "Same as --section-start with .bss as the sectionname">;
 
-defm Tdata: Eq<"Tdata">,
-  HelpText<"Same as --section-start with .data as the sectionname">;
+defm Tdata: Eq<"Tdata", "Same as --section-start with .data as the sectionname">;
 
-defm Ttext: Eq<"Ttext">,
-  HelpText<"Same as --section-start with .text as the sectionname">;
+defm Ttext: Eq<"Ttext", "Same as --section-start with .text as the sectionname">;
 
 defm allow_multiple_definition: B<"allow-multiple-definition",
     "Allow multiple definitions",
-    "Do not allow multiple definitions">;
+    "Do not allow multiple definitions (default)">;
 
 defm apply_dynamic_relocs: B<"apply-dynamic-relocs",
     "Apply dynamic relocations to place",
@@ -64,16 +63,20 @@
 
 defm as_needed: B<"as-needed",
     "Only set DT_NEEDED for shared libraries if used",
-    "Always set DT_NEEDED for shared libraries">;
+    "Always set DT_NEEDED for shared libraries (default)">;
+
+defm call_graph_ordering_file:
+  Eq<"call-graph-ordering-file", "Layout sections to optimize the given callgraph">;
 
 // -chroot doesn't have a help text because it is an internal option.
-defm chroot: Eq<"chroot">;
+def chroot: Separate<["--", "-"], "chroot">;
 
 def color_diagnostics: F<"color-diagnostics">,
-  HelpText<"Use colors in diagnostics">;
+  HelpText<"Alias for --color-diagnostics=always">;
 
 def color_diagnostics_eq: J<"color-diagnostics=">,
-  HelpText<"Use colors in diagnostics">;
+  HelpText<"Use colors in diagnostics">,
+  MetaVarName<"[auto,always,never]">;
 
 defm cref: B<"cref",
     "Output cross reference table",
@@ -84,7 +87,7 @@
     "Do not assign space to common symbols">;
 
 defm demangle: B<"demangle",
-    "Demangle symbol names",
+    "Demangle symbol names (default)",
     "Do not demangle symbol names">;
 
 def disable_new_dtags: F<"disable-new-dtags">,
@@ -98,11 +101,9 @@
 def discard_none: F<"discard-none">,
   HelpText<"Keep all symbols in the symbol table">;
 
-defm dynamic_linker: Eq<"dynamic-linker">,
-  HelpText<"Which dynamic linker to use">;
+defm dynamic_linker: Eq<"dynamic-linker", "Which dynamic linker to use">;
 
-defm dynamic_list: Eq<"dynamic-list">,
-  HelpText<"Read a list of dynamic symbols">;
+defm dynamic_list: Eq<"dynamic-list", "Read a list of dynamic symbols">;
 
 defm eh_frame_hdr: B<"eh-frame-hdr",
     "Request creation of .eh_frame_hdr section and PT_GNU_EH_FRAME segment header",
@@ -111,67 +112,65 @@
 def emit_relocs: F<"emit-relocs">, HelpText<"Generate relocations in output">;
 
 def enable_new_dtags: F<"enable-new-dtags">,
-  HelpText<"Enable new dynamic tags">;
+  HelpText<"Enable new dynamic tags (default)">;
+
+def end_group: F<"end-group">,
+  HelpText<"Ignored for compatibility with GNU unless you pass --warn-backrefs">;
 
 def end_lib: F<"end-lib">,
   HelpText<"End a grouping of objects that should be treated as if they were together in an archive">;
 
-defm entry: Eq<"entry">, HelpText<"Name of entry point symbol">,
+defm entry: Eq<"entry", "Name of entry point symbol">,
   MetaVarName<"<entry>">;
 
-defm error_limit: Eq<"error-limit">,
-  HelpText<"Maximum number of errors to emit before stopping (0 = no limit)">;
+defm error_limit:
+  Eq<"error-limit", "Maximum number of errors to emit before stopping (0 = no limit)">;
 
 def error_unresolved_symbols: F<"error-unresolved-symbols">,
   HelpText<"Report unresolved symbols as errors">;
 
-defm exclude_libs: Eq<"exclude-libs">,
-  HelpText<"Exclude static libraries from automatic export">;
+defm exclude_libs: Eq<"exclude-libs", "Exclude static libraries from automatic export">;
 
 defm export_dynamic: B<"export-dynamic",
     "Put symbols in the dynamic symbol table",
-    "Do not put symbols in the dynamic symbol table">;
+    "Do not put symbols in the dynamic symbol table (default)">;
 
-defm export_dynamic_symbol: Eq<"export-dynamic-symbol">,
-  HelpText<"Put a symbol in the dynamic symbol table">;
+defm export_dynamic_symbol:
+  Eq<"export-dynamic-symbol", "Put a symbol in the dynamic symbol table">;
 
 defm fatal_warnings: B<"fatal-warnings",
     "Treat warnings as errors",
-    "Do not treat warnings as errors">;
+    "Do not treat warnings as errors (default)">;
 
-defm filter: Eq<"filter">,
-  HelpText<"Set DT_FILTER field to the specified name">;
+defm filter: Eq<"filter", "Set DT_FILTER field to the specified name">;
 
-defm fini: Eq<"fini">,
-  HelpText<"Specify a finalizer function">, MetaVarName<"<symbol>">;
+defm fini: Eq<"fini", "Specify a finalizer function">, MetaVarName<"<symbol>">;
 
 def fix_cortex_a53_843419: F<"fix-cortex-a53-843419">,
   HelpText<"Apply fixes for AArch64 Cortex-A53 erratum 843419">;
 
-defm format: Eq<"format">,
-  HelpText<"Change the input format of the inputs following this option">,
-  MetaVarName<"<input-format>">;
+defm format: Eq<"format", "Change the input format of the inputs following this option">,
+  MetaVarName<"[default,elf,binary]">;
 
 defm gc_sections: B<"gc-sections",
     "Enable garbage collection of unused sections",
-    "Disable garbage collection of unused sections">;
+    "Disable garbage collection of unused sections (default)">;
 
 defm gdb_index: B<"gdb-index",
     "Generate .gdb_index section",
-    "Do not generate .gdb_index section">;
+    "Do not generate .gdb_index section (default)">;
 
 defm gnu_unique: B<"gnu-unique",
-  "Enable STB_GNU_UNIQUE symbol binding",
+  "Enable STB_GNU_UNIQUE symbol binding (default)",
   "Disable STB_GNU_UNIQUE symbol binding">;
 
-defm hash_style: Eq<"hash-style">,
-  HelpText<"Specify hash style (sysv, gnu or both)">;
+defm hash_style: Eq<"hash-style", "Specify hash style (sysv, gnu or both)">;
 
 def help: F<"help">, HelpText<"Print option help">;
 
 def icf_all: F<"icf=all">, HelpText<"Enable identical code folding">;
 
-def icf_none: F<"icf=none">, HelpText<"Disable identical code folding">;
+def icf_none: F<"icf=none">, HelpText<"Disable identical code folding (default)">;
 
 def ignore_function_address_equality: F<"ignore-function-address-equality">,
   HelpText<"lld can break the address equality of functions">;
@@ -179,25 +178,24 @@
 def ignore_data_address_equality: F<"ignore-data-address-equality">,
   HelpText<"lld can break the address equality of data">;
 
-defm image_base : Eq<"image-base">, HelpText<"Set the base address">;
+defm image_base: Eq<"image-base", "Set the base address">;
 
-defm init: Eq<"init">, HelpText<"Specify an initializer function">,
+defm init: Eq<"init", "Specify an initializer function">,
   MetaVarName<"<symbol>">;
 
-defm just_symbols: Eq<"just-symbols">, HelpText<"Just link symbols">;
+defm just_symbols: Eq<"just-symbols", "Just link symbols">;
 
-defm library: Eq<"library">, HelpText<"Root name of library to use">,
+defm keep_unique: Eq<"keep-unique", "Do not fold this symbol during ICF">;
+
+defm library: Eq<"library", "Root name of library to use">,
   MetaVarName<"<libName>">;
 
-def lto_O: J<"lto-O">, MetaVarName<"<opt-level>">,
-  HelpText<"Optimization level for LTO">;
-
 def m: JoinedOrSeparate<["-"], "m">, HelpText<"Set target emulation">;
 
-defm Map: Eq<"Map">, HelpText<"Print a link map to the specified file">;
+defm Map: Eq<"Map", "Print a link map to the specified file">;
 
 defm merge_exidx_entries: B<"merge-exidx-entries",
-    "Enable merging .ARM.exidx entries",
+    "Enable merging .ARM.exidx entries (default)",
     "Disable merging .ARM.exidx entries">;
 
 def nostdlib: F<"nostdlib">,
@@ -230,49 +228,58 @@
 def omagic: Flag<["--"], "omagic">, MetaVarName<"<magic>">,
   HelpText<"Set the text and data sections to be readable and writable">;
 
-defm orphan_handling: Eq<"orphan-handling">,
-  HelpText<"Control how orphan sections are handled when linker script used">;
+defm orphan_handling:
+  Eq<"orphan-handling", "Control how orphan sections are handled when linker script used">;
 
-defm pack_dyn_relocs: Eq<"pack-dyn-relocs">, MetaVarName<"<format>">,
-  HelpText<"Pack dynamic relocations in the given format (none or android)">;
+defm pack_dyn_relocs:
+  Eq<"pack-dyn-relocs", "Pack dynamic relocations in the given format">,
+  MetaVarName<"[none,android]">;
 
 defm pie: B<"pie",
     "Create a position independent executable",
-    "Do not create a position independent executable">;
+    "Do not create a position independent executable (default)">;
 
 defm print_gc_sections: B<"print-gc-sections",
     "List removed unused sections",
-    "Do not list removed unused sections">;
+    "Do not list removed unused sections (default)">;
 
 defm print_icf_sections: B<"print-icf-sections",
     "List identical folded sections",
-    "Do not list identical folded sections">;
+    "Do not list identical folded sections (default)">;
+
+def pop_state: F<"pop-state">,
+  HelpText<"Undo the effect of -push-state">;
+
+def push_state: F<"push-state">,
+  HelpText<"Save the current state of -as-needed, -static and -whole-archive">;
 
 def print_map: F<"print-map">,
   HelpText<"Print a link map to the standard output">;
 
-defm reproduce: Eq<"reproduce">,
-  HelpText<"Dump linker invocation and input files for debugging">;
+defm reproduce: Eq<"reproduce", "Dump linker invocation and input files for debugging">;
 
-defm rpath: Eq<"rpath">, HelpText<"Add a DT_RUNPATH to the output">;
+defm rpath: Eq<"rpath", "Add a DT_RUNPATH to the output">;
 
 def relocatable: F<"relocatable">, HelpText<"Create relocatable object file">;
 
-defm retain_symbols_file: Eq<"retain-symbols-file">,
-  HelpText<"Retain only the symbols listed in the file">,
+defm retain_symbols_file:
+  Eq<"retain-symbols-file", "Retain only the symbols listed in the file">,
   MetaVarName<"<file>">;
 
-defm script: Eq<"script">, HelpText<"Read linker script">;
+defm script: Eq<"script", "Read linker script">;
 
-defm section_start: Eq<"section-start">, MetaVarName<"<address>">,
-  HelpText<"Set address of section">;
+defm section_start: Eq<"section-start", "Set address of section">,
+  MetaVarName<"<address>">;
 
 def shared: F<"shared">, HelpText<"Build a shared object">;
 
-defm soname: Eq<"soname">, HelpText<"Set DT_SONAME">;
+defm soname: Eq<"soname", "Set DT_SONAME">;
 
-defm sort_section: Eq<"sort-section">,
-  HelpText<"Specifies sections sorting rule when linkerscript is used">;
+defm sort_section:
+  Eq<"sort-section", "Specifies sections sorting rule when linkerscript is used">;
+
+def start_group: F<"start-group">,
+  HelpText<"Ignored for compatibility with GNU unless you pass --warn-backrefs">;
 
 def start_lib: F<"start-lib">,
   HelpText<"Start a grouping of objects that should be treated as if they were together in an archive">;
@@ -281,39 +288,39 @@
 
 def strip_debug: F<"strip-debug">, HelpText<"Strip debugging information">;
 
-defm symbol_ordering_file: Eq<"symbol-ordering-file">,
-  HelpText<"Layout sections in the order specified by symbol file">;
+defm symbol_ordering_file:
+  Eq<"symbol-ordering-file", "Layout sections to place symbols in the order specified by symbol ordering file">;
 
-defm sysroot: Eq<"sysroot">, HelpText<"Set the system root">;
+defm sysroot: Eq<"sysroot", "Set the system root">;
 
 def target1_rel: F<"target1-rel">, HelpText<"Interpret R_ARM_TARGET1 as R_ARM_REL32">;
 
-def target1_abs: F<"target1-abs">, HelpText<"Interpret R_ARM_TARGET1 as R_ARM_ABS32">;
+def target1_abs: F<"target1-abs">, HelpText<"Interpret R_ARM_TARGET1 as R_ARM_ABS32 (default)">;
 
-defm target2: Eq<"target2">,
-  HelpText<"Interpret R_ARM_TARGET2 as <type>, where <type> is one of rel, abs, or got-rel">,
+defm target2:
+  Eq<"target2", "Interpret R_ARM_TARGET2 as <type>, where <type> is one of rel, abs, or got-rel">,
   MetaVarName<"<type>">;
 
 defm threads: B<"threads",
-    "Run the linker multi-threaded",
+    "Run the linker multi-threaded (default)",
     "Do not run the linker multi-threaded">;
 
 def trace: F<"trace">, HelpText<"Print the names of the input files">;
 
-defm trace_symbol : Eq<"trace-symbol">, HelpText<"Trace references to symbols">;
+defm trace_symbol: Eq<"trace-symbol", "Trace references to symbols">;
 
-defm undefined: Eq<"undefined">,
-  HelpText<"Force undefined symbol during linking">;
+defm undefined: Eq<"undefined", "Force undefined symbol during linking">,
+  MetaVarName<"<symbol>">;
 
-defm unresolved_symbols: Eq<"unresolved-symbols">,
-  HelpText<"Determine how to handle unresolved symbols">;
+defm unresolved_symbols:
+  Eq<"unresolved-symbols", "Determine how to handle unresolved symbols">;
 
 defm undefined_version: B<"undefined-version",
-  "Allow unused version in version script",
+  "Allow unused version in version script (default)",
   "Report version scripts that refer undefined symbols">;
 
-defm rsp_quoting: Eq<"rsp-quoting">,
-  HelpText<"Quoting style for response files. Values supported: windows|posix">;
+defm rsp_quoting: Eq<"rsp-quoting", "Quoting style for response files">,
+  MetaVarName<"[posix,windows]">;
 
 def v: Flag<["-"], "v">, HelpText<"Display the version number">;
 
@@ -321,14 +328,18 @@
 
 def version: F<"version">, HelpText<"Display the version number and exit">;
 
-defm version_script: Eq<"version-script">, HelpText<"Read a version script">;
+defm version_script: Eq<"version-script", "Read a version script">;
+
+defm warn_backrefs: B<"warn-backrefs",
+    "Warn about backward symbol references to fetch archive members",
+    "Do not warn about backward symbol references to fetch archive members (default)">;
 
 defm warn_common: B<"warn-common",
     "Warn about duplicate common symbols",
-    "Do not warn about duplicate common symbols">;
+    "Do not warn about duplicate common symbols (default)">;
 
-defm warn_symbol_ordering : B<"warn-symbol-ordering",
-    "Warn about problems with the symbol ordering file",
+defm warn_symbol_ordering: B<"warn-symbol-ordering",
+    "Warn about problems with the symbol ordering file (default)",
     "Do not warn about problems with the symbol ordering file">;
 
 def warn_unresolved_symbols: F<"warn-unresolved-symbols">,
@@ -336,83 +347,102 @@
 
 defm whole_archive: B<"whole-archive",
     "Force load of all members in a static library",
-    "Do not force load of all members in a static library">;
+    "Do not force load of all members in a static library (default)">;
 
-defm wrap: Eq<"wrap">, HelpText<"Use wrapper functions for symbol">,
-  MetaVarName<"<symbol>">;
+defm wrap: Eq<"wrap", "Use wrapper functions for symbol">,
+  MetaVarName<"<symbol>=<symbol>">;
 
 def z: JoinedOrSeparate<["-"], "z">, MetaVarName<"<option>">,
   HelpText<"Linker option extensions">;
 
 // Aliases
-def alias_auxiliary: Separate<["-"], "f">, Alias<auxiliary>;
-def alias_Bdynamic_call_shared: F<"call_shared">, Alias<Bdynamic>;
-def alias_Bdynamic_dy: F<"dy">, Alias<Bdynamic>;
-def alias_Bstatic_dn: F<"dn">, Alias<Bstatic>;
-def alias_Bstatic_non_shared: F<"non_shared">, Alias<Bstatic>;
-def alias_Bstatic_static: F<"static">, Alias<Bstatic>;
-def alias_define_common_d: Flag<["-"], "d">, Alias<define_common>;
-def alias_define_common_dc: F<"dc">, Alias<define_common>;
-def alias_define_common_dp: F<"dp">, Alias<define_common>;
-def alias_discard_all_x: Flag<["-"], "x">, Alias<discard_all>;
-def alias_discard_locals_X: Flag<["-"], "X">, Alias<discard_locals>;
-def alias_emit_relocs: Flag<["-"], "q">, Alias<emit_relocs>;
-def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>;
-def alias_export_dynamic_E: Flag<["-"], "E">, Alias<export_dynamic>;
-def alias_filter: Separate<["-"], "F">, Alias<filter>;
-def alias_format_b: Separate<["-"], "b">, Alias<format>;
-def alias_library: JoinedOrSeparate<["-"], "l">, Alias<library>;
-def alias_library_path: JoinedOrSeparate<["-"], "L">, Alias<library_path>;
-def alias_no_pie_pic_executable: F<"no-pic-executable">, Alias<no_pie>;
-def alias_omagic: Flag<["-"], "N">, Alias<omagic>;
-def alias_o_output: Joined<["--"], "output=">, Alias<o>;
-def alias_o_output2 : Separate<["--"], "output">, Alias<o>;
-def alias_pie_pic_executable: F<"pic-executable">, Alias<pie>;
-def alias_print_map_M: Flag<["-"], "M">, Alias<print_map>;
-def alias_relocatable_r: Flag<["-"], "r">, Alias<relocatable>;
-def alias_rpath_R: JoinedOrSeparate<["-"], "R">, Alias<rpath>;
-def alias_script_T: JoinedOrSeparate<["-"], "T">, Alias<script>;
-def alias_shared_Bshareable: F<"Bshareable">, Alias<shared>;
-def alias_soname_h: JoinedOrSeparate<["-"], "h">, Alias<soname>;
-def alias_strip_all: Flag<["-"], "s">, Alias<strip_all>;
-def alias_strip_debug_S: Flag<["-"], "S">, Alias<strip_debug>;
-def alias_trace: Flag<["-"], "t">, Alias<trace>;
-def alias_trace_symbol_y : JoinedOrSeparate<["-"], "y">, Alias<trace_symbol>;
-def alias_Ttext_segment: Separate<["-", "--"], "Ttext-segment">, Alias<Ttext>;
-def alias_Ttext_segment_eq: Joined<["-", "--"], "Ttext-segment=">, Alias<Ttext>;
-def alias_undefined_u: JoinedOrSeparate<["-"], "u">, Alias<undefined>;
-def alias_version_V: Flag<["-"], "V">, Alias<version>;
-
-// Our symbol resolution algorithm handles symbols in archive files differently
-// than traditional linkers, so we don't need --start-group and --end-group.
-// These options are recongized for compatibility but ignored.
-def end_group: F<"end-group">;
-def end_group_paren: Flag<["-"], ")">;
-def start_group: F<"start-group">;
-def start_group_paren: Flag<["-"], "(">;
+def: Separate<["-"], "f">, Alias<auxiliary>, HelpText<"Alias for --auxiliary">;
+def: F<"call_shared">, Alias<Bdynamic>, HelpText<"Alias for --Bdynamic">;
+def: F<"dy">, Alias<Bdynamic>, HelpText<"Alias for --Bdynamic">;
+def: F<"dn">, Alias<Bstatic>, HelpText<"Alias for --Bstatic">;
+def: F<"non_shared">, Alias<Bstatic>, HelpText<"Alias for --Bstatic">;
+def: F<"static">, Alias<Bstatic>, HelpText<"Alias for --Bstatic">;
+def: Flag<["-"], "d">, Alias<define_common>, HelpText<"Alias for --define-common">;
+def: F<"dc">, Alias<define_common>, HelpText<"Alias for --define-common">;
+def: F<"dp">, Alias<define_common>, HelpText<"Alias for --define-common">;
+def: Flag<["-"], "x">, Alias<discard_all>, HelpText<"Alias for --discard-all">;
+def: Flag<["-"], "X">, Alias<discard_locals>, HelpText<"Alias for --discard-locals">;
+def: Flag<["-"], "q">, Alias<emit_relocs>, HelpText<"Alias for --emit-relocs">;
+def: Flag<["-"], ")">, Alias<end_group>, HelpText<"Alias for --end-group">;
+def: JoinedOrSeparate<["-"], "e">, Alias<entry>, HelpText<"Alias for --entry">;
+def: Flag<["-"], "E">, Alias<export_dynamic>, HelpText<"Alias for --export-dynamic">;
+def: Separate<["-"], "F">, Alias<filter>, HelpText<"Alias for --filter">;
+def: Separate<["-"], "b">, Alias<format>, HelpText<"Alias for --format">;
+def: JoinedOrSeparate<["-"], "l">, Alias<library>, HelpText<"Alias for --library">;
+def: JoinedOrSeparate<["-"], "L">, Alias<library_path>, HelpText<"Alias for --library-path">;
+def: F<"no-pic-executable">, Alias<no_pie>, HelpText<"Alias for --no-pie">;
+def: Flag<["-"], "N">, Alias<omagic>, HelpText<"Alias for --omagic">;
+def: Joined<["--"], "output=">, Alias<o>, HelpText<"Alias for -o">;
+def: Separate<["--"], "output">, Alias<o>, HelpText<"Alias for -o">;
+def: F<"pic-executable">, Alias<pie>, HelpText<"Alias for --pie">;
+def: Flag<["-"], "M">, Alias<print_map>, HelpText<"Alias for --print-map">;
+def: Flag<["-"], "r">, Alias<relocatable>, HelpText<"Alias for --relocatable">;
+def: JoinedOrSeparate<["-"], "R">, Alias<rpath>, HelpText<"Alias for --rpath">;
+def: JoinedOrSeparate<["-"], "T">, Alias<script>, HelpText<"Alias for --script">;
+def: F<"Bshareable">, Alias<shared>, HelpText<"Alias for --shared">;
+def: JoinedOrSeparate<["-"], "h">, Alias<soname>, HelpText<"Alias for --soname">;
+def: Flag<["-"], "(">, Alias<start_group>, HelpText<"Alias for --start-group">;
+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: Separate<["-", "--"], "Ttext-segment">, Alias<Ttext>, HelpText<"Alias for --Ttext">;
+def: Joined<["-", "--"], "Ttext-segment=">, Alias<Ttext>, HelpText<"Alias for --Ttext">;
+def: JoinedOrSeparate<["-"], "u">, Alias<undefined>, HelpText<"Alias for --undefined">;
+def: Flag<["-"], "V">, Alias<version>, HelpText<"Alias for --version">;
 
 // LTO-related options.
 def lto_aa_pipeline: J<"lto-aa-pipeline=">,
   HelpText<"AA pipeline to run during LTO. Used in conjunction with -lto-newpm-passes">;
+def lto_debug_pass_manager: F<"lto-debug-pass-manager">,
+  HelpText<"Debug new pass manager">;
+def lto_new_pass_manager: F<"lto-new-pass-manager">,
+  HelpText<"Use new pass manager">;
 def lto_newpm_passes: J<"lto-newpm-passes=">,
   HelpText<"Passes to run during LTO">;
+def lto_O: J<"lto-O">, MetaVarName<"<opt-level>">,
+  HelpText<"Optimization level for LTO">;
 def lto_partitions: J<"lto-partitions=">,
   HelpText<"Number of LTO codegen partitions">;
+def lto_sample_profile: J<"lto-sample-profile=">,
+  HelpText<"Sample profile file path">;
 def disable_verify: F<"disable-verify">;
-defm mllvm: Eq<"mllvm">;
+defm mllvm: Eq<"mllvm", "Additional arguments to forward to LLVM's option processing">;
 def opt_remarks_filename: Separate<["--"], "opt-remarks-filename">,
   HelpText<"YAML output file for optimization remarks">;
 def opt_remarks_with_hotness: Flag<["--"], "opt-remarks-with-hotness">,
   HelpText<"Include hotness information in the optimization remarks file">;
-defm plugin_opt: Eq<"plugin-opt">,
-  HelpText<"specifies LTO options for compatibility with GNU linkers">;
+defm plugin_opt: Eq<"plugin-opt", "specifies LTO options for compatibility with GNU linkers">;
 def save_temps: F<"save-temps">;
 def thinlto_cache_dir: J<"thinlto-cache-dir=">,
   HelpText<"Path to ThinLTO cached object file directory">;
-defm thinlto_cache_policy: Eq<"thinlto-cache-policy">,
-  HelpText<"Pruning policy for the ThinLTO cache">;
+defm thinlto_cache_policy: Eq<"thinlto-cache-policy", "Pruning policy for the ThinLTO cache">;
 def thinlto_jobs: J<"thinlto-jobs=">, HelpText<"Number of ThinLTO jobs">;
 
+def: J<"plugin-opt=O">, Alias<lto_O>, HelpText<"Alias for -lto-O">;
+def: F<"plugin-opt=debug-pass-manager">,
+  Alias<lto_debug_pass_manager>, HelpText<"Alias for -lto-debug-pass-manager">;
+def: F<"plugin-opt=disable-verify">, Alias<disable_verify>, HelpText<"Alias for -disable-verify">;
+def: J<"plugin-opt=jobs=">, Alias<thinlto_jobs>, HelpText<"Alias for -thinlto-jobs">;
+def: J<"plugin-opt=lto-partitions=">, Alias<lto_partitions>, HelpText<"Alias for -lto-partitions">;
+def plugin_opt_mcpu_eq: J<"plugin-opt=mcpu=">;
+def: F<"plugin-opt=new-pass-manager">,
+  Alias<lto_new_pass_manager>, HelpText<"Alias for -lto-new-pass-manager">;
+def plugin_opt_obj_path_eq: J<"plugin-opt=obj-path=">;
+def: J<"plugin-opt=sample-profile=">,
+  Alias<lto_sample_profile>, HelpText<"Alias for -lto-sample-profile">;
+def: F<"plugin-opt=save-temps">, Alias<save_temps>, HelpText<"Alias for -save-temps">;
+def plugin_opt_thinlto_emit_imports_files: F<"plugin-opt=thinlto-emit-imports-files">;
+def plugin_opt_thinlto_index_only: F<"plugin-opt=thinlto-index-only">;
+def plugin_opt_thinlto_index_only_eq: J<"plugin-opt=thinlto-index-only=">;
+def plugin_opt_thinlto_object_suffix_replace_eq: J<"plugin-opt=thinlto-object-suffix-replace=">;
+def plugin_opt_thinlto_prefix_replace_eq: J<"plugin-opt=thinlto-prefix-replace=">;
+
 // Ignore LTO plugin-related options.
 // clang -flto passes -plugin and -plugin-opt to the linker. This is required
 // for ld.gold and ld.bfd to get LTO working. But it's not for lld which doesn't
@@ -420,27 +450,33 @@
 // just ignore the option on lld side as it's easier. In fact, the linker could
 // be called 'ld' and understanding which linker is used would require parsing of
 // --version output.
-defm plugin: Eq<"plugin">;
+defm plugin: Eq<"plugin", "Ignored for compatibility with GNU linkers">;
+
+def plugin_opt_fresolution_eq: J<"plugin-opt=-fresolution=">;
+def plugin_opt_pass_through_eq: J<"plugin-opt=-pass-through=">;
+def plugin_opt_thinlto: J<"plugin-opt=thinlto">;
+def plugin_opt_slash: J<"plugin-opt=/">;
 
 // Options listed below are silently ignored for now for compatibility.
-def allow_shlib_undefined: F<"allow-shlib-undefined">;
-def detect_odr_violations: F<"detect-odr-violations">;
-def g: Flag<["-"], "g">;
-def long_plt: F<"long-plt">;
-def no_add_needed: F<"no-add-needed">;
-def no_allow_shlib_undefined: F<"no-allow-shlib-undefined">;
-def no_copy_dt_needed_entries: F<"no-copy-dt-needed-entries">;
-def no_ctors_in_init_array: F<"no-ctors-in-init-array">;
-def no_keep_memory: F<"no-keep-memory">;
-def no_mmap_output_file: F<"no-mmap-output-file">;
-def no_warn_mismatch: F<"no-warn-mismatch">;
-defm rpath_link: Eq<"rpath-link">;
-def sort_common: F<"sort-common">;
-def stats: F<"stats">;
-def warn_execstack: F<"warn-execstack">;
-def warn_once: F<"warn-once">;
-def warn_shared_textrel: F<"warn-shared-textrel">;
-def EB : F<"EB">;
-def EL : F<"EL">;
-def G: JoinedOrSeparate<["-"], "G">;
-def Qy : F<"Qy">;
+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">;
+def: F<"no-mmap-output-file">;
+def: F<"no-warn-mismatch">;
+def: Separate<["--", "-"], "rpath-link">;
+def: J<"rpath-link=">;
+def: F<"sort-common">;
+def: F<"stats">;
+def: F<"warn-execstack">;
+def: F<"warn-once">;
+def: F<"warn-shared-textrel">;
+def: F<"EB">;
+def: F<"EL">;
+def: JoinedOrSeparate<["-"], "G">;
+def: F<"Qy">;
diff --git a/ELF/OutputSections.cpp b/ELF/OutputSections.cpp
index 8e9e757..31e1d19 100644
--- a/ELF/OutputSections.cpp
+++ b/ELF/OutputSections.cpp
@@ -31,8 +31,6 @@
 using namespace lld::elf;
 
 uint8_t Out::First;
-OutputSection *Out::Opd;
-uint8_t *Out::OpdBuf;
 PhdrEntry *Out::TlsPhdr;
 OutputSection *Out::DebugInfo;
 OutputSection *Out::ElfHeader;
@@ -123,7 +121,6 @@
   Flags = AndFlags | OrFlags;
 
   Alignment = std::max(Alignment, IS->Alignment);
-  IS->OutSecOff = Size++;
 
   // If this section contains a table of fixed-size entries, sh_entsize
   // holds the element size. If it contains elements of different size we
diff --git a/ELF/OutputSections.h b/ELF/OutputSections.h
index 514b9da..9720aab 100644
--- a/ELF/OutputSections.h
+++ b/ELF/OutputSections.h
@@ -128,8 +128,6 @@
 // until Writer is initialized.
 struct Out {
   static uint8_t First;
-  static OutputSection *Opd;
-  static uint8_t *OpdBuf;
   static PhdrEntry *TlsPhdr;
   static OutputSection *DebugInfo;
   static OutputSection *ElfHeader;
diff --git a/ELF/Relocations.cpp b/ELF/Relocations.cpp
index bc4f4b2..5c4a797 100644
--- a/ELF/Relocations.cpp
+++ b/ELF/Relocations.cpp
@@ -198,7 +198,7 @@
     return 1;
   }
 
-  if (isRelExprOneOf<R_TLSLD_PC, R_TLSLD>(Expr)) {
+  if (isRelExprOneOf<R_TLSLD_GOT, R_TLSLD_GOT_FROM_END, R_TLSLD_PC>(Expr)) {
     // Local-Dynamic relocs can be relaxed to Local-Exec.
     if (!Config->Shared) {
       C.Relocations.push_back(
@@ -213,13 +213,14 @@
   }
 
   // Local-Dynamic relocs can be relaxed to Local-Exec.
-  if (isRelExprOneOf<R_ABS, R_TLSLD, R_TLSLD_PC>(Expr) && !Config->Shared) {
+  if (isRelExprOneOf<R_ABS, R_TLSLD_GOT_FROM_END, R_TLSLD_PC>(Expr) &&
+      !Config->Shared) {
     C.Relocations.push_back({R_RELAX_TLS_LD_TO_LE, Type, Offset, Addend, &Sym});
     return 1;
   }
 
-  if (isRelExprOneOf<R_TLSDESC, R_TLSDESC_PAGE, R_TLSDESC_CALL, R_TLSGD,
-                     R_TLSGD_PC>(Expr)) {
+  if (isRelExprOneOf<R_TLSDESC, R_TLSDESC_PAGE, R_TLSDESC_CALL, R_TLSGD_GOT,
+                     R_TLSGD_GOT_FROM_END, R_TLSGD_PC>(Expr)) {
     if (Config->Shared) {
       if (InX::Got->addDynTlsEntry(Sym)) {
         uint64_t Off = InX::Got->getGlobalDynOffset(Sym);
@@ -312,7 +313,7 @@
 
 // Returns true if Expr refers a PLT entry.
 static bool needsPlt(RelExpr Expr) {
-  return isRelExprOneOf<R_PLT_PC, R_PPC_PLT_OPD, R_PLT, R_PLT_PAGE_PC>(Expr);
+  return isRelExprOneOf<R_PLT_PC, R_PPC_CALL_PLT, R_PLT, R_PLT_PAGE_PC>(Expr);
 }
 
 // Returns true if Expr refers a GOT entry. Note that this function
@@ -328,7 +329,8 @@
 // file (PC, or GOT for example).
 static bool isRelExpr(RelExpr Expr) {
   return isRelExprOneOf<R_PC, R_GOTREL, R_GOTREL_FROM_END, R_MIPS_GOTREL,
-                        R_PAGE_PC, R_RELAX_GOT_PC>(Expr);
+                        R_PPC_CALL, R_PPC_CALL_PLT, R_PAGE_PC,
+                        R_RELAX_GOT_PC>(Expr);
 }
 
 // Returns true if a given relocation can be computed at link-time.
@@ -346,9 +348,9 @@
   if (isRelExprOneOf<R_GOT_FROM_END, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE,
                      R_MIPS_GOTREL, R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32,
                      R_MIPS_GOT_GP_PC, R_MIPS_TLSGD, R_GOT_PAGE_PC, R_GOT_PC,
-                     R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_PC,
-                     R_TLSGD, R_PPC_PLT_OPD, R_TLSDESC_CALL, R_TLSDESC_PAGE,
-                     R_HINT>(E))
+                     R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_GOT,
+                     R_TLSGD_GOT_FROM_END, R_TLSGD_PC, R_PPC_CALL_PLT,
+                     R_TLSDESC_CALL, R_TLSDESC_PAGE, R_HINT>(E))
     return true;
 
   // These never do, except if the entire file is position dependent or if
@@ -395,8 +397,8 @@
 
 static RelExpr toPlt(RelExpr Expr) {
   switch (Expr) {
-  case R_PPC_OPD:
-    return R_PPC_PLT_OPD;
+  case R_PPC_CALL:
+    return R_PPC_CALL_PLT;
   case R_PC:
     return R_PLT_PC;
   case R_PAGE_PC:
@@ -414,8 +416,8 @@
   switch (Expr) {
   case R_PLT_PC:
     return R_PC;
-  case R_PPC_PLT_OPD:
-    return R_PPC_OPD;
+  case R_PPC_CALL_PLT:
+    return R_PPC_CALL;
   case R_PLT:
     return R_ABS;
   default:
@@ -461,6 +463,26 @@
   return Ret;
 }
 
+// When a symbol is copy relocated or we create a canonical plt entry, it is
+// effectively a defined symbol. In the case of copy relocation the symbol is
+// in .bss and in the case of a canonical plt entry it is in .plt. This function
+// replaces the existing symbol with a Defined pointing to the appropriate
+// location.
+static void replaceWithDefined(Symbol &Sym, SectionBase *Sec, uint64_t Value,
+                               uint64_t Size) {
+  Symbol Old = Sym;
+  replaceSymbol<Defined>(&Sym, Sym.File, Sym.getName(), Sym.Binding,
+                         Sym.StOther, Sym.Type, Value, Size, Sec);
+  Sym.PltIndex = Old.PltIndex;
+  Sym.GotIndex = Old.GotIndex;
+  Sym.VerdefIndex = Old.VerdefIndex;
+  Sym.IsInGlobalMipsGot = Old.IsInGlobalMipsGot;
+  Sym.IsPreemptible = true;
+  Sym.ExportDynamic = true;
+  Sym.IsUsedInRegularObj = true;
+  Sym.Used = true;
+}
+
 // Reserve space in .bss or .bss.rel.ro for copy relocation.
 //
 // The copy relocation is pretty much a hack. If you use a copy relocation
@@ -522,11 +544,8 @@
   // Look through the DSO's dynamic symbol table for aliases and create a
   // dynamic symbol for each one. This causes the copy relocation to correctly
   // interpose any aliases.
-  for (SharedSymbol *Sym : getSymbolsAt<ELFT>(SS)) {
-    Sym->CopyRelSec = Sec;
-    Sym->IsUsedInRegularObj = true;
-    Sym->Used = true;
-  }
+  for (SharedSymbol *Sym : getSymbolsAt<ELFT>(SS))
+    replaceWithDefined(*Sym, Sec, 0, Sym->Size);
 
   InX::RelaDyn->addReloc(Target->CopyRel, Sec, 0, &SS);
 }
@@ -762,12 +781,12 @@
 // complicates things for the dynamic linker and means we would have to reserve
 // space for the extra PT_LOAD even if we end up not using it.
 template <class ELFT, class RelTy>
-static RelExpr processRelocAux(InputSectionBase &Sec, RelExpr Expr,
-                               RelType Type, uint64_t Offset, Symbol &Sym,
-                               const RelTy &Rel, int64_t Addend) {
+static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type,
+                            uint64_t Offset, Symbol &Sym, const RelTy &Rel,
+                            int64_t Addend) {
   if (isStaticLinkTimeConstant(Expr, Type, Sym, Sec, Offset)) {
     Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
-    return Expr;
+    return;
   }
   bool CanWrite = (Sec.Flags & SHF_WRITE) || !Config->ZText;
   if (CanWrite) {
@@ -777,10 +796,9 @@
     if (!IsPreemptibleValue) {
       InX::RelaDyn->addReloc(Target->RelativeRel, &Sec, Offset, &Sym, Addend,
                              Expr, Type);
-      return Expr;
-    } else if (Target->isPicRel(Type)) {
-      InX::RelaDyn->addReloc(Target->getDynRel(Type), &Sec, Offset, &Sym,
-                             Addend, R_ADDEND, Type);
+      return;
+    } else if (RelType Rel = Target->getDynRel(Type)) {
+      InX::RelaDyn->addReloc(Rel, &Sec, Offset, &Sym, Addend, R_ADDEND, Type);
 
       // MIPS ABI turns using of GOT and dynamic relocations inside out.
       // While regular ABI uses dynamic relocations to fill up GOT entries
@@ -799,7 +817,7 @@
       // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf p.4-19
       if (Config->EMachine == EM_MIPS)
         InX::MipsGot->addEntry(Sym, Addend, Expr);
-      return Expr;
+      return;
     }
   }
 
@@ -807,7 +825,7 @@
   // executable, give up on it and produce a non preemptible 0.
   if (!Config->Shared && Sym.isUndefWeak()) {
     Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
-    return Expr;
+    return;
   }
 
   if (!CanWrite && (Config->Pic && !isRelExpr(Expr))) {
@@ -817,7 +835,7 @@
         " in readonly segment; recompile object files with -fPIC "
         "or pass '-Wl,-z,notext' to allow text relocations in the output" +
         getLocation(Sec, Sym, Offset));
-    return Expr;
+    return;
   }
 
   // Copy relocations are only possible if we are creating an executable.
@@ -825,34 +843,31 @@
     errorOrWarn("relocation " + toString(Type) +
                 " cannot be used against symbol " + toString(Sym) +
                 "; recompile with -fPIC" + getLocation(Sec, Sym, Offset));
-    return Expr;
+    return;
   }
 
   // If the symbol is undefined we already reported any relevant errors.
-  if (!Sym.isShared()) {
-    assert(Sym.isUndefined());
-    return Expr;
-  }
+  if (Sym.isUndefined())
+    return;
 
   if (!canDefineSymbolInExecutable(Sym)) {
     error("cannot preempt symbol: " + toString(Sym) +
           getLocation(Sec, Sym, Offset));
-    return Expr;
+    return;
   }
 
   if (Sym.isObject()) {
     // Produce a copy relocation.
-    auto &SS = cast<SharedSymbol>(Sym);
-    if (!SS.CopyRelSec) {
-      if (Config->ZNocopyreloc)
+    if (auto *SS = dyn_cast<SharedSymbol>(&Sym)) {
+      if (!Config->ZCopyreloc)
         error("unresolvable relocation " + toString(Type) +
-              " against symbol '" + toString(SS) +
+              " against symbol '" + toString(*SS) +
               "'; recompile with -fPIC or remove '-z nocopyreloc'" +
               getLocation(Sec, Sym, Offset));
-      addCopyRelSymbol<ELFT>(SS);
+      addCopyRelSymbol<ELFT>(*SS);
     }
     Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
-    return Expr;
+    return;
   }
 
   if (Sym.isFunc()) {
@@ -887,15 +902,18 @@
       errorOrWarn("symbol '" + toString(Sym) +
                   "' cannot be preempted; recompile with -fPIE" +
                   getLocation(Sec, Sym, Offset));
+    if (!Sym.isInPlt())
+      addPltEntry<ELFT>(InX::Plt, InX::GotPlt, InX::RelaPlt, Target->PltRel,
+                        Sym);
+    if (!Sym.isDefined())
+      replaceWithDefined(Sym, InX::Plt, Sym.getPltOffset(), 0);
     Sym.NeedsPltAddr = true;
-    Expr = toPlt(Expr);
     Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
-    return Expr;
+    return;
   }
 
   errorOrWarn("symbol '" + toString(Sym) + "' has no type" +
               getLocation(Sec, Sym, Offset));
-  return Expr;
 }
 
 template <class ELFT, class RelTy>
@@ -964,7 +982,6 @@
     return;
   }
 
-  Expr = processRelocAux<ELFT>(Sec, Expr, Type, Offset, Sym, Rel, Addend);
   // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.
   if (needsPlt(Expr) && !Sym.isInPlt()) {
     if (Sym.isGnuIFunc() && !Sym.IsPreemptible)
@@ -993,6 +1010,8 @@
       addGotEntry<ELFT>(Sym);
     }
   }
+
+  processRelocAux<ELFT>(Sec, Expr, Type, Offset, Sym, Rel, Addend);
 }
 
 template <class ELFT, class RelTy>
diff --git a/ELF/Relocations.h b/ELF/Relocations.h
index 69afe31..3a930d9 100644
--- a/ELF/Relocations.h
+++ b/ELF/Relocations.h
@@ -59,8 +59,8 @@
   R_PLT,
   R_PLT_PAGE_PC,
   R_PLT_PC,
-  R_PPC_OPD,
-  R_PPC_PLT_OPD,
+  R_PPC_CALL,
+  R_PPC_CALL_PLT,
   R_PPC_TOC,
   R_RELAX_GOT_PC,
   R_RELAX_GOT_PC_NOPIC,
@@ -77,9 +77,11 @@
   R_TLSDESC,
   R_TLSDESC_CALL,
   R_TLSDESC_PAGE,
-  R_TLSGD,
+  R_TLSGD_GOT,
+  R_TLSGD_GOT_FROM_END,
   R_TLSGD_PC,
-  R_TLSLD,
+  R_TLSLD_GOT_FROM_END,
+  R_TLSLD_GOT,
   R_TLSLD_PC,
 };
 
diff --git a/ELF/ScriptParser.cpp b/ELF/ScriptParser.cpp
index ff650d8..707e104 100644
--- a/ELF/ScriptParser.cpp
+++ b/ELF/ScriptParser.cpp
@@ -63,6 +63,7 @@
   void readExtern();
   void readGroup();
   void readInclude();
+  void readInput();
   void readMemory();
   void readOutput();
   void readOutputArch();
@@ -74,7 +75,7 @@
   void readVersion();
   void readVersionScriptCommand();
 
-  SymbolAssignment *readAssignment(StringRef Name);
+  SymbolAssignment *readSymbolAssignment(StringRef Name);
   ByteCommand *readByteCommand(StringRef Tok);
   uint32_t readFill();
   uint32_t parseFill(StringRef Tok);
@@ -88,10 +89,9 @@
   unsigned readPhdrType();
   SortSectionPolicy readSortKind();
   SymbolAssignment *readProvideHidden(bool Provide, bool Hidden);
-  SymbolAssignment *readProvideOrAssignment(StringRef Tok);
+  SymbolAssignment *readAssignment(StringRef Tok);
   void readSort();
-  AssertCommand *readAssert();
-  Expr readAssertExpr();
+  Expr readAssert();
   Expr readConstant();
   Expr getPageSize();
 
@@ -227,16 +227,16 @@
     if (Tok == ";")
       continue;
 
-    if (Tok == "ASSERT") {
-      Script->SectionCommands.push_back(readAssert());
-    } else if (Tok == "ENTRY") {
+    if (Tok == "ENTRY") {
       readEntry();
     } else if (Tok == "EXTERN") {
       readExtern();
-    } else if (Tok == "GROUP" || Tok == "INPUT") {
+    } else if (Tok == "GROUP") {
       readGroup();
     } else if (Tok == "INCLUDE") {
       readInclude();
+    } else if (Tok == "INPUT") {
+      readInput();
     } else if (Tok == "MEMORY") {
       readMemory();
     } else if (Tok == "OUTPUT") {
@@ -255,7 +255,7 @@
       readSections();
     } else if (Tok == "VERSION") {
       readVersion();
-    } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) {
+    } else if (SymbolAssignment *Cmd = readAssignment(Tok)) {
       Script->SectionCommands.push_back(Cmd);
     } else {
       setError("unknown directive: " + Tok);
@@ -267,8 +267,7 @@
   Expr E = readExpr();
   if (!atEOF())
     setError("EOF expected, but got " + next());
-  SymbolAssignment *Cmd = make<SymbolAssignment>(Name, E, getCurrentLocation(),
-                                                 "" /*CommandString*/);
+  SymbolAssignment *Cmd = make<SymbolAssignment>(Name, E, getCurrentLocation());
   Script->SectionCommands.push_back(Cmd);
 }
 
@@ -327,13 +326,12 @@
 }
 
 void ScriptParser::readGroup() {
-  expect("(");
-  while (!errorCount() && !consume(")")) {
-    if (consume("AS_NEEDED"))
-      readAsNeeded();
-    else
-      addFile(unquote(next()));
-  }
+  bool Orig = InputFile::IsInGroup;
+  InputFile::IsInGroup = true;
+  readInput();
+  InputFile::IsInGroup = Orig;
+  if (!Orig)
+    ++InputFile::NextGroupId;
 }
 
 void ScriptParser::readInclude() {
@@ -352,6 +350,16 @@
   setError("cannot find linker script " + Tok);
 }
 
+void ScriptParser::readInput() {
+  expect("(");
+  while (!errorCount() && !consume(")")) {
+    if (consume("AS_NEEDED"))
+      readAsNeeded();
+    else
+      addFile(unquote(next()));
+  }
+}
+
 void ScriptParser::readOutput() {
   // -o <file> takes predecence over OUTPUT(<file>).
   expect("(");
@@ -440,14 +448,10 @@
   std::vector<BaseCommand *> V;
   while (!errorCount() && !consume("}")) {
     StringRef Tok = next();
-    BaseCommand *Cmd = readProvideOrAssignment(Tok);
-    if (!Cmd) {
-      if (Tok == "ASSERT")
-        Cmd = readAssert();
-      else
-        Cmd = readOutputSectionDescription(Tok);
-    }
-    V.push_back(Cmd);
+    if (BaseCommand *Cmd = readAssignment(Tok))
+      V.push_back(Cmd);
+    else
+      V.push_back(readOutputSectionDescription(Tok));
   }
 
   if (!atEOF() && consume("INSERT")) {
@@ -597,11 +601,7 @@
   expect(")");
 }
 
-AssertCommand *ScriptParser::readAssert() {
-  return make<AssertCommand>(readAssertExpr());
-}
-
-Expr ScriptParser::readAssertExpr() {
+Expr ScriptParser::readAssert() {
   expect("(");
   Expr E = readExpr();
   expect(",");
@@ -702,13 +702,10 @@
     StringRef Tok = next();
     if (Tok == ";") {
       // Empty commands are allowed. Do nothing here.
-    } else if (SymbolAssignment *Assign = readProvideOrAssignment(Tok)) {
+    } else if (SymbolAssignment *Assign = readAssignment(Tok)) {
       Cmd->SectionCommands.push_back(Assign);
     } else if (ByteCommand *Data = readByteCommand(Tok)) {
       Cmd->SectionCommands.push_back(Data);
-    } else if (Tok == "ASSERT") {
-      Cmd->SectionCommands.push_back(readAssert());
-      expect(";");
     } else if (Tok == "CONSTRUCTORS") {
       // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors
       // by name. This is for very old file formats such as ECOFF/XCOFF.
@@ -769,31 +766,39 @@
 
 SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) {
   expect("(");
-  SymbolAssignment *Cmd = readAssignment(next());
+  SymbolAssignment *Cmd = readSymbolAssignment(next());
   Cmd->Provide = Provide;
   Cmd->Hidden = Hidden;
   expect(")");
-  expect(";");
   return Cmd;
 }
 
-SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) {
+SymbolAssignment *ScriptParser::readAssignment(StringRef Tok) {
+  // Assert expression returns Dot, so this is equal to ".=."
+  if (Tok == "ASSERT")
+    return make<SymbolAssignment>(".", readAssert(), getCurrentLocation());
+
+  size_t OldPos = Pos;
   SymbolAssignment *Cmd = nullptr;
-  if (peek() == "=" || peek() == "+=") {
-    Cmd = readAssignment(Tok);
-    expect(";");
-  } else if (Tok == "PROVIDE") {
+  if (peek() == "=" || peek() == "+=")
+    Cmd = readSymbolAssignment(Tok);
+  else if (Tok == "PROVIDE")
     Cmd = readProvideHidden(true, false);
-  } else if (Tok == "HIDDEN") {
+  else if (Tok == "HIDDEN")
     Cmd = readProvideHidden(false, true);
-  } else if (Tok == "PROVIDE_HIDDEN") {
+  else if (Tok == "PROVIDE_HIDDEN")
     Cmd = readProvideHidden(true, true);
+
+  if (Cmd) {
+    Cmd->CommandString =
+        Tok.str() + " " +
+        llvm::join(Tokens.begin() + OldPos, Tokens.begin() + Pos, " ");
+    expect(";");
   }
   return Cmd;
 }
 
-SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
-  size_t OldPos = Pos;
+SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef Name) {
   StringRef Op = next();
   assert(Op == "=" || Op == "+=");
   Expr E = readExpr();
@@ -801,11 +806,7 @@
     std::string Loc = getCurrentLocation();
     E = [=] { return add(Script->getSymbolValue(Name, Loc), E()); };
   }
-
-  std::string CommandString =
-      Name.str() + " " +
-      llvm::join(Tokens.begin() + OldPos, Tokens.begin() + Pos, " ");
-  return make<SymbolAssignment>(Name, E, getCurrentLocation(), CommandString);
+  return make<SymbolAssignment>(Name, E, getCurrentLocation());
 }
 
 // This is an operator-precedence parser to parse a linker
@@ -1046,7 +1047,7 @@
     };
   }
   if (Tok == "ASSERT")
-    return readAssertExpr();
+    return readAssert();
   if (Tok == "CONSTANT")
     return readConstant();
   if (Tok == "DATA_SEGMENT_ALIGN") {
diff --git a/ELF/SymbolTable.cpp b/ELF/SymbolTable.cpp
index 40c7d7f..00c7f74 100644
--- a/ELF/SymbolTable.cpp
+++ b/ELF/SymbolTable.cpp
@@ -82,6 +82,7 @@
 
   // Lazy object file
   if (auto *F = dyn_cast<LazyObjFile>(File)) {
+    LazyObjFiles.push_back(F);
     F->parse<ELFT>();
     return;
   }
@@ -296,26 +297,88 @@
   uint8_t Visibility = getVisibility(StOther);
   std::tie(S, WasInserted) =
       insert(Name, Type, Visibility, CanOmitFromDynSym, File);
+
   // An undefined symbol with non default visibility must be satisfied
   // in the same DSO.
   if (WasInserted || (isa<SharedSymbol>(S) && Visibility != STV_DEFAULT)) {
     replaceSymbol<Undefined>(S, File, Name, Binding, StOther, Type);
     return S;
   }
+
   if (S->isShared() || S->isLazy() || (S->isUndefined() && Binding != STB_WEAK))
     S->Binding = Binding;
-  if (Binding != STB_WEAK) {
+
+  if (!Config->GcSections && Binding != STB_WEAK)
     if (auto *SS = dyn_cast<SharedSymbol>(S))
-      if (!Config->GcSections)
-        SS->getFile<ELFT>().IsNeeded = true;
-  }
-  if (auto *L = dyn_cast<Lazy>(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.
-    if (Binding == STB_WEAK)
-      L->Type = Type;
-    else if (InputFile *F = L->fetch())
-      addFile<ELFT>(F);
+    if (Binding == STB_WEAK) {
+      S->Type = Type;
+      return S;
+    }
+
+    // Do extra check for --warn-backrefs.
+    //
+    // --warn-backrefs is an option to prevent an undefined reference from
+    // fetching an archive member written earlier in the command line. It can be
+    // used to keep compatibility with GNU linkers to some degree.
+    // I'll explain the feature and why you may find it useful in this comment.
+    //
+    // lld's symbol resolution semantics is more relaxed than traditional Unix
+    // linkers. For example,
+    //
+    //   ld.lld foo.a bar.o
+    //
+    // succeeds even if bar.o contains an undefined symbol that has to be
+    // resolved by some object file in foo.a. Traditional Unix linkers don't
+    // allow this kind of backward reference, as they visit each file only once
+    // from left to right in the command line while resolving all undefined
+    // symbols at the moment of visiting.
+    //
+    // In the above case, since there's no undefined symbol when a linker visits
+    // foo.a, no files are pulled out from foo.a, and because the linker forgets
+    // about foo.a after visiting, it can't resolve undefined symbols in bar.o
+    // that could have been resolved otherwise.
+    //
+    // That lld accepts more relaxed form means that (besides it'd make more
+    // sense) you can accidentally write a command line or a build file that
+    // works only with lld, even if you have a plan to distribute it to wider
+    // users who may be using GNU linkers. With --warn-backrefs, you can detect
+    // a library order that doesn't work with other Unix linkers.
+    //
+    // The option is also useful to detect cyclic dependencies between static
+    // archives. Again, lld accepts
+    //
+    //   ld.lld foo.a bar.a
+    //
+    // even if foo.a and bar.a depend on each other. With --warn-backrefs, it is
+    // handled as an error.
+    //
+    // Here is how the option works. We assign a group ID to each file. A file
+    // with a smaller group ID can pull out object files from an archive file
+    // with an equal or greater group ID. Otherwise, it is a reverse dependency
+    // and an error.
+    //
+    // A file outside --{start,end}-group gets a fresh ID when instantiated. All
+    // files within the same --{start,end}-group get the same group ID. E.g.
+    //
+    //   ld.lld A B --start-group C D --end-group E
+    //
+    // A forms group 0. B form group 1. C and D (including their member object
+    // files) form group 2. E forms group 3. I think that you can see how this
+    // group assignment rule simulates the traditional linker's semantics.
+    bool Backref =
+        Config->WarnBackrefs && File && S->File->GroupId < File->GroupId;
+    fetchLazy<ELFT>(S);
+
+    // We don't report backward references to weak symbols as they can be
+    // overridden later.
+    if (Backref && S->Binding != STB_WEAK)
+      warn("backward reference detected: " + Name + " in " + toString(File) +
+           " refers to " + toString(S->File));
   }
   return S;
 }
@@ -383,7 +446,11 @@
   bool WasInserted;
   std::tie(S, WasInserted) = insert(N, Type, getVisibility(StOther),
                                     /*CanOmitFromDynSym*/ false, &File);
+
   int Cmp = compareDefined(S, WasInserted, Binding, N);
+  if (Cmp < 0)
+    return S;
+
   if (Cmp > 0) {
     auto *Bss = make<BssSection>("COMMON", Size, Alignment);
     Bss->File = &File;
@@ -391,24 +458,25 @@
     InputSections.push_back(Bss);
 
     replaceSymbol<Defined>(S, &File, N, Binding, StOther, Type, 0, Size, Bss);
-  } else if (Cmp == 0) {
-    auto *D = cast<Defined>(S);
-    auto *Bss = dyn_cast_or_null<BssSection>(D->Section);
-    if (!Bss) {
-      // Non-common symbols take precedence over common symbols.
-      if (Config->WarnCommon)
-        warn("common " + S->getName() + " is overridden");
-      return S;
-    }
+    return S;
+  }
 
+  auto *D = cast<Defined>(S);
+  auto *Bss = dyn_cast_or_null<BssSection>(D->Section);
+  if (!Bss) {
+    // Non-common symbols take precedence over common symbols.
     if (Config->WarnCommon)
-      warn("multiple common of " + D->getName());
+      warn("common " + S->getName() + " is overridden");
+    return S;
+  }
 
-    Bss->Alignment = std::max(Bss->Alignment, Alignment);
-    if (Size > Bss->Size) {
-      D->File = Bss->File = &File;
-      D->Size = Bss->Size = Size;
-    }
+  if (Config->WarnCommon)
+    warn("multiple common of " + D->getName());
+
+  Bss->Alignment = std::max(Bss->Alignment, Alignment);
+  if (Size > Bss->Size) {
+    D->File = Bss->File = &File;
+    D->Size = Bss->Size = Size;
   }
   return S;
 }
@@ -528,14 +596,18 @@
   return SymVector[It->second];
 }
 
-template <class ELFT>
-void SymbolTable::addLazyArchive(StringRef Name, ArchiveFile &F,
-                                 const object::Archive::Symbol Sym) {
+// This is used to handle lazy symbols. May replace existent
+// symbol with lazy version or request to Fetch it.
+template <class ELFT, typename LazyT, typename... ArgT>
+static void replaceOrFetchLazy(StringRef Name, InputFile &File,
+                               llvm::function_ref<InputFile *()> Fetch,
+                               ArgT &&... Arg) {
   Symbol *S;
   bool WasInserted;
-  std::tie(S, WasInserted) = insert(Name);
+  std::tie(S, WasInserted) = Symtab->insert(Name);
   if (WasInserted) {
-    replaceSymbol<LazyArchive>(S, F, Sym, Symbol::UnknownType);
+    replaceSymbol<LazyT>(S, File, Symbol::UnknownType,
+                         std::forward<ArgT>(Arg)...);
     return;
   }
   if (!S->isUndefined())
@@ -544,47 +616,38 @@
   // An undefined weak will not fetch archive members. See comment on Lazy in
   // Symbols.h for the details.
   if (S->isWeak()) {
-    replaceSymbol<LazyArchive>(S, F, Sym, S->Type);
+    replaceSymbol<LazyT>(S, File, S->Type, std::forward<ArgT>(Arg)...);
     S->Binding = STB_WEAK;
     return;
   }
-  std::pair<MemoryBufferRef, uint64_t> MBInfo = F.getMember(&Sym);
-  if (!MBInfo.first.getBuffer().empty())
-    addFile<ELFT>(createObjectFile(MBInfo.first, F.getName(), MBInfo.second));
+
+  if (InputFile *F = Fetch())
+    Symtab->addFile<ELFT>(F);
+}
+
+template <class ELFT>
+void SymbolTable::addLazyArchive(StringRef Name, ArchiveFile &F,
+                                 const object::Archive::Symbol Sym) {
+  replaceOrFetchLazy<ELFT, LazyArchive>(Name, F, [&]() { return F.fetch(Sym); },
+                                        Sym);
 }
 
 template <class ELFT>
 void SymbolTable::addLazyObject(StringRef Name, LazyObjFile &Obj) {
-  Symbol *S;
-  bool WasInserted;
-  std::tie(S, WasInserted) = insert(Name);
-  if (WasInserted) {
-    replaceSymbol<LazyObject>(S, Obj, Name, Symbol::UnknownType);
-    return;
-  }
-  if (!S->isUndefined())
-    return;
-
-  // See comment for addLazyArchive above.
-  if (S->isWeak()) {
-    replaceSymbol<LazyObject>(S, Obj, Name, S->Type);
-    S->Binding = STB_WEAK;
-    return;
-  }
-  if (InputFile *F = Obj.fetch())
-    addFile<ELFT>(F);
+  replaceOrFetchLazy<ELFT, LazyObject>(Name, Obj, [&]() { return Obj.fetch(); },
+                                       Name);
 }
 
-// If we already saw this symbol, force loading its file.
-template <class ELFT> void SymbolTable::fetchIfLazy(StringRef Name) {
-  if (Symbol *B = find(Name)) {
-    // Mark the symbol not to be eliminated by LTO
-    // even if it is a bitcode symbol.
-    B->IsUsedInRegularObj = true;
-    if (auto *L = dyn_cast<Lazy>(B))
-      if (InputFile *File = L->fetch())
-        addFile<ELFT>(File);
+template <class ELFT> void SymbolTable::fetchLazy(Symbol *Sym) {
+  if (auto *S = dyn_cast<LazyArchive>(Sym)) {
+    if (InputFile *File = S->fetch())
+      addFile<ELFT>(File);
+    return;
   }
+
+  auto *S = cast<LazyObject>(Sym);
+  if (InputFile *File = cast<LazyObjFile>(S->File)->fetch())
+    addFile<ELFT>(File);
 }
 
 // Initialize DemangledSyms with a map from demangled symbols to symbol
@@ -795,6 +858,11 @@
 template void SymbolTable::addLazyObject<ELF64LE>(StringRef, LazyObjFile &);
 template void SymbolTable::addLazyObject<ELF64BE>(StringRef, LazyObjFile &);
 
+template void SymbolTable::fetchLazy<ELF32LE>(Symbol *);
+template void SymbolTable::fetchLazy<ELF32BE>(Symbol *);
+template void SymbolTable::fetchLazy<ELF64LE>(Symbol *);
+template void SymbolTable::fetchLazy<ELF64BE>(Symbol *);
+
 template void SymbolTable::addShared<ELF32LE>(StringRef, SharedFile<ELF32LE> &,
                                               const typename ELF32LE::Sym &,
                                               uint32_t Alignment, uint32_t);
@@ -807,8 +875,3 @@
 template void SymbolTable::addShared<ELF64BE>(StringRef, SharedFile<ELF64BE> &,
                                               const typename ELF64BE::Sym &,
                                               uint32_t Alignment, uint32_t);
-
-template void SymbolTable::fetchIfLazy<ELF32LE>(StringRef);
-template void SymbolTable::fetchIfLazy<ELF32BE>(StringRef);
-template void SymbolTable::fetchIfLazy<ELF64LE>(StringRef);
-template void SymbolTable::fetchIfLazy<ELF64BE>(StringRef);
diff --git a/ELF/SymbolTable.h b/ELF/SymbolTable.h
index 7937a2a..5e6d44d 100644
--- a/ELF/SymbolTable.h
+++ b/ELF/SymbolTable.h
@@ -77,7 +77,8 @@
                                    uint8_t Visibility, bool CanOmitFromDynSym,
                                    InputFile *File);
 
-  template <class ELFT> void fetchIfLazy(StringRef Name);
+  template <class ELFT> void fetchLazy(Symbol *Sym);
+
   void scanVersionScript();
 
   Symbol *find(StringRef Name);
diff --git a/ELF/Symbols.cpp b/ELF/Symbols.cpp
index 8ac3e5f..f2f9ae0 100644
--- a/ELF/Symbols.cpp
+++ b/ELF/Symbols.cpp
@@ -38,6 +38,7 @@
 Defined *ElfSym::MipsGp;
 Defined *ElfSym::MipsGpDisp;
 Defined *ElfSym::MipsLocalGp;
+Defined *ElfSym::RelaIpltEnd;
 
 static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {
   switch (Sym.kind()) {
@@ -56,6 +57,8 @@
     if (!IS)
       return D.Value;
 
+    IS = IS->Repl;
+
     uint64_t Offset = D.Value;
 
     // An object in an SHF_MERGE section might be referenced via a
@@ -94,20 +97,12 @@
     }
     return VA;
   }
-  case Symbol::SharedKind: {
-    auto &SS = cast<SharedSymbol>(Sym);
-    if (SS.CopyRelSec)
-      return SS.CopyRelSec->getVA(0);
-    if (SS.NeedsPltAddr)
-      return Sym.getPltVA();
-    return 0;
-  }
+  case Symbol::SharedKind:
   case Symbol::UndefinedKind:
     return 0;
   case Symbol::LazyArchiveKind:
   case Symbol::LazyObjectKind:
-    assert(Sym.IsUsedInRegularObj && "lazy symbol reached writer");
-    return 0;
+    llvm_unreachable("lazy symbol reached writer");
   }
   llvm_unreachable("invalid symbol kind");
 }
@@ -130,7 +125,9 @@
 }
 
 uint64_t Symbol::getGotPltOffset() const {
-  return GotPltIndex * Target->GotPltEntrySize;
+  if (IsInIgot)
+    return PltIndex * Target->GotPltEntrySize;
+  return (PltIndex + Target->GotPltHeaderEntriesNum) * Target->GotPltEntrySize;
 }
 
 uint64_t Symbol::getPltVA() const {
@@ -139,6 +136,11 @@
   return InX::Plt->getVA() + Target->getPltEntryOffset(PltIndex);
 }
 
+uint64_t Symbol::getPltOffset() const {
+  assert(!this->IsInIplt);
+  return Target->getPltEntryOffset(PltIndex);
+}
+
 uint64_t Symbol::getSize() const {
   if (const auto *DR = dyn_cast<Defined>(this))
     return DR->Size;
@@ -150,16 +152,9 @@
 OutputSection *Symbol::getOutputSection() const {
   if (auto *S = dyn_cast<Defined>(this)) {
     if (auto *Sec = S->Section)
-      return Sec->getOutputSection();
+      return Sec->Repl->getOutputSection();
     return nullptr;
   }
-
-  if (auto *S = dyn_cast<SharedSymbol>(this)) {
-    if (S->CopyRelSec)
-      return S->CopyRelSec->getParent();
-    return nullptr;
-  }
-
   return nullptr;
 }
 
@@ -175,7 +170,7 @@
     return;
 
   // Truncate the symbol name so that it doesn't include the version string.
-  Name = {S.data(), Pos};
+  NameSize = Pos;
 
   // If this is not in this DSO, it is not a definition.
   if (!isDefined())
@@ -201,33 +196,15 @@
   // It is an error if the specified version is not defined.
   // Usually version script is not provided when linking executable,
   // but we may still want to override a versioned symbol from DSO,
-  // so we do not report error in this case.
-  if (Config->Shared)
+  // so we do not report error in this case. We also do not error
+  // if the symbol has a local version as it won't be in the dynamic
+  // symbol table.
+  if (Config->Shared && VersionId != VER_NDX_LOCAL)
     error(toString(File) + ": symbol " + S + " has undefined version " +
           Verstr);
 }
 
-InputFile *Lazy::fetch() {
-  if (auto *S = dyn_cast<LazyArchive>(this))
-    return S->fetch();
-  return cast<LazyObject>(this)->fetch();
-}
-
-ArchiveFile &LazyArchive::getFile() { return *cast<ArchiveFile>(File); }
-
-InputFile *LazyArchive::fetch() {
-  std::pair<MemoryBufferRef, uint64_t> MBInfo = getFile().getMember(&Sym);
-
-  // getMember returns an empty buffer if the member was already
-  // read from the library.
-  if (MBInfo.first.getBuffer().empty())
-    return nullptr;
-  return createObjectFile(MBInfo.first, getFile().getName(), MBInfo.second);
-}
-
-LazyObjFile &LazyObject::getFile() { return *cast<LazyObjFile>(File); }
-
-InputFile *LazyObject::fetch() { return getFile().fetch(); }
+InputFile *LazyArchive::fetch() { return cast<ArchiveFile>(File)->fetch(Sym); }
 
 uint8_t Symbol::computeBinding() const {
   if (Config->Relocatable)
@@ -268,6 +245,27 @@
   message(toString(Sym->File) + S + Sym->getName());
 }
 
+void elf::warnUnorderableSymbol(const Symbol *Sym) {
+  if (!Config->WarnSymbolOrdering)
+    return;
+
+  const InputFile *File = Sym->File;
+  auto *D = dyn_cast<Defined>(Sym);
+
+  auto Warn = [&](StringRef S) { warn(toString(File) + S + Sym->getName()); };
+
+  if (Sym->isUndefined())
+    Warn(": unable to order undefined symbol: ");
+  else if (Sym->isShared())
+    Warn(": unable to order shared symbol: ");
+  else if (D && !D->Section)
+    Warn(": unable to order absolute symbol: ");
+  else if (D && isa<OutputSection>(D->Section))
+    Warn(": unable to order synthetic symbol: ");
+  else if (D && !D->Section->Repl->Live)
+    Warn(": unable to order discarded symbol: ");
+}
+
 // Returns a symbol for an error message.
 std::string lld::toString(const Symbol &B) {
   if (Config->Demangle)
diff --git a/ELF/Symbols.h b/ELF/Symbols.h
index bef5897..f0912d2 100644
--- a/ELF/Symbols.h
+++ b/ELF/Symbols.h
@@ -7,8 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// All symbols are handled as SymbolBodies regardless of their types.
-// This file defines various types of SymbolBodies.
+// This file defines various types of Symbols.
 //
 //===----------------------------------------------------------------------===//
 
@@ -33,6 +32,20 @@
 class OutputSection;
 template <class ELFT> class SharedFile;
 
+// This is a StringRef-like container that doesn't run strlen().
+//
+// ELF string tables contain a lot of null-terminated strings. Most of them
+// are not necessary for the linker because they are names of local symbols,
+// and the linker doesn't use local symbol names for name resolution. So, we
+// use this class to represents strings read from string tables.
+struct StringRefZ {
+  StringRefZ(const char *S) : Data(S), Size(-1) {}
+  StringRefZ(StringRef S) : Data(S.data()), Size(S.size()) {}
+
+  const char *Data;
+  const uint32_t Size;
+};
+
 // The base class for real symbol classes.
 class Symbol {
 public:
@@ -46,6 +59,25 @@
 
   Kind kind() const { return static_cast<Kind>(SymbolKind); }
 
+  // The file from which this symbol was created.
+  InputFile *File;
+
+protected:
+  const char *NameData;
+  mutable uint32_t NameSize;
+
+public:
+  uint32_t DynsymIndex = 0;
+  uint32_t GotIndex = -1;
+  uint32_t PltIndex = -1;
+  uint32_t GlobalDynIndex = -1;
+
+  // This field is a index to the symbol's version definition.
+  uint32_t VerdefIndex = -1;
+
+  // Version definition index.
+  uint16_t VersionId;
+
   // Symbol binding. This is not overwritten by replaceSymbol to track
   // changes during resolution. In particular:
   //  - An undefined weak is still weak when it resolves to a shared library.
@@ -53,8 +85,11 @@
   //    remember it is weak.
   uint8_t Binding;
 
-  // Version definition index.
-  uint16_t VersionId;
+  // The following fields have the same meaning as the ELF symbol attributes.
+  uint8_t Type;    // symbol type
+  uint8_t StOther; // st_other field value
+
+  const uint8_t SymbolKind;
 
   // Symbol visibility. This is the computed minimum visibility of all
   // observed non-DSO symbols.
@@ -80,9 +115,6 @@
   // True if this symbol is specified by --trace-symbol option.
   unsigned Traced : 1;
 
-  // The file from which this symbol was created.
-  InputFile *File;
-
   bool includeInDynsym() const;
   uint8_t computeBinding() const;
   bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; }
@@ -96,14 +128,15 @@
     return SymbolKind == LazyArchiveKind || SymbolKind == LazyObjectKind;
   }
 
-  // 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 for details.
-    return isWeak() && (isUndefined() || isLazy());
+  // True if this is an undefined weak symbol.
+  bool isUndefWeak() const { return isWeak() && isUndefined(); }
+
+  StringRef getName() const {
+    if (NameSize == (uint32_t)-1)
+      NameSize = strlen(NameData);
+    return {NameData, NameSize};
   }
 
-  StringRef getName() const { return Name; }
   void parseSymbolVersion();
 
   bool isInGot() const { return GotIndex != -1U; }
@@ -116,24 +149,18 @@
   uint64_t getGotPltOffset() const;
   uint64_t getGotPltVA() const;
   uint64_t getPltVA() const;
+  uint64_t getPltOffset() const;
   uint64_t getSize() const;
   OutputSection *getOutputSection() const;
 
-  uint32_t DynsymIndex = 0;
-  uint32_t GotIndex = -1;
-  uint32_t GotPltIndex = -1;
-  uint32_t PltIndex = -1;
-  uint32_t GlobalDynIndex = -1;
-
 protected:
   Symbol(Kind K, InputFile *File, StringRefZ Name, uint8_t Binding,
          uint8_t StOther, uint8_t Type)
-      : Binding(Binding), File(File), SymbolKind(K), NeedsPltAddr(false),
+      : File(File), NameData(Name.Data), NameSize(Name.Size), Binding(Binding),
+        Type(Type), StOther(StOther), SymbolKind(K), NeedsPltAddr(false),
         IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false),
         IsInIgot(false), IsPreemptible(false), Used(!Config->GcSections),
-        Type(Type), StOther(StOther), Name(Name) {}
-
-  const unsigned SymbolKind : 8;
+        NeedsTocRestore(false) {}
 
 public:
   // True the symbol should point to its PLT entry.
@@ -157,9 +184,9 @@
   // True if an undefined or shared symbol is used from a live section.
   unsigned Used : 1;
 
-  // The following fields have the same meaning as the ELF symbol attributes.
-  uint8_t Type;    // symbol type
-  uint8_t StOther; // st_other field value
+  // True if a call to this symbol needs to be followed by a restore of the
+  // PPC64 toc pointer.
+  unsigned NeedsTocRestore : 1;
 
   // The Type field may also have this value. It means that we have not yet seen
   // a non-Lazy symbol with this name, so we don't know what its type is. The
@@ -174,9 +201,6 @@
   bool isGnuIFunc() const { return Type == llvm::ELF::STT_GNU_IFUNC; }
   bool isObject() const { return Type == llvm::ELF::STT_OBJECT; }
   bool isFile() const { return Type == llvm::ELF::STT_FILE; }
-
-protected:
-  StringRefZ Name;
 };
 
 // Represents a symbol that is defined in the current output file.
@@ -210,8 +234,9 @@
   SharedSymbol(InputFile &File, StringRef Name, uint8_t Binding,
                uint8_t StOther, uint8_t Type, uint64_t Value, uint64_t Size,
                uint32_t Alignment, uint32_t VerdefIndex)
-      : Symbol(SharedKind, &File, Name, Binding, StOther, Type), Value(Value),
-        Size(Size), VerdefIndex(VerdefIndex), Alignment(Alignment) {
+      : Symbol(SharedKind, &File, Name, Binding, StOther, Type),
+        Alignment(Alignment), Value(Value), Size(Size) {
+    this->VerdefIndex = VerdefIndex;
     // GNU ifunc is a mechanism to allow user-supplied functions to
     // resolve PLT slot values at load-time. This is contrary to the
     // regular symbol resolution scheme in which symbols are resolved just
@@ -236,54 +261,36 @@
     return *cast<SharedFile<ELFT>>(File);
   }
 
-  // If not null, there is a copy relocation to this section.
-  InputSection *CopyRelSec = nullptr;
+  uint32_t Alignment;
 
   uint64_t Value; // st_value
   uint64_t Size;  // st_size
-
-  // This field is a index to the symbol's version definition.
-  uint32_t VerdefIndex;
-
-  uint32_t Alignment;
 };
 
-// This 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.
+// LazyArchive and LazyObject represent a symbols 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 Lazy : public Symbol {
-public:
-  static bool classof(const Symbol *S) { return S->isLazy(); }
-
-  // Returns an object file for this symbol, or a nullptr if the file
-  // was already returned.
-  InputFile *fetch();
-
-protected:
-  Lazy(Kind K, InputFile &File, StringRef Name, uint8_t Type)
-      : Symbol(K, &File, Name, llvm::ELF::STB_GLOBAL, llvm::ELF::STV_DEFAULT,
-               Type) {}
-};
 
 // This class represents a symbol defined in an archive file. It is
 // created from an archive file header, and it knows how to load an
 // object file from an archive to replace itself with a defined
 // symbol.
-class LazyArchive : public Lazy {
+class LazyArchive : public Symbol {
 public:
-  LazyArchive(InputFile &File, const llvm::object::Archive::Symbol S,
-              uint8_t Type)
-      : Lazy(LazyArchiveKind, File, S.getName(), Type), Sym(S) {}
+  LazyArchive(InputFile &File, uint8_t Type,
+              const llvm::object::Archive::Symbol S)
+      : Symbol(LazyArchiveKind, &File, S.getName(), llvm::ELF::STB_GLOBAL,
+               llvm::ELF::STV_DEFAULT, Type),
+        Sym(S) {}
 
   static bool classof(const Symbol *S) { return S->kind() == LazyArchiveKind; }
 
-  ArchiveFile &getFile();
   InputFile *fetch();
 
 private:
@@ -292,15 +299,13 @@
 
 // LazyObject symbols represents symbols in object files between
 // --start-lib and --end-lib options.
-class LazyObject : public Lazy {
+class LazyObject : public Symbol {
 public:
-  LazyObject(InputFile &File, StringRef Name, uint8_t Type)
-      : Lazy(LazyObjectKind, File, Name, Type) {}
+  LazyObject(InputFile &File, uint8_t Type, StringRef Name)
+      : Symbol(LazyObjectKind, &File, Name, llvm::ELF::STB_GLOBAL,
+               llvm::ELF::STV_DEFAULT, Type) {}
 
   static bool classof(const Symbol *S) { return S->kind() == LazyObjectKind; }
-
-  LazyObjFile &getFile();
-  InputFile *fetch();
 };
 
 // Some linker-generated symbols need to be created as
@@ -330,6 +335,9 @@
   static Defined *MipsGp;
   static Defined *MipsGpDisp;
   static Defined *MipsLocalGp;
+
+  // __rela_iplt_end or __rel_iplt_end
+  static Defined *RelaIpltEnd;
 };
 
 // A buffer class that is large enough to hold any Symbol-derived
@@ -371,6 +379,8 @@
   if (S->Traced)
     printTraceSymbol(S);
 }
+
+void warnUnorderableSymbol(const Symbol *Sym);
 } // namespace elf
 
 std::string toString(const elf::Symbol &B);
diff --git a/ELF/SyntheticSections.cpp b/ELF/SyntheticSections.cpp
index 5c214d0..1c66bcb 100644
--- a/ELF/SyntheticSections.cpp
+++ b/ELF/SyntheticSections.cpp
@@ -56,12 +56,6 @@
 
 constexpr size_t MergeNoTailSection::NumShards;
 
-uint64_t SyntheticSection::getVA() const {
-  if (OutputSection *Sec = getParent())
-    return Sec->Addr + OutSecOff;
-  return 0;
-}
-
 // Returns an LLD version string.
 static ArrayRef<uint8_t> getVersion() {
   // Check LLD_VERSION first for ease of testing.
@@ -190,8 +184,6 @@
 
       auto *Opt = reinterpret_cast<const Elf_Mips_Options *>(D.data());
       if (Opt->kind == ODK_REGINFO) {
-        if (Config->Relocatable && Opt->getRegInfo().ri_gp_value)
-          error(Filename + ": unsupported non-zero ri_gp_value");
         Reginfo.ri_gprmask |= Opt->getRegInfo().ri_gprmask;
         Sec->getFile<ELFT>()->MipsGp0 = Opt->getRegInfo().ri_gp_value;
         break;
@@ -242,10 +234,8 @@
       error(toString(Sec->File) + ": invalid size of .reginfo section");
       return nullptr;
     }
-    auto *R = reinterpret_cast<const Elf_Mips_RegInfo *>(Sec->Data.data());
-    if (Config->Relocatable && R->ri_gp_value)
-      error(toString(Sec->File) + ": unsupported non-zero ri_gp_value");
 
+    auto *R = reinterpret_cast<const Elf_Mips_RegInfo *>(Sec->Data.data());
     Reginfo.ri_gprmask |= R->ri_gprmask;
     Sec->getFile<ELFT>()->MipsGp0 = R->ri_gp_value;
   };
@@ -431,7 +421,7 @@
 // one and associates FDEs to the CIE.
 template <class ELFT, class RelTy>
 void EhFrameSection::addSectionAux(EhInputSection *Sec, ArrayRef<RelTy> Rels) {
-  DenseMap<size_t, CieRecord *> OffsetToCie;
+  OffsetToCie.clear();
   for (EhSectionPiece &Piece : Sec->Pieces) {
     // The empty record is the end marker.
     if (Piece.Size == 4)
@@ -466,10 +456,6 @@
   for (auto *DS : Sec->DependentSections)
     DependentSections.push_back(DS);
 
-  // .eh_frame is a sequence of CIE or FDE records. This function
-  // splits it into pieces so that we can call
-  // SplitInputSection::getSectionPiece on the section.
-  Sec->split<ELFT>();
   if (Sec->Pieces.empty())
     return;
 
@@ -507,10 +493,10 @@
   }
 
   // The LSB standard does not allow a .eh_frame section with zero
-  // Call Frame Information records. Therefore add a CIE record length
-  // 0 as a terminator if this .eh_frame section is empty.
-  if (Off == 0)
-    Off = 4;
+  // Call Frame Information records. glibc unwind-dw2-fde.c
+  // classify_object_over_fdes expects there is a CIE record length 0 as a
+  // terminator. Thus we add one unconditionally.
+  Off += 4;
 
   this->Size = Off;
 }
@@ -888,12 +874,18 @@
   }
 }
 
+// On PowerPC the .plt section is used to hold the table of function addresses
+// instead of the .got.plt, and the type is SHT_NOBITS similar to a .bss
+// section. I don't know why we have a BSS style type for the section but it is
+// consitent across both 64-bit PowerPC ABIs as well as the 32-bit PowerPC ABI.
 GotPltSection::GotPltSection()
-    : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,
-                       Target->GotPltEntrySize, ".got.plt") {}
+    : SyntheticSection(SHF_ALLOC | SHF_WRITE,
+                       Config->EMachine == EM_PPC64 ? SHT_NOBITS : SHT_PROGBITS,
+                       Target->GotPltEntrySize,
+                       Config->EMachine == EM_PPC64 ? ".plt" : ".got.plt") {}
 
 void GotPltSection::addEntry(Symbol &Sym) {
-  Sym.GotPltIndex = Target->GotPltHeaderEntriesNum + Entries.size();
+  assert(Sym.PltIndex == Entries.size());
   Entries.push_back(&Sym);
 }
 
@@ -919,16 +911,29 @@
          !(ElfSym::GlobalOffsetTable && Target->GotBaseSymInGotPlt);
 }
 
-// On ARM the IgotPltSection is part of the GotSection, on other Targets it is
-// part of the .got.plt
+static StringRef getIgotPltName() {
+  // On ARM the IgotPltSection is part of the GotSection.
+  if (Config->EMachine == EM_ARM)
+    return ".got";
+
+  // On PowerPC64 the GotPltSection is renamed to '.plt' so the IgotPltSection
+  // needs to be named the same.
+  if (Config->EMachine == EM_PPC64)
+    return ".plt";
+
+  return ".got.plt";
+}
+
+// On PowerPC64 the GotPltSection type is SHT_NOBITS so we have to follow suit
+// with the IgotPltSection.
 IgotPltSection::IgotPltSection()
-    : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,
-                       Target->GotPltEntrySize,
-                       Config->EMachine == EM_ARM ? ".got" : ".got.plt") {}
+    : SyntheticSection(SHF_ALLOC | SHF_WRITE,
+                       Config->EMachine == EM_PPC64 ? SHT_NOBITS : SHT_PROGBITS,
+                       Target->GotPltEntrySize, getIgotPltName()) {}
 
 void IgotPltSection::addEntry(Symbol &Sym) {
   Sym.IsInIgot = true;
-  Sym.GotPltIndex = Entries.size();
+  assert(Sym.PltIndex == Entries.size());
   Entries.push_back(&Sym);
 }
 
@@ -1028,6 +1033,13 @@
 }
 
 template <class ELFT>
+void DynamicSection<ELFT>::addInSecRelative(int32_t Tag, InputSection *Sec) {
+  size_t TagOffset = Entries.size() * Entsize;
+  Entries.push_back(
+      {Tag, [=] { return Sec->getVA(0) - (getVA() + TagOffset); }});
+}
+
+template <class ELFT>
 void DynamicSection<ELFT>::addOutSec(int32_t Tag, OutputSection *Sec) {
   Entries.push_back({Tag, [=] { return Sec->Addr; }});
 }
@@ -1180,8 +1192,23 @@
     else
       addInt(DT_MIPS_GOTSYM, InX::DynSymTab->getNumSymbols());
     addInSec(DT_PLTGOT, InX::MipsGot);
-    if (InX::MipsRldMap)
-      addInSec(DT_MIPS_RLD_MAP, InX::MipsRldMap);
+    if (InX::MipsRldMap) {
+      if (!Config->Pie)
+        addInSec(DT_MIPS_RLD_MAP, InX::MipsRldMap);
+      // Store the offset to the .rld_map section
+      // relative to the address of the tag.
+      addInSecRelative(DT_MIPS_RLD_MAP_REL, InX::MipsRldMap);
+    }
+  }
+
+  // Glink dynamic tag is required by the V2 abi if the plt section isn't empty.
+  if (Config->EMachine == EM_PPC64 && !InX::Plt->empty()) {
+    // The Glink tag points to 32 bytes before the first lazy symbol resolution
+    // stub, which starts directly after the header.
+    Entries.push_back({DT_PPC64_GLINK, [=] {
+                         unsigned Offset = Target->PltHeaderSize - 32;
+                         return InX::Plt->getVA(0) + Offset;
+                       }});
   }
 
   addInt(DT_NULL, 0);
@@ -1387,10 +1414,10 @@
       NonRelatives.push_back(R);
   }
 
-  std::sort(Relatives.begin(), Relatives.end(),
-            [](const Elf_Rel &A, const Elf_Rel &B) {
-              return A.r_offset < B.r_offset;
-            });
+  llvm::sort(Relatives.begin(), Relatives.end(),
+             [](const Elf_Rel &A, const Elf_Rel &B) {
+               return A.r_offset < B.r_offset;
+             });
 
   // Try to find groups of relative relocations which are spaced one word
   // apart from one another. These generally correspond to vtable entries. The
@@ -1468,10 +1495,10 @@
   }
 
   // Finally the non-relative relocations.
-  std::sort(NonRelatives.begin(), NonRelatives.end(),
-            [](const Elf_Rela &A, const Elf_Rela &B) {
-              return A.r_offset < B.r_offset;
-            });
+  llvm::sort(NonRelatives.begin(), NonRelatives.end(),
+             [](const Elf_Rela &A, const Elf_Rela &B) {
+               return A.r_offset < B.r_offset;
+             });
   if (!NonRelatives.empty()) {
     Add(NonRelatives.size());
     Add(HasAddendIfRela);
@@ -1520,39 +1547,60 @@
 void SymbolTableBaseSection::finalizeContents() {
   getParent()->Link = StrTabSec.getParent()->SectionIndex;
 
+  if (this->Type != SHT_DYNSYM)
+    return;
+
   // If it is a .dynsym, there should be no local symbols, but we need
   // to do a few things for the dynamic linker.
-  if (this->Type == SHT_DYNSYM) {
-    // Section's Info field has the index of the first non-local symbol.
-    // Because the first symbol entry is a null entry, 1 is the first.
-    getParent()->Info = 1;
 
-    if (InX::GnuHashTab) {
-      // NB: It also sorts Symbols to meet the GNU hash table requirements.
-      InX::GnuHashTab->addSymbols(Symbols);
-    } else if (Config->EMachine == EM_MIPS) {
-      std::stable_sort(Symbols.begin(), Symbols.end(), sortMipsSymbols);
-    }
+  // Section's Info field has the index of the first non-local symbol.
+  // Because the first symbol entry is a null entry, 1 is the first.
+  getParent()->Info = 1;
 
-    size_t I = 0;
-    for (const SymbolTableEntry &S : Symbols) S.Sym->DynsymIndex = ++I;
-    return;
+  if (InX::GnuHashTab) {
+    // NB: It also sorts Symbols to meet the GNU hash table requirements.
+    InX::GnuHashTab->addSymbols(Symbols);
+  } else if (Config->EMachine == EM_MIPS) {
+    std::stable_sort(Symbols.begin(), Symbols.end(), sortMipsSymbols);
   }
+
+  size_t I = 0;
+  for (const SymbolTableEntry &S : Symbols)
+    S.Sym->DynsymIndex = ++I;
 }
 
 // The ELF spec requires that all local symbols precede global symbols, so we
 // sort symbol entries in this function. (For .dynsym, we don't do that because
 // symbols for dynamic linking are inherently all globals.)
+//
+// Aside from above, we put local symbols in groups starting with the STT_FILE
+// symbol. That is convenient for purpose of identifying where are local symbols
+// coming from.
 void SymbolTableBaseSection::postThunkContents() {
   if (this->Type == SHT_DYNSYM)
     return;
-  // move all local symbols before global symbols.
-  auto It = std::stable_partition(
+
+  // Move all local symbols before global symbols.
+  auto E = std::stable_partition(
       Symbols.begin(), Symbols.end(), [](const SymbolTableEntry &S) {
         return S.Sym->isLocal() || S.Sym->computeBinding() == STB_LOCAL;
       });
-  size_t NumLocals = It - Symbols.begin();
+  size_t NumLocals = E - Symbols.begin();
   getParent()->Info = NumLocals + 1;
+
+  // Assign the growing unique ID for each local symbol's file.
+  DenseMap<InputFile *, unsigned> FileIDs;
+  for (auto I = Symbols.begin(); I != E; ++I)
+    FileIDs.insert({I->Sym->File, FileIDs.size()});
+
+  // Sort the local symbols to group them by file. We do not need to care about
+  // the STT_FILE symbols, they are already naturally placed first in each group.
+  // That happens because STT_FILE is always the first symbol in the object and
+  // hence precede all other local symbols we add for a file.
+  std::stable_sort(Symbols.begin(), E,
+                   [&](const SymbolTableEntry &L, const SymbolTableEntry &R) {
+                     return FileIDs[L.Sym->File] < FileIDs[R.Sym->File];
+                   });
 }
 
 void SymbolTableBaseSection::addSymbol(Symbol *B) {
@@ -1619,6 +1667,8 @@
         CommonSec = dyn_cast_or_null<BssSection>(D->Section);
     if (CommonSec)
       ESym->st_shndx = SHN_COMMON;
+    else if (Sym->NeedsPltAddr)
+      ESym->st_shndx = SHN_UNDEF;
     else if (const OutputSection *OutSec = Sym->getOutputSection())
       ESym->st_shndx = OutSec->SectionIndex;
     else if (isa<Defined>(Sym))
@@ -1660,9 +1710,11 @@
         ESym->st_other |= STO_MIPS_PLT;
       if (isMicroMips()) {
         // Set STO_MIPS_MICROMIPS flag and less-significant bit for
-        // defined microMIPS symbols and shared symbols with PLT record.
-        if ((Sym->isDefined() && (Sym->StOther & STO_MIPS_MICROMIPS)) ||
-            (Sym->isShared() && Sym->NeedsPltAddr)) {
+        // a defined microMIPS symbol and symbol should point to its
+        // PLT entry (in case of microMIPS, PLT entries always contain
+        // microMIPS code).
+        if (Sym->isDefined() &&
+            ((Sym->StOther & STO_MIPS_MICROMIPS) || Sym->NeedsPltAddr)) {
           if (StrTabSec.isDynamic())
             ESym->st_value |= 1;
           ESym->st_other |= STO_MIPS_MICROMIPS;
@@ -1804,10 +1856,6 @@
   // its type correctly.
   std::vector<SymbolTableEntry>::iterator Mid =
       std::stable_partition(V.begin(), V.end(), [](const SymbolTableEntry &S) {
-        // Shared symbols that this executable preempts are special. The dynamic
-        // linker has to look them up, so they have to be in the hash table.
-        if (auto *SS = dyn_cast<SharedSymbol>(S.Sym))
-          return SS->CopyRelSec == nullptr && !SS->NeedsPltAddr;
         return !S.Sym->isDefined();
       });
 
@@ -1880,8 +1928,11 @@
   }
 }
 
+// On PowerPC64 the lazy symbol resolvers go into the `global linkage table`
+// in the .glink section, rather then the typical .plt section.
 PltSection::PltSection(bool IsIplt)
-    : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16, ".plt"),
+    : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16,
+                       Config->EMachine == EM_PPC64 ? ".glink" : ".plt"),
       HeaderSize(IsIplt ? 0 : Target->PltHeaderSize), IsIplt(IsIplt) {
   // The PLT needs to be writable on SPARC as the dynamic linker will
   // modify the instructions in the PLT entries.
@@ -2332,9 +2383,8 @@
   NextIndex = getVerDefNum() + 1;
 }
 
-template <class ELFT>
-void VersionNeedSection<ELFT>::addSymbol(SharedSymbol *SS) {
-  SharedFile<ELFT> &File = SS->getFile<ELFT>();
+template <class ELFT> void VersionNeedSection<ELFT>::addSymbol(Symbol *SS) {
+  auto &File = cast<SharedFile<ELFT>>(*SS->File);
   if (SS->VerdefIndex == VER_NDX_GLOBAL) {
     SS->VersionId = VER_NDX_GLOBAL;
     return;
@@ -2513,9 +2563,18 @@
 
 // Debug sections may be compressed by zlib. Decompress if exists.
 void elf::decompressSections() {
+  parallelForEach(InputSections,
+                  [](InputSectionBase *Sec) { Sec->maybeDecompress(); });
+}
+
+template <class ELFT> void elf::splitSections() {
+  // splitIntoPieces needs to be called on each MergeInputSection
+  // before calling finalizeContents().
   parallelForEach(InputSections, [](InputSectionBase *Sec) {
-    if (Sec->Live)
-      Sec->maybeDecompress();
+    if (auto *S = dyn_cast<MergeInputSection>(Sec))
+      S->splitIntoPieces();
+    else if (auto *Eh = dyn_cast<EhInputSection>(Sec))
+      Eh->split<ELFT>();
   });
 }
 
@@ -2527,14 +2586,6 @@
 // that it replaces. It then finalizes each synthetic section in order
 // to compute an output offset for each piece of each input section.
 void elf::mergeSections() {
-  // splitIntoPieces needs to be called on each MergeInputSection
-  // before calling finalizeContents(). Do that first.
-  parallelForEach(InputSections, [](InputSectionBase *Sec) {
-    if (Sec->Live)
-      if (auto *S = dyn_cast<MergeInputSection>(Sec))
-        S->splitIntoPieces();
-  });
-
   std::vector<MergeSyntheticSection *> MergeSections;
   for (InputSectionBase *&S : InputSections) {
     MergeInputSection *MS = dyn_cast<MergeInputSection>(S);
@@ -2573,11 +2624,8 @@
     }
     (*I)->addSection(MS);
   }
-  for (auto *MS : MergeSections) {
+  for (auto *MS : MergeSections)
     MS->finalizeContents();
-    parallelForEach(MS->Sections,
-                    [](MergeInputSection *Sec) { Sec->initOffsetMap(); });
-  }
 
   std::vector<InputSectionBase *> &V = InputSections;
   V.erase(std::remove(V.begin(), V.end(), nullptr), V.end());
@@ -2683,6 +2731,11 @@
 template GdbIndexSection *elf::createGdbIndex<ELF64LE>();
 template GdbIndexSection *elf::createGdbIndex<ELF64BE>();
 
+template void elf::splitSections<ELF32LE>();
+template void elf::splitSections<ELF32BE>();
+template void elf::splitSections<ELF64LE>();
+template void elf::splitSections<ELF64BE>();
+
 template void EhFrameSection::addSection<ELF32LE>(InputSectionBase *);
 template void EhFrameSection::addSection<ELF32BE>(InputSectionBase *);
 template void EhFrameSection::addSection<ELF64LE>(InputSectionBase *);
diff --git a/ELF/SyntheticSections.h b/ELF/SyntheticSections.h
index b709f4b..fc5ffa3 100644
--- a/ELF/SyntheticSections.h
+++ b/ELF/SyntheticSections.h
@@ -52,7 +52,6 @@
   // If any additional finalization of contents are needed post thunk creation.
   virtual void postThunkContents() {}
   virtual bool empty() const { return false; }
-  uint64_t getVA() const;
 
   static bool classof(const SectionBase *D) {
     return D->kind() == InputSectionBase::Synthetic;
@@ -87,6 +86,10 @@
   ArrayRef<CieRecord *> getCieRecords() const { return CieRecords; }
 
 private:
+  // This is used only when parsing EhInputSection. We keep it here to avoid
+  // allocating one for each EhInputSection.
+  llvm::DenseMap<size_t, CieRecord *> OffsetToCie;
+
   uint64_t Size = 0;
 
   template <class ELFT, class RelTy>
@@ -360,6 +363,7 @@
   void add(int32_t Tag, std::function<uint64_t()> Fn);
   void addInt(int32_t Tag, uint64_t Val);
   void addInSec(int32_t Tag, InputSection *Sec);
+  void addInSecRelative(int32_t Tag, InputSection *Sec);
   void addOutSec(int32_t Tag, OutputSection *Sec);
   void addSize(int32_t Tag, OutputSection *Sec);
   void addSym(int32_t Tag, Symbol *Sym);
@@ -670,7 +674,7 @@
 
 public:
   VersionNeedSection();
-  void addSymbol(SharedSymbol *SS);
+  void addSymbol(Symbol *Sym);
   void finalizeContents() override;
   void writeTo(uint8_t *Buf) override;
   size_t getSize() const override;
@@ -834,6 +838,7 @@
 InputSection *createInterpSection();
 MergeInputSection *createCommentSection();
 void decompressSections();
+template <class ELFT> void splitSections();
 void mergeSections();
 
 Defined *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,
diff --git a/ELF/Target.h b/ELF/Target.h
index 698758e..c7d3906 100644
--- a/ELF/Target.h
+++ b/ELF/Target.h
@@ -25,7 +25,6 @@
 class TargetInfo {
 public:
   virtual uint32_t calcEFlags() const { return 0; }
-  virtual bool isPicRel(RelType Type) const { return true; }
   virtual RelType getDynRel(RelType Type) const { return Type; }
   virtual void writeGotPltHeader(uint8_t *Buf) const {}
   virtual void writeGotHeader(uint8_t *Buf) const {}
@@ -49,7 +48,7 @@
   }
 
   // Returns true if a relocation only uses the low bits of a value such that
-  // all those bits are in in the same page. For example, if the relocation
+  // all those bits are in the same page. For example, if the relocation
   // only uses the low 12 bits in a system with 4k pages. If this is true, the
   // bits will always have the same value at runtime and we don't have to emit
   // a dynamic relocation.
diff --git a/ELF/Thunks.cpp b/ELF/Thunks.cpp
index 4db4990..2cd7e51 100644
--- a/ELF/Thunks.cpp
+++ b/ELF/Thunks.cpp
@@ -192,6 +192,23 @@
   InputSection *getTargetInputSection() const override;
 };
 
+
+// PPC64 Plt call stubs.
+// Any call site that needs to call through a plt entry needs a call stub in
+// the .text section. The call stub is responsible for:
+// 1) Saving the toc-pointer to the stack.
+// 2) Loading the target functions address from the procedure linkage table into
+//    r12 for use by the target functions global entry point, and into the count
+//    register.
+// 3) Transfering control to the target function through an indirect branch.
+class PPC64PltCallStub final : public Thunk {
+public:
+  PPC64PltCallStub(Symbol &Dest) : Thunk(Dest) {}
+  uint32_t size() override { return 20; }
+  void writeTo(uint8_t *Buf) override;
+  void addSymbols(ThunkSection &IS) override;
+};
+
 } // end anonymous namespace
 
 Defined *Thunk::addSymbol(StringRef Name, uint8_t Type, uint64_t Value,
@@ -485,6 +502,25 @@
   return dyn_cast<InputSection>(DR.Section);
 }
 
+void PPC64PltCallStub::writeTo(uint8_t *Buf) {
+  int64_t Off = Destination.getGotPltVA() - getPPC64TocBase();
+  // Need to add 0x8000 to offset to account for the low bits being signed.
+  uint16_t OffHa = (Off + 0x8000) >> 16;
+  uint16_t OffLo = Off;
+
+  write32(Buf +  0, 0xf8410018);          // std     r2,24(r1)
+  write32(Buf +  4, 0x3d820000 | OffHa);  // addis   r12,r2, X@plt@to@ha
+  write32(Buf +  8, 0xe98c0000 | OffLo);  // ld      r12,X@plt@toc@l(r12)
+  write32(Buf + 12, 0x7d8903a6);          // mtctr   r12
+  write32(Buf + 16, 0x4e800420);          // bctr
+}
+
+void PPC64PltCallStub::addSymbols(ThunkSection &IS) {
+  Defined *S = addSymbol(Saver.save("__plt_" + Destination.getName()), STT_FUNC,
+                         0, IS);
+  S->NeedsTocRestore = true;
+}
+
 Thunk::Thunk(Symbol &D) : Destination(D), Offset(0) {}
 
 Thunk::~Thunk() = default;
@@ -528,15 +564,26 @@
   return make<MipsThunk>(S);
 }
 
+static Thunk *addThunkPPC64(RelType Type, Symbol &S) {
+  if (Type == R_PPC64_REL24)
+    return make<PPC64PltCallStub>(S);
+  fatal("unexpected relocation type");
+}
+
 Thunk *addThunk(RelType Type, Symbol &S) {
   if (Config->EMachine == EM_AARCH64)
     return addThunkAArch64(Type, S);
-  else if (Config->EMachine == EM_ARM)
+
+  if (Config->EMachine == EM_ARM)
     return addThunkArm(Type, S);
-  else if (Config->EMachine == EM_MIPS)
+
+  if (Config->EMachine == EM_MIPS)
     return addThunkMips(Type, S);
-  llvm_unreachable("add Thunk only supported for ARM and Mips");
-  return nullptr;
+
+  if (Config->EMachine == EM_PPC64)
+    return addThunkPPC64(Type, S);
+
+  llvm_unreachable("add Thunk only supported for ARM, Mips and PowerPC");
 }
 
 } // end namespace elf
diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp
index e685c8e..998b0dc 100644
--- a/ELF/Writer.cpp
+++ b/ELF/Writer.cpp
@@ -9,6 +9,7 @@
 
 #include "Writer.h"
 #include "AArch64ErrataFix.h"
+#include "CallGraphSort.h"
 #include "Config.h"
 #include "Filesystem.h"
 #include "LinkerScript.h"
@@ -62,7 +63,7 @@
   void assignFileOffsets();
   void assignFileOffsetsBinary();
   void setPhdrs();
-  void checkSectionOverlap();
+  void checkSections();
   void fixSectionAlignments();
   void openFile();
   void writeTrapInstr();
@@ -87,7 +88,11 @@
 };
 } // anonymous namespace
 
-StringRef elf::getOutputSectionName(InputSectionBase *S) {
+static bool isSectionPrefix(StringRef Prefix, StringRef Name) {
+  return Name.startswith(Prefix) || Name == Prefix.drop_back();
+}
+
+StringRef elf::getOutputSectionName(const InputSectionBase *S) {
   if (Config->Relocatable)
     return S->Name;
 
@@ -103,13 +108,25 @@
     }
   }
 
+  // This check is for -z keep-text-section-prefix.  This option separates text
+  // sections with prefix ".text.hot", ".text.unlikely", ".text.startup" or
+  // ".text.exit".
+  // When enabled, this allows identifying the hot code region (.text.hot) in
+  // the final binary which can be selectively mapped to huge pages or mlocked,
+  // for instance.
+  if (Config->ZKeepTextSectionPrefix)
+    for (StringRef V :
+         {".text.hot.", ".text.unlikely.", ".text.startup.", ".text.exit."}) {
+      if (isSectionPrefix(V, S->Name))
+        return V.drop_back();
+    }
+
   for (StringRef V :
        {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.",
         ".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.",
         ".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab."}) {
-    StringRef Prefix = V.drop_back();
-    if (S->Name.startswith(V) || S->Name == Prefix)
-      return Prefix;
+    if (isSectionPrefix(V, S->Name))
+      return V.drop_back();
   }
 
   // CommonSection is identified as "COMMON" in linker scripts.
@@ -190,11 +207,12 @@
           Symtab->addAbsolute("__gnu_local_gp", STV_HIDDEN, STB_GLOBAL);
   }
 
-  // The 64-bit PowerOpen ABI defines a TableOfContents (TOC) which combines the
-  // typical ELF GOT with the small data sections. It commonly includes .got
-  // .toc .sdata .sbss. The .TOC. symbol replaces both _GLOBAL_OFFSET_TABLE_ and
-  // _SDA_BASE_ from the 32-bit ABI. It is used to represent the TOC base which
-  // is offset by 0x8000 bytes from the start of the .got section.
+  // The Power Architecture 64-bit v2 ABI defines a TableOfContents (TOC) which
+  // combines the typical ELF GOT with the small data sections. It commonly
+  // includes .got .toc .sdata .sbss. The .TOC. symbol replaces both
+  // _GLOBAL_OFFSET_TABLE_ and _SDA_BASE_ from the 32-bit ABI. It is used to
+  // represent the TOC base which is offset by 0x8000 bytes from the start of
+  // the .got section.
   ElfSym::GlobalOffsetTable = addOptionalRegular(
       (Config->EMachine == EM_PPC64) ? ".TOC." : "_GLOBAL_OFFSET_TABLE_",
       Out::ElfHeader, Target->GotBaseSymOff);
@@ -458,7 +476,7 @@
   }
 
   if (Config->CheckSections)
-    checkSectionOverlap();
+    checkSections();
 
   // It does not make sense try to open the file if we have error already.
   if (errorCount())
@@ -494,7 +512,7 @@
 
 static bool shouldKeepInSymtab(SectionBase *Sec, StringRef SymName,
                                const Symbol &B) {
-  if (B.isFile() || B.isSection())
+  if (B.isSection())
     return false;
 
   // If sym references a section in a discarded group, don't keep it.
@@ -645,6 +663,9 @@
   if (InX::Got && Sec == InX::Got->getParent())
     return true;
 
+  if (Sec->Name.equals(".toc"))
+    return true;
+
   // .got.plt contains pointers to external function symbols. They are
   // by default resolved lazily, so we usually cannot put it into RELRO.
   // However, if "-z now" is given, the lazy symbol resolution is
@@ -680,17 +701,18 @@
   RF_NOT_INTERP = 1 << 17,
   RF_NOT_ALLOC = 1 << 16,
   RF_WRITE = 1 << 15,
-  RF_EXEC_WRITE = 1 << 13,
-  RF_EXEC = 1 << 12,
-  RF_NON_TLS_BSS = 1 << 11,
-  RF_NON_TLS_BSS_RO = 1 << 10,
-  RF_NOT_TLS = 1 << 9,
+  RF_EXEC_WRITE = 1 << 14,
+  RF_EXEC = 1 << 13,
+  RF_NON_TLS_BSS = 1 << 12,
+  RF_NON_TLS_BSS_RO = 1 << 11,
+  RF_NOT_TLS = 1 << 10,
+  RF_ALLOC_FIRST = 1 << 9,
   RF_BSS = 1 << 8,
   RF_NOTE = 1 << 7,
   RF_PPC_NOT_TOCBSS = 1 << 6,
-  RF_PPC_OPD = 1 << 5,
-  RF_PPC_TOCL = 1 << 4,
-  RF_PPC_TOC = 1 << 3,
+  RF_PPC_TOCL = 1 << 5,
+  RF_PPC_TOC = 1 << 4,
+  RF_PPC_GOT = 1 << 3,
   RF_PPC_BRANCH_LT = 1 << 2,
   RF_MIPS_GPREL = 1 << 1,
   RF_MIPS_NOT_GOT = 1 << 0
@@ -716,6 +738,16 @@
   if (!(Sec->Flags & SHF_ALLOC))
     return Rank | RF_NOT_ALLOC;
 
+  // Place .dynsym and .dynstr at the beginning of SHF_ALLOC
+  // sections. We want to do this to mitigate the possibility that
+  // huge .dynsym and .dynstr sections placed between ro-data and text
+  // sections cause relocation overflow.  Note: .dynstr has SHT_STRTAB
+  // type and SHF_ALLOC attribute, whereas sections that only have
+  // SHT_STRTAB but without SHF_ALLOC is placed at the end. All "Sec"
+  // reaching here has SHF_ALLOC bit set.
+  if (Sec->Type == SHT_DYNSYM || Sec->Type == SHT_STRTAB)
+    return Rank | RF_ALLOC_FIRST;
+
   // Sort sections based on their access permission in the following
   // order: R, RX, RWX, RW.  This order is based on the following
   // considerations:
@@ -793,15 +825,15 @@
     if (Name != ".tocbss")
       Rank |= RF_PPC_NOT_TOCBSS;
 
-    if (Name == ".opd")
-      Rank |= RF_PPC_OPD;
-
     if (Name == ".toc1")
       Rank |= RF_PPC_TOCL;
 
     if (Name == ".toc")
       Rank |= RF_PPC_TOC;
 
+    if (Name == ".got")
+      Rank |= RF_PPC_GOT;
+
     if (Name == ".branch_lt")
       Rank |= RF_PPC_BRANCH_LT;
   }
@@ -852,7 +884,8 @@
   addOptionalRegular(S, InX::RelaIplt, 0, STV_HIDDEN, STB_WEAK);
 
   S = Config->IsRela ? "__rela_iplt_end" : "__rel_iplt_end";
-  addOptionalRegular(S, InX::RelaIplt, -1, STV_HIDDEN, STB_WEAK);
+  ElfSym::RelaIpltEnd =
+      addOptionalRegular(S, InX::RelaIplt, 0, STV_HIDDEN, STB_WEAK);
 }
 
 template <class ELFT>
@@ -885,6 +918,9 @@
     ElfSym::GlobalOffsetTable->Section = GotSection;
   }
 
+  if (ElfSym::RelaIpltEnd)
+    ElfSym::RelaIpltEnd->Value = InX::RelaIplt->getSize();
+
   PhdrEntry *Last = nullptr;
   PhdrEntry *LastRO = nullptr;
 
@@ -1029,6 +1065,10 @@
 // Builds section order for handling --symbol-ordering-file.
 static DenseMap<const InputSectionBase *, int> buildSectionOrder() {
   DenseMap<const InputSectionBase *, int> SectionOrder;
+  // Use the rarely used option -call-graph-ordering-file to sort sections.
+  if (!Config->CallGraphProfile.empty())
+    return computeCallGraphProfileOrder();
+
   if (Config->SymbolOrderingFile.empty())
     return SectionOrder;
 
@@ -1046,38 +1086,31 @@
     SymbolOrder.insert({S, {Priority++, false}});
 
   // Build a map from sections to their priorities.
-  for (InputFile *File : ObjectFiles) {
-    for (Symbol *Sym : File->getSymbols()) {
-      auto It = SymbolOrder.find(Sym->getName());
-      if (It == SymbolOrder.end())
-        continue;
-      SymbolOrderEntry &Ent = It->second;
-      Ent.Present = true;
+  auto AddSym = [&](Symbol &Sym) {
+    auto It = SymbolOrder.find(Sym.getName());
+    if (It == SymbolOrder.end())
+      return;
+    SymbolOrderEntry &Ent = It->second;
+    Ent.Present = true;
 
-      auto *D = dyn_cast<Defined>(Sym);
-      if (Config->WarnSymbolOrdering) {
-        if (Sym->isUndefined())
-          warn(File->getName() +
-               ": unable to order undefined symbol: " + Sym->getName());
-        else if (Sym->isShared())
-          warn(File->getName() +
-               ": unable to order shared symbol: " + Sym->getName());
-        else if (D && !D->Section)
-          warn(File->getName() +
-               ": unable to order absolute symbol: " + Sym->getName());
-        else if (D && !D->Section->Live)
-          warn(File->getName() +
-               ": unable to order discarded symbol: " + Sym->getName());
-      }
-      if (!D)
-        continue;
+    warnUnorderableSymbol(&Sym);
 
+    if (auto *D = dyn_cast<Defined>(&Sym)) {
       if (auto *Sec = dyn_cast_or_null<InputSectionBase>(D->Section)) {
         int &Priority = SectionOrder[cast<InputSectionBase>(Sec->Repl)];
         Priority = std::min(Priority, Ent.Priority);
       }
     }
-  }
+  };
+  // We want both global and local symbols. We get the global ones from the
+  // symbol table and iterate the object files for the local ones.
+  for (Symbol *Sym : Symtab->getSymbols())
+    if (!Sym->isLazy())
+      AddSym(*Sym);
+  for (InputFile *File : ObjectFiles)
+    for (Symbol *Sym : File->getSymbols())
+      if (Sym->isLocal())
+        AddSym(*Sym);
 
   if (Config->WarnSymbolOrdering)
     for (auto OrderEntry : SymbolOrder)
@@ -1087,6 +1120,75 @@
   return SectionOrder;
 }
 
+// Sorts the sections in ISD according to the provided section order.
+static void
+sortISDBySectionOrder(InputSectionDescription *ISD,
+                      const DenseMap<const InputSectionBase *, int> &Order) {
+  std::vector<InputSection *> UnorderedSections;
+  std::vector<std::pair<InputSection *, int>> OrderedSections;
+  uint64_t UnorderedSize = 0;
+
+  for (InputSection *IS : ISD->Sections) {
+    auto I = Order.find(IS);
+    if (I == Order.end()) {
+      UnorderedSections.push_back(IS);
+      UnorderedSize += IS->getSize();
+      continue;
+    }
+    OrderedSections.push_back({IS, I->second});
+  }
+  llvm::sort(
+      OrderedSections.begin(), OrderedSections.end(),
+      [&](std::pair<InputSection *, int> A, std::pair<InputSection *, int> B) {
+        return A.second < B.second;
+      });
+
+  // Find an insertion point for the ordered section list in the unordered
+  // section list. On targets with limited-range branches, this is the mid-point
+  // of the unordered section list. This decreases the likelihood that a range
+  // extension thunk will be needed to enter or exit the ordered region. If the
+  // ordered section list is a list of hot functions, we can generally expect
+  // the ordered functions to be called more often than the unordered functions,
+  // making it more likely that any particular call will be within range, and
+  // therefore reducing the number of thunks required.
+  //
+  // For example, imagine that you have 8MB of hot code and 32MB of cold code.
+  // If the layout is:
+  //
+  // 8MB hot
+  // 32MB cold
+  //
+  // only the first 8-16MB of the cold code (depending on which hot function it
+  // is actually calling) can call the hot code without a range extension thunk.
+  // However, if we use this layout:
+  //
+  // 16MB cold
+  // 8MB hot
+  // 16MB cold
+  //
+  // both the last 8-16MB of the first block of cold code and the first 8-16MB
+  // of the second block of cold code can call the hot code without a thunk. So
+  // we effectively double the amount of code that could potentially call into
+  // the hot code without a thunk.
+  size_t InsPt = 0;
+  if (Target->ThunkSectionSpacing && !OrderedSections.empty()) {
+    uint64_t UnorderedPos = 0;
+    for (; InsPt != UnorderedSections.size(); ++InsPt) {
+      UnorderedPos += UnorderedSections[InsPt]->getSize();
+      if (UnorderedPos > UnorderedSize / 2)
+        break;
+    }
+  }
+
+  ISD->Sections.clear();
+  for (InputSection *IS : makeArrayRef(UnorderedSections).slice(0, InsPt))
+    ISD->Sections.push_back(IS);
+  for (std::pair<InputSection *, int> P : OrderedSections)
+    ISD->Sections.push_back(P.first);
+  for (InputSection *IS : makeArrayRef(UnorderedSections).slice(InsPt))
+    ISD->Sections.push_back(IS);
+}
+
 static void sortSection(OutputSection *Sec,
                         const DenseMap<const InputSectionBase *, int> &Order) {
   StringRef Name = Sec->Name;
@@ -1113,7 +1215,9 @@
   // Sort input sections by priority using the list provided
   // by --symbol-ordering-file.
   if (!Order.empty())
-    Sec->sort([&](InputSectionBase *S) { return Order.lookup(S); });
+    for (BaseCommand *B : Sec->SectionCommands)
+      if (auto *ISD = dyn_cast<InputSectionDescription>(B))
+        sortISDBySectionOrder(ISD, Order);
 }
 
 // If no layout was provided by linker script, we want to apply default
@@ -1134,22 +1238,29 @@
   if (Config->Relocatable)
     return;
 
-  for (BaseCommand *Base : Script->SectionCommands)
-    if (auto *Sec = dyn_cast<OutputSection>(Base))
-      Sec->SortRank = getSectionRank(Sec);
-
   sortInputSections();
 
+  for (BaseCommand *Base : Script->SectionCommands) {
+    auto *OS = dyn_cast<OutputSection>(Base);
+    if (!OS)
+      continue;
+    OS->SortRank = getSectionRank(OS);
+
+    // We want to assign rude approximation values to OutSecOff fields
+    // to know the relative order of the input sections. We use it for
+    // sorting SHF_LINK_ORDER sections. See resolveShfLinkOrder().
+    uint64_t I = 0;
+    for (InputSection *Sec : getInputSections(OS))
+      Sec->OutSecOff = I++;
+  }
+
   if (!Script->HasSectionsCommand) {
     // We know that all the OutputSections are contiguous in this case.
-    auto E = Script->SectionCommands.end();
-    auto I = Script->SectionCommands.begin();
     auto IsSection = [](BaseCommand *Base) { return isa<OutputSection>(Base); };
-    I = std::find_if(I, E, IsSection);
-    E = std::find_if(llvm::make_reverse_iterator(E),
-                     llvm::make_reverse_iterator(I), IsSection)
-            .base();
-    std::stable_sort(I, E, compareSections);
+    std::stable_sort(
+        llvm::find_if(Script->SectionCommands, IsSection),
+        llvm::find_if(llvm::reverse(Script->SectionCommands), IsSection).base(),
+        compareSections);
     return;
   }
 
@@ -1490,9 +1601,9 @@
 
     if (InX::DynSymTab && Sym->includeInDynsym()) {
       InX::DynSymTab->addSymbol(Sym);
-      if (auto *SS = dyn_cast<SharedSymbol>(Sym))
-        if (cast<SharedFile<ELFT>>(Sym->File)->IsNeeded)
-          In<ELFT>::VerNeed->addSymbol(SS);
+      if (auto *File = dyn_cast_or_null<SharedFile<ELFT>>(Sym->File))
+        if (File->IsNeeded && !Sym->isUndefined())
+          In<ELFT>::VerNeed->addSymbol(Sym);
     }
   }
 
@@ -1518,7 +1629,7 @@
   }
 
   // This is a bit of a hack. A value of 0 means undef, so we set it
-  // to 1 t make __ehdr_start defined. The section number is not
+  // to 1 to make __ehdr_start defined. The section number is not
   // particularly relevant.
   Out::ElfHeader->SectionIndex = 1;
 
@@ -1584,31 +1695,43 @@
     } while (Changed);
   }
 
+  // createThunks may have added local symbols to the static symbol table
+  applySynthetic({InX::SymTab},
+                 [](SyntheticSection *SS) { SS->postThunkContents(); });
+
   // Fill other section headers. The dynamic table is finalized
   // at the end because some tags like RELSZ depend on result
   // of finalizing other sections.
   for (OutputSection *Sec : OutputSections)
     Sec->finalize<ELFT>();
-
-  // createThunks may have added local symbols to the static symbol table
-  applySynthetic({InX::SymTab},
-                 [](SyntheticSection *SS) { SS->postThunkContents(); });
 }
 
 // The linker is expected to define SECNAME_start and SECNAME_end
 // symbols for a few sections. This function defines them.
 template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
-  auto Define = [&](StringRef Start, StringRef End, OutputSection *OS) {
-    // These symbols resolve to the image base if the section does not exist.
-    // A special value -1 indicates end of the section.
+  // If a section does not exist, there's ambiguity as to how we
+  // define _start and _end symbols for an init/fini section. Since
+  // the loader assume that the symbols are always defined, we need to
+  // always define them. But what value? The loader iterates over all
+  // pointers between _start and _end to run global ctors/dtors, so if
+  // the section is empty, their symbol values don't actually matter
+  // as long as _start and _end point to the same location.
+  //
+  // That said, we don't want to set the symbols to 0 (which is
+  // probably the simplest value) because that could cause some
+  // program to fail to link due to relocation overflow, if their
+  // program text is above 2 GiB. We use the address of the .text
+  // section instead to prevent that failure.
+  OutputSection *Default = findSection(".text");
+  if (!Default)
+    Default = Out::ElfHeader;
+  auto Define = [=](StringRef Start, StringRef End, OutputSection *OS) {
     if (OS) {
       addOptionalRegular(Start, OS, 0);
       addOptionalRegular(End, OS, -1);
     } else {
-      if (Config->Pic)
-        OS = Out::ElfHeader;
-      addOptionalRegular(Start, OS, 0);
-      addOptionalRegular(End, OS, 0);
+      addOptionalRegular(Start, Default, 0);
+      addOptionalRegular(End, Default, 0);
     }
   };
 
@@ -1635,7 +1758,7 @@
 }
 
 static bool needsPtLoad(OutputSection *Sec) {
-  if (!(Sec->Flags & SHF_ALLOC))
+  if (!(Sec->Flags & SHF_ALLOC) || Sec->Noload)
     return false;
 
   // Don't allocate VA space for TLS NOBITS sections. The PT_TLS PHDR is
@@ -1774,7 +1897,7 @@
   // Create one PT_NOTE per a group of contiguous .note sections.
   PhdrEntry *Note = nullptr;
   for (OutputSection *Sec : OutputSections) {
-    if (Sec->Type == SHT_NOTE) {
+    if (Sec->Type == SHT_NOTE && (Sec->Flags & SHF_ALLOC)) {
       if (!Note || Sec->LMAExpr)
         Note = AddHdr(PT_NOTE, PF_R);
       Note->add(Sec);
@@ -1917,9 +2040,8 @@
   // not do that. Unfortunately, there are apps in the wild, for example, Linux
   // kernel, which control segment distribution explicitly and move the counter
   // backwards, so we have to allow doing that to support linking them. We
-  // perform non-critical checks for overlaps in checkNoOverlappingSections(),
-  // but here we want to prevent file size overflows because it would crash the
-  // linker.
+  // perform non-critical checks for overlaps in checkSectionOverlap(), but here
+  // we want to prevent file size overflows because it would crash the linker.
   for (OutputSection *Sec : OutputSections) {
     if (Sec->Type == SHT_NOBITS)
       continue;
@@ -1977,10 +2099,10 @@
 // Check whether sections overlap for a specific address range (file offsets,
 // load and virtual adresses).
 static void checkOverlap(StringRef Name, std::vector<SectionOffset> &Sections) {
-  std::sort(Sections.begin(), Sections.end(),
-            [=](const SectionOffset &A, const SectionOffset &B) {
-              return A.Offset < B.Offset;
-            });
+  llvm::sort(Sections.begin(), Sections.end(),
+             [=](const SectionOffset &A, const SectionOffset &B) {
+               return A.Offset < B.Offset;
+             });
 
   // Finding overlap is easy given a vector is sorted by start position.
   // If an element starts before the end of the previous element, they overlap.
@@ -1996,17 +2118,25 @@
   }
 }
 
-// Check for overlapping sections
+// Check for overlapping sections and address overflows.
 //
 // In this function we check that none of the output sections have overlapping
 // file offsets. For SHF_ALLOC sections we also check that the load address
 // ranges and the virtual address ranges don't overlap
-template <class ELFT> void Writer<ELFT>::checkSectionOverlap() {
-  // First check for overlapping file offsets. In this case we need to skip
-  // any section marked as SHT_NOBITS. These sections don't actually occupy
-  // space in the file so Sec->Offset + Sec->Size can overlap with others.
-  // If --oformat binary is specified only add SHF_ALLOC sections are added to
-  // the output file so we skip any non-allocated sections in that case.
+template <class ELFT> void Writer<ELFT>::checkSections() {
+  // First, check that section's VAs fit in available address space for target.
+  for (OutputSection *OS : OutputSections)
+    if ((OS->Addr + OS->Size < OS->Addr) ||
+        (!ELFT::Is64Bits && OS->Addr + OS->Size > UINT32_MAX))
+      errorOrWarn("section " + OS->Name + " at 0x" + utohexstr(OS->Addr) +
+                  " of size 0x" + utohexstr(OS->Size) +
+                  " exceeds available address space");
+
+  // Check for overlapping file offsets. In this case we need to skip any
+  // section marked as SHT_NOBITS. These sections don't actually occupy space in
+  // the file so Sec->Offset + Sec->Size can overlap with others. If --oformat
+  // binary is specified only add SHF_ALLOC sections are added to the output
+  // file so we skip any non-allocated sections in that case.
   std::vector<SectionOffset> FileOffs;
   for (OutputSection *Sec : OutputSections)
     if (0 < Sec->Size && Sec->Type != SHT_NOBITS &&
@@ -2208,14 +2338,6 @@
 template <class ELFT> void Writer<ELFT>::writeSections() {
   uint8_t *Buf = Buffer->getBufferStart();
 
-  // PPC64 needs to process relocations in the .opd section
-  // before processing relocations in code-containing sections.
-  if (auto *OpdCmd = findSection(".opd")) {
-    Out::Opd = OpdCmd;
-    Out::OpdBuf = Buf + Out::Opd->Offset;
-    OpdCmd->template writeTo<ELFT>(Buf + Out::Opd->Offset);
-  }
-
   OutputSection *EhFrameHdr = nullptr;
   if (InX::EhFrameHdr && !InX::EhFrameHdr->empty())
     EhFrameHdr = InX::EhFrameHdr->getParent();
@@ -2228,8 +2350,7 @@
       Sec->writeTo<ELFT>(Buf + Sec->Offset);
 
   for (OutputSection *Sec : OutputSections)
-    if (Sec != Out::Opd && Sec != EhFrameHdr && Sec->Type != SHT_REL &&
-        Sec->Type != SHT_RELA)
+    if (Sec != EhFrameHdr && Sec->Type != SHT_REL && Sec->Type != SHT_RELA)
       Sec->writeTo<ELFT>(Buf + Sec->Offset);
 
   // The .eh_frame_hdr depends on .eh_frame section contents, therefore
diff --git a/ELF/Writer.h b/ELF/Writer.h
index 41f1e55..7806f82 100644
--- a/ELF/Writer.h
+++ b/ELF/Writer.h
@@ -48,7 +48,7 @@
 };
 
 void addReservedSymbols();
-llvm::StringRef getOutputSectionName(InputSectionBase *S);
+llvm::StringRef getOutputSectionName(const InputSectionBase *S);
 
 template <class ELFT> uint32_t calcMipsEFlags();
 
diff --git a/MinGW/Driver.cpp b/MinGW/Driver.cpp
index 0b7e083..3e285e7 100644
--- a/MinGW/Driver.cpp
+++ b/MinGW/Driver.cpp
@@ -136,6 +136,8 @@
     Add("-output-def:" + StringRef(A->getValue()));
   if (auto *A = Args.getLastArg(OPT_image_base))
     Add("-base:" + StringRef(A->getValue()));
+  if (auto *A = Args.getLastArg(OPT_map))
+    Add("-lldmap:" + StringRef(A->getValue()));
 
   if (auto *A = Args.getLastArg(OPT_o))
     Add("-out:" + StringRef(A->getValue()));
@@ -144,14 +146,19 @@
   else
     Add("-out:a.exe");
 
+  if (auto *A = Args.getLastArg(OPT_pdb)) {
+    Add("-debug");
+    Add("-pdb:" + StringRef(A->getValue()));
+  } else if (!Args.hasArg(OPT_strip_all)) {
+    Add("-debug:dwarf");
+  }
+
   if (Args.hasArg(OPT_shared))
     Add("-dll");
   if (Args.hasArg(OPT_verbose))
     Add("-verbose");
   if (Args.hasArg(OPT_export_all_symbols))
     Add("-export-all-symbols");
-  if (!Args.hasArg(OPT_strip_all))
-    Add("-debug:dwarf");
   if (Args.hasArg(OPT_large_address_aware))
     Add("-largeaddressaware");
   if (Args.hasArg(OPT_kill_at))
diff --git a/MinGW/Options.td b/MinGW/Options.td
index 6840471..7e15bcd 100644
--- a/MinGW/Options.td
+++ b/MinGW/Options.td
@@ -18,6 +18,8 @@
 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_whole_archive: F<"no-whole-archive">,
     HelpText<"No longer include all object files for following archives">;
 def large_address_aware: Flag<["--"], "large-address-aware">,
@@ -41,6 +43,7 @@
 def _HASH_HASH_HASH : Flag<["-"], "###">,
     HelpText<"Print (but do not run) the commands to run for this compilation">;
 def mllvm: S<"mllvm">;
+def pdb: S<"pdb">, HelpText<"Specify output PDB debug information file">;
 def Xlink : J<"Xlink=">, MetaVarName<"<arg>">,
     HelpText<"Pass <arg> to the COFF linker">;
 
diff --git a/docs/WebAssembly.rst b/docs/WebAssembly.rst
index 1df8fa3..264d221 100644
--- a/docs/WebAssembly.rst
+++ b/docs/WebAssembly.rst
@@ -18,7 +18,7 @@
 https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md.
 
 This is object format that the llvm will produce when run with the
-``wasm32-unknown-unknown-wasm`` target.  To build llvm with WebAssembly support
+``wasm32-unknown-unknown`` target.  To build llvm with WebAssembly support
 currently requires enabling the experimental backed using
 ``-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly``.
 
diff --git a/docs/ld.lld.1 b/docs/ld.lld.1
index 2ae3cd2..7f3a747 100644
--- a/docs/ld.lld.1
+++ b/docs/ld.lld.1
@@ -3,7 +3,7 @@
 .\"
 .\" This man page documents only lld's ELF linking support, obtained originally
 .\" from FreeBSD.
-.Dd February 9, 2018
+.Dd April 28, 2018
 .Dt LD.LLD 1
 .Os
 .Sh NAME
@@ -289,6 +289,15 @@
 List removed unused sections.
 .It Fl -print-map
 Print a link map to the standard output.
+.It Fl -push-state
+Save the current state of
+.Fl -as-needed ,
+.Fl -static ,
+and
+.Fl -while-archive.
+.It Fl -pop-state
+Undo the effect of
+.Fl -push-state.
 .It Fl -relocatable
 Create relocatable object file.
 .It Fl -reproduce Ns = Ns Ar value
@@ -401,6 +410,10 @@
 .It Fl v
 Display the version number and proceed with linking if object files are
 specified.
+.It Fl -warn-backrefs
+Warn about reverse or cyclic dependencies to or between static archives.
+This can be used to ensure linker invocation remains compatible with
+traditional Unix-like linkers.
 .It Fl -warn-common
 Warn about duplicate common symbols.
 .It Fl -warn-unresolved-symbols
@@ -525,3 +538,8 @@
 In practice, large bodies of third party software have been linked with
 .Nm
 without material issues.
+.Pp
+The
+.Fl -warn-backrefs
+option may be used to identify a linker invocation that may be incompatible
+with traditional Unix-like linker behavior.
diff --git a/include/lld/Common/ErrorHandler.h b/include/lld/Common/ErrorHandler.h
index 8ae6f46..b6c78f1 100644
--- a/include/lld/Common/ErrorHandler.h
+++ b/include/lld/Common/ErrorHandler.h
@@ -34,6 +34,10 @@
 #include "llvm/Support/Error.h"
 #include "llvm/Support/FileOutputBuffer.h"
 
+namespace llvm {
+class DiagnosticInfo;
+}
+
 namespace lld {
 
 class ErrorHandler {
@@ -74,6 +78,9 @@
 
 LLVM_ATTRIBUTE_NORETURN void exitLld(int Val);
 
+void diagnosticHandler(const llvm::DiagnosticInfo &DI);
+void checkError(Error E);
+
 // check functions are convenient functions to strip errors
 // from error-or-value objects.
 template <class T> T check(ErrorOr<T> E) {
diff --git a/include/lld/Common/Strings.h b/include/lld/Common/Strings.h
index 3be5eb9..e17b257 100644
--- a/include/lld/Common/Strings.h
+++ b/include/lld/Common/Strings.h
@@ -26,35 +26,8 @@
 std::vector<uint8_t> parseHex(llvm::StringRef S);
 bool isValidCIdentifier(llvm::StringRef S);
 
-// This is a lazy version of StringRef. String size is computed lazily
-// when it is needed. It is more efficient than StringRef to instantiate
-// if you have a string whose size is unknown.
-//
-// COFF and ELF string tables contain a lot of null-terminated strings.
-// Most of them are not necessary for the linker because they are names
-// of local symbols and the linker doesn't use local symbol names for
-// name resolution. So, we use this class to represents strings read
-// from string tables.
-class StringRefZ {
-public:
-  StringRefZ() : Start(nullptr), Size(0) {}
-  StringRefZ(const char *S, size_t Size) : Start(S), Size(Size) {}
-
-  /*implicit*/ StringRefZ(const char *S) : Start(S), Size(-1) {}
-
-  /*implicit*/ StringRefZ(llvm::StringRef S)
-      : Start(S.data()), Size(S.size()) {}
-
-  operator llvm::StringRef() const {
-    if (Size == (size_t)-1)
-      Size = strlen(Start);
-    return {Start, Size};
-  }
-
-private:
-  const char *Start;
-  mutable size_t Size;
-};
+// Write the contents of the a buffer to a file
+void saveBuffer(llvm::StringRef Buffer, const llvm::Twine &Path);
 
 // This class represents multiple glob patterns.
 class StringMatcher {
@@ -71,6 +44,6 @@
 inline llvm::ArrayRef<uint8_t> toArrayRef(llvm::StringRef S) {
   return {reinterpret_cast<const uint8_t *>(S.data()), S.size()};
 }
-}
+} // namespace lld
 
 #endif
diff --git a/include/lld/Common/Version.h b/include/lld/Common/Version.h
index 93de77d..23a10ed 100644
--- a/include/lld/Common/Version.h
+++ b/include/lld/Common/Version.h
@@ -18,7 +18,7 @@
 #include "llvm/ADT/StringRef.h"
 
 namespace lld {
-/// \brief Retrieves a string representing the complete lld version.
+/// Retrieves a string representing the complete lld version.
 std::string getLLDVersion();
 }
 
diff --git a/include/lld/Core/DefinedAtom.h b/include/lld/Core/DefinedAtom.h
index 6229d67..ba10b45 100644
--- a/include/lld/Core/DefinedAtom.h
+++ b/include/lld/Core/DefinedAtom.h
@@ -18,7 +18,7 @@
 namespace lld {
 class File;
 
-/// \brief The fundamental unit of linking.
+/// The fundamental unit of linking.
 ///
 /// A C function or global variable is an atom.  An atom has content and
 /// attributes. The content of a function atom is the instructions that
@@ -179,10 +179,10 @@
   };
 
   enum DynamicExport {
-    /// \brief The linker may or may not export this atom dynamically depending
+    /// The linker may or may not export this atom dynamically depending
     ///   on the output type and other context of the link.
     dynamicExportNormal,
-    /// \brief The linker will always export this atom dynamically.
+    /// The linker will always export this atom dynamically.
     dynamicExportAlways,
   };
 
@@ -212,26 +212,26 @@
     }
   };
 
-  /// \brief returns a value for the order of this Atom within its file.
+  /// returns a value for the order of this Atom within its file.
   ///
   /// This is used by the linker to order the layout of Atoms so that the
   /// resulting image is stable and reproducible.
   virtual uint64_t ordinal() const = 0;
 
-  /// \brief the number of bytes of space this atom's content will occupy in the
+  /// the number of bytes of space this atom's content will occupy in the
   /// final linked image.
   ///
   /// For a function atom, it is the number of bytes of code in the function.
   virtual uint64_t size() const = 0;
 
-  /// \brief The size of the section from which the atom is instantiated.
+  /// The size of the section from which the atom is instantiated.
   ///
   /// Merge::mergeByLargestSection is defined in terms of section size
   /// and not in terms of atom size, so we need this function separate
   /// from size().
   virtual uint64_t sectionSize() const { return 0; }
 
-  /// \brief The visibility of this atom to other atoms.
+  /// The visibility of this atom to other atoms.
   ///
   /// C static functions have scope scopeTranslationUnit.  Regular C functions
   /// have scope scopeGlobal.  Functions compiled with visibility=hidden have
@@ -239,48 +239,48 @@
   /// not by the OS loader.
   virtual Scope scope() const = 0;
 
-  /// \brief Whether the linker should use direct or indirect access to this
+  /// Whether the linker should use direct or indirect access to this
   /// atom.
   virtual Interposable interposable() const = 0;
 
-  /// \brief how the linker should handle if multiple atoms have the same name.
+  /// how the linker should handle if multiple atoms have the same name.
   virtual Merge merge() const = 0;
 
-  /// \brief The type of this atom, such as code or data.
+  /// The type of this atom, such as code or data.
   virtual ContentType contentType() const = 0;
 
-  /// \brief The alignment constraints on how this atom must be laid out in the
+  /// The alignment constraints on how this atom must be laid out in the
   /// final linked image (e.g. 16-byte aligned).
   virtual Alignment alignment() const = 0;
 
-  /// \brief Whether this atom must be in a specially named section in the final
+  /// Whether this atom must be in a specially named section in the final
   /// linked image, or if the linker can infer the section based on the
   /// contentType().
   virtual SectionChoice sectionChoice() const = 0;
 
-  /// \brief If sectionChoice() != sectionBasedOnContent, then this return the
+  /// If sectionChoice() != sectionBasedOnContent, then this return the
   /// name of the section the atom should be placed into.
   virtual StringRef customSectionName() const = 0;
 
-  /// \brief constraints on whether the linker may dead strip away this atom.
+  /// constraints on whether the linker may dead strip away this atom.
   virtual DeadStripKind deadStrip() const = 0;
 
-  /// \brief Under which conditions should this atom be dynamically exported.
+  /// Under which conditions should this atom be dynamically exported.
   virtual DynamicExport dynamicExport() const {
     return dynamicExportNormal;
   }
 
-  /// \brief Code model used by the atom.
+  /// Code model used by the atom.
   virtual CodeModel codeModel() const { return codeNA; }
 
-  /// \brief Returns the OS memory protections required for this atom's content
+  /// Returns the OS memory protections required for this atom's content
   /// at runtime.
   ///
   /// A function atom is R_X, a global variable is RW_, and a read-only constant
   /// is R__.
   virtual ContentPermissions permissions() const;
 
-  /// \brief returns a reference to the raw (unrelocated) bytes of this Atom's
+  /// returns a reference to the raw (unrelocated) bytes of this Atom's
   /// content.
   virtual ArrayRef<uint8_t> rawContent() const = 0;
 
@@ -317,10 +317,10 @@
     const void *_it;
   };
 
-  /// \brief Returns an iterator to the beginning of this Atom's References.
+  /// Returns an iterator to the beginning of this Atom's References.
   virtual reference_iterator begin() const = 0;
 
-  /// \brief Returns an iterator to the end of this Atom's References.
+  /// Returns an iterator to the end of this Atom's References.
   virtual reference_iterator end() const = 0;
 
   /// Adds a reference to this atom.
@@ -361,11 +361,11 @@
 
   ~DefinedAtom() override = default;
 
-  /// \brief Returns a pointer to the Reference object that the abstract
+  /// Returns a pointer to the Reference object that the abstract
   /// iterator "points" to.
   virtual const Reference *derefIterator(const void *iter) const = 0;
 
-  /// \brief Adjusts the abstract iterator to "point" to the next Reference
+  /// Adjusts the abstract iterator to "point" to the next Reference
   /// object for this Atom.
   virtual void incrementIterator(const void *&iter) const = 0;
 };
diff --git a/include/lld/Core/File.h b/include/lld/Core/File.h
index 2041868..54f5335 100644
--- a/include/lld/Core/File.h
+++ b/include/lld/Core/File.h
@@ -43,7 +43,7 @@
 public:
   virtual ~File();
 
-  /// \brief Kinds of files that are supported.
+  /// Kinds of files that are supported.
   enum Kind {
     kindErrorObject,          ///< a error object file (.o)
     kindNormalizedObject,     ///< a normalized file (.o)
@@ -59,7 +59,7 @@
     kindArchiveLibrary        ///< archive (.a)
   };
 
-  /// \brief Returns file kind.  Need for dyn_cast<> on File objects.
+  /// Returns file kind.  Need for dyn_cast<> on File objects.
   Kind kind() const {
     return _kind;
   }
@@ -114,10 +114,8 @@
     AtomRange(AtomVector<T> &v) : _v(v) {}
     AtomRange(const AtomVector<T> &v) : _v(const_cast<AtomVector<T> &>(v)) {}
 
-    typedef std::pointer_to_unary_function<const OwningAtomPtr<T>&,
-                                           const T*> ConstDerefFn;
-
-    typedef std::pointer_to_unary_function<OwningAtomPtr<T>&, T*> DerefFn;
+    using ConstDerefFn = const T* (*)(const OwningAtomPtr<T>&);
+    using DerefFn = T* (*)(OwningAtomPtr<T>&);
 
     typedef llvm::mapped_iterator<typename AtomVector<T>::const_iterator,
                                   ConstDerefFn> ConstItTy;
@@ -174,19 +172,19 @@
     AtomVector<T> &_v;
   };
 
-  /// \brief Must be implemented to return the AtomVector object for
+  /// Must be implemented to return the AtomVector object for
   /// all DefinedAtoms in this File.
   virtual const AtomRange<DefinedAtom> defined() const = 0;
 
-  /// \brief Must be implemented to return the AtomVector object for
+  /// Must be implemented to return the AtomVector object for
   /// all UndefinedAtomw in this File.
   virtual const AtomRange<UndefinedAtom> undefined() const = 0;
 
-  /// \brief Must be implemented to return the AtomVector object for
+  /// Must be implemented to return the AtomVector object for
   /// all SharedLibraryAtoms in this File.
   virtual const AtomRange<SharedLibraryAtom> sharedLibrary() const = 0;
 
-  /// \brief Must be implemented to return the AtomVector object for
+  /// Must be implemented to return the AtomVector object for
   /// all AbsoluteAtoms in this File.
   virtual const AtomRange<AbsoluteAtom> absolute() const = 0;
 
@@ -196,7 +194,7 @@
   /// of a different file.  We need to destruct all atoms before any files.
   virtual void clearAtoms() = 0;
 
-  /// \brief If a file is parsed using a different method than doParse(),
+  /// If a file is parsed using a different method than doParse(),
   /// one must use this method to set the last error status, so that
   /// doParse will not be called twice. Only YAML reader uses this
   /// (because YAML reader does not read blobs but structured data).
@@ -214,12 +212,12 @@
   }
 
 protected:
-  /// \brief only subclasses of File can be instantiated
+  /// only subclasses of File can be instantiated
   File(StringRef p, Kind kind)
     : _path(p), _kind(kind), _ordinal(UINT64_MAX),
       _nextAtomOrdinal(0) {}
 
-  /// \brief Subclasses should override this method to parse the
+  /// Subclasses should override this method to parse the
   /// memory buffer passed to this file's constructor.
   virtual std::error_code doParse() { return std::error_code(); }
 
diff --git a/include/lld/Core/Instrumentation.h b/include/lld/Core/Instrumentation.h
index 1623759..939d645 100644
--- a/include/lld/Core/Instrumentation.h
+++ b/include/lld/Core/Instrumentation.h
@@ -8,7 +8,7 @@
 //===----------------------------------------------------------------------===//
 ///
 /// \file
-/// \brief Provide an Instrumentation API that optionally uses VTune interfaces.
+/// Provide an Instrumentation API that optionally uses VTune interfaces.
 ///
 //===----------------------------------------------------------------------===//
 
@@ -24,7 +24,7 @@
 
 namespace lld {
 #ifdef LLD_HAS_VTUNE
-/// \brief A unique global scope for instrumentation data.
+/// A unique global scope for instrumentation data.
 ///
 /// Domains last for the lifetime of the application and cannot be destroyed.
 /// Multiple Domains created with the same name represent the same domain.
@@ -38,7 +38,7 @@
   __itt_domain *operator->() const { return _domain; }
 };
 
-/// \brief A global reference to a string constant.
+/// A global reference to a string constant.
 ///
 /// These are uniqued by the ITT runtime and cannot be deleted. They are not
 /// specific to a domain.
@@ -54,7 +54,7 @@
   operator __itt_string_handle *() const { return _handle; }
 };
 
-/// \brief A task on a single thread. Nests within other tasks.
+/// A task on a single thread. Nests within other tasks.
 ///
 /// Each thread has its own task stack and tasks nest recursively on that stack.
 /// A task cannot transfer threads.
@@ -68,7 +68,7 @@
   ScopedTask &operator=(const ScopedTask &) = delete;
 
 public:
-  /// \brief Create a task in Domain \p d named \p s.
+  /// Create a task in Domain \p d named \p s.
   ScopedTask(const Domain &d, const StringHandle &s) : _domain(d) {
     __itt_task_begin(d, __itt_null, __itt_null, s);
   }
@@ -83,7 +83,7 @@
     return *this;
   }
 
-  /// \brief Prematurely end this task.
+  /// Prematurely end this task.
   void end() {
     if (_domain)
       __itt_task_end(_domain);
@@ -93,7 +93,7 @@
   ~ScopedTask() { end(); }
 };
 
-/// \brief A specific point in time. Allows metadata to be associated.
+/// A specific point in time. Allows metadata to be associated.
 class Marker {
 public:
   Marker(const Domain &d, const StringHandle &s) {
diff --git a/include/lld/Core/LinkingContext.h b/include/lld/Core/LinkingContext.h
index eb9510c..6dffdd4 100644
--- a/include/lld/Core/LinkingContext.h
+++ b/include/lld/Core/LinkingContext.h
@@ -31,7 +31,7 @@
 class Node;
 class SharedLibraryFile;
 
-/// \brief The LinkingContext class encapsulates "what and how" to link.
+/// The LinkingContext class encapsulates "what and how" to link.
 ///
 /// The base class LinkingContext contains the options needed by core linking.
 /// Subclasses of LinkingContext have additional options needed by specific
diff --git a/include/lld/Core/PassManager.h b/include/lld/Core/PassManager.h
index 2ea65ae..f2ef10f 100644
--- a/include/lld/Core/PassManager.h
+++ b/include/lld/Core/PassManager.h
@@ -20,7 +20,7 @@
 class SimpleFile;
 class Pass;
 
-/// \brief Owns and runs a collection of passes.
+/// Owns and runs a collection of passes.
 ///
 /// This class is currently just a container for passes and a way to run them.
 ///
@@ -40,7 +40,7 @@
   }
 
 private:
-  /// \brief Passes in the order they should run.
+  /// Passes in the order they should run.
   std::vector<std::unique_ptr<Pass>> _passes;
 };
 } // end namespace lld
diff --git a/include/lld/Core/Reader.h b/include/lld/Core/Reader.h
index c7baf86..6cf6282 100644
--- a/include/lld/Core/Reader.h
+++ b/include/lld/Core/Reader.h
@@ -32,7 +32,7 @@
 class LinkingContext;
 class MachOLinkingContext;
 
-/// \brief An abstract class for reading object files, library files, and
+/// An abstract class for reading object files, library files, and
 /// executable files.
 ///
 /// Each file format (e.g. mach-o, etc) has a concrete subclass of Reader.
@@ -46,14 +46,14 @@
   /// 2) the whole file content buffer if the above is not enough.
   virtual bool canParse(llvm::file_magic magic, MemoryBufferRef mb) const = 0;
 
-  /// \brief Parse a supplied buffer (already filled with the contents of a
+  /// Parse a supplied buffer (already filled with the contents of a
   /// file) and create a File object.
   /// The resulting File object takes ownership of the MemoryBuffer.
   virtual ErrorOr<std::unique_ptr<File>>
   loadFile(std::unique_ptr<MemoryBuffer> mb, const class Registry &) const = 0;
 };
 
-/// \brief An abstract class for handling alternate yaml representations
+/// An abstract class for handling alternate yaml representations
 /// of object files.
 ///
 /// The YAML syntax allows "tags" which are used to specify the type of
diff --git a/include/lld/Core/Resolver.h b/include/lld/Core/Resolver.h
index fb62a77..5157c9f 100644
--- a/include/lld/Core/Resolver.h
+++ b/include/lld/Core/Resolver.h
@@ -28,7 +28,7 @@
 class Atom;
 class LinkingContext;
 
-/// \brief The Resolver is responsible for merging all input object files
+/// The Resolver is responsible for merging all input object files
 /// and producing a merged graph.
 class Resolver {
 public:
@@ -50,7 +50,7 @@
   // Handle a shared library file.
   llvm::Error handleSharedLibrary(File &);
 
-  /// @brief do work of merging and resolving and return list
+  /// do work of merging and resolving and return list
   bool resolve();
 
   std::unique_ptr<SimpleFile> resultFile() { return std::move(_result); }
@@ -61,7 +61,7 @@
   bool undefinesAdded(int begin, int end);
   File *getFile(int &index);
 
-  /// \brief The main function that iterates over the files to resolve
+  /// The main function that iterates over the files to resolve
   bool resolveUndefines();
   void updateReferences();
   void deadStripOptimize();
diff --git a/include/lld/Core/Simple.h b/include/lld/Core/Simple.h
index 3aa7abf..feeed6a 100644
--- a/include/lld/Core/Simple.h
+++ b/include/lld/Core/Simple.h
@@ -8,7 +8,7 @@
 //===----------------------------------------------------------------------===//
 ///
 /// \file
-/// \brief Provide simple implementations for Atoms and File.
+/// Provide simple implementations for Atoms and File.
 ///
 //===----------------------------------------------------------------------===//
 
diff --git a/include/lld/Core/SymbolTable.h b/include/lld/Core/SymbolTable.h
index 603f497..156c56e 100644
--- a/include/lld/Core/SymbolTable.h
+++ b/include/lld/Core/SymbolTable.h
@@ -27,35 +27,35 @@
 class SharedLibraryAtom;
 class UndefinedAtom;
 
-/// \brief The SymbolTable class is responsible for coalescing atoms.
+/// The SymbolTable class is responsible for coalescing atoms.
 ///
 /// All atoms coalescable by-name or by-content should be added.
 /// The method replacement() can be used to find the replacement atom
 /// if an atom has been coalesced away.
 class SymbolTable {
 public:
-  /// @brief add atom to symbol table
+  /// add atom to symbol table
   bool add(const DefinedAtom &);
 
-  /// @brief add atom to symbol table
+  /// add atom to symbol table
   bool add(const UndefinedAtom &);
 
-  /// @brief add atom to symbol table
+  /// add atom to symbol table
   bool add(const SharedLibraryAtom &);
 
-  /// @brief add atom to symbol table
+  /// add atom to symbol table
   bool add(const AbsoluteAtom &);
 
-  /// @brief returns atom in symbol table for specified name (or nullptr)
+  /// returns atom in symbol table for specified name (or nullptr)
   const Atom *findByName(StringRef sym);
 
-  /// @brief returns vector of remaining UndefinedAtoms
+  /// returns vector of remaining UndefinedAtoms
   std::vector<const UndefinedAtom *> undefines();
 
-  /// @brief if atom has been coalesced away, return replacement, else return atom
+  /// if atom has been coalesced away, return replacement, else return atom
   const Atom *replacement(const Atom *);
 
-  /// @brief if atom has been coalesced away, return true
+  /// if atom has been coalesced away, return true
   bool isCoalescedAway(const Atom *);
 
 private:
diff --git a/include/lld/Core/Writer.h b/include/lld/Core/Writer.h
index 1f0ca4c..1cdfabe 100644
--- a/include/lld/Core/Writer.h
+++ b/include/lld/Core/Writer.h
@@ -20,17 +20,17 @@
 class LinkingContext;
 class MachOLinkingContext;
 
-/// \brief The Writer is an abstract class for writing object files, shared
+/// The Writer is an abstract class for writing object files, shared
 /// library files, and executable files.  Each file format (e.g. mach-o, etc)
 /// has a concrete subclass of Writer.
 class Writer {
 public:
   virtual ~Writer();
 
-  /// \brief Write a file from the supplied File object
+  /// Write a file from the supplied File object
   virtual llvm::Error writeFile(const File &linkedFile, StringRef path) = 0;
 
-  /// \brief This method is called by Core Linking to give the Writer a chance
+  /// This method is called by Core Linking to give the Writer a chance
   /// to add file format specific "files" to set of files to be linked. This is
   /// how file format specific atoms can be added to the link.
   virtual void createImplicitFiles(std::vector<std::unique_ptr<File>> &) {}
diff --git a/include/lld/ReaderWriter/MachOLinkingContext.h b/include/lld/ReaderWriter/MachOLinkingContext.h
index 9eefa8c..5f9588d 100644
--- a/include/lld/ReaderWriter/MachOLinkingContext.h
+++ b/include/lld/ReaderWriter/MachOLinkingContext.h
@@ -201,7 +201,7 @@
 
   uint32_t swiftVersion() const { return _swiftVersion; }
 
-  /// \brief Checks whether a given path on the filesystem exists.
+  /// Checks whether a given path on the filesystem exists.
   ///
   /// When running in -test_file_usage mode, this method consults an
   /// internally maintained list of files that exist (provided by -path_exists)
@@ -211,7 +211,7 @@
   /// Like pathExists() but only used on files - not directories.
   bool fileExists(StringRef path) const;
 
-  /// \brief Adds any library search paths derived from the given base, possibly
+  /// Adds any library search paths derived from the given base, possibly
   /// modified by -syslibroots.
   ///
   /// The set of paths added consists of approximately all syslibroot-prepended
@@ -219,7 +219,7 @@
   /// for whatever reason. With various edge-cases for compatibility.
   void addModifiedSearchDir(StringRef libPath, bool isSystemPath = false);
 
-  /// \brief Determine whether -lFoo can be resolve within the given path, and
+  /// Determine whether -lFoo can be resolve within the given path, and
   /// return the filename if so.
   ///
   /// The -lFoo option is documented to search for libFoo.dylib and libFoo.a in
@@ -228,7 +228,7 @@
   llvm::Optional<StringRef> searchDirForLibrary(StringRef path,
                                                 StringRef libName) const;
 
-  /// \brief Iterates through all search path entries looking for libName (as
+  /// Iterates through all search path entries looking for libName (as
   /// specified by -lFoo).
   llvm::Optional<StringRef> searchLibrary(StringRef libName) const;
 
@@ -236,11 +236,11 @@
   /// the path with syslibroot.
   void addFrameworkSearchDir(StringRef fwPath, bool isSystemPath = false);
 
-  /// \brief Iterates through all framework directories looking for
+  /// Iterates through all framework directories looking for
   /// Foo.framework/Foo (when fwName = "Foo").
   llvm::Optional<StringRef> findPathForFramework(StringRef fwName) const;
 
-  /// \brief The dylib's binary compatibility version, in the raw uint32 format.
+  /// The dylib's binary compatibility version, in the raw uint32 format.
   ///
   /// When building a dynamic library, this is the compatibility version that
   /// gets embedded into the result. Other Mach-O binaries that link against
@@ -249,28 +249,28 @@
   /// installed dynamic library.
   uint32_t compatibilityVersion() const { return _compatibilityVersion; }
 
-  /// \brief The dylib's current version, in the the raw uint32 format.
+  /// The dylib's current version, in the the raw uint32 format.
   ///
   /// When building a dynamic library, this is the current version that gets
   /// embedded into the result. Other Mach-O binaries that link against
   /// this library will store the compatibility version in its load command.
   uint32_t currentVersion() const { return _currentVersion; }
 
-  /// \brief The dylib's install name.
+  /// The dylib's install name.
   ///
   /// Binaries that link against the dylib will embed this path into the dylib
   /// load command. When loading the binaries at runtime, this is the location
   /// on disk that the loader will look for the dylib.
   StringRef installName() const { return _installName; }
 
-  /// \brief Whether or not the dylib has side effects during initialization.
+  /// Whether or not the dylib has side effects during initialization.
   ///
   /// Dylibs marked as being dead strippable provide the guarantee that loading
   /// the dylib has no side effects, allowing the linker to strip out the dylib
   /// when linking a binary that does not use any of its symbols.
   bool deadStrippableDylib() const { return _deadStrippableDylib; }
 
-  /// \brief Whether or not to use flat namespace.
+  /// Whether or not to use flat namespace.
   ///
   /// MachO usually uses a two-level namespace, where each external symbol
   /// referenced by the target is associated with the dylib that will provide
@@ -282,7 +282,7 @@
   /// loaded flat_namespace dylibs must be resolvable at build time.
   bool useFlatNamespace() const { return _flatNamespace; }
 
-  /// \brief How to handle undefined symbols.
+  /// How to handle undefined symbols.
   ///
   /// Options are:
   ///  * error: Report an error and terminate linking.
@@ -294,7 +294,7 @@
   ///    runtime.
   UndefinedMode undefinedMode() const { return _undefinedMode; }
 
-  /// \brief The path to the executable that will load the bundle at runtime.
+  /// The path to the executable that will load the bundle at runtime.
   ///
   /// When building a Mach-O bundle, this executable will be examined if there
   /// are undefined symbols after the main link phase. It is expected that this
@@ -331,7 +331,7 @@
   /// Add section alignment constraint on final layout.
   void addSectionAlignment(StringRef seg, StringRef sect, uint16_t align);
 
-  /// \brief Add a section based on a command-line sectcreate option.
+  /// Add a section based on a command-line sectcreate option.
   void addSectCreateSection(StringRef seg, StringRef sect,
                             std::unique_ptr<MemoryBuffer> content);
 
diff --git a/lib/Driver/DarwinLdDriver.cpp b/lib/Driver/DarwinLdDriver.cpp
index a019e9c..e016a3d 100644
--- a/lib/Driver/DarwinLdDriver.cpp
+++ b/lib/Driver/DarwinLdDriver.cpp
@@ -1068,7 +1068,7 @@
   }
 
   // Parse the LLVM options before we process files in case the file handling
-  // makes use of things like DEBUG().
+  // makes use of things like LLVM_DEBUG().
   parseLLVMOptions(ctx);
 
   // Handle input files and sectcreate.
diff --git a/lib/ReaderWriter/FileArchive.cpp b/lib/ReaderWriter/FileArchive.cpp
index 04c0bee..2f52d9d 100644
--- a/lib/ReaderWriter/FileArchive.cpp
+++ b/lib/ReaderWriter/FileArchive.cpp
@@ -38,7 +38,7 @@
 
 namespace {
 
-/// \brief The FileArchive class represents an Archive Library file
+/// The FileArchive class represents an Archive Library file
 class FileArchive : public lld::ArchiveLibraryFile {
 public:
   FileArchive(std::unique_ptr<MemoryBuffer> mb, const Registry &reg,
@@ -46,7 +46,7 @@
       : ArchiveLibraryFile(path), _mb(std::shared_ptr<MemoryBuffer>(mb.release())),
         _registry(reg), _logLoading(logLoading) {}
 
-  /// \brief Check if any member of the archive contains an Atom with the
+  /// Check if any member of the archive contains an Atom with the
   /// specified name and return the File object for that member, or nullptr.
   File *find(StringRef name) override {
     auto member = _symbolMemberMap.find(name);
@@ -77,7 +77,7 @@
     return file;
   }
 
-  /// \brief parse each member
+  /// parse each member
   std::error_code
   parseAllMembers(std::vector<std::unique_ptr<File>> &result) override {
     if (std::error_code ec = parse())
diff --git a/lib/ReaderWriter/MachO/CompactUnwindPass.cpp b/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
index 1e21040..fa0aaa1 100644
--- a/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
+++ b/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
@@ -282,7 +282,7 @@
 
 private:
   llvm::Error perform(SimpleFile &mergedFile) override {
-    DEBUG(llvm::dbgs() << "MachO Compact Unwind pass\n");
+    LLVM_DEBUG(llvm::dbgs() << "MachO Compact Unwind pass\n");
 
     std::map<const Atom *, CompactUnwindEntry> unwindLocs;
     std::map<const Atom *, const Atom *> dwarfFrames;
@@ -319,7 +319,7 @@
 
     // Finally, we can start creating pages based on these entries.
 
-    DEBUG(llvm::dbgs() << "  Splitting entries into pages\n");
+    LLVM_DEBUG(llvm::dbgs() << "  Splitting entries into pages\n");
     // FIXME: we split the entries into pages naively: lots of 4k pages followed
     // by a small one. ld64 tried to minimize space and align them to real 4k
     // boundaries. That might be worth doing, or perhaps we could perform some
@@ -336,11 +336,13 @@
       pages.back().entries = remainingInfos.slice(0, entriesInPage);
       remainingInfos = remainingInfos.slice(entriesInPage);
 
-      DEBUG(llvm::dbgs()
-            << "    Page from " << pages.back().entries[0].rangeStart->name()
-            << " to " << pages.back().entries.back().rangeStart->name() << " + "
-            << llvm::format("0x%x", pages.back().entries.back().rangeLength)
-            << " has " << entriesInPage << " entries\n");
+      LLVM_DEBUG(llvm::dbgs()
+                 << "    Page from "
+                 << pages.back().entries[0].rangeStart->name() << " to "
+                 << pages.back().entries.back().rangeStart->name() << " + "
+                 << llvm::format("0x%x",
+                                 pages.back().entries.back().rangeLength)
+                 << " has " << entriesInPage << " entries\n");
     } while (!remainingInfos.empty());
 
     auto *unwind = new (_file.allocator())
@@ -360,7 +362,7 @@
       const SimpleFile &mergedFile,
       std::map<const Atom *, CompactUnwindEntry> &unwindLocs,
       std::vector<const Atom *> &personalities, uint32_t &numLSDAs) {
-    DEBUG(llvm::dbgs() << "  Collecting __compact_unwind entries\n");
+    LLVM_DEBUG(llvm::dbgs() << "  Collecting __compact_unwind entries\n");
 
     for (const DefinedAtom *atom : mergedFile.defined()) {
       if (atom->contentType() != DefinedAtom::typeCompactUnwindInfo)
@@ -369,14 +371,15 @@
       auto unwindEntry = extractCompactUnwindEntry(atom);
       unwindLocs.insert(std::make_pair(unwindEntry.rangeStart, unwindEntry));
 
-      DEBUG(llvm::dbgs() << "    Entry for " << unwindEntry.rangeStart->name()
-                         << ", encoding="
-                         << llvm::format("0x%08x", unwindEntry.encoding));
+      LLVM_DEBUG(llvm::dbgs() << "    Entry for "
+                              << unwindEntry.rangeStart->name() << ", encoding="
+                              << llvm::format("0x%08x", unwindEntry.encoding));
       if (unwindEntry.personalityFunction)
-        DEBUG(llvm::dbgs() << ", personality="
-                           << unwindEntry.personalityFunction->name()
-                           << ", lsdaLoc=" << unwindEntry.lsdaLocation->name());
-      DEBUG(llvm::dbgs() << '\n');
+        LLVM_DEBUG(llvm::dbgs()
+                   << ", personality="
+                   << unwindEntry.personalityFunction->name()
+                   << ", lsdaLoc=" << unwindEntry.lsdaLocation->name());
+      LLVM_DEBUG(llvm::dbgs() << '\n');
 
       // Count number of LSDAs we see, since we need to know how big the index
       // will be while laying out the section.
@@ -454,7 +457,7 @@
       const std::map<const Atom *, const Atom *> &dwarfFrames) {
     std::vector<CompactUnwindEntry> unwindInfos;
 
-    DEBUG(llvm::dbgs() << "  Creating __unwind_info entries\n");
+    LLVM_DEBUG(llvm::dbgs() << "  Creating __unwind_info entries\n");
     // The final order in the __unwind_info section must be derived from the
     // order of typeCode atoms, since that's how they'll be put into the object
     // file eventually (yuck!).
@@ -465,10 +468,10 @@
       unwindInfos.push_back(finalizeUnwindInfoEntryForAtom(
           atom, unwindLocs, personalities, dwarfFrames));
 
-      DEBUG(llvm::dbgs() << "    Entry for " << atom->name()
-                         << ", final encoding="
-                         << llvm::format("0x%08x", unwindInfos.back().encoding)
-                         << '\n');
+      LLVM_DEBUG(llvm::dbgs()
+                 << "    Entry for " << atom->name() << ", final encoding="
+                 << llvm::format("0x%08x", unwindInfos.back().encoding)
+                 << '\n');
     }
 
     return unwindInfos;
diff --git a/lib/ReaderWriter/MachO/LayoutPass.cpp b/lib/ReaderWriter/MachO/LayoutPass.cpp
index 7bca07e..9058e4f 100644
--- a/lib/ReaderWriter/MachO/LayoutPass.cpp
+++ b/lib/ReaderWriter/MachO/LayoutPass.cpp
@@ -191,7 +191,7 @@
   // Sort atoms by their ordinal overrides only if they fall in the same
   // chain.
   if (leftRoot == rightRoot) {
-    DEBUG(reason = formatReason("override", lc._override, rc._override));
+    LLVM_DEBUG(reason = formatReason("override", lc._override, rc._override));
     return lc._override < rc._override;
   }
 
@@ -200,8 +200,8 @@
   DefinedAtom::ContentPermissions rightPerms = rightRoot->permissions();
 
   if (leftPerms != rightPerms) {
-    DEBUG(reason =
-              formatReason("contentPerms", (int)leftPerms, (int)rightPerms));
+    LLVM_DEBUG(
+        reason = formatReason("contentPerms", (int)leftPerms, (int)rightPerms));
     return leftPerms < rightPerms;
   }
 
@@ -210,7 +210,8 @@
   DefinedAtom::ContentType rightType = rightRoot->contentType();
 
   if (leftType != rightType) {
-    DEBUG(reason = formatReason("contentType", (int)leftType, (int)rightType));
+    LLVM_DEBUG(reason =
+                   formatReason("contentType", (int)leftType, (int)rightType));
     return leftType < rightType;
   }
 
@@ -226,8 +227,8 @@
   const File *rightFile = &rightRoot->file();
 
   if (leftFile != rightFile) {
-    DEBUG(reason = formatReason(".o order", (int)leftFile->ordinal(),
-                                (int)rightFile->ordinal()));
+    LLVM_DEBUG(reason = formatReason(".o order", (int)leftFile->ordinal(),
+                                     (int)rightFile->ordinal()));
     return leftFile->ordinal() < rightFile->ordinal();
   }
 
@@ -236,8 +237,8 @@
   uint64_t rightOrdinal = rightRoot->ordinal();
 
   if (leftOrdinal != rightOrdinal) {
-    DEBUG(reason = formatReason("ordinal", (int)leftRoot->ordinal(),
-                                (int)rightRoot->ordinal()));
+    LLVM_DEBUG(reason = formatReason("ordinal", (int)leftRoot->ordinal(),
+                                     (int)rightRoot->ordinal()));
     return leftOrdinal < rightOrdinal;
   }
 
@@ -251,7 +252,7 @@
                          LayoutPass::SortOverride customSorter) {
   std::string reason;
   bool result = compareAtomsSub(lc, rc, customSorter, reason);
-  DEBUG({
+  LLVM_DEBUG({
     StringRef comp = result ? "<" : ">=";
     llvm::dbgs() << "Layout: '" << lc._atom.get()->name()
                  << "' " << comp << " '"
@@ -441,7 +442,7 @@
 
 /// Perform the actual pass
 llvm::Error LayoutPass::perform(SimpleFile &mergedFile) {
-  DEBUG(llvm::dbgs() << "******** Laying out atoms:\n");
+  LLVM_DEBUG(llvm::dbgs() << "******** Laying out atoms:\n");
   // sort the atoms
   ScopedTask task(getDefaultDomain(), "LayoutPass");
   File::AtomRange<DefinedAtom> atomRange = mergedFile.defined();
@@ -450,12 +451,12 @@
   buildFollowOnTable(atomRange);
 
   // Check the structure of followon graph if running in debug mode.
-  DEBUG(checkFollowonChain(atomRange));
+  LLVM_DEBUG(checkFollowonChain(atomRange));
 
   // Build override maps
   buildOrdinalOverrideMap(atomRange);
 
-  DEBUG({
+  LLVM_DEBUG({
     llvm::dbgs() << "unsorted atoms:\n";
     printDefinedAtoms(atomRange);
   });
@@ -465,15 +466,15 @@
        [&](const LayoutPass::SortKey &l, const LayoutPass::SortKey &r) -> bool {
          return compareAtoms(l, r, _customSorter);
        });
-  DEBUG(checkTransitivity(vec, _customSorter));
+  LLVM_DEBUG(checkTransitivity(vec, _customSorter));
   undecorate(atomRange, vec);
 
-  DEBUG({
+  LLVM_DEBUG({
     llvm::dbgs() << "sorted atoms:\n";
     printDefinedAtoms(atomRange);
   });
 
-  DEBUG(llvm::dbgs() << "******** Finished laying out atoms\n");
+  LLVM_DEBUG(llvm::dbgs() << "******** Finished laying out atoms\n");
   return llvm::Error::success();
 }
 
diff --git a/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
index 4617d23..473de89 100644
--- a/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
+++ b/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
@@ -1431,8 +1431,8 @@
 normalizedObjectToAtoms(MachOFile *file,
                         const NormalizedFile &normalizedFile,
                         bool copyRefs) {
-  DEBUG(llvm::dbgs() << "******** Normalizing file to atoms: "
-                    << file->path() << "\n");
+  LLVM_DEBUG(llvm::dbgs() << "******** Normalizing file to atoms: "
+                          << file->path() << "\n");
   bool scatterable = ((normalizedFile.flags & MH_SUBSECTIONS_VIA_SYMBOLS) != 0);
 
   // Create atoms from each section.
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index f9c3983..e5284ca 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -34,7 +34,7 @@
   list(APPEND LLD_TEST_DEPS
     FileCheck count not llvm-ar llvm-as llvm-dis llvm-dwarfdump llvm-nm
     llc llvm-config llvm-objdump llvm-readelf llvm-readobj yaml2obj obj2yaml
-    llvm-mc llvm-lib llvm-pdbutil opt
+    llvm-mc llvm-lib llvm-pdbutil opt llvm-bcanalyzer
     )
 endif()
 
diff --git a/test/COFF/Inputs/far-arm64-abs.s b/test/COFF/Inputs/far-arm64-abs.s
new file mode 100644
index 0000000..98ccbac
--- /dev/null
+++ b/test/COFF/Inputs/far-arm64-abs.s
@@ -0,0 +1,6 @@
+.global too_far26
+.global too_far19
+.global too_far14
+too_far26 = 0x08011000
+too_far19 = 0x00111000
+too_far14 = 0x00021000
diff --git a/test/COFF/Inputs/pdb-file-statics-a.yaml b/test/COFF/Inputs/pdb-file-statics-a.yaml
index 1a0dbdb..957eb5a 100644
--- a/test/COFF/Inputs/pdb-file-statics-a.yaml
+++ b/test/COFF/Inputs/pdb-file-statics-a.yaml
@@ -1353,7 +1353,7 @@
             RegRelativeSym:
               Offset:          48
               Type:            116
-              Register:        RSP
+              Register:        CVRegRSP
               VarName:         __formal
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
@@ -1528,13 +1528,13 @@
             RegRelativeSym:
               Offset:          48
               Type:            116
-              Register:        RSP
+              Register:        CVRegRSP
               VarName:         argc
           - Kind:            S_REGREL32
             RegRelativeSym:
               Offset:          56
               Type:            4098
-              Register:        RSP
+              Register:        CVRegRSP
               VarName:         argv
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
diff --git a/test/COFF/Inputs/pdb-file-statics-b.yaml b/test/COFF/Inputs/pdb-file-statics-b.yaml
index f74bab7..8b7a311 100644
--- a/test/COFF/Inputs/pdb-file-statics-b.yaml
+++ b/test/COFF/Inputs/pdb-file-statics-b.yaml
@@ -1328,7 +1328,7 @@
             RegRelativeSym:
               Offset:          48
               Type:            116
-              Register:        RSP
+              Register:        CVRegRSP
               VarName:         __formal
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
diff --git a/test/COFF/Inputs/pdb-hashes-1.yaml b/test/COFF/Inputs/pdb-hashes-1.yaml
index ba11ed1..158f936 100644
--- a/test/COFF/Inputs/pdb-hashes-1.yaml
+++ b/test/COFF/Inputs/pdb-hashes-1.yaml
@@ -1,13 +1,13 @@
 --- !COFF
-header:
+header:          
   Machine:         IMAGE_FILE_MACHINE_I386
   Characteristics: [  ]
-sections:
+sections:        
   - Name:            .text
     Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
     Alignment:       16
-    SectionData:     5589E55683EC188B450C8B4D088D55F4C745F8000000008B7508894DF089D18934248945ECE80000000083EC048D4DF4890C248945E8E80000000083C4185E5DC3
-    Relocations:
+    SectionData:     5589E55683EC188B450C8B4D08C745F8000000008B55088D75F4894DF089F18914248945ECE80000000083EC048D4DF4890C248945E8E80000000083C4185E5DC3
+    Relocations:     
       - VirtualAddress:  38
         SymbolName:      '??0Foo@NS@@QAE@H@Z'
         Type:            IMAGE_REL_I386_REL32
@@ -33,25 +33,25 @@
   - Name:            '.debug$S'
     Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
     Alignment:       4
-    SectionData:     04000000F10000002F0000002D003C1101000000070006000000000000007017000000000000636C616E672076657273696F6E20362E302E30200000F50000008400000000000000000000004100000000000000080000000000000052000000070000000400000001000000400000000000000008000000000000007F0000000600040000000000030000003E000000000000000800000000000000BD0000000400040000000000040000003D000000000000000800000000000000FA0000000300080000000000F1000000960000002A00471100000000000000000000000041000000000000000000000003100000000000000000006D61696E000D003E1174000000010061726763001200451116000000080000001700000000002A000D003E11001000000100617267760012004511160000000C0000001700000000002A000A003E1109100000000066001200451116000000F4FFFFFF1700000000002A0002004F110000F200000030000000000000000000000041000000000000000300000024000000000000000300000017000000040000003000000005000000F1000000100000000E000811091000004E533A3A466F6F00F40000003000000001000000100165C9E387F88362A8EB2B49539DD5A65500002B00000010019303CF100D518DAF59C31DA01FEF4AFC0000F30000004801000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A312E63707000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D2024657369202454302038202D205E203D2000
-    Subsections:
+    SectionData:     04000000F10000002F0000002D003C110100000007000700000000000000581B000000000000636C616E672076657273696F6E20372E302E30200000F50000008400000000000000000000004100000000000000080000000000000052000000070000000400000001000000400000000000000008000000000000007F0000000600040000000000030000003E000000000000000800000000000000BD0000000400040000000000040000003D000000000000000800000000000000FA0000000300080000000000F1000000960000002A00471100000000000000000000000041000000000000000000000003100000000000000000006D61696E000D003E1174000000010061726763001200451116000000080000001400000000002D000D003E11001000000100617267760012004511160000000C0000001400000000002D000A003E1109100000000066001200451116000000F4FFFFFF1400000000002D0002004F110000F200000030000000000000000000000041000000000000000300000024000000000000000300000014000000040000002D00000005000000F1000000100000000E000811091000004E533A3A466F6F00F40000003000000001000000100165C9E387F88362A8EB2B49539DD5A65500002B0000001001D3AE9D06B0C1F06ABE75A0557053ED6B0000F30000004801000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A312E63707000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D2024657369202454302038202D205E203D2000
+    Subsections:     
       - !Symbols
-        Records:
+        Records:         
           - Kind:            S_COMPILE3
-            Compile3Sym:
+            Compile3Sym:     
               Flags:           [  ]
               Machine:         Pentium3
-              FrontendMajor:   6
+              FrontendMajor:   7
               FrontendMinor:   0
               FrontendBuild:   0
               FrontendQFE:     0
-              BackendMajor:    6000
+              BackendMajor:    7000
               BackendMinor:    0
               BackendBuild:    0
               BackendQFE:      0
-              Version:         'clang version 6.0.0 '
+              Version:         'clang version 7.0.0 '
       - !FrameData
-        Frames:
+        Frames:          
           - CodeSize:        65
             FrameFunc:       '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = '
             LocalSize:       0
@@ -85,9 +85,9 @@
             RvaStart:        4
             SavedRegsSize:   8
       - !Symbols
-        Records:
+        Records:         
           - Kind:            S_GPROC32_ID
-            ProcSym:
+            ProcSym:         
               CodeSize:        65
               DbgStart:        0
               DbgEnd:          0
@@ -95,66 +95,96 @@
               Flags:           [  ]
               DisplayName:     main
           - Kind:            S_LOCAL
-            LocalSym:
+            LocalSym:        
               Type:            116
               Flags:           [ IsParameter ]
               VarName:         argc
+          - Kind:            S_DEFRANGE_REGISTER_REL
+            DefRangeRegisterRelSym: 
+              Register:        22
+              Flags:           0
+              BasePointerOffset: 8
+              Range:           
+                OffsetStart:     20
+                ISectStart:      0
+                Range:           45
+              Gaps:            
           - Kind:            S_LOCAL
-            LocalSym:
+            LocalSym:        
               Type:            4096
               Flags:           [ IsParameter ]
               VarName:         argv
+          - Kind:            S_DEFRANGE_REGISTER_REL
+            DefRangeRegisterRelSym: 
+              Register:        22
+              Flags:           0
+              BasePointerOffset: 12
+              Range:           
+                OffsetStart:     20
+                ISectStart:      0
+                Range:           45
+              Gaps:            
           - Kind:            S_LOCAL
-            LocalSym:
+            LocalSym:        
               Type:            4105
               Flags:           [  ]
               VarName:         f
+          - Kind:            S_DEFRANGE_REGISTER_REL
+            DefRangeRegisterRelSym: 
+              Register:        22
+              Flags:           0
+              BasePointerOffset: -12
+              Range:           
+                OffsetStart:     20
+                ISectStart:      0
+                Range:           45
+              Gaps:            
           - Kind:            S_PROC_ID_END
-            ScopeEndSym:
+            ScopeEndSym:     
       - !Lines
         CodeSize:        65
         Flags:           [  ]
         RelocOffset:     0
         RelocSegment:    0
-        Blocks:
+        Blocks:          
           - FileName:        'D:\src\llvmbuild\clang\Debug\x86\obj1.cpp'
-            Lines:
+            Lines:           
               - Offset:          0
                 LineStart:       3
                 IsStatement:     false
                 EndDelta:        0
-              - Offset:          23
+              - Offset:          20
                 LineStart:       4
                 IsStatement:     false
                 EndDelta:        0
-              - Offset:          48
+              - Offset:          45
                 LineStart:       5
                 IsStatement:     false
                 EndDelta:        0
-            Columns:
+            Columns:         
       - !Symbols
-        Records:
+        Records:         
           - Kind:            S_UDT
-            UDTSym:
+            UDTSym:          
               Type:            4105
               UDTName:         'NS::Foo'
       - !FileChecksums
-        Checksums:
+        Checksums:       
           - FileName:        'D:\src\llvmbuild\clang\Debug\x86\obj1.cpp'
             Kind:            MD5
             Checksum:        65C9E387F88362A8EB2B49539DD5A655
           - FileName:        'D:\src\llvmbuild\clang\Debug\x86\obj.h'
             Kind:            MD5
-            Checksum:        9303CF100D518DAF59C31DA01FEF4AFC
+            Checksum:        D3AE9D06B0C1F06ABE75A0557053ED6B
       - !StringTable
-        Strings:
+        Strings:         
           - 'D:\src\llvmbuild\clang\Debug\x86\obj1.cpp'
           - 'D:\src\llvmbuild\clang\Debug\x86\obj.h'
           - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = '
           - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
           - '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
           - '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $esi $T0 8 - ^ = '
-    Relocations:
+    Relocations:     
       - VirtualAddress:  68
         SymbolName:      _main
         Type:            IMAGE_REL_I386_DIR32NB
@@ -192,28 +222,28 @@
     Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
     Alignment:       4
     SectionData:     040000000A000210700400000A8000000E0001120200000074000000001000000E0008107400000000000200011000001200011600000000021000006D61696E00F3F2F12A0005150000800200000000000000000000000000004E533A3A466F6F002E3F4155466F6F404E53404000F10A000210041000000A8000000A00011201000000740000001A0009100300000004100000051000000B00010006100000000000001A0003120D15030074000000000058001115030007100000466F6F002A0005150200000208100000000000000000000004004E533A3A466F6F002E3F4155466F6F404E53404000F12E00051600000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800F10E000616091000000A100000020000000E0002160410000007100000466F6F00
-    Types:
+    Types:           
       - Kind:            LF_POINTER
-        Pointer:
+        Pointer:         
           ReferentType:    1136
           Attrs:           32778
       - Kind:            LF_ARGLIST
-        ArgList:
+        ArgList:         
           ArgIndices:      [ 116, 4096 ]
       - Kind:            LF_PROCEDURE
-        Procedure:
+        Procedure:       
           ReturnType:      116
           CallConv:        NearC
           Options:         [ None ]
           ParameterCount:  2
           ArgumentList:    4097
       - Kind:            LF_FUNC_ID
-        FuncId:
+        FuncId:          
           ParentScope:     0
           FunctionType:    4098
           Name:            main
       - Kind:            LF_STRUCTURE
-        Class:
+        Class:           
           MemberCount:     0
           Options:         [ None, ForwardReference, HasUniqueName ]
           FieldList:       0
@@ -223,14 +253,14 @@
           VTableShape:     0
           Size:            0
       - Kind:            LF_POINTER
-        Pointer:
+        Pointer:         
           ReferentType:    4100
           Attrs:           32778
       - Kind:            LF_ARGLIST
-        ArgList:
+        ArgList:         
           ArgIndices:      [ 116 ]
       - Kind:            LF_MFUNCTION
-        MemberFunction:
+        MemberFunction:  
           ReturnType:      3
           ClassType:       4100
           ThisType:        4101
@@ -240,21 +270,21 @@
           ArgumentList:    4102
           ThisPointerAdjustment: 0
       - Kind:            LF_FIELDLIST
-        FieldList:
+        FieldList:       
           - Kind:            LF_MEMBER
-            DataMember:
+            DataMember:      
               Attrs:           3
               Type:            116
               FieldOffset:     0
               Name:            X
           - Kind:            LF_ONEMETHOD
-            OneMethod:
+            OneMethod:       
               Type:            4103
               Attrs:           3
               VFTableOffset:   -1
               Name:            Foo
       - Kind:            LF_STRUCTURE
-        Class:
+        Class:           
           MemberCount:     2
           Options:         [ None, HasUniqueName ]
           FieldList:       4104
@@ -264,47 +294,47 @@
           VTableShape:     0
           Size:            4
       - Kind:            LF_STRING_ID
-        StringId:
+        StringId:        
           Id:              0
           String:          'D:\src\llvmbuild\clang\Debug\x86\obj.h'
       - Kind:            LF_UDT_SRC_LINE
-        UdtSourceLine:
+        UdtSourceLine:   
           UDT:             4105
           SourceFile:      4106
           LineNumber:      2
       - Kind:            LF_MFUNC_ID
-        MemberFuncId:
+        MemberFuncId:    
           ClassType:       4100
           FunctionType:    4103
           Name:            Foo
   - Name:            '.debug$H'
     Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
     Alignment:       4
-    SectionData:     C5C93301000000009E56666824DC4B12E25261D4E09E6E9DA0F4EE31FDEC3D2D96287486127C66070B248ED52E421F55074AE5CC2D68AF9F0A3BEF23993968F7FD82CA84BF0439C1A64C9070C6A6ADB0A34D21DAD0FFC3E99E616EF06A14EA74A2420F9062A1FB04917E5975E3A50EABE5E8FE3945468547C19DC681D0BFB3B797DD91CA4D7F1953C314442D5549419E78044E38A0BF16BFFAA5EE9C0103E7DBFE9941E63379C0B0C0A9021B711ACC4F67008974EBF441031BDD653F6935DFF3112C6A5346EF2AC94B9B7EB56EF55CFA0AF6C1846743F43D846BB19517E12E8873BBA90CC41DD1BEAC89CBA8897AC1BA46762E2557A82D894CEAE81AEF8680D723D403D9A4481F0E28683A98
-    GlobalHashes:
+    SectionData:     C5C9330100000100800309EE1ED8BB5B5397319F1CC14E2CDF04AA3125BBC50E95CEBA304A2C449323ADA4E788EB7A90B5DECADF1A832BA46632585CDC7606E4B97B86241E5F45B0BCD2406E22465E11A528BEF0A7F589C76079F1186C40C2165091EFEBD5B5446B26FFBFD620CFB362
+    GlobalHashes:    
       Version:         0
-      HashAlgorithm:   0
-      HashValues:
-        - 9E56666824DC4B12E25261D4E09E6E9DA0F4EE31
-        - FDEC3D2D96287486127C66070B248ED52E421F55
-        - 074AE5CC2D68AF9F0A3BEF23993968F7FD82CA84
-        - BF0439C1A64C9070C6A6ADB0A34D21DAD0FFC3E9
-        - 9E616EF06A14EA74A2420F9062A1FB04917E5975
-        - E3A50EABE5E8FE3945468547C19DC681D0BFB3B7
-        - 97DD91CA4D7F1953C314442D5549419E78044E38
-        - A0BF16BFFAA5EE9C0103E7DBFE9941E63379C0B0
-        - C0A9021B711ACC4F67008974EBF441031BDD653F
-        - 6935DFF3112C6A5346EF2AC94B9B7EB56EF55CFA
-        - 0AF6C1846743F43D846BB19517E12E8873BBA90C
-        - C41DD1BEAC89CBA8897AC1BA46762E2557A82D89
-        - 4CEAE81AEF8680D723D403D9A4481F0E28683A98
+      HashAlgorithm:   1
+      HashValues:      
+        - 800309EE1ED8BB5B
+        - 5397319F1CC14E2C
+        - DF04AA3125BBC50E
+        - 95CEBA304A2C4493
+        - 23ADA4E788EB7A90
+        - B5DECADF1A832BA4
+        - 6632585CDC7606E4
+        - B97B86241E5F45B0
+        - BCD2406E22465E11
+        - A528BEF0A7F589C7
+        - 6079F1186C40C216
+        - 5091EFEBD5B5446B
+        - 26FFBFD620CFB362
   - Name:            '.debug$S'
     Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
     Alignment:       4
     SectionData:     04000000F500000064000000000000000000000020000000000000000400000000000000520000000600000004000000010000001F0000000000000004000000000000007F0000000500040000000000030000001D000000000000000400000000000000BD0000000300040000000000F10000007B000000320047110000000000000000000000002000000000000000000000000C100000000000000000004E533A3A466F6F3A3A466F6F000D003E1105100000010074686973001200451116000000FCFFFFFF0F000000000011000A003E1174000000010078001200451116000000080000000F0000000000110002004F1100F2000000200000000000000000000000200000001800000001000000140000000000000003000000
-    Subsections:
+    Subsections:     
       - !FrameData
-        Frames:
+        Frames:          
           - CodeSize:        32
             FrameFunc:       '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = '
             LocalSize:       0
@@ -330,9 +360,9 @@
             RvaStart:        3
             SavedRegsSize:   4
       - !Symbols
-        Records:
+        Records:         
           - Kind:            S_GPROC32_ID
-            ProcSym:
+            ProcSym:         
               CodeSize:        32
               DbgStart:        0
               DbgEnd:          0
@@ -340,31 +370,51 @@
               Flags:           [  ]
               DisplayName:     'NS::Foo::Foo'
           - Kind:            S_LOCAL
-            LocalSym:
+            LocalSym:        
               Type:            4101
               Flags:           [ IsParameter ]
               VarName:         this
+          - Kind:            S_DEFRANGE_REGISTER_REL
+            DefRangeRegisterRelSym: 
+              Register:        22
+              Flags:           0
+              BasePointerOffset: -4
+              Range:           
+                OffsetStart:     15
+                ISectStart:      0
+                Range:           17
+              Gaps:            
           - Kind:            S_LOCAL
-            LocalSym:
+            LocalSym:        
               Type:            116
               Flags:           [ IsParameter ]
               VarName:         x
+          - Kind:            S_DEFRANGE_REGISTER_REL
+            DefRangeRegisterRelSym: 
+              Register:        22
+              Flags:           0
+              BasePointerOffset: 8
+              Range:           
+                OffsetStart:     15
+                ISectStart:      0
+                Range:           17
+              Gaps:            
           - Kind:            S_PROC_ID_END
-            ScopeEndSym:
+            ScopeEndSym:     
       - !Lines
         CodeSize:        32
         Flags:           [  ]
         RelocOffset:     0
         RelocSegment:    0
-        Blocks:
+        Blocks:          
           - FileName:        'D:\src\llvmbuild\clang\Debug\x86\obj.h'
-            Lines:
+            Lines:           
               - Offset:          0
                 LineStart:       3
                 IsStatement:     false
                 EndDelta:        0
-            Columns:
-    Relocations:
+            Columns:         
+    Relocations:     
       - VirtualAddress:  12
         SymbolName:      '??0Foo@NS@@QAE@H@Z'
         Type:            IMAGE_REL_I386_DIR32NB
@@ -392,18 +442,18 @@
       - VirtualAddress:  256
         SymbolName:      '??0Foo@NS@@QAE@H@Z'
         Type:            IMAGE_REL_I386_SECTION
-symbols:
+symbols:         
   - Name:            .text
     Value:           0
     SectionNumber:   1
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
+    SectionDefinition: 
       Length:          65
       NumberOfRelocations: 2
       NumberOfLinenumbers: 0
-      CheckSum:        4176946275
+      CheckSum:        1827148029
       Number:          1
   - Name:            .data
     Value:           0
@@ -411,7 +461,7 @@
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
+    SectionDefinition: 
       Length:          0
       NumberOfRelocations: 0
       NumberOfLinenumbers: 0
@@ -423,7 +473,7 @@
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
+    SectionDefinition: 
       Length:          0
       NumberOfRelocations: 0
       NumberOfLinenumbers: 0
@@ -435,7 +485,7 @@
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
+    SectionDefinition: 
       Length:          32
       NumberOfRelocations: 0
       NumberOfLinenumbers: 0
@@ -454,7 +504,7 @@
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
+    SectionDefinition: 
       Length:          48
       NumberOfRelocations: 0
       NumberOfLinenumbers: 0
@@ -466,11 +516,11 @@
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
+    SectionDefinition: 
       Length:          832
       NumberOfRelocations: 11
       NumberOfLinenumbers: 0
-      CheckSum:        4106171226
+      CheckSum:        372945565
       Number:          6
   - Name:            '.debug$S'
     Value:           0
@@ -478,7 +528,7 @@
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
+    SectionDefinition: 
       Length:          284
       NumberOfRelocations: 9
       NumberOfLinenumbers: 0
@@ -491,7 +541,7 @@
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
+    SectionDefinition: 
       Length:          316
       NumberOfRelocations: 0
       NumberOfLinenumbers: 0
@@ -503,11 +553,11 @@
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
-      Length:          268
+    SectionDefinition: 
+      Length:          112
       NumberOfRelocations: 0
       NumberOfLinenumbers: 0
-      CheckSum:        3965031229
+      CheckSum:        1535721080
       Number:          8
   - Name:            '@feat.00'
     Value:           1
diff --git a/test/COFF/Inputs/pdb-hashes-2-missing.yaml b/test/COFF/Inputs/pdb-hashes-2-missing.yaml
index 5b94d7f..41cba50 100644
--- a/test/COFF/Inputs/pdb-hashes-2-missing.yaml
+++ b/test/COFF/Inputs/pdb-hashes-2-missing.yaml
@@ -1,8 +1,8 @@
 --- !COFF
-header:
+header:          
   Machine:         IMAGE_FILE_MACHINE_I386
   Characteristics: [  ]
-sections:
+sections:        
   - Name:            .text
     Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
     Alignment:       16
@@ -22,25 +22,25 @@
   - Name:            '.debug$S'
     Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
     Alignment:       4
-    SectionData:     04000000F10000002F0000002D003C1101000000070006000000000000007017000000000000636C616E672076657273696F6E20362E302E30200000F5000000640000000000000000000000190000000000000004000000000000002B000000040000000400000001000000180000000000000004000000000000005800000003000400000000000300000016000000000000000400000000000000960000000100040000000000F1000000540000002E0047110000000000000000000000001900000000000000000000000D100000000000000000004E533A3A66756E63000A003E110310000001006600120045111600000008000000070000000000120002004F11F20000002800000000000000000000001900000000000000020000001C00000000000000030000000700000004000000F1000000100000000E0008110A1000004E533A3A466F6F00F40000001800000001000000100159DFAC75D18675AED1AD169FE316317E0000F3000000D400000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A322E63707000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200000
-    Subsections:
+    SectionData:     04000000F10000002F0000002D003C110100000007000700000000000000581B000000000000636C616E672076657273696F6E20372E302E30200000F5000000640000000000000000000000190000000000000004000000000000002B000000040000000400000001000000180000000000000004000000000000005800000003000400000000000300000016000000000000000400000000000000960000000100040000000000F1000000540000002E0047110000000000000000000000001900000000000000000000000D100000000000000000004E533A3A66756E63000A003E110310000001006600120045111600000008000000070000000000120002004F11F20000002800000000000000000000001900000000000000020000001C00000000000000030000000700000004000000F1000000100000000E0008110A1000004E533A3A466F6F00F40000001800000001000000100159DFAC75D18675AED1AD169FE316317E0000F3000000D400000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A322E63707000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200000
+    Subsections:     
       - !Symbols
-        Records:
+        Records:         
           - Kind:            S_COMPILE3
-            Compile3Sym:
+            Compile3Sym:     
               Flags:           [  ]
               Machine:         Pentium3
-              FrontendMajor:   6
+              FrontendMajor:   7
               FrontendMinor:   0
               FrontendBuild:   0
               FrontendQFE:     0
-              BackendMajor:    6000
+              BackendMajor:    7000
               BackendMinor:    0
               BackendBuild:    0
               BackendQFE:      0
-              Version:         'clang version 6.0.0 '
+              Version:         'clang version 7.0.0 '
       - !FrameData
-        Frames:
+        Frames:          
           - CodeSize:        25
             FrameFunc:       '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = '
             LocalSize:       0
@@ -66,9 +66,9 @@
             RvaStart:        3
             SavedRegsSize:   4
       - !Symbols
-        Records:
+        Records:         
           - Kind:            S_GPROC32_ID
-            ProcSym:
+            ProcSym:         
               CodeSize:        25
               DbgStart:        0
               DbgEnd:          0
@@ -76,20 +76,30 @@
               Flags:           [  ]
               DisplayName:     'NS::func'
           - Kind:            S_LOCAL
-            LocalSym:
+            LocalSym:        
               Type:            4099
               Flags:           [ IsParameter ]
               VarName:         f
+          - Kind:            S_DEFRANGE_REGISTER_REL
+            DefRangeRegisterRelSym: 
+              Register:        22
+              Flags:           0
+              BasePointerOffset: 8
+              Range:           
+                OffsetStart:     7
+                ISectStart:      0
+                Range:           18
+              Gaps:            
           - Kind:            S_PROC_ID_END
-            ScopeEndSym:
+            ScopeEndSym:     
       - !Lines
         CodeSize:        25
         Flags:           [  ]
         RelocOffset:     0
         RelocSegment:    0
-        Blocks:
+        Blocks:          
           - FileName:        'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp'
-            Lines:
+            Lines:           
               - Offset:          0
                 LineStart:       3
                 IsStatement:     false
@@ -98,26 +108,26 @@
                 LineStart:       4
                 IsStatement:     false
                 EndDelta:        0
-            Columns:
+            Columns:         
       - !Symbols
-        Records:
+        Records:         
           - Kind:            S_UDT
-            UDTSym:
+            UDTSym:          
               Type:            4106
               UDTName:         'NS::Foo'
       - !FileChecksums
-        Checksums:
+        Checksums:       
           - FileName:        'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp'
             Kind:            MD5
             Checksum:        59DFAC75D18675AED1AD169FE316317E
       - !StringTable
-        Strings:
+        Strings:         
           - 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp'
           - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = '
           - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
           - '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
           - ''
-    Relocations:
+    Relocations:     
       - VirtualAddress:  68
         SymbolName:      '?func@NS@@YAHABUFoo@1@@Z'
         Type:            IMAGE_REL_I386_DIR32NB
@@ -143,13 +153,13 @@
     Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
     Alignment:       4
     SectionData:     040000000A000516000000004E5300F12A0005150000800200000000000000000000000000004E533A3A466F6F002E3F4155466F6F404E53404000F10A000110011000000100F2F10A000210021000002A8000000A00011201000000031000000E0008107400000000000100041000000A000210011000000A8000000A00011201000000740000001A0009100300000001100000061000000B00010007100000000000001A0003120D15030074000000000058001115030008100000466F6F002A0005150200000209100000000000000000000004004E533A3A466F6F002E3F4155466F6F404E53404000F12E00051600000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800F10E0006160A1000000B1000000200000012000116001000000510000066756E6300F3F2F1
-    Types:
+    Types:           
       - Kind:            LF_STRING_ID
-        StringId:
+        StringId:        
           Id:              0
           String:          NS
       - Kind:            LF_STRUCTURE
-        Class:
+        Class:           
           MemberCount:     0
           Options:         [ None, ForwardReference, HasUniqueName ]
           FieldList:       0
@@ -159,32 +169,32 @@
           VTableShape:     0
           Size:            0
       - Kind:            LF_MODIFIER
-        Modifier:
+        Modifier:        
           ModifiedType:    4097
           Modifiers:       [ None, Const ]
       - Kind:            LF_POINTER
-        Pointer:
+        Pointer:         
           ReferentType:    4098
           Attrs:           32810
       - Kind:            LF_ARGLIST
-        ArgList:
+        ArgList:         
           ArgIndices:      [ 4099 ]
       - Kind:            LF_PROCEDURE
-        Procedure:
+        Procedure:       
           ReturnType:      116
           CallConv:        NearC
           Options:         [ None ]
           ParameterCount:  1
           ArgumentList:    4100
       - Kind:            LF_POINTER
-        Pointer:
+        Pointer:         
           ReferentType:    4097
           Attrs:           32778
       - Kind:            LF_ARGLIST
-        ArgList:
+        ArgList:         
           ArgIndices:      [ 116 ]
       - Kind:            LF_MFUNCTION
-        MemberFunction:
+        MemberFunction:  
           ReturnType:      3
           ClassType:       4097
           ThisType:        4102
@@ -194,21 +204,21 @@
           ArgumentList:    4103
           ThisPointerAdjustment: 0
       - Kind:            LF_FIELDLIST
-        FieldList:
+        FieldList:       
           - Kind:            LF_MEMBER
-            DataMember:
+            DataMember:      
               Attrs:           3
               Type:            116
               FieldOffset:     0
               Name:            X
           - Kind:            LF_ONEMETHOD
-            OneMethod:
+            OneMethod:       
               Type:            4104
               Attrs:           3
               VFTableOffset:   -1
               Name:            Foo
       - Kind:            LF_STRUCTURE
-        Class:
+        Class:           
           MemberCount:     2
           Options:         [ None, HasUniqueName ]
           FieldList:       4105
@@ -218,27 +228,27 @@
           VTableShape:     0
           Size:            4
       - Kind:            LF_STRING_ID
-        StringId:
+        StringId:        
           Id:              0
           String:          'D:\src\llvmbuild\clang\Debug\x86\obj.h'
       - Kind:            LF_UDT_SRC_LINE
-        UdtSourceLine:
+        UdtSourceLine:   
           UDT:             4106
           SourceFile:      4107
           LineNumber:      2
       - Kind:            LF_FUNC_ID
-        FuncId:
+        FuncId:          
           ParentScope:     4096
           FunctionType:    4101
           Name:            func
-symbols:
+symbols:         
   - Name:            .text
     Value:           0
     SectionNumber:   1
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
+    SectionDefinition: 
       Length:          25
       NumberOfRelocations: 0
       NumberOfLinenumbers: 0
@@ -250,7 +260,7 @@
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
+    SectionDefinition: 
       Length:          0
       NumberOfRelocations: 0
       NumberOfLinenumbers: 0
@@ -262,7 +272,7 @@
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
+    SectionDefinition: 
       Length:          0
       NumberOfRelocations: 0
       NumberOfLinenumbers: 0
@@ -274,7 +284,7 @@
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
+    SectionDefinition: 
       Length:          48
       NumberOfRelocations: 0
       NumberOfLinenumbers: 0
@@ -286,11 +296,11 @@
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
+    SectionDefinition: 
       Length:          584
       NumberOfRelocations: 7
       NumberOfLinenumbers: 0
-      CheckSum:        2847177244
+      CheckSum:        917356735
       Number:          5
   - Name:            '.debug$T'
     Value:           0
@@ -298,7 +308,7 @@
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
+    SectionDefinition: 
       Length:          320
       NumberOfRelocations: 0
       NumberOfLinenumbers: 0
diff --git a/test/COFF/Inputs/pdb-hashes-2.yaml b/test/COFF/Inputs/pdb-hashes-2.yaml
index 46676c4..51ea512 100644
--- a/test/COFF/Inputs/pdb-hashes-2.yaml
+++ b/test/COFF/Inputs/pdb-hashes-2.yaml
@@ -1,8 +1,8 @@
 --- !COFF
-header:
+header:          
   Machine:         IMAGE_FILE_MACHINE_I386
   Characteristics: [  ]
-sections:
+sections:        
   - Name:            .text
     Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
     Alignment:       16
@@ -22,25 +22,25 @@
   - Name:            '.debug$S'
     Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
     Alignment:       4
-    SectionData:     04000000F10000002F0000002D003C1101000000070006000000000000007017000000000000636C616E672076657273696F6E20362E302E30200000F5000000640000000000000000000000190000000000000004000000000000002B000000040000000400000001000000180000000000000004000000000000005800000003000400000000000300000016000000000000000400000000000000960000000100040000000000F1000000540000002E0047110000000000000000000000001900000000000000000000000D100000000000000000004E533A3A66756E63000A003E110310000001006600120045111600000008000000070000000000120002004F11F20000002800000000000000000000001900000000000000020000001C00000000000000030000000700000004000000F1000000100000000E0008110A1000004E533A3A466F6F00F40000001800000001000000100159DFAC75D18675AED1AD169FE316317E0000F3000000D400000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A322E63707000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200000
-    Subsections:
+    SectionData:     04000000F10000002F0000002D003C110100000007000700000000000000581B000000000000636C616E672076657273696F6E20372E302E30200000F5000000640000000000000000000000190000000000000004000000000000002B000000040000000400000001000000180000000000000004000000000000005800000003000400000000000300000016000000000000000400000000000000960000000100040000000000F1000000540000002E0047110000000000000000000000001900000000000000000000000D100000000000000000004E533A3A66756E63000A003E110310000001006600120045111600000008000000070000000000120002004F11F20000002800000000000000000000001900000000000000020000001C00000000000000030000000700000004000000F1000000100000000E0008110A1000004E533A3A466F6F00F40000001800000001000000100159DFAC75D18675AED1AD169FE316317E0000F3000000D400000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A322E63707000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200000
+    Subsections:     
       - !Symbols
-        Records:
+        Records:         
           - Kind:            S_COMPILE3
-            Compile3Sym:
+            Compile3Sym:     
               Flags:           [  ]
               Machine:         Pentium3
-              FrontendMajor:   6
+              FrontendMajor:   7
               FrontendMinor:   0
               FrontendBuild:   0
               FrontendQFE:     0
-              BackendMajor:    6000
+              BackendMajor:    7000
               BackendMinor:    0
               BackendBuild:    0
               BackendQFE:      0
-              Version:         'clang version 6.0.0 '
+              Version:         'clang version 7.0.0 '
       - !FrameData
-        Frames:
+        Frames:          
           - CodeSize:        25
             FrameFunc:       '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = '
             LocalSize:       0
@@ -66,9 +66,9 @@
             RvaStart:        3
             SavedRegsSize:   4
       - !Symbols
-        Records:
+        Records:         
           - Kind:            S_GPROC32_ID
-            ProcSym:
+            ProcSym:         
               CodeSize:        25
               DbgStart:        0
               DbgEnd:          0
@@ -76,20 +76,30 @@
               Flags:           [  ]
               DisplayName:     'NS::func'
           - Kind:            S_LOCAL
-            LocalSym:
+            LocalSym:        
               Type:            4099
               Flags:           [ IsParameter ]
               VarName:         f
+          - Kind:            S_DEFRANGE_REGISTER_REL
+            DefRangeRegisterRelSym: 
+              Register:        22
+              Flags:           0
+              BasePointerOffset: 8
+              Range:           
+                OffsetStart:     7
+                ISectStart:      0
+                Range:           18
+              Gaps:            
           - Kind:            S_PROC_ID_END
-            ScopeEndSym:
+            ScopeEndSym:     
       - !Lines
         CodeSize:        25
         Flags:           [  ]
         RelocOffset:     0
         RelocSegment:    0
-        Blocks:
+        Blocks:          
           - FileName:        'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp'
-            Lines:
+            Lines:           
               - Offset:          0
                 LineStart:       3
                 IsStatement:     false
@@ -98,26 +108,26 @@
                 LineStart:       4
                 IsStatement:     false
                 EndDelta:        0
-            Columns:
+            Columns:         
       - !Symbols
-        Records:
+        Records:         
           - Kind:            S_UDT
-            UDTSym:
+            UDTSym:          
               Type:            4106
               UDTName:         'NS::Foo'
       - !FileChecksums
-        Checksums:
+        Checksums:       
           - FileName:        'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp'
             Kind:            MD5
             Checksum:        59DFAC75D18675AED1AD169FE316317E
       - !StringTable
-        Strings:
+        Strings:         
           - 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp'
           - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = '
           - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
           - '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
           - ''
-    Relocations:
+    Relocations:     
       - VirtualAddress:  68
         SymbolName:      '?func@NS@@YAHABUFoo@1@@Z'
         Type:            IMAGE_REL_I386_DIR32NB
@@ -143,13 +153,13 @@
     Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
     Alignment:       4
     SectionData:     040000000A000516000000004E5300F12A0005150000800200000000000000000000000000004E533A3A466F6F002E3F4155466F6F404E53404000F10A000110011000000100F2F10A000210021000002A8000000A00011201000000031000000E0008107400000000000100041000000A000210011000000A8000000A00011201000000740000001A0009100300000001100000061000000B00010007100000000000001A0003120D15030074000000000058001115030008100000466F6F002A0005150200000209100000000000000000000004004E533A3A466F6F002E3F4155466F6F404E53404000F12E00051600000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800F10E0006160A1000000B1000000200000012000116001000000510000066756E6300F3F2F1
-    Types:
+    Types:           
       - Kind:            LF_STRING_ID
-        StringId:
+        StringId:        
           Id:              0
           String:          NS
       - Kind:            LF_STRUCTURE
-        Class:
+        Class:           
           MemberCount:     0
           Options:         [ None, ForwardReference, HasUniqueName ]
           FieldList:       0
@@ -159,32 +169,32 @@
           VTableShape:     0
           Size:            0
       - Kind:            LF_MODIFIER
-        Modifier:
+        Modifier:        
           ModifiedType:    4097
           Modifiers:       [ None, Const ]
       - Kind:            LF_POINTER
-        Pointer:
+        Pointer:         
           ReferentType:    4098
           Attrs:           32810
       - Kind:            LF_ARGLIST
-        ArgList:
+        ArgList:         
           ArgIndices:      [ 4099 ]
       - Kind:            LF_PROCEDURE
-        Procedure:
+        Procedure:       
           ReturnType:      116
           CallConv:        NearC
           Options:         [ None ]
           ParameterCount:  1
           ArgumentList:    4100
       - Kind:            LF_POINTER
-        Pointer:
+        Pointer:         
           ReferentType:    4097
           Attrs:           32778
       - Kind:            LF_ARGLIST
-        ArgList:
+        ArgList:         
           ArgIndices:      [ 116 ]
       - Kind:            LF_MFUNCTION
-        MemberFunction:
+        MemberFunction:  
           ReturnType:      3
           ClassType:       4097
           ThisType:        4102
@@ -194,21 +204,21 @@
           ArgumentList:    4103
           ThisPointerAdjustment: 0
       - Kind:            LF_FIELDLIST
-        FieldList:
+        FieldList:       
           - Kind:            LF_MEMBER
-            DataMember:
+            DataMember:      
               Attrs:           3
               Type:            116
               FieldOffset:     0
               Name:            X
           - Kind:            LF_ONEMETHOD
-            OneMethod:
+            OneMethod:       
               Type:            4104
               Attrs:           3
               VFTableOffset:   -1
               Name:            Foo
       - Kind:            LF_STRUCTURE
-        Class:
+        Class:           
           MemberCount:     2
           Options:         [ None, HasUniqueName ]
           FieldList:       4105
@@ -218,49 +228,49 @@
           VTableShape:     0
           Size:            4
       - Kind:            LF_STRING_ID
-        StringId:
+        StringId:        
           Id:              0
           String:          'D:\src\llvmbuild\clang\Debug\x86\obj.h'
       - Kind:            LF_UDT_SRC_LINE
-        UdtSourceLine:
+        UdtSourceLine:   
           UDT:             4106
           SourceFile:      4107
           LineNumber:      2
       - Kind:            LF_FUNC_ID
-        FuncId:
+        FuncId:          
           ParentScope:     4096
           FunctionType:    4101
           Name:            func
   - Name:            '.debug$H'
     Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
     Alignment:       4
-    SectionData:     C5C9330100000000EC145CD76AEFE74E78880D531132B3BB8FFACEF79E616EF06A14EA74A2420F9062A1FB04917E59759949E334BA18509ED692F3C65CE242D8450EBC78B81B63AF8316DC324562EB9F0D4A0D708E8A25C263DB05943C19B84A36719E1E414DDA3EDBDF005322238D70F9058EEDC5C50EF11BC849618B51FD89E3A50EABE5E8FE3945468547C19DC681D0BFB3B797DD91CA4D7F1953C314442D5549419E78044E38A0BF16BFFAA5EE9C0103E7DBFE9941E63379C0B0C0A9021B711ACC4F67008974EBF441031BDD653F6935DFF3112C6A5346EF2AC94B9B7EB56EF55CFA0AF6C1846743F43D846BB19517E12E8873BBA90CC41DD1BEAC89CBA8897AC1BA46762E2557A82D89DCBC783AF285D9DBB672F67A81E36906B2038B57
-    GlobalHashes:
+    SectionData:     C5C93301000001004A061540B751965F23ADA4E788EB7A9032673B3BABE3CA5356B1521BDAE4BEA70661C95750D0206E896FB09488EE8E1BB5DECADF1A832BA46632585CDC7606E4B97B86241E5F45B0BCD2406E22465E11A528BEF0A7F589C76079F1186C40C2165091EFEBD5B5446B5AAD8721C21DF3E6
+    GlobalHashes:    
       Version:         0
-      HashAlgorithm:   0
-      HashValues:
-        - EC145CD76AEFE74E78880D531132B3BB8FFACEF7
-        - 9E616EF06A14EA74A2420F9062A1FB04917E5975
-        - 9949E334BA18509ED692F3C65CE242D8450EBC78
-        - B81B63AF8316DC324562EB9F0D4A0D708E8A25C2
-        - 63DB05943C19B84A36719E1E414DDA3EDBDF0053
-        - 22238D70F9058EEDC5C50EF11BC849618B51FD89
-        - E3A50EABE5E8FE3945468547C19DC681D0BFB3B7
-        - 97DD91CA4D7F1953C314442D5549419E78044E38
-        - A0BF16BFFAA5EE9C0103E7DBFE9941E63379C0B0
-        - C0A9021B711ACC4F67008974EBF441031BDD653F
-        - 6935DFF3112C6A5346EF2AC94B9B7EB56EF55CFA
-        - 0AF6C1846743F43D846BB19517E12E8873BBA90C
-        - C41DD1BEAC89CBA8897AC1BA46762E2557A82D89
-        - DCBC783AF285D9DBB672F67A81E36906B2038B57
-symbols:
+      HashAlgorithm:   1
+      HashValues:      
+        - 4A061540B751965F
+        - 23ADA4E788EB7A90
+        - 32673B3BABE3CA53
+        - 56B1521BDAE4BEA7
+        - 0661C95750D0206E
+        - 896FB09488EE8E1B
+        - B5DECADF1A832BA4
+        - 6632585CDC7606E4
+        - B97B86241E5F45B0
+        - BCD2406E22465E11
+        - A528BEF0A7F589C7
+        - 6079F1186C40C216
+        - 5091EFEBD5B5446B
+        - 5AAD8721C21DF3E6
+symbols:         
   - Name:            .text
     Value:           0
     SectionNumber:   1
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
+    SectionDefinition: 
       Length:          25
       NumberOfRelocations: 0
       NumberOfLinenumbers: 0
@@ -272,7 +282,7 @@
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
+    SectionDefinition: 
       Length:          0
       NumberOfRelocations: 0
       NumberOfLinenumbers: 0
@@ -284,7 +294,7 @@
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
+    SectionDefinition: 
       Length:          0
       NumberOfRelocations: 0
       NumberOfLinenumbers: 0
@@ -296,7 +306,7 @@
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
+    SectionDefinition: 
       Length:          48
       NumberOfRelocations: 0
       NumberOfLinenumbers: 0
@@ -308,11 +318,11 @@
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
+    SectionDefinition: 
       Length:          584
       NumberOfRelocations: 7
       NumberOfLinenumbers: 0
-      CheckSum:        2847177244
+      CheckSum:        917356735
       Number:          5
   - Name:            '.debug$T'
     Value:           0
@@ -320,7 +330,7 @@
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
+    SectionDefinition: 
       Length:          320
       NumberOfRelocations: 0
       NumberOfLinenumbers: 0
@@ -332,11 +342,11 @@
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
-      Length:          288
+    SectionDefinition: 
+      Length:          120
       NumberOfRelocations: 0
       NumberOfLinenumbers: 0
-      CheckSum:        2348181452
+      CheckSum:        358820662
       Number:          7
   - Name:            '@feat.00'
     Value:           1
diff --git a/test/COFF/Inputs/pdb-scopes-a.yaml b/test/COFF/Inputs/pdb-scopes-a.yaml
index e422a62..0fc4172 100644
--- a/test/COFF/Inputs/pdb-scopes-a.yaml
+++ b/test/COFF/Inputs/pdb-scopes-a.yaml
@@ -53,7 +53,7 @@
             RegRelativeSym:
               Offset:          8
               Type:            116
-              Register:        RSP
+              Register:        CVRegRSP
               VarName:         x
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
@@ -93,7 +93,7 @@
             RegRelativeSym:
               Offset:          64
               Type:            116
-              Register:        RSP
+              Register:        CVRegRSP
               VarName:         argc
           - Kind:            S_BLOCK32
             BlockSym:
@@ -104,7 +104,7 @@
             RegRelativeSym:
               Offset:          32
               Type:            116
-              Register:        RSP
+              Register:        CVRegRSP
               VarName:         x
           - Kind:            S_END
             ScopeEndSym:
@@ -117,7 +117,7 @@
             RegRelativeSym:
               Offset:          36
               Type:            116
-              Register:        RSP
+              Register:        CVRegRSP
               VarName:         y
           - Kind:            S_END
             ScopeEndSym:
diff --git a/test/COFF/Inputs/pdb-scopes-b.yaml b/test/COFF/Inputs/pdb-scopes-b.yaml
index b1c6021..c0ee98b 100644
--- a/test/COFF/Inputs/pdb-scopes-b.yaml
+++ b/test/COFF/Inputs/pdb-scopes-b.yaml
@@ -53,7 +53,7 @@
             RegRelativeSym:
               Offset:          64
               Type:            116
-              Register:        RSP
+              Register:        CVRegRSP
               VarName:         x
           - Kind:            S_BLOCK32
             BlockSym:
@@ -64,7 +64,7 @@
             RegRelativeSym:
               Offset:          32
               Type:            116
-              Register:        RSP
+              Register:        CVRegRSP
               VarName:         y
           - Kind:            S_END
             ScopeEndSym:
@@ -77,7 +77,7 @@
             RegRelativeSym:
               Offset:          36
               Type:            116
-              Register:        RSP
+              Register:        CVRegRSP
               VarName:         w
           - Kind:            S_END
             ScopeEndSym:
diff --git a/test/COFF/Inputs/pdb-type-server-simple-a.yaml b/test/COFF/Inputs/pdb-type-server-simple-a.yaml
index 78c6816..8425c4f 100644
--- a/test/COFF/Inputs/pdb-type-server-simple-a.yaml
+++ b/test/COFF/Inputs/pdb-type-server-simple-a.yaml
@@ -53,7 +53,7 @@
             RegRelativeSym:
               Offset:          32
               Type:            4102
-              Register:        RSP
+              Register:        CVRegRSP
               VarName:         f
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
diff --git a/test/COFF/Inputs/pdb-type-server-simple-b.yaml b/test/COFF/Inputs/pdb-type-server-simple-b.yaml
index 56e97d5..3b511cb 100644
--- a/test/COFF/Inputs/pdb-type-server-simple-b.yaml
+++ b/test/COFF/Inputs/pdb-type-server-simple-b.yaml
@@ -53,7 +53,7 @@
             RegRelativeSym:
               Offset:          8
               Type:            4097
-              Register:        RSP
+              Register:        CVRegRSP
               VarName:         p
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
diff --git a/test/COFF/arm64-branch-range.test b/test/COFF/arm64-branch-range.test
new file mode 100644
index 0000000..0b581e9
--- /dev/null
+++ b/test/COFF/arm64-branch-range.test
@@ -0,0 +1,16 @@
+// 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 5680530..c7b8b7c 100644
--- a/test/COFF/arm64-relocs-imports.test
+++ b/test/COFF/arm64-relocs-imports.test
@@ -41,46 +41,54 @@
 # BEFORE:       80:       00 00 00 91     add     x0, x0, #0
 # BEFORE:       84:       00 00 40 91     add     x0, x0, #0, lsl #12
 # BEFORE:       88:       00 00 40 f9     ldr     x0, [x0]
+# BEFORE:       8c:       01 00 00 00     <unknown>
+# 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
 
 # AFTER: Disassembly of section .text:
-# AFTER:  140002000:      fe 0f 1f f8     str     x30, [sp, #-16]!
-# AFTER:  140002004:      e0 ff ff f0     adrp    x0, #-4096
-# AFTER:  140002008:      00 18 00 91     add     x0, x0, #6
-# AFTER:  14000200c:      20 00 00 94     bl      #128
-# AFTER:  140002010:      00 21 40 39     ldrb    w0, [x8, #8]
-# AFTER:  140002014:      00 11 40 79     ldrh    w0, [x8, #8]
-# AFTER:  140002018:      00 09 40 b9     ldr     w0, [x8, #8]
-# AFTER:  14000201c:      00 05 40 f9     ldr     x0, [x8, #8]
-# AFTER:  140002020:      00 21 00 39     strb    w0, [x8, #8]
-# AFTER:  140002024:      00 11 00 79     strh    w0, [x8, #8]
-# AFTER:  140002028:      00 09 00 b9     str     w0, [x8, #8]
-# AFTER:  14000202c:      00 05 00 f9     str     x0, [x8, #8]
-# AFTER:  140002030:      00 41 40 3d     ldr     b0, [x8, #16]
-# AFTER:  140002034:      00 21 40 7d     ldr     h0, [x8, #16]
-# AFTER:  140002038:      00 11 40 bd     ldr     s0, [x8, #16]
-# AFTER:  14000203c:      00 09 40 fd     ldr     d0, [x8, #16]
-# AFTER:  140002040:      00 05 c0 3d     ldr     q0, [x8, #16]
-# AFTER:  140002044:      00 41 00 3d     str     b0, [x8, #16]
-# AFTER:  140002048:      00 21 00 7d     str     h0, [x8, #16]
-# AFTER:  14000204c:      00 11 00 bd     str     s0, [x8, #16]
-# AFTER:  140002050:      00 09 00 fd     str     d0, [x8, #16]
-# AFTER:  140002054:      00 05 80 3d     str     q0, [x8, #16]
-# AFTER:  140002058:      00 09 40 f9     ldr     x0, [x8, #16]
-# AFTER:  14000205c:      00 00 00 b0     adrp    x0, #4096
-# AFTER:  140002060:      00 fc 47 f9     ldr     x0, [x0, #4088]
-# AFTER:  140002064:      e0 03 1f 2a     mov      w0, wzr
-# AFTER:  140002068:      fe 07 41 f8     ldr     x30, [sp], #16
-# AFTER:  14000206c:      c0 03 5f d6     ret
-# AFTER:  140002070:      10 10 00 40     <unknown>
-# AFTER:  140002074:      01 00 00 00     <unknown>
-# AFTER:  140002078:      09 10 00 00     <unknown>
-# AFTER:  14000207c:      09 00 00 00     <unknown>
-# AFTER:  140002080:      00 20 0e 91     add     x0, x0, #904
-# AFTER:  140002084:      00 04 40 91     add     x0, x0, #1, lsl #12
-# AFTER:  140002088:      00 c4 41 f9     ldr     x0, [x0, #904]
-# AFTER:  14000208c:      10 00 00 b0     adrp    x16, #4096
-# AFTER:  140002090:      10 1e 40 f9     ldr     x16, [x16, #56]
-# AFTER:  140002094:      00 02 1f d6     br      x16
+# 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:  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]
+# AFTER:  14000101c:      00 05 40 f9     ldr     x0, [x8, #8]
+# AFTER:  140001020:      00 21 00 39     strb    w0, [x8, #8]
+# AFTER:  140001024:      00 11 00 79     strh    w0, [x8, #8]
+# AFTER:  140001028:      00 09 00 b9     str     w0, [x8, #8]
+# AFTER:  14000102c:      00 05 00 f9     str     x0, [x8, #8]
+# AFTER:  140001030:      00 41 40 3d     ldr     b0, [x8, #16]
+# AFTER:  140001034:      00 21 40 7d     ldr     h0, [x8, #16]
+# AFTER:  140001038:      00 11 40 bd     ldr     s0, [x8, #16]
+# AFTER:  14000103c:      00 09 40 fd     ldr     d0, [x8, #16]
+# AFTER:  140001040:      00 05 c0 3d     ldr     q0, [x8, #16]
+# AFTER:  140001044:      00 41 00 3d     str     b0, [x8, #16]
+# AFTER:  140001048:      00 21 00 7d     str     h0, [x8, #16]
+# AFTER:  14000104c:      00 11 00 bd     str     s0, [x8, #16]
+# AFTER:  140001050:      00 09 00 fd     str     d0, [x8, #16]
+# AFTER:  140001054:      00 05 80 3d     str     q0, [x8, #16]
+# AFTER:  140001058:      00 09 40 f9     ldr     x0, [x8, #16]
+# AFTER:  14000105c:      00 00 00 f0     adrp    x0, #12288
+# AFTER:  140001060:      00 fc 47 f9     ldr     x0, [x0, #4088]
+# AFTER:  140001064:      e0 03 1f 2a     mov      w0, wzr
+# AFTER:  140001068:      fe 07 41 f8     ldr     x30, [sp], #16
+# AFTER:  14000106c:      c0 03 5f d6     ret
+# AFTER:  140001070:      10 20 00 40     <unknown>
+# AFTER:  140001074:      01 00 00 00     <unknown>
+# AFTER:  140001078:      09 20 00 00     <unknown>
+# AFTER:  14000107c:      09 00 00 00     <unknown>
+# AFTER:  140001080:      00 20 0e 91     add     x0, x0, #904
+# AFTER:  140001084:      00 04 40 91     add     x0, x0, #1, lsl #12
+# AFTER:  140001088:      00 c4 41 f9     ldr     x0, [x0, #904]
+# AFTER:  14000108c:      03 00 00 00     <unknown>
+# 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
 
 --- !COFF
 header:
@@ -90,7 +98,7 @@
   - Name:            .text
     Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
     Alignment:       4
-    SectionData:     FE0F1FF80000009000080091000000940001403900014079000140B9000140F90001003900010079000100B9000100F90001403D0001407D000140BD000140FD0001C03D0001003D0001007D000100BD000100FD0001803D000540F9201A01B000FC4FF9E0031F2AFE0741F8C0035FD6080000000000000001000000010000000000009100004091000040f9
+    SectionData:     FE0F1FF80000009000080091000000940001403900014079000140B9000140F90001003900010079000100B9000100F90001403D0001407D000140BD000140FD0001C03D0001003D0001007D000100BD000100FD0001803D000540F9201A01B000FC4FF9E0031F2AFE0741F8C0035FD6080000000000000001000000010000000000009100004091000040f901000000201a09300100005400000036
     Relocations:
       - VirtualAddress:  4
         SymbolName:      .Lstr
@@ -182,6 +190,18 @@
       - VirtualAddress:  136
         SymbolName:      .Lglobal5000
         Type:            IMAGE_REL_ARM64_SECREL_LOW12L
+      - VirtualAddress:  140
+        SymbolName:      .Lglobal
+        Type:            IMAGE_REL_ARM64_SECTION
+      - VirtualAddress:  144
+        SymbolName:      .Lglobal
+        Type:            IMAGE_REL_ARM64_REL21
+      - VirtualAddress:  148
+        SymbolName:      function
+        Type:            IMAGE_REL_ARM64_BRANCH19
+      - VirtualAddress:  152
+        SymbolName:      function
+        Type:            IMAGE_REL_ARM64_BRANCH14
   - Name:            .data
     Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
     Alignment:       4
diff --git a/test/COFF/armnt-movt32t.test b/test/COFF/armnt-movt32t.test
index 7c6965e..6a0640c 100644
--- a/test/COFF/armnt-movt32t.test
+++ b/test/COFF/armnt-movt32t.test
@@ -11,7 +11,7 @@
 # BEFORE:        8: 70 47         bx lr
 
 # AFTER: Disassembly of section .text:
-# AFTER:        0: 41 f2 00 00   movw r0, #4096
+# AFTER:        0: 42 f2 00 00   movw r0, #8192
 # AFTER:        4: c0 f2 40 00   movt r0, #64
 # AFTER:        8: 70 47         bx lr
 
diff --git a/test/COFF/associative-comdat.s b/test/COFF/associative-comdat.s
index dd54195..a2c3bea 100644
--- a/test/COFF/associative-comdat.s
+++ b/test/COFF/associative-comdat.s
@@ -9,14 +9,15 @@
 
 # CHECK: Sections [
 # CHECK:   Section {
-# CHECK:     Number: 1
-# CHECK-LABEL:     Name: .data (2E 64 61 74 61 00 00 00)
-# CHECK-NEXT:     VirtualSize: 0x4
-# CHECK:   Section {
+# CHECK:     Number: 2
 # CHECK-LABEL:     Name: .rdata (2E 72 64 61 74 61 00 00)
 #             This is the critical check to show that only *one* definition of
 #             foo_assoc was retained. This *must* be 8, not 16.
 # CHECK-NEXT:     VirtualSize: 0x8
+# CHECK:   Section {
+# CHECK:     Number: 3
+# CHECK-LABEL:     Name: .data (2E 64 61 74 61 00 00 00)
+# CHECK-NEXT:     VirtualSize: 0x4
 
         .text
         .def     main;
diff --git a/test/COFF/baserel.test b/test/COFF/baserel.test
index ce0b276..6441bb2 100644
--- a/test/COFF/baserel.test
+++ b/test/COFF/baserel.test
@@ -9,35 +9,35 @@
 # BASEREL:      BaseReloc [
 # BASEREL-NEXT: Entry {
 # BASEREL-NEXT:   Type: DIR64
-# BASEREL-NEXT:   Address: 0x2007
+# BASEREL-NEXT:   Address: 0x1007
 # BASEREL-NEXT: }
 # BASEREL-NEXT: Entry {
 # BASEREL-NEXT:   Type: DIR64
-# BASEREL-NEXT:   Address: 0x200C
+# BASEREL-NEXT:   Address: 0x100C
 # BASEREL-NEXT: }
 # BASEREL-NEXT: Entry {
 # BASEREL-NEXT:   Type: DIR64
-# BASEREL-NEXT:   Address: 0x201E
+# BASEREL-NEXT:   Address: 0x101E
 # BASEREL-NEXT: }
 # BASEREL-NEXT: Entry {
 # BASEREL-NEXT:   Type: ABSOLUTE
-# BASEREL-NEXT:   Address: 0x2000
+# BASEREL-NEXT:   Address: 0x1000
 # BASEREL-NEXT: }
 # BASEREL-NEXT: Entry {
 # BASEREL-NEXT:   Type: DIR64
-# BASEREL-NEXT:   Address: 0x3007
+# BASEREL-NEXT:   Address: 0x4007
 # BASEREL-NEXT: }
 # BASEREL-NEXT: Entry {
 # BASEREL-NEXT:   Type: DIR64
-# BASEREL-NEXT:   Address: 0x300C
+# BASEREL-NEXT:   Address: 0x400C
 # BASEREL-NEXT: }
 # BASEREL-NEXT: Entry {
 # BASEREL-NEXT:   Type: DIR64
-# BASEREL-NEXT:   Address: 0x301E
+# BASEREL-NEXT:   Address: 0x401E
 # BASEREL-NEXT: }
 # BASEREL-NEXT: Entry {
 # BASEREL-NEXT:   Type: ABSOLUTE
-# BASEREL-NEXT:   Address: 0x3000
+# BASEREL-NEXT:   Address: 0x4000
 # BASEREL-NEXT: }
 #
 # NOBASEREL:      BaseReloc [
diff --git a/test/COFF/combined-resources.test b/test/COFF/combined-resources.test
index e8d5d65..37dfc57 100644
--- a/test/COFF/combined-resources.test
+++ b/test/COFF/combined-resources.test
@@ -11,8 +11,8 @@
 # RUN: llvm-readobj -coff-resources -file-headers -section-data %t.exe | \
 # RUN:   FileCheck %s
 
-CHECK:      ResourceTableRVA: 0x1000
-CHECK-NEXT: ResourceTableSize: 0xC1C
+CHECK:      ResourceTableRVA: 0x2000
+CHECK-NEXT: ResourceTableSize: 0xC20
 CHECK-DAG:  Resources [
 CHECK-NEXT:   Total Number of Resources: 13
 CHECK-DAG:  .rsrc Data (
@@ -49,19 +49,19 @@
 CHECK-NEXT: 01E0: 09040000 A0020000 00000000 00000000  |................|
 CHECK-NEXT: 01F0: 00000000 00000300 09040000 B0020000  |................|
 CHECK-NEXT: 0200: 04080000 C0020000 07100000 D0020000  |................|
-CHECK-NEXT: 0210: FC1A0000 39000000 00000000 00000000  |....9...........|
-CHECK-NEXT: 0220: C4130000 28030000 00000000 00000000  |....(...........|
-CHECK-NEXT: 0230: EC160000 28030000 00000000 00000000  |....(...........|
-CHECK-NEXT: 0240: CC1A0000 30000000 00000000 00000000  |....0...........|
-CHECK-NEXT: 0250: 141A0000 2E000000 00000000 00000000  |................|
-CHECK-NEXT: 0260: 441A0000 6C000000 00000000 00000000  |D...l...........|
-CHECK-NEXT: 0270: 7C130000 2A000000 00000000 00000000  ||...*...........|
-CHECK-NEXT: 0280: AC130000 18000000 00000000 00000000  |................|
-CHECK-NEXT: 0290: 041C0000 18000000 00000000 00000000  |................|
-CHECK-NEXT: 02A0: B41A0000 18000000 00000000 00000000  |................|
-CHECK-NEXT: 02B0: 3C1B0000 36000000 00000000 00000000  |<...6...........|
-CHECK-NEXT: 02C0: 741B0000 43000000 00000000 00000000  |t...C...........|
-CHECK-NEXT: 02D0: BC1B0000 42000000 00000000 00000000  |....B...........|
+CHECK-NEXT: 0210: 002B0000 39000000 00000000 00000000  |.+..9...........|
+CHECK-NEXT: 0220: C8230000 28030000 00000000 00000000  |.#..(...........|
+CHECK-NEXT: 0230: F0260000 28030000 00000000 00000000  |.&..(...........|
+CHECK-NEXT: 0240: D02A0000 30000000 00000000 00000000  |.*..0...........|
+CHECK-NEXT: 0250: 182A0000 2E000000 00000000 00000000  |.*..............|
+CHECK-NEXT: 0260: 482A0000 6C000000 00000000 00000000  |H*..l...........|
+CHECK-NEXT: 0270: 80230000 2A000000 00000000 00000000  |.#..*...........|
+CHECK-NEXT: 0280: B0230000 18000000 00000000 00000000  |.#..............|
+CHECK-NEXT: 0290: 082C0000 18000000 00000000 00000000  |.,..............|
+CHECK-NEXT: 02A0: B82A0000 18000000 00000000 00000000  |.*..............|
+CHECK-NEXT: 02B0: 402B0000 36000000 00000000 00000000  |@+..6...........|
+CHECK-NEXT: 02C0: 782B0000 43000000 00000000 00000000  |x+..C...........|
+CHECK-NEXT: 02D0: C02B0000 42000000 00000000 00000000  |.+..B...........|
 CHECK-NEXT: 02E0: 0E004D00 59004100 43004300 45004C00  |..M.Y.A.C.C.E.L.|
 CHECK-NEXT: 02F0: 45005200 41005400 4F005200 53000600  |E.R.A.T.O.R.S...|
 CHECK-NEXT: 0300: 43005500 52005300 4F005200 04004F00  |C.U.R.S.O.R...O.|
@@ -71,14 +71,14 @@
 CHECK-NEXT: 0340: 49004E00 47004100 52005200 41005900  |I.N.G.A.R.R.A.Y.|
 CHECK-NEXT: 0350: 0A004D00 59005200 45005300 4F005500  |..M.Y.R.E.S.O.U.|
 CHECK-NEXT: 0360: 52004300 45000900 52004100 4E004400  |R.C.E...R.A.N.D.|
-CHECK-NEXT: 0370: 4F004D00 44004100 54000000 00000500  |O.M.D.A.T.......|
-CHECK-NEXT: 0380: 48006500 6C006C00 6F000000 00000000  |H.e.l.l.o.......|
+CHECK-NEXT: 0370: 4F004D00 44004100 54000000 00000000  |O.M.D.A.T.......|
+CHECK-NEXT: 0380: 00000500 48006500 6C006C00 6F000000  |....H.e.l.l.o...|
 CHECK-NEXT: 0390: 00000000 00000000 00000000 00000000  |................|
-CHECK-NEXT: 03A0: 00000000 00000000 00000000 11000300  |................|
-CHECK-NEXT: 03B0: E7030000 0D004400 4C040000 82001200  |......D.L.......|
-CHECK-NEXT: 03C0: BC010000 28000000 10000000 10000000  |....(...........|
-CHECK-NEXT: 03D0: 01001800 00000000 00030000 C40E0000  |................|
-CHECK-NEXT: 03E0: C40E0000 00000000 00000000 FFFFFFFF  |................|
+CHECK-NEXT: 03A0: 00000000 00000000 00000000 00000000  |................|
+CHECK-NEXT: 03B0: 11000300 E7030000 0D004400 4C040000  |..........D.L...|
+CHECK-NEXT: 03C0: 82001200 BC010000 28000000 10000000  |........(.......|
+CHECK-NEXT: 03D0: 10000000 01001800 00000000 00030000  |................|
+CHECK-NEXT: 03E0: C40E0000 C40E0000 00000000 00000000  |................|
 CHECK-NEXT: 03F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
 CHECK-NEXT: 0400: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
 CHECK-NEXT: 0410: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
@@ -86,50 +86,50 @@
 CHECK-NEXT: 0430: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
 CHECK-NEXT: 0440: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
 CHECK-NEXT: 0450: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 0460: FF7F7F7F 7C7C7C78 78787575 75FFFFFF  |....|||xxxuuu...|
-CHECK-NEXT: 0470: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 0480: FFFFFFFF FFFFFFFF 979797FF FFFFFFFF  |................|
-CHECK-NEXT: 0490: FF838383 AAAAAADB DBDB7979 79757575  |..........yyyuuu|
-CHECK-NEXT: 04A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 04B0: FFFFFFFF FFFFFFFF 9C9C9C98 9898FFFF  |................|
-CHECK-NEXT: 04C0: FF888888 DBDBDBB7 B7B77D7D 7DFFFFFF  |..........}}}...|
-CHECK-NEXT: 04D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 04E0: FFFFFFFF FFFFFFFF A0A0A09C 9C9C9393  |................|
-CHECK-NEXT: 04F0: 93ADADAD F2F2F284 84848181 81FFFFFF  |................|
-CHECK-NEXT: 0500: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 0510: FFFFFFFF FFFFFFFF A4A4A4D7 D7D79D9D  |................|
-CHECK-NEXT: 0520: 9DD0D0D0 EEEEEE91 91918D8D 8DFFFFFF  |................|
-CHECK-NEXT: 0530: FFFFFF81 81817E7E 7EFFFFFF FFFFFFFF  |......~~~.......|
-CHECK-NEXT: 0540: FFFFFFFF FFFFFFFF A9A9A9F2 F2F2E5E5  |................|
-CHECK-NEXT: 0550: E5E2E2E2 95959591 91918D8D 8D898989  |................|
-CHECK-NEXT: 0560: 868686FF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 0570: FFFFFFFF FFFFFFFF ADADADF2 F2F2E1E1  |................|
-CHECK-NEXT: 0580: E1DFDFDF E7E7E7E4 E4E4BBBB BB8E8E8E  |................|
-CHECK-NEXT: 0590: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 05A0: FFFFFFFF FFFFFFFF B5B5B5F2 F2F2E8E8  |................|
-CHECK-NEXT: 05B0: E8E7E7E7 EAEAEAC6 C6C69E9E 9EFFFFFF  |................|
-CHECK-NEXT: 05C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 05D0: FFFFFFFF FFFFFFFF B9B9B9F4 F4F4ECEC  |................|
-CHECK-NEXT: 05E0: ECEDEDED CBCBCBA7 A7A7FFFF FFFFFFFF  |................|
+CHECK-NEXT: 0460: FFFFFFFF FF7F7F7F 7C7C7C78 78787575  |........|||xxxuu|
+CHECK-NEXT: 0470: 75FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |u...............|
+CHECK-NEXT: 0480: FFFFFFFF FFFFFFFF FFFFFFFF 979797FF  |................|
+CHECK-NEXT: 0490: FFFFFFFF FF838383 AAAAAADB DBDB7979  |..............yy|
+CHECK-NEXT: 04A0: 79757575 FFFFFFFF FFFFFFFF FFFFFFFF  |yuuu............|
+CHECK-NEXT: 04B0: FFFFFFFF FFFFFFFF FFFFFFFF 9C9C9C98  |................|
+CHECK-NEXT: 04C0: 9898FFFF FF888888 DBDBDBB7 B7B77D7D  |..............}}|
+CHECK-NEXT: 04D0: 7DFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |}...............|
+CHECK-NEXT: 04E0: FFFFFFFF FFFFFFFF FFFFFFFF A0A0A09C  |................|
+CHECK-NEXT: 04F0: 9C9C9393 93ADADAD F2F2F284 84848181  |................|
+CHECK-NEXT: 0500: 81FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
+CHECK-NEXT: 0510: FFFFFFFF FFFFFFFF FFFFFFFF A4A4A4D7  |................|
+CHECK-NEXT: 0520: D7D79D9D 9DD0D0D0 EEEEEE91 91918D8D  |................|
+CHECK-NEXT: 0530: 8DFFFFFF FFFFFF81 81817E7E 7EFFFFFF  |..........~~~...|
+CHECK-NEXT: 0540: FFFFFFFF FFFFFFFF FFFFFFFF A9A9A9F2  |................|
+CHECK-NEXT: 0550: F2F2E5E5 E5E2E2E2 95959591 91918D8D  |................|
+CHECK-NEXT: 0560: 8D898989 868686FF FFFFFFFF FFFFFFFF  |................|
+CHECK-NEXT: 0570: FFFFFFFF FFFFFFFF FFFFFFFF ADADADF2  |................|
+CHECK-NEXT: 0580: F2F2E1E1 E1DFDFDF E7E7E7E4 E4E4BBBB  |................|
+CHECK-NEXT: 0590: BB8E8E8E FFFFFFFF FFFFFFFF FFFFFFFF  |................|
+CHECK-NEXT: 05A0: FFFFFFFF FFFFFFFF FFFFFFFF B5B5B5F2  |................|
+CHECK-NEXT: 05B0: F2F2E8E8 E8E7E7E7 EAEAEAC6 C6C69E9E  |................|
+CHECK-NEXT: 05C0: 9EFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
+CHECK-NEXT: 05D0: FFFFFFFF FFFFFFFF FFFFFFFF B9B9B9F4  |................|
+CHECK-NEXT: 05E0: F4F4ECEC ECEDEDED CBCBCBA7 A7A7FFFF  |................|
 CHECK-NEXT: 05F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 0600: FFFFFFFF FFFFFFFF BDBDBDF7 F7F7EFEF  |................|
-CHECK-NEXT: 0610: EFD0D0D0 AFAFAFFF FFFFFFFF FFFFFFFF  |................|
+CHECK-NEXT: 0600: FFFFFFFF FFFFFFFF FFFFFFFF BDBDBDF7  |................|
+CHECK-NEXT: 0610: F7F7EFEF EFD0D0D0 AFAFAFFF FFFFFFFF  |................|
 CHECK-NEXT: 0620: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 0630: FFFFFFFF FFFFFFFF C1C1C1F7 F7F7D5D5  |................|
-CHECK-NEXT: 0640: D5B6B6B6 FFFFFFFF FFFFFFFF FFFFFFFF  |................|
+CHECK-NEXT: 0630: FFFFFFFF FFFFFFFF FFFFFFFF C1C1C1F7  |................|
+CHECK-NEXT: 0640: F7F7D5D5 D5B6B6B6 FFFFFFFF FFFFFFFF  |................|
 CHECK-NEXT: 0650: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 0660: FFFFFFFF FFFFFFFF C4C4C4D9 D9D9BEBE  |................|
-CHECK-NEXT: 0670: BEFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
+CHECK-NEXT: 0660: FFFFFFFF FFFFFFFF FFFFFFFF C4C4C4D9  |................|
+CHECK-NEXT: 0670: D9D9BEBE BEFFFFFF FFFFFFFF FFFFFFFF  |................|
 CHECK-NEXT: 0680: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 0690: FFFFFFFF FFFFFFFF C8C8C8C5 C5C5FFFF  |................|
-CHECK-NEXT: 06A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
+CHECK-NEXT: 0690: FFFFFFFF FFFFFFFF FFFFFFFF C8C8C8C5  |................|
+CHECK-NEXT: 06A0: C5C5FFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
 CHECK-NEXT: 06B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 06C0: FFFFFFFF FFFFFFFF CBCBCBFF FFFFFFFF  |................|
+CHECK-NEXT: 06C0: FFFFFFFF FFFFFFFF FFFFFFFF CBCBCBFF  |................|
 CHECK-NEXT: 06D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 06E0: FFFFFFFF FFFFFFFF FFFFFFFF 28000000  |............(...|
-CHECK-NEXT: 06F0: 10000000 10000000 01001800 00000000  |................|
-CHECK-NEXT: 0700: 00030000 C40E0000 C40E0000 00000000  |................|
-CHECK-NEXT: 0710: 00000000 FFFFFFFF FFFFFFFF FFFFFFFF  |................|
+CHECK-NEXT: 06E0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
+CHECK-NEXT: 06F0: 28000000 10000000 10000000 01001800  |(...............|
+CHECK-NEXT: 0700: 00000000 00030000 C40E0000 C40E0000  |................|
+CHECK-NEXT: 0710: 00000000 00000000 FFFFFFFF FFFFFFFF  |................|
 CHECK-NEXT: 0720: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
 CHECK-NEXT: 0730: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
 CHECK-NEXT: 0740: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
@@ -142,29 +142,29 @@
 CHECK-NEXT: 07B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
 CHECK-NEXT: 07C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
 CHECK-NEXT: 07D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 07E0: A0E3A901 B31801B3 1801B318 01B31801  |................|
-CHECK-NEXT: 07F0: B31801B3 1861D06F FFFFFFFF FFFFFFFF  |.....a.o........|
+CHECK-NEXT: 07E0: FFFFFFFF A0E3A901 B31801B3 1801B318  |................|
+CHECK-NEXT: 07F0: 01B31801 B31801B3 1861D06F FFFFFFFF  |.........a.o....|
 CHECK-NEXT: 0800: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 0810: 01B31800 D7331CDB 49DBF9E2 9BEFAF00  |.....3..I.......|
-CHECK-NEXT: 0820: D73300D7 3301B318 FFFFFFFF FFFFFFFF  |.3..3...........|
+CHECK-NEXT: 0810: FFFFFFFF 01B31800 D7331CDB 49DBF9E2  |.........3..I...|
+CHECK-NEXT: 0820: 9BEFAF00 D73300D7 3301B318 FFFFFFFF  |.....3..3.......|
 CHECK-NEXT: 0830: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 0840: 01B31800 DE55F6FE F9DBFAE7 FEFFFE86  |.....U..........|
-CHECK-NEXT: 0850: EFAE00DE 5501B318 FFFFFFFF FFFFFFFF  |....U...........|
+CHECK-NEXT: 0840: FFFFFFFF 01B31800 DE55F6FE F9DBFAE7  |.........U......|
+CHECK-NEXT: 0850: FEFFFE86 EFAE00DE 5501B318 FFFFFFFF  |........U.......|
 CHECK-NEXT: 0860: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 0870: 01B31800 E676DBFB EC00E676 57EFA5FB  |.....v.....vW...|
-CHECK-NEXT: 0880: FFFD55EE A401B318 FFFFFFFF FFFFFFFF  |..U.............|
+CHECK-NEXT: 0870: FFFFFFFF 01B31800 E676DBFB EC00E676  |.........v.....v|
+CHECK-NEXT: 0880: 57EFA5FB FFFD55EE A401B318 FFFFFFFF  |W.....U.........|
 CHECK-NEXT: 0890: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 08A0: 01B31800 ED9800ED 9800ED98 00ED9887  |................|
-CHECK-NEXT: 08B0: F7CFFEFF FF01B318 FFFFFFFF FFFFFFFF  |................|
+CHECK-NEXT: 08A0: FFFFFFFF 01B31800 ED9800ED 9800ED98  |................|
+CHECK-NEXT: 08B0: 00ED9887 F7CFFEFF FF01B318 FFFFFFFF  |................|
 CHECK-NEXT: 08C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 08D0: 01B31800 F4BA00F4 BA00F4BA 00F4BA00  |................|
-CHECK-NEXT: 08E0: F4BA9CFB E401B318 FFFFFFFF FFFFFFFF  |................|
+CHECK-NEXT: 08D0: FFFFFFFF 01B31800 F4BA00F4 BA00F4BA  |................|
+CHECK-NEXT: 08E0: 00F4BA00 F4BA9CFB E401B318 FFFFFFFF  |................|
 CHECK-NEXT: 08F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 0900: 01B31800 FBDB00FB DB00FBDB 00FBDB00  |................|
-CHECK-NEXT: 0910: FBDB00FB DB01B318 FFFFFFFF FFFFFFFF  |................|
+CHECK-NEXT: 0900: FFFFFFFF 01B31800 FBDB00FB DB00FBDB  |................|
+CHECK-NEXT: 0910: 00FBDB00 FBDB00FB DB01B318 FFFFFFFF  |................|
 CHECK-NEXT: 0920: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 0930: 9FE2A801 B31801B3 1801B318 01B31801  |................|
-CHECK-NEXT: 0940: B31801B3 1861D06F FFFFFFFF FFFFFFFF  |.....a.o........|
+CHECK-NEXT: 0930: FFFFFFFF 9FE2A801 B31801B3 1801B318  |................|
+CHECK-NEXT: 0940: 01B31801 B31801B3 1861D06F FFFFFFFF  |.........a.o....|
 CHECK-NEXT: 0950: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
 CHECK-NEXT: 0960: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
 CHECK-NEXT: 0970: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
@@ -177,37 +177,37 @@
 CHECK-NEXT: 09E0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
 CHECK-NEXT: 09F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
 CHECK-NEXT: 0A00: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................|
-CHECK-NEXT: 0A10: FFFFFFFF 00000000 00006400 79007500  |..........d.y.u.|
-CHECK-NEXT: 0A20: 00000000 65007300 68006100 6C006100  |....e.s.h.a.l.a.|
-CHECK-NEXT: 0A30: 00008000 66006B00 61006F00 79006100  |....f.k.a.o.y.a.|
-CHECK-NEXT: 0A40: 00000000 0000C080 00000000 02000A00  |................|
-CHECK-NEXT: 0A50: 0A00C800 2C010000 00005400 65007300  |....,.....T.e.s.|
-CHECK-NEXT: 0A60: 74000000 01000250 00000000 0A000A00  |t......P........|
-CHECK-NEXT: 0A70: E6000E00 0100FFFF 82004300 6F006E00  |..........C.o.n.|
-CHECK-NEXT: 0A80: 74006900 6E007500 65003A00 00000000  |t.i.n.u.e.:.....|
-CHECK-NEXT: 0A90: 00000150 00000000 42008600 A1000D00  |...P....B.......|
-CHECK-NEXT: 0AA0: 0200FFFF 80002600 4F004B00 00000000  |......&.O.K.....|
-CHECK-NEXT: 0AB0: 00000000 11005800 A4000000 0D004800  |......X.......H.|
-CHECK-NEXT: 0AC0: 2E160000 82001200 BC010000 00000000  |................|
-CHECK-NEXT: 0AD0: 00006400 66006900 73006800 00000000  |..d.f.i.s.h.....|
-CHECK-NEXT: 0AE0: 65007300 61006C00 61006400 00008000  |e.s.a.l.a.d.....|
-CHECK-NEXT: 0AF0: 66006400 75006300 6B000000 74686973  |f.d.u.c.k...this|
-CHECK-NEXT: 0B00: 20697320 61207573 65722064 6566696E  | is a user defin|
-CHECK-NEXT: 0B10: 65642072 65736F75 72636500 69742063  |ed resource.it c|
-CHECK-NEXT: 0B20: 6F6E7461 696E7320 6D616E79 20737472  |ontains many str|
-CHECK-NEXT: 0B30: 696E6773 00000000 00000000 74686973  |ings........this|
-CHECK-NEXT: 0B40: 20697320 61207261 6E646F6D 20626974  | is a random bit|
-CHECK-NEXT: 0B50: 206F6620 64617461 20746861 74206D65  | of data that me|
-CHECK-NEXT: 0B60: 616E7320 6E6F7468 696E6700 A9230E14  |ans nothing..#..|
-CHECK-NEXT: 0B70: F4F60000 7A686534 20736869 34207969  |....zhe4 shi4 yi|
-CHECK-NEXT: 0B80: 31676534 20737569 326A6931 20646520  |1ge4 sui2ji1 de |
-CHECK-NEXT: 0B90: 73687534 6A75342C 207A6865 34207969  |shu4ju4, zhe4 yi|
-CHECK-NEXT: 0BA0: 34776569 347A6865 20736865 6E326D65  |4wei4zhe shen2me|
-CHECK-NEXT: 0BB0: 00A9230E 14F4F600 00000000 44696573  |..#.........Dies|
-CHECK-NEXT: 0BC0: 20697374 2065696E 207A7566 C3A46C6C  | ist ein zuf..ll|
-CHECK-NEXT: 0BD0: 69676573 20426974 20766F6E 20446174  |iges Bit von Dat|
-CHECK-NEXT: 0BE0: 656E2C20 64696520 6E696368 74732062  |en, die nichts b|
-CHECK-NEXT: 0BF0: 65646575 74657400 A9230E14 F4F60000  |edeutet..#......|
-CHECK-NEXT: 0C00: 00000000 11000300 E7030000 0D004400  |..............D.|
-CHECK-NEXT: 0C10: 4C040000 82001200 BC010000           |L...........|
+CHECK-NEXT: 0A10: FFFFFFFF FFFFFFFF 00000000 00006400  |..............d.|
+CHECK-NEXT: 0A20: 79007500 00000000 65007300 68006100  |y.u.....e.s.h.a.|
+CHECK-NEXT: 0A30: 6C006100 00008000 66006B00 61006F00  |l.a.....f.k.a.o.|
+CHECK-NEXT: 0A40: 79006100 00000000 0000C080 00000000  |y.a.............|
+CHECK-NEXT: 0A50: 02000A00 0A00C800 2C010000 00005400  |........,.....T.|
+CHECK-NEXT: 0A60: 65007300 74000000 01000250 00000000  |e.s.t......P....|
+CHECK-NEXT: 0A70: 0A000A00 E6000E00 0100FFFF 82004300  |..............C.|
+CHECK-NEXT: 0A80: 6F006E00 74006900 6E007500 65003A00  |o.n.t.i.n.u.e.:.|
+CHECK-NEXT: 0A90: 00000000 00000150 00000000 42008600  |.......P....B...|
+CHECK-NEXT: 0AA0: A1000D00 0200FFFF 80002600 4F004B00  |..........&.O.K.|
+CHECK-NEXT: 0AB0: 00000000 00000000 11005800 A4000000  |..........X.....|
+CHECK-NEXT: 0AC0: 0D004800 2E160000 82001200 BC010000  |..H.............|
+CHECK-NEXT: 0AD0: 00000000 00006400 66006900 73006800  |......d.f.i.s.h.|
+CHECK-NEXT: 0AE0: 00000000 65007300 61006C00 61006400  |....e.s.a.l.a.d.|
+CHECK-NEXT: 0AF0: 00008000 66006400 75006300 6B000000  |....f.d.u.c.k...|
+CHECK-NEXT: 0B00: 74686973 20697320 61207573 65722064  |this is a user d|
+CHECK-NEXT: 0B10: 6566696E 65642072 65736F75 72636500  |efined resource.|
+CHECK-NEXT: 0B20: 69742063 6F6E7461 696E7320 6D616E79  |it contains many|
+CHECK-NEXT: 0B30: 20737472 696E6773 00000000 00000000  | strings........|
+CHECK-NEXT: 0B40: 74686973 20697320 61207261 6E646F6D  |this is a random|
+CHECK-NEXT: 0B50: 20626974 206F6620 64617461 20746861  | bit of data tha|
+CHECK-NEXT: 0B60: 74206D65 616E7320 6E6F7468 696E6700  |t means nothing.|
+CHECK-NEXT: 0B70: A9230E14 F4F60000 7A686534 20736869  |.#......zhe4 shi|
+CHECK-NEXT: 0B80: 34207969 31676534 20737569 326A6931  |4 yi1ge4 sui2ji1|
+CHECK-NEXT: 0B90: 20646520 73687534 6A75342C 207A6865  | de shu4ju4, zhe|
+CHECK-NEXT: 0BA0: 34207969 34776569 347A6865 20736865  |4 yi4wei4zhe she|
+CHECK-NEXT: 0BB0: 6E326D65 00A9230E 14F4F600 00000000  |n2me..#.........|
+CHECK-NEXT: 0BC0: 44696573 20697374 2065696E 207A7566  |Dies ist ein zuf|
+CHECK-NEXT: 0BD0: C3A46C6C 69676573 20426974 20766F6E  |..lliges Bit von|
+CHECK-NEXT: 0BE0: 20446174 656E2C20 64696520 6E696368  | Daten, die nich|
+CHECK-NEXT: 0BF0: 74732062 65646575 74657400 A9230E14  |ts bedeutet..#..|
+CHECK-NEXT: 0C00: F4F60000 00000000 11000300 E7030000  |................|
+CHECK-NEXT: 0C10: 0D004400 4C040000 82001200 BC010000  |..D.L...........|
 CHECK-NEXT: )
diff --git a/test/COFF/common-alignment.test b/test/COFF/common-alignment.test
index a4ee157..db02d91 100644
--- a/test/COFF/common-alignment.test
+++ b/test/COFF/common-alignment.test
@@ -4,8 +4,8 @@
 # RUN: llvm-objdump -d %t.exe | FileCheck %s
 
 # Operands of B8 (MOV EAX) are common symbols
-# CHECK: 3000: b8 00 10 00 40
-# CHECK: 3005: b8 10 10 00 40
+# CHECK: 1000: b8 00 20 00 40
+# CHECK: 1005: b8 10 20 00 40
 
 --- !COFF
 header:
@@ -23,10 +23,6 @@
       - VirtualAddress:  6
         SymbolName:      bssdata4_align16
         Type:            IMAGE_REL_AMD64_ADDR32
-  - Name:            .data
-    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
-    Alignment:       4
-    SectionData:     03000000
   - Name:            .drectve
     Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
     Alignment:       1
@@ -45,18 +41,6 @@
       NumberOfLinenumbers: 0
       CheckSum:        0
       Number:          0
-  - Name:            .data
-    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:        0
-      Number:          0
   - Name:            main
     Value:           0
     SectionNumber:   1
diff --git a/test/COFF/common.test b/test/COFF/common.test
index 4a00153..7d11da2 100644
--- a/test/COFF/common.test
+++ b/test/COFF/common.test
@@ -4,11 +4,11 @@
 # RUN: llvm-objdump -d %t.exe | FileCheck %s
 
 # Operands of B8 (MOV EAX) are common symbols
-# CHECK: 3000: b8 00 10 00 40
-# CHECK: 3005: b8 04 10 00 40
-# CHECK: 300a: b8 20 10 00 40
-# CHECK: 300f: b8 60 10 00 40
-# CHECK: 3014: b8 70 10 00 40
+# CHECK: 1000: b8 00 20 00 40
+# CHECK: 1005: b8 04 20 00 40
+# CHECK: 100a: b8 20 20 00 40
+# CHECK: 100f: b8 60 20 00 40
+# CHECK: 1014: b8 70 20 00 40
 
 --- !COFF
 header:
@@ -35,10 +35,6 @@
       - VirtualAddress:  21
         SymbolName:      bssdata16
         Type:            IMAGE_REL_AMD64_ADDR32
-  - Name:            .data
-    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
-    Alignment:       4
-    SectionData:     03000000
 symbols:
   - Name:            .text
     Value:           0
@@ -52,18 +48,6 @@
       NumberOfLinenumbers: 0
       CheckSum:        0
       Number:          0
-  - Name:            .data
-    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:        0
-      Number:          0
   - Name:            main
     Value:           0
     SectionNumber:   1
diff --git a/test/COFF/crt-chars.test b/test/COFF/crt-chars.test
new file mode 100644
index 0000000..e685631
--- /dev/null
+++ b/test/COFF/crt-chars.test
@@ -0,0 +1,32 @@
+# RUN: yaml2obj %s > %t.obj
+# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj
+# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s
+
+# CHECK: Name: .CRT
+# CHECK: Characteristics [
+# CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
+# CHECK-NEXT: IMAGE_SCN_MEM_READ
+# CHECK-NEXT: ]
+# CHECK-NEXT: SectionData (
+# CHECK-NEXT: 010203
+# CHECK-NEXT: )
+
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [  ]
+sections:
+  - Name:            .CRT$XCZ
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    SectionData:     03
+  - Name:            .CRT$XCU
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       1
+    SectionData:     02
+  - Name:            .CRT$XCA
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    SectionData:     01
+symbols:
+...
diff --git a/test/COFF/ctors_dtors_priority.s b/test/COFF/ctors_dtors_priority.s
index 60562ba..efa0354 100644
--- a/test/COFF/ctors_dtors_priority.s
+++ b/test/COFF/ctors_dtors_priority.s
@@ -22,9 +22,9 @@
   .quad 2
 
 # CHECK:      Contents of section .ctors:
-# CHECK-NEXT: 140001000 01000000 00000000 02000000 00000000
-# CHECK-NEXT: 140001010 03000000 00000000
-
-# CHECK:      Contents of section .dtors:
 # CHECK-NEXT: 140002000 01000000 00000000 02000000 00000000
 # CHECK-NEXT: 140002010 03000000 00000000
+
+# CHECK:      Contents of section .dtors:
+# CHECK-NEXT: 140003000 01000000 00000000 02000000 00000000
+# CHECK-NEXT: 140003010 03000000 00000000
diff --git a/test/COFF/default-alignment.test b/test/COFF/default-alignment.test
new file mode 100644
index 0000000..da8ea06
--- /dev/null
+++ b/test/COFF/default-alignment.test
@@ -0,0 +1,21 @@
+# RUN: yaml2obj < %s > %t.obj
+# RUN: lld-link /out:%t.exe %t.obj /entry:__ImageBase /subsystem:console
+# RUN: llvm-objdump -s %t.exe | FileCheck %s
+
+# CHECK: Contents of section .rdata:
+# CHECK-NEXT: 01000000 00000000 00000000 00000000
+# CHECK-NEXT: 02
+
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: []
+sections:
+  - Name:            .rdata
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    SectionData:     01
+  - Name:            .rdata
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    SectionData:     02
+symbols:
+...
diff --git a/test/COFF/delayimports-armnt.yaml b/test/COFF/delayimports-armnt.yaml
index 231b4bc..a080d02 100644
--- a/test/COFF/delayimports-armnt.yaml
+++ b/test/COFF/delayimports-armnt.yaml
@@ -20,7 +20,7 @@
 # IMPORT-NEXT:   UnloadDelayImportTable: 0x0
 # IMPORT-NEXT:   Import {
 # IMPORT-NEXT:     Symbol: function (0)
-# IMPORT-NEXT:     Address: 0x401019
+# IMPORT-NEXT:     Address: 0x40100D
 # IMPORT-NEXT:   }
 # IMPORT-NEXT: }
 #
@@ -35,11 +35,11 @@
 # BASEREL-NEXT:   }
 # BASEREL-NEXT:   Entry {
 # BASEREL-NEXT:     Type: ARM_MOV32(T)
-# BASEREL-NEXT:     Address: 0x1018
+# BASEREL-NEXT:     Address: 0x1022
 # BASEREL-NEXT:   }
 # BASEREL-NEXT:   Entry {
-# BASEREL-NEXT:     Type: ARM_MOV32(T)
-# BASEREL-NEXT:     Address: 0x102E
+# BASEREL-NEXT:     Type: ABSOLUTE
+# BASEREL-NEXT:     Address: 0x1000
 # BASEREL-NEXT:   }
 # BASEREL-NEXT:   Entry {
 # BASEREL-NEXT:     Type: HIGHLOW
@@ -51,19 +51,19 @@
 # BASEREL-NEXT:   }
 # BASEREL-NEXT: ]
 #
-# DISASM:      401018:       43 f2 08 0c     movw    r12, #12296
-# DISASM-NEXT: 40101c:       c0 f2 40 0c     movt    r12, #64
-# DISASM-NEXT: 401020:       2d e9 0f 48     push.w  {r0, r1, r2, r3, r11, lr}
-# DISASM-NEXT: 401024:       0d f2 10 0b     addw    r11, sp, #16
-# DISASM-NEXT: 401028:       2d ed 10 0b     vpush   {d0, d1, d2, d3, d4, d5, d6, d7}
-# DISASM-NEXT: 40102c:       61 46           mov     r1, r12
-# DISASM-NEXT: 40102e:       42 f2 00 00     movw    r0, #8192
-# DISASM-NEXT: 401032:       c0 f2 40 00     movt    r0, #64
-# DISASM-NEXT: 401036:       ff f7 e3 ff     bl      #-58
-# DISASM-NEXT: 40103a:       84 46           mov     r12, r0
-# DISASM-NEXT: 40103c:       bd ec 10 0b     vpop    {d0, d1, d2, d3, d4, d5, d6, d7}
-# DISASM-NEXT: 401040:       bd e8 0f 48     pop.w   {r0, r1, r2, r3, r11, lr}
-# DISASM-NEXT: 401044:       60 47           bx      r12
+# DISASM:      40100c:       43 f2 08 0c     movw r12, #12296
+# DISASM-NEXT:               c0 f2 40 0c     movt    r12, #64
+# DISASM-NEXT:               2d e9 0f 48     push.w  {r0, r1, r2, r3, r11, lr}
+# DISASM-NEXT:               0d f2 10 0b     addw    r11, sp, #16
+# DISASM-NEXT:               2d ed 10 0b     vpush   {d0, d1, d2, d3, d4, d5, d6, d7}
+# DISASM-NEXT:               61 46           mov     r1, r12
+# DISASM-NEXT:               42 f2 00 00     movw r0, #8192
+# DISASM-NEXT:               c0 f2 40 00     movt    r0, #64
+# DISASM-NEXT:               ff f7 e9 ff     bl      #-46
+# DISASM-NEXT:               84 46           mov     r12, r0
+# DISASM-NEXT:               bd ec 10 0b     vpop    {d0, d1, d2, d3, d4, d5, d6, d7}
+# DISASM-NEXT:               bd e8 0f 48     pop.w   {r0, r1, r2, r3, r11, lr}
+# DISASM-NEXT:               60 47           bx      r12
 
 --- !COFF
 header:
diff --git a/test/COFF/delayimports.test b/test/COFF/delayimports.test
index 2c27d58..c6888b3 100644
--- a/test/COFF/delayimports.test
+++ b/test/COFF/delayimports.test
@@ -7,35 +7,35 @@
 IMPORT:      DelayImport {
 IMPORT-NEXT:   Name: std64.dll
 IMPORT-NEXT:   Attributes: 0x1
-IMPORT-NEXT:   ModuleHandle: 0x1018
-IMPORT-NEXT:   ImportAddressTable: 0x1020
-IMPORT-NEXT:   ImportNameTable: 0x3040
+IMPORT-NEXT:   ModuleHandle: 0x3018
+IMPORT-NEXT:   ImportAddressTable: 0x3020
+IMPORT-NEXT:   ImportNameTable: 0x2040
 IMPORT-NEXT:   BoundDelayImportTable: 0x0
 IMPORT-NEXT:   UnloadDelayImportTable: 0x0
 IMPORT-NEXT:   Import {
 IMPORT-NEXT:     Symbol: ExitProcess (0)
-IMPORT-NEXT:     Address: 0x140002066
+IMPORT-NEXT:     Address: 0x140001066
 IMPORT-NEXT:   }
 IMPORT-NEXT:   Import {
 IMPORT-NEXT:     Symbol:  (50)
-IMPORT-NEXT:     Address: 0x1400020BD
+IMPORT-NEXT:     Address: 0x1400010BD
 IMPORT-NEXT:   }
 IMPORT-NEXT:   Import {
 IMPORT-NEXT:     Symbol: MessageBoxA (0)
-IMPORT-NEXT:     Address: 0x140002114
+IMPORT-NEXT:     Address: 0x140001114
 IMPORT-NEXT:   }
 IMPORT-NEXT: }
 
 BASEREL:      BaseReloc [
 BASEREL-NEXT:   Entry {
 BASEREL-NEXT:     Type: DIR64
-BASEREL-NEXT:     Address: 0x1020
+BASEREL-NEXT:     Address: 0x3020
 BASEREL-NEXT:   }
 BASEREL-NEXT:   Entry {
 BASEREL-NEXT:     Type: DIR64
-BASEREL-NEXT:     Address: 0x1028
+BASEREL-NEXT:     Address: 0x3028
 BASEREL-NEXT:   }
 BASEREL-NEXT:   Entry {
 BASEREL-NEXT:     Type: DIR64
-BASEREL-NEXT:     Address: 0x1030
+BASEREL-NEXT:     Address: 0x3030
 BASEREL-NEXT:   }
diff --git a/test/COFF/delayimports32.test b/test/COFF/delayimports32.test
index 006eecf..9aa8f86 100644
--- a/test/COFF/delayimports32.test
+++ b/test/COFF/delayimports32.test
@@ -2,7 +2,7 @@
 # RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj
 # RUN: lld-link %t.obj %p/Inputs/std32.lib /subsystem:console \
 # RUN:   /entry:main@0 /alternatename:___delayLoadHelper2@8=_main@0 \
-# RUN:   /debug /delayload:std32.dll /out:%t.exe
+# RUN:   /delayload:std32.dll /out:%t.exe
 # RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s
 # RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s
 # RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s
@@ -13,75 +13,75 @@
 IMPORT-NEXT: DelayImport {
 IMPORT-NEXT:   Name: std32.dll
 IMPORT-NEXT:   Attributes: 0x1
-IMPORT-NEXT:   ModuleHandle: 0x1018
-IMPORT-NEXT:   ImportAddressTable: 0x1020
-IMPORT-NEXT:   ImportNameTable: 0x4040
+IMPORT-NEXT:   ModuleHandle: 0x3018
+IMPORT-NEXT:   ImportAddressTable: 0x3020
+IMPORT-NEXT:   ImportNameTable: 0x2040
 IMPORT-NEXT:   BoundDelayImportTable: 0x0
 IMPORT-NEXT:   UnloadDelayImportTable: 0x0
 IMPORT-NEXT:   Import {
 IMPORT-NEXT:     Symbol: ExitProcess (0)
-IMPORT-NEXT:     Address: 0x402029
+IMPORT-NEXT:     Address: 0x401029
 IMPORT-NEXT:   }
 IMPORT-NEXT:   Import {
 IMPORT-NEXT:     Symbol: MessageBoxA (0)
-IMPORT-NEXT:     Address: 0x40203E
+IMPORT-NEXT:     Address: 0x40103E
 IMPORT-NEXT:   }
 IMPORT-NEXT: }
 
 BASEREL:      BaseReloc [
 BASEREL-NEXT:   Entry {
 BASEREL-NEXT:     Type: HIGHLOW
-BASEREL-NEXT:     Address: 0x1020
+BASEREL-NEXT:     Address: 0x1005
 BASEREL-NEXT:   }
 BASEREL-NEXT:   Entry {
 BASEREL-NEXT:     Type: HIGHLOW
-BASEREL-NEXT:     Address: 0x1024
+BASEREL-NEXT:     Address: 0x100C
 BASEREL-NEXT:   }
 BASEREL-NEXT:   Entry {
 BASEREL-NEXT:     Type: HIGHLOW
-BASEREL-NEXT:     Address: 0x2005
+BASEREL-NEXT:     Address: 0x101F
 BASEREL-NEXT:   }
 BASEREL-NEXT:   Entry {
 BASEREL-NEXT:     Type: HIGHLOW
-BASEREL-NEXT:     Address: 0x200C
+BASEREL-NEXT:     Address: 0x1025
 BASEREL-NEXT:   }
 BASEREL-NEXT:   Entry {
 BASEREL-NEXT:     Type: HIGHLOW
-BASEREL-NEXT:     Address: 0x201F
+BASEREL-NEXT:     Address: 0x102C
 BASEREL-NEXT:   }
 BASEREL-NEXT:   Entry {
 BASEREL-NEXT:     Type: HIGHLOW
-BASEREL-NEXT:     Address: 0x2025
+BASEREL-NEXT:     Address: 0x1031
 BASEREL-NEXT:   }
 BASEREL-NEXT:   Entry {
 BASEREL-NEXT:     Type: HIGHLOW
-BASEREL-NEXT:     Address: 0x202C
+BASEREL-NEXT:     Address: 0x1041
 BASEREL-NEXT:   }
 BASEREL-NEXT:   Entry {
 BASEREL-NEXT:     Type: HIGHLOW
-BASEREL-NEXT:     Address: 0x2031
+BASEREL-NEXT:     Address: 0x1046
 BASEREL-NEXT:   }
 BASEREL-NEXT:   Entry {
 BASEREL-NEXT:     Type: HIGHLOW
-BASEREL-NEXT:     Address: 0x2041
+BASEREL-NEXT:     Address: 0x3020
 BASEREL-NEXT:   }
 BASEREL-NEXT:   Entry {
 BASEREL-NEXT:     Type: HIGHLOW
-BASEREL-NEXT:     Address: 0x2046
+BASEREL-NEXT:     Address: 0x3024
 BASEREL-NEXT:   }
 BASEREL-NEXT: ]
 
-DISASM:      202b:      68 20 10 40 00  pushl   $4198432
-DISASM-NEXT: 2030:      68 00 40 40 00  pushl   $4210688
-DISASM-NEXT: 2035:      e8 c6 ff ff ff  calll   -58 <.text>
-DISASM-NEXT: 203a:      5a      popl    %edx
-DISASM-NEXT: 203b:      59      popl    %ecx
-DISASM-NEXT: 203c:      ff e0   jmpl    *%eax
-DISASM-NEXT: 203e:      51      pushl   %ecx
-DISASM-NEXT: 203f:      52      pushl   %edx
-DISASM-NEXT: 2040:      68 24 10 40 00  pushl   $4198436
-DISASM-NEXT: 2045:      68 00 40 40 00  pushl   $4210688
-DISASM-NEXT: 204a:      e8 b1 ff ff ff  calll   -79 <.text>
-DISASM-NEXT: 204f:      5a      popl    %edx
-DISASM-NEXT: 2050:      59      popl    %ecx
-DISASM-NEXT: 2051:      ff e0   jmpl    *%eax
+DISASM:      102b:      68 20 30 40 00  pushl   $4206624
+DISASM-NEXT: 1030:      68 00 20 40 00  pushl   $4202496
+DISASM-NEXT: 1035:      e8 c6 ff ff ff  calll   -58 <.text>
+DISASM-NEXT: 103a:      5a      popl    %edx
+DISASM-NEXT: 103b:      59      popl    %ecx
+DISASM-NEXT: 103c:      ff e0   jmpl    *%eax
+DISASM-NEXT: 103e:      51      pushl   %ecx
+DISASM-NEXT: 103f:      52      pushl   %edx
+DISASM-NEXT: 1040:      68 24 30 40 00  pushl   $4206628
+DISASM-NEXT: 1045:      68 00 20 40 00  pushl   $4202496
+DISASM-NEXT: 104a:      e8 b1 ff ff ff  calll   -79 <.text>
+DISASM-NEXT: 104f:      5a      popl    %edx
+DISASM-NEXT: 1050:      59      popl    %ecx
+DISASM-NEXT: 1051:      ff e0   jmpl    *%eax
diff --git a/test/COFF/export-armnt.yaml b/test/COFF/export-armnt.yaml
index 367dabf..88d198c 100644
--- a/test/COFF/export-armnt.yaml
+++ b/test/COFF/export-armnt.yaml
@@ -9,10 +9,10 @@
 # CHECK:      DLL name: export-armnt.yaml.tmp.dll
 # CHECK:      Ordinal      RVA  Name
 # CHECK-NEXT:       0        0
-# CHECK-NEXT:       1   0x1000  exportdata
-# CHECK-NEXT:       2   0x2005  exportfn1
-# CHECK-NEXT:       3   0x2009  exportfn2
-# CHECK-NEXT:       4   0x2009  exportfn3
+# CHECK-NEXT:       1   0x3000  exportdata
+# CHECK-NEXT:       2   0x1005  exportfn1
+# CHECK-NEXT:       3   0x1009  exportfn2
+# CHECK-NEXT:       4   0x1009  exportfn3
 
 --- !COFF
 header:
diff --git a/test/COFF/export.test b/test/COFF/export.test
index 174f4ac..a00a29c 100644
--- a/test/COFF/export.test
+++ b/test/COFF/export.test
@@ -86,6 +86,10 @@
 # RUN: lld-link /out:%t.dll /dll %t.obj /export:foo=kernel32.foobar
 # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=FORWARDER %s
 
+# RUN: echo "EXPORTS foo=kernel32.foobar" > %t.def
+# RUN: lld-link /out:%t.dll /dll %t.obj /def:%t.def
+# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=FORWARDER %s
+
 FORWARDER: Export Table:
 FORWARDER:  DLL name: export.test.tmp.dll
 FORWARDER:  Ordinal base: 0
diff --git a/test/COFF/export32.test b/test/COFF/export32.test
index 34cd1a7..9218ac2 100644
--- a/test/COFF/export32.test
+++ b/test/COFF/export32.test
@@ -2,6 +2,10 @@
 #
 # RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2
 # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK1 %s
+#
+# RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 /merge:.edata=.rdata
+# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK1 %s
+# RUN: llvm-readobj -file-headers -sections %t.dll | FileCheck -check-prefix=HEADER-MERGE %s
 
 # CHECK1:      Export Table:
 # CHECK1:      DLL name: export32.test.tmp.dll
@@ -10,6 +14,12 @@
 # CHECK1-NEXT:       1   0x1008  exportfn1
 # CHECK1-NEXT:       2   0x1010  exportfn2
 
+# HEADER-MERGE: ExportTableRVA: 0x2000
+# HEADER-MERGE-NEXT: ExportTableSize: 0x7E
+# HEADER-MERGE: Name: .rdata
+# HEADER-MERGE-NEXT: VirtualSize: 0x7E
+# HEADER-MERGE-NEXT: VirtualAddress: 0x2000
+
 # RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1,@5 \
 # RUN:   /export:exportfn2 /export:mangled
 # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK2 %s
diff --git a/test/COFF/filename-casing.s b/test/COFF/filename-casing.s
index e210aea..0834c03 100644
--- a/test/COFF/filename-casing.s
+++ b/test/COFF/filename-casing.s
@@ -6,8 +6,10 @@
 # RUN: llvm-lib /out:%T/MixedCase.lib %T/MixedCase.obj
 # RUN: not lld-link /machine:x64 /entry:main %T/MixedCase.lib 2>&1 | FileCheck -check-prefix=ARCHIVE %s
 
-# OBJECT: MixedCase.obj: undefined symbol: f
-# ARCHIVE: MixedCase.lib(MixedCase.obj): undefined symbol: f
+# OBJECT: undefined symbol: f
+# OBJECT-NEXT: >>> referenced by {{.*}}MixedCase.obj:(main)
+# ARCHIVE: undefined symbol: f
+# ARCHIVE-NEXT: >>> referenced by {{.*}}MixedCase.lib(MixedCase.obj):(main)
 
 .globl main
 main:
diff --git a/test/COFF/force.test b/test/COFF/force.test
index b96c1f8..20c4e1a 100644
--- a/test/COFF/force.test
+++ b/test/COFF/force.test
@@ -4,8 +4,10 @@
 # RUN: lld-link /out:%t.exe /entry:main %t.obj /force >& %t.log
 # RUN: FileCheck -check-prefix=WARN %s < %t.log
 
-# ERROR: error: {{.*}}.obj: undefined symbol: foo
-# WARN: warning: {{.*}}.obj: undefined symbol: foo
+# ERROR: error: undefined symbol: foo
+# ERROR-NEXT: >>> referenced by {{.*}}.obj
+# WARN: warning: undefined symbol: foo
+# WARN-NEXT: >>> referenced by {{.*}}.obj
 
 --- !COFF
 header:
diff --git a/test/COFF/gfids-gc.s b/test/COFF/gfids-gc.s
index 1e2e72a..1ae348c 100644
--- a/test/COFF/gfids-gc.s
+++ b/test/COFF/gfids-gc.s
@@ -1,6 +1,8 @@
 # RUN: llvm-mc -triple x86_64-windows-msvc %s -filetype=obj -o %t.obj
 # RUN: lld-link %t.obj -guard:nolongjmp -out:%t.exe -opt:noref -entry:main
 # RUN: llvm-readobj -file-headers -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-NOGC
+# RUN: lld-link %t.obj -guard:nolongjmp -out:%t.exe -opt:noref -entry:main -debug:dwarf
+# RUN: llvm-readobj -file-headers -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-NOGC
 # RUN: lld-link %t.obj -guard:nolongjmp -out:%t.exe -opt:ref -entry:main
 # RUN: llvm-readobj -file-headers -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-GC
 
diff --git a/test/COFF/hello32.test b/test/COFF/hello32.test
index 9f3cadc..87c5879 100644
--- a/test/COFF/hello32.test
+++ b/test/COFF/hello32.test
@@ -27,8 +27,8 @@
 HEADER-NEXT:   SizeOfCode: 512
 HEADER-NEXT:   SizeOfInitializedData: 1536
 HEADER-NEXT:   SizeOfUninitializedData: 0
-HEADER-NEXT:   AddressOfEntryPoint: 0x2000
-HEADER-NEXT:   BaseOfCode: 0x2000
+HEADER-NEXT:   AddressOfEntryPoint: 0x1000
+HEADER-NEXT:   BaseOfCode: 0x1000
 HEADER-NEXT:   BaseOfData: 0x0
 HEADER-NEXT:   ImageBase: 0x400000
 HEADER-NEXT:   SectionAlignment: 4096
@@ -57,7 +57,7 @@
 HEADER-NEXT:   DataDirectory {
 HEADER-NEXT:     ExportTableRVA: 0x0
 HEADER-NEXT:     ExportTableSize: 0x0
-HEADER-NEXT:     ImportTableRVA: 0x3000
+HEADER-NEXT:     ImportTableRVA: 0x2000
 HEADER-NEXT:     ImportTableSize: 0x28
 HEADER-NEXT:     ResourceTableRVA: 0x0
 HEADER-NEXT:     ResourceTableSize: 0x0
@@ -79,7 +79,7 @@
 HEADER-NEXT:     LoadConfigTableSize: 0x0
 HEADER-NEXT:     BoundImportRVA: 0x0
 HEADER-NEXT:     BoundImportSize: 0x0
-HEADER-NEXT:     IATRVA: 0x3034
+HEADER-NEXT:     IATRVA: 0x2034
 HEADER-NEXT:     IATSize: 0xC
 HEADER-NEXT:     DelayImportDescriptorRVA: 0x0
 HEADER-NEXT:     DelayImportDescriptorSize: 0x0
@@ -114,8 +114,8 @@
 IMPORTS: AddressSize: 32bit
 IMPORTS: Import {
 IMPORTS:   Name: std32.dll
-IMPORTS:   ImportLookupTableRVA: 0x3028
-IMPORTS:   ImportAddressTableRVA: 0x3034
+IMPORTS:   ImportLookupTableRVA: 0x2028
+IMPORTS:   ImportAddressTableRVA: 0x2034
 IMPORTS:   Symbol: ExitProcess (0)
 IMPORTS:   Symbol: MessageBoxA (1)
 IMPORTS: }
@@ -123,10 +123,10 @@
 BASEREL: BaseReloc [
 BASEREL:   Entry {
 BASEREL:     Type: HIGHLOW
-BASEREL:     Address: 0x2005
+BASEREL:     Address: 0x1005
 BASEREL:   }
 BASEREL:   Entry {
 BASEREL:     Type: HIGHLOW
-BASEREL:     Address: 0x200C
+BASEREL:     Address: 0x100C
 BASEREL:   }
 BASEREL: ]
diff --git a/test/COFF/icf-different-align.test b/test/COFF/icf-different-align.test
index 3502ed3..0e2fce9 100644
--- a/test/COFF/icf-different-align.test
+++ b/test/COFF/icf-different-align.test
@@ -2,9 +2,14 @@
 # RUN: lld-link /entry:foo /out:%t.exe /subsystem:console /include:bar \
 # RUN:   /verbose %t.obj > %t.log 2>&1
 # RUN: FileCheck %s < %t.log
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=OBJDUMP %s
 
-# CHECK-NOT: Selected foo
-# CHECK-NOT:   Removed bar
+# CHECK: Selected foo
+# CHECK:   Removed bar
+
+# OBJDUMP: Contents of section .text:
+# OBJDUMP-NEXT: 140001000 00cccccc cccccccc cccccccc cccccccc
+# OBJDUMP-NEXT: 140001010 4883ec28 e8000000 004883c4 28c3
 
 --- !COFF
 header:
@@ -19,6 +24,10 @@
     Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
     Alignment:       16
     SectionData:     4883EC28E8000000004883C428C3
+  - Name:            '.text'
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    SectionData:     00
 symbols:
   - Name:            '.text$mn'
     Value:           0
diff --git a/test/COFF/icf-pdata.s b/test/COFF/icf-pdata.s
new file mode 100644
index 0000000..ebd8479
--- /dev/null
+++ b/test/COFF/icf-pdata.s
@@ -0,0 +1,97 @@
+# RUN: llvm-mc %s -triple x86_64-windows-msvc -filetype=obj -o %t.obj
+# RUN: lld-link %t.obj -dll -noentry -out:%t.dll -merge:.xdata=.xdata
+# RUN: llvm-readobj -sections -coff-exports %t.dll | FileCheck %s
+
+# CHECK:         Name: .pdata
+# CHECK-NEXT:    VirtualSize: 0x18
+# CHECK:         Name: .xdata
+# CHECK-NEXT:    VirtualSize: 0x10
+
+# CHECK:         Name: xdata1
+# CHECK-NEXT:    RVA: 0x1010
+# CHECK:         Name: xdata1a
+# CHECK-NEXT:    RVA: 0x1010
+# CHECK:         Name: xdata1b
+# CHECK-NEXT:    RVA: 0x1030
+
+	.text
+callee:
+	ret
+
+	.def	 xdata1;
+	.scl	2;
+	.type	32;
+	.endef
+	.section	.text,"xr",one_only,xdata1
+	.globl	xdata1                  # -- Begin function xdata1
+	.p2align	4, 0x90
+xdata1:                                 # @xdata1
+.seh_proc xdata1
+# BB#0:                                 # %entry
+	subq	$40, %rsp
+	.seh_stackalloc 40
+	.seh_endprologue
+	callq	callee
+	nop
+	addq	$40, %rsp
+	jmp	callee                  # TAILCALL
+	.seh_handlerdata
+	.section	.text,"xr",one_only,xdata1
+	.seh_endproc
+                                        # -- End function
+
+# xdata1a is identical to xdata1, so it should be ICFd, and so should its pdata.
+# It also has associative debug and CFG sections which should be ignored by ICF.
+	.def	 xdata1a;
+	.scl	2;
+	.type	32;
+	.endef
+	.section	.text,"xr",one_only,xdata1a
+	.globl	xdata1a                  # -- Begin function xdata1a
+	.p2align	4, 0x90
+xdata1a:                                 # @xdata1a
+.seh_proc xdata1a
+# BB#0:                                 # %entry
+	subq	$40, %rsp
+	.seh_stackalloc 40
+	.seh_endprologue
+	callq	callee
+	nop
+	addq	$40, %rsp
+	jmp	callee                  # TAILCALL
+	.seh_handlerdata
+	.section	.text,"xr",one_only,xdata1a
+	.seh_endproc
+
+	.section .debug$S,"r",associative,xdata1a
+	.section .gfids$y,"r",associative,xdata1a
+	.section .gljmp$y,"r",associative,xdata1a
+
+# xdata1b's text is identical to xdata1, but its xdata specifies a different
+# stack size, so it cannot be ICFd with xdata1.
+	.def	 xdata1b;
+	.scl	2;
+	.type	32;
+	.endef
+	.section	.text,"xr",one_only,xdata1b
+	.globl	xdata1b                  # -- Begin function xdata1b
+	.p2align	4, 0x90
+xdata1b:                                 # @xdata1b
+.seh_proc xdata1b
+# BB#0:                                 # %entry
+	subq	$40, %rsp
+	.seh_stackalloc 48
+	.seh_endprologue
+	callq	callee
+	nop
+	addq	$40, %rsp
+	jmp	callee                  # TAILCALL
+	.seh_handlerdata
+	.section	.text,"xr",one_only,xdata1b
+	.seh_endproc
+                                        # -- End function
+
+	.section	.drectve,"yn"
+	.ascii	" -export:xdata1"
+	.ascii	" -export:xdata1a"
+	.ascii	" -export:xdata1b"
diff --git a/test/COFF/icf-vtables.s b/test/COFF/icf-vtables.s
new file mode 100644
index 0000000..6500247
--- /dev/null
+++ b/test/COFF/icf-vtables.s
@@ -0,0 +1,28 @@
+# REQUIRES: x86
+# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s
+# RUN: lld-link %t.obj /out:%t.exe /entry:main /subsystem:console
+# RUN: llvm-objdump -s %t.exe | FileCheck %s
+
+# CHECK: Contents of section .text:
+.globl main
+main:
+# CHECK-NEXT: 140001000 00200040 01000000 01200040 01000000
+.8byte "??_"
+.8byte "??_7"
+# CHECK-NEXT: 140001010 01200040 01000000
+.8byte "??_7a"
+
+.section .rdata,"dr",discard,"??_"
+.globl "??_"
+"??_":
+.byte 42
+
+.section .rdata,"dr",discard,"??_7"
+.globl "??_7"
+"??_7":
+.byte 42
+
+.section .rdata,"dr",discard,"??_7a"
+.globl "??_7a"
+"??_7a":
+.byte 42
diff --git a/test/COFF/icf-xdata.s b/test/COFF/icf-xdata.s
index 8fb4bad..ec7f625 100644
--- a/test/COFF/icf-xdata.s
+++ b/test/COFF/icf-xdata.s
@@ -1,13 +1,25 @@
 # RUN: llvm-mc %s -triple x86_64-windows-msvc -filetype=obj -o %t.obj
+# RUN: lld-link %t.obj -dll -noentry -out:%t.dll -merge:.xdata=.xdata 2>&1 \
+# RUN:     | FileCheck %s --check-prefix=WARN
+# RUN: llvm-readobj -sections %t.dll | FileCheck %s --check-prefix=XDATA
 # RUN: lld-link %t.obj -dll -noentry -out:%t.dll
-# RUN: llvm-readobj -sections %t.dll | FileCheck %s
+# RUN: llvm-readobj -sections %t.dll | FileCheck %s --check-prefix=RDATA
 
 # There shouldn't be much xdata, because all three .pdata entries (12 bytes
 # each) should use the same .xdata unwind info.
-# CHECK:         Name: .pdata
-# CHECK-NEXT:    VirtualSize: 0x24
-# CHECK:         Name: .xdata
-# CHECK-NEXT:    VirtualSize: 0x8
+# XDATA:         Name: .rdata
+# XDATA-NEXT:    VirtualSize: 0x73
+# XDATA:         Name: .pdata
+# XDATA-NEXT:    VirtualSize: 0x24
+# XDATA:         Name: .xdata
+# XDATA-NEXT:    VirtualSize: 0x8
+#
+# WARN: warning: .xdata=.rdata: already merged into .xdata
+#
+# RDATA:         Name: .rdata
+# RDATA-NEXT:    VirtualSize: 0x7C
+# RDATA:         Name: .pdata
+# RDATA-NEXT:    VirtualSize: 0x24
 
 	.text
 callee:
diff --git a/test/COFF/imports.test b/test/COFF/imports.test
index 326bfbe..64f3900 100644
--- a/test/COFF/imports.test
+++ b/test/COFF/imports.test
@@ -15,8 +15,8 @@
 TEXT-NEXT: .text:
 TEXT-NEXT: subq    $40, %rsp
 TEXT-NEXT: movq    $0, %rcx
-TEXT-NEXT: leaq    -4108(%rip), %rdx
-TEXT-NEXT: leaq    -4121(%rip), %r8
+TEXT-NEXT: leaq    8180(%rip), %rdx
+TEXT-NEXT: leaq    8167(%rip), %r8
 TEXT-NEXT: movl    $0, %r9d
 TEXT-NEXT: callq   60
 TEXT-NEXT: movl    $0, %ecx
@@ -28,8 +28,8 @@
 
 IMPORT:      Import {
 IMPORT-NEXT:   Name: std64.dll
-IMPORT-NEXT:   ImportLookupTableRVA: 0x3028
-IMPORT-NEXT:   ImportAddressTableRVA: 0x3048
+IMPORT-NEXT:   ImportLookupTableRVA: 0x2028
+IMPORT-NEXT:   ImportAddressTableRVA: 0x2048
 IMPORT-NEXT:   Symbol: ExitProcess (0)
 IMPORT-NEXT:   Symbol:  (50)
 IMPORT-NEXT:   Symbol: MessageBoxA (1)
diff --git a/test/COFF/loadcfg.ll b/test/COFF/loadcfg.ll
index c49ae2f..139ec74 100644
--- a/test/COFF/loadcfg.ll
+++ b/test/COFF/loadcfg.ll
@@ -2,7 +2,7 @@
 ; RUN: lld-link /out:%t.exe %t.obj /entry:main /subsystem:console
 ; RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
 
-; CHECK: LoadConfigTableRVA: 0x1000
+; CHECK: LoadConfigTableRVA: 0x2000
 ; CHECK: LoadConfigTableSize: 0x70
 
 target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/test/COFF/loadcfg.test b/test/COFF/loadcfg.test
index 072ee6b..2e226f4 100644
--- a/test/COFF/loadcfg.test
+++ b/test/COFF/loadcfg.test
@@ -2,7 +2,7 @@
 # RUN: lld-link /out:%t.exe %t.obj /entry:main /subsystem:console
 # RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
 
-# CHECK: LoadConfigTableRVA: 0x1000
+# CHECK: LoadConfigTableRVA: 0x2000
 # CHECK: LoadConfigTableSize: 0x70
 
 --- !COFF
diff --git a/test/COFF/loadcfg32.test b/test/COFF/loadcfg32.test
index 03a066c..9485aa0 100644
--- a/test/COFF/loadcfg32.test
+++ b/test/COFF/loadcfg32.test
@@ -2,7 +2,7 @@
 # RUN: lld-link /out:%t.exe %t.obj /entry:main /subsystem:console
 # RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
 
-# CHECK: LoadConfigTableRVA: 0x1000
+# CHECK: LoadConfigTableRVA: 0x2000
 # CHECK: LoadConfigTableSize: 0x40
 
 --- !COFF
diff --git a/test/COFF/lto-comdat.ll b/test/COFF/lto-comdat.ll
index 9594d30..9ff3776 100644
--- a/test/COFF/lto-comdat.ll
+++ b/test/COFF/lto-comdat.ll
@@ -45,7 +45,7 @@
 ; TEXT-11-NEXT: xorl	%eax, %eax
 ; TEXT-11-NEXT: retq
 
-; HEADERS-01: AddressOfEntryPoint: 0x2000
+; HEADERS-01: AddressOfEntryPoint: 0x1000
 ; TEXT-01: Disassembly of section .text:
 ; TEXT-01-NEXT: .text:
 ; TEXT-01-NEXT: subq	$40, %rsp
@@ -62,7 +62,7 @@
 ; TEXT-01: int3
 ; TEXT-01-NOT: {{.}}
 
-; HEADERS-10: AddressOfEntryPoint: 0x2020
+; HEADERS-10: AddressOfEntryPoint: 0x1020
 ; TEXT-10: Disassembly of section .text:
 ; TEXT-10-NEXT: .text:
 ; TEXT-10-NEXT: subq	$40, %rsp
diff --git a/test/COFF/lto.ll b/test/COFF/lto.ll
index 587ca5d..4e16c9b 100644
--- a/test/COFF/lto.ll
+++ b/test/COFF/lto.ll
@@ -52,7 +52,7 @@
 ; TEXT-11-NEXT: movl	$2, %eax
 ; TEXT-11-NEXT: retq
 
-; HEADERS-01: AddressOfEntryPoint: 0x2000
+; HEADERS-01: AddressOfEntryPoint: 0x1000
 ; TEXT-01: Disassembly of section .text:
 ; TEXT-01-NEXT: .text:
 ; TEXT-01-NEXT: subq	$40, %rsp
@@ -78,7 +78,7 @@
 ; TEXT-01-NEXT: int3
 ; TEXT-01-NEXT: retq
 
-; HEADERS-10: AddressOfEntryPoint: 0x2020
+; HEADERS-10: AddressOfEntryPoint: 0x1020
 ; TEXT-10: Disassembly of section .text:
 ; TEXT-10-NEXT: .text:
 ; TEXT-10-NEXT: retq
diff --git a/test/COFF/manifestinput-error.test b/test/COFF/manifestinput-error.test
index eca7d0d..22ddc67 100644
--- a/test/COFF/manifestinput-error.test
+++ b/test/COFF/manifestinput-error.test
@@ -7,4 +7,4 @@
 # RUN:   /manifestuac:"level='requireAdministrator'" \
 # RUN:   /manifestinput:%p/Inputs/manifestinput.test %t.obj 2>&1 | FileCheck %s
 
-# CHECK: error: unable to find mt.exe in PATH: No such file or directory
+# CHECK: error: unable to find mt.exe in PATH: {{[Nn]}}o such file or directory
diff --git a/test/COFF/manifestinput.test b/test/COFF/manifestinput.test
index 51c1890..33f14d8 100644
--- a/test/COFF/manifestinput.test
+++ b/test/COFF/manifestinput.test
@@ -8,8 +8,8 @@
 # RUN: llvm-readobj -coff-resources -file-headers %t.exe | FileCheck %s \
 # RUN:   -check-prefix TEST_EMBED
 
-TEST_EMBED:          ResourceTableRVA: 0x1000
-TEST_EMBED-NEXT:     ResourceTableSize: 0x298
+TEST_EMBED:          ResourceTableRVA: 0x2000
+TEST_EMBED-NEXT:     ResourceTableSize: 0x2A0
 TEST_EMBED-DAG:      Resources [
 TEST_EMBED-NEXT:       Total Number of Resources: 1
 TEST_EMBED-DAG:        Number of String Entries: 0
diff --git a/test/COFF/merge.test b/test/COFF/merge.test
index 4b5c100..10a5672 100644
--- a/test/COFF/merge.test
+++ b/test/COFF/merge.test
@@ -3,9 +3,35 @@
 # RUN:   /merge:.foo=.abc /merge:.bar=.def %t.obj /debug
 # RUN: llvm-readobj -sections %t.exe | FileCheck %s
 
+# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /force \
+# RUN:   /merge:.foo=.bar /merge:.bar=.abc %t.obj /debug
+# RUN: llvm-readobj -sections %t.exe | FileCheck --check-prefix=CHECK2 %s
+
+# RUN: not lld-link /out:%t.exe /entry:main /subsystem:console /force \
+# RUN:   /merge:.rsrc=.foo %t.obj /debug 2>&1 | FileCheck --check-prefix=NO-RSRC %s
+# RUN: not lld-link /out:%t.exe /entry:main /subsystem:console /force \
+# RUN:   /merge:.foo=.rsrc %t.obj /debug 2>&1 | FileCheck --check-prefix=NO-RSRC %s
+# RUN: not lld-link /out:%t.exe /entry:main /subsystem:console /force \
+# RUN:   /merge:.reloc=.foo %t.obj /debug 2>&1 | FileCheck --check-prefix=NO-RELOC %s
+# RUN: not lld-link /out:%t.exe /entry:main /subsystem:console /force \
+# RUN:   /merge:.foo=.reloc %t.obj /debug 2>&1 | FileCheck --check-prefix=NO-RELOC %s
+# RUN: not lld-link /out:%t.exe /entry:main /subsystem:console /force \
+# RUN:   /merge:.foo=.foo1 /merge:.foo1=.foo %t.obj /debug 2>&1 | FileCheck --check-prefix=NO-CYCLE %s
+# RUN: not lld-link /out:%t.exe /entry:main /subsystem:console /force \
+# RUN:   /merge:.foo=.foo1 /merge:.foo1=.foo2 /merge:.foo2=.foo1 %t.obj /debug 2>&1 | FileCheck --check-prefix=NO-CYCLE %s
+
 # CHECK: Name: .def
 # CHECK: Name: .abc
 
+# CHECK2-NOT: Name: .bar
+# CHECK2: Name: .abc
+# CHECK2-NOT: Name: .bar
+
+# NO-RSRC: /merge: cannot merge '.rsrc' with any section
+# NO-RELOC: /merge: cannot merge '.reloc' with any section
+
+# NO-CYCLE: /merge: cycle found for section '.foo'
+
 --- !COFF
 header:
   Machine:         IMAGE_FILE_MACHINE_AMD64
diff --git a/test/COFF/nodefaultlib.test b/test/COFF/nodefaultlib.test
index c0f8d50..8f4da3a 100644
--- a/test/COFF/nodefaultlib.test
+++ b/test/COFF/nodefaultlib.test
@@ -21,7 +21,8 @@
 
 CHECK1: error: could not open hello64.obj: {{[Nn]}}o such file or directory
 CHECK2: error: could not open hello64: {{[Nn]}}o such file or directory
-CHECK3: error: {{.*}}hello64.obj: undefined symbol: MessageBoxA
+CHECK3: error: undefined symbol: MessageBoxA
+CHECK3-NEXT: >>> referenced by {{.*}}hello64.obj:(main)
 
 # RUN: lld-link /libpath:%T /out:%t.exe /entry:main \
 # RUN:   /subsystem:console hello64.obj /defaultlib:std64.lib
diff --git a/test/COFF/options.test b/test/COFF/options.test
index 39f944b..6b9f2ca 100644
--- a/test/COFF/options.test
+++ b/test/COFF/options.test
@@ -30,6 +30,16 @@
 # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOENT %s
 NOENT-NOT: IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA
 
+# RUN: lld-link /out:%t.exe /entry:main /integritycheck %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=INT %s
+INT: IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY
+
+# RUN: lld-link /out:%t.exe /entry:main %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOINT %s
+# RUN: lld-link /out:%t.exe /integritycheck:no /out:%t.exe /entry:main %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOINT %s
+NOINT-NOT: IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY
+
 # RUN: lld-link /out:%t.exe /entry:main %t.obj
 # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NXCOMPAT %s
 # RUN: lld-link /out:%t.exe /entry:main /nxcompat %t.obj
@@ -48,4 +58,8 @@
 
 # RUN: lld-link /tsaware:no /out:%t.exe /entry:main %t.obj
 # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOTSAWARE %s
+# RUN: lld-link /dll /out:%t.dll /entry:main %t.obj
+# RUN: llvm-readobj -file-headers %t.dll | FileCheck -check-prefix=NOTSAWARE %s
+# RUN: lld-link /tsaware /dll /out:%t.dll /entry:main %t.obj
+# RUN: llvm-readobj -file-headers %t.dll | FileCheck -check-prefix=NOTSAWARE %s
 NOTSAWARE-NOT: IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE
diff --git a/test/COFF/output-chars.test b/test/COFF/output-chars.test
new file mode 100644
index 0000000..2ccb084
--- /dev/null
+++ b/test/COFF/output-chars.test
@@ -0,0 +1,109 @@
+# RUN: yaml2obj %s > %t.obj
+# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj
+# RUN: llvm-readobj -sections %t.dll | FileCheck %s
+# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj /section:.foo,rwe
+# RUN: llvm-readobj -sections %t.dll | FileCheck --check-prefix=SECTION %s
+# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj /merge:.foo=.bar
+# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck --check-prefix=MERGE %s
+# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj /merge:.foo=.bar /section:.foo,rwe
+# RUN: llvm-readobj -sections %t.dll | FileCheck --check-prefix=MERGE-SECTION %s
+
+# CHECK: Name: .foo
+# CHECK: Characteristics [
+# CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
+# CHECK-NEXT: IMAGE_SCN_MEM_READ
+# CHECK-NEXT: ]
+
+# CHECK: Name: .foo
+# CHECK: Characteristics [
+# CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
+# CHECK-NEXT: IMAGE_SCN_MEM_READ
+# CHECK-NEXT: IMAGE_SCN_MEM_WRITE
+# CHECK-NEXT: ]
+
+# SECTION: Name: .foo
+# SECTION: Characteristics [
+# SECTION-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
+# SECTION-NEXT: IMAGE_SCN_MEM_EXECUTE
+# SECTION-NEXT: IMAGE_SCN_MEM_READ
+# SECTION-NEXT: IMAGE_SCN_MEM_WRITE
+# SECTION-NEXT: ]
+
+# SECTION: Name: .foo
+# SECTION: Characteristics [
+# SECTION-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
+# SECTION-NEXT: IMAGE_SCN_MEM_EXECUTE
+# SECTION-NEXT: IMAGE_SCN_MEM_READ
+# SECTION-NEXT: IMAGE_SCN_MEM_WRITE
+# SECTION-NEXT: ]
+
+# MERGE: Name: .bar
+# MERGE: Characteristics [
+# MERGE-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
+# MERGE-NEXT: IMAGE_SCN_MEM_READ
+# MERGE-NEXT: ]
+# MERGE-NEXT: SectionData (
+# MERGE-NEXT: 0000: 0301
+
+# MERGE: Name: .bar
+# MERGE: Characteristics [
+# MERGE-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
+# MERGE-NEXT: IMAGE_SCN_MEM_READ
+# MERGE-NEXT: IMAGE_SCN_MEM_WRITE
+# MERGE-NEXT: ]
+# MERGE-NEXT: SectionData (
+# MERGE-NEXT: 0000: 04
+
+# MERGE: Name: .foo
+# MERGE: Characteristics [
+# MERGE-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
+# MERGE-NEXT: IMAGE_SCN_MEM_READ
+# MERGE-NEXT: IMAGE_SCN_MEM_WRITE
+# MERGE-NEXT: ]
+# MERGE-NEXT: SectionData (
+# MERGE-NEXT: 0000: 02
+
+# MERGE-SECTION: Name: .bar
+# MERGE-SECTION: Characteristics [
+# MERGE-SECTION-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
+# MERGE-SECTION-NEXT: IMAGE_SCN_MEM_READ
+# MERGE-SECTION-NEXT: ]
+
+# MERGE-SECTION: Name: .bar
+# MERGE-SECTION: Characteristics [
+# MERGE-SECTION-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
+# MERGE-SECTION-NEXT: IMAGE_SCN_MEM_READ
+# MERGE-SECTION-NEXT: IMAGE_SCN_MEM_WRITE
+# MERGE-SECTION-NEXT: ]
+
+# MERGE-SECTION: Name: .foo
+# MERGE-SECTION: Characteristics [
+# MERGE-SECTION-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
+# MERGE-SECTION-NEXT: IMAGE_SCN_MEM_EXECUTE
+# MERGE-SECTION-NEXT: IMAGE_SCN_MEM_READ
+# MERGE-SECTION-NEXT: IMAGE_SCN_MEM_WRITE
+# MERGE-SECTION-NEXT: ]
+
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [  ]
+sections:
+  - Name:            .foo
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    SectionData:     01
+  - Name:            .foo
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       1
+    SectionData:     02
+  - Name:            .bar
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    SectionData:     03
+  - Name:            .bar
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       1
+    SectionData:     04
+symbols:
+...
diff --git a/test/COFF/pdata-arm64.yaml b/test/COFF/pdata-arm64.yaml
index f21749b..4f5210c 100644
--- a/test/COFF/pdata-arm64.yaml
+++ b/test/COFF/pdata-arm64.yaml
@@ -3,7 +3,7 @@
 # RUN: lld-link /out:%t.exe /entry:func1 /subsystem:console %t.obj
 # RUN: llvm-objdump -s -section=.pdata %t.exe | FileCheck -check-prefix=PDATA %s
 
-# PDATA: 00200000 2500a100 24200000 31002201
+# PDATA: 00100000 2500a100 24100000 31002201
 
 --- !COFF
 header:
diff --git a/test/COFF/pdb-comdat.test b/test/COFF/pdb-comdat.test
index 655f215..1659f98 100644
--- a/test/COFF/pdb-comdat.test
+++ b/test/COFF/pdb-comdat.test
@@ -61,7 +61,7 @@
 CHECK:         frontend = 19.0.24215.1, backend = 19.0.24215.1
 CHECK:         flags = security checks | hot patchable
 CHECK:   120 | S_GPROC32 [size = 44] `main`
-CHECK:         parent = 0, end = 196, addr = 0002:0000, code size = 24
+CHECK:         parent = 0, end = 196, addr = 0001:0000, code size = 24
 CHECK:         debug start = 4, debug end = 19, flags = none
 CHECK:   164 | S_FRAMEPROC [size = 32]
 CHECK:         size = 40, padding size = 0, offset to padding = 0
@@ -70,7 +70,7 @@
 CHECK:   196 | S_END [size = 4]
 CHECK:   200 | S_BUILDINFO [size = 8] BuildId = `0x100A`
 CHECK:   208 | S_GPROC32 [size = 44] `foo`
-CHECK:         parent = 0, end = 284, addr = 0002:0032, code size = 15
+CHECK:         parent = 0, end = 284, addr = 0001:0032, code size = 15
 CHECK:         debug start = 0, debug end = 14, flags = none
 CHECK:   252 | S_FRAMEPROC [size = 32]
 CHECK:         size = 0, padding size = 0, offset to padding = 0
@@ -84,7 +84,7 @@
 CHECK:       frontend = 19.0.24215.1, backend = 19.0.24215.1
 CHECK:       flags = security checks | hot patchable
 CHECK:   120 | S_GPROC32 [size = 44] `bar`
-CHECK:       parent = 0, end = 196, addr = 0002:0048, code size = 14
+CHECK:       parent = 0, end = 196, addr = 0001:0048, code size = 14
 CHECK:       debug start = 4, debug end = 9, flags = none
 CHECK:   164 | S_FRAMEPROC [size = 32]
 CHECK:       size = 40, padding size = 0, offset to padding = 0
diff --git a/test/COFF/pdb-global-hashes.test b/test/COFF/pdb-global-hashes.test
index b47e438..238613c 100644
--- a/test/COFF/pdb-global-hashes.test
+++ b/test/COFF/pdb-global-hashes.test
@@ -83,7 +83,7 @@
 CHECK-NEXT:   Showing 6 records
 CHECK-NEXT:   0x1000 | LF_FUNC_ID [size = 20]
 CHECK-NEXT:            name = main, type = 0x1002, parent scope = <no type>
-CHECK-NEXT:   0x1001 | LF_STRING_ID [size = 48] ID: <no type>, String: D:\src\llvmbuild\clang\Debug\x86\obj.h
+CHECK-NEXT:   0x1001 | LF_STRING_ID [size = {{.*}}] ID: <no type>, String: {{.*}}obj.h
 CHECK-NEXT:   0x1002 | LF_UDT_SRC_LINE [size = 16]
 CHECK-NEXT:            udt = 0x1008, file = 4097, line = 2
 CHECK-NEXT:   0x1003 | LF_MFUNC_ID [size = 16]
diff --git a/test/COFF/pdb-globals.test b/test/COFF/pdb-globals.test
index b5e4f49..3eee76a 100644
--- a/test/COFF/pdb-globals.test
+++ b/test/COFF/pdb-globals.test
@@ -24,9 +24,9 @@
 CHECK-NEXT:      312 | S_PROCREF [size = 40] `HelloPoint::HelloPoint`
 CHECK-NEXT:            module = 1, sum name = 0, offset = 376
 CHECK-NEXT:      232 | S_GDATA32 [size = 28] `__purecall`
-CHECK-NEXT:            type = 0x0403 (void*), addr = 0000:0000
+CHECK-NEXT:            type = 0x0403 (void*), addr = 0003:0004
 CHECK-NEXT:      260 | S_GDATA32 [size = 24] `GlobalVar`
-CHECK-NEXT:            type = 0x100B (const int*), addr = 0001:0000
+CHECK-NEXT:            type = 0x100B (const int*), addr = 0003:0000
 CHECK-NEXT:      284 | S_LDATA32 [size = 28] `ConstantVar`
 CHECK-NEXT:            type = 0x100A (const int), addr = 0002:0000
 
diff --git a/test/COFF/pdb-heapsite.yaml b/test/COFF/pdb-heapsite.yaml
index 966ae42..bfdd7b4 100644
--- a/test/COFF/pdb-heapsite.yaml
+++ b/test/COFF/pdb-heapsite.yaml
@@ -69,7 +69,7 @@
             RegRelativeSym:
               Offset:          8
               Type:            35
-              Register:        RSP
+              Register:        CVRegRSP
               VarName:         __formal
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
diff --git a/test/COFF/pdb-procid-remapping.test b/test/COFF/pdb-procid-remapping.test
index cb61240..e42616d 100644
--- a/test/COFF/pdb-procid-remapping.test
+++ b/test/COFF/pdb-procid-remapping.test
@@ -9,7 +9,7 @@
 CHECK-NEXT: ============================================================
 CHECK-LABEL:    Mod 0000 |
 CHECK:                92 | S_GPROC32 [size = 44] `main`
-CHECK-NEXT:                parent = 0, end = 168, addr = 0002:0000, code size = 14
+CHECK-NEXT:                parent = 0, end = 168, addr = 0001:0000, code size = 14
 CHECK-NEXT:                type = `0x1004 (int (<no type>))`, debug start = 4, debug end = 9, flags = none
 CHECK-NEXT:          136 | S_FRAMEPROC [size = 32]
 CHECK-NEXT:                size = 40, padding size = 0, offset to padding = 0
@@ -18,7 +18,7 @@
 CHECK-NEXT:          168 | S_END [size = 4]
 CHECK-LABEL:    Mod 0001 |
 CHECK:                92 | S_GPROC32 [size = 44] `foo`
-CHECK-NEXT:                parent = 0, end = 168, addr = 0002:0016, code size = 6
+CHECK-NEXT:                parent = 0, end = 168, addr = 0001:0016, code size = 6
 CHECK-NEXT:                type = `0x1001 (int ())`, debug start = 0, debug end = 5, flags = none
 CHECK-NEXT:          136 | S_FRAMEPROC [size = 32]
 CHECK-NEXT:                size = 0, padding size = 0, offset to padding = 0
diff --git a/test/COFF/pdb-publics-import.test b/test/COFF/pdb-publics-import.test
index 1c75e90..a1fe7d0 100644
--- a/test/COFF/pdb-publics-import.test
+++ b/test/COFF/pdb-publics-import.test
@@ -6,7 +6,8 @@
 RUN: lld-link /out:%t1.dll /dll %t1.obj /implib:%t1.lib \
 RUN:   /export:exportfn1 /export:exportfn2
 RUN: yaml2obj < %p/Inputs/import.yaml > %t2.obj
-RUN: lld-link /out:%t2.exe /pdb:%t2.pdb /debug /entry:main %t2.obj %t1.lib
+RUN: lld-link /out:%t2.exe /pdb:%t2.pdb /pdbaltpath:test.pdb \
+RUN:   /debug /entry:main %t2.obj %t1.lib
 RUN: llvm-pdbutil dump %t2.pdb -publics -section-contribs | FileCheck %s
 
 CHECK:                             Public Symbols
@@ -19,9 +20,9 @@
 CHECK-NEXT:       88 | S_PUB32 [size = 24] `exportfn2`
 CHECK-NEXT:            flags = function, addr = 0001:0032
 CHECK-NEXT:       32 | S_PUB32 [size = 32] `__imp_exportfn2`
-CHECK-NEXT:            flags = none, addr = 0003:0072
+CHECK-NEXT:            flags = none, addr = 0002:0136
 CHECK-NEXT:        0 | S_PUB32 [size = 32] `__imp_exportfn1`
-CHECK-NEXT:            flags = none, addr = 0003:0064
+CHECK-NEXT:            flags = none, addr = 0002:0128
 
 CHECK:                         Section Contributions
 CHECK-NEXT: ============================================================
@@ -38,5 +39,5 @@
     .rdata debug directory data chunks
 CHECK-NEXT:   SC[.rdata]  | mod = 1, 0002:0000, size = 28, data crc = 0, reloc crc = 0
 CHECK-NEXT:                 IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
-CHECK-NEXT:   SC[.rdata]  | mod = 1, 0002:0028, size = {{.*}}, data crc = 0, reloc crc = 0
+CHECK-NEXT:   SC[.rdata]  | mod = 1, 0002:0028, size = 33, data crc = 0, reloc crc = 0
 CHECK-NEXT:                 IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
diff --git a/test/COFF/pdb-scopes.test b/test/COFF/pdb-scopes.test
index 2649167..f0381f1 100644
--- a/test/COFF/pdb-scopes.test
+++ b/test/COFF/pdb-scopes.test
@@ -35,39 +35,39 @@
 
 CHECK-LABEL: Mod 0000 | `{{.*}}pdb-scopes.test.tmp-a.obj`:
 CHECK: 104 | S_GPROC32 [size = 44] `g`
-CHECK:       parent = 0, end = 196, addr = 0002:0000, code size = 5
+CHECK:       parent = 0, end = 196, addr = 0001:0000, code size = 5
 CHECK:       debug start = 4, debug end = 4, flags = none
 CHECK: 180 | S_REGREL32 [size = 16] `x`
 CHECK: 196 | S_END [size = 4]
 CHECK: 200 | S_GPROC32 [size = 44] `main`
-CHECK:       parent = 0, end = 384, addr = 0002:0016, code size = 58
+CHECK:       parent = 0, end = 384, addr = 0001:0016, code size = 58
 CHECK:       debug start = 8, debug end = 53, flags = none
 CHECK: 276 | S_REGREL32 [size = 20] `argc`
 CHECK: 296 | S_BLOCK32 [size = 24] ``
 CHECK:       parent = 200, end = 336
-CHECK:       code size = 17, addr = 0002:0031
+CHECK:       code size = 17, addr = 0001:0031
 CHECK: 320 | S_REGREL32 [size = 16] `x`
 CHECK: 336 | S_END [size = 4]
 CHECK: 340 | S_BLOCK32 [size = 24] ``
 CHECK:       parent = 200, end = 380
-CHECK:       code size = 17, addr = 0002:0050
+CHECK:       code size = 17, addr = 0001:0050
 CHECK: 364 | S_REGREL32 [size = 16] `y`
 CHECK: 380 | S_END [size = 4]
 CHECK: 384 | S_END [size = 4]
 
 CHECK-LABEL: Mod 0001 | `{{.*}}pdb-scopes.test.tmp-b.obj`:
 CHECK: 104 | S_GPROC32 [size = 44] `f`
-CHECK:       parent = 0, end = 284, addr = 0002:0080, code size = 62
+CHECK:       parent = 0, end = 284, addr = 0001:0080, code size = 62
 CHECK:       debug start = 8, debug end = 57, flags = none
 CHECK: 180 | S_REGREL32 [size = 16] `x`
 CHECK: 196 | S_BLOCK32 [size = 24] ``
 CHECK:       parent = 104, end = 236
-CHECK:       code size = 20, addr = 0002:0095
+CHECK:       code size = 20, addr = 0001:0095
 CHECK: 220 | S_REGREL32 [size = 16] `y`
 CHECK: 236 | S_END [size = 4]
 CHECK: 240 | S_BLOCK32 [size = 24] ``
 CHECK:       parent = 104, end = 280
-CHECK:       code size = 20, addr = 0002:0117
+CHECK:       code size = 20, addr = 0001:0117
 CHECK: 264 | S_REGREL32 [size = 16] `w`
 CHECK: 280 | S_END [size = 4]
 CHECK: 284 | S_END [size = 4]
diff --git a/test/COFF/pdb-source-lines.test b/test/COFF/pdb-source-lines.test
index 3b8dff9..416cab0 100644
--- a/test/COFF/pdb-source-lines.test
+++ b/test/COFF/pdb-source-lines.test
@@ -26,11 +26,11 @@
 CHECK-LABEL: DbiStream:
 CHECK-NEXT:   VerHeader:       V70
 CHECK-NEXT:   Age:             1
-CHECK-NEXT:   BuildNumber:     0
+CHECK-NEXT:   BuildNumber:     36363
 CHECK-NEXT:   PdbDllVersion:   0
 CHECK-NEXT:   PdbDllRbld:      0
 CHECK-NEXT:   Flags:           0
-CHECK-NEXT:   MachineType:     x86
+CHECK-NEXT:   MachineType:     Amd64
 CHECK-NEXT:   Modules:
 
 CHECK-LABEL:    - Module:          {{.*}}pdb_lines_1.obj
@@ -43,7 +43,7 @@
 CHECK-NEXT:           CodeSize:        19
 CHECK-NEXT:           Flags:           [  ]
 CHECK-NEXT:           RelocOffset:     0
-CHECK-NEXT:           RelocSegment:    2
+CHECK-NEXT:           RelocSegment:    1
 CHECK-NEXT:           Blocks:
 CHECK-NEXT:             - FileName:        '{{.*}}pdb_lines_1.c'
 CHECK-NEXT:               Lines:
@@ -68,7 +68,7 @@
 CHECK-NEXT:           CodeSize:        14
 CHECK-NEXT:           Flags:           [  ]
 CHECK-NEXT:           RelocOffset:     32
-CHECK-NEXT:           RelocSegment:    2
+CHECK-NEXT:           RelocSegment:    1
 CHECK-NEXT:           Blocks:
 CHECK-NEXT:             - FileName:        '{{.*}}foo.h'
 CHECK-NEXT:               Lines:
@@ -103,7 +103,7 @@
 CHECK-NEXT:           CodeSize:        1
 CHECK-NEXT:           Flags:           [  ]
 CHECK-NEXT:           RelocOffset:     48
-CHECK-NEXT:           RelocSegment:    2
+CHECK-NEXT:           RelocSegment:    1
 CHECK-NEXT:           Blocks:
 CHECK-NEXT:             - FileName:        '{{.*}}pdb_lines_2.c'
 CHECK-NEXT:               Lines:
diff --git a/test/COFF/pdb-symbol-types.yaml b/test/COFF/pdb-symbol-types.yaml
index 9dad72d..0ed1215 100644
--- a/test/COFF/pdb-symbol-types.yaml
+++ b/test/COFF/pdb-symbol-types.yaml
@@ -19,7 +19,7 @@
 # CHECK-NEXT:       48 | S_PROCREF [size = 20] `main`
 # CHECK-NEXT:             module = 1, sum name = 0, offset = 116
 # CHECK-NEXT:       68 | S_GDATA32 [size = 28] `global_foo`
-# CHECK-NEXT:             type = 0x1004 (Foo), addr = 0001:0000
+# CHECK-NEXT:             type = 0x1004 (Foo), addr = 0003:0000
 
 # CHECK:                           Symbols
 # CHECK: ============================================================
@@ -30,7 +30,7 @@
 # CHECK:         frontend = 19.0.24215.1, backend = 19.0.24215.1
 # CHECK:         flags = security checks | hot patchable
 # CHECK:   116 | S_GPROC32 [size = 44] `main`
-# CHECK:         parent = 0, end = 192, addr = 0002:0000, code size = 7
+# CHECK:         parent = 0, end = 192, addr = 0001:0000, code size = 7
 # CHECK:         debug start = 0, debug end = 6, flags = none
 # CHECK:   160 | S_FRAMEPROC [size = 32]
 # CHECK:         size = 0, padding size = 0, offset to padding = 0
diff --git a/test/COFF/pdb-thunk.yaml b/test/COFF/pdb-thunk.yaml
index 6435a17..444800f 100644
--- a/test/COFF/pdb-thunk.yaml
+++ b/test/COFF/pdb-thunk.yaml
@@ -84,7 +84,7 @@
             RegRelativeSym:
               Offset:          8
               Type:            4097
-              Register:        RSP
+              Register:        CVRegRSP
               VarName:         this
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
@@ -124,7 +124,7 @@
             RegRelativeSym:
               Offset:          8
               Type:            4121
-              Register:        RSP
+              Register:        CVRegRSP
               VarName:         this
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
@@ -164,7 +164,7 @@
             RegRelativeSym:
               Offset:          48
               Type:            4143
-              Register:        RSP
+              Register:        CVRegRSP
               VarName:         this
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
@@ -208,7 +208,7 @@
             RegRelativeSym:
               Offset:          8
               Type:            4143
-              Register:        RSP
+              Register:        CVRegRSP
               VarName:         this
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
@@ -2176,7 +2176,7 @@
             RegRelativeSym:
               Offset:          8
               Type:            4097
-              Register:        RSP
+              Register:        CVRegRSP
               VarName:         this
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
@@ -2222,7 +2222,7 @@
             RegRelativeSym:
               Offset:          8
               Type:            4121
-              Register:        RSP
+              Register:        CVRegRSP
               VarName:         this
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
diff --git a/test/COFF/pdb-type-server-simple.test b/test/COFF/pdb-type-server-simple.test
index 898c5d4..51a92db 100644
--- a/test/COFF/pdb-type-server-simple.test
+++ b/test/COFF/pdb-type-server-simple.test
@@ -72,7 +72,7 @@
 CHECK-LABEL:   Mod 0000 | `{{.*}}a.obj`:
 CHECK:        4 | S_OBJNAME [size = 40] sig=0, `C:\src\llvm-project\build\a.obj`
 CHECK:      104 | S_GPROC32 [size = 44] `main`
-CHECK:            parent = 0, end = 196, addr = 0002:0000, code size = 27
+CHECK:            parent = 0, end = 196, addr = 0001:0000, code size = 27
 CHECK:            type = {{.*}}, debug start = 4, debug end = 22, flags = none
 CHECK:      200 | S_BUILDINFO [size = 8] BuildId = `[[A_BUILD]]`
 CHECK-LABEL:   Mod 0001 | `{{.*}}b.obj`:
@@ -82,14 +82,14 @@
 CHECK:            frontend = 19.0.24215.1, backend = 19.0.24215.1
 CHECK:            flags = security checks | hot patchable
 CHECK:      104 | S_GPROC32 [size = 44] `g`
-CHECK:            parent = 0, end = 196, addr = 0002:0032, code size = 13
+CHECK:            parent = 0, end = 196, addr = 0001:0032, code size = 13
 CHECK:            type = {{.*}}, debug start = 5, debug end = 12, flags = none
 CHECK:      148 | S_FRAMEPROC [size = 32]
 CHECK:            size = 0, padding size = 0, offset to padding = 0
 CHECK:            bytes of callee saved registers = 0, exception handler addr = 0000:0000
 CHECK:            flags = has async eh | opt speed
 CHECK:      180 | S_REGREL32 [size = 16] `p`
-CHECK:            type = [[FOO_PTR]] (Foo*), register = RSP, offset = 8
+CHECK:            type = [[FOO_PTR]] (Foo*), register = CVRegRSP, offset = 8
 CHECK:      196 | S_END [size = 4]
 CHECK:      200 | S_BUILDINFO [size = 8] BuildId = `[[B_BUILD]]`
 CHECK-LABEL:   Mod 0002 | `* Linker *`:
diff --git a/test/COFF/pdb.test b/test/COFF/pdb.test
index faab5fe..5788b51 100644
--- a/test/COFF/pdb.test
+++ b/test/COFF/pdb.test
@@ -1,8 +1,8 @@
 # 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 /entry:main /nodefaultlib \
-# RUN:   %t1.obj %t2.obj
+# RUN: lld-link /debug /pdb:%t.pdb /pdbaltpath:test.pdb /dll /out:%t.dll \
+# RUN:   /entry:main /nodefaultlib %t1.obj %t2.obj
 
 # RUN: llvm-pdbutil pdb2yaml -stream-metadata -stream-directory -pdb-stream \
 # RUN:   -dbi-stream -ipi-stream -tpi-stream %t.pdb | FileCheck %s
@@ -34,11 +34,11 @@
 # CHECK-NEXT: DbiStream:
 # CHECK-NEXT:   VerHeader:       V70
 # CHECK-NEXT:   Age:             1
-# CHECK-NEXT:   BuildNumber:     0
+# CHECK-NEXT:   BuildNumber:     36363
 # CHECK-NEXT:   PdbDllVersion:   0
 # CHECK-NEXT:   PdbDllRbld:      0
 # CHECK-NEXT:   Flags:           0
-# CHECK-NEXT:   MachineType:     x86
+# CHECK-NEXT:   MachineType:     Amd64
 # CHECK-NEXT: TpiStream:
 # CHECK-NEXT:   Version:         VC80
 # CHECK-NEXT:   Records:
@@ -120,14 +120,22 @@
 RAW:                               Modules
 RAW-NEXT: ============================================================
 RAW-NEXT:   Mod 0000 | `{{.*}}pdb.test.tmp1.obj`:
+RAW-NEXT:              SC[.text]  | mod = 0, 0001:0000, size = 14, data crc = 1682752513, reloc crc = 0
+RAW-NEXT:                           IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE |
+RAW-NEXT:                           IMAGE_SCN_MEM_READ
 RAW-NEXT:              Obj: `{{.*}}pdb.test.tmp1.obj`:
 RAW-NEXT:              debug stream: 11, # files: 1, has ec info: false
 RAW-NEXT:              pdb file ni: 0 ``, src file ni: 0 ``
 RAW-NEXT:   Mod 0001 | `{{.*}}pdb.test.tmp2.obj`:
+RAW-NEXT:              SC[.text]  | mod = 1, 0001:0016, size = 6, data crc = 2139436471, reloc crc = 0
+RAW-NEXT:                           IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE |
+RAW-NEXT:                           IMAGE_SCN_MEM_READ
 RAW-NEXT:              Obj: `{{.*}}pdb.test.tmp2.obj`:
 RAW-NEXT:              debug stream: 12, # files: 1, has ec info: false
 RAW-NEXT:              pdb file ni: 0 ``, src file ni: 0 ``
 RAW-NEXT:   Mod 0002 | `* Linker *`:
+RAW-NEXT:              SC[???]  | mod = 2, 0000:0000, size = 0, data crc = 0, reloc crc = 0
+RAW-NEXT:                         none
 RAW-NEXT:              Obj: ``:
 RAW-NEXT:              debug stream: 13, # files: 0, has ec info: false
 RAW-NEXT:              pdb file ni: 1 `{{.*pdb.test.tmp.pdb}}`, src file ni: 0 ``
@@ -181,9 +189,9 @@
 RAW-NEXT:     sig = 0xFFFFFFFF, hdr = 0xF12F091A, hr size = 16, num buckets = 524
 RAW-NEXT:   Records
 RAW-NEXT:       20 | S_PUB32 [size = 20] `main`
-RAW-NEXT:            flags = function, addr = 0002:0000
+RAW-NEXT:            flags = function, addr = 0001:0000
 RAW-NEXT:        0 | S_PUB32 [size = 20] `foo`
-RAW-NEXT:            flags = function, addr = 0002:0016
+RAW-NEXT:            flags = function, addr = 0001:0016
 RAW-NOT:             S_PUB32
 RAW-NEXT:   Hash Entries
 RAW-NEXT:     off = 21, refcnt = 1
@@ -196,93 +204,80 @@
 RAW-NEXT:     off = 0
 RAW:                            Section Headers
 RAW-NEXT: ============================================================
+
 RAW:        SECTION HEADER #1
-RAW-NEXT:     .pdata name
-RAW-NEXT:            virtual size
-RAW-NEXT:       1000 virtual address
-RAW-NEXT:        200 size of raw data
-RAW-NEXT:        400 file pointer to raw data
-RAW-NEXT:          0 file pointer to relocation table
-RAW-NEXT:          0 file pointer to line numbers
-RAW-NEXT:          0 number of relocations
-RAW-NEXT:          0 number of line numbers
-RAW-NEXT:   40000040 flags
-RAW-NEXT:            IMAGE_SCN_CNT_INITIALIZED_DATA
-RAW-NEXT:            IMAGE_SCN_MEM_READ
+RAW-NEXT:     .text name
+RAW-NEXT:        16 virtual size
+RAW-NEXT:      1000 virtual address
+RAW-NEXT:       200 size of raw data
+RAW-NEXT:       400 file pointer to raw data
+RAW-NEXT:         0 file pointer to relocation table
+RAW-NEXT:         0 file pointer to line numbers
+RAW-NEXT:         0 number of relocations
+RAW-NEXT:         0 number of line numbers
+RAW-NEXT:  60000020 flags
+RAW-NEXT:           IMAGE_SCN_CNT_CODE
+RAW-NEXT:           IMAGE_SCN_MEM_EXECUTE
+RAW-NEXT:           IMAGE_SCN_MEM_READ
 RAW:        SECTION HEADER #2
-RAW-NEXT:      .text name
-RAW-NEXT:            virtual size
-RAW-NEXT:       2000 virtual address
-RAW-NEXT:        200 size of raw data
-RAW-NEXT:        600 file pointer to raw data
-RAW-NEXT:          0 file pointer to relocation table
-RAW-NEXT:          0 file pointer to line numbers
-RAW-NEXT:          0 number of relocations
-RAW-NEXT:          0 number of line numbers
-RAW-NEXT:   60000020 flags
-RAW-NEXT:            IMAGE_SCN_CNT_CODE
-RAW-NEXT:            IMAGE_SCN_MEM_EXECUTE
-RAW-NEXT:            IMAGE_SCN_MEM_READ
+RAW-NEXT:    .rdata name
+RAW-NEXT:           virtual size
+RAW-NEXT:      2000 virtual address
+RAW-NEXT:       200 size of raw data
+RAW-NEXT:       600 file pointer to raw data
+RAW-NEXT:         0 file pointer to relocation table
+RAW-NEXT:         0 file pointer to line numbers
+RAW-NEXT:         0 number of relocations
+RAW-NEXT:         0 number of line numbers
+RAW-NEXT:  40000040 flags
+RAW-NEXT:           IMAGE_SCN_CNT_INITIALIZED_DATA
+RAW-NEXT:           IMAGE_SCN_MEM_READ
 RAW:        SECTION HEADER #3
-RAW-NEXT:     .xdata name
-RAW-NEXT:            virtual size
-RAW-NEXT:       3000 virtual address
-RAW-NEXT:        200 size of raw data
-RAW-NEXT:        800 file pointer to raw data
-RAW-NEXT:          0 file pointer to relocation table
-RAW-NEXT:          0 file pointer to line numbers
-RAW-NEXT:          0 number of relocations
-RAW-NEXT:          0 number of line numbers
-RAW-NEXT:   40000040 flags
-RAW-NEXT:            IMAGE_SCN_CNT_INITIALIZED_DATA
-RAW-NEXT:            IMAGE_SCN_MEM_READ
-RAW:        SECTION HEADER #4
-RAW-NEXT:     .rdata name
-RAW-NEXT:            virtual size
-RAW-NEXT:       4000 virtual address
-RAW-NEXT:        200 size of raw data
-RAW-NEXT:        A00 file pointer to raw data
-RAW-NEXT:          0 file pointer to relocation table
-RAW-NEXT:          0 file pointer to line numbers
-RAW-NEXT:          0 number of relocations
-RAW-NEXT:          0 number of line numbers
-RAW-NEXT:   40000040 flags
-RAW-NEXT:            IMAGE_SCN_CNT_INITIALIZED_DATA
-RAW-NEXT:            IMAGE_SCN_MEM_READ
+RAW-NEXT:    .pdata name
+RAW-NEXT:         C virtual size
+RAW-NEXT:      3000 virtual address
+RAW-NEXT:       200 size of raw data
+RAW-NEXT:       800 file pointer to raw data
+RAW-NEXT:         0 file pointer to relocation table
+RAW-NEXT:         0 file pointer to line numbers
+RAW-NEXT:         0 number of relocations
+RAW-NEXT:         0 number of line numbers
+RAW-NEXT:  40000040 flags
+RAW-NEXT:           IMAGE_SCN_CNT_INITIALIZED_DATA
+RAW-NEXT:           IMAGE_SCN_MEM_READ
 RAW:                        Original Section Headers
 RAW-NEXT: ============================================================
 RAW-NEXT:   PDB does not contain the requested image section header type
 RAW:                        Section Contributions
 RAW-NEXT: ============================================================
-RAW-NEXT:   SC[.pdata]  | mod = 0, 0001:0000, size = 12, data crc = 361370162, reloc crc = 0
-RAW-NEXT:                 IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ
-RAW-NEXT:   SC[.text]   | mod = 0, 0002:0000, size = 14, data crc = 1682752513, reloc crc = 0
+
+RAW-NEXT:   SC[.text]   | mod = 0, 0001:0000, size = 14, data crc = 1682752513, reloc crc = 0
 RAW-NEXT:                 IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE |
 RAW-NEXT:                 IMAGE_SCN_MEM_READ
-RAW-NEXT:   SC[.text]   | mod = 1, 0002:0016, size = 6, data crc = 2139436471, reloc crc = 0
+RAW-NEXT:   SC[.text]   | mod = 1, 0001:0016, size = 6, data crc = 2139436471, reloc crc = 0
 RAW-NEXT:                 IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE |
 RAW-NEXT:                 IMAGE_SCN_MEM_READ
-RAW-NEXT:   SC[.xdata]  | mod = 0, 0003:0000, size = 8, data crc = 264583633, reloc crc = 0
+RAW-NEXT:   SC[.rdata]  | mod = 2, 0002:0000, size = {{[0-9]+}}, data crc = 0, reloc crc = 0
+RAW-NEXT:                 IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
+RAW-NEXT:   SC[.rdata]  | mod = 2, 0002:0028, size = {{[0-9]+}}, data crc = 0, reloc crc = 0
+RAW-NEXT:                 IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
+RAW-NEXT:   SC[.rdata]  | mod = 0, 0002:0064, size = {{[0-9]+}}, data crc = 264583633, reloc crc = 0
 RAW-NEXT:                 IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ
-RAW-NEXT:   SC[???]     | mod = 2, 0004:0000, size = {{[0-9]+}}, data crc = 0, reloc crc = 0
-RAW-NEXT:                 IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
-RAW-NEXT:   SC[???]     | mod = 2, 0004:0028, size = {{[0-9]+}}, data crc = 0, reloc crc = 0
-RAW-NEXT:                 IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
+RAW-NEXT:   SC[.pdata]  | mod = 0, 0003:0000, size = 12, data crc = 361370162, reloc crc = 0
+RAW-NEXT:                 IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ
 RAW-NOT: SC[
 RAW:                             Section Map
 RAW-NEXT: ============================================================
+
 RAW-NEXT:   Section 0000 | ovl = 0, group = 0, frame = 1, name = 65535
 RAW-NEXT:                  class = 65535, offset = 0, size =
-RAW-NEXT:                  flags = read | 32 bit addr | selector
+RAW-NEXT:                  flags = read | execute | 32 bit addr | selector
 RAW-NEXT:   Section 0001 | ovl = 0, group = 0, frame = 2, name = 65535
 RAW-NEXT:                  class = 65535, offset = 0, size =
-RAW-NEXT:                  flags = read | execute | 32 bit addr | selector
+RAW-NEXT:                  flags = read | 32 bit addr | selector
 RAW-NEXT:   Section 0002 | ovl = 0, group = 0, frame = 3, name = 65535
 RAW-NEXT:                  class = 65535, offset = 0, size =
 RAW-NEXT:                  flags = read | 32 bit addr | selector
 RAW-NEXT:   Section 0003 | ovl = 0, group = 0, frame = 4, name = 65535
-RAW-NEXT:                  class = 65535, offset = 0, size =
-RAW-NEXT:                  flags = read | 32 bit addr | selector
-RAW-NEXT:   Section 0004 | ovl = 0, group = 0, frame = 5, name = 65535
-RAW-NEXT:                  class = 65535, offset = 0, size =
+RAW-NEXT:                  class = 65535, offset = 0, size = 4294967295
 RAW-NEXT:                  flags = 32 bit addr | absolute addr
diff --git a/test/COFF/reloc-arm.test b/test/COFF/reloc-arm.test
index 872e6d5..87d93ed 100644
--- a/test/COFF/reloc-arm.test
+++ b/test/COFF/reloc-arm.test
@@ -3,14 +3,14 @@
 # RUN: llvm-objdump -s %t.exe | FileCheck %s
 
 # CHECK: .text:
-# CHECK: 402000 01104000 00000000 00000000 00000000
-# CHECK: 402010 01100000 00000000 00000000 00000000
-# CHECK: 402020 41f20009 c0f24009 00000000 00000000
-# CHECK: 402030 fe07e62f 00000000 00000000 00000000
-# CHECK: 402040 3e04de2f 00000000 00000000 00000000
-# CHECK: 402050 fe07d62f 00000000 00000000 00000000
-# CHECK: 402060 fef0cef7 00000000 00000000 00000000
-# CHECK: 402070 00005000 00000000 00000000 00000000
+# CHECK: 401000 01204000 00000000 00000000 00000000
+# CHECK: 401010 01200000 00000000 00000000 00000000
+# CHECK: 401020 42f20009 c0f24009 00000000 00000000
+# CHECK: 401030 0000e62f 00000000 00000000 00000000
+# CHECK: 401040 0000de07 00000000 00000000 00000000
+# CHECK: 401050 0000d62f 00000000 00000000 00000000
+# CHECK: 401060 00f1cef7 00000000 00000000 00000000
+# CHECK: 401070 00005000 00000000 00000000 00000000
 
 --- !COFF
 header:
diff --git a/test/COFF/resource.test b/test/COFF/resource.test
index 53242cd..4108957 100644
--- a/test/COFF/resource.test
+++ b/test/COFF/resource.test
@@ -10,11 +10,11 @@
 # RUN: llvm-readobj -file-headers -coff-resources -section-data %t.exe | \
 # RUN:   FileCheck --check-prefix=RESOURCE_INFO %s
 
-RESOURCE_INFO:      ResourceTableRVA: 0x1000
-RESOURCE_INFO-NEXT: ResourceTableSize: 0x88
+RESOURCE_INFO:      ResourceTableRVA: 0x2000
+RESOURCE_INFO-NEXT: ResourceTableSize: 0x90
 RESOURCE_INFO-DAG:  Resources [
 RESOURCE_INFO-NEXT:   Total Number of Resources: 1
-RESOURCE_INFO-NEXT:   Base Table Address: 0x400
+RESOURCE_INFO-NEXT:   Base Table Address: 0x600
 RESOURCE_INFO-DAG:    Number of String Entries: 0
 RESOURCE_INFO-NEXT:   Number of ID Entries: 1
 RESOURCE_INFO-NEXT:   Type: kRT_STRING (ID 6) [
@@ -36,9 +36,9 @@
 RESOURCE_INFO-NEXT: 0010: 06000000 18000080 00000000 00000000  |................|
 RESOURCE_INFO-NEXT: 0020: 00000000 00000100 01000000 30000080  |............0...|
 RESOURCE_INFO-NEXT: 0030: 00000000 00000000 00000000 00000100  |................|
-RESOURCE_INFO-NEXT: 0040: 09040000 48000000 58100000 2A000000  |....H...X...*...|
-RESOURCE_INFO-NEXT: 0050: 00000000 00000000 00000500 48006500  |............H.e.|
-RESOURCE_INFO-NEXT: 0060: 6C006C00 6F000000 00000000 00000000  |l.l.o...........|
+RESOURCE_INFO-NEXT: 0040: 09040000 48000000 60200000 2A000000  |....H...` ..*...|
+RESOURCE_INFO-NEXT: 0050: 00000000 00000000 00000000 00000000  |................|
+RESOURCE_INFO-NEXT: 0060: 00000500 48006500 6C006C00 6F000000  |....H.e.l.l.o...|
 RESOURCE_INFO-NEXT: 0070: 00000000 00000000 00000000 00000000  |................|
-RESOURCE_INFO-NEXT: 0080: 00000000 00000000                    |........|
+RESOURCE_INFO-NEXT: 0080: 00000000 00000000 00000000 00000000  |................|
 RESOURCE_INFO-NEXT: )
diff --git a/test/COFF/rsds.test b/test/COFF/rsds.test
index 10c2c56..6ce92a9 100644
--- a/test/COFF/rsds.test
+++ b/test/COFF/rsds.test
@@ -1,16 +1,16 @@
 # RUN: yaml2obj %s > %t.obj
 
 # RUN: rm -f %t.dll %t.pdb
-# RUN: lld-link /debug /dll /out:%t.dll /entry:DllMain %t.obj
+# RUN: lld-link /debug /pdbaltpath:test1.pdb /dll /out:%t.dll /entry:DllMain %t.obj
 # RUN: llvm-readobj -coff-debug-directory %t.dll > %t.1.txt
-# RUN: lld-link /debug /dll /out:%t.dll /entry:DllMain %t.obj
+# RUN: lld-link /debug /pdbaltpath:test2.pdb /dll /out:%t.dll /entry:DllMain %t.obj
 # RUN: llvm-readobj -coff-debug-directory %t.dll > %t.2.txt
 # RUN: cat %t.1.txt %t.2.txt | FileCheck %s
 
 # RUN: rm -f %t.dll %t.pdb
-# RUN: lld-link /debug /pdb:%t.pdb /dll /out:%t.dll /entry:DllMain %t.obj
+# RUN: lld-link /debug /pdb:%t1.pdb /dll /out:%t.dll /entry:DllMain %t.obj
 # RUN: llvm-readobj -coff-debug-directory %t.dll > %t.3.txt
-# RUN: lld-link /debug /pdb:%t.pdb /dll /out:%t.dll /entry:DllMain %t.obj
+# RUN: lld-link /debug /pdb:%t2.pdb /dll /out:%t.dll /entry:DllMain %t.obj
 # RUN: llvm-readobj -coff-debug-directory %t.dll > %t.4.txt
 # RUN: cat %t.3.txt %t.4.txt | FileCheck %s
 
@@ -29,7 +29,7 @@
 # CHECK:       PDBSignature: 0x53445352
 # CHECK:       PDBGUID: [[GUID:\(([A-Za-z0-9]{2} ?){16}\)]]
 # CHECK:       PDBAge: 1
-# CHECK:       PDBFileName: {{.*}}.pdb
+# CHECK:       PDBFileName: {{.*}}1.pdb
 # CHECK:     }
 # CHECK:   }
 # CHECK: ]
@@ -48,7 +48,7 @@
 # CHECK:       PDBSignature: 0x53445352
 # CHECK:       PDBGUID: [[GUID]]
 # CHECK:       PDBAge: 2
-# CHECK:       PDBFileName: {{.*}}.pdb
+# CHECK:       PDBFileName: {{.*}}2.pdb
 # CHECK:     }
 # CHECK:   }
 # CHECK: ]
diff --git a/test/COFF/safeseh-notable.s b/test/COFF/safeseh-notable.s
new file mode 100644
index 0000000..1f00cb2
--- /dev/null
+++ b/test/COFF/safeseh-notable.s
@@ -0,0 +1,43 @@
+# RUN: llvm-mc -triple i686-windows-msvc %s -filetype=obj -o %t.obj
+# RUN: lld-link %t.obj -safeseh -out:%t.exe -entry:main
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
+
+# This object lacks a _load_config_used global, so we set
+# IMAGE_DLL_CHARACTERISTICS_NO_SEH even though there is an exception handler.
+# This is a more secure default. If someone wants to use a CRT without a load
+# config and they want to use 32-bit SEH, they will need to provide a
+# safeseh-compatible load config.
+
+# CHECK-LABEL: Characteristics [
+# CHECK:   IMAGE_DLL_CHARACTERISTICS_NO_SEH
+# CHECK: ]
+
+# CHECK-LABEL:  DataDirectory {
+# CHECK:    LoadConfigTableRVA: 0x0
+# CHECK:    LoadConfigTableSize: 0x0
+# CHECK:  }
+
+# CHECK-NOT: LoadConfig
+# CHECK-NOT: SEHTable
+
+        .def     @feat.00;
+        .scl    3;
+        .type   0;
+        .endef
+        .globl  @feat.00
+@feat.00 = 1
+
+        .text
+        .def     _main; .scl    2; .type   32; .endef
+        .globl  _main
+_main:
+        pushl $_my_handler
+        movl $42, %eax
+        popl %ecx
+        ret
+
+        .def     _my_handler; .scl    3; .type   32; .endef
+_my_handler:
+        ret
+
+.safeseh _my_handler
diff --git a/test/COFF/safeseh.s b/test/COFF/safeseh.s
index 35f54c5..efe20fb 100644
--- a/test/COFF/safeseh.s
+++ b/test/COFF/safeseh.s
@@ -1,27 +1,35 @@
 # RUN: llvm-mc -triple i686-windows-msvc %s -filetype=obj -o %t.obj
 # RUN: lld-link %t.obj -safeseh -out:%t.exe -opt:noref -entry:main
 # RUN: llvm-readobj -coff-basereloc -coff-load-config -file-headers %t.exe | FileCheck %s --check-prefix=CHECK-NOGC
+# RUN: lld-link %t.obj -safeseh -out:%t.exe -opt:noref -entry:main -debug:dwarf
+# RUN: llvm-readobj -coff-basereloc -coff-load-config -file-headers %t.exe | FileCheck %s --check-prefix=CHECK-NOGC
 # RUN: lld-link %t.obj -safeseh -out:%t.exe -opt:ref -entry:main
 # RUN: llvm-readobj -coff-basereloc -coff-load-config -file-headers %t.exe | FileCheck %s --check-prefix=CHECK-GC
 
 # __safe_se_handler_table needs to be relocated against ImageBase.
 # check that the relocation is present.
+#
 # CHECK-NOGC-NOT: IMAGE_DLL_CHARACTERISTICS_NO_SEH
 # CHECK-NOGC: BaseReloc [
 # CHECK-NOGC:   Entry {
 # CHECK-NOGC:     Type: HIGHLOW
 # CHECK-NOGC: LoadConfig [
 # CHECK-NOGC:   Size: 0x48
-# CHECK-NOGC:   SEHandlerTable: 0x401048
+# CHECK-NOGC:   SEHandlerTable: 0x
 # CHECK-NOGC:   SEHandlerCount: 1
 # CHECK-NOGC: ]
 # CHECK-NOGC: SEHTable [
-# CHECK-NOGC-NEXT:   0x402006
+# CHECK-NOGC-NEXT:   0x401006
 # CHECK-NOGC-NEXT: ]
 
-# Without the SEH table, the address is absolute, so check that we do
-# not have a relocation for it.
-# CHECK-GC-NOT: IMAGE_DLL_CHARACTERISTICS_NO_SEH
+# If we enable GC, the exception handler should be removed, and we should add
+# the DLL characteristic flag that indicates that there are no exception
+# handlers in this DLL. The exception handler table in the load config should
+# be empty and there should be no relocations for it.
+#
+# CHECK-GC: Characteristics [
+# CHECK-GC:   IMAGE_DLL_CHARACTERISTICS_NO_SEH
+# CHECK-GC: ]
 # CHECK-GC: BaseReloc [
 # CHECK-GC-NEXT: ]
 # CHECK-GC: LoadConfig [
diff --git a/test/COFF/secidx-absolute.s b/test/COFF/secidx-absolute.s
index bfe7136..a62d2c7 100644
--- a/test/COFF/secidx-absolute.s
+++ b/test/COFF/secidx-absolute.s
@@ -16,18 +16,18 @@
 # CHECK: Sections [
 # CHECK:   Section {
 # CHECK:     Number: 1
-# CHECK:     Name: .rdata (2E 72 64 61 74 61 00 00)
-# CHECK:     SectionData (
-# CHECK:       0000: 0300                                 |..|
-# CHECK:     )
-# CHECK:   }
-# CHECK:   Section {
-# CHECK:     Number: 2
 # CHECK:     Name: .text (2E 74 65 78 74 00 00 00)
 # CHECK:     VirtualSize: 0x1
 # CHECK:     SectionData (
 # CHECK:       0000: C3                                   |.|
 # CHECK:     )
 # CHECK:   }
+# CHECK:   Section {
+# CHECK:     Number: 2
+# CHECK:     Name: .rdata (2E 72 64 61 74 61 00 00)
+# CHECK:     SectionData (
+# CHECK:       0000: 0300                                 |..|
+# CHECK:     )
+# CHECK:   }
 # CHECK-NOT: Section
 # CHECK: ]
diff --git a/test/COFF/secrel-common.s b/test/COFF/secrel-common.s
index 0188f6c..85cb10d 100644
--- a/test/COFF/secrel-common.s
+++ b/test/COFF/secrel-common.s
@@ -2,29 +2,30 @@
 # RUN: lld-link -entry:main -nodefaultlib %t.obj -out:%t.exe
 # RUN: llvm-readobj %t.exe -sections -section-data | FileCheck %s
 
-# Section relocations against common symbols resolve to .bss.
+# Section relocations against common symbols resolve to .bss (merged into .data).
 
 # CHECK: Sections [
 # CHECK:   Section {
 # CHECK:     Number: 1
-# CHECK:     Name: .bss (2E 62 73 73 00 00 00 00)
-# CHECK:     VirtualSize: 0x4
-# CHECK:   }
-# CHECK:   Section {
-# CHECK:     Number: 2
-# CHECK:     Name: .rdata (2E 72 64 61 74 61 00 00)
-# CHECK:     SectionData (
-# CHECK:       0000: 00000000 01000000 |........|
-# CHECK:     )
-# CHECK:   }
-# CHECK:   Section {
-# CHECK:     Number: 3
 # CHECK:     Name: .text (2E 74 65 78 74 00 00 00)
 # CHECK:     VirtualSize: 0x1
 # CHECK:     SectionData (
 # CHECK:       0000: C3                                   |.|
 # CHECK:     )
 # CHECK:   }
+# CHECK:   Section {
+# CHECK:     Number: 2
+# CHECK:     Name: .rdata (2E 72 64 61 74 61 00 00)
+# CHECK:     SectionData (
+# CHECK:       0000: 00020000 03000000 |........|
+# CHECK:     )
+# CHECK:   }
+# CHECK:   Section {
+# CHECK:     Number: 3
+# CHECK:     Name: .data (2E 64 61 74 61 00 00 00)
+# CHECK:     VirtualSize: 0x204
+# CHECK:     RawDataSize: 512
+# CHECK:   }
 # CHECK-NOT: Section
 # CHECK: ]
 
@@ -39,3 +40,6 @@
 .secrel32 common_global
 .secidx common_global
 .short 0
+
+.section .data,"drw"
+.zero 512
diff --git a/test/COFF/section-size.s b/test/COFF/section-size.s
index 28f3f4a..d971b6e 100644
--- a/test/COFF/section-size.s
+++ b/test/COFF/section-size.s
@@ -7,7 +7,7 @@
 # Run: lld-link -entry:main %tmain.obj %t3.obj -out:%t.exe
 
 # RUN: not lld-link -entry:main %tmain.obj %t1.obj %t2.obj -out:%t.exe 2>&1 | FileCheck %s
-# CHECK: error: section larger than 4 GiB: .bss
+# CHECK: error: section larger than 4 GiB: .data
 
 .globl main
 main:
diff --git a/test/COFF/section.test b/test/COFF/section.test
index 591c04d..5e1162e 100644
--- a/test/COFF/section.test
+++ b/test/COFF/section.test
@@ -16,18 +16,22 @@
 # RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=S %s
 
 # R:      Characteristics [
+# R-NEXT:   IMAGE_SCN_CNT_INITIALIZED_DATA
 # R-NEXT:   IMAGE_SCN_MEM_READ
 # R-NEXT: ]
 
 # W:      Characteristics [
+# W-NEXT:   IMAGE_SCN_CNT_INITIALIZED_DATA
 # W-NEXT:   IMAGE_SCN_MEM_WRITE
 # W-NEXT: ]
 
 # E:      Characteristics [
+# E-NEXT:   IMAGE_SCN_CNT_INITIALIZED_DATA
 # E-NEXT:   IMAGE_SCN_MEM_EXECUTE
 # E-NEXT: ]
 
 # S:      Characteristics [
+# S-NEXT:   IMAGE_SCN_CNT_INITIALIZED_DATA
 # S-NEXT:   IMAGE_SCN_MEM_SHARED
 # S-NEXT: ]
 
diff --git a/test/COFF/string-tail-merge.s b/test/COFF/string-tail-merge.s
index f55041f..2e3b735 100644
--- a/test/COFF/string-tail-merge.s
+++ b/test/COFF/string-tail-merge.s
@@ -2,29 +2,48 @@
 # RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s
 # RUN: lld-link %t.obj /out:%t.exe /entry:main /subsystem:console
 # RUN: llvm-objdump -s %t.exe | FileCheck %s
+# RUN: lld-link %t.obj /out:%t.exe /entry:main /subsystem:console /opt:noicf /opt:lldtailmerge
+# RUN: llvm-objdump -s %t.exe | FileCheck %s
+# RUN: lld-link %t.obj /out:%t.exe /entry:main /subsystem:console /opt:noicf
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=NOSTM %s
+# RUN: lld-link %t.obj /out:%t.exe /entry:main /subsystem:console /opt:nolldtailmerge
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=NOSTM %s
+
+# CHECK: Contents of section .text:
+# NOSTM: Contents of section .text:
+.globl main
+main:
+# CHECK-NEXT: 140001000 11200040 01000000 17200040 01000000
+# NOSTM-NEXT: 140001000 00200040 01000000 0c200040 01000000
+.8byte "??_C@_0M@LACCCNMM@hello?5world?$AA@"
+.8byte "??_C@_05MCBCHHEJ@world?$AA@"
+# CHECK-NEXT: 140001010 2a200040 01000000 36200040 01000000
+# NOSTM-NEXT: 140001010 12200040 01000000 2a200040 01000000
+.8byte "??_C@_1BI@HHJHKLLN@?$AAh?$AAe?$AAl?$AAl?$AAo?$AA?5?$AAw?$AAo?$AAr?$AAl?$AAd?$AA?$AA@"
+.8byte "??_C@_1M@NBBDDHIO@?$AAw?$AAo?$AAr?$AAl?$AAd?$AA?$AA@"
+# CHECK-NEXT: 140001020 00200040 01000000 0c200040 01000000
+# NOSTM-NEXT: 140001020 36200040 01000000 42200040 01000000
+.8byte "??_D@not_a_string_literal"
+.8byte "??_C@string_literal_with_relocs"
+# CHECK-NEXT: 140001030 00300040 01000000 1e200040 01000000
+# NOSTM-NEXT: 140001030 00300040 01000000 48200040 01000000
+.8byte "??_C@string_literal_in_wrong_section"
+.8byte "??_C@overaligned_string_literal"
 
 # CHECK: Contents of section .rdata:
-# CHECK-NEXT:  140002000 68656c6c 6f20776f 726c6400 6fa26ca4  hello world.o.l.
+# CHECK-NEXT:  140002000 68656c6c 6f20776f 726c6400 6f826ca4  hello world.o.l.
 # CHECK-NEXT:  140002010 0068656c 6c6f2077 6f726c64 00006865  .hello world..he
 # CHECK-NEXT:  140002020 6c6c6f20 776f726c 64006800 65006c00  llo world.h.e.l.
 # CHECK-NEXT:  140002030 6c006f00 20007700 6f007200 6c006400  l.o. .w.o.r.l.d.
 # CHECK-NEXT:  140002040 0000                                 ..
 
-# CHECK: Contents of section .text:
-.globl main
-main:
-# CHECK-NEXT: 140003000 11200040 01000000 17200040 01000000
-.8byte "??_C@_0M@LACCCNMM@hello?5world?$AA@"
-.8byte "??_C@_05MCBCHHEJ@world?$AA@"
-# CHECK-NEXT: 140003010 2a200040 01000000 36200040 01000000
-.8byte "??_C@_1BI@HHJHKLLN@?$AAh?$AAe?$AAl?$AAl?$AAo?$AA?5?$AAw?$AAo?$AAr?$AAl?$AAd?$AA?$AA@"
-.8byte "??_C@_1M@NBBDDHIO@?$AAw?$AAo?$AAr?$AAl?$AAd?$AA?$AA@"
-# CHECK-NEXT: 140003020 00200040 01000000 0c200040 01000000
-.8byte "??_D@not_a_string_literal"
-.8byte "??_C@string_literal_with_relocs"
-# CHECK-NEXT: 140003030 00100040 01000000 1e200040 01000000
-.8byte "??_C@string_literal_in_wrong_section"
-.8byte "??_C@overaligned_string_literal"
+# NOSTM: Contents of section .rdata:
+# NOSTM-NEXT:  140002000 68656c6c 6f20776f 726c6400 776f726c  hello world.worl
+# NOSTM-NEXT:  140002010 64006800 65006c00 6c006f00 20007700  d.h.e.l.l.o. .w.
+# NOSTM-NEXT:  140002020 6f007200 6c006400 00007700 6f007200  o.r.l.d...w.o.r.
+# NOSTM-NEXT:  140002030 6c006400 00006865 6c6c6f20 776f726c  l.d...hello worl
+# NOSTM-NEXT:  140002040 64006f82 6ca40000 68656c6c 6f20776f  d.o.l...hello wo
+# NOSTM-NEXT:  140002050 726c6400                             rld.
 
 .section .rdata,"dr",discard,"??_C@_0M@LACCCNMM@hello?5world?$AA@"
 .globl "??_C@_0M@LACCCNMM@hello?5world?$AA@"
diff --git a/test/COFF/symtab.test b/test/COFF/symtab.test
index 4e46e33..49302d7 100644
--- a/test/COFF/symtab.test
+++ b/test/COFF/symtab.test
@@ -11,7 +11,7 @@
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Name: .text
 # CHECK-NEXT:     Value: 0
-# CHECK-NEXT:     Section: .text (2)
+# CHECK-NEXT:     Section: .text (1)
 # CHECK-NEXT:     BaseType: Null (0x0)
 # CHECK-NEXT:     ComplexType: Null (0x0)
 # CHECK-NEXT:     StorageClass: Static (0x3)
@@ -20,7 +20,7 @@
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Name: .text2
 # CHECK-NEXT:     Value: 0
-# CHECK-NEXT:     Section: .text (2)
+# CHECK-NEXT:     Section: .text (1)
 # CHECK-NEXT:     BaseType: Null (0x0)
 # CHECK-NEXT:     ComplexType: Null (0x0)
 # CHECK-NEXT:     StorageClass: Static (0x3)
@@ -29,7 +29,7 @@
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Name: .data
 # CHECK-NEXT:     Value: 0
-# CHECK-NEXT:     Section: .data (1)
+# CHECK-NEXT:     Section: .data (3)
 # CHECK-NEXT:     BaseType: Null (0x0)
 # CHECK-NEXT:     ComplexType: Null (0x0)
 # CHECK-NEXT:     StorageClass: Static (0x3)
@@ -38,7 +38,7 @@
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Name: MessageBoxA
 # CHECK-NEXT:     Value: 80
-# CHECK-NEXT:     Section: .text (2)
+# CHECK-NEXT:     Section: .text (1)
 # CHECK-NEXT:     BaseType: Null (0x0)
 # CHECK-NEXT:     ComplexType: Null (0x0)
 # CHECK-NEXT:     StorageClass: External (0x2)
@@ -47,7 +47,7 @@
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Name: ExitProcess
 # CHECK-NEXT:     Value: 64
-# CHECK-NEXT:     Section: .text (2)
+# CHECK-NEXT:     Section: .text (1)
 # CHECK-NEXT:     BaseType: Null (0x0)
 # CHECK-NEXT:     ComplexType: Null (0x0)
 # CHECK-NEXT:     StorageClass: External (0x2)
@@ -56,7 +56,7 @@
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Name: message
 # CHECK-NEXT:     Value: 6
-# CHECK-NEXT:     Section: .text2 (3)
+# CHECK-NEXT:     Section: .text2
 # CHECK-NEXT:     BaseType: Null (0x0)
 # CHECK-NEXT:     ComplexType: Null (0x0)
 # CHECK-NEXT:     StorageClass: Static (0x3)
@@ -65,7 +65,7 @@
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Name: main
 # CHECK-NEXT:     Value: 0
-# CHECK-NEXT:     Section: .text (2)
+# CHECK-NEXT:     Section: .text (1)
 # CHECK-NEXT:     BaseType: Null (0x0)
 # CHECK-NEXT:     ComplexType: Null (0x0)
 # CHECK-NEXT:     StorageClass: External (0x2)
@@ -74,7 +74,7 @@
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Name: caption
 # CHECK-NEXT:     Value: 0
-# CHECK-NEXT:     Section: .text2 (3)
+# CHECK-NEXT:     Section: .text2
 # CHECK-NEXT:     BaseType: Null (0x0)
 # CHECK-NEXT:     ComplexType: Null (0x0)
 # CHECK-NEXT:     StorageClass: Static (0x3)
diff --git a/test/COFF/timestamp.test b/test/COFF/timestamp.test
new file mode 100644
index 0000000..7e5f79f
--- /dev/null
+++ b/test/COFF/timestamp.test
@@ -0,0 +1,18 @@
+rm %t.*.exe
+RUN: yaml2obj %p/Inputs/generic.yaml > %t.obj
+RUN: lld-link %t.obj /debug /Brepro /entry:main /nodefaultlib /out:%t.1.exe
+RUN: lld-link %t.obj /debug /Brepro /entry:main /nodefaultlib /out:%t.2.exe
+RUN: lld-link %t.obj /debug /timestamp:0 /entry:main /nodefaultlib /out:%t.3.exe
+RUN: llvm-readobj -file-headers -coff-debug-directory %t.1.exe | FileCheck %s --check-prefix=HASH
+RUN: llvm-readobj -file-headers -coff-debug-directory %t.2.exe | FileCheck %s --check-prefix=HASH
+RUN: llvm-readobj -file-headers -coff-debug-directory %t.3.exe | FileCheck %s --check-prefix=ZERO
+
+HASH: ImageFileHeader {
+HASH: TimeDateStamp: [[STAMP:.*]]
+HASH: DebugDirectory [
+HASH: TimeDateStamp: [[STAMP]]
+
+ZERO: ImageFileHeader {
+ZERO: TimeDateStamp: 1970-01-01 00:00:00 (0x0)
+ZERO: DebugDirectory [
+ZERO: TimeDateStamp: 1970-01-01 00:00:00 (0x0)
diff --git a/test/COFF/undefined-symbol-cv.s b/test/COFF/undefined-symbol-cv.s
new file mode 100644
index 0000000..be57832
--- /dev/null
+++ b/test/COFF/undefined-symbol-cv.s
@@ -0,0 +1,61 @@
+# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s
+# RUN: not lld-link /out:%t.exe %t.obj 2>&1 | FileCheck %s
+
+# CHECK: error: undefined symbol: ?foo@@YAHXZ
+# CHECK-NEXT: >>> referenced by file1.cpp:1
+# CHECK-NEXT: >>>               {{.*}}.obj:(main)
+# CHECK-NEXT: >>> referenced by file1.cpp:2
+# CHECK-NEXT: >>>               {{.*}}.obj:(main)
+
+# CHECK: error: undefined symbol: ?bar@@YAHXZ
+# CHECK-NEXT: >>> referenced by file2.cpp:3
+# CHECK-NEXT: >>>               {{.*}}.obj:(main)
+# CHECK-NEXT: >>> referenced by file1.cpp:4
+# CHECK-NEXT: >>>               {{.*}}.obj:(f1)
+
+# CHECK: error: undefined symbol: ?baz@@YAHXZ
+# CHECK-NEXT: >>> referenced by file1.cpp:5
+# CHECK-NEXT: >>>               {{.*}}.obj:(f2)
+
+	.cv_file	1 "file1.cpp" "EDA15C78BB573E49E685D8549286F33C" 1
+	.cv_file	2 "file2.cpp" "EDA15C78BB573E49E685D8549286F33D" 1
+
+        .section        .text,"xr",one_only,main
+.globl main
+main:
+	.cv_func_id 0
+	.cv_loc	0 1 1 0 is_stmt 0
+	call	"?foo@@YAHXZ"
+	.cv_loc	0 1 2 0
+	call	"?foo@@YAHXZ"
+	.cv_loc	0 2 3 0
+	call	"?bar@@YAHXZ"
+.Lfunc_end0:
+
+f1:
+	.cv_func_id 1
+	.cv_loc	1 1 4 0 is_stmt 0
+	call	"?bar@@YAHXZ"
+.Lfunc_end1:
+
+        .section        .text,"xr",one_only,f2
+.globl f2
+f2:
+	.cv_func_id 2
+	.cv_loc	2 1 5 0 is_stmt 0
+	call	"?baz@@YAHXZ"
+.Lfunc_end2:
+
+	.section	.debug$S,"dr",associative,main
+	.long	4
+	.cv_linetable	0, main, .Lfunc_end0
+	.cv_linetable	1, f1, .Lfunc_end1
+
+	.section	.debug$S,"dr",associative,f2
+	.long	4
+	.cv_linetable	2, f2, .Lfunc_end2
+
+	.section	.debug$S,"dr"
+	.long	4
+	.cv_filechecksums
+	.cv_stringtable
diff --git a/test/COFF/undefined-symbol.s b/test/COFF/undefined-symbol.s
new file mode 100644
index 0000000..ee146ad
--- /dev/null
+++ b/test/COFF/undefined-symbol.s
@@ -0,0 +1,29 @@
+# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s
+# RUN: not lld-link /out:%t.exe %t.obj 2>&1 | FileCheck %s
+
+# CHECK: error: undefined symbol: ?foo@@YAHXZ
+# CHECK-NEXT: >>> referenced by {{.*}}.obj:(main)
+# CHECK-NEXT: >>> referenced by {{.*}}.obj:(main)
+
+# CHECK: error: undefined symbol: ?bar@@YAHXZ
+# CHECK-NEXT: >>> referenced by {{.*}}.obj:(main)
+# CHECK-NEXT: >>> referenced by {{.*}}.obj:(f1)
+
+# CHECK: error: undefined symbol: ?baz@@YAHXZ
+# CHECK-NEXT: >>> referenced by {{.*}}.obj:(f2)
+
+        .section        .text,"xr",one_only,main
+.globl main
+main:
+	call	"?foo@@YAHXZ"
+	call	"?foo@@YAHXZ"
+	call	"?bar@@YAHXZ"
+
+f1:
+	call	"?bar@@YAHXZ"
+.Lfunc_end1:
+
+        .section        .text,"xr",one_only,f2
+.globl f2
+f2:
+	call	"?baz@@YAHXZ"
diff --git a/test/COFF/unwind.test b/test/COFF/unwind.test
index 2415b05..5b74aa7 100644
--- a/test/COFF/unwind.test
+++ b/test/COFF/unwind.test
@@ -4,12 +4,24 @@
 # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=HEADER %s
 # RUN: llvm-objdump -unwind-info %t.exe | FileCheck -check-prefix=UNWIND %s
 #
-# HEADER: ExceptionTableRVA: 0x1000
+# RUN: lld-link /merge:.pdata=.rdata /out:%t.exe /entry:main %t.obj
+# RUN: llvm-readobj -file-headers -sections %t.exe | FileCheck -check-prefix=HEADER-MERGE %s
+#
+# HEADER: ExceptionTableRVA: 0x3000
+#
+# FIXME: llvm-readobj currently does not understand files with .pdata merged
+# into .rdata. But we can at least check that the section headers look correct.
+#
+# HEADER-MERGE: ExceptionTableRVA: 0x2004
+# HEADER-MERGE-NEXT: ExceptionTableSize: 0x30
+# HEADER-MERGE: Name: .rdata
+# HEADER-MERGE-NEXT: VirtualSize: 0x78
+# HEADER-MERGE-NEXT: VirtualAddress: 0x2000
 #
 # UNWIND: Function Table:
-# UNWIND:   Start Address: 0x2000
-# UNWIND:   End Address: 0x201b
-# UNWIND:   Unwind Info Address: 0x3000
+# UNWIND:   Start Address: 0x1000
+# UNWIND:   End Address: 0x101b
+# UNWIND:   Unwind Info Address: 0x2004
 # UNWIND:     Version: 1
 # UNWIND:     Flags: 1 UNW_ExceptionHandler
 # UNWIND:     Size of prolog: 18
@@ -24,27 +36,27 @@
 # UNWIND:       0x04: UOP_AllocSmall 24
 # UNWIND:       0x00: UOP_PushMachFrame w/o error code
 # UNWIND: Function Table:
-# UNWIND:   Start Address: 0x2012
-# UNWIND:   End Address: 0x2012
-# UNWIND:   Unwind Info Address: 0x301c
+# UNWIND:   Start Address: 0x1012
+# UNWIND:   End Address: 0x1012
+# UNWIND:   Unwind Info Address: 0x2020
 # UNWIND:     Version: 1
 # UNWIND:     Flags: 4 UNW_ChainInfo
 # UNWIND:     Size of prolog: 0
 # UNWIND:     Number of Codes: 0
 # UNWIND:     No frame pointer used
 # UNWIND: Function Table:
-# UNWIND:   Start Address: 0x201b
-# UNWIND:   End Address: 0x201c
-# UNWIND:   Unwind Info Address: 0x302c
+# UNWIND:   Start Address: 0x101b
+# UNWIND:   End Address: 0x101c
+# UNWIND:   Unwind Info Address: 0x2030
 # UNWIND:     Version: 1
 # UNWIND:     Flags: 0
 # UNWIND:     Size of prolog: 0
 # UNWIND:     Number of Codes: 0
 # UNWIND:     No frame pointer used
 # UNWIND: Function Table:
-# UNWIND:   Start Address: 0x201c
-# UNWIND:   End Address: 0x2039
-# UNWIND:   Unwind Info Address: 0x3034
+# UNWIND:   Start Address: 0x101c
+# UNWIND:   End Address: 0x1039
+# UNWIND:   Unwind Info Address: 0x2038
 # UNWIND:     Version: 1
 # UNWIND:     Flags: 0
 # UNWIND:     Size of prolog: 14
@@ -122,6 +134,10 @@
       - VirtualAddress:  44
         SymbolName:      .xdata
         Type:            IMAGE_REL_AMD64_ADDR32NB
+  - Name:            .rdata
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     00000000
 symbols:
   - Name:            .text
     Value:           0
diff --git a/test/ELF/Inputs/mips-micro-gp0-non-zero.o b/test/ELF/Inputs/mips-micro-gp0-non-zero.o
new file mode 100644
index 0000000..abd67bc
--- /dev/null
+++ b/test/ELF/Inputs/mips-micro-gp0-non-zero.o
Binary files differ
diff --git a/test/ELF/Inputs/mips-n64-gp0-non-zero.o b/test/ELF/Inputs/mips-n64-gp0-non-zero.o
new file mode 100644
index 0000000..43b930b
--- /dev/null
+++ b/test/ELF/Inputs/mips-n64-gp0-non-zero.o
Binary files differ
diff --git a/test/ELF/Inputs/ppc64-func-global-entry.s b/test/ELF/Inputs/ppc64-func-global-entry.s
new file mode 100644
index 0000000..5987db6
--- /dev/null
+++ b/test/ELF/Inputs/ppc64-func-global-entry.s
@@ -0,0 +1,35 @@
+	.text
+	.abiversion 2
+	.globl	foo_external_diff       # -- Begin function foo_external_diff
+	.p2align	4
+	.type	foo_external_diff,@function
+foo_external_diff:                      # @foo_external_diff
+.Lfunc_begin0:
+.Lfunc_gep0:
+	addis 2, 12, .TOC.-.Lfunc_gep0@ha
+	addi 2, 2, .TOC.-.Lfunc_gep0@l
+.Lfunc_lep0:
+	.localentry	foo_external_diff, .Lfunc_lep0-.Lfunc_gep0
+# %bb.0:                                # %entry
+	addis 5, 2, .LC0@toc@ha
+	add 3, 4, 3
+	ld 5, .LC0@toc@l(5)
+	lwz 5, 0(5)
+	add 3, 3, 5
+	extsw 3, 3
+	blr
+	.long	0
+	.quad	0
+.Lfunc_end0:
+	.size	foo_external_diff, .Lfunc_end0-.Lfunc_begin0
+                                        # -- End function
+	.section	.toc,"aw",@progbits
+.LC0:
+	.tc glob2[TC],glob2
+	.type	glob2,@object           # @glob2
+	.data
+	.globl	glob2
+	.p2align	2
+glob2:
+	.long	10                      # 0xa
+	.size	glob2, 4
diff --git a/test/ELF/Inputs/ppc64-func-local-entry.s b/test/ELF/Inputs/ppc64-func-local-entry.s
new file mode 100644
index 0000000..fc0a72d
--- /dev/null
+++ b/test/ELF/Inputs/ppc64-func-local-entry.s
@@ -0,0 +1,16 @@
+	.text
+	.abiversion 2
+	.globl	foo_external_same       # -- Begin function foo_external_same
+	.p2align	4
+	.type	foo_external_same,@function
+foo_external_same:                      # @foo_external_same
+.Lfunc_begin0:
+# %bb.0:                                # %entry
+	add 3, 4, 3
+	extsw 3, 3
+	blr
+	.long	0
+	.quad	0
+.Lfunc_end0:
+	.size	foo_external_same, .Lfunc_end0-.Lfunc_begin0
+                                        # -- End function
diff --git a/test/ELF/Inputs/ppc64-func.s b/test/ELF/Inputs/ppc64-func.s
new file mode 100644
index 0000000..745faf8
--- /dev/null
+++ b/test/ELF/Inputs/ppc64-func.s
@@ -0,0 +1,14 @@
+    .text
+    .abiversion 2
+    .globl  foo_not_shared
+    .p2align        4
+    .type   foo_not_shared,@function
+
+foo_not_shared:
+.Lfunc_begin0:
+  li 3, 55
+  blr
+  .long   0
+  .quad   0
+.Lfunc_end0:
+  .size foo_not_shared, .Lfunc_end0-.Lfunc_begin0
diff --git a/test/ELF/Inputs/ppc64-tls.s b/test/ELF/Inputs/ppc64-tls.s
new file mode 100644
index 0000000..11d1d12
--- /dev/null
+++ b/test/ELF/Inputs/ppc64-tls.s
@@ -0,0 +1,20 @@
+	.text
+	.abiversion 2
+	.type	a,@object # @a
+	.type	b,@object # @a
+	.type	c,@object # @a
+	.section	.tdata,"awT",@progbits
+	.globl	a
+a:
+	.long	10                      # 0xa
+	.size	a, 4
+
+	.globl	b
+b:
+	.long	10                      # 0xa
+	.size	b, 4
+
+	.globl	c
+c:
+	.long	10                      # 0xa
+	.size	c, 4
diff --git a/test/ELF/Inputs/shared-ppc64.s b/test/ELF/Inputs/shared-ppc64.s
index b0117ac..0e1ecf7 100644
--- a/test/ELF/Inputs/shared-ppc64.s
+++ b/test/ELF/Inputs/shared-ppc64.s
@@ -1,9 +1,14 @@
-.section        ".opd","aw"
-.global bar
-bar:
-.quad   .Lbar,.TOC.@tocbase,0
-.quad   .Lbar,0,0
+    .text
+    .abiversion 2
+    .globl  foo
+    .p2align        4
+    .type   foo,@function
 
-.text
-.Lbar:
-        blr
+foo:
+.Lfunc_begin0:
+  li 3, 55
+  blr
+  .long   0
+  .quad   0
+.Lfunc_end0:
+  .size foo, .Lfunc_end0-.Lfunc_begin0
diff --git a/test/ELF/Inputs/undef-bad-debug.s b/test/ELF/Inputs/undef-bad-debug.s
index c887b28..e3e9f5e 100644
--- a/test/ELF/Inputs/undef-bad-debug.s
+++ b/test/ELF/Inputs/undef-bad-debug.s
@@ -1,7 +1,77 @@
 .section .text,"ax"
 sym:
     .quad zed6
-    
+sym2:
+    .quad zed7
+
+.section .debug_line,"",@progbits
+.Lunit:
+    .long .Lunit_end - .Lunit_start # unit length
+.Lunit_start:
+    .short 4                        # version
+    .long .Lprologue_end - .Lprologue_start # prologue length
+.Lprologue_start:
+    .byte 1                         # minimum instruction length
+    .byte 1                         # maximum operatiosn per instruction
+    .byte 1                         # default is_stmt
+    .byte -5                        # line base
+    .byte 14                        # line range
+    .byte 13                        # opcode base
+    .byte 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 # standard opcode lengths
+    .asciz "dir"                    # include directories
+    .byte 0
+    .asciz "undef-bad-debug.s"      # file names
+    .byte 1, 0, 0
+    .byte 0
+    .byte 0                         # extraneous byte
+.Lprologue_end:
+    .byte 0, 9, 2                   # DW_LNE_set_address
+    .quad sym
+    .byte 3                         # DW_LNS_advance_line
+    .byte 10
+    .byte 1                         # DW_LNS_copy
+    .byte 2                         # DW_LNS_advance_pc
+    .byte 8
+    .byte 0, 1, 1                   # DW_LNE_end_sequence
+.Lunit_end:
+
+.Lunit2:
+    .long .Lunit2_end - .Lunit2_start # unit length
+.Lunit2_start:
+    .short 4                        # version
+    .long .Lprologue2_end - .Lprologue2_start # prologue length
+.Lprologue2_start:
+    .byte 1                         # minimum instruction length
+    .byte 1                         # maximum operatiosn per instruction
+    .byte 1                         # default is_stmt
+    .byte -5                        # line base
+    .byte 14                        # line range
+    .byte 13                        # opcode base
+    .byte 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 # standard opcode lengths
+    .asciz "dir2"                   # include directories
+    .byte 0
+    .asciz "undef-bad-debug2.s"     # file names
+    .byte 1, 0, 0
+    .byte 0
+.Lprologue2_end:
+    .byte 0, 9, 2                   # DW_LNE_set_address
+    .quad sym2
+    .byte 3                         # DW_LNS_advance_line
+    .byte 10
+    .byte 1                         # DW_LNS_copy
+    .byte 2                         # DW_LNS_advance_pc
+    .byte 8
+    .byte 0, 1, 1                   # DW_LNE_end_sequence
+    .byte 0, 9, 2                   # DW_LNE_set_address
+    .quad 0x0badbeef
+    .byte 3                         # DW_LNS_advance_line
+    .byte 99
+    .byte 1                         # DW_LNS_copy
+    .byte 99                        # DW_LNS_advance_pc
+    .byte 119
+    # Missing end of sequence.
+.Lunit2_end:
+
 .section .debug_info,"",@progbits
     .long   .Lcu_end - .Lcu_start   # Length of Unit
 .Lcu_start:
@@ -9,6 +79,7 @@
     .long   .Lsection_abbrev        # Offset Into Abbrev. Section
     .byte   8                       # Address Size (in bytes)
     .byte   1                       # Abbrev [1] 0xb:0x79 DW_TAG_compile_unit
+    .long   .Lunit                  # DW_AT_stmt_list
     .byte   2                       # Abbrev [2] 0x2a:0x15 DW_TAG_variable
     .long   .Linfo_string           # DW_AT_name
                                         # DW_AT_external
@@ -17,11 +88,28 @@
     .byte   0                       # End Of Children Mark
 .Lcu_end:
 
+    .long   .Lcu2_end - .Lcu2_start # Length of Unit
+.Lcu2_start:
+    .short  4                       # DWARF version number
+    .long   .Lsection_abbrev        # Offset Into Abbrev. Section
+    .byte   8                       # Address Size (in bytes)
+    .byte   1                       # Abbrev [1] 0xb:0x79 DW_TAG_compile_unit
+    .long   .Lunit2                 # DW_AT_stmt_list
+    .byte   2                       # Abbrev [2] 0x2a:0x15 DW_TAG_variable
+    .long   .Linfo2_string          # DW_AT_name
+                                        # DW_AT_external
+    .byte   1                       # DW_AT_decl_file
+    .byte   3                       # DW_AT_decl_line
+    .byte   0                       # End Of Children Mark
+.Lcu2_end:
+
 .section .debug_abbrev,"",@progbits
 .Lsection_abbrev:
     .byte   1                       # Abbreviation Code
     .byte   17                      # DW_TAG_compile_unit
     .byte   1                       # DW_CHILDREN_yes
+    .byte   16                      # DW_AT_stmt_list
+    .byte   23                      # DW_FORM_sec_offset
     .byte   0                       # EOM(1)
     .byte   0                       # EOM(2)
     .byte   2                       # Abbreviation Code
@@ -42,3 +130,5 @@
 .section .debug_str,"MS",@progbits,1
 .Linfo_string:
     .asciz "sym"
+.Linfo2_string:
+    .asciz "sym2"
diff --git a/test/ELF/Inputs/versiondef.s b/test/ELF/Inputs/versiondef.s
new file mode 100644
index 0000000..911cc14
--- /dev/null
+++ b/test/ELF/Inputs/versiondef.s
@@ -0,0 +1,9 @@
+.text
+.globl func_impl
+func_impl:
+  ret
+.globl func_impl2
+func_impl2:
+  ret
+.symver func_impl, func@@VER2
+.symver func_impl2, func@VER
diff --git a/test/ELF/Inputs/weak-and-strong-undef.s b/test/ELF/Inputs/weak-and-strong-undef.s
deleted file mode 100644
index a5e476d..0000000
--- a/test/ELF/Inputs/weak-and-strong-undef.s
+++ /dev/null
@@ -1 +0,0 @@
-        .weak foo
diff --git a/test/ELF/aarch64-copy.s b/test/ELF/aarch64-copy.s
index ffecf2f..ffdb01b 100644
--- a/test/ELF/aarch64-copy.s
+++ b/test/ELF/aarch64-copy.s
@@ -1,7 +1,7 @@
 // REQUIRES: aarch64
 // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t.o
 // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %p/Inputs/relocation-copy.s -o %t2.o
-// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: ld.lld -shared %t2.o -soname fixed-length-string.so -o %t2.so
 // RUN: ld.lld %t.o %t2.so -o %t3
 // RUN: llvm-readobj -s -r --expand-relocs -symbols %t3 | FileCheck %s
 // RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=CODE %s
@@ -90,4 +90,4 @@
 
 // RODATA: Contents of section .rodata:
 // S(z) = 0x40014
-// RODATA-NEXT:  101c8 14000400
+// RODATA-NEXT:  10246 14000400
diff --git a/test/ELF/aarch64-cortex-a53-843419-recognize.s b/test/ELF/aarch64-cortex-a53-843419-recognize.s
index be71c29..a9d0692 100644
--- a/test/ELF/aarch64-cortex-a53-843419-recognize.s
+++ b/test/ELF/aarch64-cortex-a53-843419-recognize.s
@@ -262,7 +262,7 @@
 // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 3BFFC in unpatched output.
 // CHECK: t3_ffc_st1singlepost:
 // CHECK-NEXT:    3bffc:        37 01 00 b0     adrp    x23, #151552
-// CHECK-NEXT:    3c000:        20 70 82 4c     st1     { v0.16b }, [x1], x2
+// CHECK-NEXT:    3c000:        20 04 82 0d     st1 { v0.b }[1], [x1], x2
 // CHECK-FIX:     3c004:        1c 50 00 14     b       #82032
 // CHECK-NOFIX:   3c004:        f6 06 40 f9     ldr     x22, [x23, #8]
 // CHECK-NEXT:    3c008:        c0 03 5f d6     ret
@@ -273,7 +273,7 @@
         .space 4096 - 4
 t3_ffc_st1singlepost:
         adrp x23, dat2
-        st1 { v0.16b }, [x1], x2
+        st1 { v0.b }[1], [x1], x2
         ldr x22, [x23, :lo12:dat2]
         ret
 
@@ -438,7 +438,7 @@
 // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 4DFFC in unpatched output.
 // CHECK: t4_ffc_st1:
 // CHECK-NEXT:    4dffc:        98 00 00 f0     adrp    x24, #77824
-// CHECK-NEXT:    4e000:        20 70 00 4c     st1     { v0.16b }, [x1]
+// CHECK-NEXT:    4e000:        20 80 00 4d     st1 { v0.s }[2], [x1]
 // CHECK-NEXT:    4e004:        f6 06 40 f9     ldr     x22, [x23, #8]
 // CHECK-FIX:     4e008:        2d 08 00 14     b       #8372
 // CHECK-NOFIX:   4e008:        18 ff 3f f9     str     x24, [x24, #32760]
@@ -450,7 +450,7 @@
         .space 4096 - 4
 t4_ffc_st1:
         adrp x24, dat2
-        st1 { v0.16b }, [x1]
+        st1 { v0.s }[2], [x1]
         ldr x22, [x23, :got_lo12:dat2]
         str x24, [x24, #32760]
         ret
diff --git a/test/ELF/aarch64-thunk-pi.s b/test/ELF/aarch64-thunk-pi.s
index 91e2b7f..ddd5897 100644
--- a/test/ELF/aarch64-thunk-pi.s
+++ b/test/ELF/aarch64-thunk-pi.s
@@ -33,13 +33,13 @@
 // Expect range extension thunks for .text_low
 // adrp calculation is (PC + signed immediate) & (!0xfff)
 // CHECK: __AArch64ADRPThunk_high_target:
-// CHECK-NEXT:       10:       10 00 08 90     adrp    x16, #268435456
-// CHECK-NEXT:       14:       10 82 04 91     add     x16, x16, #288
-// CHECK-NEXT:       18:       00 02 1f d6     br      x16
+// CHECK-NEXT:       70:       10 00 08 90     adrp    x16, #268435456
+// CHECK-NEXT:       74:       10 02 03 91     add     x16, x16, #192
+// CHECK-NEXT:       78:       00 02 1f d6     br      x16
 // CHECK: __AArch64ADRPThunk_high_target2:
-// CHECK-NEXT:       1c:       10 00 08 90     adrp    x16, #268435456
-// CHECK-NEXT:       20:       10 22 00 91     add     x16, x16, #8
-// CHECK-NEXT:       24:       00 02 1f d6     br      x16
+// CHECK-NEXT:       7c:       10 00 08 90     adrp    x16, #268435456
+// CHECK-NEXT:       80:       10 22 00 91     add     x16, x16, #8
+// CHECK-NEXT:       84:       00 02 1f d6     br      x16
 
 
  .section .text_high, "ax", %progbits
@@ -50,7 +50,7 @@
  bl low_target
  ret
 // CHECK: high_target:
-// CHECK-NEXT: 10000000:        4c 00 00 94     bl      #304
+// CHECK-NEXT: 10000000:        34 00 00 94     bl      #208
 // CHECK-NEXT: 10000004:        c0 03 5f d6     ret
 
  .hidden high_target2
@@ -68,24 +68,24 @@
 
 // CHECK: __AArch64ADRPThunk_low_target2:
 // CHECK-NEXT: 10000010:	10 00 f8 90 	adrp	x16, #-268435456
-// CHECK-NEXT: 10000014:	10 22 00 91 	add	x16, x16, #8
+// CHECK-NEXT: 10000014:	10 a2 01 91 	add	x16, x16, #104
 // CHECK-NEXT: 10000018:	00 02 1f d6 	br	x16
 
 // CHECK: Disassembly of section .plt:
 // CHECK-NEXT: .plt:
-// CHECK-NEXT: 10000100:        f0 7b bf a9     stp     x16, x30, [sp, #-16]!
-// CHECK-NEXT: 10000104:        10 00 00 90     adrp    x16, #0
-// CHECK-NEXT: 10000108:        11 aa 40 f9     ldr     x17, [x16, #336]
-// CHECK-NEXT: 1000010c:        10 42 05 91     add     x16, x16, #336
-// CHECK-NEXT: 10000110:        20 02 1f d6     br      x17
-// CHECK-NEXT: 10000114:        1f 20 03 d5     nop
-// CHECK-NEXT: 10000118:        1f 20 03 d5     nop
-// CHECK-NEXT: 1000011c:        1f 20 03 d5     nop
-// CHECK-NEXT: 10000120:        10 00 00 90     adrp    x16, #0
-// CHECK-NEXT: 10000124:        11 ae 40 f9     ldr     x17, [x16, #344]
-// CHECK-NEXT: 10000128:        10 62 05 91     add     x16, x16, #344
-// CHECK-NEXT: 1000012c:        20 02 1f d6     br      x17
-// CHECK-NEXT: 10000130:        10 00 00 90     adrp    x16, #0
-// CHECK-NEXT: 10000134:        11 b2 40 f9     ldr     x17, [x16, #352]
-// CHECK-NEXT: 10000138:        10 82 05 91     add     x16, x16, #352
-// CHECK-NEXT: 1000013c:        20 02 1f d6     br      x17
+// CHECK-NEXT: 100000a0:       f0 7b bf a9     stp     x16, x30, [sp, #-16]!
+// CHECK-NEXT: 100000a4:       10 00 00 90     adrp    x16, #0
+// CHECK-NEXT: 100000a8:       11 7a 40 f9     ldr     x17, [x16, #240]
+// CHECK-NEXT: 100000ac:       10 c2 03 91     add     x16, x16, #240
+// CHECK-NEXT: 100000b0:       20 02 1f d6     br      x17
+// CHECK-NEXT: 100000b4:       1f 20 03 d5     nop
+// CHECK-NEXT: 100000b8:       1f 20 03 d5     nop
+// CHECK-NEXT: 100000bc:       1f 20 03 d5     nop
+// CHECK-NEXT: 100000c0:       10 00 00 90     adrp    x16, #0
+// CHECK-NEXT: 100000c4:       11 7e 40 f9     ldr     x17, [x16, #248]
+// CHECK-NEXT: 100000c8:       10 e2 03 91     add     x16, x16, #248
+// CHECK-NEXT: 100000cc:       20 02 1f d6     br      x17
+// CHECK-NEXT: 100000d0:       10 00 00 90     adrp    x16, #0
+// CHECK-NEXT: 100000d4:       11 82 40 f9     ldr     x17, [x16, #256]
+// CHECK-NEXT: 100000d8:       10 02 04 91     add     x16, x16, #256
+// CHECK-NEXT: 100000dc:       20 02 1f d6     br      x17
diff --git a/test/ELF/aarch64-tlsld-ldst.s b/test/ELF/aarch64-tlsld-ldst.s
new file mode 100644
index 0000000..7b9798c
--- /dev/null
+++ b/test/ELF/aarch64-tlsld-ldst.s
@@ -0,0 +1,85 @@
+// RUN: llvm-mc -triple=aarch64-linux-gnu -filetype=obj %s -o %t.o
+// RUN: ld.lld %t.o -o %t
+// RUN: llvm-objdump -d %t | FileCheck %s
+// RUN: llvm-readelf --symbols %t | FileCheck -check-prefix CHECK-SYMS %s
+// REQUIRES: aarch64
+
+        .text
+        .globl _start
+        .type _start, %function
+_start:  mrs x8, TPIDR_EL0
+
+        add x8, x8, :tprel_hi12:var0
+        ldr q20, [x8, :tprel_lo12_nc:var0]
+
+        add x8, x8, :tprel_hi12:var1
+        ldr x0, [x8, :tprel_lo12_nc:var1]
+
+        add x8, x8, :tprel_hi12:var2
+        ldr w0, [x8, :tprel_lo12_nc:var2]
+
+        add x8, x8, :tprel_hi12:var3
+        ldrh w0, [x8, :tprel_lo12_nc:var3]
+
+        add x8, x8, :tprel_hi12:var4
+        ldrb w0, [x8, :tprel_lo12_nc:var4]
+
+// CHECK: _start:
+// CHECK-NEXT:    20000:       48 d0 3b d5     mrs     x8, TPIDR_EL0
+// 0x0 + c10 = 0xc10       = tcb (16-bytes) + var0
+// CHECK-NEXT:    20004:       08 01 40 91     add     x8, x8, #0, lsl #12
+// CHECK-NEXT:    20008:       14 05 c3 3d     ldr     q20, [x8, #3088]
+// 0x1000 + 0x820 = 0x1820 = tcb + var1
+// CHECK-NEXT:    2000c:       08 05 40 91     add     x8, x8, #1, lsl #12
+// CHECK-NEXT:    20010:       00 11 44 f9     ldr     x0, [x8, #2080]
+// 0x2000 + 0x428 = 0x2428 = tcb + var2
+// CHECK-NEXT:    20014:       08 09 40 91     add     x8, x8, #2, lsl #12
+// CHECK-NEXT:    20018:       00 29 44 b9     ldr     w0, [x8, #1064]
+// 0x3000 + 0x2c  = 0x302c = tcb + var3
+// CHECK-NEXT:    2001c:       08 0d 40 91     add     x8, x8, #3, lsl #12
+// CHECK-NEXT:    20020:       00 59 40 79     ldrh    w0, [x8, #44]
+// 0x3000 + 0xc2e = 0x32ce = tcb + var4
+// CHECK-NEXT:    20024:       08 0d 40 91     add     x8, x8, #3, lsl #12
+// CHECK-NEXT:    20028:       00 b9 70 39     ldrb    w0, [x8, #3118]
+
+// 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
+
+        .globl var0
+        .globl var1
+        .globl var2
+        .globl var3
+        .globl var4
+        .type var0,@object
+        .type var1,@object
+        .type var2,@object
+        .type var3,@object
+
+.section .tbss,"awT",@nobits
+        .balign 16
+        .space 1024 * 3
+var0:
+        .quad 0
+        .quad 0
+        .size var1, 16
+        .space 1024 * 3
+var1:
+        .quad 0
+        .size var1, 8
+        .space 1024 * 3
+var2:
+        .word 0
+        .size var1, 4
+
+        .space 1024 * 3
+var3:
+        .hword 0
+        .size var2, 2
+        .space 1024 * 3
+var4:
+        .byte 0
+        .size var3, 1
+        .space 1024 * 3
diff --git a/test/ELF/arm-copy.s b/test/ELF/arm-copy.s
index dc9e362..6e304b6 100644
--- a/test/ELF/arm-copy.s
+++ b/test/ELF/arm-copy.s
@@ -1,7 +1,7 @@
 // REQUIRES: arm
 // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
 // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/relocation-copy-arm.s -o %t2.o
-// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: ld.lld -shared %t2.o -soname fixed-length-string.so -o %t2.so
 // RUN: ld.lld --hash-style=sysv %t.o %t2.so -o %t3
 // RUN: llvm-readobj -s -r --expand-relocs -symbols %t3 | FileCheck %s
 // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CODE %s
@@ -78,4 +78,4 @@
 
 // RODATA: Contents of section .rodata:
 // S(z) = 0x13004
-// RODATA-NEXT: 10114 04300100
+// RODATA-NEXT: 10160 04300100
diff --git a/test/ELF/arm-execute-only.s b/test/ELF/arm-execute-only.s
index 655a2c6..b278e07 100644
--- a/test/ELF/arm-execute-only.s
+++ b/test/ELF/arm-execute-only.s
@@ -14,24 +14,24 @@
 // RUN: llvm-readelf -l %t.so | FileCheck --check-prefix=DIFF %s
 
 // CHECK-NOT:  LOAD
-// CHECK:      LOAD           0x000000 0x00000000 0x00000000 0x0016d  0x0016d  R   0x1000
+// CHECK:      LOAD           0x000000 0x00000000 0x00000000 0x00170 0x00170  R 0x1000
 // CHECK:      LOAD           0x001000 0x00001000 0x00001000 0x{{.*}} 0x{{.*}} R E 0x1000
 // CHECK:      LOAD           0x002000 0x00002000 0x00002000 0x{{.*}} 0x{{.*}}   E 0x1000
 // CHECK:      LOAD           0x003000 0x00003000 0x00003000 0x00038  0x00038  RW  0x1000
 // CHECK-NOT:  LOAD
 
-// CHECK: 01     .dynsym .gnu.hash .hash .dynstr
+// CHECK: 01     .dynsym .dynstr .gnu.hash .hash
 // CHECK: 02     .text
 // CHECK: 03     .foo
 // CHECK: 04     .dynamic
 
 // DIFF-NOT:  LOAD
-// DIFF:      LOAD           0x000000 0x00000000 0x00000000 0x0014d 0x0014d R   0x1000
+// DIFF:      LOAD           0x000000 0x00000000 0x00000000 0x00150 0x00150 R   0x1000
 // DIFF:      LOAD           0x001000 0x00001000 0x00001000 0x0000c 0x0000c R E 0x1000
 // DIFF:      LOAD           0x002000 0x00002000 0x00002000 0x00038 0x00038 RW  0x1000
 // DIFF-NOT:  LOAD
 
-// DIFF: 01     .dynsym .gnu.hash .hash .dynstr
+// DIFF: 01     .dynsym .dynstr .gnu.hash .hash
 // DIFF: 02     .text .foo
 // DIFF: 03     .dynamic
 
diff --git a/test/ELF/arm-exidx-shared.s b/test/ELF/arm-exidx-shared.s
index bf7c2dc..bcf2955 100644
--- a/test/ELF/arm-exidx-shared.s
+++ b/test/ELF/arm-exidx-shared.s
@@ -41,5 +41,5 @@
 // CHECK-NEXT:     0x200C R_ARM_JUMP_SLOT __gxx_personality_v0
 
 // CHECK-EXTAB: Contents of section .ARM.extab:
-// 014c + 0ee4 = 0x1030 = __gxx_personality_v0(PLT)
-// CHECK-EXTAB-NEXT:  014c e40e0000 b0b0b000 00000000
+// 01d8 + 0e58 = 0x1030 = __gxx_personality_v0(PLT)
+// CHECK-EXTAB-NEXT:  01d8 580e0000 b0b0b000 00000000
diff --git a/test/ELF/arm-symbol-ordering-file.s b/test/ELF/arm-symbol-ordering-file.s
new file mode 100644
index 0000000..fe3de0d
--- /dev/null
+++ b/test/ELF/arm-symbol-ordering-file.s
@@ -0,0 +1,32 @@
+# REQUIRES: arm
+# RUN: llvm-mc -filetype=obj -triple=armv7-unknown-linux %s -o %t.o
+
+# RUN: echo ordered > %t_order.txt
+# RUN: ld.lld --symbol-ordering-file %t_order.txt %t.o -o %t2.out
+# RUN: llvm-nm -n %t2.out | FileCheck %s
+
+# CHECK: unordered1
+# CHECK-NEXT: unordered2
+# CHECK-NEXT: unordered3
+# CHECK-NEXT: ordered
+# CHECK-NEXT: unordered4
+
+.section .foo,"ax",%progbits,unique,1
+unordered1:
+.zero 1
+
+.section .foo,"ax",%progbits,unique,2
+unordered2:
+.zero 1
+
+.section .foo,"ax",%progbits,unique,3
+unordered3:
+.zero 2
+
+.section .foo,"ax",%progbits,unique,4
+unordered4:
+.zero 4
+
+.section .foo,"ax",%progbits,unique,5
+ordered:
+.zero 1
diff --git a/test/ELF/arm-thunk-nosuitable.s b/test/ELF/arm-thunk-nosuitable.s
new file mode 100644
index 0000000..1fac4a5
--- /dev/null
+++ b/test/ELF/arm-thunk-nosuitable.s
@@ -0,0 +1,33 @@
+// RUN: llvm-mc %s --arm-add-build-attributes --triple=armv7a-linux-gnueabihf --filetype=obj -o %t.o
+// RUN: ld.lld %t.o -o %t
+// RUN: llvm-objdump -triple=thumbv7a-linux-gnueabihf -d -start-address=2166784 -stop-address=2166794 %t | FileCheck %s
+// REQUIRES: ARM
+
+        // Create a conditional branch too far away from a precreated thunk
+        // section. This will need a thunk section created within range.
+        .syntax unified
+        .thumb
+
+        .section .text.0, "ax", %progbits
+        .space 2 * 1024 * 1024
+        .globl _start
+        .type _start, %function
+_start:
+        // Range of +/- 1 Megabyte, new ThunkSection will need creating after
+        // .text.1
+        beq.w target
+        .section .text.1, "ax", %progbits
+        bx lr
+
+// CHECK: _start:
+// CHECK-NEXT:   211000:        00 f0 00 80     beq.w   #0
+// CHECK: __Thumbv7ABSLongThunk_target:
+// CHECK-NEXT:   211004:        00 f0 01 90     b.w     #12582914
+// CHECK: $t.1:
+// CHECK-NEXT:   211008:        70 47   bx      lr
+
+        .section .text.2, "ax", %progbits
+        .space 12 * 1024 * 1024
+        .globl target
+        .type target, %function
+target: bx lr
diff --git a/test/ELF/arm-thunk-section-too-large.s b/test/ELF/arm-thunk-section-too-large.s
new file mode 100644
index 0000000..2b2d0d3
--- /dev/null
+++ b/test/ELF/arm-thunk-section-too-large.s
@@ -0,0 +1,21 @@
+// RUN: llvm-mc %s -triple=armv7a-linux-gnueabihf -arm-add-build-attributes -filetype=obj -o %t.o
+// RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
+// REQUIRES: ARM
+
+// CHECK: InputSection too large for range extension thunk
+        .syntax unified
+        .thumb
+        .text
+        .globl _start
+        .type _start, %function
+_start:
+        .space 2 * 1024 * 1024
+        // conditional branch has range of 1 Mb expect error as we can't place
+        // a thunk in range of the branch.
+        beq target
+        .space 2 * 1024 * 1024
+
+        .section .text.2, "ax", %progbits
+        .globl target
+        .type target, %function
+target: bx lr
diff --git a/test/ELF/as-needed-weak.s b/test/ELF/as-needed-weak.s
new file mode 100644
index 0000000..f009c72
--- /dev/null
+++ b/test/ELF/as-needed-weak.s
@@ -0,0 +1,22 @@
+# REQUIRES: x86
+
+# RUN: echo '.globl foo; .type foo, @function; foo:' | \
+# RUN:   llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t1.o
+# RUN: ld.lld -shared -o %t1.so -soname libfoo %t1.o
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2.o
+# RUN: ld.lld -o %t.exe %t2.o --as-needed %t1.so
+# RUN: llvm-readelf -dynamic-table -dyn-symbols %t.exe | FileCheck %s
+
+# 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@
+
+.globl _start
+.weak foo
+
+_start:
+  mov $foo, %eax
+  callq foo
diff --git a/test/ELF/basic-ppc.s b/test/ELF/basic-ppc.s
index cda3224..2e52514 100644
--- a/test/ELF/basic-ppc.s
+++ b/test/ELF/basic-ppc.s
@@ -65,7 +65,7 @@
 // CHECK-NEXT:     Address: 0x114
 // CHECK-NEXT:     Offset: 0x114
 // CHECK-NEXT:     Size: 16
-// CHECK-NEXT:     Link: 3
+// CHECK-NEXT:     Link: 2
 // CHECK-NEXT:     Info: 1
 // CHECK-NEXT:     AddressAlignment: 4
 // CHECK-NEXT:     EntrySize: 16
@@ -75,31 +75,13 @@
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Section {
 // CHECK-NEXT:     Index: 2
-// CHECK-NEXT:     Name: .hash
-// CHECK-NEXT:     Type: SHT_HASH (0x5)
-// CHECK-NEXT:     Flags [ (0x2)
-// CHECK-NEXT:       SHF_ALLOC (0x2)
-// CHECK-NEXT:     ]
-// CHECK-NEXT:     Address: 0x124
-// CHECK-NEXT:     Offset: 0x124
-// CHECK-NEXT:     Size: 16
-// CHECK-NEXT:     Link: 1
-// CHECK-NEXT:     Info: 0
-// CHECK-NEXT:     AddressAlignment: 4
-// CHECK-NEXT:     EntrySize: 4
-// CHECK-NEXT:     SectionData (
-// CHECK-NEXT:       0000: 00000001 00000001 00000000 00000000  |................|
-// CHECK-NEXT:     )
-// CHECK-NEXT:   }
-// CHECK-NEXT:   Section {
-// CHECK-NEXT:     Index: 3
 // CHECK-NEXT:     Name: .dynstr
 // CHECK-NEXT:     Type: SHT_STRTAB (0x3)
 // CHECK-NEXT:     Flags [ (0x2)
 // CHECK-NEXT:       SHF_ALLOC (0x2)
 // CHECK-NEXT:     ]
-// CHECK-NEXT:     Address: 0x134
-// CHECK-NEXT:     Offset: 0x134
+// CHECK-NEXT:     Address: 0x124
+// CHECK-NEXT:     Offset: 0x124
 // CHECK-NEXT:     Size: 1
 // CHECK-NEXT:     Link: 0
 // CHECK-NEXT:     Info: 0
@@ -110,6 +92,24 @@
 // CHECK-NEXT:     )
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Section {
+// CHECK-NEXT:     Index: 3
+// CHECK-NEXT:     Name: .hash
+// CHECK-NEXT:     Type: SHT_HASH (0x5)
+// CHECK-NEXT:     Flags [ (0x2)
+// CHECK-NEXT:       SHF_ALLOC (0x2)
+// CHECK-NEXT:     ]
+// CHECK-NEXT:     Address: 0x128
+// CHECK-NEXT:     Offset: 0x128
+// CHECK-NEXT:     Size: 16
+// CHECK-NEXT:     Link: 1
+// CHECK-NEXT:     Info: 0
+// CHECK-NEXT:     AddressAlignment: 4
+// CHECK-NEXT:     EntrySize: 4
+// CHECK-NEXT:     SectionData (
+// CHECK-NEXT:       0000: 00000001 00000001 00000000 00000000  |................|
+// CHECK-NEXT:     )
+// CHECK-NEXT:   }
+// CHECK-NEXT:   Section {
 // CHECK-NEXT:     Index: 4
 // CHECK-NEXT:     Name: .text
 // CHECK-NEXT:     Type: SHT_PROGBITS (0x1)
@@ -139,14 +139,14 @@
 // CHECK-NEXT:     Address: 0x2000
 // CHECK-NEXT:     Offset: 0x2000
 // CHECK-NEXT:     Size: 48
-// CHECK-NEXT:     Link: 3
+// CHECK-NEXT:     Link: 2
 // CHECK-NEXT:     Info: 0
 // CHECK-NEXT:     AddressAlignment: 4
 // CHECK-NEXT:     EntrySize: 8
 // CHECK-NEXT:     SectionData (
 // CHECK-NEXT:       0000: 00000006 00000114 0000000B 00000010  |................|
-// CHECK-NEXT:       0010: 00000005 00000134 0000000A 00000001  |.......4........|
-// CHECK-NEXT:       0020: 00000004 00000124 00000000 00000000  |.......$........|
+// CHECK-NEXT:       0010: 00000005 00000124 0000000A 00000001  |.......$........|
+// CHECK-NEXT:       0020: 00000004 00000128 00000000 00000000  |.......(........|
 // CHECK-NEXT:     )
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Section {
@@ -165,7 +165,7 @@
 // CHECK-NEXT:     AddressAlignment: 1
 // CHECK-NEXT:     EntrySize: 1
 // CHECK-NEXT:     SectionData (
-// CHECK-NEXT:       0000: 4C4C4420 312E3000 |LLD 1.0.|
+// CHECK-NEXT:       0000: 4C4C4420 312E3000                    |LLD 1.0.|
 // CHECK-NEXT:     )
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Section {
@@ -200,8 +200,8 @@
 // CHECK-NEXT:     AddressAlignment: 1
 // CHECK-NEXT:     EntrySize: 0
 // CHECK-NEXT:     SectionData (
-// CHECK-NEXT:       0000: 002E6479 6E73796D 002E6861 7368002E  |..dynsym..hash..|
-// CHECK-NEXT:       0010: 64796E73 7472002E 74657874 002E6479  |dynstr..text..dy|
+// CHECK-NEXT:       0000: 002E6479 6E73796D 002E6479 6E737472  |..dynsym..dynstr|
+// CHECK-NEXT:       0010: 002E6861 7368002E 74657874 002E6479  |..hash..text..dy|
 // CHECK-NEXT:       0020: 6E616D69 63002E63 6F6D6D65 6E74002E  |namic..comment..|
 // CHECK-NEXT:       0030: 73796D74 6162002E 73687374 72746162  |symtab..shstrtab|
 // CHECK-NEXT:       0040: 002E7374 72746162 00                 |..strtab.|
@@ -215,7 +215,7 @@
 // CHECK-NEXT:     ]
 // CHECK-NEXT:     Address: 0x0
 // CHECK-NEXT:     Offset: 0x20A1
-// CHECK-NEXT:     Size: 1
+// CHECK-NEXT:     Size: 10
 // CHECK-NEXT:     Link: 0
 // CHECK-NEXT:     Info: 0
 // CHECK-NEXT:     AddressAlignment: 1
@@ -243,8 +243,8 @@
 // CHECK-NEXT:     Offset: 0x0
 // CHECK-NEXT:     VirtualAddress: 0x0
 // CHECK-NEXT:     PhysicalAddress: 0x0
-// CHECK-NEXT:     FileSize: 309
-// CHECK-NEXT:     MemSize: 309
+// CHECK-NEXT:     FileSize: 312
+// CHECK-NEXT:     MemSize: 312
 // CHECK-NEXT:     Flags [ (0x4)
 // CHECK-NEXT:       PF_R (0x4)
 // CHECK-NEXT:     ]
diff --git a/test/ELF/basic-ppc64.s b/test/ELF/basic-ppc64.s
index 5b9896d..fd933b8 100644
--- a/test/ELF/basic-ppc64.s
+++ b/test/ELF/basic-ppc64.s
@@ -66,7 +66,7 @@
 // CHECK-NEXT:    Address: 0x1C8
 // CHECK-NEXT:    Offset: 0x1C8
 // CHECK-NEXT:    Size: 24
-// CHECK-NEXT:    Link: 3
+// CHECK-NEXT:    Link: 2
 // CHECK-NEXT:    Info: 1
 // CHECK-NEXT:    AddressAlignment: 8
 // CHECK-NEXT:    EntrySize: 24
@@ -77,31 +77,13 @@
 // CHECK-NEXT:  }
 // CHECK-NEXT:  Section {
 // CHECK-NEXT:    Index: 2
-// CHECK-NEXT:    Name: .hash (9)
-// CHECK-NEXT:    Type: SHT_HASH (0x5)
+// CHECK-NEXT:    Name: .dynstr (9)
+// CHECK-NEXT:    Type: SHT_STRTAB (0x3)
 // CHECK-NEXT:    Flags [ (0x2)
 // CHECK-NEXT:      SHF_ALLOC (0x2)
 // CHECK-NEXT:    ]
 // CHECK-NEXT:    Address: 0x1E0
 // CHECK-NEXT:    Offset: 0x1E0
-// CHECK-NEXT:    Size: 16
-// CHECK-NEXT:    Link: 1
-// CHECK-NEXT:    Info: 0
-// CHECK-NEXT:    AddressAlignment: 4
-// CHECK-NEXT:    EntrySize: 4
-// CHECK-NEXT:    SectionData (
-// CHECK-NEXT:      0000: 01000000 01000000 00000000 00000000  |................|
-// CHECK-NEXT:    )
-// CHECK-NEXT:  }
-// CHECK-NEXT:  Section {
-// CHECK-NEXT:    Index: 3
-// CHECK-NEXT:    Name: .dynstr (15)
-// CHECK-NEXT:    Type: SHT_STRTAB (0x3)
-// CHECK-NEXT:    Flags [ (0x2)
-// CHECK-NEXT:      SHF_ALLOC (0x2)
-// CHECK-NEXT:    ]
-// CHECK-NEXT:    Address: 0x1F0
-// CHECK-NEXT:    Offset: 0x1F0
 // CHECK-NEXT:    Size: 1
 // CHECK-NEXT:    Link: 0
 // CHECK-NEXT:    Info: 0
@@ -112,6 +94,24 @@
 // CHECK-NEXT:    )
 // CHECK-NEXT:  }
 // CHECK-NEXT:  Section {
+// CHECK-NEXT:    Index: 3
+// CHECK-NEXT:    Name: .hash (17)
+// CHECK-NEXT:    Type: SHT_HASH (0x5)
+// CHECK-NEXT:    Flags [ (0x2)
+// CHECK-NEXT:      SHF_ALLOC (0x2)
+// CHECK-NEXT:    ]
+// CHECK-NEXT:    Address: 0x1E4
+// CHECK-NEXT:    Offset: 0x1E4
+// CHECK-NEXT:    Size: 16
+// CHECK-NEXT:    Link: 1
+// CHECK-NEXT:    Info: 0
+// CHECK-NEXT:    AddressAlignment: 4
+// CHECK-NEXT:    EntrySize: 4
+// CHECK-NEXT:    SectionData (
+// CHECK-NEXT:      0000: 01000000 01000000 00000000 00000000  |................|
+// CHECK-NEXT:    )
+// CHECK-NEXT:  }
+// CHECK-NEXT:  Section {
 // CHECK-NEXT:    Index: 4
 // CHECK-NEXT:    Name: .text (23)
 // CHECK-NEXT:    Type: SHT_PROGBITS (0x1)
@@ -141,16 +141,16 @@
 // CHECK-NEXT:    Address: 0x20000
 // CHECK-NEXT:    Offset: 0x20000
 // CHECK-NEXT:    Size: 96
-// CHECK-NEXT:    Link: 3
+// CHECK-NEXT:    Link: 2
 // CHECK-NEXT:    Info: 0
 // CHECK-NEXT:    AddressAlignment: 8
 // CHECK-NEXT:    EntrySize: 16
 // CHECK-NEXT:    SectionData (
 // CHECK-NEXT:      0000: 06000000 00000000 C8010000 00000000  |................|
 // CHECK-NEXT:      0010: 0B000000 00000000 18000000 00000000  |................|
-// CHECK-NEXT:      0020: 05000000 00000000 F0010000 00000000  |................|
+// CHECK-NEXT:      0020: 05000000 00000000 E0010000 00000000  |................|
 // CHECK-NEXT:      0030: 0A000000 00000000 01000000 00000000  |................|
-// CHECK-NEXT:      0040: 04000000 00000000 E0010000 00000000  |................|
+// CHECK-NEXT:      0040: 04000000 00000000 E4010000 00000000  |................|
 // CHECK-NEXT:      0050: 00000000 00000000 00000000 00000000  |................|
 // CHECK-NEXT:    )
 // CHECK-NEXT:  }
@@ -170,7 +170,7 @@
 // CHECK-NEXT:    AddressAlignment: 1
 // CHECK-NEXT:    EntrySize: 1
 // CHECK-NEXT:    SectionData (
-// CHECK-NEXT:      0000: 4C4C4420 312E3000 |LLD 1.0.|
+// CHECK-NEXT:      0000: 4C4C4420 312E3000                    |LLD 1.0.|
 // CHECK-NEXT:    )
 // CHECK-NEXT:  }
 // CHECK-NEXT:  Section {
@@ -206,8 +206,8 @@
 // CHECK-NEXT:    AddressAlignment: 1
 // CHECK-NEXT:    EntrySize: 0
 // CHECK-NEXT:    SectionData (
-// CHECK-NEXT:      0000: 002E6479 6E73796D 002E6861 7368002E  |..dynsym..hash..|
-// CHECK-NEXT:      0010: 64796E73 7472002E 74657874 002E6479  |dynstr..text..dy|
+// CHECK-NEXT:      0000: 002E6479 6E73796D 002E6479 6E737472  |..dynsym..dynstr|
+// CHECK-NEXT:      0010: 002E6861 7368002E 74657874 002E6479  |..hash..text..dy|
 // CHECK-NEXT:      0020: 6E616D69 63002E63 6F6D6D65 6E74002E  |namic..comment..|
 // CHECK-NEXT:      0030: 73796D74 6162002E 73687374 72746162  |symtab..shstrtab|
 // CHECK-NEXT:      0040: 002E7374 72746162 00                 |..strtab.|
@@ -249,8 +249,8 @@
 // CHECK-NEXT:    Offset: 0x0
 // CHECK-NEXT:    VirtualAddress: 0x0
 // CHECK-NEXT:    PhysicalAddress: 0x0
-// CHECK-NEXT:    FileSize: 497
-// CHECK-NEXT:    MemSize: 497
+// CHECK-NEXT:    FileSize: 500
+// CHECK-NEXT:    MemSize: 500
 // CHECK-NEXT:    Flags [ (0x4)
 // CHECK-NEXT:      PF_R (0x4)
 // CHECK-NEXT:    ]
diff --git a/test/ELF/basic64be.s b/test/ELF/basic64be.s
index 03a4a1f..670bc0b 100644
--- a/test/ELF/basic64be.s
+++ b/test/ELF/basic64be.s
@@ -4,26 +4,11 @@
 # REQUIRES: ppc
 
 # exits with return code 42 on linux
-.section        ".opd","aw"
-.global _start
-_start:
-.quad   .Lfoo,.TOC.@tocbase,0
-
-# generate .toc and .toc1 sections to make sure that the ordering is as
-# intended (.toc before .toc1, and both before .opd).
-.section        ".toc1","aw"
-.quad          22, 37, 89, 47
-
-.section        ".toc","aw"
-.quad          45, 86, 72, 24
-
 .text
-.Lfoo:
 	li      0,1
 	li      3,42
 	sc
-
-# CHECK:      ElfHeader {
+# CHECK: ElfHeader {
 # CHECK-NEXT:   Ident {
 # CHECK-NEXT:     Magic: (7F 45 4C 46)
 # CHECK-NEXT:     Class: 64-bit (0x2)
@@ -36,18 +21,18 @@
 # CHECK-NEXT:   Type: Executable (0x2)
 # CHECK-NEXT:   Machine: EM_PPC64 (0x15)
 # CHECK-NEXT:   Version: 1
-# CHECK-NEXT:   Entry: 0x10020040
+# CHECK-NEXT:   Entry: 0x10010000
 # CHECK-NEXT:   ProgramHeaderOffset: 0x40
-# CHECK-NEXT:   SectionHeaderOffset: 0x30080
-# CHECK-NEXT:   Flags [ (0x1)
-# CHECK-NEXT:    0x1
+# CHECK-NEXT:   SectionHeaderOffset: 0x11050
+# CHECK-NEXT:   Flags [ (0x2)
+# CHECK-NEXT:     0x2
 # CHECK-NEXT:   ]
 # CHECK-NEXT:   HeaderSize: 64
 # CHECK-NEXT:   ProgramHeaderEntrySize: 56
-# CHECK-NEXT:   ProgramHeaderCount: 6
+# CHECK-NEXT:   ProgramHeaderCount: 4
 # CHECK-NEXT:   SectionHeaderEntrySize: 64
-# CHECK-NEXT:   SectionHeaderCount: 10
-# CHECK-NEXT:   StringTableSectionIndex: 8
+# CHECK-NEXT:   SectionHeaderCount: 6
+# CHECK-NEXT:   StringTableSectionIndex: 4
 # CHECK-NEXT: }
 # CHECK-NEXT: Sections [
 # CHECK-NEXT:   Section {
@@ -68,7 +53,7 @@
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Section {
 # CHECK-NEXT:     Index: 1
-# CHECK-NEXT:     Name: .text
+# CHECK-NEXT:     Name: .text (1)
 # CHECK-NEXT:     Type: SHT_PROGBITS (0x1)
 # CHECK-NEXT:     Flags [ (0x6)
 # CHECK-NEXT:       SHF_ALLOC (0x2)
@@ -82,152 +67,80 @@
 # CHECK-NEXT:     AddressAlignment: 4
 # CHECK-NEXT:     EntrySize: 0
 # CHECK-NEXT:     SectionData (
-# CHECK:          )
+# CHECK-NEXT:       0000: 38000001 3860002A 44000002           |8...8`.*D...|
+# CHECK-NEXT:     )
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Section {
 # CHECK-NEXT:     Index: 2
-# CHECK-NEXT:     Name: .toc
-# CHECK-NEXT:     Type: SHT_PROGBITS (0x1)
-# CHECK-NEXT:     Flags [ (0x3)
-# CHECK-NEXT:       SHF_ALLOC (0x2)
-# CHECK-NEXT:       SHF_WRITE (0x1)
-# CHECK-NEXT:     ]
-# CHECK-NEXT:     Address: 0x10020000
-# CHECK-NEXT:     Offset: 0x20000
-# CHECK-NEXT:     Size: 32
-# CHECK-NEXT:     Link: 0
-# CHECK-NEXT:     Info: 0
-# CHECK-NEXT:     AddressAlignment: 1
-# CHECK-NEXT:     EntrySize: 0
-# CHECK-NEXT:     SectionData (
-# CHECK-NEXT:      0000: 00000000 0000002D 00000000 00000056 |.......-.......V|
-# CHECK-NEXT:      0010: 00000000 00000048 00000000 00000018 |.......H........|
-# CHECK-NEXT:     )
-# CHECK-NEXT:   }
-# CHECK-NEXT:   Section {
-# CHECK-NEXT:     Index: 3
-# CHECK-NEXT:     Name: .toc1
-# CHECK-NEXT:     Type: SHT_PROGBITS (0x1)
-# CHECK-NEXT:     Flags [ (0x3)
-# CHECK-NEXT:       SHF_ALLOC (0x2)
-# CHECK-NEXT:       SHF_WRITE (0x1)
-# CHECK-NEXT:     ]
-# CHECK-NEXT:     Address: 0x10020020
-# CHECK-NEXT:     Offset: 0x20020
-# CHECK-NEXT:     Size: 32
-# CHECK-NEXT:     Link: 0
-# CHECK-NEXT:     Info: 0
-# CHECK-NEXT:     AddressAlignment: 1
-# CHECK-NEXT:     EntrySize: 0
-# CHECK-NEXT:     SectionData (
-# CHECK-NEXT:       0000: 00000000 00000016 00000000 00000025  |...............%|
-# CHECK-NEXT:       0010: 00000000 00000059 00000000 0000002F  |.......Y......./|
-# CHECK-NEXT:     )
-# CHECK-NEXT:   }
-# CHECK-NEXT:   Section {
-# CHECK-NEXT:     Index: 4
-# CHECK-NEXT:     Name: .opd
-# CHECK-NEXT:     Type: SHT_PROGBITS (0x1)
-# CHECK-NEXT:     Flags [ (0x3)
-# CHECK-NEXT:       SHF_ALLOC (0x2)
-# CHECK-NEXT:       SHF_WRITE (0x1)
-# CHECK-NEXT:     ]
-# CHECK-NEXT:     Address: 0x10020040
-# CHECK-NEXT:     Offset: 0x20040
-# CHECK-NEXT:     Size: 24
-# CHECK-NEXT:     Link: 0
-# CHECK-NEXT:     Info: 0
-# CHECK-NEXT:     AddressAlignment: 1
-# CHECK-NEXT:     EntrySize: 0
-# CHECK-NEXT:     SectionData (
-# CHECK-NEXT:       0000: 00000000 10010000 00000000 10038000 |................|
-# CHECK-NEXT:       0010: 00000000 00000000                   |........|
-# CHECK-NEXT:     )
-# CHECK-NEXT:   }
-# CHECK-NEXT:   Section {
-# CHECK-NEXT:     Index: 5
-# CHECK-NEXT:     Name: .got
-# CHECK-NEXT:     Type: SHT_PROGBITS
-# CHECK-NEXT:     Flags [
-# CHECK-NEXT:       SHF_ALLOC
-# CHECK-NEXT:       SHF_WRITE
-# CHECK-NEXT:     ]
-# CHECK-NEXT:     Address: 0x10030000
-# CHECK-NEXT:     Offset: 0x30000
-# CHECK-NEXT:     Size: 0
-# CHECK-NEXT:     Link: 0
-# CHECK-NEXT:     Info: 0
-# CHECK-NEXT:     AddressAlignment: 8
-# CHECK-NEXT:     EntrySize: 0
-# CHECK-NEXT:     SectionData (
-# CHECK-NEXT:     )
-# CHECK-NEXT:   }
-# CHECK-NEXT:   Section {
-# CHECK-NEXT:     Index: 6
-# CHECK-NEXT:     Name: .comment
+# CHECK-NEXT:     Name: .comment (7)
 # CHECK-NEXT:     Type: SHT_PROGBITS (0x1)
 # CHECK-NEXT:     Flags [ (0x30)
 # CHECK-NEXT:       SHF_MERGE (0x10)
 # CHECK-NEXT:       SHF_STRINGS (0x20)
 # CHECK-NEXT:     ]
 # CHECK-NEXT:     Address: 0x0
-# CHECK-NEXT:     Offset: 0x30000
+# CHECK-NEXT:     Offset: 0x11000
 # CHECK-NEXT:     Size: 8
 # CHECK-NEXT:     Link: 0
 # CHECK-NEXT:     Info: 0
 # CHECK-NEXT:     AddressAlignment: 1
 # CHECK-NEXT:     EntrySize: 1
 # CHECK-NEXT:     SectionData (
-# CHECK-NEXT:         0000: 4C4C4420 312E3000 |LLD 1.0.|
+# CHECK-NEXT:       0000: 4C4C4420 312E3000                    |LLD 1.0.|
 # CHECK-NEXT:     )
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Section {
-# CHECK-NEXT:     Index: 7
-# CHECK-NEXT:     Name: .symtab
+# CHECK-NEXT:     Index: 3
+# CHECK-NEXT:     Name: .symtab (16)
 # CHECK-NEXT:     Type: SHT_SYMTAB (0x2)
 # CHECK-NEXT:     Flags [ (0x0)
 # CHECK-NEXT:     ]
 # CHECK-NEXT:     Address: 0x0
-# CHECK-NEXT:     Offset: 0x30008
-# CHECK-NEXT:     Size: 48
-# CHECK-NEXT:     Link: 9
+# CHECK-NEXT:     Offset: 0x11008
+# CHECK-NEXT:     Size: 24
+# CHECK-NEXT:     Link: 5
 # CHECK-NEXT:     Info: 1
 # CHECK-NEXT:     AddressAlignment: 8
 # CHECK-NEXT:     EntrySize: 24
 # CHECK-NEXT:     SectionData (
-# CHECK:          )
+# CHECK-NEXT:       0000: 00000000 00000000 00000000 00000000  |................|
+# CHECK-NEXT:       0010: 00000000 00000000                    |........|
+# CHECK-NEXT:     )
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Section {
-# CHECK-NEXT:     Index: 8
-# CHECK-NEXT:     Name: .shstrtab
-# CHECK-NEXT:     Type: SHT_STRTAB
-# CHECK-NEXT:     Flags [
-# CHECK-NEXT:     ]
-# CHECK-NEXT:     Address: 0x0
-# CHECK-NEXT:     Offset: 0x30038
-# CHECK-NEXT:     Size: 63
-# CHECK-NEXT:     Link: 0
-# CHECK-NEXT:     Info: 0
-# CHECK-NEXT:     AddressAlignment: 1
-# CHECK-NEXT:     EntrySize: 0
-# CHECK-NEXT:     SectionData (
-# CHECK:          )
-# CHECK-NEXT:   }
-# CHECK-NEXT:   Section {
-# CHECK-NEXT:     Index: 9
-# CHECK-NEXT:     Name: .strtab
-# CHECK-NEXT:     Type: SHT_STRTAB
+# CHECK-NEXT:     Index: 4
+# CHECK-NEXT:     Name: .shstrtab (24)
+# CHECK-NEXT:     Type: SHT_STRTAB (0x3)
 # CHECK-NEXT:     Flags [ (0x0)
 # CHECK-NEXT:     ]
 # CHECK-NEXT:     Address: 0x0
-# CHECK-NEXT:     Offset: 0x30077
-# CHECK-NEXT:     Size: 8
+# CHECK-NEXT:     Offset: 0x11020
+# CHECK-NEXT:     Size: 42
 # CHECK-NEXT:     Link: 0
 # CHECK-NEXT:     Info: 0
 # CHECK-NEXT:     AddressAlignment: 1
 # CHECK-NEXT:     EntrySize: 0
 # CHECK-NEXT:     SectionData (
-# CHECK-NEXT:       0000: 005F7374 61727400                    |._start.|
+# CHECK-NEXT:       0000: 002E7465 7874002E 636F6D6D 656E7400  |..text..comment.|
+# CHECK-NEXT:       0010: 2E73796D 74616200 2E736873 74727461  |.symtab..shstrta|
+# CHECK-NEXT:       0020: 62002E73 74727461 6200               |b..strtab.|
+# CHECK-NEXT:     )
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Section {
+# CHECK-NEXT:     Index: 5
+# CHECK-NEXT:     Name: .strtab (34)
+# CHECK-NEXT:     Type: SHT_STRTAB (0x3)
+# CHECK-NEXT:     Flags [ (0x0)
+# CHECK-NEXT:     ]
+# CHECK-NEXT:     Address: 0x0
+# CHECK-NEXT:     Offset: 0x1104A
+# CHECK-NEXT:     Size: 1
+# CHECK-NEXT:     Link: 0
+# CHECK-NEXT:     Info: 0
+# CHECK-NEXT:     AddressAlignment: 1
+# CHECK-NEXT:     EntrySize: 0
+# CHECK-NEXT:     SectionData (
+# CHECK-NEXT:       0000: 00                                   |.|
 # CHECK-NEXT:     )
 # CHECK-NEXT:   }
 # CHECK-NEXT: ]
@@ -237,74 +150,49 @@
 # CHECK-NEXT:     Offset: 0x40
 # CHECK-NEXT:     VirtualAddress: 0x10000040
 # CHECK-NEXT:     PhysicalAddress: 0x10000040
-# CHECK-NEXT:     FileSize: 336
-# CHECK-NEXT:     MemSize: 336
-# CHECK-NEXT:     Flags [
-# CHECK-NEXT:       PF_R
+# CHECK-NEXT:     FileSize: 224
+# CHECK-NEXT:     MemSize: 224
+# CHECK-NEXT:     Flags [ (0x4)
+# CHECK-NEXT:       PF_R (0x4)
 # CHECK-NEXT:     ]
 # CHECK-NEXT:     Alignment: 8
 # CHECK-NEXT:   }
-# CHECK-NEXT:  ProgramHeader {
-# CHECK-NEXT:    Type: PT_LOAD (0x1)
-# CHECK-NEXT:    Offset: 0x0
-# CHECK-NEXT:    VirtualAddress: 0x10000000
-# CHECK-NEXT:    PhysicalAddress: 0x10000000
-# CHECK-NEXT:    FileSize: 400
-# CHECK-NEXT:    MemSize: 400
-# CHECK-NEXT:    Flags [
-# CHECK-NEXT:      PF_R
-# CHECK-NEXT:    ]
-# CHECK-NEXT:    Alignment: 65536
-# CHECK-NEXT:  }
-# CHECK-NEXT:  ProgramHeader {
-# CHECK-NEXT:    Type: PT_LOAD (0x1)
-# CHECK-NEXT:    Offset: 0x10000
-# CHECK-NEXT:    VirtualAddress: 0x10010000
-# CHECK-NEXT:    PhysicalAddress: 0x10010000
-# CHECK-NEXT:    FileSize: 12
-# CHECK-NEXT:    MemSize: 12
-# CHECK-NEXT:    Flags [ (0x5)
-# CHECK-NEXT:      PF_R (0x4)
-# CHECK-NEXT:      PF_X (0x1)
-# CHECK-NEXT:    ]
-# CHECK-NEXT:    Alignment: 65536
-# CHECK-NEXT:  }
-# CHECK-NEXT:  ProgramHeader {
-# CHECK-NEXT:    Type: PT_LOAD (0x1)
-# CHECK-NEXT:    Offset: 0x20000
-# CHECK-NEXT:    VirtualAddress: 0x10020000
-# CHECK-NEXT:    PhysicalAddress: 0x10020000
-# CHECK-NEXT:    FileSize: 65536
-# CHECK-NEXT:    MemSize: 65536
-# CHECK-NEXT:    Flags [ (0x6)
-# CHECK-NEXT:      PF_R (0x4)
-# CHECK-NEXT:      PF_W (0x2)
-# CHECK-NEXT:    ]
-# CHECK-NEXT:    Alignment: 65536
-# CHECK-NEXT:  }
-# CHECK-NEXT:  ProgramHeader {
-# CHECK-NEXT:    Type: PT_GNU_RELRO
-# CHECK-NEXT:    Offset: 0x30000
-# CHECK-NEXT:    VirtualAddress: 0x10030000
-# CHECK-NEXT:    PhysicalAddress: 0x10030000
-# CHECK-NEXT:    FileSize: 0
-# CHECK-NEXT:    MemSize: 0
-# CHECK-NEXT:    Flags [ (0x4)
-# CHECK-NEXT:      PF_R (0x4)
-# CHECK-NEXT:    ]
-# CHECK-NEXT:    Alignment: 1
-# CHECK-NEXT:  }
-# CHECK-NEXT:  ProgramHeader {
-# CHECK-NEXT:    Type: PT_GNU_STACK (0x6474E551)
-# CHECK-NEXT:    Offset: 0x0
-# CHECK-NEXT:    VirtualAddress: 0x0
-# CHECK-NEXT:    PhysicalAddress: 0x0
-# CHECK-NEXT:    FileSize: 0
-# CHECK-NEXT:    MemSize: 0
-# CHECK-NEXT:    Flags [ (0x6)
-# CHECK-NEXT:      PF_R (0x4)
-# CHECK-NEXT:      PF_W (0x2)
-# CHECK-NEXT:    ]
-# CHECK-NEXT:    Alignment: 0
-# CHECK-NEXT:  }
+# CHECK-NEXT:   ProgramHeader {
+# CHECK-NEXT:     Type: PT_LOAD (0x1)
+# CHECK-NEXT:     Offset: 0x0
+# CHECK-NEXT:     VirtualAddress: 0x10000000
+# CHECK-NEXT:     PhysicalAddress: 0x10000000
+# CHECK-NEXT:     FileSize: 288
+# CHECK-NEXT:     MemSize: 288
+# CHECK-NEXT:     Flags [ (0x4)
+# CHECK-NEXT:       PF_R (0x4)
+# CHECK-NEXT:     ]
+# CHECK-NEXT:     Alignment: 65536
+# CHECK-NEXT:   }
+# CHECK-NEXT:   ProgramHeader {
+# CHECK-NEXT:     Type: PT_LOAD (0x1)
+# CHECK-NEXT:     Offset: 0x10000
+# CHECK-NEXT:     VirtualAddress: 0x10010000
+# CHECK-NEXT:     PhysicalAddress: 0x10010000
+# CHECK-NEXT:     FileSize: 4096
+# CHECK-NEXT:     MemSize: 4096
+# CHECK-NEXT:     Flags [ (0x5)
+# CHECK-NEXT:       PF_R (0x4)
+# CHECK-NEXT:       PF_X (0x1)
+# CHECK-NEXT:     ]
+# CHECK-NEXT:     Alignment: 65536
+# CHECK-NEXT:   }
+# CHECK-NEXT:   ProgramHeader {
+# CHECK-NEXT:     Type: PT_GNU_STACK (0x6474E551)
+# CHECK-NEXT:     Offset: 0x0
+# CHECK-NEXT:     VirtualAddress: 0x0
+# CHECK-NEXT:     PhysicalAddress: 0x0
+# CHECK-NEXT:     FileSize: 0
+# CHECK-NEXT:     MemSize: 0
+# CHECK-NEXT:     Flags [ (0x6)
+# CHECK-NEXT:       PF_R (0x4)
+# CHECK-NEXT:       PF_W (0x2)
+# CHECK-NEXT:     ]
+# CHECK-NEXT:     Alignment: 0
+# CHECK-NEXT:   }
 # CHECK-NEXT: ]
diff --git a/test/ELF/cgprofile-bad-clusters.s b/test/ELF/cgprofile-bad-clusters.s
new file mode 100644
index 0000000..77bfe69
--- /dev/null
+++ b/test/ELF/cgprofile-bad-clusters.s
@@ -0,0 +1,71 @@
+# This test checks that CallGraphSort ignores edges that would form "bad"
+# clusters.
+
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: echo "A C 1" > %t.call_graph
+# RUN: echo "E B 4" >> %t.call_graph
+# RUN: echo "C D 2" >> %t.call_graph
+# RUN: echo "B D 1" >> %t.call_graph
+# RUN: echo "F G 6" >> %t.call_graph
+# RUN: echo "G H 5" >> %t.call_graph
+# RUN: echo "H I 4" >> %t.call_graph
+# RUN: ld.lld -e A %t --call-graph-ordering-file %t.call_graph -o %t2
+# RUN: llvm-readobj -symbols %t2 | FileCheck %s
+
+    .section    .text.A,"ax",@progbits
+    .globl A
+A:
+    retq
+
+    .section    .text.D,"ax",@progbits
+D:
+    .fill 1000, 1, 0
+
+    .section    .text.E,"ax",@progbits
+E:
+    retq
+
+    .section    .text.C,"ax",@progbits
+C:
+    retq
+
+    .section    .text.B,"ax",@progbits
+B:
+    .fill 1000, 1, 0
+
+    .section    .text.F,"ax",@progbits
+F:
+    .fill (1024 * 1024) - 1, 1, 0
+
+    .section    .text.G,"ax",@progbits
+G:
+    retq
+
+    .section    .text.H,"ax",@progbits
+H:
+    retq
+
+    .section    .text.I,"ax",@progbits
+I:
+    .fill 13, 1, 0
+
+# CHECK:          Name: B
+# CHECK-NEXT:     Value: 0x201011
+# CHECK:          Name: C
+# CHECK-NEXT:     Value: 0x20100F
+# CHECK:          Name: D
+# CHECK-NEXT:     Value: 0x2013F9
+# CHECK:          Name: E
+# CHECK-NEXT:     Value: 0x201010
+# CHECK:          Name: F
+# CHECK-NEXT:     Value: 0x2017E1
+# CHECK:          Name: G
+# CHECK-NEXT:     Value: 0x3017E0
+# CHECK:          Name: H
+# CHECK-NEXT:     Value: 0x201000
+# CHECK:          Name: I
+# CHECK-NEXT:     Value: 0x201001
+# CHECK:          Name: A
+# CHECK-NEXT:     Value: 0x20100E
diff --git a/test/ELF/cgprofile-icf.s b/test/ELF/cgprofile-icf.s
new file mode 100644
index 0000000..93b7274
--- /dev/null
+++ b/test/ELF/cgprofile-icf.s
@@ -0,0 +1,53 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+# RUN: echo "A B 100" > %t.call_graph
+# RUN: echo "A C 40" >> %t.call_graph
+# RUN: echo "C D 61" >> %t.call_graph
+# RUN: ld.lld -e A %t --call-graph-ordering-file %t.call_graph -o %t.out -icf=all
+# RUN: llvm-readobj -symbols %t.out | FileCheck %s
+# RUN: ld.lld -e A %t --call-graph-ordering-file %t.call_graph -o %t2.out
+# RUN: llvm-readobj -symbols %t2.out | FileCheck %s --check-prefix=NOICF
+
+    .section    .text.D,"ax",@progbits
+    .globl  D
+D:
+    mov $60, %rax
+    retq
+
+    .section    .text.C,"ax",@progbits
+    .globl  C
+C:
+    mov $60, %rax
+    retq
+
+    .section    .text.B,"ax",@progbits
+    .globl  B
+B:
+    mov $2, %rax
+    retq
+
+    .section    .text.A,"ax",@progbits
+    .globl  A
+A:
+    mov $42, %rax
+    retq
+
+# CHECK:          Name: A
+# CHECK-NEXT:     Value: 0x201000
+# CHECK:          Name: B
+# CHECK-NEXT:     Value: 0x201010
+# CHECK:          Name: C
+# CHECK-NEXT:     Value: 0x201008
+# CHECK:          Name: D
+# CHECK-NEXT:     Value: 0x201008
+
+# NOICF:          Name: A
+# NOICF-NEXT:     Value: 0x201000
+# NOICF:          Name: B
+# NOICF-NEXT:     Value: 0x201008
+# NOICF:          Name: C
+# NOICF-NEXT:     Value: 0x201010
+# NOICF:          Name: D
+# NOICF-NEXT:     Value: 0x201018
diff --git a/test/ELF/cgprofile-txt.s b/test/ELF/cgprofile-txt.s
new file mode 100644
index 0000000..ee5149a
--- /dev/null
+++ b/test/ELF/cgprofile-txt.s
@@ -0,0 +1,185 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld -e A %t -o %t2
+# RUN: llvm-readobj -symbols %t2 | FileCheck %s --check-prefix=NOSORT
+
+# RUN: echo "A B 10" > %t.call_graph
+# RUN: echo "A B 10" >> %t.call_graph
+# RUN: echo "Aa B 80" >> %t.call_graph
+# RUN: echo "A C 40" >> %t.call_graph
+# RUN: echo "B C 30" >> %t.call_graph
+# RUN: echo "C D 90" >> %t.call_graph
+# RUN: echo "PP TS 100" >> %t.call_graph
+# RUN: echo "_init2 _init 24567837" >> %t.call_graph
+# RUN: echo "TS QC 9001" >> %t.call_graph
+# RUN: echo "TooManyPreds0 TooManyPreds 10" >> %t.call_graph
+# RUN: echo "TooManyPreds1 TooManyPreds 10" >> %t.call_graph
+# RUN: echo "TooManyPreds2 TooManyPreds 10" >> %t.call_graph
+# RUN: echo "TooManyPreds3 TooManyPreds 10" >> %t.call_graph
+# RUN: echo "TooManyPreds4 TooManyPreds 10" >> %t.call_graph
+# RUN: echo "TooManyPreds5 TooManyPreds 10" >> %t.call_graph
+# RUN: echo "TooManyPreds6 TooManyPreds 10" >> %t.call_graph
+# RUN: echo "TooManyPreds7 TooManyPreds 10" >> %t.call_graph
+# RUN: echo "TooManyPreds8 TooManyPreds 10" >> %t.call_graph
+# RUN: echo "TooManyPreds9 TooManyPreds 10" >> %t.call_graph
+# RUN: echo "TooManyPreds10 TooManyPreds 11" >> %t.call_graph
+# RUN: ld.lld -e A %t --call-graph-ordering-file %t.call_graph -o %t2
+# RUN: llvm-readobj -symbols %t2 | FileCheck %s
+
+    .section    .text.D,"ax",@progbits
+D:
+    retq
+
+    .section    .text.C,"ax",@progbits
+    .globl  C
+C:
+    retq
+
+    .section    .text.B,"ax",@progbits
+    .globl  B
+B:
+    retq
+
+    .section    .text.A,"ax",@progbits
+    .globl  A
+A:
+Aa:
+    retq
+
+    .section    .ponies,"ax",@progbits,unique,1
+    .globl TS
+TS:
+    retq
+
+    .section    .ponies,"ax",@progbits,unique,2
+    .globl PP
+PP:
+    retq
+
+    .section    .other,"ax",@progbits,unique,1
+    .globl QC
+QC:
+    retq
+
+    .section    .other,"ax",@progbits,unique,2
+    .globl GB
+GB:
+    retq
+
+    .section    .init,"ax",@progbits,unique,1
+    .globl _init
+_init:
+    retq
+
+    .section    .init,"ax",@progbits,unique,2
+    .globl _init2
+_init2:
+    retq
+
+    .section    .text.TooManyPreds,"ax",@progbits
+TooManyPreds:
+    retq
+	retq
+	retq
+	retq
+	retq
+	retq
+	retq
+	retq
+	retq
+	retq
+
+    .section    .text.TooManyPreds0,"ax",@progbits
+TooManyPreds0:
+    retq
+
+    .section    .text.TooManyPreds1,"ax",@progbits
+TooManyPreds1:
+    retq
+
+    .section    .text.TooManyPreds2,"ax",@progbits
+TooManyPreds2:
+    retq
+
+    .section    .text.TooManyPreds3,"ax",@progbits
+TooManyPreds3:
+    retq
+
+    .section    .text.TooManyPreds4,"ax",@progbits
+TooManyPreds4:
+    retq
+
+    .section    .text.TooManyPreds5,"ax",@progbits
+TooManyPreds5:
+    retq
+
+    .section    .text.TooManyPreds6,"ax",@progbits
+TooManyPreds6:
+    retq
+
+    .section    .text.TooManyPreds7,"ax",@progbits
+TooManyPreds7:
+    retq
+
+    .section    .text.TooManyPreds8,"ax",@progbits
+TooManyPreds8:
+    retq
+
+    .section    .text.TooManyPreds9,"ax",@progbits
+TooManyPreds9:
+    retq
+
+    .section    .text.TooManyPreds10,"ax",@progbits
+TooManyPreds10:
+    retq
+
+# CHECK:          Name: D
+# CHECK-NEXT:     Value: 0x201003
+# CHECK:          Name: TooManyPreds
+# CHECK-NEXT:     Value: 0x201004
+# CHECK:          Name: TooManyPreds10
+# CHECK-NEXT:     Value: 0x201018
+# CHECK:          Name: A
+# CHECK-NEXT:     Value: 0x201000
+# CHECK:          Name: B
+# CHECK-NEXT:     Value: 0x201001
+# CHECK:          Name: C
+# CHECK-NEXT:     Value: 0x201002
+# CHECK:          Name: GB
+# CHECK-NEXT:     Value: 0x20101F
+# CHECK:          Name: PP
+# CHECK-NEXT:     Value: 0x20101C
+# CHECK:          Name: QC
+# CHECK-NEXT:     Value: 0x20101E
+# CHECK:          Name: TS
+# CHECK-NEXT:     Value: 0x20101D
+# CHECK:          Name: _init
+# CHECK-NEXT:     Value: 0x201020
+# CHECK:          Name: _init2
+# CHECK-NEXT:     Value: 0x201021
+
+# NOSORT:          Name: D
+# NOSORT-NEXT:     Value: 0x201000
+# NOSORT:          Name: TooManyPreds
+# NOSORT-NEXT:     Value: 0x201004
+# NOSORT:          Name: TooManyPreds10
+# NOSORT-NEXT:     Value: 0x201018
+# NOSORT:          Name: A
+# NOSORT-NEXT:     Value: 0x201003
+# NOSORT:          Name: B
+# NOSORT-NEXT:     Value: 0x201002
+# NOSORT:          Name: C
+# NOSORT-NEXT:     Value: 0x201001
+# NOSORT:          Name: GB
+# NOSORT-NEXT:     Value: 0x20101C
+# NOSORT:          Name: PP
+# NOSORT-NEXT:     Value: 0x20101A
+# NOSORT:          Name: QC
+# NOSORT-NEXT:     Value: 0x20101B
+# NOSORT:          Name: TS
+# NOSORT-NEXT:     Value: 0x201019
+# NOSORT:          Name: _init
+# NOSORT-NEXT:     Value: 0x20101D
+# NOSORT:          Name: _init2
+# NOSORT-NEXT:     Value: 0x20101E
diff --git a/test/ELF/cgprofile-warn.s b/test/ELF/cgprofile-warn.s
new file mode 100644
index 0000000..2b30a1a
--- /dev/null
+++ b/test/ELF/cgprofile-warn.s
@@ -0,0 +1,29 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+# RUN: echo "A B 100" > %t.call_graph
+# RUN: echo "A C 40" >> %t.call_graph
+# RUN: echo "B C 30" >> %t.call_graph
+# RUN: echo "adena A 30" >> %t.call_graph
+# RUN: echo "poppy A 30" >> %t.call_graph
+# RUN: ld.lld -e A %t --call-graph-ordering-file %t.call_graph -o %t.out \
+# RUN:   -noinhibit-exec -icf=all 2>&1 | FileCheck %s
+
+    .section    .text.C,"ax",@progbits
+    .globl  C
+C:
+    mov poppy, %rax
+    retq
+
+B = 0x1234
+
+    .section    .text.A,"ax",@progbits
+    .globl  A
+A:
+    mov poppy, %rax
+    retq
+
+# CHECK: unable to order absolute symbol: B
+# CHECK: call graph file: no such symbol: adena
+# CHECK: unable to order undefined symbol: poppy
diff --git a/test/ELF/combrelocs.s b/test/ELF/combrelocs.s
index 3c8be80..595f604 100644
--- a/test/ELF/combrelocs.s
+++ b/test/ELF/combrelocs.s
@@ -4,6 +4,9 @@
 # RUN: ld.lld -shared %t.o -o %t.out
 # RUN: llvm-readobj -r --expand-relocs --dynamic-table %t.out | FileCheck %s
 
+# RUN: ld.lld -shared %t.o -o %t.out -z combreloc
+# RUN: llvm-readobj -r --expand-relocs --dynamic-table %t.out | FileCheck %s
+
 # CHECK:      Relocations [
 # CHECK-NEXT:   Section ({{.*}}) .rela.dyn {
 # CHECK-NEXT:     Relocation {
diff --git a/test/ELF/cref.s b/test/ELF/cref.s
index 01516fa..2a82f42 100644
--- a/test/ELF/cref.s
+++ b/test/ELF/cref.s
@@ -2,9 +2,12 @@
 
 // RUN: echo '.global foo; foo:' | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t1.o
 // RUN: echo '.global foo, bar; bar:' | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t2.o
+// RUN: echo '.global zed; zed:' | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %ta.o
+// RUN: rm -f %t.a
+// RUN: llvm-ar rcs %t.a %ta.o
 // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t3.o
-// RUN: ld.lld -shared -o %t1.so %t1.o -gc-sections
-// RUN: ld.lld -o /dev/null %t1.so %t2.o %t3.o -cref | FileCheck -strict-whitespace %s
+// RUN: ld.lld -shared -o %t1.so %t1.o
+// RUN: ld.lld -o /dev/null %t1.so %t2.o %t3.o %t.a -gc-sections -cref | FileCheck -strict-whitespace %s
 
 //      CHECK: Symbol                                            File
 // CHECK-NEXT: bar                                               {{.*}}2.o
@@ -14,11 +17,15 @@
 // CHECK-NEXT:                                                   {{.*}}3.o
 // CHECK-NEXT: _start                                            {{.*}}3.o
 // CHECK-NEXT: baz                                               {{.*}}3.o
+// CHECK-NEXT: zed                                               {{.*}}.a({{.*}}a.o)
+// CHECK-NEXT:                                                   {{.*}}3.o
+// CHECK-NOT:  discarded
 
-.global _start, foo, bar, baz
+.global _start, foo, bar, baz, discarded
 _start:
   call foo
   call bar
+  call zed
 localsym:
 baz:
 
diff --git a/test/ELF/dt_flags.s b/test/ELF/dt_flags.s
index 431f83d..dffaec8 100644
--- a/test/ELF/dt_flags.s
+++ b/test/ELF/dt_flags.s
@@ -2,9 +2,14 @@
 
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
 # RUN: ld.lld -shared %t -o %t.so
+
 # RUN: ld.lld -z now -z nodelete -z nodlopen -z origin -Bsymbolic %t %t.so -o %t1
-# RUN: ld.lld %t %t.so -o %t2
 # RUN: llvm-readobj -dynamic-table %t1 | FileCheck -check-prefix=FLAGS %s
+
+# RUN: ld.lld %t %t.so -o %t2
+# RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s
+
+# RUN: ld.lld -z lazy %t %t.so -o %t2
 # RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s
 
 # FLAGS: DynamicSection [
diff --git a/test/ELF/dynamic-no-rosegment.s b/test/ELF/dynamic-no-rosegment.s
index f2b5f35..b65e37d 100644
--- a/test/ELF/dynamic-no-rosegment.s
+++ b/test/ELF/dynamic-no-rosegment.s
@@ -7,9 +7,9 @@
 # CHECK-NEXT:   Tag                Type                 Name/Value
 # CHECK-NEXT:   0x0000000000000006 SYMTAB               0x120
 # CHECK-NEXT:   0x000000000000000B SYMENT               24 (bytes)
-# CHECK-NEXT:   0x0000000000000005 STRTAB               0x1D8
+# CHECK-NEXT:   0x0000000000000005 STRTAB               0x138
 # CHECK-NEXT:   0x000000000000000A STRSZ                1 (bytes)
-# CHECK-NEXT:   0x000000006FFFFEF5 GNU_HASH             0x138
-# CHECK-NEXT:   0x0000000000000004 HASH                 0x154
+# CHECK-NEXT:   0x000000006FFFFEF5 GNU_HASH             0x140
+# CHECK-NEXT:   0x0000000000000004 HASH                 0x15C
 # CHECK-NEXT:   0x0000000000000000 NULL                 0x0
 # CHECK-NEXT: ]
diff --git a/test/ELF/dynsec-at-beginning.s b/test/ELF/dynsec-at-beginning.s
new file mode 100644
index 0000000..90504c9
--- /dev/null
+++ b/test/ELF/dynsec-at-beginning.s
@@ -0,0 +1,16 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
+
+# RUN: ld.lld --hash-style=gnu -o %t1  %t -shared
+# RUN: llvm-readobj -elf-output-style=GNU -s %t1 | FileCheck %s
+
+# Dynamic symbol and dynamic strtab sections are at the beginning of
+# SHF_ALLOC sections.
+# CHECK:      .dynsym  {{.*}}   A
+# CHECK-NEXT: .dynstr  {{.*}}   A
+# CHECK-NEXT: foo      {{.*}}   A
+# CHECK-NEXT: .hash    {{.*}}   A
+# CHECK-NEXT: .text    {{.*}}   AX
+
+.section foo, "a"
+.byte 0
diff --git a/test/ELF/eh-frame-hdr-icf-fde.s b/test/ELF/eh-frame-hdr-icf-fde.s
index 54c2cd8..68de65d 100644
--- a/test/ELF/eh-frame-hdr-icf-fde.s
+++ b/test/ELF/eh-frame-hdr-icf-fde.s
@@ -52,7 +52,7 @@
 # CHECK-NEXT:   ]
 # CHECK-NEXT:   Address: 0x200178
 # CHECK-NEXT:   Offset: 0x178
-# CHECK-NEXT:   Size: 72
+# CHECK-NEXT:   Size: 76
 # CHECK-NEXT:   Link: 0
 # CHECK-NEXT:   Info: 0
 # CHECK-NEXT:   AddressAlignment: 8
@@ -62,7 +62,7 @@
 # CHECK-NEXT:     0010: 1B0C0708 90010000 14000000 1C000000
 # CHECK-NEXT:     0020: 680E0000 01000000 00000000 00000000
 # CHECK-NEXT:     0030: 14000000 34000000 520E0000 01000000
-# CHECK-NEXT:     0040: 00000000 00000000
+# CHECK-NEXT:     0040: 00000000 00000000 00000000
 # CHECK-NEXT:   )
 # CHECK-NEXT: }
 
diff --git a/test/ELF/eh-frame-hdr.s b/test/ELF/eh-frame-hdr.s
index aaeccda..0c33bc6 100644
--- a/test/ELF/eh-frame-hdr.s
+++ b/test/ELF/eh-frame-hdr.s
@@ -92,7 +92,7 @@
 // HDR-NEXT:    ]
 // HDR-NEXT:    Address: 0x200180
 // HDR-NEXT:    Offset: 0x180
-// HDR-NEXT:    Size: 96
+// HDR-NEXT:    Size: 100
 // HDR-NEXT:    Link: 0
 // HDR-NEXT:    Info: 0
 // HDR-NEXT:    AddressAlignment: 8
@@ -104,6 +104,7 @@
 // HDR-NEXT:      0030: 14000000 34000000 490E0000 01000000
 // HDR-NEXT:      0040: 00000000 00000000 14000000 4C000000
 // HDR-NEXT:      0050: 320E0000 01000000 00000000 00000000
+// HDR-NEXT:      0060: 00000000
 // HDR-NEXT:    )
 //            CIE: 14000000 00000000 017A5200 01781001 1B0C0708 90010000
 //            FDE(1): 14000000 1C000000 600E0000 01000000 00000000 00000000
diff --git a/test/ELF/eh-frame-merge.s b/test/ELF/eh-frame-merge.s
index 4b54c17..6731d90 100644
--- a/test/ELF/eh-frame-merge.s
+++ b/test/ELF/eh-frame-merge.s
@@ -27,7 +27,7 @@
 // CHECK-NEXT: ]
 // CHECK-NEXT: Address:
 // CHECK-NEXT: Offset:
-// CHECK-NEXT: Size: 96
+// CHECK-NEXT: Size: 100
 // CHECK-NEXT: Link: 0
 // CHECK-NEXT: Info: 0
 // CHECK-NEXT: AddressAlignment: 8
@@ -39,6 +39,7 @@
 // CHECK-NEXT: 0030: 14000000 34000000 D20D0000 02000000  |
 // CHECK-NEXT: 0040: 00000000 00000000 14000000 4C000000  |
 // CHECK-NEXT: 0050: B90D0000 01000000 00000000 00000000  |
+// CHECK-NEXT: 0060: 00000000
 // CHECK-NEXT: )
 
 // CHECK:      Name: foo
diff --git a/test/ELF/eh-frame-padding-no-rosegment.s b/test/ELF/eh-frame-padding-no-rosegment.s
index e106f29..6805de1 100644
--- a/test/ELF/eh-frame-padding-no-rosegment.s
+++ b/test/ELF/eh-frame-padding-no-rosegment.s
@@ -58,7 +58,7 @@
 // CHECK-NEXT: EntrySize:
 // CHECK-NEXT: SectionData (
 // CHECK-NEXT:   0000: 1C000000 00000000 017A5052 00017810
-// CHECK-NEXT:   0010: 061BBEFF FFFF1B0C 07089001 00000000
-// CHECK-NEXT:   0020: 14000000 24000000 A8FFFFFF 00000000
+// CHECK-NEXT:   0010: 061BDAFF FFFF1B0C 07089001 00000000
+// CHECK-NEXT:   0020: 14000000 24000000 C4FFFFFF 00000000
 // CHECK-NEXT:   0030: 00000000 00000000
 // CHECK-NEXT: )
diff --git a/test/ELF/ehframe-relocation.s b/test/ELF/ehframe-relocation.s
index 0213b1b..4ab44c2 100644
--- a/test/ELF/ehframe-relocation.s
+++ b/test/ELF/ehframe-relocation.s
@@ -12,7 +12,7 @@
 // CHECK-NEXT: ]
 // CHECK-NEXT: Address: 0x200120
 // CHECK-NEXT: Offset:
-// CHECK-NEXT: Size: 48
+// CHECK-NEXT: Size: 52
 // CHECK-NOT: .eh_frame
 
 // 0x200120 = 2097440
diff --git a/test/ELF/emulation.s b/test/ELF/emulation.s
index c176cc1..1a2af0f 100644
--- a/test/ELF/emulation.s
+++ b/test/ELF/emulation.s
@@ -208,8 +208,8 @@
 # PPC64-NEXT:   Entry:
 # PPC64-NEXT:   ProgramHeaderOffset: 0x40
 # PPC64-NEXT:   SectionHeaderOffset:
-# PPC64-NEXT:   Flags [ (0x1)
-# PPC64-NEXT:     0x1
+# PPC64-NEXT:   Flags [ (0x2)
+# PPC64-NEXT:     0x2
 # PPC64-NEXT:   ]
 # PPC64-NEXT:   HeaderSize: 64
 # PPC64-NEXT:   ProgramHeaderEntrySize: 56
@@ -366,8 +366,12 @@
 # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %taarch64
 # RUN: ld.lld -m aarch64linux %taarch64 -o %t2aarch64
 # RUN: llvm-readobj -file-headers %t2aarch64 | FileCheck --check-prefix=AARCH64 %s
-# RUN: ld.lld %taarch64 -o %t3aarch64
+# RUN: ld.lld -m aarch64elf %taarch64 -o %t3aarch64
 # RUN: llvm-readobj -file-headers %t3aarch64 | FileCheck --check-prefix=AARCH64 %s
+# RUN: ld.lld -m aarch64_elf64_le_vec %taarch64 -o %t4aarch64
+# RUN: llvm-readobj -file-headers %t4aarch64 | FileCheck --check-prefix=AARCH64 %s
+# RUN: ld.lld %taarch64 -o %t5aarch64
+# RUN: llvm-readobj -file-headers %t5aarch64 | FileCheck --check-prefix=AARCH64 %s
 # AARCH64:      ElfHeader {
 # AARCH64-NEXT:   Ident {
 # AARCH64-NEXT:     Magic: (7F 45 4C 46)
diff --git a/test/ELF/file-sym.s b/test/ELF/file-sym.s
deleted file mode 100644
index c349226..0000000
--- a/test/ELF/file-sym.s
+++ /dev/null
@@ -1,12 +0,0 @@
-# Check that we do not keep STT_FILE symbols in the symbol table
-
-# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
-# RUN: ld.lld %t.o -shared -o %t.so
-# RUN: llvm-readobj -symbols %t.so | FileCheck %s
-
-# REQUIRES: x86
-
-# CHECK-NOT: Name: xxx
-
-.file "xxx"
-.file ""
diff --git a/test/ELF/fill-trap-ppc.s b/test/ELF/fill-trap-ppc.s
new file mode 100644
index 0000000..da7d7cb
--- /dev/null
+++ b/test/ELF/fill-trap-ppc.s
@@ -0,0 +1,31 @@
+# REQUIRES: ppc
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t.ppc64le
+# RUN: llvm-readobj -program-headers %t.ppc64le | FileCheck %s
+# RUN: od -Ax -t x1 -N16 -j0x10ff0 %t.ppc64le | FileCheck %s -check-prefix=LE
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t.ppc64
+# RUN: llvm-readobj -program-headers %t.ppc64 | FileCheck %s
+# RUN: od -Ax -t x1 -N16 -j0x10ff0 %t.ppc64 | FileCheck %s -check-prefix=BE
+
+# CHECK: ProgramHeader {
+# CHECK:   Type: PT_LOAD
+# CHECK:        Offset: 0x10000{{$}}
+# CHECK-NEXT:   VirtualAddress:
+# CHECK-NEXT:   PhysicalAddress:
+# CHECK-NEXT:   FileSize: 4096
+# CHECK-NEXT:   MemSize:
+# CHECK-NEXT:   Flags [
+# CHECK-NEXT:     PF_R
+# CHECK-NEXT:     PF_X
+# CHECK-NEXT:   ]
+
+## Check that executable page is filled with traps at its end.
+# LE: 010ff0 08 00 e0 7f 08 00 e0 7f 08 00 e0 7f 08 00 e0 7f
+# BE: 010ff0 7f e0 00 08 7f e0 00 08 7f e0 00 08 7f e0 00 08
+
+.globl _start
+_start:
+  nop
diff --git a/test/ELF/format-binary-non-ascii.s b/test/ELF/format-binary-non-ascii.s
index 5a3ad96..36263e5 100644
--- a/test/ELF/format-binary-non-ascii.s
+++ b/test/ELF/format-binary-non-ascii.s
@@ -4,9 +4,9 @@
 # RUN: ld.lld -o %t.elf %t£.o --format=binary %t£.o
 # RUN: llvm-readobj -symbols %t.elf | FileCheck %s
 
-# CHECK: Name: _binary_{{[a-zA-Z0-9_]+}}test_ELF_Output_format_binary_non_ascii_s_tmp___o_start
-# CHECK: Name: _binary_{{[a-zA-Z0-9_]+}}test_ELF_Output_format_binary_non_ascii_s_tmp___o_end
-# CHECK: Name: _binary_{{[a-zA-Z0-9_]+}}test_ELF_Output_format_binary_non_ascii_s_tmp___o_size
+# CHECK: Name: _binary_{{[a-zA-Z0-9_]+}}test_ELF_Output_format_binary_non_ascii_s_tmp_{{[_]+}}o_start
+# CHECK: Name: _binary_{{[a-zA-Z0-9_]+}}test_ELF_Output_format_binary_non_ascii_s_tmp_{{[_]+}}o_end
+# CHECK: Name: _binary_{{[a-zA-Z0-9_]+}}test_ELF_Output_format_binary_non_ascii_s_tmp_{{[_]+}}o_size
 
 .text
 .align 4
diff --git a/test/ELF/gc-merge-local-sym.s b/test/ELF/gc-merge-local-sym.s
index b02a3a4..9cb4907 100644
--- a/test/ELF/gc-merge-local-sym.s
+++ b/test/ELF/gc-merge-local-sym.s
@@ -9,7 +9,7 @@
 // CHECK-NEXT:   SHF_MERGE
 // CHECK-NEXT:   SHF_STRINGS
 // CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x1C8
+// CHECK-NEXT: Address: 0x1FD
 // CHECK-NEXT: Offset:
 // CHECK-NEXT: Size: 4
 // CHECK-NEXT: Link: 0
diff --git a/test/ELF/gc-sections-shared.s b/test/ELF/gc-sections-shared.s
index 55b3ef5..c0ebf40 100644
--- a/test/ELF/gc-sections-shared.s
+++ b/test/ELF/gc-sections-shared.s
@@ -25,6 +25,15 @@
 # CHECK-NEXT:     Section: Undefined (0x0)
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: qux
+# CHECK-NEXT:     Value:
+# CHECK-NEXT:     Size:
+# CHECK-NEXT:     Binding: Weak
+# CHECK-NEXT:     Type:
+# CHECK-NEXT:     Other:
+# CHECK-NEXT:     Section: Undefined
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Name: bar
 # CHECK-NEXT:     Value:
 # CHECK-NEXT:     Size:
@@ -51,15 +60,6 @@
 # CHECK-NEXT:     Other:
 # CHECK-NEXT:     Section: .text
 # CHECK-NEXT:   }
-# CHECK-NEXT:   Symbol {
-# CHECK-NEXT:     Name: qux
-# CHECK-NEXT:     Value:
-# CHECK-NEXT:     Size:
-# CHECK-NEXT:     Binding: Weak
-# CHECK-NEXT:     Type:
-# CHECK-NEXT:     Other:
-# CHECK-NEXT:     Section: Undefined
-# CHECK-NEXT:   }
 # CHECK-NEXT: ]
 
 # CHECK-NOT: NEEDED
@@ -68,59 +68,7 @@
 
 # Test with %t.o at the end too.
 # RUN: ld.lld --gc-sections --export-dynamic-symbol foo -o %t --as-needed %t2.so %t3.so %t4.so %t.o
-# RUN: llvm-readobj --dynamic-table --dyn-symbols %t | FileCheck --check-prefix=CHECK2 %s
-
-# CHECK2:      DynamicSymbols [
-# CHECK2-NEXT:   Symbol {
-# CHECK2-NEXT:     Name:
-# CHECK2-NEXT:     Value:
-# CHECK2-NEXT:     Size:
-# CHECK2-NEXT:     Binding: Local
-# CHECK2-NEXT:     Type:
-# CHECK2-NEXT:     Other:
-# CHECK2-NEXT:     Section: Undefined (0x0)
-# CHECK2-NEXT:   }
-# CHECK2-NEXT:   Symbol {
-# CHECK2-NEXT:     Name: bar
-# CHECK2-NEXT:     Value:
-# CHECK2-NEXT:     Size:
-# CHECK2-NEXT:     Binding: Global
-# CHECK2-NEXT:     Type:
-# CHECK2-NEXT:     Other:
-# CHECK2-NEXT:     Section: .text
-# CHECK2-NEXT:   }
-# CHECK2-NEXT:   Symbol {
-# CHECK2-NEXT:     Name: baz
-# CHECK2-NEXT:     Value:
-# CHECK2-NEXT:     Size:
-# CHECK2-NEXT:     Binding: Global
-# CHECK2-NEXT:     Type:
-# CHECK2-NEXT:     Other:
-# CHECK2-NEXT:     Section: Undefined
-# CHECK2-NEXT:   }
-# CHECK2-NEXT:   Symbol {
-# CHECK2-NEXT:     Name: qux
-# CHECK2-NEXT:     Value:
-# CHECK2-NEXT:     Size:
-# CHECK2-NEXT:     Binding: Weak
-# CHECK2-NEXT:     Type:
-# CHECK2-NEXT:     Other:
-# CHECK2-NEXT:     Section: Undefined
-# CHECK2-NEXT:   }
-# CHECK2-NEXT:   Symbol {
-# CHECK2-NEXT:     Name: foo
-# CHECK2-NEXT:     Value:
-# CHECK2-NEXT:     Size:
-# CHECK2-NEXT:     Binding: Global
-# CHECK2-NEXT:     Type:
-# CHECK2-NEXT:     Other:
-# CHECK2-NEXT:     Section: .text
-# CHECK2-NEXT:   }
-# CHECK2-NEXT: ]
-
-# CHECK2-NOT: NEEDED
-# CHECK2:     NEEDED Shared library: [{{.*}}3.so]
-# CHECK2-NOT: NEEDED
+# RUN: llvm-readobj --dynamic-table --dyn-symbols %t | FileCheck --check-prefix=CHECK %s
 
 .section .text.foo, "ax"
 .globl foo
diff --git a/test/ELF/gnu-hash-table.s b/test/ELF/gnu-hash-table.s
index e8fd059..ffbf19f 100644
--- a/test/ELF/gnu-hash-table.s
+++ b/test/ELF/gnu-hash-table.s
@@ -4,30 +4,36 @@
 # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux      %te.s -o %te-i386.o
 # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux      %s    -o %t-i386.o
 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux    %s    -o %t-x86_64.o
-# RUN: llvm-mc -filetype=obj -triple=powerpc64-pc-linux %s    -o %t-ppc64.o
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s    -o %t-ppc64le.o
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s    -o %t-ppc64.o
 
 # RUN: echo ".global zed; zed:" > %t2.s
 # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux      %t2.s -o %t2-i386.o
 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux    %t2.s -o %t2-x86_64.o
-# RUN: llvm-mc -filetype=obj -triple=powerpc64-pc-linux %t2.s -o %t2-ppc64.o
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %t2.s -o %t2-ppc64le.o
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %t2.s -o %t2-ppc64.o
 
 # RUN: rm -f %t2-i386.a %t2-x86_64.a %t2-ppc64.a
 # RUN: llvm-ar rc %t2-i386.a %t2-i386.o
 # RUN: llvm-ar rc %t2-x86_64.a %t2-x86_64.o
+# RUN: llvm-ar rc %t2-ppc64le.a %t2-ppc64le.o
 # RUN: llvm-ar rc %t2-ppc64.a %t2-ppc64.o
 
 # RUN: echo ".global xyz; xyz:" > %t3.s
 # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux      %t3.s -o %t3-i386.o
 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux    %t3.s -o %t3-x86_64.o
-# RUN: llvm-mc -filetype=obj -triple=powerpc64-pc-linux %t3.s -o %t3-ppc64.o
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %t3.s -o %t3-ppc64le.o
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %t3.s -o %t3-ppc64.o
 
 # RUN: ld.lld -shared %t3-i386.o   -o %t3-i386.so
 # RUN: ld.lld -shared %t3-x86_64.o -o %t3-x86_64.so
+# RUN: ld.lld -shared %t3-ppc64le.o  -o %t3-ppc64le.so
 # RUN: ld.lld -shared %t3-ppc64.o  -o %t3-ppc64.so
 
 # RUN: ld.lld -shared --hash-style=gnu  -o %te-i386.so  %te-i386.o
 # RUN: ld.lld -shared  -hash-style=gnu  -o %t-i386.so   %t-i386.o   %t2-i386.a   %t3-i386.so
 # RUN: ld.lld -shared  -hash-style=gnu  -o %t-x86_64.so %t-x86_64.o %t2-x86_64.a %t3-x86_64.so
+# RUN: ld.lld -shared --hash-style both -o %t-ppc64le.so  %t-ppc64le.o  %t2-ppc64le.a  %t3-ppc64le.so
 # RUN: ld.lld -shared --hash-style both -o %t-ppc64.so  %t-ppc64.o  %t2-ppc64.a  %t3-ppc64.so
 
 # RUN: llvm-readobj -dyn-symbols -gnu-hash-table %te-i386.so \
@@ -36,6 +42,8 @@
 # RUN:   | FileCheck %s -check-prefix=I386
 # RUN: llvm-readobj -sections -dyn-symbols -gnu-hash-table %t-x86_64.so \
 # RUN:   | FileCheck %s -check-prefix=X86_64
+# RUN: llvm-readobj -sections -dyn-symbols -gnu-hash-table %t-ppc64le.so \
+# RUN:   | FileCheck %s -check-prefix=PPC64
 # RUN: llvm-readobj -sections -dyn-symbols -gnu-hash-table %t-ppc64.so \
 # RUN:   | FileCheck %s -check-prefix=PPC64
 
diff --git a/test/ELF/gnu-ifunc-dyntags.s b/test/ELF/gnu-ifunc-dyntags.s
index 81bd338..37d46d2 100644
--- a/test/ELF/gnu-ifunc-dyntags.s
+++ b/test/ELF/gnu-ifunc-dyntags.s
@@ -8,7 +8,7 @@
 ## when there are no other relocations except R_*_IRELATIVE.
 
 # CHECK:  Name          Size      Address
-# CHECK:  .rela.plt   00000030 0000000000000210
+# CHECK:  .rela.plt   00000030 0000000000000218
 # CHECK:  .got.plt    00000010 0000000000002000
 
 # TAGS:      Relocations [
@@ -19,7 +19,7 @@
 # TAGS-NEXT: ]
 
 # TAGS:   Tag                Type                 Name/Value
-# TAGS:   0x0000000000000017 JMPREL               0x210
+# TAGS:   0x0000000000000017 JMPREL               0x218
 # TAGS:   0x0000000000000002 PLTRELSZ             48
 # TAGS:   0x0000000000000003 PLTGOT               0x2000
 # TAGS:   0x0000000000000014 PLTREL               RELA
diff --git a/test/ELF/gnustack.s b/test/ELF/gnustack.s
index c506fb8..3ab6f16 100644
--- a/test/ELF/gnustack.s
+++ b/test/ELF/gnustack.s
@@ -1,10 +1,15 @@
 # REQUIRES: x86
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
+
 # RUN: ld.lld %t1 -z execstack -o %t
 # RUN: llvm-readobj --program-headers -s %t | FileCheck --check-prefix=RWX %s
+
 # RUN: ld.lld %t1 -o %t
 # RUN: llvm-readobj --program-headers -s %t | FileCheck --check-prefix=RW %s
 
+# RUN: ld.lld %t1 -o %t -z noexecstack
+# RUN: llvm-readobj --program-headers -s %t | FileCheck --check-prefix=RW %s
+
 # RW:      Type: PT_GNU_STACK
 # RW-NEXT: Offset: 0x0
 # RW-NEXT: VirtualAddress: 0x0
diff --git a/test/ELF/got32-i386-pie-rw.s b/test/ELF/got32-i386-pie-rw.s
index 0938148..45d2ec1 100644
--- a/test/ELF/got32-i386-pie-rw.s
+++ b/test/ELF/got32-i386-pie-rw.s
@@ -7,8 +7,8 @@
 
 # CHECK: .foobar           PROGBITS        00001000
 # CHECK: .got              PROGBITS        [[GOT:[0-9a-z]*]]
-# CHECK: 00001002  00000008 R_386_RELATIVE
-# CHECK: [[GOT]]   00000008 R_386_RELATIVE
+# CHECK-DAG: 00001002  00000008 R_386_RELATIVE
+# CHECK-DAG: [[GOT]]   00000008 R_386_RELATIVE
 foo:
 
 .section .foobar, "awx"
diff --git a/test/ELF/help.s b/test/ELF/help.s
index 2554531..aca2ceb 100644
--- a/test/ELF/help.s
+++ b/test/ELF/help.s
@@ -1,5 +1,5 @@
 # RUN: ld.lld --help 2>&1 | FileCheck %s
 # CHECK:  OPTIONS:
-# CHECK:  --output=<value>        Path to file to write output
-# CHECK:  --output <value>        Path to file to write output
+# CHECK:  --output=<value>        Alias for -o
+# CHECK:  --output <value>        Alias for -o
 # CHECK:  -o <path>               Path to file to write output
diff --git a/test/ELF/i386-merge.s b/test/ELF/i386-merge.s
index 00c9549..91a153e 100644
--- a/test/ELF/i386-merge.s
+++ b/test/ELF/i386-merge.s
@@ -9,7 +9,7 @@
 // CHECK-NEXT:   SHF_ALLOC
 // CHECK-NEXT:   SHF_MERGE
 // CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x114
+// CHECK-NEXT: Address: 0x128
 // CHECK-NEXT: Offset:
 // CHECK-NEXT: Size:
 // CHECK-NEXT: Link:
@@ -35,7 +35,7 @@
 // CHECK-NEXT: AddressAlignment: 1
 // CHECK-NEXT: EntrySize: 0
 // CHECK-NEXT: SectionData (
-// CHECK-NEXT:   0000: 14010000 |
+// CHECK-NEXT:   0000: 28010000 |
 // CHECK-NEXT: )
 
 // The content of .data should be the address of .mysec. 14010000 is 0x114 in
diff --git a/test/ELF/i386-reloc-16-large-addend.s b/test/ELF/i386-reloc-16-large-addend.s
new file mode 100644
index 0000000..ceb4862
--- /dev/null
+++ b/test/ELF/i386-reloc-16-large-addend.s
@@ -0,0 +1,12 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t
+# RUN: ld.lld -Ttext 0x7c00 %t -o %t2
+# RUN: llvm-objdump -s %t2 | FileCheck %s
+
+# CHECK:       Contents of section .text:
+# CHECK-NEXT:  7c00 b800ff
+
+.code16
+.global _start
+_start:
+ movw $_start+0x8300,%ax
diff --git a/test/ELF/i386-reloc-16.s b/test/ELF/i386-reloc-16.s
index e9d4fbb..33b6c44 100644
--- a/test/ELF/i386-reloc-16.s
+++ b/test/ELF/i386-reloc-16.s
@@ -10,6 +10,6 @@
 // CHECK-NEXT:   1000 42
 
 // RUN: not ld.lld -shared %t %t2 -o %t4 2>&1 | FileCheck --check-prefix=ERROR %s
-// ERROR: relocation R_386_16 out of range: 65536 is not in [0, 65535]
+// ERROR: relocation R_386_16 out of range: 65536 is not in [-32768, 32767]
 
 .short foo
diff --git a/test/ELF/i386-reloc-8-large-addend.s b/test/ELF/i386-reloc-8-large-addend.s
new file mode 100644
index 0000000..61d6380
--- /dev/null
+++ b/test/ELF/i386-reloc-8-large-addend.s
@@ -0,0 +1,12 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t
+# RUN: ld.lld -Ttext 0x7c %t -o %t2
+# RUN: llvm-objdump -s %t2 | FileCheck %s
+
+# CHECK:       Contents of section .text:
+# CHECK-NEXT:  007c b4ff
+
+.code16
+.global _start
+_start:
+ movb $_start+0x83,%ah
diff --git a/test/ELF/i386-reloc-8.s b/test/ELF/i386-reloc-8.s
index e0e255b..9e9f0cc 100644
--- a/test/ELF/i386-reloc-8.s
+++ b/test/ELF/i386-reloc-8.s
@@ -10,6 +10,6 @@
 // CHECK-NEXT:   1000 ff
 
 // RUN: not ld.lld -shared %t %t2 -o %t4 2>&1 | FileCheck --check-prefix=ERROR %s
-// ERROR: relocation R_386_8 out of range: 256 is not in [0, 255]
+// ERROR: relocation R_386_8 out of range: 256 is not in [-128, 127]
 
 .byte foo
diff --git a/test/ELF/i386-retpoline-nopic-linkerscript.s b/test/ELF/i386-retpoline-nopic-linkerscript.s
index 0c7d1fc..88fbfe9 100644
--- a/test/ELF/i386-retpoline-nopic-linkerscript.s
+++ b/test/ELF/i386-retpoline-nopic-linkerscript.s
@@ -14,9 +14,9 @@
 
 // CHECK:      Disassembly of section .plt:
 // CHECK-NEXT: .plt:
-// CHECK-NEXT: 10:       ff 35 fc 00 00 00       pushl   252
+// CHECK-NEXT: 10:       ff 35 cc 00 00 00       pushl   204
 // CHECK-NEXT: 16:       50      pushl   %eax
-// CHECK-NEXT: 17:       a1 00 01 00 00  movl    256, %eax
+// CHECK-NEXT: 17:       a1 d0 00 00 00 movl    208, %eax
 // CHECK-NEXT: 1c:       e8 0f 00 00 00  calll   15 <.plt+0x20>
 // CHECK-NEXT: 21:       f3 90   pause
 // CHECK-NEXT: 23:       0f ae e8        lfence
@@ -37,7 +37,7 @@
 // CHECK-NEXT: 3e:       c3      retl
 // CHECK-NEXT: 3f:       cc      int3
 // CHECK-NEXT: 40:       50      pushl   %eax
-// CHECK-NEXT: 41:       a1 04 01 00 00  movl    260, %eax
+// CHECK-NEXT: 41:       a1 d4 00 00 00  movl    212, %eax
 // CHECK-NEXT: 46:       e8 e5 ff ff ff  calll   -27 <.plt+0x20>
 // CHECK-NEXT: 4b:       e9 d1 ff ff ff  jmp     -47 <.plt+0x11>
 // CHECK-NEXT: 50:       68 00 00 00 00  pushl   $0
@@ -49,7 +49,7 @@
 // CHECK-NEXT: 5e:       cc      int3
 // CHECK-NEXT: 5f:       cc      int3
 // CHECK-NEXT: 60:       50      pushl   %eax
-// CHECK-NEXT: 61:       a1 08 01 00 00  movl    264, %eax
+// CHECK-NEXT: 61:       a1 d8 00 00 00  movl    216, %eax
 // CHECK-NEXT: 66:       e8 c5 ff ff ff  calll   -59 <.plt+0x20>
 // CHECK-NEXT: 6b:       e9 b1 ff ff ff  jmp     -79 <.plt+0x11>
 // CHECK-NEXT: 70:       68 08 00 00 00  pushl   $8
diff --git a/test/ELF/i386-retpoline-pic-linkerscript.s b/test/ELF/i386-retpoline-pic-linkerscript.s
index 049e53f..a502f3f 100644
--- a/test/ELF/i386-retpoline-pic-linkerscript.s
+++ b/test/ELF/i386-retpoline-pic-linkerscript.s
@@ -14,9 +14,9 @@
 
 // CHECK:      Disassembly of section .plt:
 // CHECK-NEXT: .plt:
-// CHECK-NEXT: 10:       ff b3 fc 00 00 00       pushl   252(%ebx)
+// CHECK-NEXT: 10:       ff b3 cc 00 00 00       pushl   204(%ebx)
 // CHECK-NEXT: 16:       50      pushl   %eax
-// CHECK-NEXT: 17:       8b 83 00 01 00 00       movl    256(%ebx), %eax
+// CHECK-NEXT: 17:       8b 83 d0 00 00 00 movl    208(%ebx), %eax
 // CHECK-NEXT: 1d:       e8 0e 00 00 00  calll   14 <.plt+0x20>
 // CHECK-NEXT: 22:       f3 90   pause
 // CHECK-NEXT: 24:       0f ae e8        lfence
@@ -36,7 +36,7 @@
 // CHECK-NEXT: 3e:       c3      retl
 // CHECK-NEXT: 3f:       cc      int3
 // CHECK-NEXT: 40:       50      pushl   %eax
-// CHECK-NEXT: 41:       8b 83 04 01 00 00       movl    260(%ebx), %eax
+// CHECK-NEXT: 41:       8b 83 d4 00 00 00       movl    212(%ebx), %eax
 // CHECK-NEXT: 47:       e8 e4 ff ff ff  calll   -28 <.plt+0x20>
 // CHECK-NEXT: 4c:       e9 d1 ff ff ff  jmp     -47 <.plt+0x12>
 // CHECK-NEXT: 51:       68 00 00 00 00  pushl   $0
@@ -47,7 +47,7 @@
 // CHECK-NEXT: 5e:       cc      int3
 // CHECK-NEXT: 5f:       cc      int3
 // CHECK-NEXT: 60:       50      pushl   %eax
-// CHECK-NEXT: 61:       8b 83 08 01 00 00       movl    264(%ebx), %eax
+// CHECK-NEXT: 61:       8b 83 d8 00 00 00       movl    216(%ebx), %eax
 // CHECK-NEXT: 67:       e8 c4 ff ff ff  calll   -60 <.plt+0x20>
 // CHECK-NEXT: 6c:       e9 b1 ff ff ff  jmp     -79 <.plt+0x12>
 // CHECK-NEXT: 71:       68 08 00 00 00  pushl   $8
diff --git a/test/ELF/icf-c-identifier.s b/test/ELF/icf-c-identifier.s
new file mode 100644
index 0000000..b1bd934
--- /dev/null
+++ b/test/ELF/icf-c-identifier.s
@@ -0,0 +1,9 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld %t -o %t2 --icf=all --print-icf-sections | count 0
+
+.section foo,"ax",@progbits,unique,0
+.byte 42
+
+.section foo,"ax",@progbits,unique,1
+.byte 42
diff --git a/test/ELF/icf-different-output-sections.s b/test/ELF/icf-different-output-sections.s
new file mode 100644
index 0000000..5f44f9b
--- /dev/null
+++ b/test/ELF/icf-different-output-sections.s
@@ -0,0 +1,9 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld %t -o %t2 --icf=all --print-icf-sections | count 0
+
+.section .foo,"ax"
+.byte 42
+
+.section .bar,"ax"
+.byte 42
diff --git a/test/ELF/icf-keep-unique.s b/test/ELF/icf-keep-unique.s
new file mode 100644
index 0000000..a6f883f
--- /dev/null
+++ b/test/ELF/icf-keep-unique.s
@@ -0,0 +1,43 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld %t -o %t2 --icf=all --print-icf-sections | FileCheck %s
+# RUN: ld.lld %t -o %t2 --keep-unique f2 --keep-unique f4 --keep-unique f5 --icf=all --print-icf-sections 2>&1 | FileCheck %s -check-prefix=CHECK-KEEP
+
+// Base case, expect only .text.f1 to be kept
+// CHECK: selected section {{.*}}:(.text.f1)
+// CHECK-NEXT:   removing identical section {{.*}}:(.text.f2)
+// CHECK-NEXT:   removing identical section {{.*}}:(.text.f3)
+// CHECK-NEXT:   removing identical section {{.*}}:(.text.f4)
+// CHECK-NEXT:   removing identical section {{.*}}:(.text.f5)
+
+// With --keep-unique f2, f4 and f5 we expect only f3 and f5 to be removed.
+// f5 is not matched by --keep-unique as it is a local symbol.
+// CHECK-KEEP: warning: could not find symbol f5 to keep unique
+// CHECK-KEEP: selected section {{.*}}:(.text.f1)
+// CHECK-KEEP-NEXT:   removing identical section {{.*}}:(.text.f3)
+// CHECK-KEEP-NEXT:   removing identical section {{.*}}:(.text.f5)
+ .globl _start, f1, f2, f3, f4
+_start:
+ ret
+
+ .section .text.f1, "ax"
+f1:
+ nop
+
+ .section .text.f2, "ax"
+f2:
+ nop
+
+.section .text.f3, "ax"
+f3:
+ nop
+
+.section .text.f4, "ax"
+f4:
+ nop
+
+# f5 is local, not found by --keep-unique f5
+.section .text.f5, "ax"
+f5:
+ nop
diff --git a/test/ELF/icf-relro.s b/test/ELF/icf-relro.s
new file mode 100644
index 0000000..492c042
--- /dev/null
+++ b/test/ELF/icf-relro.s
@@ -0,0 +1,13 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld %t -o %t2 --icf=all --ignore-data-address-equality --print-icf-sections | FileCheck %s
+
+# CHECK: selected section {{.*}}:(.data.rel.ro)
+# CHECK:   removing identical section {{.*}}:(.data.rel.ro.foo)
+
+.section .data.rel.ro,"aw"
+.quad foo
+
+.section .data.rel.ro.foo,"aw"
+foo:
+.quad foo
diff --git a/test/ELF/ignore-plugin.test b/test/ELF/ignore-plugin.test
new file mode 100644
index 0000000..fcd3fa6
--- /dev/null
+++ b/test/ELF/ignore-plugin.test
@@ -0,0 +1,2 @@
+RUN: not ld.lld --plugin foo 2>&1 | FileCheck %s
+CHECK: no input files
diff --git a/test/ELF/invalid-fde-rel.s b/test/ELF/invalid-fde-rel.s
index f43b9da..f651322 100644
--- a/test/ELF/invalid-fde-rel.s
+++ b/test/ELF/invalid-fde-rel.s
@@ -33,4 +33,4 @@
         .long 0x0
         .long 0x0
 
-// CHECK:  1 .eh_frame     00000018
+// CHECK:  1 .eh_frame     0000001c
diff --git a/test/ELF/linkerscript/Inputs/map-file2.s b/test/ELF/linkerscript/Inputs/map-file2.s
new file mode 100644
index 0000000..daf994e
--- /dev/null
+++ b/test/ELF/linkerscript/Inputs/map-file2.s
@@ -0,0 +1,19 @@
+.global _start
+_start:
+.global _Z1fi
+_Z1fi:
+.cfi_startproc
+nop
+.cfi_endproc
+
+.section .aaa, "a";
+.quad 1;
+
+.section .bbb, "a";
+.quad 2;
+
+.section .ccc, "a";
+.quad 3;
+
+.section .ddd, "a";
+.quad 4
diff --git a/test/ELF/linkerscript/addr-zero.test b/test/ELF/linkerscript/addr-zero.test
index 77adebc..0133fc0 100644
--- a/test/ELF/linkerscript/addr-zero.test
+++ b/test/ELF/linkerscript/addr-zero.test
@@ -8,7 +8,7 @@
 
 # CHECK:      Symbol {
 # CHECK:        Name: foo
-# CHECK-NEXT:   Value: 0x0
+# CHECK-NEXT:   Value: 0x38
 # CHECK-NEXT:   Size: 0
 # CHECK-NEXT:   Binding: Global
 # CHECK-NEXT:   Type: None
diff --git a/test/ELF/linkerscript/align-empty.test b/test/ELF/linkerscript/align-empty.test
index deb8268..9f879dd 100644
--- a/test/ELF/linkerscript/align-empty.test
+++ b/test/ELF/linkerscript/align-empty.test
@@ -15,4 +15,6 @@
 # CHECK:      Sections:
 # CHECK-NEXT: Idx Name          Size      Address
 # CHECK-NEXT:   0               00000000 0000000000000000
-# CHECK-NEXT:   1 foo           00000001 0000000000001000
+# CHECK-NEXT:   1 .dynsym       00000018 0000000000000190
+# CHECK-NEXT:   2 .dynstr       00000001 00000000000001a8
+# CHECK-NEXT:   3 foo           00000001 0000000000001000
diff --git a/test/ELF/linkerscript/align-r.test b/test/ELF/linkerscript/align-r.test
new file mode 100644
index 0000000..684ac1e
--- /dev/null
+++ b/test/ELF/linkerscript/align-r.test
@@ -0,0 +1,21 @@
+# REQUIRES: x86
+
+## Check output section ALIGN modifier with -r
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/align.s -o %t1.o
+# RUN: ld.lld -r -o %t2.o --script %s %t1.o
+# RUN: llvm-readelf -s %t2.o | FileCheck %s
+
+# CHECK:      Section Headers:
+# CHECK-NEXT: Name Type     Address          Off    Size   ES Flg Lk Inf Al
+# CHECK-NEXT:      NULL     0000000000000000 000000 000000 00
+# CHECK-NEXT: .aaa PROGBITS 0000000000000000 000040 000008 00   A  0   0   1
+# CHECK-NEXT: .bbb PROGBITS 0000000000000000 001000 000008 00   A  0   0  4096
+# CHECK-NEXT: .ccc PROGBITS 0000000000000000 004000 000008 00   A  0   0  16384
+
+SECTIONS {
+  . = 0x10000;
+  .aaa : { *(.aaa) }
+  .bbb : ALIGN(4096) { *(.bbb) }
+  .ccc : ALIGN(4096 * 4) { *(.ccc) }
+}
diff --git a/test/ELF/linkerscript/assert.s b/test/ELF/linkerscript/assert.s
index 73cc940..100631a 100644
--- a/test/ELF/linkerscript/assert.s
+++ b/test/ELF/linkerscript/assert.s
@@ -30,10 +30,11 @@
 # RUN: ld.lld -shared -o %t6 --script %t6.script %t1.o
 # RUN: llvm-readobj %t6 > /dev/null
 
+## Unlike the GNU ld, we accept the ASSERT without the semicolon.
+## It is consistent with how ASSERT can be written outside of the
+## output section declaration.
 # RUN: echo "SECTIONS { .foo : { ASSERT(1, \"true\") } }" > %t7.script
-# RUN: not ld.lld -shared -o %t7 --script %t7.script %t1.o > %t.log 2>&1
-# RUN: FileCheck %s -check-prefix=CHECK-SEMI < %t.log
-# CHECK-SEMI: error: {{.*}}.script:1: ; expected, but got }
+# RUN: ld.lld -shared -o %t7 --script %t7.script %t1.o
 
 .section .foo, "a"
  .quad 0
diff --git a/test/ELF/linkerscript/dot-is-not-abs.s b/test/ELF/linkerscript/dot-is-not-abs.s
index a93d1c8..1fae25e 100644
--- a/test/ELF/linkerscript/dot-is-not-abs.s
+++ b/test/ELF/linkerscript/dot-is-not-abs.s
@@ -26,7 +26,7 @@
 # CHECK-NEXT:     SHF_ALLOC
 # CHECK-NEXT:     SHF_EXECINSTR
 # CHECK-NEXT:   ]
-# CHECK-NEXT:   Address: 0x0
+# CHECK-NEXT:   Address: 0x1C
 # CHECK-NEXT:   Offset:
 # CHECK-NEXT:   Size: 4
 # CHECK-NEXT:   Link:
@@ -40,7 +40,7 @@
 
 # CHECK:      Symbol {
 # CHECK:        Name: foo
-# CHECK-NEXT:   Value: 0x4
+# CHECK-NEXT:   Value: 0x20
 # CHECK-NEXT:   Size: 0
 # CHECK-NEXT:   Binding: Local
 # CHECK-NEXT:   Type: None
diff --git a/test/ELF/linkerscript/eh-frame-hdr.s b/test/ELF/linkerscript/eh-frame-hdr.s
index 02bc3ea..a7892b2 100644
--- a/test/ELF/linkerscript/eh-frame-hdr.s
+++ b/test/ELF/linkerscript/eh-frame-hdr.s
@@ -4,7 +4,7 @@
 # RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t
 # RUN: llvm-objdump -s -section=".eh_frame_hdr" %t1 | FileCheck %s
 
-# CHECK:      011b033b 14000000 01000000 49000000
+# CHECK:      011b033b 14000000 01000000 4d000000
 # CHECK-NEXT: 30000000
 
 .global _start
diff --git a/test/ELF/linkerscript/emit-reloc.s b/test/ELF/linkerscript/emit-reloc.s
index 2fe127a..43ab4e8 100644
--- a/test/ELF/linkerscript/emit-reloc.s
+++ b/test/ELF/linkerscript/emit-reloc.s
@@ -9,9 +9,9 @@
 
 # CHECK:      Relocations [
 # CHECK-NEXT:   Section ({{.*}}) .rela.dyn {
-# CHECK-NEXT:     0x66 R_X86_64_64 .foo 0x0
+# CHECK-NEXT:     0x68 R_X86_64_64 .foo 0x0
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Section ({{.*}}) .rela.data {
-# CHECK-NEXT:     0x66 R_X86_64_64 .foo 0x0
+# CHECK-NEXT:     0x68 R_X86_64_64 .foo 0x0
 # CHECK-NEXT:   }
 # CHECK-NEXT: ]
diff --git a/test/ELF/linkerscript/empty-section-size.test b/test/ELF/linkerscript/empty-section-size.test
new file mode 100644
index 0000000..665ddf1
--- /dev/null
+++ b/test/ELF/linkerscript/empty-section-size.test
@@ -0,0 +1,17 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o
+# RUN: ld.lld %t.o --script %s -o %t1
+# RUN: llvm-readobj -symbols %t1 | FileCheck %s
+
+## We had a bug when LLD increased the size of the output section even
+## if it was empty. That happened because of empty synthetic sections included.
+## Here we check that size of empty output section is zero.
+
+# CHECK:       Name: foo
+# CHECK-NEXT:  Value: 0x0
+
+SECTIONS {
+  . = 0x1000;
+  .bss : { *(.bss*) *(COMMON) }
+  foo = SIZEOF(.bss);
+}
diff --git a/test/ELF/linkerscript/expr-sections.test b/test/ELF/linkerscript/expr-sections.test
index a9219e6..f7d541d 100644
--- a/test/ELF/linkerscript/expr-sections.test
+++ b/test/ELF/linkerscript/expr-sections.test
@@ -13,11 +13,11 @@
   }
 };
 
-# CHECK:  1 .text         00000000 0000000000000004 TEXT DATA
+# CHECK:  3 .text         00000000 00000000000000d0 TEXT DATA
 
-# CHECK: 0000000000000005         .text		 00000000 foo1
-# CHECK: 0000000000000005         .text		 00000000 bar1
+# CHECK: 00000000000000d1         .text		 00000000 foo1
+# CHECK: 00000000000000d1         .text		 00000000 bar1
 # CHECK: 0000000000000000         .text		 00000000 foo2
 # CHECK: 0000000000000000         .text		 00000000 bar2
-# CHECK: 0000000000000005         .text		 00000000 foo3
-# CHECK: 0000000000000005         .text		 00000000 bar3
+# CHECK: 00000000000000d1         .text		 00000000 foo3
+# CHECK: 00000000000000d1         .text		 00000000 bar3
diff --git a/test/ELF/linkerscript/i386-sections-max-va-overflow.s b/test/ELF/linkerscript/i386-sections-max-va-overflow.s
new file mode 100644
index 0000000..80c4fb5
--- /dev/null
+++ b/test/ELF/linkerscript/i386-sections-max-va-overflow.s
@@ -0,0 +1,13 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o
+
+# RUN: echo "SECTIONS { . = 0xfffffff1;" > %t.script
+# RUN: echo "           .bar : { *(.bar*) } }" >> %t.script
+# RUN: not ld.lld -o %t.so --script %t.script %t.o 2>&1 | FileCheck %s -check-prefix=ERR
+
+## .bar section has data in [0xfffffff1, 0xfffffff1 + 0x10] == [0xffffff1, 0x1]. 
+## Check we can catch this overflow.
+# ERR: error: section .bar at 0xFFFFFFF1 of size 0x10 exceeds available address space
+
+.section .bar,"ax",@progbits
+.zero 0x10
diff --git a/test/ELF/linkerscript/implicit-program-header.test b/test/ELF/linkerscript/implicit-program-header.test
index ea5c873..06b6161 100644
--- a/test/ELF/linkerscript/implicit-program-header.test
+++ b/test/ELF/linkerscript/implicit-program-header.test
@@ -8,8 +8,8 @@
 # RUN: llvm-readobj -elf-output-style=GNU -l %t1 | FileCheck %s
 
 # CHECK:      Segment Sections...
-# CHECK-NEXT:   00     .text .dynsym .hash .dynstr .dynamic
-# CHECK-NEXT:   01     .bar .foo
+# CHECK-NEXT:   00     .text .hash .dynamic
+# CHECK-NEXT:   01     .bar .dynsym .dynstr .foo
 
 PHDRS {
   ph_write PT_LOAD FLAGS(2);
diff --git a/test/ELF/linkerscript/locationcountererr2.s b/test/ELF/linkerscript/locationcountererr2.s
index 8968f67..7e7bd72 100644
--- a/test/ELF/linkerscript/locationcountererr2.s
+++ b/test/ELF/linkerscript/locationcountererr2.s
@@ -1,11 +1,11 @@
 # REQUIRES: x86
 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
 # RUN: echo "SECTIONS {" > %t.script
-# RUN: echo ". = 0x20; . = 0x10; .text : {} }" >> %t.script
+# 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: Idx Name   Size      Address
-# CHECK:  1 .text 00000000 0000000000000010
+# CHECK:  3 .text 00000000 0000000000000010
 
 # RUN: echo "SECTIONS { . = 0x20; . = ASSERT(0x1, "foo"); }" > %t2.script
 # RUN: ld.lld %t.o --script %t2.script -o %t -shared
diff --git a/test/ELF/linkerscript/map-file.test b/test/ELF/linkerscript/map-file.test
index 5ab3d01..540b8d4 100644
--- a/test/ELF/linkerscript/map-file.test
+++ b/test/ELF/linkerscript/map-file.test
@@ -1,6 +1,6 @@
 # REQUIRES: x86
 
-# RUN: echo '.section .foo.1, "a"; .quad 1' > %t.s
+# RUN: echo '.quad sym3; .quad sym4; .section .foo.1, "a"; .quad 1' > %t.s
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t.o
 
 # RUN: ld.lld -o %t %t.o -Map=%t.map --script %s
@@ -13,25 +13,48 @@
     SHORT(0x1122)
     LONG(0x11223344)
     QUAD(0x1122334455667788)
+    PROVIDE_HIDDEN(sym4 = .);
     . += 0x1000;
     *(.foo.1)
+    PROVIDE(unused1 = 0xff);
+    HIDDEN(sym6 = .);
     . += 0x123 *
          (1 + 1);
     foo = .;
     bar = 0x42 - 0x26;
   }
+  sym1 = .;
+  . += 0x500;
+  sym2 = .;
+  PROVIDE(unused2 = 0xff);
+  PROVIDE(sym3 = 42);
 }
 
-# CHECK:      Address          Size             Align Out     In      Symbol
-# CHECK-NEXT: 0000000000001000 000000000000125d     1 .foo
-# CHECK-NEXT: 0000000000001000 0000000000000001     1         BYTE ( 0x11 )
-# CHECK-NEXT: 0000000000001001 0000000000000002     1         SHORT ( 0x1122 )
-# CHECK-NEXT: 0000000000001003 0000000000000004     1         LONG ( 0x11223344 )
-# CHECK-NEXT: 0000000000001007 0000000000000008     1         QUAD ( 0x1122334455667788 )
-# CHECK-NEXT: 000000000000100f 0000000000001000     1         . += 0x1000
-# CHECK-NEXT: 000000000000200f 0000000000000008     1         {{.*}}{{/|\\}}map-file.test.tmp.o:(.foo.1)
-# CHECK-NEXT: 0000000000002017 0000000000000246     1         . += 0x123 * ( 1 + 1 )
-# CHECK-NEXT: 000000000000225d 0000000000000000     1         foo = .
-# CHECK-NEXT: 000000000000225d 0000000000000000     1         bar = 0x42 - 0x26
-# CHECK-NEXT: 0000000000002260 0000000000000000     4 .text
-# CHECK-NEXT: 0000000000002260 0000000000000000     4         {{.*}}{{/|\\}}map-file.test.tmp.o:(.text)
+# CHECK:         VMA              LMA     Size Align Out     In      Symbol
+# CHECK-NEXT:      0                0     1000     1 . = 0x1000
+# CHECK-NEXT:   1000             1000     125d     1 .foo
+# CHECK-NEXT:   1000             1000        1     1         BYTE ( 0x11 )
+# CHECK-NEXT:   1001             1001        2     1         SHORT ( 0x1122 )
+# CHECK-NEXT:   1003             1003        4     1         LONG ( 0x11223344 )
+# CHECK-NEXT:   1007             1007        8     1         QUAD ( 0x1122334455667788 )
+# CHECK-NEXT:   100f             100f        0     1         PROVIDE_HIDDEN ( sym4 = . )
+# CHECK-NEXT:   100f             100f     1000     1         . += 0x1000
+# CHECK-NEXT:   200f             200f        8     1         {{.*}}{{/|\\}}map-file.test.tmp.o:(.foo.1)
+# CHECK-NEXT:   2017             2017        0     1         HIDDEN ( sym6 = . )
+# CHECK-NEXT:   2017             2017      246     1         . += 0x123 * ( 1 + 1 )
+# CHECK-NEXT:   225d             225d        0     1         foo = .
+# CHECK-NEXT:   225d             225d        0     1         bar = 0x42 - 0x26
+# CHECK-NEXT:   225d                0        0     1 sym1 = .
+# CHECK-NEXT:   225d                0      500     1 . += 0x500
+# CHECK-NEXT:   275d                0        0     1 sym2 = .
+# CHECK-NEXT:   275d                0        0     1 PROVIDE ( sym3 = 42 )
+# CHECK-NEXT:   2760             2760       10     4 .text
+# CHECK-NEXT:   2760             2760       10     4         {{.*}}{{/|\\}}map-file.test.tmp.o:(.text)
+# CHECK-NEXT:      0                0        8     1 .comment
+# CHECK-NEXT:      0                0        8     1         <internal>:(.comment)
+# CHECK-NEXT:      0                0       c0     8 .symtab
+# CHECK-NEXT:      0                0       c0     8         <internal>:(.symtab)
+# CHECK-NEXT:      0                0       2f     1 .shstrtab
+# CHECK-NEXT:      0                0       2f     1         <internal>:(.shstrtab)
+# CHECK-NEXT:      0                0       22     1 .strtab
+# CHECK-NEXT:      0                0       22     1         <internal>:(.strtab)
diff --git a/test/ELF/linkerscript/map-file2.test b/test/ELF/linkerscript/map-file2.test
new file mode 100644
index 0000000..7c4689c
--- /dev/null
+++ b/test/ELF/linkerscript/map-file2.test
@@ -0,0 +1,44 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/map-file2.s -o %t.o
+# RUN: ld.lld -o %t %t.o -Map=%t.map --script %s
+# RUN: FileCheck -strict-whitespace %s < %t.map
+
+SECTIONS {
+  . = 0x1000;
+  .aaa : { *(.aaa.*) }
+  .bbb : AT(0x2000) { *(.bbb.*) }
+  .ccc : AT(0x3000) { *(.ccc.*) }
+  .ddd : {
+    BYTE(0x11)
+    . += 0x100;
+    *(.ddd.*)
+  }
+  .text : { *(.text.*) }
+}
+
+# CHECK:             VMA              LMA     Size Align Out     In      Symbol
+# CHECK-NEXT:          0                0     1000     1 . = 0x1000
+# CHECK-NEXT:       1000             1000        8     1 .aaa
+# CHECK-NEXT:       1000             1000        8     1         {{.*}}{{/|\\}}map-file2.test.tmp.o:(.aaa)
+# CHECK-NEXT:       1008             2000        8     1 .bbb
+# CHECK-NEXT:       1008             2000        8     1         {{.*}}{{/|\\}}map-file2.test.tmp.o:(.bbb)
+# CHECK-NEXT:       1010             3000        8     1 .ccc
+# CHECK-NEXT:       1010             3000        8     1         {{.*}}{{/|\\}}map-file2.test.tmp.o:(.ccc)
+# CHECK-NEXT:       1018             3008      109     1 .ddd
+# CHECK-NEXT:       1018             3008        1     1         BYTE ( 0x11 )
+# CHECK-NEXT:       1019             3009      100     1         . += 0x100
+# CHECK-NEXT:       1119             3109        8     1         {{.*}}{{/|\\}}map-file2.test.tmp.o:(.ddd)
+# CHECK-NEXT:       1124             3114        1     4 .text
+# CHECK-NEXT:       1124             3114        1     4         {{.*}}{{/|\\}}map-file2.test.tmp.o:(.text)
+# CHECK-NEXT:       1124             3114        0     1                 f(int)
+# CHECK-NEXT:       1124             3114        0     1                 _start
+# CHECK-NEXT:       1128             3118       34     8 .eh_frame
+# CHECK-NEXT:       1128             3118       30     1         {{.*}}{{/|\\}}map-file2.test.tmp.o:(.eh_frame+0x0)
+# CHECK-NEXT:          0                0        8     1 .comment
+# CHECK-NEXT:          0                0        8     1         <internal>:(.comment)
+# CHECK-NEXT:          0                0       48     8 .symtab
+# CHECK-NEXT:          0                0       48     8         <internal>:(.symtab)
+# CHECK-NEXT:          0                0       48     1 .shstrtab
+# CHECK-NEXT:          0                0       48     1         <internal>:(.shstrtab)
+# CHECK-NEXT:          0                0        e     1 .strtab
+# CHECK-NEXT:          0                0        e     1         <internal>:(.strtab)
diff --git a/test/ELF/linkerscript/merge-sections-syms.s b/test/ELF/linkerscript/merge-sections-syms.s
index 713d334..37b25c3 100644
--- a/test/ELF/linkerscript/merge-sections-syms.s
+++ b/test/ELF/linkerscript/merge-sections-syms.s
@@ -20,7 +20,7 @@
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Name: A
-# CHECK-NEXT:     Value: 0x195
+# CHECK-NEXT:     Value: 0x1E2
 # CHECK-NEXT:     Size:
 # CHECK-NEXT:     Binding:
 # CHECK-NEXT:     Type:
@@ -29,7 +29,7 @@
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Name: B
-# CHECK-NEXT:     Value: 0x196
+# CHECK-NEXT:     Value: 0x1E3
 # CHECK-NEXT:     Size:
 # CHECK-NEXT:     Binding:
 # CHECK-NEXT:     Type:
diff --git a/test/ELF/linkerscript/merge-sections.s b/test/ELF/linkerscript/merge-sections.s
index 2709bda..e76e2cd 100644
--- a/test/ELF/linkerscript/merge-sections.s
+++ b/test/ELF/linkerscript/merge-sections.s
@@ -29,7 +29,7 @@
 
 # CHECK:      Name: end
 # 0x19E = begin + sizeof(.foo) = 0x190 + 0xE
-# CHECK-NEXT: Value: 0x19E
+# CHECK-NEXT: Value: 0x1F2
 
 # Check that we don't crash with --gc-sections
 # RUN: ld.lld --gc-sections -o %t2 --script %t.script %t -shared
diff --git a/test/ELF/linkerscript/no-space.s b/test/ELF/linkerscript/no-space.s
index 21a38e4..a423a5e 100644
--- a/test/ELF/linkerscript/no-space.s
+++ b/test/ELF/linkerscript/no-space.s
@@ -1,11 +1,11 @@
 # REQUIRES: x86
 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
 
-# RUN: echo "SECTIONS {foo 0 : {*(foo*)} }" > %t.script
+# RUN: echo "SECTIONS {foo 0 : {*(foo*)} .dynsym : {*(.dynsym)} .dynstr : {*(.dynstr)} }" > %t.script
 # RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared
 # RUN: llvm-readobj -elf-output-style=GNU -l %t | FileCheck %s
 
-# RUN: echo "SECTIONS {foo : {*(foo*)} }" > %t.script
+# RUN: echo "SECTIONS {foo : {*(foo*)} .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } }" > %t.script
 # RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared
 # RUN: llvm-readobj -elf-output-style=GNU -l %t | FileCheck %s
 
@@ -18,7 +18,7 @@
 
 # CHECK:      Section to Segment mapping:
 # CHECK-NEXT:  Segment Sections...
-# CHECK-NEXT:   00     foo .text .dynsym .hash .dynstr
+# CHECK-NEXT:   00     foo .text .hash .dynsym .dynstr
 
 .section foo, "a"
 .quad 0
diff --git a/test/ELF/linkerscript/noload.s b/test/ELF/linkerscript/noload.s
index 28be55d..bd49160 100644
--- a/test/ELF/linkerscript/noload.s
+++ b/test/ELF/linkerscript/noload.s
@@ -2,12 +2,13 @@
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
 # RUN: echo "SECTIONS { \
 # RUN:        .data_noload_a (NOLOAD) : { *(.data_noload_a) } \
-# RUN:        .data_noload_b (0x10000) (NOLOAD) : { *(.data_noload_b) } };" > %t.script
+# RUN:        .data_noload_b (0x10000) (NOLOAD) : { *(.data_noload_b) } \
+# RUN:        .text (0x20000) : { *(.text) } };" > %t.script
 # RUN: ld.lld -o %t --script %t.script %t.o
-# RUN: llvm-readobj --symbols -sections %t | FileCheck %s
+# RUN: llvm-readobj -sections -program-headers  %t | FileCheck %s
 
 # CHECK:      Section {
-# CHECK:        Index: 2
+# CHECK:        Index: 1
 # CHECK-NEXT:   Name: .data_noload_a
 # CHECK-NEXT:   Type: SHT_NOBITS
 # CHECK-NEXT:   Flags [
@@ -15,7 +16,7 @@
 # CHECK-NEXT:     SHF_WRITE
 # CHECK-NEXT:   ]
 # CHECK-NEXT:   Address: 0x0
-# CHECK-NEXT:   Offset: 0x1000
+# CHECK-NEXT:   Offset: 0xE8
 # CHECK-NEXT:   Size: 4096
 # CHECK-NEXT:   Link: 0
 # CHECK-NEXT:   Info: 0
@@ -23,7 +24,7 @@
 # CHECK-NEXT:   EntrySize: 0
 # CHECK-NEXT: }
 # CHECK-NEXT: Section {
-# CHECK-NEXT:   Index: 3
+# CHECK-NEXT:   Index: 2
 # CHECK-NEXT:   Name: .data_noload_b
 # CHECK-NEXT:   Type: SHT_NOBITS
 # CHECK-NEXT:   Flags [
@@ -31,13 +32,29 @@
 # CHECK-NEXT:     SHF_WRITE
 # CHECK-NEXT:   ]
 # CHECK-NEXT:   Address: 0x10000
-# CHECK-NEXT:   Offset: 0x1000
+# CHECK-NEXT:   Offset: 0xE8
 # CHECK-NEXT:   Size: 4096
 # CHECK-NEXT:   Link: 0
 # CHECK-NEXT:   Info: 0
 # CHECK-NEXT:   AddressAlignment: 1
 # CHECK-NEXT:   EntrySize: 0
 # CHECK-NEXT: }
+# CHECK:      ProgramHeader {
+# CHECK-NEXT:   Type: PT_LOAD (0x1)
+# CHECK-NEXT:   Offset: 0x1000
+# CHECK-NEXT:   VirtualAddress: 0x20000
+# CHECK-NEXT:   PhysicalAddress: 0x20000
+# CHECK-NEXT:   FileSize: 1
+# CHECK-NEXT:   MemSize: 1
+# CHECK-NEXT:   Flags [ (0x5)
+# CHECK-NEXT:     PF_R (0x4)
+# CHECK-NEXT:     PF_X (0x1)
+# CHECK-NEXT:   ]
+# CHECK-NEXT:   Alignment: 4096
+# CHECK-NEXT: }
+
+.section .text,"ax",@progbits
+  nop
 
 .section .data_noload_a,"aw",@progbits
 .zero 4096
diff --git a/test/ELF/linkerscript/non-absolute.s b/test/ELF/linkerscript/non-absolute.s
index a0e9e7d..6e8d3e6 100644
--- a/test/ELF/linkerscript/non-absolute.s
+++ b/test/ELF/linkerscript/non-absolute.s
@@ -7,7 +7,7 @@
 
 # DUMP:       Disassembly of section .text:
 # DUMP-NEXT:  foo:
-# DUMP-NEXT:   0: {{.*}} -21(%rip), %eax
+# DUMP-NEXT:   50: {{.*}} -101(%rip), %eax
 
 # SYMBOL:     Symbol {
 # SYMBOL:        Name: B
@@ -18,7 +18,7 @@
 # SYMBOL-NEXT:   Other [
 # SYMBOL-NEXT:     STV_HIDDEN
 # SYMBOL-NEXT:   ]
-# SYMBOL-NEXT:   Section: .text
+# SYMBOL-NEXT:   Section: .dynsym
 # SYMBOL-NEXT: }
 
 .text
diff --git a/test/ELF/linkerscript/non-absolute2.test b/test/ELF/linkerscript/non-absolute2.test
index fa9e0e4..8935602 100644
--- a/test/ELF/linkerscript/non-absolute2.test
+++ b/test/ELF/linkerscript/non-absolute2.test
@@ -9,8 +9,10 @@
 }
 
 # CHECK:       Sections:
-# CHECK-NEXT:   Idx Name          Size      Address
-# CHECK-NEXT:    0               00000000 0000000000000000
-# CHECK-NEXT:    1 .text         00000000 0000000000001000
+# CHECK-NEXT:  Idx Name          Size      Address          Type
+# CHECK-NEXT:    0               00000000 0000000000000000 
+# CHECK-NEXT:    1 .dynsym       00000030 0000000000001000 
+# CHECK-NEXT:    2 .dynstr       00000003 0000000000001030 
+# CHECK-NEXT:    3 .text         00000000 0000000000001034
 
-# CHECK: 0000000000000001         .text            00000000 A
+# CHECK: 0000000000000001         .dynsym            00000000 A
diff --git a/test/ELF/linkerscript/non-alloc.s b/test/ELF/linkerscript/non-alloc.s
index 3257cb9..a40d29d 100644
--- a/test/ELF/linkerscript/non-alloc.s
+++ b/test/ELF/linkerscript/non-alloc.s
@@ -15,7 +15,7 @@
 
 # CHECK:      Section to Segment mapping:
 # CHECK-NEXT:  Segment Sections...
-# CHECK-NEXT:   00     .text .dynsym .hash .dynstr
+# CHECK-NEXT:   00     .dynsym .dynstr .text .hash 
 # CHECK-NEXT:   01     .dynamic
 
 nop
diff --git a/test/ELF/linkerscript/orphan-first-cmd.test b/test/ELF/linkerscript/orphan-first-cmd.test
index 6ef473b..31bff59 100644
--- a/test/ELF/linkerscript/orphan-first-cmd.test
+++ b/test/ELF/linkerscript/orphan-first-cmd.test
@@ -17,4 +17,4 @@
 # CHECK-NEXT:   SHF_ALLOC
 # CHECK-NEXT:   SHF_EXECINSTR
 # CHECK-NEXT: ]
-# CHECK-NEXT: Address: 0x1000
+# CHECK-NEXT: Address: 0x1038
diff --git a/test/ELF/linkerscript/out-of-order.s b/test/ELF/linkerscript/out-of-order.s
index c43df43..c76604a 100644
--- a/test/ELF/linkerscript/out-of-order.s
+++ b/test/ELF/linkerscript/out-of-order.s
@@ -1,19 +1,37 @@
 # REQUIRES: x86
 # RUN: llvm-mc -filetype=obj -triple=x86_64-linux %s -o %t.o
-# RUN: echo "SECTIONS { .data 0x4000 : { *(.data) } .text 0x2000 : { *(.text) } }" > %t.script
+# RUN: echo "SECTIONS { .data 0x4000 : {*(.data)} .dynsym 0x2000 : {*(.dynsym)} .dynstr : {*(.dynstr)} }" > %t.script
 # RUN: ld.lld --hash-style=sysv -o %t.so --script %t.script %t.o -shared
 # RUN: llvm-objdump -section-headers %t.so | FileCheck %s
 
+# Note: how the layout is done:
+#  we need to layout 2 segments, each contains sections:
+#    seg1: .data .dynamic
+#    seg2: .dynsym .dynstr .text .hash
+# for each segment, we start from the first section, regardless
+# whether it is an orphan or not (sections that are not listed in the
+# linkerscript are orphans):
+#   for seg1, we assign address: .data(0x4000), .dynamic(0x4008)
+#   for seg2, we assign address: .dynsym(0x2000), .dynstr(0x2018) ...
+# .dynsym is not an orphan, so we take address from script, we assign
+# .dynstr current address cursor, which is the end # of .dynsym and so
+# on for later sections.
+
+# Also note, it is absolutely *illegal* to have section addresses of
+# the same segment in none-increasing order, authors of linker scripts
+# must take responsibility to make sure this does not happen.
+
 # CHECK:      Sections:
 # CHECK-NEXT: Idx Name          Size      Address          Type
 # CHECK-NEXT:   0               00000000 0000000000000000
-# CHECK-NEXT:   1 .data         00000008 0000000000004000  DATA
+# CHECK-NEXT:   1 .data         00000008 0000000000004000
 # CHECK-NEXT:   2 .dynamic      00000060 0000000000004008
-# CHECK-NEXT:   3 .text         00000008 0000000000002000  TEXT DATA
-# CHECK-NEXT:   4 .dynsym       00000018 0000000000002008
-# CHECK-NEXT:   5 .hash         00000010 0000000000002020
-# CHECK-NEXT:   6 .dynstr       00000001 0000000000002030
+# CHECK-NEXT:   3 .dynsym       00000018 0000000000002000 
+# CHECK-NEXT:   4 .dynstr       00000001 0000000000002018
+# CHECK-NEXT:   5 .text         00000008 000000000000201c
+# CHECK-NEXT:   6 .hash         00000010 0000000000002024
 
 .quad 0
 .data
 .quad 0
+
diff --git a/test/ELF/linkerscript/output-too-large.s b/test/ELF/linkerscript/output-too-large.s
index c892a88..5b9c04a 100644
--- a/test/ELF/linkerscript/output-too-large.s
+++ b/test/ELF/linkerscript/output-too-large.s
@@ -1,7 +1,7 @@
 # REQUIRES: x86
 # RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
 # RUN: echo "SECTIONS { .text : { . = 0xffffffff; *(.text*); } }" > %t.script
-# RUN: not ld.lld --script %t.script %t.o -o %t 2>&1 | FileCheck %s
+# RUN: not ld.lld --no-check-sections --script %t.script %t.o -o %t 2>&1 | FileCheck %s
 # CHECK: error: output file too large
 
 .global _start
diff --git a/test/ELF/linkerscript/overlapping-sections.s b/test/ELF/linkerscript/overlapping-sections.s
index 0b7b741..98fa374 100644
--- a/test/ELF/linkerscript/overlapping-sections.s
+++ b/test/ELF/linkerscript/overlapping-sections.s
@@ -23,7 +23,7 @@
 # BAD-LMA: .sec2             PROGBITS        0000000000008800 002800 000100 00  WA  0   0  1
 # BAD-LMA-LABEL: Program Headers:
 # BAD-LMA-NEXT:  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
-# BAD-LMA-NEXT:  LOAD           0x001000 0x0000000000000000 0x0000000000000000 0x0000fd 0x0000fd R E 0x1000
+# BAD-LMA-NEXT:  LOAD           0x001000 0x0000000000000000 0x0000000000000000 0x000104 0x000104 R E 0x1000
 # BAD-LMA-NEXT:  LOAD           0x002000 0x0000000000008000 0x0000000000008000 0x000100 0x000100 RW  0x1000
 # BAD-LMA-NEXT:  LOAD           0x002800 0x0000000000008800 0x0000000000008080 0x000170 0x000170 RW  0x1000
 # BAD-LMA-LABEL: Section to Segment mapping:
@@ -49,7 +49,7 @@
 # BAD-VADDR: .sec2             PROGBITS        0000000000008020 003020 000100 00  WA  0   0  1
 # BAD-VADDR-LABEL: Program Headers:
 # BAD-VADDR-NEXT:  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
-# BAD-VADDR-NEXT:  LOAD           0x001000 0x0000000000000000 0x0000000000000000 0x0000fd 0x0000fd R E 0x1000
+# BAD-VADDR-NEXT:  LOAD           0x001000 0x0000000000000000 0x0000000000000000 0x000104 0x000104 R E 0x1000
 # BAD-VADDR-NEXT:  LOAD           0x002000 0x0000000000008000 0x0000000000008000 0x000100 0x000100 RW  0x1000
 # BAD-VADDR-NEXT:  LOAD           0x003020 0x0000000000008020 0x0000000000008800 0x000170 0x000170 RW  0x1000
 # BAD-VADDR-LABEL: Section to Segment mapping:
@@ -97,7 +97,7 @@
 # BAD-BOTH: .sec2             PROGBITS        0000000000008040 002040 000100 00  WA  0   0  1
 # BAD-BOTH-LABEL: Program Headers:
 # BAD-BOTH-NEXT:  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
-# BAD-BOTH-NEXT:  LOAD           0x001000 0x0000000000000000 0x0000000000000000 0x0000fd 0x0000fd R E 0x1000
+# BAD-BOTH-NEXT:  LOAD 0x001000 0x0000000000000000 0x0000000000000000 0x000104 0x000104 R E 0x1000
 # BAD-BOTH-NEXT:  LOAD           0x002000 0x0000000000008000 0x0000000000008000 0x0001b0 0x0001b0 RW  0x1000
 # BAD-BOTH-LABEL: Section to Segment mapping:
 # BAD-BOTH:   01     .sec1 .sec2 .dynamic
diff --git a/test/ELF/linkerscript/section-metadata2.s b/test/ELF/linkerscript/section-metadata2.s
new file mode 100644
index 0000000..6302492
--- /dev/null
+++ b/test/ELF/linkerscript/section-metadata2.s
@@ -0,0 +1,37 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: echo "SECTIONS { .text : { *(.text.*) } }" > %t.script
+
+# RUN: echo "_bar" > %t.ord
+# RUN: echo "_foo" >> %t.ord
+# RUN: ld.lld --symbol-ordering-file %t.ord -o %t --script %t.script %t.o
+# RUN: llvm-objdump -s %t | FileCheck %s
+
+# CHECK:      Contents of section .text:
+# CHECK-NEXT: 02000000 00000000 01000000 00000000
+# CHECK:      Contents of section .rodata:
+# CHECK-NEXT: 02000000 00000000 01000000 00000000
+
+# RUN: echo "_foo" > %t.ord
+# RUN: echo "_bar" >> %t.ord
+# RUN: ld.lld --symbol-ordering-file %t.ord -o %t --script %t.script %t.o
+# RUN: llvm-objdump -s %t | FileCheck %s --check-prefix=INV
+
+# INV:      Contents of section .text:
+# INV-NEXT: 01000000 00000000 02000000 00000000
+# INV:      Contents of section .rodata:
+# INV-NEXT: 01000000 00000000 02000000 00000000
+
+.section .text.foo,"a",@progbits
+_foo:
+.quad 1
+
+.section .text.bar,"a",@progbits
+_bar:
+.quad 2
+
+.section .rodata.foo,"ao",@progbits,.text.foo
+.quad 1
+
+.section .rodata.bar,"ao",@progbits,.text.bar
+.quad 2
diff --git a/test/ELF/linkerscript/sections-max-va-overflow.s b/test/ELF/linkerscript/sections-max-va-overflow.s
new file mode 100644
index 0000000..e8fcd8d
--- /dev/null
+++ b/test/ELF/linkerscript/sections-max-va-overflow.s
@@ -0,0 +1,13 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+
+# RUN: echo "SECTIONS { . = 0xfffffffffffffff1;" > %t.script
+# RUN: echo "           .bar : { *(.bar*) } }" >> %t.script
+# RUN: not ld.lld -o %t.so --script %t.script %t.o 2>&1 | FileCheck %s -check-prefix=ERR
+
+## .bar section has data in [0xfffffffffffffff1, 0xfffffffffffffff1 + 0x10] ==
+## [0xfffffffffffffff1, 0x1]. Check we can catch this overflow.
+# ERR: error: section .bar at 0xFFFFFFFFFFFFFFF1 of size 0x10 exceeds available address space
+
+.section .bar,"ax",@progbits
+.zero 0x10
diff --git a/test/ELF/linkerscript/sections-sort.s b/test/ELF/linkerscript/sections-sort.s
index 99bbbea..dd93f5a 100644
--- a/test/ELF/linkerscript/sections-sort.s
+++ b/test/ELF/linkerscript/sections-sort.s
@@ -15,11 +15,11 @@
 
 # CHECK: Id
 # CHECK-NEXT: 0
-# CHECK-NEXT: 1 .text
-# CHECK-NEXT: 2 foo
-# CHECK-NEXT: 3 .dynsym
-# CHECK-NEXT: 4 .hash
-# CHECK-NEXT: 5 .dynstr
+# CHECK-NEXT: 1 .dynsym
+# CHECK-NEXT: 2 .dynstr
+# CHECK-NEXT: 3 .text
+# CHECK-NEXT: 4 foo
+# CHECK-NEXT: 5 .hash
 # CHECK-NEXT: 6 .dynamic
 # CHECK-NEXT: 7 .comment
 # CHECK-NEXT: 8 .symtab
diff --git a/test/ELF/linkerscript/sort-non-script.s b/test/ELF/linkerscript/sort-non-script.s
index 4611b18..563843c 100644
--- a/test/ELF/linkerscript/sort-non-script.s
+++ b/test/ELF/linkerscript/sort-non-script.s
@@ -5,10 +5,10 @@
 # RUN: ld.lld --hash-style=sysv -o %t1 --script %t.script %t -shared
 # RUN: llvm-readobj -elf-output-style=GNU -s %t1 | FileCheck %s
 
-# CHECK:      .text    {{.*}}   AX
-# CHECK-NEXT: .dynsym  {{.*}}   A
-# CHECK-NEXT: .hash    {{.*}}   A
+# CHECK:      .dynsym  {{.*}}   A
 # CHECK-NEXT: .dynstr  {{.*}}   A
+# CHECK-NEXT: .text    {{.*}}   AX
+# CHECK-NEXT: .hash    {{.*}}   A
 # CHECK-NEXT: foo      {{.*}}  WA
 # CHECK-NEXT: .dynamic {{.*}}  WA
 
diff --git a/test/ELF/linkerscript/symbol-only.test b/test/ELF/linkerscript/symbol-only.test
index e2123fb..6763423 100644
--- a/test/ELF/linkerscript/symbol-only.test
+++ b/test/ELF/linkerscript/symbol-only.test
@@ -15,6 +15,8 @@
 # CHECK-NEXT: Idx Name          Size      Address
 # CHECK-NEXT:   0               00000000 0000000000000000
 # CHECK:          abc           00000000 [[ADDR:[0-9a-f]*]] BSS
+# CHECK-NEXT:     .dynsym       00000030 0000000000000190
+# CHECK-NEXT:     .dynstr       00000005 00000000000001c0
 # CHECK-NEXT:     bar           00000000 0000000000001000 DATA
 
 # CHECK: SYMBOL TABLE:
diff --git a/test/ELF/linkerscript/symbol-ordering-file2.s b/test/ELF/linkerscript/symbol-ordering-file2.s
new file mode 100644
index 0000000..31746ae
--- /dev/null
+++ b/test/ELF/linkerscript/symbol-ordering-file2.s
@@ -0,0 +1,16 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+
+## Check we do not crash when trying to order linker script symbol.
+
+# RUN: echo "bar" > %t.ord
+# RUN: echo "SECTIONS { bar = 1; }" > %t.script
+# RUN: ld.lld --symbol-ordering-file %t.ord %t.o --script %t.script \
+# RUN:   -o %t.out 2>&1 | FileCheck %s
+# CHECK: warning: <internal>: unable to order absolute symbol: bar
+
+## Check we do not crash when trying to order --defsym symbol.
+
+# RUN: echo "bar" > %t.ord
+# RUN: ld.lld --symbol-ordering-file %t.ord %t.o -defsym=bar=1 \
+# RUN:   -o %t.out 2>&1 | FileCheck %s
diff --git a/test/ELF/linkerscript/synthetic-symbols1.test b/test/ELF/linkerscript/synthetic-symbols1.test
index eb09d2d..908a05f 100644
--- a/test/ELF/linkerscript/synthetic-symbols1.test
+++ b/test/ELF/linkerscript/synthetic-symbols1.test
@@ -41,7 +41,7 @@
 # CHECK:      0000000000000128         .foo    00000000 .hidden _end_sec
 # CHECK-NEXT: 0000000000000120         .foo    00000000 _begin_sec
 # CHECK-NEXT: 0000000000000128         *ABS*   00000000 _end_sec_abs
-# CHECK-NEXT: 0000000000001048         .text   00000000 _start
+# CHECK-NEXT: 000000000000104c         .text   00000000 _start
 # CHECK-NEXT: 0000000000000120         .foo    00000000 begin_foo
 # CHECK-NEXT: 0000000000000128         .foo    00000000 end_foo
 # CHECK-NEXT: 0000000000000008         *ABS*   00000000 size_foo_1
diff --git a/test/ELF/linkerscript/unused-synthetic.s b/test/ELF/linkerscript/unused-synthetic.s
index fb33421..80f0627 100644
--- a/test/ELF/linkerscript/unused-synthetic.s
+++ b/test/ELF/linkerscript/unused-synthetic.s
@@ -10,8 +10,10 @@
 # RUN: llvm-objdump -section-headers %t.so | FileCheck %s
 # CHECK-NOT:  .got
 # CHECK-NOT:  .plt
-# CHECK:      .text
-# CHECK-NEXT: .dynsym
+# CHECK:      .dynsym
+# CHECK-NEXT: .dynstr
+# CHECK-NEXT: .text
+# CHECK-NEXT: .gnu.hash
 
 # Test that the size of a removed unused synthetic input section is not added
 # to the output section size. Adding a symbol assignment prevents removal of
diff --git a/test/ELF/local-symbols-order.s b/test/ELF/local-symbols-order.s
new file mode 100644
index 0000000..dfd964f
--- /dev/null
+++ b/test/ELF/local-symbols-order.s
@@ -0,0 +1,37 @@
+# REQUIRES: x86
+
+# RUN: echo '.data; .file "file2"; foo2:; .global bar2; .hidden bar2; bar2:' > %t2.s
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t2.s -o %t2.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+
+# RUN: ld.lld -o %t %t1.o %t2.o --emit-relocs
+# RUN: llvm-readobj -symbols -sections -elf-output-style=GNU %t | FileCheck %s
+
+## Check we sort local symbols to match the following order: 
+## file1, local1, section1, hidden1, file2, local2, section2, hidden2 ...
+
+# CHECK: Section Headers:
+# CHECK:   [Nr] Name
+# CHECK:   [ [[ST:.*]]] .text
+# CHECK:   [ [[SD:.*]]] .data
+# CHECK:   [ [[SC:.*]]] .comment
+
+# CHECK:      Num:    Value          Size Type    Bind   Vis      Ndx Name
+# CHECK-NEXT:   0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
+# CHECK-NEXT:   1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS file1
+# CHECK-NEXT:   2: 0000000000201000     0 NOTYPE  LOCAL  DEFAULT    1 foo1
+# CHECK-NEXT:   3: 0000000000201000     0 SECTION LOCAL  DEFAULT    [[ST]]
+# CHECK-NEXT:   4: 0000000000201000     0 NOTYPE  LOCAL  HIDDEN     1 bar1
+# CHECK-NEXT:   5: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS file2
+# CHECK-NEXT:   6: 0000000000201000     0 NOTYPE  LOCAL  DEFAULT    2 foo2
+# CHECK-NEXT:   7: 0000000000201000     0 SECTION LOCAL  DEFAULT    [[SD]]
+# CHECK-NEXT:   8: 0000000000201000     0 NOTYPE  LOCAL  HIDDEN     2 bar2
+# CHECK-NEXT:   9: 0000000000000000     0 SECTION LOCAL  DEFAULT    [[SC]]
+
+foo1:
+
+.global bar1
+.hidden bar1
+bar1:
+
+.file "file1"
diff --git a/test/ELF/lto/Inputs/archive-3.ll b/test/ELF/lto/Inputs/archive-3.ll
index ad8fb1e..3744246 100644
--- a/test/ELF/lto/Inputs/archive-3.ll
+++ b/test/ELF/lto/Inputs/archive-3.ll
@@ -1,5 +1,6 @@
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
+
 define void @foo() {
   ret void
 }
diff --git a/test/ELF/lto/Inputs/common3.ll b/test/ELF/lto/Inputs/common3.ll
index a4efc65..8f20a1e 100644
--- a/test/ELF/lto/Inputs/common3.ll
+++ b/test/ELF/lto/Inputs/common3.ll
@@ -1,3 +1,4 @@
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
+
 @a = common hidden global i64 0, align 4
diff --git a/test/ELF/lto/Inputs/lazy-internal.ll b/test/ELF/lto/Inputs/lazy-internal.ll
new file mode 100644
index 0000000..918791c
--- /dev/null
+++ b/test/ELF/lto/Inputs/lazy-internal.ll
@@ -0,0 +1,6 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define hidden void @bar() {
+  ret void
+}
diff --git a/test/ELF/lto/Inputs/thinlto_empty.ll b/test/ELF/lto/Inputs/thinlto_empty.ll
new file mode 100644
index 0000000..a3c99cd
--- /dev/null
+++ b/test/ELF/lto/Inputs/thinlto_empty.ll
@@ -0,0 +1,2 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/ELF/lto/archive-2.ll b/test/ELF/lto/archive-2.ll
index 6712d60..28e349e 100644
--- a/test/ELF/lto/archive-2.ll
+++ b/test/ELF/lto/archive-2.ll
@@ -3,9 +3,9 @@
 ; RUN: rm -f %t.a
 ; RUN: llvm-ar rcs %t.a %t1.o
 ; RUN: llvm-as %s -o %t2.o
-; RUN: ld.lld -m elf_x86_64 %t2.o %t.a -o %t3
+; RUN: ld.lld %t2.o %t.a -o %t3
 ; RUN: llvm-readobj -t %t3 | FileCheck %s
-; RUN: ld.lld -m elf_x86_64 %t2.o --whole-archive %t.a -o %t3 -shared
+; RUN: ld.lld %t2.o --whole-archive %t.a -o %t3 -shared
 ; RUN: llvm-readobj -t %t3 | FileCheck %s
 
 ; CHECK:      Name: _start (
diff --git a/test/ELF/lto/archive-3.ll b/test/ELF/lto/archive-3.ll
index 0322e41..fec1b61 100644
--- a/test/ELF/lto/archive-3.ll
+++ b/test/ELF/lto/archive-3.ll
@@ -2,12 +2,12 @@
 ; RUN: llvm-as %S/Inputs/archive-3.ll -o %t1.o
 ; RUN: llvm-as %s -o %t2.o
 
-; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o  -o %t3 -save-temps
+; RUN: ld.lld %t1.o %t2.o  -o %t3 -save-temps
 ; RUN: llvm-dis %t3.0.2.internalize.bc -o - | FileCheck %s
 
 ; RUN: rm -f %t.a
 ; RUN: llvm-ar rcs %t.a %t1.o
-; RUN: ld.lld -m elf_x86_64 %t.a %t1.o %t2.o  -o %t3 -save-temps
+; RUN: ld.lld %t.a %t1.o %t2.o  -o %t3 -save-temps
 ; RUN: llvm-dis %t3.0.2.internalize.bc -o - | FileCheck %s
 
 ; CHECK: define internal void @foo() {
diff --git a/test/ELF/lto/archive-no-index.ll b/test/ELF/lto/archive-no-index.ll
index 48cca0a..5ac2628 100644
--- a/test/ELF/lto/archive-no-index.ll
+++ b/test/ELF/lto/archive-no-index.ll
@@ -11,8 +11,8 @@
 ; RUN: llvm-ar crS %t1.a %t2.o
 ; RUN: llvm-ar crs %t2.a %t2.o
 
-; RUN: ld.lld -o %t -emain -m elf_x86_64 %t1.o %t1.a
-; RUN: ld.lld -o %t -emain -m elf_x86_64 %t1.o %t2.a
+; RUN: ld.lld -o %t -emain %t1.o %t1.a
+; RUN: ld.lld -o %t -emain %t1.o %t2.a
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/ELF/lto/archive.ll b/test/ELF/lto/archive.ll
index b4d011f..6c4ca5e 100644
--- a/test/ELF/lto/archive.ll
+++ b/test/ELF/lto/archive.ll
@@ -3,9 +3,9 @@
 ; RUN: rm -f %t.a
 ; RUN: llvm-ar rcs %t.a %t1.o
 ; RUN: llvm-as %s -o %t2.o
-; RUN: ld.lld -m elf_x86_64 %t2.o %t.a -o %t3 -shared
+; RUN: ld.lld %t2.o %t.a -o %t3 -shared
 ; RUN: llvm-readobj -t %t3 | FileCheck %s
-; RUN: ld.lld -m elf_x86_64 %t2.o --whole-archive %t.a -o %t3 -shared
+; RUN: ld.lld %t2.o --whole-archive %t.a -o %t3 -shared
 ; RUN: llvm-readobj -t %t3 | FileCheck %s
 
 ; CHECK:      Name: g (
diff --git a/test/ELF/lto/asmundef.ll b/test/ELF/lto/asmundef.ll
index 677bee6..604af8f 100644
--- a/test/ELF/lto/asmundef.ll
+++ b/test/ELF/lto/asmundef.ll
@@ -1,7 +1,7 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
 ; RUN: llvm-as %S/Inputs/asmundef.ll -o %t2.o
-; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t -save-temps
+; RUN: ld.lld %t.o %t2.o -o %t -save-temps
 ; RUN: llvm-dis %t.0.4.opt.bc -o - | FileCheck %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/test/ELF/lto/available-externally.ll b/test/ELF/lto/available-externally.ll
index 315e710..516bec8 100644
--- a/test/ELF/lto/available-externally.ll
+++ b/test/ELF/lto/available-externally.ll
@@ -1,7 +1,7 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t1.o
 ; RUN: llvm-as %p/Inputs/available-externally.ll -o %t2.o
-; RUN: ld.lld %t1.o %t2.o -m elf_x86_64 -o %t.so -shared -save-temps
+; RUN: ld.lld %t1.o %t2.o -o %t.so -shared -save-temps
 ; RUN: llvm-dis < %t.so.0.2.internalize.bc | FileCheck %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/test/ELF/lto/bitcode-nodatalayout.ll b/test/ELF/lto/bitcode-nodatalayout.ll
index 5c4883a..c99cbb8 100644
--- a/test/ELF/lto/bitcode-nodatalayout.ll
+++ b/test/ELF/lto/bitcode-nodatalayout.ll
@@ -1,6 +1,6 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
-; RUN: not ld.lld -m elf_x86_64 %t.o -o %t 2>&1 | FileCheck %s
+; RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
 
 ; CHECK: input module has no datalayout
 
diff --git a/test/ELF/lto/codemodel.ll b/test/ELF/lto/codemodel.ll
index cc12620..995575a 100644
--- a/test/ELF/lto/codemodel.ll
+++ b/test/ELF/lto/codemodel.ll
@@ -1,7 +1,7 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
-; RUN: ld.lld -m elf_x86_64 %t.o -o %ts -mllvm -code-model=small
-; RUN: ld.lld -m elf_x86_64 %t.o -o %tl -mllvm -code-model=large
+; RUN: ld.lld %t.o -o %ts -mllvm -code-model=small
+; RUN: ld.lld %t.o -o %tl -mllvm -code-model=large
 ; RUN: llvm-objdump -d %ts | FileCheck %s --check-prefix=CHECK-SMALL
 ; RUN: llvm-objdump -d %tl | FileCheck %s --check-prefix=CHECK-LARGE
 
diff --git a/test/ELF/lto/combined-lto-object-name.ll b/test/ELF/lto/combined-lto-object-name.ll
index 76564f9..e0b9874 100644
--- a/test/ELF/lto/combined-lto-object-name.ll
+++ b/test/ELF/lto/combined-lto-object-name.ll
@@ -1,6 +1,6 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
-; RUN: not ld.lld -m elf_x86_64 %t.o -o %t2 2>&1 | FileCheck %s
+; RUN: not ld.lld %t.o -o %t2 2>&1 | FileCheck %s
 
 target triple = "x86_64-unknown-linux-gnu"
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/test/ELF/lto/comdat.ll b/test/ELF/lto/comdat.ll
index e1384d0..1739351 100644
--- a/test/ELF/lto/comdat.ll
+++ b/test/ELF/lto/comdat.ll
@@ -1,6 +1,6 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
-; RUN: ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -shared
+; RUN: ld.lld %t.o %t.o -o %t.so -shared
 ; RUN: llvm-readobj -t %t.so | FileCheck %s
 
 ; CHECK:      Name: foo
diff --git a/test/ELF/lto/comdat2.ll b/test/ELF/lto/comdat2.ll
index 2831821..e7c6ea1 100644
--- a/test/ELF/lto/comdat2.ll
+++ b/test/ELF/lto/comdat2.ll
@@ -1,9 +1,9 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
 ; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/comdat.s -o %t2.o -filetype=obj
-; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t.so -shared
+; RUN: ld.lld %t.o %t2.o -o %t.so -shared
 ; RUN: llvm-readobj -t %t.so | FileCheck %s
-; RUN: ld.lld -m elf_x86_64 %t2.o %t.o -o %t2.so -shared
+; RUN: ld.lld %t2.o %t.o -o %t2.so -shared
 ; RUN: llvm-readobj -t %t2.so | FileCheck %s --check-prefix=OTHER
 
 
diff --git a/test/ELF/lto/common2.ll b/test/ELF/lto/common2.ll
index 2345a20..1cb5c32 100644
--- a/test/ELF/lto/common2.ll
+++ b/test/ELF/lto/common2.ll
@@ -1,6 +1,6 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t1.o
-; RUN: ld.lld -m elf_x86_64 %t1.o -o %t -shared -save-temps
+; RUN: ld.lld %t1.o -o %t -shared -save-temps
 ; RUN: llvm-dis < %t.0.2.internalize.bc | FileCheck %s
 ; RUN: llvm-readobj -t %t | FileCheck %s --check-prefix=SHARED
 
diff --git a/test/ELF/lto/common3.ll b/test/ELF/lto/common3.ll
index aea33f4..de52615 100644
--- a/test/ELF/lto/common3.ll
+++ b/test/ELF/lto/common3.ll
@@ -1,7 +1,7 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t1.o
 ; RUN: llvm-as %S/Inputs/common3.ll -o %t2.o
-; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t -shared -save-temps
+; RUN: ld.lld %t1.o %t2.o -o %t -shared -save-temps
 ; RUN: llvm-dis < %t.0.2.internalize.bc | FileCheck %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/test/ELF/lto/ctors.ll b/test/ELF/lto/ctors.ll
index 7fce645..f641897 100644
--- a/test/ELF/lto/ctors.ll
+++ b/test/ELF/lto/ctors.ll
@@ -1,6 +1,6 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
-; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared
+; RUN: ld.lld %t.o -o %t.so -shared
 ; RUN: llvm-readobj -sections %t.so | FileCheck %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/test/ELF/lto/data-ordering-lto.s b/test/ELF/lto/data-ordering-lto.s
index 0364e58..8291ef0 100644
--- a/test/ELF/lto/data-ordering-lto.s
+++ b/test/ELF/lto/data-ordering-lto.s
@@ -12,13 +12,14 @@
 
 # Check that the order is tin -> dipsy -> pat.
 
-# CHECK: Symbol table '.symtab' contains 5 entries:
+# CHECK: Symbol table '.symtab' contains 6 entries:
 # CHECK-NEXT:    Num:    Value          Size Type    Bind   Vis      Ndx Name
 # CHECK-NEXT:      0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
-# CHECK-NEXT:      1: 0000000000201000     0 NOTYPE  GLOBAL DEFAULT    1 _start
-# CHECK-NEXT:      2: 0000000000202004     4 OBJECT  GLOBAL DEFAULT    2 dipsy
-# CHECK-NEXT:      3: 0000000000202008     4 OBJECT  GLOBAL DEFAULT    2 pat
-# CHECK-NEXT:      4: 0000000000202000     4 OBJECT  GLOBAL DEFAULT    2 tin
+# CHECK-NEXT:      1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS {{.*}}.o
+# CHECK-NEXT:      2: 0000000000201000     0 NOTYPE  GLOBAL DEFAULT    1 _start
+# CHECK-NEXT:      3: 0000000000202004     4 OBJECT  GLOBAL DEFAULT    2 dipsy
+# CHECK-NEXT:      4: 0000000000202008     4 OBJECT  GLOBAL DEFAULT    2 pat
+# CHECK-NEXT:      5: 0000000000202000     4 OBJECT  GLOBAL DEFAULT    2 tin
 
 .globl _start
 _start:
diff --git a/test/ELF/lto/discard-value-names.ll b/test/ELF/lto/discard-value-names.ll
index f1e95fe..485014e 100644
--- a/test/ELF/lto/discard-value-names.ll
+++ b/test/ELF/lto/discard-value-names.ll
@@ -1,7 +1,7 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
 
-; RUN: ld.lld -m elf_x86_64 -shared -save-temps %t.o -o %t2.o
+; RUN: ld.lld -shared -save-temps %t.o -o %t2.o
 ; RUN: llvm-dis < %t2.o.0.0.preopt.bc | FileCheck %s
 
 ; CHECK: @GlobalValueName
diff --git a/test/ELF/lto/drop-debug-info.ll b/test/ELF/lto/drop-debug-info.ll
index dae7b96..f820faf 100644
--- a/test/ELF/lto/drop-debug-info.ll
+++ b/test/ELF/lto/drop-debug-info.ll
@@ -3,7 +3,7 @@
 ; drop-debug-info.bc was created from "void f(void) {}" with clang 3.5 and
 ; -gline-tables-only, so it contains old debug info.
 ;
-; RUN: ld.lld -m elf_x86_64 -shared %p/Inputs/drop-debug-info.bc \
+; RUN: ld.lld -shared %p/Inputs/drop-debug-info.bc \
 ; RUN: -disable-verify -o %t 2>&1 | FileCheck %s
 ; CHECK: ignoring debug info with an invalid version (1) in {{.*}}drop-debug-info.bc
 
diff --git a/test/ELF/lto/drop-linkage.ll b/test/ELF/lto/drop-linkage.ll
index 1ff1796..f02fa02 100644
--- a/test/ELF/lto/drop-linkage.ll
+++ b/test/ELF/lto/drop-linkage.ll
@@ -1,12 +1,12 @@
-target triple = "x86_64-unknown-linux-gnu"
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-
 ; REQUIRES: x86
 ; RUN: llc %s -o %t.o -filetype=obj
 ; RUN: llvm-as %p/Inputs/drop-linkage.ll -o %t2.o
 ; RUN: ld.lld %t.o %t2.o -o %t.so -save-temps -shared
 ; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s
 
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
 define void @foo() {
   ret void
 }
diff --git a/test/ELF/lto/duplicated.ll b/test/ELF/lto/duplicated.ll
index 1567481..fc60fba 100644
--- a/test/ELF/lto/duplicated.ll
+++ b/test/ELF/lto/duplicated.ll
@@ -1,6 +1,6 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
-; RUN: not ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -shared 2>&1 | FileCheck %s
+; RUN: not ld.lld %t.o %t.o -o %t.so -shared 2>&1 | FileCheck %s
 
 ; CHECK:      duplicate symbol: f
 ; CHECK-NEXT: >>> defined in {{.*}}.o
diff --git a/test/ELF/lto/dynamic-list.ll b/test/ELF/lto/dynamic-list.ll
index 0e950b3..c5473d8 100644
--- a/test/ELF/lto/dynamic-list.ll
+++ b/test/ELF/lto/dynamic-list.ll
@@ -1,7 +1,7 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
 ; RUN: echo "{ foo; };" > %t.list
-; RUN: ld.lld -m elf_x86_64 -o %t --dynamic-list %t.list -pie %t.o
+; RUN: ld.lld -o %t --dynamic-list %t.list -pie %t.o
 ; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
 
 ; CHECK:      Name:     foo@
diff --git a/test/ELF/lto/dynsym.ll b/test/ELF/lto/dynsym.ll
index b2b4157..d056c0b 100644
--- a/test/ELF/lto/dynsym.ll
+++ b/test/ELF/lto/dynsym.ll
@@ -1,12 +1,12 @@
 ; REQUIRES: x86
 ; RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux -o %t.o %p/Inputs/dynsym.s
-; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared
+; RUN: ld.lld %t.o -o %t.so -shared
 ; RUN: llvm-as %s -o %t2.o
-; RUN: ld.lld -m elf_x86_64 %t2.o %t.so -o %t
+; RUN: ld.lld %t2.o %t.so -o %t
 ; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
 
 ; Check that we don't crash when gc'ing sections and printing the result.
-; RUN: ld.lld -m elf_x86_64 %t2.o %t.so --gc-sections --print-gc-sections \
+; RUN: ld.lld %t2.o %t.so --gc-sections --print-gc-sections \
 ; RUN:   -o %t
 ; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
 
diff --git a/test/ELF/lto/inline-asm.ll b/test/ELF/lto/inline-asm.ll
index b6af6a5..e0732e6 100644
--- a/test/ELF/lto/inline-asm.ll
+++ b/test/ELF/lto/inline-asm.ll
@@ -1,6 +1,6 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
-; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared
+; RUN: ld.lld %t.o -o %t.so -shared
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/ELF/lto/internalize-basic.ll b/test/ELF/lto/internalize-basic.ll
index b5691a7..5197654 100644
--- a/test/ELF/lto/internalize-basic.ll
+++ b/test/ELF/lto/internalize-basic.ll
@@ -1,6 +1,6 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
-; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -save-temps
+; RUN: ld.lld %t.o -o %t2 -save-temps
 ; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s
 
 target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/ELF/lto/internalize-exportdyn.ll b/test/ELF/lto/internalize-exportdyn.ll
index 0ffde69..7c996e1 100644
--- a/test/ELF/lto/internalize-exportdyn.ll
+++ b/test/ELF/lto/internalize-exportdyn.ll
@@ -1,7 +1,7 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
 ; RUN: llvm-as %p/Inputs/internalize-exportdyn.ll -o %t2.o
-; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t2 --export-dynamic -save-temps
+; RUN: ld.lld %t.o %t2.o -o %t2 --export-dynamic -save-temps
 ; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s
 
 target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/ELF/lto/internalize-llvmused.ll b/test/ELF/lto/internalize-llvmused.ll
index 253dcb2..7e3d867 100644
--- a/test/ELF/lto/internalize-llvmused.ll
+++ b/test/ELF/lto/internalize-llvmused.ll
@@ -1,6 +1,6 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
-; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -save-temps
+; RUN: ld.lld %t.o -o %t2 -save-temps
 ; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s
 
 target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/ELF/lto/internalize-undef.ll b/test/ELF/lto/internalize-undef.ll
index f76528b..c0860d8 100644
--- a/test/ELF/lto/internalize-undef.ll
+++ b/test/ELF/lto/internalize-undef.ll
@@ -1,7 +1,7 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
 ; RUN: llvm-as %p/Inputs/internalize-undef.ll -o %t2.o
-; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t -save-temps
+; RUN: ld.lld %t.o %t2.o -o %t -save-temps
 ; RUN: llvm-dis < %t.0.2.internalize.bc | FileCheck %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/test/ELF/lto/internalize-version-script.ll b/test/ELF/lto/internalize-version-script.ll
index c577e43..7e242e1 100644
--- a/test/ELF/lto/internalize-version-script.ll
+++ b/test/ELF/lto/internalize-version-script.ll
@@ -1,7 +1,7 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
 ; RUN: echo "{ global: foo; local: *; };" > %t.script
-; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -shared --version-script %t.script -save-temps
+; RUN: ld.lld %t.o -o %t2 -shared --version-script %t.script -save-temps
 ; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s
 
 target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/ELF/lto/irmover-error.ll b/test/ELF/lto/irmover-error.ll
index 8b9836d..d1c962f 100644
--- a/test/ELF/lto/irmover-error.ll
+++ b/test/ELF/lto/irmover-error.ll
@@ -1,6 +1,6 @@
 ; RUN: llvm-as -o %t1.bc %s
 ; RUN: llvm-as -o %t2.bc %S/Inputs/irmover-error.ll
-; RUN: not ld.lld -m elf_x86_64 %t1.bc %t2.bc -o %t 2>&1 | FileCheck %s
+; RUN: not ld.lld %t1.bc %t2.bc -o %t 2>&1 | FileCheck %s
 
 ; CHECK: linking module flags 'foo': IDs have conflicting values
 
diff --git a/test/ELF/lto/keep-undefined.ll b/test/ELF/lto/keep-undefined.ll
index cb0f4ce..55d2a05 100644
--- a/test/ELF/lto/keep-undefined.ll
+++ b/test/ELF/lto/keep-undefined.ll
@@ -2,7 +2,7 @@
 ; This test checks that symbols which are specified in "-u" switches
 ; are kept over LTO if we link an executable.
 ; RUN: llvm-as %s -o %t.o
-; RUN: ld.lld -m elf_x86_64 %t.o -o %tout -u foo
+; RUN: ld.lld %t.o -o %tout -u foo
 ; RUN: llvm-nm %tout | FileCheck %s
 
 ; CHECK: T foo
diff --git a/test/ELF/lto/lazy-internal.ll b/test/ELF/lto/lazy-internal.ll
new file mode 100644
index 0000000..1bb2bac
--- /dev/null
+++ b/test/ELF/lto/lazy-internal.ll
@@ -0,0 +1,19 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t1.o
+; RUN: llvm-as %p/Inputs/lazy-internal.ll -o %t2.o
+; RUN: rm -f %t2.a
+; RUN: llvm-ar rc %t2.a %t2.o
+; RUN: ld.lld %t2.a %t1.o -o %t.so -shared -save-temps
+; RUN: llvm-dis %t.so.0.2.internalize.bc -o - | FileCheck %s
+
+; CHECK: define internal void @foo()
+; CHECK: define internal void @bar()
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define hidden void @foo() {
+  call void @bar()
+  ret void
+}
+declare void @bar()
diff --git a/test/ELF/lto/linkage.ll b/test/ELF/lto/linkage.ll
index 5af9b32..9b93900 100644
--- a/test/ELF/lto/linkage.ll
+++ b/test/ELF/lto/linkage.ll
@@ -1,6 +1,6 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t1.o
-; RUN: ld.lld -m elf_x86_64 %t1.o %t1.o -o %t.so -shared
+; RUN: ld.lld %t1.o %t1.o -o %t.so -shared
 ; RUN: llvm-nm %t.so | FileCheck %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/test/ELF/lto/linker-script-symbols-assign.ll b/test/ELF/lto/linker-script-symbols-assign.ll
index 6ca7824..bd7a374 100644
--- a/test/ELF/lto/linker-script-symbols-assign.ll
+++ b/test/ELF/lto/linker-script-symbols-assign.ll
@@ -2,7 +2,7 @@
 ; RUN: llvm-as %s -o %t.o
 
 ; RUN: echo "foo = 1;" > %t.script
-; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 --script %t.script -save-temps
+; RUN: ld.lld %t.o -o %t2 --script %t.script -save-temps
 ; RUN: llvm-readobj -symbols %t2.lto.o | FileCheck %s
 
 ; CHECK-NOT: bar
@@ -20,7 +20,7 @@
 ; VAL-NEXT: }
 
 ; RUN: echo "zed = 1;" > %t2.script
-; RUN: ld.lld -m elf_x86_64 %t.o -o %t3 --script %t2.script
+; RUN: ld.lld %t.o -o %t3 --script %t2.script
 ; RUN: llvm-readobj -symbols %t3 | FileCheck %s --check-prefix=ABS
 ; ABS:      Symbol {
 ; ABS:        Name: zed
diff --git a/test/ELF/lto/linker-script-symbols-ipo.ll b/test/ELF/lto/linker-script-symbols-ipo.ll
index 330ac67..4cc95c6 100644
--- a/test/ELF/lto/linker-script-symbols-ipo.ll
+++ b/test/ELF/lto/linker-script-symbols-ipo.ll
@@ -4,7 +4,7 @@
 ; RUN: echo "bar = foo;" > %t.script
 
 ;; Check that without linkerscript bar is inlined.
-; RUN: ld.lld  -m elf_x86_64 %t1.o %t2.o -o %t3 -save-temps
+; RUN: ld.lld %t1.o %t2.o -o %t3 -save-temps
 ; RUN: llvm-objdump -d %t3 | FileCheck %s --check-prefix=IPO
 ; IPO:      Disassembly of section .text:
 ; IPO:      _start:
@@ -12,7 +12,7 @@
 ; IPO-NEXT:   201005: {{.*}} retq
 
 ;; Check that LTO does not do IPO for symbols assigned by script.
-; RUN: ld.lld  -m elf_x86_64 %t1.o %t2.o -o %t4 --script %t.script -save-temps
+; RUN: ld.lld %t1.o %t2.o -o %t4 --script %t.script -save-temps
 ; RUN: llvm-objdump -d %t4 | FileCheck %s --check-prefix=NOIPO
 ; NOIPO:      Disassembly of section .text:
 ; NOIPO:      foo:
diff --git a/test/ELF/lto/linker-script-symbols.ll b/test/ELF/lto/linker-script-symbols.ll
index c2a58b6..28758c0 100644
--- a/test/ELF/lto/linker-script-symbols.ll
+++ b/test/ELF/lto/linker-script-symbols.ll
@@ -2,7 +2,7 @@
 ; RUN: llvm-as %s -o %t.o
 ; RUN: echo "foo = bar;" > %t.script
 
-; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 --script %t.script -save-temps
+; RUN: ld.lld %t.o -o %t2 --script %t.script -save-temps
 ; RUN: llvm-readobj -symbols %t2.lto.o | FileCheck %s
 
 ; CHECK-NOT:  zed
diff --git a/test/ELF/lto/lto-start.ll b/test/ELF/lto/lto-start.ll
index e93eecf..cc1eb4b 100644
--- a/test/ELF/lto/lto-start.ll
+++ b/test/ELF/lto/lto-start.ll
@@ -1,6 +1,6 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
-; RUN: ld.lld -m elf_x86_64 %t.o -o %t2
+; RUN: ld.lld %t.o -o %t2
 ; RUN: llvm-readobj -t %t2 | FileCheck %s
 
 ; CHECK:      Format: ELF64-x86-64
diff --git a/test/ELF/lto/ltopasses-basic.ll b/test/ELF/lto/ltopasses-basic.ll
index 0c4ad8b..6789bdc 100644
--- a/test/ELF/lto/ltopasses-basic.ll
+++ b/test/ELF/lto/ltopasses-basic.ll
@@ -1,6 +1,6 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
-; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -save-temps -mllvm -debug-pass=Arguments -shared 2>&1 | FileCheck %s --check-prefix=MLLVM
+; RUN: ld.lld %t.o -o %t.so -save-temps -mllvm -debug-pass=Arguments -shared 2>&1 | FileCheck %s --check-prefix=MLLVM
 ; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/test/ELF/lto/ltopasses-custom.ll b/test/ELF/lto/ltopasses-custom.ll
index a48959a..a75000d 100644
--- a/test/ELF/lto/ltopasses-custom.ll
+++ b/test/ELF/lto/ltopasses-custom.ll
@@ -1,8 +1,8 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
-; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -save-temps --lto-aa-pipeline=basic-aa \
+; RUN: ld.lld %t.o -o %t.so -save-temps --lto-aa-pipeline=basic-aa \
 ; RUN: --lto-newpm-passes=ipsccp -shared
-; RUN: ld.lld -m elf_x86_64 %t.o -o %t2.so -save-temps --lto-newpm-passes=loweratomic -shared
+; RUN: ld.lld %t.o -o %t2.so -save-temps --lto-newpm-passes=loweratomic -shared
 ; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s
 ; RUN: llvm-dis %t2.so.0.4.opt.bc -o - | FileCheck %s --check-prefix=ATOMIC
 
diff --git a/test/ELF/lto/metadata.ll b/test/ELF/lto/metadata.ll
index 2eaacaa..238b5bd 100644
--- a/test/ELF/lto/metadata.ll
+++ b/test/ELF/lto/metadata.ll
@@ -1,6 +1,6 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t1.o
-; RUN: ld.lld -m elf_x86_64 %t1.o %t1.o -o %t.so -shared
+; RUN: ld.lld %t1.o %t1.o -o %t.so -shared
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/ELF/lto/module-asm.ll b/test/ELF/lto/module-asm.ll
index 1389b9f..eaf2762 100644
--- a/test/ELF/lto/module-asm.ll
+++ b/test/ELF/lto/module-asm.ll
@@ -1,6 +1,6 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
-; RUN: ld.lld -m elf_x86_64 %t.o -o %t
+; RUN: ld.lld %t.o -o %t
 ; RUN: llvm-nm %t | FileCheck %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/test/ELF/lto/new-pass-manager.ll b/test/ELF/lto/new-pass-manager.ll
new file mode 100644
index 0000000..918b505
--- /dev/null
+++ b/test/ELF/lto/new-pass-manager.ll
@@ -0,0 +1,14 @@
+; REQUIRES: x86
+; RUN: opt -module-summary %s -o %t.o
+
+; Test new-pass-manager and debug-pass-manager option
+; RUN: ld.lld --plugin-opt=new-pass-manager --plugin-opt=debug-pass-manager -o %t2.o %t.o 2>&1 | FileCheck %s
+; RUN: ld.lld --plugin-opt=new-pass-manager --lto-debug-pass-manager -o %t2.o %t.o 2>&1 | FileCheck %s
+; RUN: ld.lld --lto-new-pass-manager --plugin-opt=debug-pass-manager -o %t2.o %t.o 2>&1 | FileCheck %s
+; RUN: ld.lld --lto-new-pass-manager --lto-debug-pass-manager -o %t2.o %t.o 2>&1 | FileCheck %s
+
+; CHECK: Starting llvm::Module pass manager run
+; CHECK: Finished llvm::Module pass manager run
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/ELF/lto/opt-level.ll b/test/ELF/lto/opt-level.ll
index b2b56a4..5c4ec43 100644
--- a/test/ELF/lto/opt-level.ll
+++ b/test/ELF/lto/opt-level.ll
@@ -1,30 +1,30 @@
 ; REQUIRES: x86
 ; RUN: llvm-as -o %t.o %s
-; RUN: ld.lld -o %t0 -m elf_x86_64 -e main --lto-O0 %t.o
+; RUN: ld.lld -o %t0 -e main --lto-O0 %t.o
 ; RUN: llvm-nm %t0 | FileCheck --check-prefix=CHECK-O0 %s
-; RUN: ld.lld -o %t0 -m elf_x86_64 -e main --plugin-opt=O0 %t.o
+; RUN: ld.lld -o %t0 -e main --plugin-opt=O0 %t.o
 ; RUN: llvm-nm %t0 | FileCheck --check-prefix=CHECK-O0 %s
-; RUN: ld.lld -o %t2 -m elf_x86_64 -e main --lto-O2 %t.o
+; RUN: ld.lld -o %t2 -e main --lto-O2 %t.o
 ; RUN: llvm-nm %t2 | FileCheck --check-prefix=CHECK-O2 %s
-; RUN: ld.lld -o %t2a -m elf_x86_64 -e main %t.o
+; RUN: ld.lld -o %t2a -e main %t.o
 ; RUN: llvm-nm %t2a | FileCheck --check-prefix=CHECK-O2 %s
-; RUN: ld.lld -o %t2 -m elf_x86_64 -e main --plugin-opt=O2 %t.o
+; RUN: ld.lld -o %t2 -e main %t.o --plugin-opt O2
 ; RUN: llvm-nm %t2 | FileCheck --check-prefix=CHECK-O2 %s
 
 ; Reject invalid optimization levels.
-; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --lto-O6 %t.o 2>&1 | \
+; RUN: not ld.lld -o %t3 -e main --lto-O6 %t.o 2>&1 | \
 ; RUN:   FileCheck --check-prefix=INVALID1 %s
 ; INVALID1: invalid optimization level for LTO: 6
-; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --plugin-opt=O6 %t.o 2>&1 | \
+; RUN: not ld.lld -o %t3 -e main --plugin-opt=O6 %t.o 2>&1 | \
 ; RUN:   FileCheck --check-prefix=INVALID1 %s
-; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --plugin-opt=Ofoo %t.o 2>&1 | \
+; RUN: not ld.lld -o %t3 -e main --plugin-opt=Ofoo %t.o 2>&1 | \
 ; RUN:   FileCheck --check-prefix=INVALID2 %s
 ; INVALID2: --plugin-opt=Ofoo: number expected, but got 'foo'
 
-; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --lto-O-1 %t.o 2>&1 | \
+; RUN: not ld.lld -o %t3 -e main --lto-O-1 %t.o 2>&1 | \
 ; RUN:   FileCheck --check-prefix=INVALIDNEGATIVE1 %s
 ; INVALIDNEGATIVE1: invalid optimization level for LTO: 4294967295
-; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --plugin-opt=O-1 %t.o 2>&1 | \
+; RUN: not ld.lld -o %t3 -e main --plugin-opt=O-1 %t.o 2>&1 | \
 ; RUN:   FileCheck --check-prefix=INVALIDNEGATIVE2 %s
 ; INVALIDNEGATIVE2: invalid optimization level for LTO: 4294967295
 
diff --git a/test/ELF/lto/parallel-internalize.ll b/test/ELF/lto/parallel-internalize.ll
index da5bdc6..f21b3cc 100644
--- a/test/ELF/lto/parallel-internalize.ll
+++ b/test/ELF/lto/parallel-internalize.ll
@@ -1,7 +1,7 @@
 ; REQUIRES: x86
 ; RUN: llvm-as -o %t.bc %s
 ; RUN: rm -f %t.lto.o %t1.lto.o
-; RUN: ld.lld -m elf_x86_64 --lto-partitions=2 -save-temps -o %t %t.bc \
+; RUN: ld.lld --lto-partitions=2 -save-temps -o %t %t.bc \
 ; RUN:   -e foo --lto-O0
 ; RUN: llvm-readobj -t -dyn-symbols %t | FileCheck %s
 ; RUN: llvm-nm %t.lto.o | FileCheck --check-prefix=CHECK0 %s
@@ -18,6 +18,24 @@
 ; CHECK-NEXT:     Section: Undefined (0x0)
 ; CHECK-NEXT:   }
 ; CHECK-NEXT:   Symbol {
+; CHECK-NEXT:     Name: {{.*}}.o
+; CHECK-NEXT:     Value: 0x0
+; CHECK-NEXT:     Size: 0
+; CHECK-NEXT:     Binding: Local
+; CHECK-NEXT:     Type: File
+; CHECK-NEXT:     Other: 0
+; CHECK-NEXT:     Section: Absolute
+; CHECK-NEXT:   }
+; CHECK-NEXT:   Symbol {
+; CHECK-NEXT:     Name: {{.*}}.o
+; CHECK-NEXT:     Value: 0x0
+; CHECK-NEXT:     Size: 0
+; CHECK-NEXT:     Binding: Local
+; CHECK-NEXT:     Type: File
+; CHECK-NEXT:     Other: 0
+; CHECK-NEXT:     Section: Absolute
+; CHECK-NEXT:   }
+; CHECK-NEXT:   Symbol {
 ; CHECK-NEXT:     Name: bar
 ; CHECK-NEXT:     Value: 0x201010
 ; CHECK-NEXT:     Size: 8
diff --git a/test/ELF/lto/parallel.ll b/test/ELF/lto/parallel.ll
index a1c15af..4ba3fd6 100644
--- a/test/ELF/lto/parallel.ll
+++ b/test/ELF/lto/parallel.ll
@@ -1,7 +1,7 @@
 ; REQUIRES: x86
 ; RUN: llvm-as -o %t.bc %s
 ; RUN: rm -f %t.lto.o %t1.lto.o
-; RUN: ld.lld -m elf_x86_64 --lto-partitions=2 -save-temps -o %t %t.bc -shared
+; RUN: ld.lld --lto-partitions=2 -save-temps -o %t %t.bc -shared
 ; RUN: llvm-nm %t.lto.o | FileCheck --check-prefix=CHECK0 %s
 ; RUN: llvm-nm %t1.lto.o | FileCheck --check-prefix=CHECK1 %s
 
diff --git a/test/ELF/lto/relax-relocs.ll b/test/ELF/lto/relax-relocs.ll
index 8e8d9d1..80e5dac 100644
--- a/test/ELF/lto/relax-relocs.ll
+++ b/test/ELF/lto/relax-relocs.ll
@@ -1,6 +1,6 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
-; RUN: ld.lld -m elf_x86_64 -save-temps -shared %t.o -o %t.so
+; RUN: ld.lld -save-temps -shared %t.o -o %t.so
 ; RUN: llvm-readobj -r %t.so.lto.o | FileCheck %s
 
 ; Test that we produce R_X86_64_REX_GOTPCRELX instead of R_X86_64_GOTPCREL
diff --git a/test/ELF/lto/relocatable.ll b/test/ELF/lto/relocatable.ll
index ef21f84..2ec9144 100644
--- a/test/ELF/lto/relocatable.ll
+++ b/test/ELF/lto/relocatable.ll
@@ -14,6 +14,15 @@
 ; CHECK-NEXT:     Section: Undefined
 ; CHECK-NEXT:   }
 ; CHECK-NEXT:   Symbol {
+; CHECK-NEXT:     Name: {{.*}}.o
+; CHECK-NEXT:     Value: 0x0
+; CHECK-NEXT:     Size: 0
+; CHECK-NEXT:     Binding: Local
+; CHECK-NEXT:     Type: File
+; CHECK-NEXT:     Other: 0
+; CHECK-NEXT:     Section: Absolute
+; CHECK-NEXT:   }
+; CHECK-NEXT:   Symbol {
 ; CHECK-NEXT:     Name:
 ; CHECK-NEXT:     Value: 0x0
 ; CHECK-NEXT:     Size: 0
diff --git a/test/ELF/lto/sample-profile.ll b/test/ELF/lto/sample-profile.ll
new file mode 100644
index 0000000..17eead7
--- /dev/null
+++ b/test/ELF/lto/sample-profile.ll
@@ -0,0 +1,25 @@
+; REQUIRES: x86
+; RUN: opt -module-summary %s -o %t1.o
+; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o
+
+; RUN: rm -f %t1.lto.o %t2.lto.o
+; RUN: ld.lld --lto-sample-profile=/dev/null %t1.o %t2.o -o %t3
+; RUN  opt -S %t3.lto.o | FileCheck %s
+
+; RUN: rm -f %t1.lto.o %t2.lto.o
+; RUN: ld.lld --plugin-opt=sample-profile=/dev/null %t1.o %t2.o -o %t3
+; RUN  opt -S %t3.lto.o | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; CHECK: ProfileSummary
+declare void @g(...)
+declare void @h(...)
+
+define void @f() {
+entry:
+  call void (...) @g()
+  call void (...) @h()
+  ret void
+}
diff --git a/test/ELF/lto/save-temps.ll b/test/ELF/lto/save-temps.ll
index c8e52ff..b34134c 100644
--- a/test/ELF/lto/save-temps.ll
+++ b/test/ELF/lto/save-temps.ll
@@ -3,7 +3,7 @@
 ; RUN: rm -f a.out a.out.lto.bc a.out.lto.o
 ; RUN: llvm-as %s -o %t.o
 ; RUN: llvm-as %p/Inputs/save-temps.ll -o %t2.o
-; RUN: ld.lld -shared -m elf_x86_64 %t.o %t2.o -save-temps
+; RUN: ld.lld -shared %t.o %t2.o -save-temps
 ; RUN: llvm-nm a.out | FileCheck %s
 ; RUN: llvm-nm a.out.0.0.preopt.bc | FileCheck %s
 ; RUN: llvm-nm a.out.lto.o | FileCheck %s
diff --git a/test/ELF/lto/start-lib.ll b/test/ELF/lto/start-lib.ll
index ec73954..024d887 100644
--- a/test/ELF/lto/start-lib.ll
+++ b/test/ELF/lto/start-lib.ll
@@ -4,17 +4,17 @@
 ; RUN: llvm-as %p/Inputs/start-lib1.ll -o %t2.o
 ; RUN: llvm-as %p/Inputs/start-lib2.ll -o %t3.o
 ;
-; RUN: ld.lld -m elf_x86_64 -shared -o %t3 %t1.o %t2.o %t3.o
+; RUN: ld.lld -shared -o %t3 %t1.o %t2.o %t3.o
 ; RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST1 %s
 ; TEST1: Name: bar
 ; TEST1: Name: foo
 ;
-; RUN: ld.lld -m elf_x86_64 -shared -o %t3 -u bar %t1.o --start-lib %t2.o %t3.o
+; RUN: ld.lld -shared -o %t3 -u bar %t1.o --start-lib %t2.o %t3.o
 ; RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST2 %s
 ; TEST2: Name: bar
 ; TEST2-NOT: Name: foo
 ;
-; RUN: ld.lld -m elf_x86_64 -shared -o %t3 %t1.o --start-lib %t2.o %t3.o
+; RUN: ld.lld -shared -o %t3 %t1.o --start-lib %t2.o %t3.o
 ; RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST3 %s
 ; TEST3-NOT: Name: bar
 ; TEST3-NOT: Name: foo
diff --git a/test/ELF/lto/symbol-ordering-lto.s b/test/ELF/lto/symbol-ordering-lto.s
index 4c29e54..232817c 100644
--- a/test/ELF/lto/symbol-ordering-lto.s
+++ b/test/ELF/lto/symbol-ordering-lto.s
@@ -12,12 +12,13 @@
 
 # Check that the order is tin -> _start -> pat.
 
-# CHECK: Symbol table '.symtab' contains 4 entries:
+# CHECK: Symbol table '.symtab' contains 5 entries:
 # CHECK-NEXT:   Num:    Value          Size Type    Bind   Vis      Ndx Name
 # CHECK-NEXT:     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
-# CHECK-NEXT:     1: 0000000000201008     0 NOTYPE  GLOBAL DEFAULT    1 _start
-# CHECK-NEXT:     2: 0000000000201020     6 FUNC    GLOBAL DEFAULT    1 pat
-# CHECK-NEXT:     3: 0000000000201000     6 FUNC    GLOBAL DEFAULT    1 tin
+# CHECK-NEXT:     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS {{.*}}.o
+# CHECK-NEXT:     2: 0000000000201008     0 NOTYPE  GLOBAL DEFAULT    1 _start
+# CHECK-NEXT:     3: 0000000000201020     6 FUNC    GLOBAL DEFAULT    1 pat
+# CHECK-NEXT:     4: 0000000000201000     6 FUNC    GLOBAL DEFAULT    1 tin
 
 .globl _start
 _start:
diff --git a/test/ELF/lto/thinlto-cant-write-index.ll b/test/ELF/lto/thinlto-cant-write-index.ll
new file mode 100644
index 0000000..94f2a45
--- /dev/null
+++ b/test/ELF/lto/thinlto-cant-write-index.ll
@@ -0,0 +1,23 @@
+; REQUIRES: x86
+
+; Basic ThinLTO tests.
+; RUN: opt -module-summary %s -o %t1.o
+; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o
+
+; Ensure lld generates error if unable to write to index files
+; RUN: rm -f %t2.o.thinlto.bc
+; RUN: touch %t2.o.thinlto.bc
+; RUN: chmod 400 %t2.o.thinlto.bc
+; RUN: not ld.lld --plugin-opt=thinlto-index-only -shared %t1.o %t2.o -o %t3 2>&1 | FileCheck %s
+; CHECK: cannot open {{.*}}2.o.thinlto.bc: {{P|p}}ermission denied
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @g(...)
+
+define void @f() {
+entry:
+  call void (...) @g()
+  ret void
+}
diff --git a/test/ELF/lto/thinlto-emit-imports.ll b/test/ELF/lto/thinlto-emit-imports.ll
new file mode 100644
index 0000000..cae7922
--- /dev/null
+++ b/test/ELF/lto/thinlto-emit-imports.ll
@@ -0,0 +1,55 @@
+; REQUIRES: x86
+
+; Generate summary sections and test lld handling.
+; RUN: opt -module-summary %s -o %t1.o
+; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o
+
+; Include a file with an empty module summary index, to ensure that the expected
+; output files are created regardless, for a distributed build system.
+; RUN: opt -module-summary %p/Inputs/thinlto_empty.ll -o %t3.o
+
+; Ensure lld generates imports files if requested for distributed backends.
+; RUN: rm -f %t3.o.imports %t3.o.thinlto.bc
+; RUN: ld.lld --plugin-opt=thinlto-index-only --plugin-opt=thinlto-emit-imports-files -shared %t1.o %t2.o %t3.o -o %t4
+
+; The imports file for this module contains the bitcode file for
+; Inputs/thinlto.ll
+; RUN: cat %t1.o.imports | count 1
+; RUN: cat %t1.o.imports | FileCheck %s --check-prefix=IMPORTS1
+; IMPORTS1: thinlto-emit-imports.ll.tmp2.o
+
+; The imports file for Input/thinlto.ll is empty as it does not import anything.
+; RUN: cat %t2.o.imports | count 0
+
+; The imports file for Input/thinlto_empty.ll is empty but should exist.
+; RUN: cat %t3.o.imports | count 0
+
+; The index file should be created even for the input with an empty summary.
+; RUN: ls %t3.o.thinlto.bc
+
+; Ensure lld generates error if unable to write to imports file.
+; RUN: rm -f %t3.o.imports
+; RUN: touch %t3.o.imports
+; RUN: chmod 400 %t3.o.imports
+; RUN: not ld.lld --plugin-opt=thinlto-index-only --plugin-opt=thinlto-emit-imports-files -shared %t1.o %t2.o %t3.o -o %t4 2>&1 | FileCheck %s --check-prefix=ERR
+; ERR: cannot open {{.*}}3.o.imports: {{P|p}}ermission denied
+
+; Ensure lld doesn't generate import files when thinlto-index-only is not enabled
+; RUN: rm -f %t1.o.imports
+; RUN: rm -f %t2.o.imports
+; RUN: rm -f %t3.o.imports
+; RUN: ld.lld --plugin-opt=thinlto-emit-imports-files -shared %t1.o %t2.o %t3.o -o %t4
+; RUN: not ls %t1.o.imports
+; RUN: not ls %t2.o.imports
+; RUN: not ls %t3.o.imports
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @g(...)
+
+define void @f() {
+entry:
+  call void (...) @g()
+  ret void
+}
diff --git a/test/ELF/lto/thinlto-index-file.ll b/test/ELF/lto/thinlto-index-file.ll
new file mode 100644
index 0000000..91f0b29
--- /dev/null
+++ b/test/ELF/lto/thinlto-index-file.ll
@@ -0,0 +1,24 @@
+; REQUIRES: x86
+
+; Basic ThinLTO tests.
+; RUN: opt -module-summary %s -o %t1.o
+; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o
+; RUN: opt -module-summary %p/Inputs/thinlto_empty.ll -o %t3.o
+
+; Ensure lld writes linked files to linked objects file
+; RUN: ld.lld --plugin-opt=thinlto-index-only=%t.idx -shared %t1.o %t2.o %t3.o -o %t4
+; RUN: FileCheck %s < %t.idx
+; CHECK: {{.*}}thinlto-index-file.ll.tmp1.o
+; CHECK: {{.*}}thinlto-index-file.ll.tmp2.o
+; CHECK: {{.*}}thinlto-index-file.ll.tmp3.o
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @g(...)
+
+define void @f() {
+entry:
+  call void (...) @g()
+  ret void
+}
diff --git a/test/ELF/lto/thinlto-index-only.ll b/test/ELF/lto/thinlto-index-only.ll
new file mode 100644
index 0000000..dba2fbc
--- /dev/null
+++ b/test/ELF/lto/thinlto-index-only.ll
@@ -0,0 +1,70 @@
+; REQUIRES: x86
+
+; First ensure that the ThinLTO handling in lld handles
+; bitcode without summary sections gracefully and generates index file.
+; RUN: llvm-as %s -o %t1.o
+; RUN: llvm-as %p/Inputs/thinlto.ll -o %t2.o
+; RUN: rm -f %t3
+; RUN: ld.lld --plugin-opt=thinlto-index-only -shared %t1.o %t2.o -o %t3
+; RUN: ls %t2.o.thinlto.bc
+; RUN: not test -e %t3
+; RUN: ld.lld -shared %t1.o %t2.o -o %t3
+; RUN: llvm-nm %t3 | FileCheck %s --check-prefix=NM
+
+; Basic ThinLTO tests.
+; RUN: opt -module-summary %s -o %t1.o
+; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o
+; RUN: opt -module-summary %p/Inputs/thinlto_empty.ll -o %t3.o
+
+; Ensure lld generates an index and not a binary if requested.
+; RUN: rm -f %t4
+; RUN: ld.lld --plugin-opt=thinlto-index-only -shared %t1.o %t2.o -o %t4
+; RUN: llvm-bcanalyzer -dump %t1.o.thinlto.bc | FileCheck %s --check-prefix=BACKEND1
+; RUN: llvm-bcanalyzer -dump %t2.o.thinlto.bc | FileCheck %s --check-prefix=BACKEND2
+; RUN: not test -e %t4
+
+; Ensure lld generates an index even if the file is wrapped in --start-lib/--end-lib
+; RUN: rm -f %t2.o.thinlto.bc %t4
+; RUN: ld.lld --plugin-opt=thinlto-index-only -shared %t1.o %t3.o --start-lib %t2.o --end-lib -o %t4
+; RUN: ls %t2.o.thinlto.bc
+; RUN: not test -e %t4
+
+; NM: T f
+
+; The backend index for this module contains summaries from itself and
+; Inputs/thinlto.ll, as it imports from the latter.
+; BACKEND1: <MODULE_STRTAB_BLOCK
+; BACKEND1-NEXT: <ENTRY {{.*}} record string = '{{.*}}thinlto-index-only.ll.tmp{{.*}}.o'
+; BACKEND1-NEXT: <ENTRY {{.*}} record string = '{{.*}}thinlto-index-only.ll.tmp{{.*}}.o'
+; BACKEND1-NEXT: </MODULE_STRTAB_BLOCK
+; BACKEND1: <GLOBALVAL_SUMMARY_BLOCK
+; BACKEND1: <VERSION
+; BACKEND1: <FLAGS
+; BACKEND1: <VALUE_GUID op0={{1|2}} op1={{-3706093650706652785|-5300342847281564238}}
+; BACKEND1: <VALUE_GUID op0={{1|2}} op1={{-3706093650706652785|-5300342847281564238}}
+; BACKEND1: <COMBINED
+; BACKEND1: <COMBINED
+; BACKEND1: </GLOBALVAL_SUMMARY_BLOCK
+
+; The backend index for Input/thinlto.ll contains summaries from itself only,
+; as it does not import anything.
+; BACKEND2: <MODULE_STRTAB_BLOCK
+; BACKEND2-NEXT: <ENTRY {{.*}} record string = '{{.*}}thinlto-index-only.ll.tmp2.o'
+; BACKEND2-NEXT: </MODULE_STRTAB_BLOCK
+; BACKEND2-NEXT: <GLOBALVAL_SUMMARY_BLOCK
+; BACKEND2-NEXT: <VERSION
+; BACKEND2-NEXT: <FLAGS
+; BACKEND2-NEXT: <VALUE_GUID op0=1 op1=-5300342847281564238
+; BACKEND2-NEXT: <COMBINED
+; BACKEND2-NEXT: </GLOBALVAL_SUMMARY_BLOCK
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @g(...)
+
+define void @f() {
+entry:
+  call void (...) @g()
+  ret void
+}
diff --git a/test/ELF/lto/thinlto-no-index.ll b/test/ELF/lto/thinlto-no-index.ll
new file mode 100644
index 0000000..f80cf0e
--- /dev/null
+++ b/test/ELF/lto/thinlto-no-index.ll
@@ -0,0 +1,24 @@
+; REQUIRES: x86
+
+; Basic ThinLTO tests.
+; RUN: opt -module-summary %s -o %t1.o
+; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o
+; RUN: opt -module-summary %p/Inputs/thinlto_empty.ll -o %t3.o
+
+; Ensure lld doesn't generates index files when thinlto-index-only is not enabled
+; RUN: rm -f %t1.o.thinlto.bc %t2.o.thinlto.bc %t3.o.thinlto.bc
+; RUN: ld.lld -shared %t1.o %t2.o %t3.o -o %t4
+; RUN: not ls %t1.o.thinlto.bc
+; RUN: not ls %t2.o.thinlto.bc
+; RUN: not ls %t3.o.thinlto.bc
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @g(...)
+
+define void @f() {
+entry:
+  call void (...) @g()
+  ret void
+}
diff --git a/test/ELF/lto/thinlto-obj-path.ll b/test/ELF/lto/thinlto-obj-path.ll
new file mode 100644
index 0000000..bb69bb8
--- /dev/null
+++ b/test/ELF/lto/thinlto-obj-path.ll
@@ -0,0 +1,23 @@
+; REQUIRES: x86
+
+; RUN: opt -module-summary %s -o %t1.o
+; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o
+
+; Test to ensure that thinlto-index-only with obj-path creates the file.
+; RUN: rm -f %t4.o
+; RUN: ld.lld --plugin-opt=thinlto-index-only --plugin-opt=obj-path=%t4.o -shared %t1.o %t2.o -o %t3
+; RUN: llvm-readobj -h %t4.o | FileCheck %s
+; RUN: llvm-nm %t4.o | count 0
+
+; CHECK: Format: ELF64-x86-64
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @g(...)
+
+define void @f() {
+entry:
+  call void (...) @g()
+  ret void
+}
diff --git a/test/ELF/lto/thinlto-object-suffix-replace.ll b/test/ELF/lto/thinlto-object-suffix-replace.ll
new file mode 100644
index 0000000..05ce942
--- /dev/null
+++ b/test/ELF/lto/thinlto-object-suffix-replace.ll
@@ -0,0 +1,50 @@
+; REQUIRES: x86
+
+; Test to make sure the thinlto-object-suffix-replace option is handled
+; correctly.
+
+; Generate bitcode file with summary, as well as a minimized bitcode without
+; the debug metadata for the thin link.
+; RUN: opt -thinlto-bc %s -thin-link-bitcode-file=%t1.thinlink.bc -o %t1.o
+
+; First perform the thin link on the normal bitcode file, and save the
+; resulting index.
+; RUN: ld.lld --plugin-opt=thinlto-index-only -shared %t1.o -o %t3
+; RUN: cp %t1.o.thinlto.bc %t1.o.thinlto.bc.orig
+
+; Next perform the thin link on the minimized bitcode file, and compare dump
+; of the resulting index to the above dump to ensure they are identical.
+; RUN: rm -f %t1.o.thinlto.bc
+; Make sure it isn't inadvertently using the regular bitcode file.
+; RUN: rm -f %t1.o
+; RUN: ld.lld --plugin-opt=thinlto-index-only \
+; RUN: --plugin-opt=thinlto-object-suffix-replace=".thinlink.bc;.o" \
+; RUN: -shared %t1.thinlink.bc -o %t3
+; RUN: diff %t1.o.thinlto.bc.orig %t1.o.thinlto.bc
+
+; Ensure lld generates error if object suffix replace option does not have 'old;new' format
+; RUN: rm -f %t1.o.thinlto.bc
+; RUN: not ld.lld --plugin-opt=thinlto-index-only \
+; RUN: --plugin-opt=thinlto-object-suffix-replace="abc:def" -shared %t1.thinlink.bc \
+; RUN: -o %t3 2>&1 | FileCheck %s --check-prefix=ERR1
+; ERR1: --plugin-opt=thinlto-object-suffix-replace= expects 'old;new' format, but got abc:def
+
+; Ensure lld generates error if old suffix doesn't exist in file name
+; RUN: rm -f %t1.o
+; RUN: not ld.lld --plugin-opt=thinlto-index-only \
+; RUN: --plugin-opt=thinlto-object-suffix-replace=".abc;.o" -shared %t1.thinlink.bc \
+; RUN: -o %t3 2>&1 | FileCheck %s --check-prefix=ERR2
+; ERR2: error: -thinlto-object-suffix-replace=.abc;.o was given, but {{.*}} does not end with the suffix
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f() {
+entry:
+  ret void
+}
+
+!llvm.dbg.cu = !{}
+
+!1 = !{i32 2, !"Debug Info Version", i32 3}
+!llvm.module.flags = !{!1}
diff --git a/test/ELF/lto/thinlto-prefix-replace.ll b/test/ELF/lto/thinlto-prefix-replace.ll
new file mode 100644
index 0000000..c276dae
--- /dev/null
+++ b/test/ELF/lto/thinlto-prefix-replace.ll
@@ -0,0 +1,23 @@
+; REQUIRES: x86
+; Check that changing the output path via thinlto-prefix-replace works
+; RUN: mkdir -p %t/oldpath
+; RUN: opt -module-summary %s -o %t/oldpath/thinlto_prefix_replace.o
+
+; Ensure that there is no existing file at the new path, so we properly
+; test the creation of the new file there.
+; RUN: rm -f %t/newpath/thinlto_prefix_replace.o.thinlto.bc
+; RUN: ld.lld --plugin-opt=thinlto-index-only --plugin-opt=thinlto-prefix-replace="%t/oldpath/;%t/newpath/" -shared %t/oldpath/thinlto_prefix_replace.o -o %t/thinlto_prefix_replace
+; RUN: ls %t/newpath/thinlto_prefix_replace.o.thinlto.bc
+
+; Ensure that lld generates error if prefix replace option does not have 'old;new' format
+; RUN: rm -f %t/newpath/thinlto_prefix_replace.o.thinlto.bc
+; RUN: not ld.lld --plugin-opt=thinlto-index-only --plugin-opt=thinlto-prefix-replace=abc:def -shared %t/oldpath/thinlto_prefix_replace.o -o %t/thinlto_prefix_replace 2>&1 | FileCheck %s --check-prefix=ERR
+; ERR: --plugin-opt=thinlto-prefix-replace= expects 'old;new' format, but got abc:def
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f() {
+entry:
+  ret void
+}
diff --git a/test/ELF/lto/thinlto.ll b/test/ELF/lto/thinlto.ll
index 37d2b88..51c82ec 100644
--- a/test/ELF/lto/thinlto.ll
+++ b/test/ELF/lto/thinlto.ll
@@ -1,29 +1,28 @@
 ; REQUIRES: x86
+
 ; Basic ThinLTO tests.
-; RUN: opt -module-summary %s -o %t.o
+; RUN: opt -module-summary %s -o %t1.o
 ; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o
 
 ; First force single-threaded mode
-; RUN: rm -f %t.lto.o %t1.lto.o
-; RUN: ld.lld -save-temps --thinlto-jobs=1 -shared %t.o %t2.o -o %t
-; RUN: llvm-nm %t1.lto.o | FileCheck %s --check-prefix=NM1
-; RUN: llvm-nm %t2.lto.o | FileCheck %s --check-prefix=NM2
+; RUN: rm -f %t31.lto.o %t32.lto.o
+; RUN: ld.lld -save-temps --thinlto-jobs=1 -shared %t1.o %t2.o -o %t3
+; RUN: llvm-nm %t31.lto.o | FileCheck %s --check-prefix=NM1
+; RUN: llvm-nm %t32.lto.o | FileCheck %s --check-prefix=NM2
 
 ; Next force multi-threaded mode
-; RUN: rm -f %t2.lto.o %t21.lto.o
-; RUN: ld.lld -save-temps --thinlto-jobs=2 -shared %t.o %t2.o -o %t2
-; RUN: llvm-nm %t21.lto.o | FileCheck %s --check-prefix=NM1
-; RUN: llvm-nm %t22.lto.o | FileCheck %s --check-prefix=NM2
-
-; NM1: T f
-; NM1-NOT: U g
-
-; NM2: T g
+; RUN: rm -f %t31.lto.o %t32.lto.o
+; RUN: ld.lld -save-temps --thinlto-jobs=2 -shared %t1.o %t2.o -o %t3
+; RUN: llvm-nm %t31.lto.o | FileCheck %s --check-prefix=NM1
+; RUN: llvm-nm %t32.lto.o | FileCheck %s --check-prefix=NM2
 
 ; Then check without --thinlto-jobs (which currently default to hardware_concurrency)
-; We just check that we don't crash or fail (as it's not sure which tests are
-; stable on the final output file itself.
-; RUN: ld.lld -shared %t.o %t2.o -o %t2
+; RUN: ld.lld -shared %t1.o %t2.o -o %t3
+; RUN: llvm-nm %t31.lto.o | FileCheck %s --check-prefix=NM1
+; RUN: llvm-nm %t32.lto.o | FileCheck %s --check-prefix=NM2
+
+; NM1: T f
+; NM2: T g
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/ELF/lto/tls-mixed.ll b/test/ELF/lto/tls-mixed.ll
index 524bb4f..9d5a693 100644
--- a/test/ELF/lto/tls-mixed.ll
+++ b/test/ELF/lto/tls-mixed.ll
@@ -1,7 +1,7 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t1.o
 ; RUN: llvm-mc %p/Inputs/tls-mixed.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
-; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t.so -shared
+; RUN: ld.lld %t1.o %t2.o -o %t.so -shared
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/ELF/lto/tls-preserve.ll b/test/ELF/lto/tls-preserve.ll
index 8aebcb7..c9b7675 100644
--- a/test/ELF/lto/tls-preserve.ll
+++ b/test/ELF/lto/tls-preserve.ll
@@ -1,7 +1,7 @@
 ; TLS attribute needs to be preserved.
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t1.o
-; RUN: ld.lld -shared %t1.o -m elf_x86_64 -o %t1
+; RUN: ld.lld -shared %t1.o -o %t1
 ; RUN: llvm-readobj -t %t1 | FileCheck %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/test/ELF/lto/type-merge.ll b/test/ELF/lto/type-merge.ll
index d6f196d..985c44b 100644
--- a/test/ELF/lto/type-merge.ll
+++ b/test/ELF/lto/type-merge.ll
@@ -1,7 +1,7 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
 ; RUN: llvm-as %p/Inputs/type-merge.ll -o %t2.o
-; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t -shared -save-temps
+; RUN: ld.lld %t.o %t2.o -o %t -shared -save-temps
 ; RUN: llvm-dis < %t.0.0.preopt.bc | FileCheck %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/test/ELF/lto/type-merge2.ll b/test/ELF/lto/type-merge2.ll
index 6ebbf77..5944be7 100644
--- a/test/ELF/lto/type-merge2.ll
+++ b/test/ELF/lto/type-merge2.ll
@@ -1,7 +1,7 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
 ; RUN: llvm-as %p/Inputs/type-merge2.ll -o %t2.o
-; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t.so -shared -save-temps
+; RUN: ld.lld %t.o %t2.o -o %t.so -shared -save-temps
 ; RUN: llvm-dis %t.so.0.0.preopt.bc -o - | FileCheck %s
 
 target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/ELF/lto/undef-weak.ll b/test/ELF/lto/undef-weak.ll
index 215978a..e090f56 100644
--- a/test/ELF/lto/undef-weak.ll
+++ b/test/ELF/lto/undef-weak.ll
@@ -1,13 +1,12 @@
 ; REQUIRES: x86
-
 ; RUN: llvm-as %S/Inputs/archive.ll -o %t1.o
 ; RUN: rm -f %t.a
 ; RUN: llvm-ar rcs %t.a %t1.o
 
-
 ; RUN: llvm-as %s -o %t2.o
-; RUN: ld.lld -m elf_x86_64 %t2.o -o %t2.so %t.a -shared
+; RUN: ld.lld %t2.o -o %t2.so %t.a -shared
 ; RUN: llvm-readobj -t %t2.so | FileCheck %s
+
 target triple = "x86_64-unknown-linux-gnu"
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 
diff --git a/test/ELF/lto/undef.ll b/test/ELF/lto/undef.ll
index 41da610..4ea7e83 100644
--- a/test/ELF/lto/undef.ll
+++ b/test/ELF/lto/undef.ll
@@ -1,6 +1,6 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
-; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared
+; RUN: ld.lld %t.o -o %t.so -shared
 ; RUN: llvm-readobj -t %t.so | FileCheck %s
 target triple = "x86_64-unknown-linux-gnu"
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/test/ELF/lto/undefined-puts.ll b/test/ELF/lto/undefined-puts.ll
index d136303..6c3dc76 100644
--- a/test/ELF/lto/undefined-puts.ll
+++ b/test/ELF/lto/undefined-puts.ll
@@ -2,7 +2,7 @@
 ; RUN: llvm-mc %p/Inputs/shared.s -o %t1.o -filetype=obj -triple=x86_64-unknown-linux
 ; RUN: ld.lld %t1.o -o %t1.so -shared
 ; RUN: llvm-as %s -o %t2.o
-; RUN: ld.lld %t1.so %t2.o -m elf_x86_64 -o %t
+; RUN: ld.lld %t1.so %t2.o -o %t
 ; RUN: llvm-readobj -dyn-symbols -dyn-relocations %t | FileCheck %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/test/ELF/lto/unnamed-addr-comdat.ll b/test/ELF/lto/unnamed-addr-comdat.ll
index 29a5941..38b08ab 100644
--- a/test/ELF/lto/unnamed-addr-comdat.ll
+++ b/test/ELF/lto/unnamed-addr-comdat.ll
@@ -1,6 +1,6 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
-; RUN: ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -save-temps -shared
+; RUN: ld.lld %t.o %t.o -o %t.so -save-temps -shared
 ; RUN: llvm-dis %t.so.0.2.internalize.bc -o - | FileCheck %s
 
 target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/ELF/lto/unnamed-addr-drop.ll b/test/ELF/lto/unnamed-addr-drop.ll
index e827cbb..ad662b7 100644
--- a/test/ELF/lto/unnamed-addr-drop.ll
+++ b/test/ELF/lto/unnamed-addr-drop.ll
@@ -1,7 +1,7 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t1.o
 ; RUN: llvm-as %S/Inputs/unnamed-addr-drop.ll -o %t2.o
-; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t.so -save-temps -shared
+; RUN: ld.lld %t1.o %t2.o -o %t.so -save-temps -shared
 ; RUN: llvm-dis %t.so.0.2.internalize.bc -o - | FileCheck %s
 
 target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/ELF/lto/unnamed-addr-lib.ll b/test/ELF/lto/unnamed-addr-lib.ll
index c2bc601..0c47468 100644
--- a/test/ELF/lto/unnamed-addr-lib.ll
+++ b/test/ELF/lto/unnamed-addr-lib.ll
@@ -2,7 +2,7 @@
 ; RUN: llvm-as %s -o %t.o
 ; RUN: llvm-mc %p/Inputs/unnamed-addr-lib.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
 ; RUN: ld.lld %t2.o -shared -o %t2.so
-; RUN: ld.lld -m elf_x86_64 %t.o %t2.so -o %t.so -save-temps -shared
+; RUN: ld.lld %t.o %t2.so -o %t.so -save-temps -shared
 ; RUN: llvm-dis %t.so.0.2.internalize.bc -o - | FileCheck %s
 
 ; This documents a small limitation of lld's internalization logic. We decide
diff --git a/test/ELF/lto/unnamed-addr.ll b/test/ELF/lto/unnamed-addr.ll
index 56fe148..7504fdf 100644
--- a/test/ELF/lto/unnamed-addr.ll
+++ b/test/ELF/lto/unnamed-addr.ll
@@ -1,6 +1,6 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
-; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -save-temps -shared
+; RUN: ld.lld %t.o -o %t.so -save-temps -shared
 ; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s
 
 target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/ELF/lto/verify-invalid.ll b/test/ELF/lto/verify-invalid.ll
index e6138a3..9fa0f9e 100644
--- a/test/ELF/lto/verify-invalid.ll
+++ b/test/ELF/lto/verify-invalid.ll
@@ -1,10 +1,10 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
-; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -mllvm -debug-pass=Arguments \
+; RUN: ld.lld %t.o -o %t2 -mllvm -debug-pass=Arguments \
 ; RUN:   2>&1 | FileCheck -check-prefix=DEFAULT %s
-; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -mllvm -debug-pass=Arguments \
+; RUN: ld.lld %t.o -o %t2 -mllvm -debug-pass=Arguments \
 ; RUN:   -disable-verify 2>&1 | FileCheck -check-prefix=DISABLE %s
-; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -mllvm -debug-pass=Arguments \
+; RUN: ld.lld %t.o -o %t2 -mllvm -debug-pass=Arguments \
 ; RUN:   --plugin-opt=disable-verify 2>&1 | FileCheck -check-prefix=DISABLE %s
 
 target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/ELF/lto/version-script.ll b/test/ELF/lto/version-script.ll
index c43b443..35a36b5 100644
--- a/test/ELF/lto/version-script.ll
+++ b/test/ELF/lto/version-script.ll
@@ -1,7 +1,7 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
 ; RUN: echo "VERSION_1.0{ global: foo; local: *; }; VERSION_2.0{ global: bar; local: *; };" > %t.script
-; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -shared --version-script %t.script -save-temps
+; RUN: ld.lld %t.o -o %t2 -shared --version-script %t.script -save-temps
 ; RUN: llvm-dis < %t2.0.0.preopt.bc | FileCheck %s
 ; RUN: llvm-readobj -V -dyn-symbols %t2 | FileCheck --check-prefix=DSO %s
 
diff --git a/test/ELF/lto/weak.ll b/test/ELF/lto/weak.ll
index 381ef7a..a807c13 100644
--- a/test/ELF/lto/weak.ll
+++ b/test/ELF/lto/weak.ll
@@ -1,6 +1,6 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
-; RUN: ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -shared
+; RUN: ld.lld %t.o %t.o -o %t.so -shared
 ; RUN: llvm-readobj -t %t.so | FileCheck %s
 
 target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/ELF/map-file.s b/test/ELF/map-file.s
index 23b9381..390d880 100644
--- a/test/ELF/map-file.s
+++ b/test/ELF/map-file.s
@@ -40,60 +40,61 @@
 abs = 0xAB5
 labs = 0x1AB5
 
-// CHECK:      Address          Size             Align Out     In      Symbol
-// CHECK-NEXT: 00000000002001c8 0000000000000078     8 .dynsym
-// CHECK-NEXT: 00000000002001c8 0000000000000078     8         <internal>:(.dynsym)
-// CHECK-NEXT: 0000000000200240 000000000000002c     8 .gnu.hash
-// CHECK-NEXT: 0000000000200240 000000000000002c     8         <internal>:(.gnu.hash)
-// CHECK-NEXT: 000000000020026c 0000000000000030     4 .hash
-// CHECK-NEXT: 000000000020026c 0000000000000030     4         <internal>:(.hash)
-// CHECK-NEXT: 000000000020029c 0000000000000031     1 .dynstr
-// CHECK-NEXT: 000000000020029c 0000000000000031     1         <internal>:(.dynstr)
-// CHECK-NEXT: 00000000002002d0 0000000000000030     8 .rela.dyn
-// CHECK-NEXT: 00000000002002d0 0000000000000030     8         <internal>:(.rela.dyn)
-// CHECK-NEXT: 0000000000200300 0000000000000030     8 .rela.plt
-// CHECK-NEXT: 0000000000200300 0000000000000030     8         <internal>:(.rela.plt)
-// CHECK-NEXT: 0000000000200330 0000000000000060     8 .eh_frame
-// CHECK-NEXT: 0000000000200330 000000000000002c     0         {{.*}}{{/|\\}}map-file.s.tmp1.o:(.eh_frame+0x0)
-// CHECK-NEXT: 0000000000200360 0000000000000014     0         {{.*}}{{/|\\}}map-file.s.tmp1.o:(.eh_frame+0x2c)
-// CHECK-NEXT: 0000000000200378 0000000000000018     0         {{.*}}{{/|\\}}map-file.s.tmp2.o:(.eh_frame+0x18)
-// CHECK-NEXT: 0000000000201000 000000000000002d     4 .text
-// CHECK-NEXT: 0000000000201000 0000000000000028     4         {{.*}}{{/|\\}}map-file.s.tmp1.o:(.text)
-// CHECK-NEXT: 0000000000201000 0000000000000000     0                 _start
-// CHECK-NEXT: 000000000020101f 0000000000000000     0                 f(int)
-// CHECK-NEXT: 0000000000201028 0000000000000000     0                 local
-// CHECK-NEXT: 0000000000201028 0000000000000002     4         {{.*}}{{/|\\}}map-file.s.tmp2.o:(.text)
-// CHECK-NEXT: 0000000000201028 0000000000000000     0                 foo
-// CHECK-NEXT: 0000000000201029 0000000000000000     0                 bar
-// CHECK-NEXT: 000000000020102a 0000000000000000     1         {{.*}}{{/|\\}}map-file.s.tmp2.o:(.text.zed)
-// CHECK-NEXT: 000000000020102a 0000000000000000     0                 zed
-// CHECK-NEXT: 000000000020102c 0000000000000000     4         {{.*}}{{/|\\}}map-file.s.tmp3.o:(.text)
-// CHECK-NEXT: 000000000020102c 0000000000000000     0                 bah
-// CHECK-NEXT: 000000000020102c 0000000000000001     4         {{.*}}{{/|\\}}map-file.s.tmp4.a(map-file.s.tmp4.o):(.text)
-// CHECK-NEXT: 000000000020102c 0000000000000000     0                 baz
-// CHECK-NEXT: 0000000000201030 0000000000000030    16 .plt
-// CHECK-NEXT: 0000000000201030 0000000000000030    16         <internal>:(.plt)
-// CHECK-NEXT: 0000000000201040 0000000000000000     0                 sharedFunc1
-// CHECK-NEXT: 0000000000201050 0000000000000000     0                 sharedFunc2
-// CHECK-NEXT: 0000000000202000 0000000000000028     8 .got.plt
-// CHECK-NEXT: 0000000000202000 0000000000000028     8         <internal>:(.got.plt)
-// CHECK-NEXT: 0000000000203000 0000000000000100     8 .dynamic
-// CHECK-NEXT: 0000000000203000 0000000000000100     8         <internal>:(.dynamic)
-// CHECK-NEXT: 0000000000204000 0000000000000010    16 .bss
-// CHECK-NEXT: 0000000000204000 0000000000000004    16         {{.*}}{{/|\\}}map-file.s.tmp1.o:(COMMON)
-// CHECK-NEXT: 0000000000204000 0000000000000004     0                 common
-// CHECK-NEXT: 0000000000204004 0000000000000004     1         <internal>:(.bss)
-// CHECK-NEXT: 0000000000204004 0000000000000004     0                 sharedFoo
-// CHECK-NEXT: 0000000000204008 0000000000000008     1         <internal>:(.bss)
-// CHECK-NEXT: 0000000000204008 0000000000000008     0                 sharedBar
-// CHECK-NEXT: 0000000000000000 0000000000000008     1 .comment
-// CHECK-NEXT: 0000000000000000 0000000000000008     1         <internal>:(.comment)
-// CHECK-NEXT: 0000000000000000 0000000000000198     8 .symtab
-// CHECK-NEXT: 0000000000000000 0000000000000198     8         <internal>:(.symtab)
-// CHECK-NEXT: 0000000000000000 0000000000000084     1 .shstrtab
-// CHECK-NEXT: 0000000000000000 0000000000000084     1         <internal>:(.shstrtab)
-// CHECK-NEXT: 0000000000000000 000000000000006d     1 .strtab
-// CHECK-NEXT: 0000000000000000 000000000000006d     1         <internal>:(.strtab)
+// CHECK:         VMA              LMA     Size Align Out     In      Symbol
+// CHECK-NEXT: 2001c8           2001c8       78     8 .dynsym
+// CHECK-NEXT: 2001c8           2001c8       78     8         <internal>:(.dynsym)
+// CHECK-NEXT: 200240           200240       31     1 .dynstr
+// CHECK-NEXT: 200240           200240       31     1         <internal>:(.dynstr)
+// CHECK-NEXT: 200278           200278       2c     8 .gnu.hash
+// CHECK-NEXT: 200278           200278       2c     8         <internal>:(.gnu.hash)
+// CHECK-NEXT: 2002a4           2002a4       30     4 .hash
+// CHECK-NEXT: 2002a4           2002a4       30     4         <internal>:(.hash)
+// CHECK-NEXT: 2002d8           2002d8       30     8 .rela.dyn
+// CHECK-NEXT: 2002d8           2002d8       30     8         <internal>:(.rela.dyn)
+// CHECK-NEXT: 200308           200308       30     8 .rela.plt
+// CHECK-NEXT: 200308           200308       30     8         <internal>:(.rela.plt)
+// CHECK-NEXT: 200338           200338       64     8 .eh_frame
+// CHECK-NEXT: 200338           200338       2c     1         {{.*}}{{/|\\}}map-file.s.tmp1.o:(.eh_frame+0x0)
+// CHECK-NEXT: 200368           200368       14     1         {{.*}}{{/|\\}}map-file.s.tmp1.o:(.eh_frame+0x2c)
+// CHECK-NEXT: 200380           200380       18     1         {{.*}}{{/|\\}}map-file.s.tmp2.o:(.eh_frame+0x18)
+// CHECK-NEXT: 201000           201000       2d     4 .text
+// CHECK-NEXT: 201000           201000       28     4         {{.*}}{{/|\\}}map-file.s.tmp1.o:(.text)
+// CHECK-NEXT: 201000           201000        0     1                 _start
+// CHECK-NEXT: 20101f           20101f        0     1                 f(int)
+// CHECK-NEXT: 201028           201028        0     1                 local
+// CHECK-NEXT: 201028           201028        2     4         {{.*}}{{/|\\}}map-file.s.tmp2.o:(.text)
+// CHECK-NEXT: 201028           201028        0     1                 foo
+// CHECK-NEXT: 201029           201029        0     1                 bar
+// CHECK-NEXT: 20102a           20102a        0     1         {{.*}}{{/|\\}}map-file.s.tmp2.o:(.text.zed)
+// CHECK-NEXT: 20102a           20102a        0     1                 zed
+// CHECK-NEXT: 20102c           20102c        0     4         {{.*}}{{/|\\}}map-file.s.tmp3.o:(.text)
+// CHECK-NEXT: 20102c           20102c        0     1                 bah
+// CHECK-NEXT: 20102c           20102c        1     4         {{.*}}{{/|\\}}map-file.s.tmp4.a(map-file.s.tmp4.o):(.text)
+// CHECK-NEXT: 20102c           20102c        0     1                 baz
+// CHECK-NEXT: 201030           201030       30    16 .plt
+// CHECK-NEXT: 201030           201030       30    16         <internal>:(.plt)
+// CHECK-NEXT: 201040           201040        0     1                 sharedFunc1
+// CHECK-NEXT: 201050           201050        0     1                 sharedFunc2
+// CHECK-NEXT: 202000           202000       28     8 .got.plt
+// CHECK-NEXT: 202000           202000       28     8         <internal>:(.got.plt)
+// CHECK-NEXT: 203000           203000      100     8 .dynamic
+// CHECK-NEXT: 203000           203000      100     8         <internal>:(.dynamic)
+// CHECK-NEXT: 204000           204000       10    16 .bss
+// CHECK-NEXT: 204000           204000        4    16         {{.*}}{{/|\\}}map-file.s.tmp1.o:(COMMON)
+// CHECK-NEXT: 204000           204000        4     1                 common
+// CHECK-NEXT: 204004           204004        4     1         <internal>:(.bss)
+// CHECK-NEXT: 204004           204004        4     1                 sharedFoo
+// CHECK-NEXT: 204008           204008        8     1         <internal>:(.bss)
+// CHECK-NEXT: 204008           204008        8     1                 sharedBar
+// CHECK-NEXT:      0                0        8     1 .comment
+// CHECK-NEXT:      0                0        8     1         <internal>:(.comment)
+// CHECK-NEXT:      0                0      198     8 .symtab
+// CHECK-NEXT:      0                0      198     8         <internal>:(.symtab)
+// CHECK-NEXT:      0                0       84     1 .shstrtab
+// CHECK-NEXT:      0                0       84     1         <internal>:(.shstrtab)
+// CHECK-NEXT:      0                0       6d     1 .strtab
+// CHECK-NEXT:      0                0       6d     1         <internal>:(.strtab)
+
 
 // RUN: not ld.lld %t1.o %t2.o %t3.o %t4.a -o %t -Map=/ 2>&1 \
 // RUN:  | FileCheck -check-prefix=FAIL %s
diff --git a/test/ELF/merge-gc-piece.s b/test/ELF/merge-gc-piece.s
new file mode 100644
index 0000000..95ea17c
--- /dev/null
+++ b/test/ELF/merge-gc-piece.s
@@ -0,0 +1,38 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t.so -shared --gc-sections
+# RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
+
+
+# CHECK:      Name: .foo
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT:   SHF_ALLOC
+# CHECK-NEXT:   SHF_MERGE
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x1C8
+
+# CHECK:      Name: .bar
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address:
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size: 16
+# CHECK-NEXT: Link:
+# CHECK-NEXT: Info:
+# CHECK-NEXT: AddressAlignment:
+# CHECK-NEXT: EntrySize:
+# CHECK-NEXT: SectionData (
+# CHECK-NEXT:   0000: C9010000 00000000 CA010000 00000000
+# CHECK-NEXT: )
+
+        .section .foo,"aM",@progbits,8
+        .quad 42
+        .global sym
+sym:
+        .quad 43
+
+        .section .bar
+        .quad .foo + 1
+        .quad .foo + 2
diff --git a/test/ELF/merge-gc-piece2.s b/test/ELF/merge-gc-piece2.s
new file mode 100644
index 0000000..88e0904
--- /dev/null
+++ b/test/ELF/merge-gc-piece2.s
@@ -0,0 +1,27 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t.so -shared --gc-sections
+# RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
+
+# CHECK:      Name: .bar
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address:
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size: 16
+# CHECK-NEXT: Link:
+# CHECK-NEXT: Info:
+# CHECK-NEXT: AddressAlignment:
+# CHECK-NEXT: EntrySize:
+# CHECK-NEXT: SectionData (
+# CHECK-NEXT:   0000: 01000000 00000000 02000000 00000000
+# CHECK-NEXT: )
+
+        .section .foo,"aM",@progbits,8
+        .quad 42
+        .quad 43
+
+        .section .bar
+        .quad .foo + 1
+        .quad .foo + 2
diff --git a/test/ELF/merge-shared-str.s b/test/ELF/merge-shared-str.s
index 2ab03a4..e06d00d 100644
--- a/test/ELF/merge-shared-str.s
+++ b/test/ELF/merge-shared-str.s
@@ -19,10 +19,10 @@
 // CHECK-NEXT:   SHF_MERGE
 // CHECK-NEXT:   SHF_STRINGS
 // CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x1C8
+// CHECK-NEXT: Address: 0x1E1
 
 // CHECK:      Relocations [
 // CHECK-NEXT:   Section ({{.*}}) .rela.dyn {
-// CHECK-NEXT:     0x{{.*}} R_X86_64_RELATIVE - 0x1C9
+// CHECK-NEXT:     0x{{.*}} R_X86_64_RELATIVE - 0x1E2
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]
diff --git a/test/ELF/merge-shared.s b/test/ELF/merge-shared.s
index 4c1d7c0..3894e53 100644
--- a/test/ELF/merge-shared.s
+++ b/test/ELF/merge-shared.s
@@ -17,10 +17,10 @@
 // CHECK-NEXT:   SHF_ALLOC
 // CHECK-NEXT:   SHF_MERGE
 // CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x1C8
+// CHECK-NEXT: Address: 0x1E4
 
 // CHECK:      Relocations [
 // CHECK-NEXT:   Section ({{.*}}) .rela.dyn {
-// CHECK-NEXT:     0x{{.*}} R_X86_64_RELATIVE - 0x1CA
+// CHECK-NEXT:     0x{{.*}} R_X86_64_RELATIVE - 0x1E6
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]
diff --git a/test/ELF/merge-string.s b/test/ELF/merge-string.s
index d284d0a..2496205 100644
--- a/test/ELF/merge-string.s
+++ b/test/ELF/merge-string.s
@@ -28,8 +28,8 @@
 // CHECK-NEXT:   SHF_MERGE
 // CHECK-NEXT:   SHF_STRINGS
 // CHECK-NEXT: ]
-// CHECK-NEXT: Address:         0x1C8
-// CHECK-NEXT: Offset:  0x1C8
+// CHECK-NEXT: Address: 0x1E1
+// CHECK-NEXT: Offset: 0x1E1
 // CHECK-NEXT: Size:    4
 // CHECK-NEXT: Link: 0
 // CHECK-NEXT: Info: 0
@@ -46,8 +46,8 @@
 // NOTAIL-NEXT:   SHF_MERGE
 // NOTAIL-NEXT:   SHF_STRINGS
 // NOTAIL-NEXT: ]
-// NOTAIL-NEXT: Address:         0x1C8
-// NOTAIL-NEXT: Offset:  0x1C8
+// NOTAIL-NEXT: Address: 0x1E1
+// NOTAIL-NEXT: Offset: 0x1E1
 // NOTAIL-NEXT: Size:    7
 // NOTAIL-NEXT: Link: 0
 // NOTAIL-NEXT: Info: 0
@@ -64,8 +64,8 @@
 // NOMERGE-NEXT:   SHF_MERGE
 // NOMERGE-NEXT:   SHF_STRINGS
 // NOMERGE-NEXT: ]
-// NOMERGE-NEXT: Address:         0x1C8
-// NOMERGE-NEXT: Offset:  0x1C8
+// NOMERGE-NEXT: Address: 0x1E1
+// NOMERGE-NEXT: Offset: 0x1E1
 // NOMERGE-NEXT: Size:    11
 // NOMERGE-NEXT: Link: 0
 // NOMERGE-NEXT: Info: 0
@@ -82,8 +82,8 @@
 // CHECK-NEXT:   SHF_MERGE
 // CHECK-NEXT:   SHF_STRINGS
 // CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x1CC
-// CHECK-NEXT: Offset: 0x1CC
+// CHECK-NEXT: Address: 0x1E6
+// CHECK-NEXT: Offset: 0x1E6
 // CHECK-NEXT: Size: 4
 // CHECK-NEXT: Link: 0
 // CHECK-NEXT: Info: 0
@@ -95,11 +95,11 @@
 
 
 // CHECK:      Name:    bar
-// CHECK-NEXT: Value:   0x1C9
+// CHECK-NEXT: Value: 0x1E2
 
 // CHECK:      Name:    foo
-// CHECK-NEXT: Value:   0x1C8
+// CHECK-NEXT: Value: 0x1E1
 
 // CHECK:      Name: zed
-// CHECK-NEXT: Value: 0x1CC
+// CHECK-NEXT: Value: 0x1E6
 // CHECK-NEXT: Size: 0
diff --git a/test/ELF/merge-sym.s b/test/ELF/merge-sym.s
index 4a4e982..7329bd4 100644
--- a/test/ELF/merge-sym.s
+++ b/test/ELF/merge-sym.s
@@ -15,7 +15,7 @@
 // CHECK-NEXT:   SHF_ALLOC
 // CHECK-NEXT:   SHF_MERGE
 // CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x1C8
+// CHECK-NEXT: Address: 0x1E4
 
 // CHECK:      Name: foo
-// CHECK-NEXT: Value: 0x1CA
+// CHECK-NEXT: Value: 0x1E6
diff --git a/test/ELF/merge-to-non-alloc.s b/test/ELF/merge-to-non-alloc.s
new file mode 100644
index 0000000..e2894ed
--- /dev/null
+++ b/test/ELF/merge-to-non-alloc.s
@@ -0,0 +1,33 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readobj -s -section-data -t %t.so | FileCheck %s
+
+// CHECK:      Name: .bar
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address:
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 16
+// CHECK-NEXT: Link:
+// CHECK-NEXT: Info:
+// CHECK-NEXT: AddressAlignment:
+// CHECK-NEXT: EntrySize:
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT:   0000: E4010000 00000000 EC010000 00000000  |
+// CHECK-NEXT: )
+
+// CHECK:      Name: foo
+// CHECK-NEXT: Value: 0x1E4
+
+        .section        .foo,"aM",@progbits,4
+        .align  4
+        .global foo
+        .hidden foo
+foo:
+        .long   0x42
+
+        .section .bar
+        .quad foo
+        .quad foo + 8
diff --git a/test/ELF/mips-dynamic.s b/test/ELF/mips-dynamic.s
index 15afb02..820776b 100644
--- a/test/ELF/mips-dynamic.s
+++ b/test/ELF/mips-dynamic.s
@@ -6,7 +6,11 @@
 
 # RUN: ld.lld %t.o %td.so -o %t.exe
 # RUN: llvm-readobj -sections -dynamic-table %t.exe \
-# RUN:   | FileCheck -check-prefix=EXE %s
+# RUN:   | FileCheck -check-prefixes=EXE,NOPIE %s
+
+# RUN: ld.lld -pie %t.o %td.so -o %t.so
+# RUN: llvm-readobj -sections -dyn-symbols -dynamic-table %t.so \
+# RUN:   | FileCheck -check-prefixes=EXE,PIE %s
 
 # RUN: ld.lld %t.o --image-base=0x123000 %td.so -o %t.exe
 # RUN: llvm-readobj -sections -dynamic-table %t.exe \
@@ -44,17 +48,35 @@
 # EXE-NEXT:     Offset:
 # EXE-NEXT:     Size: 8
 # EXE:      ]
-# EXE:      DynamicSection [
-# EXE-NEXT:   Tag        Type                 Name/Value
-# EXE-DAG:    0x00000003 PLTGOT               [[GOTADDR]]
-# EXE-DAG:    0x70000001 MIPS_RLD_VERSION     1
-# EXE-DAG:    0x70000005 MIPS_FLAGS           NOTPOT
-# EXE-DAG:    0x70000006 MIPS_BASE_ADDRESS    0x10000
-# EXE-DAG:    0x7000000A MIPS_LOCAL_GOTNO     2
-# EXE-DAG:    0x70000011 MIPS_SYMTABNO        2
-# EXE-DAG:    0x70000013 MIPS_GOTSYM          0x2
-# EXE-DAG:    0x70000016 MIPS_RLD_MAP         [[RLDMAPADDR]]
-# EXE:      ]
+
+# PIE:      DynamicSection [
+# PIE-NEXT:   Tag        Type                 Name/Value
+# PIE:        0x00000004 HASH                 0x{{[0-9A-F]+}}
+# PIE-NEXT:   0x70000001 MIPS_RLD_VERSION     1
+# PIE-NEXT:   0x70000005 MIPS_FLAGS           NOTPOT
+# PIE-NEXT:   0x70000006 MIPS_BASE_ADDRESS    0x0
+# PIE-NEXT:   0x70000011 MIPS_SYMTABNO        2
+# PIE-NEXT:   0x7000000A MIPS_LOCAL_GOTNO     2
+# PIE-NEXT:   0x70000013 MIPS_GOTSYM          0x2
+# PIE-NEXT:   0x00000003 PLTGOT               [[GOTADDR]]
+# PIE-NEXT:   0x70000035 MIPS_RLD_MAP_REL     0x{{[0-9A-F]+}}
+# PIE-NEXT:   0x00000000 NULL                 0x0
+# PIE-NEXT: ]
+
+# NOPIE:      DynamicSection [
+# NOPIE-NEXT:   Tag        Type                 Name/Value
+# NOPIE:        0x00000004 HASH                 0x{{[0-9A-F]+}}
+# NOPIE-NEXT:   0x70000001 MIPS_RLD_VERSION     1
+# NOPIE-NEXT:   0x70000005 MIPS_FLAGS           NOTPOT
+# NOPIE-NEXT:   0x70000006 MIPS_BASE_ADDRESS    0x10000
+# NOPIE-NEXT:   0x70000011 MIPS_SYMTABNO        2
+# NOPIE-NEXT:   0x7000000A MIPS_LOCAL_GOTNO     2
+# NOPIE-NEXT:   0x70000013 MIPS_GOTSYM          0x2
+# NOPIE-NEXT:   0x00000003 PLTGOT               [[GOTADDR]]
+# NOPIE-NEXT:   0x70000016 MIPS_RLD_MAP         [[RLDMAPADDR]]
+# NOPIE-NEXT:   0x70000035 MIPS_RLD_MAP_REL     0x{{[0-9A-F]+}}
+# NOPIE-NEXT:   0x00000000 NULL                 0x0
+# NOPIE-NEXT: ]
 
 # IMAGE_BASE: 0x70000006 MIPS_BASE_ADDRESS    0x123000
 
diff --git a/test/ELF/mips-got-string.s b/test/ELF/mips-got-string.s
index 598865c..aec80dd 100644
--- a/test/ELF/mips-got-string.s
+++ b/test/ELF/mips-got-string.s
@@ -8,7 +8,7 @@
 
 # CHECK:      Symbol {
 # CHECK:        Name: $.str
-# CHECK-NEXT:   Value: 0xF4
+# CHECK-NEXT:   Value: 0x105
 # CHECK:      }
 
 # CHECK:      Local entries [
diff --git a/test/ELF/mips-gp-ext.s b/test/ELF/mips-gp-ext.s
index 2fd21b7..eb9788c 100644
--- a/test/ELF/mips-gp-ext.s
+++ b/test/ELF/mips-gp-ext.s
@@ -27,42 +27,44 @@
 # REQUIRES: mips
 
 # REL:      Contents of section .text:
-# REL-NEXT:  0000 3c080000 2108010c 8f82fffc
+# REL-NEXT:  0030 3c080000 2108010c 8f82ffcc
 #                 ^-- %hi(_gp_disp)
 #                          ^-- %lo(_gp_disp)
-#                                   ^-- 8 - (0x10c - 0x100)
+#                                   ^-- 8 - (0x13c - 0x100)
 #                                       G - (GP - .got)
 
 # REL:      Contents of section .reginfo:
-# REL-NEXT:  0028 10000104 00000000 00000000 00000000
-# REL-NEXT:  0038 00000000 0000010c
+# REL-NEXT:  0058 10000104 00000000 00000000 00000000
+# REL-NEXT:  0068 00000000 0000013c
 #                          ^-- _gp
 
 # REL:      Contents of section .data:
 # REL-NEXT:  00f0 fffffef4
-#                 ^-- 0-0x10c
+#                 ^-- 0x30-0x13c
+#                     foo - GP
 
-# REL: 00000000         .text           00000000 foo
+# REL: 00000030         .text           00000000 foo
 # REL: 00000000         *ABS*           00000000 .hidden _gp_disp
-# REL: 0000010c         *ABS*           00000000 .hidden _gp
+# REL: 0000013c         *ABS*           00000000 .hidden _gp
 
 # ABS:      Contents of section .text:
-# ABS-NEXT:  0000 3c080000 21080200 8f82ff08
+# ABS-NEXT:  0030 3c080000 210801d0 8f82ff08
 #                 ^-- %hi(_gp_disp)
 #                          ^-- %lo(_gp_disp)
 #                                   ^-- 8 - (0x200 - 0x100)
 #                                       G - (GP - .got)
 
 # ABS:      Contents of section .reginfo:
-# ABS-NEXT:  0028 10000104 00000000 00000000 00000000
-# ABS-NEXT:  0038 00000000 00000200
+# ABS-NEXT:  0058 10000104 00000000 00000000 00000000
+# ABS-NEXT:  0068 00000000 00000200
 #                          ^-- _gp
 
 # ABS:      Contents of section .data:
-# ABS-NEXT:  00f0 fffffe00
-#                 ^-- 0-0x200
+# ABS-NEXT:  00f0 fffffe30
+#                 ^-- 0x30-0x200
+#                     foo - GP
 
-# ABS: 00000000         .text           00000000 foo
+# ABS: 00000030         .text           00000000 foo
 # ABS: 00000000         *ABS*           00000000 .hidden _gp_disp
 # ABS: 00000200         *ABS*           00000000 .hidden _gp
 
diff --git a/test/ELF/mips-gp-lowest.s b/test/ELF/mips-gp-lowest.s
index 32a3e85..ecc5f7b 100644
--- a/test/ELF/mips-gp-lowest.s
+++ b/test/ELF/mips-gp-lowest.s
@@ -26,7 +26,7 @@
 # CHECK-NEXT:     SHF_MIPS_GPREL
 # CHECK-NEXT:     SHF_WRITE
 # CHECK-NEXT:   ]
-# CHECK-NEXT:   Address: 0xE0
+# CHECK-NEXT:   Address: 0xF0
 # CHECK:      }
 # CHECK:      Section {
 # CHECK:        Name: .got
@@ -36,9 +36,9 @@
 # CHECK-NEXT:     SHF_MIPS_GPREL
 # CHECK-NEXT:     SHF_WRITE
 # CHECK-NEXT:   ]
-# CHECK-NEXT:   Address: 0xF0
+# CHECK-NEXT:   Address: 0x100
 # CHECK:      }
 
 # CHECK:      Name: _gp (5)
-# CHECK-NEXT: Value: 0x80D0
-#                    ^-- 0xE0 + 0x7ff0
+# CHECK-NEXT: Value: 0x80E0
+#                    ^-- 0xF0 + 0x7ff0
diff --git a/test/ELF/mips-gprel32-relocs-gp0.s b/test/ELF/mips-gprel32-relocs-gp0.s
index 507224e..f27caa3 100644
--- a/test/ELF/mips-gprel32-relocs-gp0.s
+++ b/test/ELF/mips-gprel32-relocs-gp0.s
@@ -1,8 +1,4 @@
 # Check that relocatable object produced by LLD has zero gp0 value.
-# Also check an error message if input object file has non-zero gp0 value
-# and the linker generates a relocatable object.
-# mips-gp0-non-zero.o is a relocatable object produced from the asm code
-# below and linked by GNU bfd linker.
 
 # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
 # RUN: ld.lld -r -o %t-rel.o %t.o
@@ -12,9 +8,6 @@
 # RUN: llvm-readobj -mips-reginfo %t.so | FileCheck --check-prefix=DSO %s
 # RUN: llvm-objdump -s -t %t.so | FileCheck --check-prefix=DUMP %s
 
-# RUN: not ld.lld -r -o %t-rel.o %S/Inputs/mips-gp0-non-zero.o 2>&1 \
-# RUN:   | FileCheck --check-prefix=ERR %s
-
 # REQUIRES: mips
 
 # REL: GP: 0x0
@@ -31,8 +24,6 @@
 # DUMP: 00010004         .text          00000000 foo
 # DUMP: 00027ff0         .got           00000000 .hidden _gp
 
-# ERR: error: {{.*}}mips-gp0-non-zero.o: unsupported non-zero ri_gp_value
-
   .text
   .global  __start
 __start:
diff --git a/test/ELF/mips-micro-plt.s b/test/ELF/mips-micro-plt.s
index 5671dc4..16f3bd4 100644
--- a/test/ELF/mips-micro-plt.s
+++ b/test/ELF/mips-micro-plt.s
@@ -7,13 +7,14 @@
 # RUN:         -mattr=micromips %s -o %t-exe.o
 # RUN: ld.lld %t-exe.o %t.so -o %t.exe
 # RUN: llvm-readobj -t -dt -mips-plt-got %t.exe | FileCheck %s
+# RUN: llvm-objdump -d -mattr=micromips %t.exe | FileCheck --check-prefix=ASM %s
 
 # REQUIRES: mips
 
 # CHECK:      Symbols [
 # CHECK:        Symbol {
 # CHECK:          Name: foo
-# CHECK-NEXT:     Value: 0x20008
+# CHECK-NEXT:     Value: 0x20010
 # CHECK-NEXT:     Size:
 # CHECK-NEXT:     Binding: Local
 # CHECK-NEXT:     Type: None
@@ -36,22 +37,28 @@
 # CHECK-NEXT:   }
 # CHECK:        Symbol {
 # CHECK:          Name: foo0
-# CHECK-NEXT:     Value: 0x0
+# CHECK-NEXT:     Value: 0x20040
 # CHECK-NEXT:     Size:
 # CHECK-NEXT:     Binding: Global
 # CHECK-NEXT:     Type: Function
-# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Other [
+# CHECK-NEXT:       STO_MIPS_MICROMIPS
+# CHECK-NEXT:       STO_MIPS_PLT
+# CHECK-NEXT:     ]
 # CHECK-NEXT:     Section: Undefined
 # CHECK-NEXT:   }
 # CHECK-NEXT: ]
 # CHECK:      DynamicSymbols [
 # CHECK:        Symbol {
 # CHECK:          Name: foo0
-# CHECK-NEXT:     Value: 0x0
+# CHECK-NEXT:     Value: 0x20041
 # CHECK-NEXT:     Size:
 # CHECK-NEXT:     Binding: Global
 # CHECK-NEXT:     Type: Function
-# CHECK-NEXT:     Other: 0
+# CHECK-NEXT:     Other [
+# CHECK-NEXT:       STO_MIPS_MICROMIPS
+# CHECK-NEXT:       STO_MIPS_PLT
+# CHECK-NEXT:     ]
 # CHECK-NEXT:     Section: Undefined
 # CHECK-NEXT:   }
 # CHECK-NEXT: ]
@@ -61,7 +68,7 @@
 # CHECK-NEXT:     Entry {
 # CHECK-NEXT:       Address:
 # CHECK-NEXT:       Access:
-# CHECK-NEXT:       Initial: 0x20009
+# CHECK-NEXT:       Initial: 0x20011
 # CHECK-NEXT:     }
 # CHECK:        ]
 # CHECK:      }
@@ -70,8 +77,8 @@
 # CHECK:        Entries [
 # CHECK-NEXT:     Entry {
 # CHECK-NEXT:       Address:
-# CHECK-NEXT:       Initial: 0x20011
-# CHECK-NEXT:       Value: 0x0
+# CHECK-NEXT:       Initial: 0x20021
+# CHECK-NEXT:       Value: 0x20041
 # CHECK-NEXT:       Type: Function
 # CHECK-NEXT:       Section: Undefined
 # CHECK-NEXT:       Name: foo0@
@@ -79,6 +86,15 @@
 # CHECK-NEXT:   ]
 # CHECK-NEXT: }
 
+# ASM:      __start:
+# ASM-NEXT:    20000:       fd 1c 80 18     lw      $8, -32744($gp)
+# ASM-NEXT:    20004:       11 08 00 10     addi    $8, $8, 16
+# ASM-NEXT:    20008:       41 a8 00 02     lui     $8, 2
+# ASM-NEXT:    2000c:       11 08 00 40     addi    $8, $8, 64
+#
+# ASM:      foo:
+# ASM-NEXT:    20010:       f4 01 00 20     jal     131136
+
   .text
   .set micromips
   .global foo
@@ -87,5 +103,7 @@
 __start:
   lw    $t0,%got(foo)($gp)
   addi  $t0,$t0,%lo(foo)
+  lui   $t0,%hi(foo0)
+  addi  $t0,$t0,%lo(foo0)
 foo:
   jal   foo0
diff --git a/test/ELF/mips-micro-thunks.s b/test/ELF/mips-micro-thunks.s
index 18a8fc3..c8695cc 100644
--- a/test/ELF/mips-micro-thunks.s
+++ b/test/ELF/mips-micro-thunks.s
@@ -1,44 +1,78 @@
 # Check microMIPS thunk generation.
 
 # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
-# RUN:         -mattr=micromips %s -o %t-eb.o
+# RUN:         -mcpu=mips32r2 -mattr=micromips %s -o %t-eb.o
 # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
-# RUN:         -position-independent -mattr=micromips \
+# RUN:         -position-independent -mcpu=mips32r2 -mattr=micromips \
 # RUN:         %S/Inputs/mips-micro.s -o %t-eb-pic.o
 # RUN: ld.lld -o %t-eb.exe %t-eb.o %t-eb-pic.o
 # RUN: llvm-objdump -d -mattr=+micromips %t-eb.exe \
-# RUN:   | FileCheck --check-prefix=EB %s
+# RUN:   | FileCheck --check-prefix=EB-R2 %s
 
 # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \
-# RUN:         -mattr=micromips %s -o %t-el.o
+# RUN:         -mcpu=mips32r2 -mattr=micromips %s -o %t-el.o
 # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \
-# RUN:         -position-independent -mattr=micromips \
+# RUN:         -position-independent -mcpu=mips32r2 -mattr=micromips \
 # RUN:         %S/Inputs/mips-micro.s -o %t-el-pic.o
 # RUN: ld.lld -o %t-el.exe %t-el.o %t-el-pic.o
 # RUN: llvm-objdump -d -mattr=+micromips %t-el.exe \
-# RUN:   | FileCheck --check-prefix=EL %s
+# RUN:   | FileCheck --check-prefix=EL-R2 %s
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
+# RUN:         -mcpu=mips32r6 -mattr=micromips %s -o %t-eb-r6.o
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
+# RUN:         -position-independent -mcpu=mips32r6 -mattr=micromips \
+# RUN:         %S/Inputs/mips-micro.s -o %t-eb-pic-r6.o
+# RUN: ld.lld -o %t-eb-r6.exe %t-eb-r6.o %t-eb-pic-r6.o
+# RUN: llvm-objdump -d -mattr=+micromips %t-eb-r6.exe \
+# RUN:   | FileCheck --check-prefix=EB-R6 %s
+
+# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \
+# RUN:         -mcpu=mips32r6 -mattr=micromips %s -o %t-el-r6.o
+# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \
+# RUN:         -position-independent -mcpu=mips32r6 -mattr=micromips \
+# RUN:         %S/Inputs/mips-micro.s -o %t-el-pic-r6.o
+# RUN: ld.lld -o %t-el-r6.exe %t-el-r6.o %t-el-pic-r6.o
+# RUN: llvm-objdump -d -mattr=+micromips %t-el-r6.exe \
+# RUN:   | FileCheck --check-prefix=EL-R6 %s
 
 # REQUIRES: mips
 
-# EB: __start:
-# EB-NEXT:    20000:       f4 01 00 04     jal     131080 <__microLA25Thunk_foo>
-# EB-NEXT:    20004:       00 00 00 00     nop
+# EB-R2: __start:
+# EB-R2-NEXT:    20000:       f4 01 00 04  jal   131080 <__microLA25Thunk_foo>
+# EB-R2-NEXT:    20004:       00 00 00 00  nop
 
-# EB: __microLA25Thunk_foo:
-# EB-NEXT:    20008:       41 b9 00 02     lui     $25, 2
-# EB-NEXT:    2000c:       d4 01 00 10     j       131104
-# EB-NEXT:    20010:       33 39 00 21     addiu   $25, $25, 33
-# EB-NEXT:    20014:       0c 00           nop
+# EB-R2: __microLA25Thunk_foo:
+# EB-R2-NEXT:    20008:       41 b9 00 02  lui   $25, 2
+# EB-R2-NEXT:    2000c:       d4 01 00 10  j     131104
+# EB-R2-NEXT:    20010:       33 39 00 21  addiu $25, $25, 33
+# EB-R2-NEXT:    20014:       0c 00        nop
 
-# EL: __start:
-# EL-NEXT:    20000:       01 f4 04 00     jal     131080 <__microLA25Thunk_foo>
-# EL-NEXT:    20004:       00 00 00 00     nop
+# EL-R2: __start:
+# EL-R2-NEXT:    20000:       01 f4 04 00  jal   131080 <__microLA25Thunk_foo>
+# EL-R2-NEXT:    20004:       00 00 00 00  nop
 
-# EL: __microLA25Thunk_foo:
-# EL-NEXT:    20008:       b9 41 02 00     lui     $25, 2
-# EL-NEXT:    2000c:       01 d4 10 00     j       131104
-# EL-NEXT:    20010:       39 33 21 00     addiu   $25, $25, 33
-# EL-NEXT:    20014:       00 0c           nop
+# EL-R2: __microLA25Thunk_foo:
+# EL-R2-NEXT:    20008:       b9 41 02 00  lui   $25, 2
+# EL-R2-NEXT:    2000c:       01 d4 10 00  j     131104
+# EL-R2-NEXT:    20010:       39 33 21 00  addiu $25, $25, 33
+# EL-R2-NEXT:    20014:       00 0c        nop
+
+# EB-R6: __start:
+# EB-R6-NEXT:    20000:       b4 00 00 00  balc  0 <__start>
+
+# EB-R6: __microLA25Thunk_foo:
+# EB-R6-NEXT:    20004:       13 20 00 02  lui   $25, 2
+# EB-R6-NEXT:    20008:       33 39 00 11  addiu $25, $25, 17
+# EB-R6-NEXT:    2000c:       94 00 00 00  bc    0 <__microLA25Thunk_foo+0x8>
+
+# EL-R6: __start:
+# EL-R6-NEXT:    20000:       00 b4 00 00  balc  0 <__start>
+
+# EL-R6: __microLA25Thunk_foo:
+# EL-R6-NEXT:    20004:       20 13 02 00  lui   $25, 2
+# EL-R6-NEXT:    20008:       39 33 11 00  addiu $25, $25, 17
+# EL-R6-NEXT:    2000c:       00 94 00 00  bc    0 <__microLA25Thunk_foo+0x8>
 
   .text
   .set micromips
diff --git a/test/ELF/mips-micro64-relocs.s b/test/ELF/mips-micro64-relocs.s
new file mode 100644
index 0000000..b440c7a
--- /dev/null
+++ b/test/ELF/mips-micro64-relocs.s
@@ -0,0 +1,22 @@
+# REQUIRES: mips
+
+# Check handling of some microMIPS relocations in 64-bit mode.
+
+# RUN: llvm-mc -filetype=obj -triple=mips64el-unknown-linux \
+# RUN:         -mattr=micromips %s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=mips64el-unknown-linux \
+# RUN:         -mattr=micromips %S/Inputs/mips-dynamic.s -o %t2.o
+# RUN: ld.lld %t1.o %t2.o -o %t.exe
+# RUN: llvm-objdump -d %t.exe | FileCheck %s
+
+  .global  __start
+__start:
+  lui     $7,  %highest(_foo+0x300047FFF7FF8)
+  lui     $7,  %higher (_foo+0x300047FFF7FF8)
+  lui     $gp, %hi(%neg(%gp_rel(__start)))
+  lui     $gp, %lo(%neg(%gp_rel(__start)))
+
+# CHECK:      20000:  a7 41 03 00  lui $7, 3
+# CHECK-NEXT: 20004:  a7 41 05 00  lui $7, 5
+# CHECK-NEXT: 20008:  bc 41 02 00  lui $gp, 2
+# CHECK-NEXT: 2000c:  bc 41 00 80  lui $gp, 32768
diff --git a/test/ELF/mips-micror6-relocs.s b/test/ELF/mips-micror6-relocs.s
new file mode 100644
index 0000000..ca2c1c0
--- /dev/null
+++ b/test/ELF/mips-micror6-relocs.s
@@ -0,0 +1,38 @@
+# REQUIRES: mips
+
+# Check handling of microMIPS R6 relocations.
+
+# RUN: llvm-mc -filetype=obj -triple=mips -mcpu=mips32r6 \
+# RUN:         %S/Inputs/mips-micro.s -o %t1eb.o
+# RUN: llvm-mc -filetype=obj -triple=mips -mcpu=mips32r6 %s -o %t2eb.o
+# RUN: ld.lld -o %teb.exe %t1eb.o %t2eb.o
+# RUN: llvm-objdump -d -t -mattr=micromips %teb.exe \
+# RUN:   | FileCheck --check-prefixes=EB,SYM %s
+
+# RUN: llvm-mc -filetype=obj -triple=mipsel -mcpu=mips32r6 \
+# RUN:         %S/Inputs/mips-micro.s -o %t1el.o
+# RUN: llvm-mc -filetype=obj -triple=mipsel -mcpu=mips32r6 %s -o %t2el.o
+# RUN: ld.lld -o %tel.exe %t1el.o %t2el.o
+# RUN: llvm-objdump -d -t -mattr=micromips %tel.exe \
+# RUN:   | FileCheck --check-prefixes=EL,SYM %s
+
+# EB:      __start:
+# EB-NEXT:    20010:  78 47 ff fd  lapc   $2, -12
+# EB-NEXT:    20014:  80 7f ff f6  beqzc  $3, -36
+# EB-NEXT:    20018:  b7 ff ff f4  balc   -24 <foo>
+
+# EL:      __start:
+# EL-NEXT:    20010:  47 78 fd ff  lapc   $2, -12
+# EL-NEXT:    20014:  7f 80 f6 ff  beqzc  $3, -36
+# EL-NEXT:    20018:  ff b7 f4 ff  balc   -24 <foo>
+
+# SYM: 00020000 g F     .text           00000000 foo
+# SYM: 00020010         .text           00000000 __start
+
+  .text
+  .set micromips
+  .global __start
+__start:
+  addiupc $2, foo+4   # R_MICROMIPS_PC19_S2
+  beqzc   $3, foo+4   # R_MICROMIPS_PC21_S1
+  balc    foo+4       # R_MICROMIPS_PC26_S1
diff --git a/test/ELF/mips-non-zero-gp0.s b/test/ELF/mips-non-zero-gp0.s
new file mode 100644
index 0000000..babfde9
--- /dev/null
+++ b/test/ELF/mips-non-zero-gp0.s
@@ -0,0 +1,66 @@
+# REQUIRES: mips
+
+# Check addend adjustment in case of generating a relocatable object
+# if some input files have non-zero GP0 value.
+
+# We have to use GNU as and ld.bfd 2.28 to generate relocatable object
+# files with non-zero GP0 value using the following command lines:
+#
+# as -mips32 -o test.o \
+#   && ld.bfd -m elf32btsmip -r test.o -o mips-gp0-non-zero.o
+# as -mips64 -mmicromips -o test.o \
+#   && ld.bfd -m elf64btsmip -r test.o -o mips-micro-gp0-non-zero.o
+# as -mips64 -o test.o \
+#   && ld.bfd -m elf64btsmip -r test.o -o mips-n64-gp0-non-zero.o
+
+# Source code for mips-gp0-non-zero.o:
+#   .text
+#   .global  __start
+# __start:
+#   lw      $t0,%call16(__start)($gp)
+# foo:
+#   nop
+# bar:
+#   nop
+#
+#   .section .rodata, "a"
+# v:
+#   .gpword foo
+#   .gpword bar
+
+# Source code for mips-n64-gp0-non-zero.o and mips-micro-gp0-non-zero.o:
+#   .text
+#   .global  __start
+# __start:
+# foo:
+#   lui     $gp,%hi(%neg(%gp_rel(foo)))
+
+# RUN: ld.lld -r -o %t-32.r %S/Inputs/mips-gp0-non-zero.o
+# RUN: llvm-readobj -mips-reginfo %t-32.r | FileCheck --check-prefix=GPVAL %s
+# RUN: llvm-objdump -s %t-32.r | FileCheck --check-prefix=ADDEND32 %s
+
+# RUN: ld.lld -r -o %t-64.r %S/Inputs/mips-n64-gp0-non-zero.o
+# RUN: llvm-readobj -mips-options %t-64.r | FileCheck --check-prefix=GPVAL %s
+# RUN: llvm-readobj -r %S/Inputs/mips-n64-gp0-non-zero.o %t-64.r \
+# RUN:   | FileCheck --check-prefix=ADDEND64 %s
+
+# RUN: ld.lld -r -o %t-micro.r %S/Inputs/mips-micro-gp0-non-zero.o
+# RUN: llvm-readobj -mips-options %t-micro.r | FileCheck --check-prefix=GPVAL %s
+# RUN: llvm-readobj -r %S/Inputs/mips-micro-gp0-non-zero.o %t-micro.r \
+# RUN:   | FileCheck --check-prefix=ADDENDMM %s
+
+# GPVAL: GP: 0x0
+
+# ADDEND32:      Contents of section .rodata:
+# ADDEND32-NEXT:  0000 00007ff4 00007ff8
+#                      ^ 4+GP0  ^ 8+GP0
+
+# ADDEND64: File: {{.*}}{{/|\\}}mips-n64-gp0-non-zero.o
+# ADDEND64: .text 0xFFFFFFFFFFFF8011
+# ADDEND64: File: {{.*}}{{/|\\}}mips-non-zero-gp0.s.tmp-64.r
+# ADDEND64: .text 0x0
+
+# ADDENDMM: File: {{.*}}{{/|\\}}mips-micro-gp0-non-zero.o
+# ADDENDMM: .text 0xFFFFFFFFFFFF8012
+# ADDENDMM: File: {{.*}}{{/|\\}}mips-non-zero-gp0.s.tmp-micro.r
+# ADDENDMM: .text 0x1
diff --git a/test/ELF/mips-plt-n32.s b/test/ELF/mips-plt-n32.s
new file mode 100644
index 0000000..06699fc
--- /dev/null
+++ b/test/ELF/mips-plt-n32.s
@@ -0,0 +1,43 @@
+# REQUIRES: mips
+
+# Check PLT entries generation in case of using N32 ABI.
+
+# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \
+# RUN:         -target-abi n32 %s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \
+# RUN:         -target-abi n32 %S/Inputs/mips-dynamic.s -o %t2.o
+# RUN: ld.lld %t2.o -shared -o %t.so
+# RUN: ld.lld %t1.o %t.so -o %t.exe
+# RUN: llvm-objdump -d %t.exe | FileCheck %s --check-prefixes=DEFAULT,CHECK
+# RUN: ld.lld %t2.o -shared -o %t.so -z hazardplt
+# RUN: ld.lld %t1.o %t.so -o %t.exe -z hazardplt
+# RUN: llvm-objdump -d %t.exe | FileCheck %s --check-prefixes=HAZARDPLT,CHECK
+
+# CHECK:      Disassembly of section .text:
+# CHECK-NEXT: __start:
+# CHECK-NEXT:   20000:       0c 00 80 0c     jal     131120
+#                                                    ^-- 0x20030 gotplt[foo0]
+# CHECK-NEXT:   20004:       00 00 00 00     nop
+#
+# CHECK-NEXT: Disassembly of section .plt:
+# CHECK-NEXT: .plt:
+# CHECK-NEXT:   20010:       3c 0e 00 03     lui     $14, 3
+# CHECK-NEXT:   20014:       8d d9 00 04     lw      $25, 4($14)
+# CHECK-NEXT:   20018:       25 ce 00 04     addiu   $14, $14, 4
+# CHECK-NEXT:   2001c:       03 0e c0 23     subu    $24, $24, $14
+# CHECK-NEXT:   20020:       03 e0 78 25     move    $15, $ra
+# CHECK-NEXT:   20024:       00 18 c0 82     srl     $24, $24, 2
+# DEFAULT:      20028:       03 20 f8 09     jalr    $25
+# HAZARDPLT:    20028:       03 20 fc 09     jalr.hb $25
+# CHECK-NEXT:   2002c:       27 18 ff fe     addiu   $24, $24, -2
+
+# CHECK-NEXT:   20030:       3c 0f 00 03     lui     $15, 3
+# CHECK-NEXT:   20034:       8d f9 00 0c     lw      $25, 12($15)
+# DEFAULT:      20038:       03 20 00 08     jr      $25
+# HAZARDPLT:    20038:       03 20 04 08     jr.hb   $25
+# CHECK-NEXT:   2003c:       25 f8 00 0c     addiu   $24, $15, 12
+
+  .text
+  .global __start
+__start:
+  jal foo0        # R_MIPS_26 against 'foo0' from DSO
diff --git a/test/ELF/no-line-parser-errors-if-empty-section.s b/test/ELF/no-line-parser-errors-if-empty-section.s
new file mode 100644
index 0000000..56b255e
--- /dev/null
+++ b/test/ELF/no-line-parser-errors-if-empty-section.s
@@ -0,0 +1,21 @@
+# REQUIRES: x86
+
+# LLD uses the debug data to get information for error messages, if possible.
+# However, if the debug line section is empty, we should not attempt to parse
+# it, as that would result in errors from the parser.
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: not ld.lld %t.o -o %t.elf 2>&1 | FileCheck %s
+
+# CHECK-NOT: warning:
+# CHECK-NOT: error:
+# CHECK: error: undefined symbol: undefined
+# CHECK-NEXT: {{.*}}.o:(.text+0x1)
+# CHECK-NOT: warning:
+# CHECK-NOT: error:
+
+.globl _start
+_start:
+    callq undefined
+
+.section .debug_line,"",@progbits
diff --git a/test/ELF/no-line-parser-errors-if-no-section.s b/test/ELF/no-line-parser-errors-if-no-section.s
new file mode 100644
index 0000000..9210d85
--- /dev/null
+++ b/test/ELF/no-line-parser-errors-if-no-section.s
@@ -0,0 +1,19 @@
+# REQUIRES: x86
+
+# LLD uses the debug data to get information for error messages, if possible.
+# However, if there is no debug line section, we should not attempt to parse
+# it, as that would result in errors from the parser.
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: not ld.lld %t.o -o %t.elf 2>&1 | FileCheck %s
+
+# CHECK-NOT: warning:
+# CHECK-NOT: error:
+# CHECK: error: undefined symbol: undefined
+# CHECK-NEXT: {{.*}}.o:(.text+0x1)
+# CHECK-NOT: warning:
+# CHECK-NOT: error:
+
+.globl _start
+_start:
+    callq undefined
diff --git a/test/ELF/non-alloc-link-order-gc.s b/test/ELF/non-alloc-link-order-gc.s
new file mode 100644
index 0000000..8147c45
--- /dev/null
+++ b/test/ELF/non-alloc-link-order-gc.s
@@ -0,0 +1,34 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t1 --gc-sections
+# RUN: llvm-objdump -section-headers -D %t1 | FileCheck %s
+
+## Check that we are able to GC non-allocatable metadata sections without crash.
+
+# CHECK:      Disassembly of section .stack_sizes:
+# CHECK-NEXT:   .stack_sizes:
+# CHECK-NEXT:    01
+
+# CHECK:      Name          Size
+# CHECK:      .stack_sizes  00000001
+
+.section .text.live,"ax",@progbits
+.globl live
+live:
+ nop
+
+.section .stack_sizes,"o",@progbits,.text.live,unique,0
+.byte 1
+
+.section .text.dead,"ax",@progbits
+.globl dead
+dead:
+ nop
+
+.section .stack_sizes,"o",@progbits,.text.dead,unique,1
+.byte 2
+
+.section .text.main,"ax",@progbits
+.globl _start
+_start:
+  callq live@PLT
diff --git a/test/ELF/note-noalloc.s b/test/ELF/note-noalloc.s
new file mode 100644
index 0000000..ddbde3e
--- /dev/null
+++ b/test/ELF/note-noalloc.s
@@ -0,0 +1,38 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld %t.o -o %t -shared
+// RUN: llvm-readobj -program-headers -sections %t | FileCheck %s
+
+// PR37361: A note without SHF_ALLOC should not be included into a PT_NOTE program header.
+
+// CHECK:      Section {
+// CHECK:        Index:
+// CHECK:        Name: .note.a
+// CHECK-NEXT:   Type: SHT_NOTE
+// CHECK-NEXT:   Flags [
+// CHECK-NEXT:     SHF_ALLOC
+// CHECK-NEXT:   ]
+// CHECK-NEXT:   Address: 0x[[ADDR:.*]]
+
+// Check we still emit the non-alloc SHT_NOTE section and keep its type.
+
+// CHECK:        Name: .note.b
+// CHECK-NEXT:   Type: SHT_NOTE
+// CHECK-NEXT:   Flags [
+// CHECK-NEXT:   ]
+
+// CHECK:      ProgramHeader {
+// CHECK:        Type: PT_NOTE
+// CHECK-NEXT:   Offset:
+// CHECK-NEXT:   VirtualAddress: 0x[[ADDR]]
+// CHECK-NEXT:   PhysicalAddress: 0x24C
+// CHECK-NEXT:   FileSize: 16
+// CHECK-NEXT:   MemSize: 16
+// CHECK-NOT:  PT_NOTE
+
+.section        .note.a,"a",@note
+.quad 1
+.quad 2
+
+.section        .note.b,"",@note
+.quad 3
diff --git a/test/ELF/note-noalloc2.s b/test/ELF/note-noalloc2.s
new file mode 100644
index 0000000..3705799
--- /dev/null
+++ b/test/ELF/note-noalloc2.s
@@ -0,0 +1,11 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t
+# RUN: llvm-readobj -program-headers %t | FileCheck %s
+
+## Check we do not create a PT_NOTE segment for non-allocatable note section.
+
+# CHECK-NOT:  PT_NOTE
+
+.section  .note,"",@note
+.quad 0
diff --git a/test/ELF/ppc64-addr16-error.s b/test/ELF/ppc64-addr16-error.s
index f16ca69..d258089 100644
--- a/test/ELF/ppc64-addr16-error.s
+++ b/test/ELF/ppc64-addr16-error.s
@@ -1,7 +1,12 @@
+// REQUIRES: ppc
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-addr16-error.s -o %t2
+// RUN: not ld.lld -shared %t %t2 -o %t3 2>&1 | FileCheck %s
+
 // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
 // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-addr16-error.s -o %t2
 // RUN: not ld.lld -shared %t %t2 -o %t3 2>&1 | FileCheck %s
-// REQUIRES: ppc
 
 .short sym+65539
 
diff --git a/test/ELF/ppc64-dynamic-relocations.s b/test/ELF/ppc64-dynamic-relocations.s
new file mode 100644
index 0000000..2d9dfc6
--- /dev/null
+++ b/test/ELF/ppc64-dynamic-relocations.s
@@ -0,0 +1,50 @@
+// REQUIRES: ppc
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: ld.lld %t.o %t2.so -o %t
+// RUN: llvm-readobj -dyn-relocations %t | FileCheck %s
+// RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=DIS %s
+// RUN: llvm-readelf -dynamic-table %t | FileCheck --check-prefix=DT %s
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: ld.lld %t.o %t2.so -o %t
+// RUN: llvm-readobj -dyn-relocations %t | FileCheck %s
+// RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=DIS %s
+// RUN: llvm-readelf -dynamic-table %t | FileCheck --check-prefix=DT %s
+
+
+// The dynamic relocation for foo should point to 16 bytes past the start of
+// the .plt section.
+// CHECK: Dynamic Relocations {
+// CHECK-NEXT:    0x10030010 R_PPC64_JMP_SLOT foo 0x0
+
+// 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:     .plt       00000018  0000000010030000 BSS
+
+// DT_PLTGOT should point to the start of the .plt section.
+// DT: 0x0000000000000003 PLTGOT               0x10030000
+
+    .text
+    .abiversion 2
+    .globl  _start
+    .p2align        4
+    .type   _start,@function
+_start:
+.Lfunc_begin0:
+.Lfunc_gep0:
+  addis 2, 12, .TOC.-.Lfunc_gep0@ha
+  addi 2, 2, .TOC.-.Lfunc_gep0@l
+.Lfunc_lep0:
+  .localentry     _start, .Lfunc_lep0-.Lfunc_gep0
+  bl foo
+  nop
+  li 0, 1
+  sc
+  .size _start, .-.Lfunc_begin0
diff --git a/test/ELF/ppc64-error-toc-restore.s b/test/ELF/ppc64-error-toc-restore.s
new file mode 100644
index 0000000..19153b7
--- /dev/null
+++ b/test/ELF/ppc64-error-toc-restore.s
@@ -0,0 +1,20 @@
+// REQUIRES: ppc
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s
+
+# Calling external function bar needs a nop
+// CHECK: call lacks nop, can't restore toc
+    .text
+    .abiversion 2
+
+.global _start
+_start:
+  bl foo
diff --git a/test/ELF/ppc64-error-toc-tail-call.s b/test/ELF/ppc64-error-toc-tail-call.s
new file mode 100644
index 0000000..da8fea2
--- /dev/null
+++ b/test/ELF/ppc64-error-toc-tail-call.s
@@ -0,0 +1,20 @@
+// REQUIRES: ppc
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s
+
+# A tail call to an external function without a nop should issue an error.
+// CHECK: call lacks nop, can't restore toc
+    .text
+    .abiversion 2
+
+.global _start
+_start:
+  b foo
diff --git a/test/ELF/ppc64-func-entry-points.s b/test/ELF/ppc64-func-entry-points.s
new file mode 100644
index 0000000..640c94f
--- /dev/null
+++ b/test/ELF/ppc64-func-entry-points.s
@@ -0,0 +1,80 @@
+// REQUIRES: ppc
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-func-global-entry.s -o %t2.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-func-local-entry.s -o %t3.o
+// RUN: ld.lld -dynamic-linker /lib64/ld64.so.2 %t.o %t2.o %t3.o -o %t
+// RUN: llvm-objdump -d %t | FileCheck %s
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-func-global-entry.s -o %t2.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-func-local-entry.s -o %t3.o
+// RUN: ld.lld -dynamic-linker /lib64/ld64.so.2 %t.o %t2.o %t3.o -o %t
+// RUN: llvm-objdump -d %t | FileCheck %s
+
+	.text
+	.abiversion 2
+	.globl	_start                    # -- Begin function _start
+	.p2align	4
+	.type	_start,@function
+_start:                                   # @_start
+.Lfunc_begin0:
+.Lfunc_gep0:
+	addis 2, 12, .TOC.-.Lfunc_gep0@ha
+	addi 2, 2, .TOC.-.Lfunc_gep0@l
+.Lfunc_lep0:
+	.localentry	_start, .Lfunc_lep0-.Lfunc_gep0
+# %bb.0:                                # %entry
+	mflr 0
+	std 0, 16(1)
+	stdu 1, -48(1)
+	li 3, 1
+	li 4, 1
+	std 30, 32(1)                   # 8-byte Folded Spill
+	bl foo_external_same
+	nop
+	mr 30, 3
+	li 3, 2
+	li 4, 2
+	bl foo_external_diff
+	nop
+	addis 4, 2, .LC0@toc@ha
+	add 3, 3, 30
+	ld 30, 32(1)                    # 8-byte Folded Reload
+	ld 4, .LC0@toc@l(4)
+	lwz 4, 0(4)
+	add 3, 3, 4
+	extsw 3, 3
+	addi 1, 1, 48
+	ld 0, 16(1)
+	li 0, 1
+	sc
+	.long	0
+	.quad	0
+.Lfunc_end0:
+	.size	_start, .Lfunc_end0-.Lfunc_begin0
+                                        # -- End function
+	.section	.toc,"aw",@progbits
+.LC0:
+	.tc glob[TC],glob
+	.type	glob,@object            # @glob
+	.data
+	.globl	glob
+	.p2align	2
+glob:
+	.long	10                      # 0xa
+	.size	glob, 4
+
+# Check that foo_external_diff has a global entry point and we branch to
+# foo_external_diff+8. Also check that foo_external_same has no global entry
+# point and we branch to start of foo_external_same.
+
+// CHECK: _start:
+// CHECK: 10010020:       {{.*}}     bl .+144
+// CHECK: 10010034:       {{.*}}     bl .+84
+// CHECK: foo_external_diff:
+// CHECK-NEXT: 10010080:       {{.*}}     addis 2, 12, 2
+// CHECK-NEXT: 10010084:       {{.*}}     addi 2, 2, 32640
+// CHECK-NEXT: 10010088:       {{.*}}     addis 5, 2, 0
+// CHECK: foo_external_same:
+// CHECK-NEXT: 100100b0:       {{.*}}     add 3, 4, 3
diff --git a/test/ELF/ppc64-general-dynamic-tls.s b/test/ELF/ppc64-general-dynamic-tls.s
new file mode 100644
index 0000000..66dab93
--- /dev/null
+++ b/test/ELF/ppc64-general-dynamic-tls.s
@@ -0,0 +1,112 @@
+// REQUIRES: ppc
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+// RUN: ld.lld -shared %t.o -o %t.so
+// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -relocations --wide %t.so | FileCheck --check-prefix=OutputRelocs %s
+// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s
+// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+// RUN: ld.lld -shared %t.o -o %t.so
+// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -relocations --wide %t.so | FileCheck --check-prefix=OutputRelocs %s
+// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s
+// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s
+
+	.text
+	.abiversion 2
+	.globl	test
+	.p2align	4
+	.type	test,@function
+test:
+.Lfunc_gep0:
+	addis 2, 12, .TOC.-.Lfunc_gep0@ha
+	addi 2, 2, .TOC.-.Lfunc_gep0@l
+.Lfunc_lep0:
+	.localentry	test, .Lfunc_lep0-.Lfunc_gep0
+	mflr 0
+	std 31, -8(1)
+	std 0, 16(1)
+	stdu 1, -48(1)
+	mr 31, 1
+	std 30, 32(31)
+	addis 3, 2, i@got@tlsgd@ha
+	addi 3, 3, i@got@tlsgd@l
+	bl __tls_get_addr(i@tlsgd)
+	nop
+	lwz 30, 0(3)
+	extsw 3, 30
+	ld 30, 32(31)
+	addi 1, 1, 48
+	ld 0, 16(1)
+	ld 31, -8(1)
+	mtlr 0
+	blr
+
+
+test_hi:
+.Lfunc_gep1:
+  addis 2, 12, .TOC.-.Lfunc_gep1@ha
+  addi  2, 2,  .TOC.-.Lfunc_gep1@l
+.Lfunc_lep1:
+  .localentry test2, .Lfunc_lep1-.Lfunc_gep1
+  addis 3, 0, j@got@tlsgd@h
+  blr
+
+test_16:
+.Lfunc_gep2:
+  addis 2, 12, .TOC.-.Lfunc_gep2@ha
+  addi 2, 2, .TOC.-.Lfunc_gep2@l
+.Lfunc_lep2:
+  .localentry test16, .Lfunc_lep2-.Lfunc_gep2
+  addi 3, 0, k@got@tlsgd
+  blr
+
+// Verify that the input has every general-dynamic tls relocation type.
+// InputRelocs:  Relocation section '.rela.text'
+// InputRelocs: R_PPC64_GOT_TLSGD16_HA  {{0+}}  i + 0
+// InputRelocs: R_PPC64_GOT_TLSGD16_LO  {{0+}}  i + 0
+// InputRelocs: R_PPC64_TLSGD           {{0+}}  i + 0
+// InputRelocs: R_PPC64_GOT_TLSGD16_HI  {{0+}}  j + 0
+// InputRelocs: R_PPC64_GOT_TLSGD16     {{0+}}  k + 0
+
+// There is 2 got entries for each tls variable that is accessed with the
+// general-dynamic model.  The entries can be though of as a structure to be
+// filled in by the dynamic linker:
+// typedef struct {
+//  unsigned long int ti_module; --> R_PPC64_DTPMOD64
+//  unsigned long int ti_offset; --> R_PPC64_DTPREL64
+//} tls_index;
+// OutputRelocs: Relocation section '.rela.dyn' at offset 0x{{[0-9a-f]+}} contains 6 entries:
+// OutputRelocs: R_PPC64_DTPMOD64  {{0+}}  i + 0
+// OutputRelocs: R_PPC64_DTPREL64  {{0+}}  i + 0
+// OutputRelocs: R_PPC64_DTPMOD64  {{0+}}  j + 0
+// OutputRelocs: R_PPC64_DTPREL64  {{0+}}  j + 0
+// OutputRelocs: R_PPC64_DTPMOD64  {{0+}}  k + 0
+// OutputRelocs: R_PPC64_DTPREL64  {{0+}}  k + 0
+
+// Check that the got has 7 entires. (1 for the TOC and 3 structures of
+// 2 entries for the tls variables). Also verify the address so we can check
+// the offsets we calculated for each relocation type.
+// CheckGot: got          00000038 00000000000200f0
+
+// got starts at 0x200f0, so .TOC. will be 0x280f0.
+
+// We are building the address of the first tls_index in the got which starts at
+// 0x200f8 (got[1]).
+// #ha(i@got@tlsgd) --> (0x200f8 - 0x280f0 + 0x8000) >> 16 = 0
+// #lo(i@got@tlsgd) --> (0x200f8 - 0x280f0) & 0xFFFF =  -7ff8 = -32760
+// Dis:  test:
+// Dis:    addis 3, 2, 0
+// Dis:    addi 3, 3, -32760
+
+// Second tls_index starts at got[3].
+// #hi(j@got@tlsgd) --> (0x20108 - 0x280f0) >> 16 = -1
+// Dis: test_hi:
+// Dis:   lis 3, -1
+
+// Third tls index is at got[5].
+// k@got@tlsgd --> (0x20118 -  0x280f0) = -0x7fd8 = -32728
+// Dis: test_16:
+// Dis:   li 3, -32728
diff --git a/test/ELF/ppc64-got-indirect.s b/test/ELF/ppc64-got-indirect.s
new file mode 100644
index 0000000..2837582
--- /dev/null
+++ b/test/ELF/ppc64-got-indirect.s
@@ -0,0 +1,115 @@
+# REQUIRES: ppc
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+# RUN: llvm-readobj -relocations %t.o | FileCheck -check-prefix=RELOCS-LE %s
+# RUN: ld.lld %t.o -o %t2
+# RUN: llvm-objdump -D %t2 | FileCheck %s --check-prefix=CHECK-LE
+# RUN: llvm-objdump -D %t2 | FileCheck %s
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+# RUN: llvm-readobj -relocations %t.o | FileCheck -check-prefix=RELOCS-BE %s
+# RUN: ld.lld %t.o -o %t2
+# RUN: llvm-objdump -D %t2 | FileCheck %s --check-prefix=CHECK-BE
+# RUN: llvm-objdump -D %t2 | FileCheck %s
+
+# Make sure we calculate the offset correctly for a got-indirect access to a
+# global variable as described by the PPC64 ELF V2 abi.
+  .text
+  .abiversion 2
+  .globl  _start                    # -- Begin function _start
+  .p2align  4
+  .type  _start,@function
+_start:                                   # @_start
+.Lfunc_begin0:
+.Lfunc_gep0:
+  addis 2, 12, .TOC.-.Lfunc_gep0@ha
+  addi 2, 2, .TOC.-.Lfunc_gep0@l
+.Lfunc_lep0:
+  .localentry  _start, .Lfunc_lep0-.Lfunc_gep0
+# %bb.0:                                # %entry
+  addis 3, 2, .LC0@toc@ha
+  ld 3, .LC0@toc@l(3)
+  li 4, 0
+  stw 4, -12(1)
+  li 0,1
+        lwa 3, 0(3)
+  sc
+  .long  0
+  .quad  0
+.Lfunc_end0:
+  .size  _start, .Lfunc_end0-.Lfunc_begin0
+                                        # -- End function
+  .section  .toc,"aw",@progbits
+.LC0:
+  .tc glob[TC],glob
+  .type  glob,@object            # @glob
+  .data
+  .globl  glob
+  .p2align  2
+glob:
+  .long  55                      # 0x37
+  .size  glob, 4
+
+# Verify the relocations emitted for glob are through the .toc
+
+# RELOCS-LE: Relocations [
+# RELOCS-LE:  .rela.text {
+# RELOCS-LE:     0x0 R_PPC64_REL16_HA .TOC. 0x0
+# RELOCS-LE:     0x4 R_PPC64_REL16_LO .TOC. 0x4
+# RELOCS-LE:     0x8 R_PPC64_TOC16_HA .toc 0x0
+# RELOCS-LE:     0xC R_PPC64_TOC16_LO_DS .toc 0x0
+# RELOCS-LE:   }
+# RELOCS-LE:   .rela.toc {
+# RELOCS-LE:     0x0 R_PPC64_ADDR64 glob 0x0
+# RELOCS-LE:   }
+
+# RELOCS-BE: Relocations [
+# RELOCS-BE:  .rela.text {
+# RELOCS-BE:    0x2 R_PPC64_REL16_HA .TOC. 0x2
+# RELOCS-BE:    0x6 R_PPC64_REL16_LO .TOC. 0x6
+# RELOCS-BE:    0xA R_PPC64_TOC16_HA .toc 0x0
+# RELOCS-BE:    0xE R_PPC64_TOC16_LO_DS .toc 0x0
+# RELOCS-BE:  }
+# RELOCS-BE:  .rela.toc {
+# RELOCS-BE:    0x0 R_PPC64_ADDR64 glob 0x0
+# RELOCS-BE:  }
+# RELOCS-BE:]
+
+# Verify that the global variable access is done through the correct
+# toc entry:
+# r2 = .TOC. = 0x10038000.
+# r3 = r2 - 32760 = 0x10030008 -> .toc entry for glob.
+
+# CHECK: _start:
+# CHECK-NEXT: 10010000:  {{.*}}   addis 2, 12, 3
+# CHECK-NEXT: 10010004:  {{.*}}   addi 2, 2, -32768
+# CHECK-NEXT: 10010008:  {{.*}}   addis 3, 2, 0
+# CHECK-NEXT: 1001000c:  {{.*}}   ld 3, -32760(3)
+# CHECK: 1001001c:  {{.*}}   lwa 3, 0(3)
+
+# CHECK-LE: Disassembly of section .data:
+# CHECK-LE-NEXT: glob:
+# CHECK-LE-NEXT: 10020000:       37 00 00 00
+
+# CHECK-LE: Disassembly of section .got:
+# CHECK-LE-NEXT: .got:
+# CHECK-LE-NEXT: 10030000:       00 80 03 10
+# CHECK-LE-NEXT: 10030004:       00 00 00 00
+
+# Verify that .toc comes right after .got
+# CHECK-LE: Disassembly of section .toc:
+# CHECK-LE: 10030008:       00 00 02 10
+
+# CHECK-BE: Disassembly of section .data:
+# CHECK-BE-NEXT: glob:
+# CHECK-BE-NEXT: 10020000:       00 00 00 37
+
+# CHECK-BE: Disassembly of section .got:
+# CHECK-BE-NEXT: .got:
+# CHECK-BE-NEXT: 10030000:       00 00 00 00
+# CHECK-BE-NEXT: 10030004:       10 03 80 00
+
+# Verify that .toc comes right after .got
+# CHECK-BE: Disassembly of section .toc:
+# CHECK-BE: 10030008:       00 00 00 00
+# CHECK-BE: 1003000c:       10 02 00 00
diff --git a/test/ELF/ppc64-ifunc.s b/test/ELF/ppc64-ifunc.s
index b993206..6f2d331 100644
--- a/test/ELF/ppc64-ifunc.s
+++ b/test/ELF/ppc64-ifunc.s
@@ -1,41 +1,87 @@
 # REQUIRES: ppc
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
+# RUN: ld.lld -shared %t2.o -o %t2.so
+# RUN: ld.lld %t.o %t2.so -o %t
+# RUN: llvm-objdump -D %t | FileCheck %s
+# RUN: llvm-readelf -dynamic-table %t | FileCheck --check-prefix=DT %s
+# RUN: llvm-readelf -dyn-relocations %t | FileCheck --check-prefix=DYNREL %s
+
 # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
 # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
 # RUN: ld.lld -shared %t2.o -o %t2.so
 # RUN: ld.lld %t.o %t2.so -o %t
-# RUN: llvm-objdump -d %t | FileCheck %s
+# RUN: llvm-objdump -D %t | FileCheck %s
+# RUN: llvm-readelf -dynamic-table %t | FileCheck --check-prefix=DT %s
+# RUN: llvm-readelf -dyn-relocations %t | FileCheck --check-prefix=DYNREL %s
 
-# CHECK:      _start:
-# CHECK-NEXT:  10010004: {{.*}} bl .+12
-# CHECK-NEXT:  10010008: {{.*}} bl .+40
+# CHECK: Disassembly of section .text:
 
-# 0x10010004 + 12 = 0x10010010 (PLT entry 0)
-# 0x10010008 + 40 = 0x10010030 (PLT entry 1)
+# Tocbase    + (0 << 16) + 32560
+# 0x100280e0 +  0        + 32560 = 0x10030010 (.plt[2])
+# CHECK: __plt_foo:
+# CHECK-NEXT:     std 2, 24(1)
+# CHECK-NEXT:     addis 12, 2, 0
+# CHECK-NEXT:     ld 12, 32560(12)
+# CHECK-NEXT:     mtctr 12
+# CHECK-NEXT:     bctr
 
-# CHECK:     Disassembly of section .plt:
-# CHECK:       10010010: {{.*}} std 2, 40(1)
-# CHECK-NEXT:  10010014: {{.*}} addis 11, 2, 4098
-# CHECK-NEXT:  10010018: {{.*}} ld 12, -32744(11)
-# CHECK-NEXT:  1001001c: {{.*}} ld 11, 0(12)
-# CHECK-NEXT:  10010020: {{.*}} mtctr 11
-# CHECK-NEXT:  10010024: {{.*}} ld 2, 8(12)
-# CHECK-NEXT:  10010028: {{.*}} ld 11, 16(12)
-# CHECK-NEXT:  1001002c: {{.*}} bctr
-# CHECK-NEXT:  10010030: {{.*}} std 2, 40(1)
-# CHECK-NEXT:  10010034: {{.*}} addis 11, 2, 4098
-# CHECK-NEXT:  10010038: {{.*}} ld 12, -32736(11)
-# CHECK-NEXT:  1001003c: {{.*}} ld 11, 0(12)
-# CHECK-NEXT:  10010040: {{.*}} mtctr 11
-# CHECK-NEXT:  10010044: {{.*}} ld 2, 8(12)
-# CHECK-NEXT:  10010048: {{.*}} ld 11, 16(12)
-# CHECK-NEXT:  1001004c: {{.*}} bctr
+# Tocbase    + (0 << 16)  +  32568
+# 0x100280e0 +  0          + 32568 = 0x1003018 (.plt[3])
+# CHECK: __plt_ifunc:
+# CHECK-NEXT:     std 2, 24(1)
+# CHECK-NEXT:     addis 12, 2, 0
+# CHECK-NEXT:     ld 12, 32568(12)
+# CHECK-NEXT:     mtctr 12
+# CHECK-NEXT:     bctr
+
+# CHECK: ifunc:
+# CHECK-NEXT: 10010028:  {{.*}} nop
+
+# CHECK: _start:
+# CHECK-NEXT:     addis 2, 12, 2
+# CHECK-NEXT:     addi 2, 2, -32588
+# CHECK-NEXT:     bl .+67108812
+# CHECK-NEXT:     ld 2, 24(1)
+# CHECK-NEXT:     bl .+67108824
+# CHECK-NEXT:     ld 2, 24(1)
+
+# Check tocbase
+# CHECK:       Disassembly of section .got:
+# CHECK-NEXT:    .got:
+# CHECK-NEXT:    100200e0
+
+# Check .plt address
+# DT_PLTGOT should point to the start of the .plt section.
+# DT: 0x0000000000000003 PLTGOT 0x10030000
+
+# Check that we emit the correct dynamic relocation type for an ifunc
+# DYNREL: 'PLT' relocation section at offset 0x{{[0-9a-f]+}} contains 48 bytes:
+# 48 bytes --> 2 Elf64_Rela relocations
+# DYNREL-NEXT: Offset        Info           Type               Symbol's Value  Symbol's Name + Addend
+# DYNREL-NEXT: {{[0-9a-f]+}} {{[0-9a-f]+}}  R_PPC64_JMP_SLOT      {{0+}}            foo + 0
+# DYNREL-NEXT: {{[0-9a-f]+}} {{[0-9a-f]+}}  R_PPC64_IRELATIVE     10010028
+
+
+    .text
+    .abiversion 2
 
 .type ifunc STT_GNU_IFUNC
 .globl ifunc
 ifunc:
  nop
 
-.global _start
+    .global _start
+    .type   _start,@function
+
 _start:
-  bl bar
+.Lfunc_gep0:
+  addis 2, 12, .TOC.-.Lfunc_gep0@ha
+  addi 2, 2, .TOC.-.Lfunc_gep0@l
+.Lfunc_lep0:
+  .localentry     _start, .Lfunc_lep0-.Lfunc_gep0
+  bl foo
+  nop
   bl ifunc
+  nop
diff --git a/test/ELF/ppc64-initial-exec-tls.s b/test/ELF/ppc64-initial-exec-tls.s
new file mode 100644
index 0000000..5218b68
--- /dev/null
+++ b/test/ELF/ppc64-initial-exec-tls.s
@@ -0,0 +1,102 @@
+// REQUIRES: ppc
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-tls.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: ld.lld -dynamic-linker /lib64/ld64.so.2 %t.o %t2.so -o %t
+// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s
+// RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=CheckGot %s
+// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-tls.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: ld.lld -dynamic-linker /lib64/ld64.so.2 %t.o %t2.so -o %t
+// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s
+// RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=CheckGot %s
+// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
+
+	.text
+	.abiversion 2
+	.file	"intial_exec.c"
+	.globl	test_initial_exec                    # -- Begin function test_initial_exec
+	.p2align	4
+	.type	test_initial_exec,@function
+test_initial_exec:                                   # @test_initial_exec
+.Lfunc_begin0:
+.Lfunc_gep0:
+	addis 2, 12, .TOC.-.Lfunc_gep0@ha
+	addi 2, 2, .TOC.-.Lfunc_gep0@l
+.Lfunc_lep0:
+	.localentry	test_initial_exec, .Lfunc_lep0-.Lfunc_gep0
+# %bb.0:                                # %entry
+	li 3, 0
+	stw 3, -12(1)
+	addis 3, 2, a@got@tprel@ha
+	ld 3, a@got@tprel@l(3)
+	lwzx 4, 3, a@tls
+	extsw 3, 4
+	blr
+
+
+test_hi:
+.Lfunc_gep1:
+  addis 2, 12, .TOC.-.Lfunc_gep1@ha
+  addi  2, 2,  .TOC.-.Lfunc_gep1@l
+.Lfunc_lep1:
+  .localentry test2, .Lfunc_lep1-.Lfunc_gep1
+  addis 3, 0, b@got@tprel@h
+  blr
+
+test_ds:
+.Lfunc_gep2:
+  addis 2, 12, .TOC.-.Lfunc_gep2@ha
+  addi 2, 2, .TOC.-.Lfunc_gep2@l
+.Lfunc_lep2:
+  .localentry test16, .Lfunc_lep2-.Lfunc_gep2
+  addi 3, 0, c@got@tprel
+  blr
+
+// Verify that the input has every initial-exec tls relocation type.
+// InputRelocs: Relocation section '.rela.text'
+// InputRelocs: R_PPC64_GOT_TPREL16_HA {{0+}} a + 0
+// InputRelocs: R_PPC64_GOT_TPREL16_LO_DS {{0+}} a + 0
+// InputRelocs: R_PPC64_TLS {{0+}} a + 0
+// InputRelocs: R_PPC64_GOT_TPREL16_HI {{0+}} b + 0
+// InputRelocs: R_PPC64_GOT_TPREL16_DS {{0+}} c + 0
+
+// There is a got entry for each tls variable that is accessed with the
+// initial-exec model to be filled in by the dynamic linker.
+// OutputRelocs: Relocation section '.rela.dyn' at offset 0x{{[0-9a-f]+}} contains 3 entries:
+// OutputRelocs: R_PPC64_TPREL64  {{0+}}  a + 0
+// OutputRelocs: R_PPC64_TPREL64  {{0+}}  b + 0
+// OutputRelocs: R_PPC64_TPREL64  {{0+}}  c + 0
+
+// Check that the got has 4 entires. (1 for the TOC and 3 entries for TLS
+// variables). Also verify the address so we can check
+// the offsets we calculated for each relocation type.
+// CheckGot: got          00000020 00000000100200c0
+
+// GOT stats at 0x100200c0, so TOC will be 0x100280c0
+
+// We are building the address of the first TLS got entry which contains the
+// offset of the tls variable relative to the thread pointer.
+// 0x100200c8 (got[1]).
+// #ha(a@got@tprel) --> (0x100200c8 - 0x100280c0 + 0x8000) >> 16 = 0
+// #lo(a@got@tprel)) --> (0x100200c8 - 0x100280c0) & 0xFFFF =  -7ff8 = -32760
+// Dis:  test_initial_exec:
+// Dis:    addis 3, 2, 0
+// Dis:    ld 3, -32760(3)
+// Dis:    lwzx 4, 3, 13
+
+// Second TLS got entry starts at got[2] 0x100200d0
+// #hi(b@got@tprel) --> (0x100200d0 - 0x100280c0) >> 16 = -1
+// Dis: test_hi:
+// Dis:   lis 3, -1
+
+// Third TLS got entry starts at got[3] 0x100200d8.
+// c@got@tprel--> (0x100200d8. -  0x100280c0) = -0x7fe8 = 32744
+// Dis: test_ds:
+// Dis:   li 3, -32744
diff --git a/test/ELF/ppc64-local-dynamic.s b/test/ELF/ppc64-local-dynamic.s
new file mode 100644
index 0000000..a051eae
--- /dev/null
+++ b/test/ELF/ppc64-local-dynamic.s
@@ -0,0 +1,112 @@
+// REQUIRES: ppc
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+// RUN: ld.lld -shared %t.o -o %t.so
+// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -relocations --wide %t.so | FileCheck --check-prefix=OutputRelocs %s
+// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s
+// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+// RUN: ld.lld -shared %t.o -o %t.so
+// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -relocations --wide %t.so | FileCheck --check-prefix=OutputRelocs %s
+// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s
+// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s
+
+        .text
+        .abiversion 2
+        .globl  test
+        .p2align        4
+        .type   test,@function
+test:
+.Lfunc_gep0:
+        addis 2, 12, .TOC.-.Lfunc_gep0@ha
+        addi 2, 2, .TOC.-.Lfunc_gep0@l
+.Lfunc_lep0:
+        .localentry     test, .Lfunc_lep0-.Lfunc_gep0
+        mflr 0
+        std 0, 16(1)
+        stdu 1, -32(1)
+        addis 3, 2, i@got@tlsld@ha
+        addi 3, 3, i@got@tlsld@l
+        bl __tls_get_addr(i@tlsld)
+        nop
+        ld 0, 16(1)
+        mtlr 0
+        blr
+
+        .globl test_hi
+        .p2align 4
+        .type test_hi,@function
+test_hi:
+         lis 3, j@got@tlsld@h
+         blr
+
+        .globl test_16
+        .p2align 4
+        .type test_16,@function
+test_16:
+         li 3, k@got@tlsld
+         blr
+
+        .type   i,@object
+        .section        .tdata,"awT",@progbits
+        .p2align        2
+i:
+        .long   55
+        .size   i, 4
+
+        .type   j,@object
+        .section        .tbss,"awT",@nobits
+        .p2align        2
+j:
+        .long   0
+        .size   j, 4
+
+        .type   k,@object
+        .section        .tdata,"awT",@progbits
+        .p2align        3
+k:
+        .quad   66
+        .size   k, 8
+
+// Verify that the input contains all the R_PPC64_GOT_TLSLD16* relocations.
+// InputRelocs: Relocation section '.rela.text'
+// InputRelocs:     R_PPC64_GOT_TLSLD16_HA 0000000000000000 i + 0
+// InputRelocs:     R_PPC64_GOT_TLSLD16_LO 0000000000000000 i + 0
+// InputRelocs:     R_PPC64_TLSLD          0000000000000000 i + 0
+// InputRelocs:     R_PPC64_GOT_TLSLD16_HI 0000000000000000 j + 0
+// InputRelocs:     R_PPC64_GOT_TLSLD16    0000000000000008 k + 0
+
+// The local dynamic version of tls needs to use the same mechanism to look up
+// a variables address as general-dynamic. ie a call to __tls_get_addr with the
+// address of a tls_index struct as the argument. However for local-dynamic
+// variables  all will have the same ti_module, and the offset field is left as
+// as 0, so the same struct can be used for every local-dynamic variable
+// used in the shared-object.
+// OutputRelocs:      Relocation section '.rela.dyn' at offset 0x{{[0-9a-f]+}} contains 1 entries:
+// OutputRelocs-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend
+// OutputRelocs-NEXT: R_PPC64_DTPMOD64
+
+// Check that the got has 3 entries, 1 for the TOC and 1 stucture of 2 entries
+// for the tls variables. Also verify the address so we can check the offsets
+// we calculate for each relocation type.
+// CheckGot: got          00000018 0000000000020100
+
+// got starts at 0x20100 so .TOC. will be 0x28100, and the tls_index struct is
+// at 0x20108.
+
+// #ha(i@got@tlsld) --> (0x20108 - 0x28100 + 0x8000) >> 16 = 0
+// #lo(i@got@tlsld) --> (0x20108 - 0x28100) = -7ff8 = -32760
+// Dis:     test:
+// Dis:        addis 3, 2, 0
+// Dis-NEXT:   addi 3, 3, -32760
+
+// #hi(j@got@tlsld) --> (0x20108 - 0x28100 ) > 16 = -1
+// Dis: test_hi:
+// Dis:   lis 3, -1
+
+// k@got@tlsld --> (0x20108 - 0x28100) = -7ff8 = -32760
+// Dis: test_16:
+// Dis:   li 3, -32760
diff --git a/test/ELF/ppc64-plt-stub.s b/test/ELF/ppc64-plt-stub.s
new file mode 100644
index 0000000..a644f48
--- /dev/null
+++ b/test/ELF/ppc64-plt-stub.s
@@ -0,0 +1,42 @@
+// REQUIRES: ppc
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: ld.lld %t.o %t2.so -o %t
+// RUN: llvm-objdump -d %t | FileCheck %s
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: ld.lld %t.o %t2.so -o %t
+// RUN: llvm-objdump -d %t | FileCheck %s
+
+// CHECK:      Disassembly of section .text:
+// CHECK-NEXT: __plt_foo:
+// CHECK-NEXT:      std 2, 24(1)
+// CHECK-NEXT:      addis 12, 2, 0
+// CHECK-NEXT:      ld 12, 32560(12)
+// CHECK-NEXT:      mtctr 12
+// CHECK-NEXT:      bctr
+
+
+// CHECK:            _start:
+// CHECK:            bl .+67108824
+        .text
+        .abiversion 2
+        .globl  _start
+        .p2align        4
+        .type   _start,@function
+_start:
+.Lfunc_begin0:
+.Lfunc_gep0:
+  addis 2, 12, .TOC.-.Lfunc_gep0@ha
+  addi 2, 2, .TOC.-.Lfunc_gep0@l
+.Lfunc_lep0:
+  .localentry     _start, .Lfunc_lep0-.Lfunc_gep0
+  bl foo
+  nop
+  li 0, 1
+  sc
+  .size _start, .-.Lfunc_begin0
diff --git a/test/ELF/ppc64-rel-calls.s b/test/ELF/ppc64-rel-calls.s
index f3b309f..4c79498 100644
--- a/test/ELF/ppc64-rel-calls.s
+++ b/test/ELF/ppc64-rel-calls.s
@@ -1,32 +1,29 @@
+# REQUIRES: ppc
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t
+# RUN: ld.lld %t -o %t2
+# RUN: llvm-objdump -d %t2 | FileCheck %s
+
 # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
 # RUN: ld.lld %t -o %t2
 # RUN: llvm-objdump -d %t2 | FileCheck %s
-# REQUIRES: ppc
 
 # CHECK: Disassembly of section .text:
 
-.section        ".opd","aw"
+.text
 .global _start
 _start:
-.quad   .Lfoo,.TOC.@tocbase,0
-
-.text
 .Lfoo:
   li      0,1
   li      3,42
   sc
 
-# CHECK: 10010000:       38 00 00 01     li 0, 1
-# CHECK: 10010004:       38 60 00 2a     li 3, 42
-# CHECK: 10010008:       44 00 00 02     sc
+# CHECK: 10010000:       {{.*}}     li 0, 1
+# CHECK: 10010004:       {{.*}}     li 3, 42
+# CHECK: 10010008:       {{.*}}     sc
 
-.section        ".opd","aw"
 .global bar
 bar:
-.quad   .Lbar,.TOC.@tocbase,0
-
-.text
-.Lbar:
   bl _start
   nop
   bl .Lfoo
@@ -34,9 +31,8 @@
   blr
 
 # FIXME: The printing here is misleading, the branch offset here is negative.
-# CHECK: 1001000c:       4b ff ff f5     bl .+67108852
-# CHECK: 10010010:       60 00 00 00     nop
-# CHECK: 10010014:       4b ff ff ed     bl .+67108844
-# CHECK: 10010018:       60 00 00 00     nop
-# CHECK: 1001001c:       4e 80 00 20     blr
-
+# CHECK: 1001000c:       {{.*}}     bl .+67108852
+# CHECK: 10010010:       {{.*}}     nop
+# CHECK: 10010014:       {{.*}}     bl .+67108844
+# CHECK: 10010018:       {{.*}}     nop
+# CHECK: 1001001c:       {{.*}}     blr
diff --git a/test/ELF/ppc64-rel-so-local-calls.s b/test/ELF/ppc64-rel-so-local-calls.s
new file mode 100644
index 0000000..834dbd5
--- /dev/null
+++ b/test/ELF/ppc64-rel-so-local-calls.s
@@ -0,0 +1,87 @@
+// REQUIRES: ppc
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+// RUN: ld.lld -shared -z notext %t.o -o %t.so
+// RUN: llvm-readelf -dyn-relocations %t.so | FileCheck %s
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+// RUN: ld.lld -shared -z notext %t.o -o %t.so
+// RUN: llvm-readelf -dyn-relocations %t.so | FileCheck %s
+
+
+// CHECK-NOT: foo
+// CHECK-NOT: bar
+
+	.text
+	.abiversion 2
+	.globl	baz
+	.p2align	4
+	.type	baz,@function
+baz:
+.Lfunc_begin0:
+.Lfunc_gep0:
+	addis 2, 12, .TOC.-.Lfunc_gep0@ha
+	addi 2, 2, .TOC.-.Lfunc_gep0@l
+.Lfunc_lep0:
+	.localentry	baz, .Lfunc_lep0-.Lfunc_gep0
+	mflr 0
+	std 0, 16(1)
+	stdu 1, -64(1)
+	std 30, 48(1)
+	std 29, 40(1)
+	mr 30, 3
+	bl foo
+	mr 29, 3
+	mr 3, 30
+	bl bar
+	mullw 3, 3, 29
+	ld 30, 48(1)
+	ld 29, 40(1)
+	extsw 3, 3
+	addi 1, 1, 64
+	ld 0, 16(1)
+	mtlr 0
+	blr
+	.long	0
+	.quad	0
+.Lfunc_end0:
+	.size	baz, .Lfunc_end0-.Lfunc_begin0
+
+	.p2align	4
+	.type	foo,@function
+foo:
+.Lfunc_begin1:
+	mullw 3, 3, 3
+	extsw 3, 3
+	blr
+	.long	0
+	.quad	0
+.Lfunc_end1:
+	.size	foo, .Lfunc_end1-.Lfunc_begin1
+
+        .p2align	4
+	.type	bar,@function
+bar:
+.Lfunc_begin2:
+.Lfunc_gep2:
+	addis 2, 12, .TOC.-.Lfunc_gep2@ha
+	addi 2, 2, .TOC.-.Lfunc_gep2@l
+.Lfunc_lep2:
+	.localentry	bar, .Lfunc_lep2-.Lfunc_gep2
+	mflr 0
+	std 0, 16(1)
+	stdu 1, -48(1)
+	std 30, 32(1)
+	mr 30, 3
+	bl foo
+	mullw 3, 3, 30
+	ld 30, 32(1)
+	extsw 3, 3
+	addi 1, 1, 48
+	ld 0, 16(1)
+	mtlr 0
+	blr
+	.long	0
+	.quad	0
+.Lfunc_end2:
+	.size	bar, .Lfunc_end2-.Lfunc_begin2
diff --git a/test/ELF/ppc64-relocs.s b/test/ELF/ppc64-relocs.s
index cb6177d..88e3d4b 100644
--- a/test/ELF/ppc64-relocs.s
+++ b/test/ELF/ppc64-relocs.s
@@ -1,22 +1,33 @@
-# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
-# RUN: ld.lld %t -o %t2
-# RUN: llvm-objdump -d %t2 | FileCheck %s
 # REQUIRES: ppc
 
-.section        ".opd","aw"
-.global _start
-_start:
-.quad   .Lfoo,.TOC.@tocbase,0
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t
+# RUN: ld.lld %t -o %t2
+# RUN: llvm-objdump -D %t2 | FileCheck %s --check-prefix=DATALE
+# RUN: llvm-objdump -D %t2 | FileCheck %s
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
+# RUN: ld.lld %t -o %t2
+# RUN: llvm-objdump -D %t2 | FileCheck %s --check-prefix=DATABE
+# RUN: llvm-objdump -D %t2 | FileCheck %s
 
 .text
+.global _start
+_start:
 .Lfoo:
 	li      0,1
 	li      3,42
 	sc
 
-.section        ".toc","aw"
+.section        .rodata,"a",@progbits
+        .p2align        2
+.LJTI0_0:
+        .long   .LBB0_2-.LJTI0_0
+
+.section        .toc,"aw",@progbits
 .L1:
 .quad           22, 37, 89, 47
+.LC0:
+        .tc .LJTI0_0[TC],.LJTI0_0
 
 .section .R_PPC64_TOC16_LO_DS,"ax",@progbits
 .globl .FR_PPC64_TOC16_LO_DS
@@ -25,7 +36,7 @@
 
 # CHECK: Disassembly of section .R_PPC64_TOC16_LO_DS:
 # CHECK: .FR_PPC64_TOC16_LO_DS:
-# CHECK: 1001000c:       e8 22 80 00     ld 1, -32768(2)
+# CHECK: 1001000c:       {{.*}}     ld 1, -32768(2)
 
 .section .R_PPC64_TOC16_LO,"ax",@progbits
 .globl .FR_PPC64_TOC16_LO
@@ -34,7 +45,7 @@
 
 # CHECK: Disassembly of section .R_PPC64_TOC16_LO:
 # CHECK: .FR_PPC64_TOC16_LO:
-# CHECK: 10010010: 38 22 80 00 addi 1, 2, -32768
+# CHECK: 10010010: {{.*}} addi 1, 2, -32768
 
 .section .R_PPC64_TOC16_HI,"ax",@progbits
 .globl .FR_PPC64_TOC16_HI
@@ -43,7 +54,7 @@
 
 # CHECK: Disassembly of section .R_PPC64_TOC16_HI:
 # CHECK: .FR_PPC64_TOC16_HI:
-# CHECK: 10010014: 3c 22 ff fe addis 1, 2, -2
+# CHECK: 10010014: {{.*}} addis 1, 2, -1
 
 .section .R_PPC64_TOC16_HA,"ax",@progbits
 .globl .FR_PPC64_TOC16_HA
@@ -52,7 +63,7 @@
 
 # CHECK: Disassembly of section .R_PPC64_TOC16_HA:
 # CHECK: .FR_PPC64_TOC16_HA:
-# CHECK: 10010018: 3c 22 ff ff addis 1, 2, -1
+# CHECK: 10010018: {{.*}} addis 1, 2, 0
 
 .section .R_PPC64_REL24,"ax",@progbits
 .globl .FR_PPC64_REL24
@@ -63,7 +74,7 @@
 
 # CHECK: Disassembly of section .R_PPC64_REL24:
 # CHECK: .FR_PPC64_REL24:
-# CHECK: 1001001c: 48 00 00 04 b .+4
+# CHECK: 1001001c: {{.*}} b .+4
 
 .section .R_PPC64_ADDR16_LO,"ax",@progbits
 .globl .FR_PPC64_ADDR16_LO
@@ -72,7 +83,7 @@
 
 # CHECK: Disassembly of section .R_PPC64_ADDR16_LO:
 # CHECK: .FR_PPC64_ADDR16_LO:
-# CHECK: 10010020: 38 20 00 00 li 1, 0
+# CHECK: 10010020: {{.*}} li 1, 0
 
 .section .R_PPC64_ADDR16_HI,"ax",@progbits
 .globl .FR_PPC64_ADDR16_HI
@@ -81,7 +92,7 @@
 
 # CHECK: Disassembly of section .R_PPC64_ADDR16_HI:
 # CHECK: .FR_PPC64_ADDR16_HI:
-# CHECK: 10010024: 38 20 10 01 li 1, 4097
+# CHECK: 10010024: {{.*}} li 1, 4097
 
 .section .R_PPC64_ADDR16_HA,"ax",@progbits
 .globl .FR_PPC64_ADDR16_HA
@@ -90,7 +101,7 @@
 
 # CHECK: Disassembly of section .R_PPC64_ADDR16_HA:
 # CHECK: .FR_PPC64_ADDR16_HA:
-# CHECK: 10010028: 38 20 10 01 li 1, 4097
+# CHECK: 10010028: {{.*}} li 1, 4097
 
 .section .R_PPC64_ADDR16_HIGHER,"ax",@progbits
 .globl .FR_PPC64_ADDR16_HIGHER
@@ -99,7 +110,7 @@
 
 # CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHER:
 # CHECK: .FR_PPC64_ADDR16_HIGHER:
-# CHECK: 1001002c: 38 20 00 00 li 1, 0
+# CHECK: 1001002c: {{.*}} li 1, 0
 
 .section .R_PPC64_ADDR16_HIGHERA,"ax",@progbits
 .globl .FR_PPC64_ADDR16_HIGHERA
@@ -108,7 +119,7 @@
 
 # CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHERA:
 # CHECK: .FR_PPC64_ADDR16_HIGHERA:
-# CHECK: 10010030: 38 20 00 00 li 1, 0
+# CHECK: 10010030: {{.*}} li 1, 0
 
 .section .R_PPC64_ADDR16_HIGHEST,"ax",@progbits
 .globl .FR_PPC64_ADDR16_HIGHEST
@@ -117,7 +128,7 @@
 
 # CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHEST:
 # CHECK: .FR_PPC64_ADDR16_HIGHEST:
-# CHECK: 10010034: 38 20 00 00 li 1, 0
+# CHECK: 10010034: {{.*}} li 1, 0
 
 .section .R_PPC64_ADDR16_HIGHESTA,"ax",@progbits
 .globl .FR_PPC64_ADDR16_HIGHESTA
@@ -126,5 +137,57 @@
 
 # CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHESTA:
 # CHECK: .FR_PPC64_ADDR16_HIGHESTA:
-# CHECK: 10010038: 38 20 00 00 li 1, 0
+# CHECK: 10010038: {{.*}} li 1, 0
 
+.section  .R_PPC64_REL32, "ax",@progbits
+.globl .FR_PPC64_REL32
+.FR_PPC64_REL32:
+  addis 5, 2, .LC0@toc@ha
+  ld 5, .LC0@toc@l(5)
+.LBB0_2:
+  add 3, 3, 4
+
+# DATALE: Disassembly of section .rodata:
+# DATALE: .rodata:
+# DATALE: 10000190: b4 fe 00 00
+
+# DATABE: Disassembly of section .rodata:
+# DATABE: .rodata:
+# DATABE: 10000190: 00 00 fe b4
+
+# Address of rodata + value stored at rodata entry
+# should equal address of LBB0_2.
+# 0x10000190 + 0xfeb4 = 0x10010044
+# CHECK: Disassembly of section .R_PPC64_REL32:
+# CHECK: .FR_PPC64_REL32:
+# CHECK: 1001003c: {{.*}} addis 5, 2, 0
+# CHECK: 10010040: {{.*}} ld 5, -32736(5)
+# CHECK: 10010044: {{.*}} add 3, 3, 4
+
+.section .R_PPC64_REL64, "ax",@progbits
+.globl  .FR_PPC64_REL64
+.FR_PPC64_REL64:
+        .cfi_startproc
+        .cfi_personality 148, __foo
+        li 0, 1
+        li 3, 55
+        sc
+        .cfi_endproc
+__foo:
+  li 3,0
+
+# Check that address of eh_frame entry + value stored
+# should equal the address of foo. Since it is not aligned,
+# the entry is not stored exactly at 100001a8. It starts at
+# address 0x100001aa and has the value 0xfeaa.
+# 0x100001aa + 0xfeaa = 0x10010054
+# DATALE: Disassembly of section .eh_frame:
+# DATALE: .eh_frame:
+# DATALE: 100001a8: {{.*}} aa fe
+
+# DATABE: Disassembly of section .eh_frame:
+# DATABE: .eh_frame:
+# DATABE: 100001b0: fe aa {{.*}}
+
+# CHECK: __foo
+# CHECK-NEXT: 10010054: {{.*}} li 3, 0
diff --git a/test/ELF/ppc64-shared-rel-toc.s b/test/ELF/ppc64-shared-rel-toc.s
deleted file mode 100644
index 445011b..0000000
--- a/test/ELF/ppc64-shared-rel-toc.s
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
-// RUN: ld.lld -shared %t.o -o %t.so
-// RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
-// REQUIRES: ppc
-
-// When we create the TOC reference in the shared library, make sure that the
-// R_PPC64_RELATIVE relocation uses the correct (non-zero) offset.
-
-        .globl  foo
-        .align  2
-        .type   foo,@function
-        .section        .opd,"aw",@progbits
-foo:                                    # @foo
-        .align  3
-        .quad   .Lfunc_begin0
-        .quad   .TOC.@tocbase
-        .quad   0
-        .text
-.Lfunc_begin0:
-        blr
-
-// CHECK: 0x20000 R_PPC64_RELATIVE - 0x10000
-// CHECK: 0x20008 R_PPC64_RELATIVE - 0x8000
-
-// CHECK: Name: foo
-// CHECK-NEXT: Value: 0x20000
-
diff --git a/test/ELF/ppc64-toc-rel.s b/test/ELF/ppc64-toc-rel.s
new file mode 100644
index 0000000..ac156c7
--- /dev/null
+++ b/test/ELF/ppc64-toc-rel.s
@@ -0,0 +1,90 @@
+# REQUIRES: ppc
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+# RUN: llvm-readobj -relocations %t.o | FileCheck -check-prefix=RELOCS %s
+# RUN: ld.lld %t.o -o %t2
+# RUN: llvm-objdump -D %t2 | FileCheck %s
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+# RUN: llvm-readobj -relocations %t.o | FileCheck -check-prefix=RELOCS-BE %s
+# RUN: ld.lld %t.o -o %t2
+# RUN: llvm-objdump -D %t2 | FileCheck -check-prefix=CHECK-BE %s
+
+# Make sure we calculate the offset correctly for a toc-relative access to a
+# global variable as described by the PPC64 Elf V2 abi.
+.abiversion 2
+
+#  int global_a = 55
+   .globl      global_a
+   .section    ".data"
+   .align      2
+   .type       global_a, @object
+   .size       global_a, 4
+   .p2align    2
+global_a:
+   .long   41
+
+
+   .section        ".text"
+   .align 2
+   .global _start
+   .type   _start, @function
+_start:
+.Lfunc_gep0:
+    addis 2, 12, .TOC.-.Lfunc_gep0@ha
+    addi 2, 2, .TOC.-.Lfunc_gep0@l
+.Lfunc_lep0:
+    .localentry _start, .Lfunc_lep0-.Lfunc_gep0
+
+    addis 3, 2, global_a@toc@ha
+    addi 3, 3, global_a@toc@l
+    li 0,1
+    lwa 3, 0(3)
+    sc
+.size   _start,.-_start
+
+# Verify the relocations that get emitted for the global variable are the
+# expected ones.
+# RELOCS:      Relocations [
+# RELOCS-NEXT:   .rela.text {
+# RELOCS:          0x8 R_PPC64_TOC16_HA global_a 0x0
+# RELOCS:          0xC R_PPC64_TOC16_LO global_a 0x0
+
+# RELOCS-BE:      Relocations [
+# RELOCS-BE-NEXT:   .rela.text {
+# RELOCS-BE:          0xA R_PPC64_TOC16_HA global_a 0x0
+# RELOCS-NE:          0xE R_PPC64_TOC16_LO global_a 0x0
+
+# Want to check _start for the values used to build the offset from the TOC base
+# to global_a. The .TOC. symbol is expected at address 0x10030000, and the
+# TOC base is address-of(.TOC.) + 0x8000.  The expected offset is:
+# 0x10020000(global_a) - 0x10038000(Toc base) = -0x18000(Offset)
+# which gets materialized into r3 as ((-1 << 16) - 32768).
+
+# CHECK:      Disassembly of section .text:
+# CHECK-NEXT: _start:
+# CHECK:      10010008:       {{.*}}     addis 3, 2, -1
+# CHECK-NEXT: 1001000c:       {{.*}}     addi 3, 3, -32768
+
+# CHECK:      Disassembly of section .data:
+# CHECK-NEXT: global_a:
+# CHECK-NEXT: 10020000:       {{.*}}
+
+# CHECK:      Disassembly of section .got:
+# CHECK-NEXT: .got:
+# CHECK-NEXT: 10030000:       00 80 03 10
+
+
+# CHECK-BE:      Disassembly of section .text:
+# CHECK-BE-NEXT: _start:
+# CHECK-BE:      10010008:       {{.*}}     addis 3, 2, -1
+# CHECK-BE-NEXT: 1001000c:       {{.*}}     addi 3, 3, -32768
+
+# CHECK-BE:      Disassembly of section .data:
+# CHECK-BE-NEXT: global_a:
+# CHECK-BE-NEXT: 10020000:       {{.*}}
+
+# CHECK-BE:      Disassembly of section .got:
+# CHECK-BE-NEXT: .got:
+# CHECK-BE-NEXT: 10030000:       00 00 00 00
+# CHECK-BE-NEXT: 10030004:       10 03 80 00
diff --git a/test/ELF/ppc64-toc-restore.s b/test/ELF/ppc64-toc-restore.s
index 0c3d30b..9efe0e8 100644
--- a/test/ELF/ppc64-toc-restore.s
+++ b/test/ELF/ppc64-toc-restore.s
@@ -1,62 +1,72 @@
-// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
-// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
-// RUN: ld.lld -shared %t2.o -o %t2.so
-// RUN: ld.lld %t.o %t2.so -o %t
-// RUN: llvm-objdump -d %t | FileCheck %s
 // REQUIRES: ppc
 
-// CHECK: Disassembly of section .text:
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-func.s -o %t3.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: ld.lld %t.o %t2.so %t3.o -o %t
+// RUN: llvm-objdump -d %t | FileCheck %s
 
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-func.s -o %t3.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: ld.lld %t.o %t2.so %t3.o -o %t
+// RUN: llvm-objdump -d %t | FileCheck %s
+
+    .text
+    .abiversion 2
+.global bar_local
+bar_local:
+  li 3, 2
+  blr
+
+# Calling external function foo in a shared object needs a nop.
+# Calling local function bar_local doe snot need a nop.
 .global _start
 _start:
-  bl bar
+  bl foo
+  nop
+  bl bar_local
+
+
+// CHECK: Disassembly of section .text:
+// CHECK: _start:
+// CHECK:     1001001c: {{.*}}  bl .+67108836
+// CHECK-NOT: 10010020: {{.*}}  nop
+// CHECK:     10010020: {{.*}}  ld 2, 24(1)
+// CHECK:     10010024: {{.*}}  bl .+67108848
+// CHECK-NOT: 10010028: {{.*}}  nop
+// CHECK-NOT: 10010028: {{.*}}  ld 2, 24(1)
+
+# Calling a function in another object file which will have same
+# TOC base does not need a nop. If nop present, do not rewrite to
+# a toc restore
+.global diff_object
+_diff_object:
+  bl foo_not_shared
+  bl foo_not_shared
   nop
 
-// CHECK: _start:
-// CHECK: 10010000:       48 00 00 21     bl .+32
-// CHECK-NOT: 10010004:       60 00 00 00     nop
-// CHECK: 10010004:       e8 41 00 28     ld 2, 40(1)
+// CHECK: _diff_object:
+// CHECK-NEXT: 10010028: {{.*}}  bl .+24
+// CHECK-NEXT: 1001002c: {{.*}}  bl .+20
+// CHECK-NEXT: 10010030: {{.*}}  nop
 
-.global noret
-noret:
-  bl bar
-  li 5, 7
-
-// CHECK: noret:
-// CHECK: 10010008: 48 00 00 19 bl .+24
-// CHECK: 1001000c: 38 a0 00 07 li 5, 7
-
-.global noretend
-noretend:
-  bl bar
-
-// CHECK: noretend:
-// CHECK: 10010010: 48 00 00 11 bl .+16
-
-.global noretb
-noretb:
-  b bar
-
-// CHECK: noretb:
-// CHECK: 10010014: 48 00 00 0c b .+12
+# Branching to a local function does not need a nop
+.global noretbranch
+noretbranch:
+  b bar_local
+// CHECK: noretbranch:
+// CHECK:     10010034:  {{.*}}  b .+67108832
+// CHECK-NOT: 10010038:  {{.*}}  nop
+// CHECK-NOT: 1001003c:  {{.*}}  ld 2, 24(1)
 
 // This should come last to check the end-of-buffer condition.
 .global last
 last:
-  bl bar
+  bl foo
   nop
-
 // CHECK: last:
-// CHECK: 10010018: 48 00 00 09 bl .+8
-// CHECK: 1001001c: e8 41 00 28 ld 2, 40(1)
-
-// CHECK: Disassembly of section .plt:
-// CHECK: .plt:
-// CHECK: 10010020:       f8 41 00 28     std 2, 40(1)
-// CHECK: 10010024:       3d 62 10 02     addis 11, 2, 4098
-// CHECK: 10010028:       e9 8b 80 18     ld 12, -32744(11)
-// CHECK: 1001002c:       e9 6c 00 00     ld 11, 0(12)
-// CHECK: 10010030:       7d 69 03 a6     mtctr 11
-// CHECK: 10010034:       e8 4c 00 08     ld 2, 8(12)
-// CHECK: 10010038:       e9 6c 00 10     ld 11, 16(12)
-// CHECK: 1001003c:       4e 80 04 20     bctr
+// CHECK:      10010038: {{.*}}   bl .+67108808
+// CHECK-NEXT: 1001003c: {{.*}}   ld 2, 24(1)
diff --git a/test/ELF/ppc64-weak-undef-call-shared.s b/test/ELF/ppc64-weak-undef-call-shared.s
index 2c27a27..db48247 100644
--- a/test/ELF/ppc64-weak-undef-call-shared.s
+++ b/test/ELF/ppc64-weak-undef-call-shared.s
@@ -1,7 +1,12 @@
+# REQUIRES: ppc
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+# RUN: ld.lld -shared %t.o -o %t.so
+# RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
+
 # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
 # RUN: ld.lld -shared %t.o -o %t.so
 # RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
-# REQUIRES: ppc
 
 .section        ".toc","aw"
 .quad weakfunc
@@ -10,7 +15,7 @@
 .text
 .Lfoo:
   bl weakfunc
+  nop
 // CHECK-NOT: R_PPC64_REL24
 
 .weak weakfunc
-
diff --git a/test/ELF/ppc64-weak-undef-call.s b/test/ELF/ppc64-weak-undef-call.s
index 55443cb..30c1686 100644
--- a/test/ELF/ppc64-weak-undef-call.s
+++ b/test/ELF/ppc64-weak-undef-call.s
@@ -1,17 +1,18 @@
+# REQUIRES: ppc
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t
+# RUN: ld.lld %t -o %t2
+# RUN: llvm-objdump -d %t2 | FileCheck %s
+
 # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
 # RUN: ld.lld %t -o %t2
 # RUN: llvm-objdump -d %t2 | FileCheck %s
-# REQUIRES: ppc
 
 # CHECK: Disassembly of section .text:
 
-.section        ".opd","aw"
+.text
 .global _start
 _start:
-.quad   .Lfoo,.TOC.@tocbase,0
-
-.text
-.Lfoo:
   bl weakfunc
   nop
   blr
@@ -22,6 +23,6 @@
 # be unreachable. But, we should link successfully. We should not, however,
 # generate a .plt entry (this would be wasted space). For now, we do nothing
 # (leaving the zero relative offset present in the input).
-# CHECK: 10010000:       48 00 00 01     bl .+0
-# CHECK: 10010004:       60 00 00 00     nop
-# CHECK: 10010008:       4e 80 00 20     blr
+# CHECK: 10010000:       {{.*}}     bl .+0
+# CHECK: 10010004:       {{.*}}     nop
+# CHECK: 10010008:       {{.*}}     blr
diff --git a/test/ELF/ppc64_entry_point.s b/test/ELF/ppc64_entry_point.s
index b3bd5ec..a6f426c 100644
--- a/test/ELF/ppc64_entry_point.s
+++ b/test/ELF/ppc64_entry_point.s
@@ -1,8 +1,13 @@
 # REQUIRES: ppc
+
 # RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t
 # RUN: ld.lld %t -o %t2
 # RUN: llvm-objdump -D %t2 | FileCheck %s
 
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
+# RUN: ld.lld %t -o %t2
+# RUN: llvm-objdump -D %t2 | FileCheck -check-prefix=CHECK-BE %s
+
 .text
 .abiversion 2
 .globl  _start
@@ -27,10 +32,19 @@
 .Lfunc_end0:
     .size   _start, .Lfunc_end0-.Lfunc_begin0
 
-// CHECK: 10010000:       01 10 80 3c     lis 4, 4097
-// CHECK-NEXT: 10010004:       00 00 84 38     addi 4, 4, 0
-// CHECK-NEXT: 10010008:       02 00 a0 3c     lis 5, 2
-// CHECK-NEXT: 1001000c:       00 80 a5 38     addi 5, 5, -32768
+// CHECK: 10010000:       {{.*}}     lis 4, 4097
+// CHECK-NEXT: 10010004:       {{.*}}     addi 4, 4, 0
+// CHECK-NEXT: 10010008:       {{.*}}     lis 5, 2
+// CHECK-NEXT: 1001000c:       {{.*}}     addi 5, 5, -32768
 // CHECK: Disassembly of section .got:
 // CHECK-NEXT: .got:
 // CHECK-NEXT: 10020000:       00 80 02 10
+
+// CHECK-BE: 10010000:       {{.*}}     lis 4, 4097
+// CHECK-BE-NEXT: 10010004:       {{.*}}     addi 4, 4, 0
+// CHECK-BE-NEXT: 10010008:       {{.*}}     lis 5, 2
+// CHECK-BE-NEXT: 1001000c:       {{.*}}     addi 5, 5, -32768
+// CHECK-BE: Disassembly of section .got:
+// CHECK-BE-NEXT: .got:
+// CHECK-BE-NEXT: 10020000:       00 00 00 00 {{.*}}
+// CHECK-BE-NEXT: 10020004:       10 02 80 00 {{.*}}
diff --git a/test/ELF/pre_init_fini_array_missing.s b/test/ELF/pre_init_fini_array_missing.s
index 7dabfa7..4a6b612 100644
--- a/test/ELF/pre_init_fini_array_missing.s
+++ b/test/ELF/pre_init_fini_array_missing.s
@@ -14,30 +14,27 @@
   call __fini_array_start
   call __fini_array_end
 
-// With no .init_array section the symbols resolve to 0
-// 0 - (0x201000 + 5) = -2101253
-// 0 - (0x201005 + 5) = -2101258
-// 0 - (0x20100a + 5) = -2101263
-// 0 - (0x20100f + 5) = -2101268
-// 0 - (0x201014 + 5) = -2101273
-// 0 - (0x201019 + 5) = -2101278
+// With no .init_array section the symbols resolve to .text.
+// 0x201000 - (0x201000 + 5) = -5
+// 0x201000 - (0x201005 + 5) = -10
+// ...
 
 // CHECK: Disassembly of section .text:
 // CHECK-NEXT:  _start:
-// CHECK-NEXT:   201000:    e8 fb ef df ff     callq    -2101253
-// CHECK-NEXT:   201005:    e8 f6 ef df ff     callq    -2101258
-// CHECK-NEXT:   20100a:    e8 f1 ef df ff     callq    -2101263
-// CHECK-NEXT:   20100f:    e8 ec ef df ff     callq    -2101268
-// CHECK-NEXT:   201014:    e8 e7 ef df ff     callq    -2101273
-// CHECK-NEXT:   201019:    e8 e2 ef df ff     callq    -2101278
+// CHECK-NEXT:   201000:    e8 fb ff ff ff     callq    -5
+// CHECK-NEXT:   201005:    e8 f6 ff ff ff     callq    -10
+// CHECK-NEXT:   20100a:    e8 f1 ff ff ff     callq    -15
+// CHECK-NEXT:   20100f:    e8 ec ff ff ff     callq    -20
+// CHECK-NEXT:   201014:    e8 e7 ff ff ff     callq    -25
+// CHECK-NEXT:   201019:    e8 e2 ff ff ff     callq    -30
 
-// In position-independent binaries, they resolve to the image base.
+// In position-independent binaries, they resolve to .text too.
 
 // PIE:      Disassembly of section .text:
 // PIE-NEXT: _start:
-// PIE-NEXT:     1000:	e8 fb ef ff ff 	callq	-4101
-// PIE-NEXT:     1005:	e8 f6 ef ff ff 	callq	-4106
-// PIE-NEXT:     100a:	e8 f1 ef ff ff 	callq	-4111
-// PIE-NEXT:     100f:	e8 ec ef ff ff 	callq	-4116
-// PIE-NEXT:     1014:	e8 e7 ef ff ff 	callq	-4121
-// PIE-NEXT:     1019:	e8 e2 ef ff ff 	callq	-4126
+// PIE-NEXT:     1000:  e8 fb ff ff ff  callq   -5
+// PIE-NEXT:     1005:  e8 f6 ff ff ff  callq   -10
+// PIE-NEXT:     100a:  e8 f1 ff ff ff  callq   -15
+// PIE-NEXT:     100f:  e8 ec ff ff ff  callq   -20
+// PIE-NEXT:     1014:  e8 e7 ff ff ff  callq   -25
+// PIE-NEXT:     1019:  e8 e2 ff ff ff  callq   -30
diff --git a/test/ELF/push-state.s b/test/ELF/push-state.s
new file mode 100644
index 0000000..5a01cd2
--- /dev/null
+++ b/test/ELF/push-state.s
@@ -0,0 +1,36 @@
+// REQUIRES: x86
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
+// RUN:   %p/Inputs/whole-archive.s -o %t2.o
+// RUN: rm -f %t.a
+// RUN: llvm-ar rcs %t.a %t2.o
+
+// RUN: ld.lld -o %t.exe -push-state -whole-archive %t.a %t1.o -M | \
+// RUN:   FileCheck -check-prefix=WHOLE %s
+// WHOLE: _bar
+
+// RUN: ld.lld -o %t.exe -push-state -whole-archive -pop-state %t.a %t1.o -M | \
+// RUN:   FileCheck -check-prefix=NO-WHOLE %s
+// NO-WHOLE-NOT: _bar
+
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t3.o
+// RUN: ld.lld -shared %t3.o -soname libfoo -o %t.so
+
+// RUN: ld.lld -o %t.exe -push-state -as-needed %t.so %t1.o
+// RUN: llvm-readobj -dynamic-table %t.exe | FileCheck -check-prefix=AS-NEEDED %s
+// AS-NEEDED-NOT: NEEDED Shared library: [libfoo]
+
+// RUN: ld.lld -o %t.exe -push-state -as-needed -pop-state %t.so %t1.o
+// RUN: llvm-readobj -dynamic-table %t.exe | FileCheck -check-prefix=NO-AS-NEEDED %s
+// NO-AS-NEEDED: NEEDED Shared library: [libfoo]
+
+
+// RUN: mkdir -p %t.dir
+// RUN: cp %t.so %t.dir/libfoo.so
+// RUN: ld.lld -o %t.exe -L%t.dir -push-state -static -pop-state  %t1.o -lfoo
+// RUN: not ld.lld -o %t.exe -L%t.dir -push-state -static %t1.o -lfoo
+
+.globl _start
+_start:
diff --git a/test/ELF/relative-dynamic-reloc-ppc64.s b/test/ELF/relative-dynamic-reloc-ppc64.s
index 65d0e8e..99c2457 100644
--- a/test/ELF/relative-dynamic-reloc-ppc64.s
+++ b/test/ELF/relative-dynamic-reloc-ppc64.s
@@ -1,6 +1,11 @@
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+// RUN: ld.lld -shared %t.o -o %t.so
+// RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
+
 // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
 // RUN: ld.lld -shared %t.o -o %t.so
 // RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
+
 // REQUIRES: ppc
 
 // Test that we create R_PPC64_RELATIVE relocations but don't put any
diff --git a/test/ELF/relocatable-comdat-multiple.s b/test/ELF/relocatable-comdat-multiple.s
index 935fbdc..bb7a784 100644
--- a/test/ELF/relocatable-comdat-multiple.s
+++ b/test/ELF/relocatable-comdat-multiple.s
@@ -21,7 +21,7 @@
 # CHECK-NEXT:     Name: .group
 # CHECK-NEXT:     Index: 5
 # CHECK-NEXT:     Link: 8
-# CHECK-NEXT:     Info: 2
+# CHECK-NEXT:     Info: 6
 # CHECK-NEXT:     Type: COMDAT
 # CHECK-NEXT:     Signature: bbb
 # CHECK-NEXT:     Section(s) in group [
diff --git a/test/ELF/relocatable-eh-frame.s b/test/ELF/relocatable-eh-frame.s
index c2e5ec6..dee906a 100644
--- a/test/ELF/relocatable-eh-frame.s
+++ b/test/ELF/relocatable-eh-frame.s
@@ -5,7 +5,7 @@
 # RUN: ld.lld %t -o %t.so -shared
 # RUN: llvm-objdump -h %t.so | FileCheck --check-prefix=DSO %s
 
-# DSO: .eh_frame     00000030
+# DSO: .eh_frame     00000034
 
 # CHECK:      Relocations [
 # CHECK-NEXT:   Section ({{.*}}) .rela.eh_frame {
diff --git a/test/ELF/relocation-shared.s b/test/ELF/relocation-shared.s
index 4fba7a5..730395a 100644
--- a/test/ELF/relocation-shared.s
+++ b/test/ELF/relocation-shared.s
@@ -8,7 +8,7 @@
 // CHECK-NEXT: Flags [
 // CHECK-NEXT:   SHF_ALLOC
 // CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x1C8
+// CHECK-NEXT: Address: 0x1E1
 // CHECK-NEXT: Offset:
 // CHECK-NEXT: Size: 8
 // CHECK-NEXT: Link: 0
@@ -16,8 +16,8 @@
 // CHECK-NEXT: AddressAlignment: 1
 // CHECK-NEXT: EntrySize: 0
 // CHECK-NEXT: SectionData (
-// CHECK-NEXT:   0000: 380E0000 00000000
-//                     0x1000 - 0x1C8 = 0xE38
+// CHECK-NEXT:   0000: 1F0E0000 00000000
+//                     0x1000 - 0x1E1 = 0xE1F
 // CHECK-NEXT: )
 
 // CHECK:      Name: .text
diff --git a/test/ELF/relocation.s b/test/ELF/relocation.s
index 3359a8b..8205728 100644
--- a/test/ELF/relocation.s
+++ b/test/ELF/relocation.s
@@ -1,6 +1,6 @@
 // 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/shared.s -o %t2
-// RUN: ld.lld %t2 -o %t2.so -shared
+// RUN: ld.lld %t2 -soname fixed-length-string.so -o %t2.so -shared
 // RUN: ld.lld --hash-style=sysv %t %t2.so -o %t3
 // RUN: llvm-readobj -s  %t3 | FileCheck --check-prefix=SEC %s
 // RUN: llvm-objdump -s -d %t3 | FileCheck %s
@@ -113,17 +113,16 @@
  .quad R_X86_64_64
 
 // CHECK:      Contents of section .R_X86_64_64:
-// CHECK-NEXT:   2001c8 c8012000 00000000
+// CHECK-NEXT:   20024d 4d022000 00000000
 
 .section .R_X86_64_GOTPCREL,"a",@progbits
 .global R_X86_64_GOTPCREL
 R_X86_64_GOTPCREL:
  .long zed@gotpcrel
 
-// 0x2020F8 - 0x2001D8 = 7952
-// 7952 = 0x101f0000 in little endian
+// 0x2020F0(.got) - 0x200255(.R_X86_64_GOTPCREL) = 0x2e9b
 // CHECK:      Contents of section .R_X86_64_GOTPCREL
-// CHECK-NEXT:   2001d0 202f0000
+// CHECK-NEXT:   200255 9b2e0000
 
 .section .R_X86_64_GOT32,"a",@progbits
 .global R_X86_64_GOT32
diff --git a/test/ELF/relro-omagic.s b/test/ELF/relro-omagic.s
index 97c3a81..3eac082 100644
--- a/test/ELF/relro-omagic.s
+++ b/test/ELF/relro-omagic.s
@@ -9,8 +9,8 @@
 # NORELRO-NEXT: Idx Name          Size      Address          Type
 # NORELRO-NEXT:   0               00000000 0000000000000000
 # NORELRO-NEXT:   1 .dynsym       00000048 0000000000200120
-# NORELRO-NEXT:   2 .hash         00000020 0000000000200168
-# NORELRO-NEXT:   3 .dynstr       00000021 0000000000200188
+# NORELRO-NEXT:   2 .dynstr       00000021 0000000000200168
+# NORELRO-NEXT:   3 .hash         00000020 000000000020018c
 # NORELRO-NEXT:   4 .rela.dyn     00000018 00000000002001b0
 # NORELRO-NEXT:   5 .rela.plt     00000018 00000000002001c8
 # NORELRO-NEXT:   6 .text         0000000a 00000000002001e0 TEXT DATA
diff --git a/test/ELF/relro.s b/test/ELF/relro.s
index b21e514..0f72131 100644
--- a/test/ELF/relro.s
+++ b/test/ELF/relro.s
@@ -1,13 +1,17 @@
+// REQUIRES: x86
+
 // 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/shared.s -o %t2.o
 // RUN: ld.lld -shared %t2.o -o %t2.so
-// RUN: ld.lld %t.o %t2.so -z now -z relro -o %t
+
+// RUN: ld.lld %t.o %t2.so -z now -z norelro -z relro -o %t
 // RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=CHECK --check-prefix=FULLRELRO %s
-// RUN: ld.lld %t.o %t2.so -z relro -o %t
+
+// RUN: ld.lld %t.o %t2.so -z norelro -z relro -o %t
 // RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=CHECK --check-prefix=PARTRELRO %s
+
 // RUN: ld.lld %t.o %t2.so -z norelro -o %t
 // RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=NORELRO %s
-// REQUIRES: x86
 
 // CHECK:      Program Headers:
 // CHECK-NEXT: Type
diff --git a/test/ELF/reproduce-backslash.s b/test/ELF/reproduce-backslash.s
index 40b9dd8..7a9964d 100644
--- a/test/ELF/reproduce-backslash.s
+++ b/test/ELF/reproduce-backslash.s
@@ -3,7 +3,7 @@
 # Test that we don't erroneously replace \ with / on UNIX, as it's
 # legal for a filename to contain backslashes.
 # RUN: llvm-mc %s -o %T/foo\\.o -filetype=obj -triple=x86_64-pc-linux
-# RUN: ld.lld %T/foo\\.o --reproduce repro.tar
-# RUN: tar tf repro.tar | FileCheck %s
+# RUN: ld.lld %T/foo\\.o --reproduce %T/repro.tar -o /dev/null
+# RUN: tar tf %T/repro.tar | FileCheck %s
 
 # CHECK: repro/{{.*}}/foo\\.o
diff --git a/test/ELF/shared-be.s b/test/ELF/shared-ppc64.s
similarity index 78%
rename from test/ELF/shared-be.s
rename to test/ELF/shared-ppc64.s
index 0b941d3..f2280a1 100644
--- a/test/ELF/shared-be.s
+++ b/test/ELF/shared-ppc64.s
@@ -1,9 +1,16 @@
+// REQUIRES: ppc
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: ld.lld -dynamic-linker /lib64/ld64.so.1 -rpath foo -rpath bar --export-dynamic %t.o %t2.so -o %t
+// RUN: llvm-readobj --dynamic-table -s %t | FileCheck %s
+
 // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
 // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared.s -o %t2.o
 // RUN: ld.lld -shared %t2.o -o %t2.so
 // RUN: ld.lld -dynamic-linker /lib64/ld64.so.1 -rpath foo -rpath bar --export-dynamic %t.o %t2.so -o %t
 // RUN: llvm-readobj --dynamic-table -s %t | FileCheck %s
-// REQUIRES: ppc
 
 // CHECK:      Name: .rela.dyn
 // CHECK-NEXT: Type: SHT_REL
diff --git a/test/ELF/shared.s b/test/ELF/shared.s
index 65ad2c6..6d4bcd1 100644
--- a/test/ELF/shared.s
+++ b/test/ELF/shared.s
@@ -59,21 +59,6 @@
 // CHECK-NEXT:     0030:
 // CHECK-NEXT:   )
 // CHECK-NEXT: }
-// CHECK-NEXT: Section {
-// CHECK-NEXT:   Index: 3
-// CHECK-NEXT:    Name: .hash
-// CHECK-NEXT:    Type: SHT_HASH
-// CHECK-NEXT:    Flags [
-// CHECK-NEXT:      SHF_ALLOC
-// CHECK-NEXT:    ]
-// CHECK-NEXT:    Address: [[HASHADDR:.*]]
-// CHECK-NEXT:    Offset:
-// CHECK-NEXT:    Size:
-// CHECK-NEXT:    Link: 2
-// CHECK-NEXT:    Info: 0
-// CHECK-NEXT:    AddressAlignment: 4
-// CHECK-NEXT:    EntrySize: 4
-
 // CHECK:        Index: [[DYNSTR]]
 // CHECK-NEXT:   Name: .dynstr
 // CHECK-NEXT:   Type: SHT_STRTAB
@@ -90,6 +75,20 @@
 // CHECK-NEXT:   SectionData (
 // CHECK:        )
 // CHECK-NEXT: }
+// CHECK-NEXT: Section {
+// CHECK-NEXT:   Index: 4
+// CHECK-NEXT:    Name: .hash
+// CHECK-NEXT:    Type: SHT_HASH
+// CHECK-NEXT:    Flags [
+// CHECK-NEXT:      SHF_ALLOC
+// CHECK-NEXT:    ]
+// CHECK-NEXT:    Address: [[HASHADDR:.*]]
+// CHECK-NEXT:    Offset:
+// CHECK-NEXT:    Size:
+// CHECK-NEXT:    Link: 2
+// CHECK-NEXT:    Info: 0
+// CHECK-NEXT:    AddressAlignment: 4
+// CHECK-NEXT:    EntrySize: 4
 
 // CHECK:      Name: .rel.dyn
 // CHECK-NEXT: Type: SHT_REL
diff --git a/test/ELF/sort-norosegment.s b/test/ELF/sort-norosegment.s
index bd74f2e..6d02eee 100644
--- a/test/ELF/sort-norosegment.s
+++ b/test/ELF/sort-norosegment.s
@@ -4,10 +4,10 @@
 # RUN: ld.lld --hash-style=sysv -no-rosegment -o %t1  %t -shared
 # RUN: llvm-readobj -elf-output-style=GNU -s %t1 | FileCheck %s
 
-# CHECK:      .text    {{.*}}   AX
-# CHECK-NEXT: .dynsym  {{.*}}   A
-# CHECK-NEXT: .hash    {{.*}}   A
+# CHECK:      .dynsym  {{.*}}   A
 # CHECK-NEXT: .dynstr  {{.*}}   A
+# CHECK-NEXT: .text    {{.*}}   AX
+# CHECK-NEXT: .hash    {{.*}}   A
 # CHECK-NEXT: foo      {{.*}}  WA
 # CHECK-NEXT: .dynamic {{.*}}  WA
 
diff --git a/test/ELF/start-lib.s b/test/ELF/start-lib.s
index 013a2b2..b79d9ef 100644
--- a/test/ELF/start-lib.s
+++ b/test/ELF/start-lib.s
@@ -21,5 +21,14 @@
 // TEST3-NOT: Name: bar
 // TEST3-NOT: Name: foo
 
+// RUN: not ld.lld %t1.o --start-lib --start-lib 2>&1 | FileCheck -check-prefix=NESTED-LIB %s
+// NESTED-LIB: nested --start-lib
+
+// RUN: not ld.lld %t1.o --start-group --start-lib 2>&1 | FileCheck -check-prefix=LIB-IN-GROUP %s
+// LIB-IN-GROUP: may not nest --start-lib in --start-group
+
+// RUN: not ld.lld --end-lib 2>&1 | FileCheck -check-prefix=END %s
+// END: stray --end-lib
+
 .globl _start
 _start:
diff --git a/test/ELF/symbol-ordering-file-warnings.s b/test/ELF/symbol-ordering-file-warnings.s
index aabac53..71414bf 100644
--- a/test/ELF/symbol-ordering-file-warnings.s
+++ b/test/ELF/symbol-ordering-file-warnings.s
@@ -39,11 +39,15 @@
 # RUN: ld.lld %t1.o -o %t --symbol-ordering-file %t-order-gc.txt --gc-sections \
 # RUN:   --unresolved-symbols=ignore-all 2>&1 | FileCheck %s --check-prefixes=WARN,GC
 
-# Check that a warning is emitted for the symbol removed due to --icf.
+# Check that a warning is not emitted for the symbol removed due to --icf.
 # RUN: echo "icf1" > %t-order-icf.txt
 # RUN: echo "icf2" >> %t-order-icf.txt
 # RUN: ld.lld %t1.o -o %t --symbol-ordering-file %t-order-icf.txt --icf=all \
-# RUN:   --unresolved-symbols=ignore-all 2>&1 | FileCheck %s --check-prefixes=WARN,ICF
+# RUN:   --unresolved-symbols=ignore-all --fatal-warnings
+
+# RUN: echo "_GLOBAL_OFFSET_TABLE_" > %t-order-synthetic.txt
+# RUN: ld.lld %t1.o -o %t --symbol-ordering-file %t-order-synthetic.txt --icf=all \
+# RUN:   --unresolved-symbols=ignore-all 2>&1 | FileCheck %s --check-prefixes=WARN,SYNTHETIC
 
 # Check that a warning is emitted for symbols discarded due to a linker script /DISCARD/ section.
 # RUN: echo "discard" > %t-order-discard.txt
@@ -90,30 +94,31 @@
 # RUN: echo "absolute" >> %t-order-multi.txt
 # RUN: echo "gc" >> %t-order-multi.txt
 # RUN: echo "discard" >> %t-order-multi.txt
+# RUN: echo "_GLOBAL_OFFSET_TABLE_" >> %t-order-multi.txt
 # RUN: echo "_start" >> %t-order-multi.txt
 # RUN: ld.lld %t1.o %t3.o %t.so -o %t --symbol-ordering-file %t-order-multi.txt --gc-sections -T %t.script \
-# RUN:   --unresolved-symbols=ignore-all 2>&1 | FileCheck %s --check-prefixes=WARN,SAMESYM,ABSOLUTE,SHARED,UNDEFINED,GC,DISCARD,MISSING2
+# RUN:   --unresolved-symbols=ignore-all 2>&1 | FileCheck %s --check-prefixes=WARN,SAMESYM,ABSOLUTE,SHARED,UNDEFINED,GC,DISCARD,MISSING2,SYNTHETIC
 
 # WARN-NOT:    warning:
 # SAMESYM:     warning: {{.*}}.txt: duplicate ordered symbol: _start
 # WARN-NOT:    warning:
-# ABSOLUTE:    warning: {{.*}}1.o: unable to order absolute symbol: absolute
+# SYNTHETIC:   warning: <internal>: unable to order synthetic symbol: _GLOBAL_OFFSET_TABLE_
 # WARN-NOT:    warning:
 # DISCARD:     warning: {{.*}}1.o: unable to order discarded symbol: discard
 # WARN-NOT:    warning:
 # GC:          warning: {{.*}}1.o: unable to order discarded symbol: gc
 # WARN-NOT:    warning:
-# SHARED:      warning: {{.*}}1.o: unable to order shared symbol: shared
+# SHARED:      warning: {{.*}}.so: unable to order shared symbol: shared
 # WARN-NOT:    warning:
 # UNDEFINED:   warning: {{.*}}3.o: unable to order undefined symbol: undefined
 # WARN-NOT:    warning:
+# ABSOLUTE:    warning: {{.*}}1.o: unable to order absolute symbol: absolute
+# WARN-NOT:    warning:
 # MISSING:     warning: symbol ordering file: no such symbol: missing
 # MISSING2:    warning: symbol ordering file: no such symbol: missing_sym
-# ICF:         warning: {{.*}}1.o: unable to order discarded symbol: icf2
 # COMDAT:      warning: {{.*}}1.o: unable to order discarded symbol: comdat
-# COMDAT-NEXT: warning: {{.*}}2.o: unable to order discarded symbol: comdat
-# MULTI:       warning: {{.*}}2.o: unable to order absolute symbol: multi
-# MULTI-NEXT:  warning: {{.*}}3.o: unable to order undefined symbol: multi
+# MULTI:       warning: {{.*}}3.o: unable to order undefined symbol: multi
+# MULTI-NEXT:  warning: {{.*}}2.o: unable to order absolute symbol: multi
 # WARN-NOT:    warning:
 
 absolute = 0x1234
@@ -157,4 +162,4 @@
 # This is a "good" instance of the symbol
 .section .text.multi,"ax",@progbits
 multi:
-  nop
+  .quad _GLOBAL_OFFSET_TABLE_
diff --git a/test/ELF/synthetic-got.s b/test/ELF/synthetic-got.s
index 375a438..8bc7fc5 100644
--- a/test/ELF/synthetic-got.s
+++ b/test/ELF/synthetic-got.s
@@ -7,13 +7,13 @@
 # RUN:   | FileCheck %s --check-prefix=GOTDATA
 
 # GOT:     Sections:
-# GOT:      8  .got.plt     00000020 00000000000000e0 DATA
-# GOT:      10 .got         00000008 00000000000001d0 DATA
+# GOT:      8  .got.plt     00000020 00000000000000d0 DATA
+# GOT:      10 .got         00000008 00000000000001c0 DATA
 # GOTDATA:     Contents of section .got.plt:
-# GOTDATA-NEXT:  00e0 00010000 00000000 00000000 00000000
-# GOTDATA-NEXT:  00f0 00000000 00000000 d6000000 00000000
+# GOTDATA-NEXT:  00d0 f0000000 00000000 00000000 00000000
+# GOTDATA-NEXT:  00e0 00000000 00000000 c6000000 00000000
 # GOTDATA-NEXT: Contents of section .got:
-# GOTDATA-NEXT:  01d0 00000000 00000000
+# GOTDATA-NEXT:  01c0 00000000 00000000
 
 # RUN: echo "SECTIONS { .mygot : { *(.got) *(.got.plt) } }" > %t1.script
 # RUN: ld.lld --hash-style=sysv -shared %t.o -o %t1.out --script %t1.script
@@ -21,12 +21,12 @@
 # RUN: llvm-objdump -s -section=.mygot %t1.out | FileCheck %s --check-prefix=MYGOTDATA
 
 # MYGOT:     Sections:
-# MYGOT:      8  .mygot     00000028 00000000000000e0 DATA
+# MYGOT:      8  .mygot     00000028 00000000000000d0 DATA
 # MYGOT-NOT:  .got
 # MYGOT-NOT:  .got.plt
-# MYGOTDATA:      00e0 00000000 00000000 08010000 00000000
-# MYGOTDATA-NEXT: 00f0 00000000 00000000 00000000 00000000
-# MYGOTDATA-NEXT: 0100 d6000000 00000000
+# MYGOTDATA:      00d0 00000000 00000000 f8000000 00000000
+# MYGOTDATA-NEXT: 00e0 00000000 00000000 00000000 00000000
+# MYGOTDATA-NEXT: 00f0 c6000000 00000000
 
 mov bar@gotpcrel(%rip), %rax
 call foo@plt
diff --git a/test/ELF/text-section-prefix.s b/test/ELF/text-section-prefix.s
new file mode 100644
index 0000000..b9e9a60
--- /dev/null
+++ b/test/ELF/text-section-prefix.s
@@ -0,0 +1,38 @@
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld -z keep-text-section-prefix %t -o %t2
+# RUN: llvm-readelf -l %t2 | FileCheck %s
+# RUN: ld.lld %t -o %t3
+# RUN: llvm-readelf -l %t3 | FileCheck --check-prefix=CHECKNO %s
+# RUN: ld.lld -z nokeep-text-section-prefix %t -o %t4
+# RUN: llvm-readelf -l %t4 | FileCheck --check-prefix=CHECKNO %s
+
+# CHECK: .text
+# CHECK: .text.hot
+# CHECK: .text.startup
+# CHECK: .text.exit
+# CHECK: .text.unlikely
+# CHECKNO: .text
+# CHECKNO-NOT: .text.hot
+
+_start:
+  ret
+
+.section .text.f,"ax"
+f:
+  nop
+
+.section .text.hot.f_hot,"ax"
+f_hot:
+  nop
+
+.section .text.startup.f_startup,"ax"
+f_startup:
+  nop
+
+.section .text.exit.f_exit,"ax"
+f_exit:
+  nop
+
+.section .text.unlikely.f_unlikely,"ax"
+f_unlikely:
+  nop
diff --git a/test/ELF/undef-start.s b/test/ELF/undef-start.s
index 590d0a8..d0e0147 100644
--- a/test/ELF/undef-start.s
+++ b/test/ELF/undef-start.s
@@ -1,3 +1,5 @@
-# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
-# RUN: ld.lld %t -o %t2 2>&1
 # REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t 2>&1 | FileCheck %s
+
+# CHECK: warning: cannot find entry symbol _start
diff --git a/test/ELF/undef.s b/test/ELF/undef.s
index aabcbbc..07e3b68 100644
--- a/test/ELF/undef.s
+++ b/test/ELF/undef.s
@@ -34,9 +34,19 @@
 # CHECK: >>> referenced by undef-debug.s:11 (dir{{/|\\}}undef-debug.s:11)
 # CHECK: >>>               {{.*}}.o:(.text.2+0x0)
 
+# Show that all line table problems are mentioned as soon as the object's line information
+# is requested, even if that particular part of the line information is not currently required.
+# CHECK: warning: parsing line table prologue at 0x00000000 should have ended at 0x00000038 but it ended at 0x00000037
+# CHECK: warning: last sequence in debug line table is not terminated!
 # CHECK: error: undefined symbol: zed6
 # CHECK: >>> referenced by {{.*}}tmp4.o:(.text+0x0)
 
+# Show that a problem with one line table's information doesn't affect getting information from
+# a different one in the same object.
+# CHECK: error: undefined symbol: zed7
+# CHECK: >>> referenced by undef-bad-debug2.s:11 (dir2{{/|\\}}undef-bad-debug2.s:11)
+# CHECK: >>>               {{.*}}tmp4.o:(.text+0x8)
+
 # RUN: not ld.lld %t.o %t2.a -o %t.exe -no-demangle 2>&1 | \
 # RUN:   FileCheck -check-prefix=NO-DEMANGLE %s
 # NO-DEMANGLE: error: undefined symbol: _Z3fooi
diff --git a/test/ELF/verdef-defaultver.s b/test/ELF/verdef-defaultver.s
index c8444c4..4f01f17 100644
--- a/test/ELF/verdef-defaultver.s
+++ b/test/ELF/verdef-defaultver.s
@@ -55,8 +55,8 @@
 # DSO-NEXT:  ]
 # DSO-NEXT:  Version symbols {
 # DSO-NEXT:    Section Name: .gnu.version
-# DSO-NEXT:    Address: 0x240
-# DSO-NEXT:    Offset: 0x240
+# DSO-NEXT:    Address: 0x256
+# DSO-NEXT:    Offset: 0x256
 # DSO-NEXT:    Link: 1
 # DSO-NEXT:    Symbols [
 # DSO-NEXT:      Symbol {
@@ -150,8 +150,8 @@
 # EXE-NEXT:  ]
 # EXE-NEXT:  Version symbols {
 # EXE-NEXT:    Section Name: .gnu.version
-# EXE-NEXT:    Address: 0x200228
-# EXE-NEXT:    Offset: 0x228
+# EXE-NEXT:    Address: 0x20023C
+# EXE-NEXT:    Offset: 0x23C
 # EXE-NEXT:    Link: 1
 # EXE-NEXT:    Symbols [
 # EXE-NEXT:      Symbol {
diff --git a/test/ELF/verdef.s b/test/ELF/verdef.s
index b5d12ee..af7c2ad 100644
--- a/test/ELF/verdef.s
+++ b/test/ELF/verdef.s
@@ -8,8 +8,8 @@
 
 # DSO:        Version symbols {
 # DSO-NEXT:   Section Name: .gnu.version
-# DSO-NEXT:   Address: 0x228
-# DSO-NEXT:   Offset: 0x228
+# DSO-NEXT:   Address: 0x260
+# DSO-NEXT:   Offset: 0x260
 # DSO-NEXT:   Link: 1
 # DSO-NEXT:   Symbols [
 # DSO-NEXT:     Symbol {
@@ -70,8 +70,8 @@
 
 # MAIN:      Version symbols {
 # MAIN-NEXT:   Section Name: .gnu.version
-# MAIN-NEXT:   Address: 0x200228
-# MAIN-NEXT:   Offset: 0x228
+# MAIN-NEXT:   Address: 0x200260
+# MAIN-NEXT:   Offset: 0x260
 # MAIN-NEXT:   Link: 1
 # MAIN-NEXT:   Symbols [
 # MAIN-NEXT:     Symbol {
diff --git a/test/ELF/verneed.s b/test/ELF/verneed.s
index 27ab047..3c92336 100644
--- a/test/ELF/verneed.s
+++ b/test/ELF/verneed.s
@@ -10,67 +10,70 @@
 # RUN: llvm-readobj -V -sections -section-data -dyn-symbols -dynamic-table %t | FileCheck %s
 
 # CHECK:        Section {
-# CHECK:         Index: 1
-# CHECK-NEXT:    Name: .dynsym
-# CHECK-NEXT:    Type: SHT_DYNSYM (0xB)
+# CHECK:          Index: 1
+# CHECK-NEXT:     Name: .dynsym
+# CHECK-NEXT:     Type: SHT_DYNSYM (0xB)
+# CHECK-NEXT:     Flags [ (0x2)
+# CHECK-NEXT:       SHF_ALLOC (0x2)
+# CHECK-NEXT:     ]
+# CHECK-NEXT:     Address: 0x2001C8
+# CHECK-NEXT:     Offset: 0x1C8
+# CHECK-NEXT:     Size: 96
+# CHECK-NEXT:     Link: 2
+# CHECK-NEXT:     Info: 1
+# CHECK-NEXT:     AddressAlignment: 8
+# CHECK-NEXT:     EntrySize: 24
+
+# CHECK:        Section {
+# CHECK-NEXT:     Index: 2
+# CHECK-NEXT:     Name: .dynstr
+# CHECK-NEXT:     Type: SHT_STRTAB (0x3)
+# CHECK-NEXT:     Flags [ (0x2)
+# CHECK-NEXT:       SHF_ALLOC (0x2)
+# CHECK-NEXT:     ]
+# CHECK-NEXT:     Address: 0x200228
+# CHECK-NEXT:     Offset: 0x228
+# CHECK-NEXT:     Size: 47
+# CHECK-NEXT:     Link: 0
+# CHECK-NEXT:     Info: 0
+# CHECK-NEXT:     AddressAlignment: 1
+# CHECK-NEXT:     EntrySize: 0
+# CHECK-NEXT:     SectionData (
+# CHECK-NEXT:       0000: 00766572 6E656564 312E736F 2E300076  |.verneed1.so.0.v|
+# CHECK-NEXT:       0010: 65726E65 6564322E 736F2E30 00663100  |erneed2.so.0.f1.|
+# CHECK-NEXT:       0020: 76330066 32007632 00673100 763100    |v3.f2.v2.g1.v1.|
+# CHECK-NEXT:     )
+# CHECK-NEXT:   }
+
+# CHECK:       Section {
+# CHECK-NEXT:    Index: 3
+# CHECK-NEXT:    Name: .gnu.version
+# CHECK-NEXT:    Type: SHT_GNU_versym (0x6FFFFFFF)
 # CHECK-NEXT:    Flags [ (0x2)
 # CHECK-NEXT:      SHF_ALLOC (0x2)
 # CHECK-NEXT:    ]
-# CHECK-NEXT:    Address: 0x2001C8
-# CHECK-NEXT:    Offset: 0x1C8
-# CHECK-NEXT:    Size: 96
-# CHECK-NEXT:    Link: 5
-# CHECK-NEXT:    Info: 1
-# CHECK-NEXT:    AddressAlignment: 8
-# CHECK-NEXT:    EntrySize: 24
+# CHECK-NEXT:    Address: 0x200258
+# CHECK-NEXT:    Offset: 0x258
+# CHECK-NEXT:    Size: 8
+# CHECK-NEXT:    Link: 1
+# CHECK-NEXT:    Info: 0
+# CHECK-NEXT:    AddressAlignment: 2
+# CHECK-NEXT:    EntrySize: 2
+
 # CHECK:       Section {
-# CHECK-NEXT:   Index: 2
-# CHECK-NEXT:   Name: .gnu.version
-# CHECK-NEXT:   Type: SHT_GNU_versym (0x6FFFFFFF)
-# CHECK-NEXT:   Flags [ (0x2)
-# CHECK-NEXT:     SHF_ALLOC (0x2)
-# CHECK-NEXT:   ]
-# CHECK-NEXT:   Address: 0x200228
-# CHECK-NEXT:   Offset: 0x228
-# CHECK-NEXT:   Size: 8
-# CHECK-NEXT:   Link: 1
-# CHECK-NEXT:   Info: 0
-# CHECK-NEXT:   AddressAlignment: 2
-# CHECK-NEXT:   EntrySize: 2
-# CHECK:       Section {
-# CHECK-NEXT:   Index: 3
-# CHECK-NEXT:   Name: .gnu.version_r
-# CHECK-NEXT:   Type: SHT_GNU_verneed (0x6FFFFFFE)
-# CHECK-NEXT:   Flags [ (0x2)
-# CHECK-NEXT:     SHF_ALLOC (0x2)
-# CHECK-NEXT:   ]
-# CHECK-NEXT:   Address: 0x200230
-# CHECK-NEXT:   Offset: 0x230
-# CHECK-NEXT:   Size: 80
-# CHECK-NEXT:   Link: 5
-# CHECK-NEXT:   Info: 2
-# CHECK-NEXT:   AddressAlignment: 4
-# CHECK-NEXT:   EntrySize: 0
-# CHECK:      Section {
-# CHECK:        Index: 5
-# CHECK-NEXT:   Name: .dynstr
-# CHECK-NEXT:   Type: SHT_STRTAB
-# CHECK-NEXT:   Flags [ (0x2)
-# CHECK-NEXT:     SHF_ALLOC (0x2)
-# CHECK-NEXT:   ]
-# CHECK-NEXT:   Address: 0x2002A8
-# CHECK-NEXT:   Offset: 0x2A8
-# CHECK-NEXT:   Size: 47
-# CHECK-NEXT:   Link: 0
-# CHECK-NEXT:   Info: 0
-# CHECK-NEXT:   AddressAlignment: 1
-# CHECK-NEXT:   EntrySize: 0
-# CHECK-NEXT:   SectionData (
-# CHECK-NEXT:     0000: 00766572 6E656564 312E736F 2E300076  |.verneed1.so.0.v|
-# CHECK-NEXT:     0010: 65726E65 6564322E 736F2E30 00663100  |erneed2.so.0.f1.|
-# CHECK-NEXT:     0020: 76330066 32007632 00673100 763100    |v3.f2.v2.g1.v1.|
-# CHECK-NEXT:   )
-# CHECK-NEXT: }
+# CHECK-NEXT:    Index: 4
+# CHECK-NEXT:    Name: .gnu.version_r
+# CHECK-NEXT:    Type: SHT_GNU_verneed (0x6FFFFFFE)
+# CHECK-NEXT:    Flags [ (0x2)
+# CHECK-NEXT:      SHF_ALLOC (0x2)
+# CHECK-NEXT:    ]
+# CHECK-NEXT:    Address: 0x200260
+# CHECK-NEXT:    Offset: 0x260
+# CHECK-NEXT:    Size: 80
+# CHECK-NEXT:    Link: 2
+# CHECK-NEXT:    Info: 2
+# CHECK-NEXT:    AddressAlignment: 4
+# CHECK-NEXT:    EntrySize: 0
 
 # CHECK:      DynamicSymbols [
 # CHECK-NEXT:   Symbol {
@@ -111,14 +114,14 @@
 # CHECK-NEXT:   }
 # CHECK-NEXT: ]
 
-# CHECK:      0x000000006FFFFFF0 VERSYM               0x200228
-# CHECK-NEXT: 0x000000006FFFFFFE VERNEED              0x200230
+# CHECK:      0x000000006FFFFFF0 VERSYM               0x200258
+# CHECK-NEXT: 0x000000006FFFFFFE VERNEED              0x200260
 # CHECK-NEXT: 0x000000006FFFFFFF VERNEEDNUM           2
 
 # CHECK:      Version symbols {
 # CHECK-NEXT:    Section Name: .gnu.version
-# CHECK-NEXT:    Address: 0x200228
-# CHECK-NEXT:    Offset: 0x228
+# CHECK-NEXT:    Address: 0x200258
+# CHECK-NEXT:    Offset: 0x258
 # CHECK-NEXT:    Link: 1
 # CHECK-NEXT:    Symbols [
 # CHECK-NEXT:      Symbol {
diff --git a/test/ELF/version-exclude-libs.s b/test/ELF/version-exclude-libs.s
new file mode 100644
index 0000000..7335c23
--- /dev/null
+++ b/test/ELF/version-exclude-libs.s
@@ -0,0 +1,30 @@
+// REQUIRES: x86
+// RUN: llvm-mc %p/Inputs/versiondef.s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: llvm-ar -r %t.a %t.o
+// RUN: llvm-mc %s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld %t2.o %t.a --shared --exclude-libs ALL -o %t.so
+// RUN: llvm-readobj -symbols %t.so | FileCheck %s
+// RUN: llvm-readobj -dyn-symbols %t.so | FileCheck -check-prefix CHECK-DYN %s
+// RUN: not ld.lld %t2.o %t.a --shared -o %t.so 2>&1 | FileCheck -check-prefix=CHECK-ERR %s
+
+// Test that we do not give an error message for undefined versions when the
+// symbol is not exported to the dynamic symbol table.
+
+// CHECK:          Name: func
+// CHECK-NEXT:     Value:
+// CHECK-NEXT:     Size:
+// CHECK-NEXT:     Binding: Local (0x0)
+
+// CHECK-DYN-NOT: func
+
+// CHECK-ERR: symbol func@@VER2 has undefined version VER2
+// CHECK-ERR-NEXT: symbol func@VER has undefined version VER
+
+ .text
+ .globl _start
+ .globl func
+_start:
+ ret
+
+ .data
+ .quad func
diff --git a/test/ELF/version-script-extern.s b/test/ELF/version-script-extern.s
index c63ff81..3125f62 100644
--- a/test/ELF/version-script-extern.s
+++ b/test/ELF/version-script-extern.s
@@ -7,7 +7,7 @@
 # RUN: echo "LIBSAMPLE_2.0 { global:" >> %t.script
 # RUN: echo '  extern "C" { _Z3bari; };' >> %t.script
 # RUN: echo "};" >> %t.script
-# RUN: ld.lld --hash-style=sysv --version-script %t.script -shared %t.o -o %t.so
+# RUN: ld.lld --hash-style=sysv --version-script %t.script -soname fixed-length-string -shared %t.o -o %t.so
 # RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s
 
 # DSO:      DynamicSymbols [
@@ -68,8 +68,8 @@
 # DSO-NEXT:  ]
 # DSO-NEXT:  Version symbols {
 # DSO-NEXT:    Section Name: .gnu.version
-# DSO-NEXT:    Address: 0x258
-# DSO-NEXT:    Offset: 0x258
+# DSO-NEXT:    Address: 0x2BA
+# DSO-NEXT:    Offset: 0x2BA
 # DSO-NEXT:    Link: 1
 # DSO-NEXT:    Symbols [
 # DSO-NEXT:      Symbol {
diff --git a/test/ELF/warn-backrefs.s b/test/ELF/warn-backrefs.s
new file mode 100644
index 0000000..d51e1f5
--- /dev/null
+++ b/test/ELF/warn-backrefs.s
@@ -0,0 +1,48 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+# RUN: echo ".globl foo; foo:" | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t2.o
+# RUN: rm -f %t2.a
+# RUN: llvm-ar rcs %t2.a %t2.o
+
+# RUN: ld.lld --fatal-warnings -o %t.exe %t1.o %t2.a
+# RUN: ld.lld --fatal-warnings -o %t.exe %t2.a %t1.o
+# RUN: ld.lld --fatal-warnings --warn-backrefs -o %t.exe %t1.o %t2.a
+# RUN: ld.lld --fatal-warnings --warn-backrefs -o %t.exe %t1.o --start-lib %t2.o --end-lib
+
+# RUN: ld.lld --fatal-warnings --warn-backrefs -o %t.exe --start-group %t2.a %t1.o --end-group
+# RUN: ld.lld --fatal-warnings --warn-backrefs -o %t.exe "-(" %t2.a %t1.o "-)"
+
+# RUN: echo "INPUT(\"%t1.o\" \"%t2.a\")" > %t1.script
+# RUN: ld.lld --fatal-warnings --warn-backrefs -o %t.exe %t1.script
+
+# RUN: echo "GROUP(\"%t2.a\" \"%t1.o\")" > %t2.script
+# RUN: ld.lld --fatal-warnings --warn-backrefs -o %t.exe %t2.script
+
+# RUN: not ld.lld --fatal-warnings --warn-backrefs -o %t.exe %t2.a %t1.o 2>&1 | FileCheck %s
+# RUN: not ld.lld --fatal-warnings --warn-backrefs -o %t.exe %t2.a "-(" %t1.o "-)" 2>&1 | FileCheck %s
+# RUN: not ld.lld --fatal-warnings --warn-backrefs -o %t.exe --start-group %t2.a --end-group %t1.o 2>&1 | FileCheck %s
+
+# RUN: echo "GROUP(\"%t2.a\")" > %t3.script
+# RUN: not ld.lld --fatal-warnings --warn-backrefs -o %t.exe %t3.script %t1.o 2>&1 | FileCheck %s
+# RUN: ld.lld --fatal-warnings --warn-backrefs -o %t.exe "-(" %t3.script %t1.o "-)"
+
+# CHECK: backward reference detected: foo in {{.*}}1.o refers to {{.*}}2.a
+
+# RUN: not ld.lld --fatal-warnings --start-group --start-group 2>&1 | FileCheck -check-prefix=START %s
+# START: nested --start-group
+
+# RUN: not ld.lld --fatal-warnings --end-group 2>&1 | FileCheck -check-prefix=END %s
+# END: stray --end-group
+
+# RUN: echo ".globl bar; bar:" | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t3.o
+# RUN: echo ".globl foo; foo: call bar" | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t4.o
+# RUN: ld.lld --fatal-warnings --warn-backrefs %t1.o --start-lib %t3.o %t4.o --end-lib -o %t.exe
+
+# We don't report backward references to weak symbols as they can be overriden later.
+# RUN: echo ".weak foo; foo:" | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t5.o
+# RUN: ld.lld --fatal-warnings --warn-backrefs --start-lib %t5.o --end-lib %t1.o %t2.o -o %t.exe
+
+.globl _start, foo
+_start:
+  call foo
diff --git a/test/ELF/weak-and-strong-undef.s b/test/ELF/weak-and-strong-undef.s
index db93470..32ce649 100644
--- a/test/ELF/weak-and-strong-undef.s
+++ b/test/ELF/weak-and-strong-undef.s
@@ -1,6 +1,6 @@
 # REQUIRES: x86
 # 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/weak-and-strong-undef.s -o %t2.o
+# RUN: echo ".weak foo" | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t2.o
 # RUN: not ld.lld %t1.o %t2.o -o %t 2>&1 | FileCheck %s
 # RUN: not ld.lld %t2.o %t1.o -o %t 2>&1 | FileCheck %s
 
diff --git a/test/ELF/weak-shared-gc.s b/test/ELF/weak-shared-gc.s
new file mode 100644
index 0000000..2cafbe8
--- /dev/null
+++ b/test/ELF/weak-shared-gc.s
@@ -0,0 +1,21 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
+# RUN: echo -e '.globl __cxa_finalize\n__cxa_finalize:' | \
+# RUN:   llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t2.o
+# RUN: ld.lld %t2.o -o %t2.so -shared
+# RUN: ld.lld %t1.o --as-needed --gc-sections %t2.so -o %t
+# RUN: llvm-readelf -dynamic-table -dyn-symbols %t | FileCheck %s
+
+# The crt files on linux have a weak reference to __cxa_finalize. It
+# is important that a weak undefined reference is produced. Like
+# other weak undefined references, the shared library is not marked as
+# needed.
+
+# CHECK-NOT: NEEDED
+# CHECK: WEAK   DEFAULT UND __cxa_finalize
+# CHECK-NOT: NEEDED
+
+        .global _start
+_start:
+	.weak	__cxa_finalize
+	call	__cxa_finalize@PLT
diff --git a/test/ELF/x86-64-dyn-rel-error3.s b/test/ELF/x86-64-dyn-rel-error3.s
new file mode 100644
index 0000000..82a580d
--- /dev/null
+++ b/test/ELF/x86-64-dyn-rel-error3.s
@@ -0,0 +1,16 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: not ld.lld %t.o -shared -o %t.so 2>&1 | FileCheck %s
+
+# CHECK: relocation R_X86_64_8 cannot be used against symbol foo; recompile with -fPIC
+# CHECK: relocation R_X86_64_16 cannot be used against symbol foo; recompile with -fPIC
+# CHECK: relocation R_X86_64_PC8 cannot be used against symbol foo; recompile with -fPIC
+# CHECK: relocation R_X86_64_PC16 cannot be used against symbol foo; recompile with -fPIC
+
+.global foo
+
+.data
+.byte foo       # R_X86_64_8
+.short foo      # R_X86_64_16
+.byte foo - .   # R_X86_64_PC8
+.short foo - .  # R_X86_64_PC16
diff --git a/test/ELF/x86-64-plt-high-addr.s b/test/ELF/x86-64-plt-high-addr.s
new file mode 100644
index 0000000..4acccb6
--- /dev/null
+++ b/test/ELF/x86-64-plt-high-addr.s
@@ -0,0 +1,24 @@
+// REQUIRES: x86
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t1.o
+// RUN: ld.lld -o %t.so -shared %t1.o
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2.o
+// RUN: ld.lld -o %t1.exe %t2.o %t.so -image-base=0xcafe00000000
+// RUN: llvm-objdump -s -j .got.plt %t1.exe | FileCheck %s
+
+// CHECK:      Contents of section .got.plt:
+// CHECK-NEXT: cafe00002000 00300000 feca0000 00000000 00000000
+// CHECK-NEXT: cafe00002010 00000000 00000000 26100000 feca0000
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2.o
+// RUN: ld.lld -o %t2.exe %t2.o %t.so -image-base=0xcafe00000000 -z retpolineplt
+// RUN: llvm-objdump -s -j .got.plt %t2.exe | FileCheck -check-prefix=RETPOLINE %s
+
+// RETPOLINE:      Contents of section .got.plt:
+// RETPOLINE-NEXT: cafe00002000 00300000 feca0000 00000000 00000000
+// RETPOLINE-NEXT: cafe00002010 00000000 00000000 51100000 feca0000
+
+.global _start
+_start:
+  jmp bar@PLT
diff --git a/test/ELF/x86-64-retpoline-linkerscript.s b/test/ELF/x86-64-retpoline-linkerscript.s
index d173cf5..03c3ef2 100644
--- a/test/ELF/x86-64-retpoline-linkerscript.s
+++ b/test/ELF/x86-64-retpoline-linkerscript.s
@@ -14,8 +14,8 @@
 
 // CHECK:      Disassembly of section .plt:
 // CHECK-NEXT: .plt:
-// CHECK-NEXT: 10:       ff 35 4a 01 00 00       pushq   330(%rip)
-// CHECK-NEXT: 16:       4c 8b 1d 4b 01 00 00    movq    331(%rip), %r11
+// CHECK-NEXT: 10:       ff 35 ea 00 00 00       pushq   234(%rip)
+// CHECK-NEXT: 16:       4c 8b 1d eb 00 00 00    movq    235(%rip), %r11
 // CHECK-NEXT: 1d:       e8 0e 00 00 00  callq   14 <.plt+0x20>
 // CHECK-NEXT: 22:       f3 90   pause
 // CHECK-NEXT: 24:       0f ae e8        lfence
@@ -40,7 +40,7 @@
 // CHECK-NEXT: 3d:       cc      int3
 // CHECK-NEXT: 3e:       cc      int3
 // CHECK-NEXT: 3f:       cc      int3
-// CHECK-NEXT: 40:       4c 8b 1d 29 01 00 00    movq    297(%rip), %r11
+// CHECK-NEXT: 40:       4c 8b 1d c9 00 00 00    movq    201(%rip), %r11
 // CHECK-NEXT: 47:       e8 e4 ff ff ff  callq   -28 <.plt+0x20>
 // CHECK-NEXT: 4c:       e9 d1 ff ff ff  jmp     -47 <.plt+0x12>
 // CHECK-NEXT: 51:       68 00 00 00 00  pushq   $0
@@ -50,7 +50,7 @@
 // CHECK-NEXT: 5d:       cc      int3
 // CHECK-NEXT: 5e:       cc      int3
 // CHECK-NEXT: 5f:       cc      int3
-// CHECK-NEXT: 60:       4c 8b 1d 11 01 00 00    movq    273(%rip), %r11
+// CHECK-NEXT: 60:       4c 8b 1d b1 00 00 00    movq    177(%rip), %r11
 // CHECK-NEXT: 67:       e8 c4 ff ff ff  callq   -60 <.plt+0x20>
 // CHECK-NEXT: 6c:       e9 b1 ff ff ff  jmp     -79 <.plt+0x12>
 // CHECK-NEXT: 71:       68 01 00 00 00  pushq   $1
diff --git a/test/ELF/x86-64-retpoline-znow-linkerscript.s b/test/ELF/x86-64-retpoline-znow-linkerscript.s
index 27737b8..e4eed84 100644
--- a/test/ELF/x86-64-retpoline-znow-linkerscript.s
+++ b/test/ELF/x86-64-retpoline-znow-linkerscript.s
@@ -35,13 +35,13 @@
 // CHECK-NEXT: 2d:	cc 	int3
 // CHECK-NEXT: 2e:	cc 	int3
 // CHECK-NEXT: 2f:	cc 	int3
-// CHECK-NEXT: 30:	4c 8b 1d 09 01 00 00 	movq	265(%rip), %r11
+// CHECK-NEXT: 30:	4c 8b 1d a9 00 00 00 	movq	169(%rip), %r11
 // CHECK-NEXT: 37:	e9 d4 ff ff ff 	jmp	-44 <.plt>
 // CHECK-NEXT: 3c:	cc 	int3
 // CHECK-NEXT: 3d:	cc 	int3
 // CHECK-NEXT: 3e:	cc 	int3
 // CHECK-NEXT: 3f:	cc 	int3
-// CHECK-NEXT: 40: 4c 8b 1d 01 01 00 00 	movq	257(%rip), %r11
+// CHECK-NEXT: 40:      4c 8b 1d a1 00 00 00 	movq	161(%rip), %r11
 // CHECK-NEXT: 47:	e9 c4 ff ff ff 	jmp	-60 <.plt>
 // CHECK-NEXT: 4c:	cc 	int3
 // CHECK-NEXT: 4d:	cc 	int3
diff --git a/test/ELF/x86-64-tls-ld-local.s b/test/ELF/x86-64-tls-ld-local.s
new file mode 100644
index 0000000..6daba63
--- /dev/null
+++ b/test/ELF/x86-64-tls-ld-local.s
@@ -0,0 +1,29 @@
+// REQUIRES: x86
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readobj -r -s %t.so | FileCheck %s
+
+// CHECK:      Relocations [
+// CHECK-NEXT:   Section ({{.*}}) .rela.dyn {
+// CHECK-NEXT:     R_X86_64_DTPMOD64 - 0x0
+// CHECK-NEXT:     R_X86_64_DTPMOD64 - 0x0
+// CHECK-NEXT:   }
+// CHECK-NEXT:   Section ({{.*}}) .rela.plt {
+// CHECK-NEXT:     R_X86_64_JUMP_SLOT __tls_get_addr 0x0
+// CHECK-NEXT:   }
+// CHECK-NEXT: ]
+
+	data16
+	leaq	bar@TLSGD(%rip), %rdi
+	data16
+	data16
+	rex64
+	callq	__tls_get_addr@PLT
+
+	leaq	bar@TLSLD(%rip), %rdi
+	callq	__tls_get_addr@PLT
+	leaq	bar@DTPOFF(%rax), %rax
+
+	.section	.tdata,"awT",@progbits
+bar:
+	.long	42
diff --git a/test/ELF/ztext.s b/test/ELF/ztext.s
index 1ce19cf..1757769 100644
--- a/test/ELF/ztext.s
+++ b/test/ELF/ztext.s
@@ -2,6 +2,7 @@
 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/ztext.s -o %t2.o
 # RUN: ld.lld %t2.o -o %t2.so -shared
+
 # RUN: ld.lld -z notext %t.o %t2.so -o %t -shared
 # RUN: llvm-readobj  -dynamic-table -r %t | FileCheck %s
 # RUN: ld.lld -z notext %t.o %t2.so -o %t2 -pie
@@ -9,6 +10,10 @@
 # RUN: ld.lld -z notext %t.o %t2.so -o %t3
 # RUN: llvm-readobj  -dynamic-table -r %t3 | FileCheck --check-prefix=STATIC %s
 
+# RUN: not ld.lld %t.o %t2.so -o %t -shared 2>&1 | FileCheck --check-prefix=ERR %s
+# RUN: not ld.lld -z text %t.o %t2.so -o %t -shared 2>&1 | FileCheck --check-prefix=ERR %s
+# ERR: error: can't create dynamic relocation
+
 # If the preference is to have text relocations, don't create plt of copy relocations.
 
 # CHECK:      Relocations [
diff --git a/test/MinGW/driver.test b/test/MinGW/driver.test
index 1a95d23..e7c608a 100644
--- a/test/MinGW/driver.test
+++ b/test/MinGW/driver.test
@@ -90,6 +90,10 @@
 RUN: ld.lld -### -m i386pep foo.o --strip-all | FileCheck -check-prefix STRIP %s
 STRIP-NOT: -debug:dwarf
 
+RUN: ld.lld -### -m i386pep foo.o -pdb out.pdb | FileCheck -check-prefix PDB %s
+PDB: -debug -pdb:out.pdb
+PDB-NOT: -debug:dwarf
+
 RUN: ld.lld -### -m i386pep foo.o --large-address-aware | FileCheck -check-prefix LARGE-ADDRESS-AWARE %s
 LARGE-ADDRESS-AWARE: -largeaddressaware
 
@@ -130,3 +134,9 @@
 RUN: ld.lld -### foo.o -m i386pe -shared --kill-at | FileCheck -check-prefix=KILL-AT %s
 RUN: ld.lld -### foo.o -m i386pe -shared -kill-at | FileCheck -check-prefix=KILL-AT %s
 KILL-AT: -kill-at
+
+RUN: ld.lld -### foo.o -m i386pep -Map bar.map | FileCheck -check-prefix=MAP %s
+RUN: ld.lld -### foo.o -m i386pep --Map bar.map | FileCheck -check-prefix=MAP %s
+RUN: ld.lld -### foo.o -m i386pep -Map=bar.map | FileCheck -check-prefix=MAP %s
+RUN: ld.lld -### foo.o -m i386pep --Map=bar.map | FileCheck -check-prefix=MAP %s
+MAP: -lldmap:bar.map
diff --git a/test/lit.cfg.py b/test/lit.cfg.py
index 8fd1a60..41b57e5 100644
--- a/test/lit.cfg.py
+++ b/test/lit.cfg.py
@@ -40,7 +40,8 @@
 
 tool_patterns = [
     'llc', 'llvm-as', 'llvm-mc', 'llvm-nm', 'llvm-objdump', 'llvm-pdbutil',
-    'llvm-readelf', 'llvm-readobj', 'obj2yaml', 'yaml2obj']
+    'llvm-dwarfdump', 'llvm-readelf', 'llvm-readobj', 'obj2yaml', 'yaml2obj',
+    'opt', 'llvm-dis']
 
 llvm_config.add_tool_substitutions(tool_patterns)
 
diff --git a/test/wasm/Inputs/archive1.ll b/test/wasm/Inputs/archive1.ll
index d0722e6..7f61479 100644
--- a/test/wasm/Inputs/archive1.ll
+++ b/test/wasm/Inputs/archive1.ll
@@ -1,4 +1,4 @@
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 declare i32 @bar() local_unnamed_addr #1
 
diff --git a/test/wasm/Inputs/archive2.ll b/test/wasm/Inputs/archive2.ll
index f0e00ba..c4903cb 100644
--- a/test/wasm/Inputs/archive2.ll
+++ b/test/wasm/Inputs/archive2.ll
@@ -1,4 +1,4 @@
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 declare i32 @foo() local_unnamed_addr #1
 
diff --git a/test/wasm/Inputs/call-indirect.ll b/test/wasm/Inputs/call-indirect.ll
index eaa7bb9..6afcf30 100644
--- a/test/wasm/Inputs/call-indirect.ll
+++ b/test/wasm/Inputs/call-indirect.ll
@@ -1,4 +1,4 @@
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 @indirect_bar = internal local_unnamed_addr global i64 ()* @bar, align 4
 @indirect_foo = internal local_unnamed_addr global i32 ()* @foo, align 4
diff --git a/test/wasm/Inputs/comdat1.ll b/test/wasm/Inputs/comdat1.ll
index ff4f3c0..12678b0 100644
--- a/test/wasm/Inputs/comdat1.ll
+++ b/test/wasm/Inputs/comdat1.ll
@@ -1,4 +1,4 @@
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 $inlineFn = comdat any
 @constantData = weak_odr constant [3 x i8] c"abc", comdat($inlineFn)
diff --git a/test/wasm/Inputs/comdat2.ll b/test/wasm/Inputs/comdat2.ll
index 6b7ca4a..d910e1a 100644
--- a/test/wasm/Inputs/comdat2.ll
+++ b/test/wasm/Inputs/comdat2.ll
@@ -1,4 +1,4 @@
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 $inlineFn = comdat any
 @constantData = weak_odr constant [3 x i8] c"abc", comdat($inlineFn)
@@ -9,5 +9,5 @@
 
 define i32 @callInline2() {
 entry:
-    ret i32 ptrtoint (i32 ()* @inlineFn to i32)
+  ret i32 ptrtoint (i32 ()* @inlineFn to i32)
 }
diff --git a/test/wasm/Inputs/custom.ll b/test/wasm/Inputs/custom.ll
new file mode 100644
index 0000000..30b4ef0
--- /dev/null
+++ b/test/wasm/Inputs/custom.ll
@@ -0,0 +1,6 @@
+target triple = "wasm32-unknown-unknown"
+
+!0 = !{ !"red", !"foo" }
+!1 = !{ !"green", !"bar" }
+!2 = !{ !"green", !"qux" }
+!wasm.custom_sections = !{ !0, !1, !2 }
diff --git a/test/wasm/Inputs/debuginfo1.ll b/test/wasm/Inputs/debuginfo1.ll
new file mode 100644
index 0000000..7f37fd4
--- /dev/null
+++ b/test/wasm/Inputs/debuginfo1.ll
@@ -0,0 +1,68 @@
+; ModuleID = 'hi.c'
+source_filename = "hi.c"
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+; // hi.c:
+; extern void foo(int);
+;
+; int test(int t) {
+;   return t * t;
+; }
+;
+; int _start() {
+;   foo(test(10));
+;   return 0;
+; }
+
+; Function Attrs: nounwind readnone
+define hidden i32 @test(i32 %t) local_unnamed_addr #0 !dbg !7 {
+entry:
+  call void @llvm.dbg.value(metadata i32 %t, metadata !12, metadata !DIExpression()), !dbg !13
+  %mul = mul nsw i32 %t, %t, !dbg !14
+  ret i32 %mul, !dbg !15
+}
+
+; Function Attrs: nounwind
+define hidden i32 @_start() local_unnamed_addr #1 !dbg !16 {
+entry:
+  tail call void @foo(i32 100) #4, !dbg !19
+  ret i32 0, !dbg !20
+}
+
+declare void @foo(i32) local_unnamed_addr #2
+
+; Function Attrs: nounwind readnone speculatable
+declare void @llvm.dbg.value(metadata, metadata, metadata) #3
+
+attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #3 = { nounwind readnone speculatable }
+attributes #4 = { nounwind }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 7.0.0 (trunk 331321)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+!1 = !DIFile(filename: "hi.c", directory: "/Users/yury/llvmwasm")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 7.0.0 (trunk 331321)"}
+!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 3, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10, !10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!12}
+!12 = !DILocalVariable(name: "t", arg: 1, scope: !7, file: !1, line: 3, type: !10)
+!13 = !DILocation(line: 3, column: 14, scope: !7)
+!14 = !DILocation(line: 4, column: 12, scope: !7)
+!15 = !DILocation(line: 4, column: 3, scope: !7)
+!16 = distinct !DISubprogram(name: "_start", scope: !1, file: !1, line: 7, type: !17, isLocal: false, isDefinition: true, scopeLine: 7, isOptimized: true, unit: !0, retainedNodes: !2)
+!17 = !DISubroutineType(types: !18)
+!18 = !{!10}
+!19 = !DILocation(line: 8, column: 3, scope: !16)
+!20 = !DILocation(line: 9, column: 3, scope: !16)
diff --git a/test/wasm/Inputs/debuginfo2.ll b/test/wasm/Inputs/debuginfo2.ll
new file mode 100644
index 0000000..72f94e0
--- /dev/null
+++ b/test/wasm/Inputs/debuginfo2.ll
@@ -0,0 +1,70 @@
+; ModuleID = 'hi_foo.c'
+source_filename = "hi_foo.c"
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+; // hi_foo.c:
+; int y[2] = {23, 41};
+;
+; void foo(int p) {
+;   y[p & 1]++;
+; }
+;
+; // Will be GCed, but remain visible in debug info
+; int z[2] = {1, 2};
+
+@y = hidden local_unnamed_addr global [2 x i32] [i32 23, i32 41], align 4, !dbg !0
+@z = hidden local_unnamed_addr global [2 x i32] [i32 1, i32 2], align 4, !dbg !6
+
+; Function Attrs: nounwind
+define hidden void @foo(i32 %p) local_unnamed_addr #0 !dbg !16 {
+entry:
+  call void @llvm.dbg.value(metadata i32 %p, metadata !20, metadata !DIExpression()), !dbg !21
+  %and = and i32 %p, 1, !dbg !22
+  %arrayidx = getelementptr inbounds [2 x i32], [2 x i32]* @y, i32 0, i32 %and, !dbg !23
+  %0 = load i32, i32* %arrayidx, align 4, !dbg !24, !tbaa !25
+  %inc = add nsw i32 %0, 1, !dbg !24
+  store i32 %inc, i32* %arrayidx, align 4, !dbg !24, !tbaa !25
+  ret void, !dbg !29
+}
+
+; Function Attrs: nounwind readnone speculatable
+declare void @llvm.dbg.value(metadata, metadata, metadata) #1
+
+attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind readnone speculatable }
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!12, !13, !14}
+!llvm.ident = !{!15}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "y", scope: !2, file: !3, line: 1, type: !8, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 7.0.0 (trunk 332913) (llvm/trunk 332919)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
+!3 = !DIFile(filename: "hi_foo.c", directory: "/usr/local/google/home/sbc/dev/wasm/llvm-build")
+!4 = !{}
+!5 = !{!0, !6}
+!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression())
+!7 = distinct !DIGlobalVariable(name: "z", scope: !2, file: !3, line: 8, type: !8, isLocal: false, isDefinition: true)
+!8 = !DICompositeType(tag: DW_TAG_array_type, baseType: !9, size: 64, elements: !10)
+!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!10 = !{!11}
+!11 = !DISubrange(count: 2)
+!12 = !{i32 2, !"Dwarf Version", i32 4}
+!13 = !{i32 2, !"Debug Info Version", i32 3}
+!14 = !{i32 1, !"wchar_size", i32 4}
+!15 = !{!"clang version 7.0.0 (trunk 332913) (llvm/trunk 332919)"}
+!16 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 3, type: !17, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !2, retainedNodes: !19)
+!17 = !DISubroutineType(types: !18)
+!18 = !{null, !9}
+!19 = !{!20}
+!20 = !DILocalVariable(name: "p", arg: 1, scope: !16, file: !3, line: 3, type: !9)
+!21 = !DILocation(line: 3, column: 14, scope: !16)
+!22 = !DILocation(line: 4, column: 7, scope: !16)
+!23 = !DILocation(line: 4, column: 3, scope: !16)
+!24 = !DILocation(line: 4, column: 11, scope: !16)
+!25 = !{!26, !26, i64 0}
+!26 = !{!"int", !27, i64 0}
+!27 = !{!"omnipotent char", !28, i64 0}
+!28 = !{!"Simple C/C++ TBAA"}
+!29 = !DILocation(line: 5, column: 1, scope: !16)
diff --git a/test/wasm/Inputs/global-ctor-dtor.ll b/test/wasm/Inputs/global-ctor-dtor.ll
index f934b83..5e73f06 100644
--- a/test/wasm/Inputs/global-ctor-dtor.ll
+++ b/test/wasm/Inputs/global-ctor-dtor.ll
@@ -1,4 +1,4 @@
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 define hidden void @myctor() {
 entry:
diff --git a/test/wasm/Inputs/globals.yaml b/test/wasm/Inputs/globals.yaml
new file mode 100644
index 0000000..c08a304
--- /dev/null
+++ b/test/wasm/Inputs/globals.yaml
@@ -0,0 +1,54 @@
+--- !WASM
+FileHeader:
+  Version:         0x00000001
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ReturnType:      I64
+        ParamTypes:
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0 ]
+  - Type:            GLOBAL
+    Globals:
+      - Index:       0
+        Type:        I64
+        Mutable:     true
+        InitExpr:
+          Opcode:          I64_CONST
+          Value:           123
+      - Index:       1
+        Type:        I64
+        Mutable:     true
+        InitExpr:
+          Opcode:          I64_CONST
+          Value:           456
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:
+        Body:            2381808080000B
+    Relocations:
+      - Type:            R_WEBASSEMBLY_GLOBAL_INDEX_LEB
+        Index:           1
+        Offset:          0x00000004
+  - Type:            CUSTOM
+    Name:            linking
+    Version:         1
+    SymbolTable:
+      - Index:           0
+        Kind:            GLOBAL
+        Name:            unused_global
+        Flags:           [ VISIBILITY_HIDDEN ]
+        Global:          0
+      - Index:           1
+        Kind:            GLOBAL
+        Name:            used_global
+        Flags:           [ VISIBILITY_HIDDEN ]
+        Global:          1
+      - Index:           2
+        Kind:            FUNCTION
+        Name:            use_global
+        Flags:           [ VISIBILITY_HIDDEN ]
+        Function:        0
+...
diff --git a/test/wasm/Inputs/hello.ll b/test/wasm/Inputs/hello.ll
index a00c4d8..6755668 100644
--- a/test/wasm/Inputs/hello.ll
+++ b/test/wasm/Inputs/hello.ll
@@ -1,4 +1,4 @@
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 ; Wasm module generated from the following C code:
 ;   void puts(const char*);
diff --git a/test/wasm/Inputs/hidden.ll b/test/wasm/Inputs/hidden.ll
index e3471ac..4af16b3 100644
--- a/test/wasm/Inputs/hidden.ll
+++ b/test/wasm/Inputs/hidden.ll
@@ -1,4 +1,4 @@
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 ; Function Attrs: norecurse nounwind readnone
 define hidden i32 @archiveHidden() #0 {
diff --git a/test/wasm/Inputs/locals-duplicate1.ll b/test/wasm/Inputs/locals-duplicate1.ll
index 9d4092b..f118dd4 100644
--- a/test/wasm/Inputs/locals-duplicate1.ll
+++ b/test/wasm/Inputs/locals-duplicate1.ll
@@ -1,4 +1,4 @@
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 ; Will collide: local (internal linkage) with global (external) linkage
 @colliding_global1 = internal default global i32 0, align 4
diff --git a/test/wasm/Inputs/locals-duplicate2.ll b/test/wasm/Inputs/locals-duplicate2.ll
index bc1e2c6..617abfe 100644
--- a/test/wasm/Inputs/locals-duplicate2.ll
+++ b/test/wasm/Inputs/locals-duplicate2.ll
@@ -1,4 +1,4 @@
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 ; Will collide: local (internal linkage) with global (external) linkage
 @colliding_global1 = default global i32 0, align 4
diff --git a/test/wasm/Inputs/many-funcs.ll b/test/wasm/Inputs/many-funcs.ll
index a54cbb8..1829d7d 100644
--- a/test/wasm/Inputs/many-funcs.ll
+++ b/test/wasm/Inputs/many-funcs.ll
@@ -1,4 +1,4 @@
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 @g0 = global i32 1, align 4
 @foo = global i32 1, align 4
diff --git a/test/wasm/Inputs/ret32.ll b/test/wasm/Inputs/ret32.ll
index f5a70be..b1ccd64 100644
--- a/test/wasm/Inputs/ret32.ll
+++ b/test/wasm/Inputs/ret32.ll
@@ -1,4 +1,4 @@
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 ; Function Attrs: norecurse nounwind readnone
 define i32 @ret32(float %arg) #0 {
diff --git a/test/wasm/Inputs/ret64.ll b/test/wasm/Inputs/ret64.ll
index d39026e..034260d 100644
--- a/test/wasm/Inputs/ret64.ll
+++ b/test/wasm/Inputs/ret64.ll
@@ -1,4 +1,4 @@
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 define i64 @ret64(double %arg) local_unnamed_addr #0 {
 entry:
diff --git a/test/wasm/Inputs/start.ll b/test/wasm/Inputs/start.ll
index 66f4b17..e262965 100644
--- a/test/wasm/Inputs/start.ll
+++ b/test/wasm/Inputs/start.ll
@@ -1,4 +1,4 @@
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 define void @_start() local_unnamed_addr {
 entry:
diff --git a/test/wasm/Inputs/strong-symbol.ll b/test/wasm/Inputs/strong-symbol.ll
index 59bce52..cc2aa8a 100644
--- a/test/wasm/Inputs/strong-symbol.ll
+++ b/test/wasm/Inputs/strong-symbol.ll
@@ -1,4 +1,4 @@
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 define i64 @weakFn() #0 {
 entry:
diff --git a/test/wasm/Inputs/undefined-globals.yaml b/test/wasm/Inputs/undefined-globals.yaml
new file mode 100644
index 0000000..440a538
--- /dev/null
+++ b/test/wasm/Inputs/undefined-globals.yaml
@@ -0,0 +1,52 @@
+--- !WASM
+FileHeader:
+  Version:         0x00000001
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ReturnType:      I64
+        ParamTypes:
+  - Type:            IMPORT
+    Imports:
+      - Module:          env
+        Field:           unused_undef_global
+        Kind:            GLOBAL
+        GlobalType:      I64
+        GlobalMutable:   true
+      - Module:          env
+        Field:           used_undef_global
+        Kind:            GLOBAL
+        GlobalType:      I64
+        GlobalMutable:   true
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0 ]
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:
+        Body:            2381808080000B
+    Relocations:
+      - Type:            R_WEBASSEMBLY_GLOBAL_INDEX_LEB
+        Index:           1
+        Offset:          0x00000004
+  - Type:            CUSTOM
+    Name:            linking
+    Version:         1
+    SymbolTable:
+      - Index:           0
+        Kind:            GLOBAL
+        Name:            unused_undef_global
+        Flags:           [ VISIBILITY_HIDDEN, UNDEFINED ]
+        Global:          0
+      - Index:           1
+        Kind:            GLOBAL
+        Name:            used_undef_global
+        Flags:           [ VISIBILITY_HIDDEN, UNDEFINED ]
+        Global:          1
+      - Index:           2
+        Kind:            FUNCTION
+        Name:            use_undef_global
+        Flags:           [ VISIBILITY_HIDDEN ]
+        Function:        0
+...
diff --git a/test/wasm/Inputs/weak-alias.ll b/test/wasm/Inputs/weak-alias.ll
index d4f1326..1840ffd 100644
--- a/test/wasm/Inputs/weak-alias.ll
+++ b/test/wasm/Inputs/weak-alias.ll
@@ -1,4 +1,4 @@
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 ; Function Attrs: norecurse nounwind readnone
 define i32 @direct_fn() #0 {
diff --git a/test/wasm/Inputs/weak-symbol1.ll b/test/wasm/Inputs/weak-symbol1.ll
index 0541f38..6e394ff 100644
--- a/test/wasm/Inputs/weak-symbol1.ll
+++ b/test/wasm/Inputs/weak-symbol1.ll
@@ -1,4 +1,4 @@
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 define weak i32 @weakFn() #0 {
 entry:
diff --git a/test/wasm/Inputs/weak-symbol2.ll b/test/wasm/Inputs/weak-symbol2.ll
index 3b989c1..e9c30c1 100644
--- a/test/wasm/Inputs/weak-symbol2.ll
+++ b/test/wasm/Inputs/weak-symbol2.ll
@@ -1,4 +1,4 @@
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 define weak i32 @weakFn() #0 {
 entry:
diff --git a/test/wasm/alias.ll b/test/wasm/alias.ll
index c12ef2d..f88452e 100644
--- a/test/wasm/alias.ll
+++ b/test/wasm/alias.ll
@@ -1,8 +1,8 @@
 ; RUN: llc -filetype=obj -o %t.o %s
-; RUN: wasm-ld --check-signatures %t.o -o %t.wasm
+; RUN: wasm-ld %t.o -o %t.wasm
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 @start_alias = alias void (), void ()* @_start
 
diff --git a/test/wasm/archive.ll b/test/wasm/archive.ll
index 78daff0..b2499ea 100644
--- a/test/wasm/archive.ll
+++ b/test/wasm/archive.ll
@@ -4,16 +4,16 @@
 ; RUN: llc -filetype=obj %S/Inputs/hello.ll -o %t.a3.o
 ; RUN: llvm-ar rcs %t.a %t.a1.o %t.a2.o %t.a3.o
 ; RUN: rm -f %t.imports
-; RUN: not wasm-ld --check-signatures %t.a %t.o -o %t.wasm 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED %s
+; RUN: not wasm-ld %t.a %t.o -o %t.wasm 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED %s
 
 ; CHECK-UNDEFINED: undefined symbol: missing_func
 
 ; RUN: echo 'missing_func' > %t.imports
-; RUN: wasm-ld --check-signatures -r %t.a %t.o -o %t.wasm
+; RUN: wasm-ld -r %t.a %t.o -o %t.wasm
 
 ; RUN: llvm-nm -a %t.wasm | FileCheck %s
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 declare i32 @foo() local_unnamed_addr #1
 declare i32 @missing_func() local_unnamed_addr #1
@@ -40,4 +40,4 @@
 ; CHECK-NOT: hello
 
 ; Specifying the same archive twice is allowed.
-; RUN: wasm-ld --check-signatures %t.a %t.a %t.o -o %t.wasm
+; RUN: wasm-ld %t.a %t.a %t.o -o %t.wasm
diff --git a/test/wasm/call-indirect.ll b/test/wasm/call-indirect.ll
index 9a6d64f..63a6def 100644
--- a/test/wasm/call-indirect.ll
+++ b/test/wasm/call-indirect.ll
@@ -1,6 +1,6 @@
 ; RUN: llc -filetype=obj %p/Inputs/call-indirect.ll -o %t2.o
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: wasm-ld --check-signatures -o %t.wasm %t2.o %t.o
+; RUN: wasm-ld -o %t.wasm %t2.o %t.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
 ; bitcode generated from the following C code:
@@ -8,7 +8,7 @@
 ; int (*indirect_func)(void) = &foo;
 ; void _start(void) { indirect_func(); }
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 @indirect_func = local_unnamed_addr global i32 ()* @foo, align 4
 
diff --git a/test/wasm/comdats.ll b/test/wasm/comdats.ll
index d737132..d0bec4c 100644
--- a/test/wasm/comdats.ll
+++ b/test/wasm/comdats.ll
@@ -1,10 +1,10 @@
 ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/comdat1.ll -o %t1.o
 ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/comdat2.ll -o %t2.o
 ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %s -o %t.o
-; RUN: wasm-ld --check-signatures -o %t.wasm %t.o %t1.o %t2.o
+; RUN: wasm-ld -o %t.wasm %t.o %t1.o %t2.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 declare i32 @inlineFn()
 
diff --git a/test/wasm/compress-relocs.ll b/test/wasm/compress-relocs.ll
new file mode 100644
index 0000000..b137d5a
--- /dev/null
+++ b/test/wasm/compress-relocs.ll
@@ -0,0 +1,22 @@
+; RUN: llc -filetype=obj %p/Inputs/call-indirect.ll -o %t2.o
+; RUN: llc -filetype=obj %s -o %t.o
+; RUN: wasm-ld -o %t.wasm %t2.o %t.o
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+; RUN: wasm-ld -O2 -o %t-compressed.wasm %t2.o %t.o
+; RUN: obj2yaml %t-compressed.wasm | FileCheck %s -check-prefix=COMPRESS
+
+target triple = "wasm32-unknown-unknown-wasm"
+
+define i32 @foo() {
+entry:
+  ret i32 2
+}
+
+define void @_start() local_unnamed_addr {
+entry:
+  ret void
+}
+
+; CHECK:    Body:            4100280284888080002100410028028088808000118080808000001A2000118180808000001A0B
+; COMPRESS: Body:            41002802840821004100280280081100001A20001101001A0B
diff --git a/test/wasm/conflict.test b/test/wasm/conflict.test
index c869802..9adc92e 100644
--- a/test/wasm/conflict.test
+++ b/test/wasm/conflict.test
@@ -1,5 +1,5 @@
 # RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
-# RUN: not wasm-ld --check-signatures -o %t.wasm %t.ret32.o %t.ret32.o 2>&1 | FileCheck %s
+# RUN: not wasm-ld -o %t.wasm %t.ret32.o %t.ret32.o 2>&1 | FileCheck %s
 
 # CHECK:      duplicate symbol: ret32
 # CHECK-NEXT: >>> defined in {{.*}}conflict.test.tmp.ret32.o
diff --git a/test/wasm/custom-sections.ll b/test/wasm/custom-sections.ll
new file mode 100644
index 0000000..c33ca27
--- /dev/null
+++ b/test/wasm/custom-sections.ll
@@ -0,0 +1,22 @@
+; RUN: llc -filetype=obj %s -o %t1.o
+; RUN: llc -filetype=obj  %S/Inputs/custom.ll -o %t2.o
+; RUN: wasm-ld --relocatable -o %t.wasm %t1.o %t2.o
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+define i32 @_start() local_unnamed_addr {
+entry:
+  %retval = alloca i32, align 4
+  ret i32 0
+}
+
+!0 = !{ !"red", !"extra" }
+!wasm.custom_sections = !{ !0 }
+
+; CHECK:        - Type:            CUSTOM
+; CHECK-NEXT:     Name:            green
+; CHECK-NEXT:     Payload:         '626172717578'
+; CHECK-NEXT:   - Type:            CUSTOM
+; CHECK-NEXT:     Name:            red
+; CHECK-NEXT:     Payload:         6578747261666F6F
diff --git a/test/wasm/cxx-mangling.ll b/test/wasm/cxx-mangling.ll
index 8b73ca9..67f3594 100644
--- a/test/wasm/cxx-mangling.ll
+++ b/test/wasm/cxx-mangling.ll
@@ -1,10 +1,10 @@
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: wasm-ld --demangle --check-signatures -o %t_demangle.wasm %t.o
+; RUN: wasm-ld --demangle -o %t_demangle.wasm %t.o
 ; RUN: obj2yaml %t_demangle.wasm | FileCheck %s
-; RUN: wasm-ld --no-demangle --check-signatures -o %t_nodemangle.wasm %t.o
+; RUN: wasm-ld --no-demangle -o %t_nodemangle.wasm %t.o
 ; RUN: obj2yaml %t_nodemangle.wasm | FileCheck %s
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 ; Check that the EXPORT name is still mangled, but that the "name" custom
 ; section contains the unmangled name.
diff --git a/test/wasm/data-layout.ll b/test/wasm/data-layout.ll
index ece5f20..5fd3f2d 100644
--- a/test/wasm/data-layout.ll
+++ b/test/wasm/data-layout.ll
@@ -1,7 +1,7 @@
 ; RUN: llc -filetype=obj %p/Inputs/hello.ll -o %t.hello.o
 ; RUN: llc -filetype=obj %s -o %t.o
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 @foo = hidden global i32 1, align 4
 @aligned_bar = hidden global i32 3, align 16
@@ -13,7 +13,7 @@
 @local_struct = hidden global %struct.s zeroinitializer, align 4
 @local_struct_internal_ptr = hidden local_unnamed_addr global i32* getelementptr inbounds (%struct.s, %struct.s* @local_struct, i32 0, i32 1), align 4
 
-; RUN: wasm-ld -no-gc-sections --check-signatures --allow-undefined -o %t.wasm %t.o %t.hello.o
+; RUN: wasm-ld -no-gc-sections --allow-undefined --no-entry -o %t.wasm %t.o %t.hello.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
 ; CHECK:        - Type:            MEMORY
@@ -57,7 +57,7 @@
 ; CHECK-NEXT:    - Type:            CUSTOM
 
 
-; RUN: wasm-ld -no-gc-sections --check-signatures --allow-undefined \
+; RUN: wasm-ld -no-gc-sections --allow-undefined --no-entry \
 ; RUN:     --initial-memory=131072 --max-memory=131072 -o %t_max.wasm %t.o \
 ; RUN:     %t.hello.o
 ; RUN: obj2yaml %t_max.wasm | FileCheck %s -check-prefix=CHECK-MAX
@@ -69,7 +69,7 @@
 ; CHECK-MAX-NEXT:         Maximum:         0x00000002
 
 
-; RUN: wasm-ld --check-signatures --relocatable -o %t_reloc.wasm %t.o %t.hello.o
+; RUN: wasm-ld --relocatable -o %t_reloc.wasm %t.o %t.hello.o
 ; RUN: obj2yaml %t_reloc.wasm | FileCheck %s -check-prefix=RELOC
 
 ; RELOC:       - Type:            DATA
@@ -119,9 +119,7 @@
 ; RELOC-NEXT:           Value:           40
 ; RELOC-NEXT:         Content:         68656C6C6F0A00
 
-; RELOC:        - Type:            CUSTOM
-; RELOC-NEXT:     Name:            linking
-; RELOC-NEXT:     SymbolTable:
+; RELOC:          SymbolTable:
 ; RELOC-NEXT:       - Index:           0
 ; RELOC-NEXT:         Kind:            DATA
 ; RELOC-NEXT:         Name:            foo
diff --git a/test/wasm/data-segment-merging.ll b/test/wasm/data-segment-merging.ll
new file mode 100644
index 0000000..d0df84d
--- /dev/null
+++ b/test/wasm/data-segment-merging.ll
@@ -0,0 +1,48 @@
+target triple = "wasm32-unknown-unknown"
+
+@a = hidden global [6 x i8] c"hello\00", align 1
+@b = hidden global [8 x i8] c"goodbye\00", align 1
+@c = hidden global [9 x i8] c"whatever\00", align 1
+@d = hidden global i32 42, align 4
+
+; RUN: llc -filetype=obj %s -o %t.data-segment-merging.o
+
+; RUN: wasm-ld -no-gc-sections --no-entry -o %t.merged.wasm %t.data-segment-merging.o
+; RUN: obj2yaml %t.merged.wasm | FileCheck %s --check-prefix=MERGE
+; MERGE:       - Type:            DATA
+; MERGE-NEXT:    Segments:
+; MERGE-NEXT:      - SectionOffset:   7
+; MERGE-NEXT:        MemoryIndex:     0
+; MERGE-NEXT:        Offset:
+; MERGE-NEXT:          Opcode:          I32_CONST
+; MERGE-NEXT:          Value:           1024
+; MERGE-NEXT:        Content:         68656C6C6F00676F6F6462796500776861746576657200002A000000
+
+; RUN: wasm-ld -no-gc-sections --no-entry --no-merge-data-segments -o %t.separate.wasm %t.data-segment-merging.o
+; RUN: obj2yaml %t.separate.wasm | FileCheck %s --check-prefix=SEPARATE
+; SEPARATE:       - Type:            DATA
+; SEPARATE-NEXT:    Segments:
+; SEPARATE-NEXT:      - SectionOffset:   7
+; SEPARATE-NEXT:        MemoryIndex:     0
+; SEPARATE-NEXT:        Offset:
+; SEPARATE-NEXT:          Opcode:          I32_CONST
+; SEPARATE-NEXT:          Value:           1024
+; SEPARATE-NEXT:        Content:         68656C6C6F00
+; SEPARATE-NEXT:      - SectionOffset:   19
+; SEPARATE-NEXT:        MemoryIndex:     0
+; SEPARATE-NEXT:        Offset:
+; SEPARATE-NEXT:          Opcode:          I32_CONST
+; SEPARATE-NEXT:          Value:           1030
+; SEPARATE-NEXT:        Content:         676F6F6462796500
+; SEPARATE-NEXT:      - SectionOffset:   33
+; SEPARATE-NEXT:        MemoryIndex:     0
+; SEPARATE-NEXT:        Offset:
+; SEPARATE-NEXT:          Opcode:          I32_CONST
+; SEPARATE-NEXT:          Value:           1038
+; SEPARATE-NEXT:        Content:         '776861746576657200'
+; SEPARATE-NEXT:      - SectionOffset:   48
+; SEPARATE-NEXT:        MemoryIndex:     0
+; SEPARATE-NEXT:        Offset:
+; SEPARATE-NEXT:          Opcode:          I32_CONST
+; SEPARATE-NEXT:          Value:           1048
+; SEPARATE-NEXT:        Content:         2A000000
diff --git a/test/wasm/debuginfo.test b/test/wasm/debuginfo.test
new file mode 100644
index 0000000..ce68a03
--- /dev/null
+++ b/test/wasm/debuginfo.test
@@ -0,0 +1,85 @@
+RUN: llc -filetype=obj %p/Inputs/debuginfo1.ll -o %t.debuginfo1.o
+RUN: llc -filetype=obj %p/Inputs/debuginfo2.ll -o %t.debuginfo2.o
+RUN: wasm-ld -o %t.wasm %t.debuginfo1.o %t.debuginfo2.o
+RUN: llvm-dwarfdump %t.wasm | FileCheck %s
+
+CHECK: file format WASM
+
+CHECK: .debug_info contents:
+CHECK: DW_TAG_compile_unit
+CHECK-NEXT:              DW_AT_producer	("clang version 7.0.0 (trunk {{.*}})")
+CHECK-NEXT:              DW_AT_language	(DW_LANG_C99)
+CHECK-NEXT:              DW_AT_name	("hi.c")
+
+CHECK:   DW_TAG_subprogram
+CHECK-NEXT:                DW_AT_low_pc
+CHECK-NEXT:                DW_AT_high_pc
+CHECK-NEXT:                DW_AT_name	("test")
+CHECK-NEXT:                DW_AT_decl_file	("/Users/yury/llvmwasm{{(/|\\)}}hi.c")
+CHECK-NEXT:                DW_AT_decl_line	(3)
+CHECK-NEXT:                DW_AT_prototyped	(true)
+
+CHECK:     DW_TAG_formal_parameter
+CHECK-NEXT:                  DW_AT_name	("t")
+CHECK-NEXT:                  DW_AT_decl_file	("/Users/yury/llvmwasm{{(/|\\)}}hi.c")
+CHECK-NEXT:                  DW_AT_decl_line	(3)
+
+CHECK:   DW_TAG_subprogram
+CHECK-NEXT:                DW_AT_low_pc
+CHECK-NEXT:                DW_AT_high_pc
+CHECK-NEXT:                DW_AT_name	("_start")
+CHECK-NEXT:                DW_AT_decl_file	("/Users/yury/llvmwasm{{(/|\\)}}hi.c")
+CHECK-NEXT:                DW_AT_decl_line	(7)
+
+CHECK:   DW_TAG_base_type
+CHECK-NEXT:                DW_AT_name	("int")
+CHECK-NEXT:                DW_AT_encoding	(DW_ATE_signed)
+CHECK-NEXT:                DW_AT_byte_size	(0x04)
+
+CHECK: DW_TAG_compile_unit
+CHECK-NEXT:              DW_AT_producer	("clang version 7.0.0 (trunk {{.*}})")
+CHECK-NEXT:              DW_AT_language	(DW_LANG_C99)
+CHECK-NEXT:              DW_AT_name	("hi_foo.c")
+
+CHECK:   DW_TAG_variable
+CHECK-NEXT:                DW_AT_name	("y")
+CHECK-NEXT:                DW_AT_type	(0x00000097 "int[]")
+CHECK-NEXT:                DW_AT_external	(true)
+CHECK-NEXT:                DW_AT_decl_file	("{{.*}}hi_foo.c")
+CHECK-NEXT:                DW_AT_decl_line	(1)
+CHECK:                     DW_AT_location	(DW_OP_addr 0x400)
+
+CHECK:   DW_TAG_array_type
+
+CHECK:     DW_TAG_subrange_type
+
+CHECK:   DW_TAG_base_type
+CHECK-NEXT:                DW_AT_name	("int")
+CHECK-NEXT:                DW_AT_encoding	(DW_ATE_signed)
+CHECK-NEXT:                DW_AT_byte_size	(0x04)
+
+CHECK:   DW_TAG_base_type
+CHECK-NEXT:                DW_AT_name	("__ARRAY_SIZE_TYPE__")
+CHECK-NEXT:                DW_AT_byte_size	(0x08)
+CHECK-NEXT:                DW_AT_encoding	(DW_ATE_unsigned)
+
+CHECK:   DW_TAG_variable
+CHECK-NEXT:                DW_AT_name	("z")
+CHECK-NEXT:                DW_AT_type	(0x00000097 "int[]")
+CHECK-NEXT:                DW_AT_external	(true)
+CHECK-NEXT:                DW_AT_decl_file	("{{.*}}hi_foo.c")
+CHECK-NEXT:                DW_AT_decl_line	(8)
+CHECK-NEXT:                DW_AT_location	(DW_OP_addr 0x0)
+
+CHECK:   DW_TAG_subprogram
+CHECK-NEXT:                DW_AT_low_pc	
+CHECK-NEXT:                DW_AT_high_pc
+CHECK-NEXT:                DW_AT_name	("foo")
+CHECK-NEXT:                DW_AT_decl_file	("{{.*}}hi_foo.c")
+CHECK-NEXT:                DW_AT_decl_line	(3)
+
+CHECK:     DW_TAG_formal_parameter
+CHECK-NEXT:                  DW_AT_name	("p")
+CHECK-NEXT:                  DW_AT_decl_file	("{{.*}}hi_foo.c")
+CHECK-NEXT:                  DW_AT_decl_line	(3)
+
diff --git a/test/wasm/demangle.ll b/test/wasm/demangle.ll
index 07f9927..f0416bb 100644
--- a/test/wasm/demangle.ll
+++ b/test/wasm/demangle.ll
@@ -1,15 +1,15 @@
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: not wasm-ld --check-signatures --undefined _Z3fooi \
+; RUN: not wasm-ld --undefined _Z3fooi \
 ; RUN:     -o %t.wasm %t.o 2>&1 | FileCheck %s
 
 ; CHECK: error: undefined symbol: foo(int)
 
-; RUN: not wasm-ld --check-signatures --no-demangle --undefined _Z3fooi \
+; RUN: not wasm-ld --no-demangle --undefined _Z3fooi \
 ; RUN:     -o %t.wasm %t.o 2>&1 |  FileCheck -check-prefix=CHECK-NODEMANGLE %s
 
 ; CHECK-NODEMANGLE: error: undefined symbol: _Z3fooi
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 define hidden void @_start() local_unnamed_addr {
 entry:
diff --git a/test/wasm/driver.ll b/test/wasm/driver.ll
index 7222cb5..22e6bc1 100644
--- a/test/wasm/driver.ll
+++ b/test/wasm/driver.ll
@@ -1,6 +1,6 @@
 ; RUN: llc -filetype=obj %s -o %t.o
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 define hidden void @entry() local_unnamed_addr #0 {
 entry:
diff --git a/test/wasm/entry-signature.ll b/test/wasm/entry-signature.ll
new file mode 100644
index 0000000..8e245b1
--- /dev/null
+++ b/test/wasm/entry-signature.ll
@@ -0,0 +1,10 @@
+; Verify that the entry point signauture can be flexible.
+; RUN: llc -filetype=obj %s -o %t.o
+; RUN: wasm-ld -o %t1.wasm %t.o
+
+target triple = "wasm32-unknown-unknown-wasm"
+
+define hidden i32 @_start(i32, i64) local_unnamed_addr #0 {
+entry:
+  ret i32 0
+}
diff --git a/test/wasm/entry.ll b/test/wasm/entry.ll
index 083bf97..30fff9a 100644
--- a/test/wasm/entry.ll
+++ b/test/wasm/entry.ll
@@ -1,15 +1,15 @@
 ; RUN: llc -filetype=obj %s -o %t.o
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 define hidden void @entry() local_unnamed_addr #0 {
 entry:
   ret void
 }
 
-; RUN: wasm-ld --check-signatures -e entry -o %t1.wasm %t.o
+; RUN: wasm-ld -e entry -o %t1.wasm %t.o
 ; RUN: obj2yaml %t1.wasm | FileCheck %s
-; RUN: wasm-ld --check-signatures --entry=entry -o %t2.wasm %t.o
+; RUN: wasm-ld --entry=entry -o %t2.wasm %t.o
 ; RUN: obj2yaml %t2.wasm | FileCheck %s
 
 ; CHECK:        - Type:            EXPORT
@@ -28,9 +28,9 @@
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:   - Type:
 
-; The __wasm_call_ctors is somewhat special.  Make sure we can use it
-; as the entry point if we choose
-; RUN: wasm-ld --check-signatures --entry=__wasm_call_ctors -o %t3.wasm %t.o
+; The __wasm_call_ctors is somewhat special since its created by the linker.
+; Make sure we can use it as the entry point if we choose
+; RUN: wasm-ld --entry=__wasm_call_ctors -o %t3.wasm %t.o
 ; RUN: obj2yaml %t3.wasm | FileCheck %s -check-prefix=CHECK-CTOR
 
 ; CHECK-CTOR:        - Type:            EXPORT
diff --git a/test/wasm/export-table.test b/test/wasm/export-table.test
index 0923af6..58775b9 100644
--- a/test/wasm/export-table.test
+++ b/test/wasm/export-table.test
@@ -1,5 +1,5 @@
 # RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.start.o
-# RUN: wasm-ld --check-signatures --export-table -o %t.wasm %t.start.o
+# RUN: wasm-ld --export-table -o %t.wasm %t.start.o
 # RUN: obj2yaml %t.wasm | FileCheck %s
 
 # Verify the --export-table flag creates a table export
diff --git a/test/wasm/export.ll b/test/wasm/export.ll
index f2a4fff..16b2b6c 100644
--- a/test/wasm/export.ll
+++ b/test/wasm/export.ll
@@ -1,9 +1,9 @@
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: not wasm-ld --check-signatures --export=missing -o %t.wasm %t.o 2>&1 | FileCheck -check-prefix=CHECK-ERROR %s
-; RUN: wasm-ld --check-signatures --export=hidden_function -o %t.wasm %t.o
+; RUN: not wasm-ld --export=missing -o %t.wasm %t.o 2>&1 | FileCheck -check-prefix=CHECK-ERROR %s
+; RUN: wasm-ld --export=hidden_function -o %t.wasm %t.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 define hidden i32 @hidden_function() local_unnamed_addr {
 entry:
diff --git a/test/wasm/fatal-warnings.ll b/test/wasm/fatal-warnings.ll
new file mode 100644
index 0000000..9bfe95e
--- /dev/null
+++ b/test/wasm/fatal-warnings.ll
@@ -0,0 +1,17 @@
+; 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
+
+; CHECK-WARN: warning: Function type mismatch: ret32
+; CHECK-FATAL: error: Function type mismatch: ret32
+
+target triple = "wasm32-unknown-unknown"
+
+define hidden void @_start() local_unnamed_addr #0 {
+entry:
+  %call = tail call i32 @ret32(i32 1, i64 2, i32 3) #2
+  ret void
+}
+
+declare i32 @ret32(i32, i64, i32) local_unnamed_addr #1
diff --git a/test/wasm/function-imports-first.ll b/test/wasm/function-imports-first.ll
index be71d7c..00c7374 100644
--- a/test/wasm/function-imports-first.ll
+++ b/test/wasm/function-imports-first.ll
@@ -1,9 +1,9 @@
 ; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: wasm-ld --check-signatures -o %t.wasm %t.o %t.ret32.o
+; RUN: wasm-ld -o %t.wasm %t.o %t.ret32.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 ; Function Attrs: nounwind
 define hidden void @_start() local_unnamed_addr #0 {
diff --git a/test/wasm/function-imports.ll b/test/wasm/function-imports.ll
index 742cec2..a2c6405 100644
--- a/test/wasm/function-imports.ll
+++ b/test/wasm/function-imports.ll
@@ -1,9 +1,9 @@
 ; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: wasm-ld --check-signatures -o %t.wasm %t.ret32.o %t.o
+; RUN: wasm-ld -o %t.wasm %t.ret32.o %t.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 ; Function Attrs: nounwind
 define hidden void @_start() local_unnamed_addr #0 {
diff --git a/test/wasm/function-index.test b/test/wasm/function-index.test
index 8784271..82f5d0c 100644
--- a/test/wasm/function-index.test
+++ b/test/wasm/function-index.test
@@ -1,6 +1,6 @@
 # RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
 # RUN: llc -filetype=obj %p/Inputs/ret64.ll -o %t.ret64.o
-# RUN: wasm-ld --check-signatures -r -o %t.wasm %t.ret32.o %t.ret64.o
+# RUN: wasm-ld -r -o %t.wasm %t.ret32.o %t.ret64.o
 # RUN: obj2yaml %t.wasm | FileCheck %s
 
 CHECK: Sections:
diff --git a/test/wasm/gc-imports.ll b/test/wasm/gc-imports.ll
new file mode 100644
index 0000000..066cd88
--- /dev/null
+++ b/test/wasm/gc-imports.ll
@@ -0,0 +1,111 @@
+; RUN: llc -filetype=obj %s -o %t.o
+; RUN: yaml2obj %S/Inputs/undefined-globals.yaml -o %t_globals.o
+; RUN: wasm-ld -print-gc-sections --allow-undefined -o %t1.wasm %t.o %t_globals.o
+
+target triple = "wasm32-unknown-unknown"
+
+declare hidden i64 @unused_undef_function(i64 %arg)
+
+declare hidden i32 @used_undef_function()
+
+declare i64 @use_undef_global()
+
+define hidden void @_start() {
+entry:
+  call i32 @used_undef_function()
+  call i64 @use_undef_global()
+  ret void
+}
+
+; RUN: obj2yaml %t1.wasm | FileCheck %s
+
+; CHECK:        - Type:            TYPE
+; CHECK-NEXT:     Signatures:
+; CHECK-NEXT:       - Index:           0
+; CHECK-NEXT:         ReturnType:      I32
+; CHECK-NEXT:         ParamTypes:
+; CHECK-NEXT:       - Index:           1
+; CHECK-NEXT:         ReturnType:      NORESULT
+; CHECK-NEXT:         ParamTypes:
+; CHECK-NEXT:       - Index:           2
+; CHECK-NEXT:         ReturnType:      I64
+; CHECK-NEXT:         ParamTypes:
+; CHECK-NEXT:   - Type:            IMPORT
+; CHECK-NEXT:     Imports:
+; CHECK-NEXT:       - Module:          env
+; CHECK-NEXT:         Field:           used_undef_function
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         SigIndex:        0
+; CHECK-NEXT:       - Module:          env
+; CHECK-NEXT:         Field:           used_undef_global
+; CHECK-NEXT:         Kind:            GLOBAL
+; CHECK-NEXT:         GlobalType:      I64
+; CHECK-NEXT:         GlobalMutable:   true
+; CHECK-NEXT:   - Type:
+; CHECK:        - Type:            CUSTOM
+; CHECK-NEXT:     Name:            name
+; CHECK-NEXT:     FunctionNames:
+; CHECK-NEXT:       - Index:           0
+; CHECK-NEXT:         Name:            used_undef_function
+; CHECK-NEXT:       - Index:           1
+; CHECK-NEXT:         Name:            __wasm_call_ctors
+; CHECK-NEXT:       - Index:           2
+; CHECK-NEXT:         Name:            _start
+; CHECK-NEXT:       - Index:           3
+; CHECK-NEXT:         Name:            use_undef_global
+; CHECK-NEXT: ...
+
+; RUN: wasm-ld -print-gc-sections --no-gc-sections --allow-undefined \
+; RUN:     -o %t1.no-gc.wasm %t.o %t_globals.o
+; RUN: obj2yaml %t1.no-gc.wasm | FileCheck %s -check-prefix=NO-GC
+
+; NO-GC:        - Type:            TYPE
+; NO-GC-NEXT:     Signatures:
+; NO-GC-NEXT:       - Index:           0
+; NO-GC-NEXT:         ReturnType:      I32
+; NO-GC-NEXT:         ParamTypes:
+; NO-GC-NEXT:       - Index:           1
+; NO-GC-NEXT:         ReturnType:      I64
+; NO-GC-NEXT:         ParamTypes:
+; NO-GC-NEXT:           - I64
+; NO-GC-NEXT:       - Index:           2
+; NO-GC-NEXT:         ReturnType:      NORESULT
+; NO-GC-NEXT:         ParamTypes:
+; NO-GC-NEXT:       - Index:           3
+; NO-GC-NEXT:         ReturnType:      I64
+; NO-GC-NEXT:         ParamTypes:
+; NO-GC-NEXT:   - Type:            IMPORT
+; NO-GC-NEXT:     Imports:
+; NO-GC-NEXT:       - Module:          env
+; NO-GC-NEXT:         Field:           used_undef_function
+; NO-GC-NEXT:         Kind:            FUNCTION
+; NO-GC-NEXT:         SigIndex:        0
+; NO-GC-NEXT:       - Module:          env
+; NO-GC-NEXT:         Field:           unused_undef_function
+; NO-GC-NEXT:         Kind:            FUNCTION
+; NO-GC-NEXT:         SigIndex:        1
+; NO-GC-NEXT:       - Module:          env
+; NO-GC-NEXT:         Field:           unused_undef_global
+; NO-GC-NEXT:         Kind:            GLOBAL
+; NO-GC-NEXT:         GlobalType:      I64
+; NO-GC-NEXT:         GlobalMutable:   true
+; NO-GC-NEXT:       - Module:          env
+; NO-GC-NEXT:         Field:           used_undef_global
+; NO-GC-NEXT:         Kind:            GLOBAL
+; NO-GC-NEXT:         GlobalType:      I64
+; NO-GC-NEXT:         GlobalMutable:   true
+; NO-GC-NEXT:   - Type:
+; NO-GC:        - Type:            CUSTOM
+; NO-GC-NEXT:     Name:            name
+; NO-GC-NEXT:     FunctionNames:
+; NO-GC-NEXT:       - Index:           0
+; NO-GC-NEXT:         Name:            used_undef_function
+; NO-GC-NEXT:       - Index:           1
+; NO-GC-NEXT:         Name:            unused_undef_function
+; NO-GC-NEXT:       - Index:           2
+; NO-GC-NEXT:         Name:            __wasm_call_ctors
+; NO-GC-NEXT:       - Index:           3
+; NO-GC-NEXT:         Name:            _start
+; NO-GC-NEXT:       - Index:           4
+; NO-GC-NEXT:         Name:            use_undef_global
+; NO-GC-NEXT: ...
diff --git a/test/wasm/gc-sections.ll b/test/wasm/gc-sections.ll
index dec455e..57b6973 100644
--- a/test/wasm/gc-sections.ll
+++ b/test/wasm/gc-sections.ll
@@ -1,16 +1,20 @@
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: wasm-ld -print-gc-sections -o %t1.wasm %t.o | FileCheck %s -check-prefix=PRINT-GC
+; RUN: yaml2obj %S/Inputs/globals.yaml -o %t_globals.o
+; RUN: wasm-ld -print-gc-sections -o %t1.wasm %t.o %t_globals.o | \
+; RUN:     FileCheck %s -check-prefix=PRINT-GC
 ; PRINT-GC: removing unused section {{.*}}:(unused_function)
 ; PRINT-GC-NOT: removing unused section {{.*}}:(used_function)
 ; PRINT-GC: removing unused section {{.*}}:(.data.unused_data)
 ; PRINT-GC-NOT: removing unused section {{.*}}:(.data.used_data)
+; PRINT-GC: removing unused section {{.*}}:(unused_global)
+; PRINT-GC-NOT: removing unused section {{.*}}:(used_global)
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 @unused_data = hidden global i64 1, align 4
 @used_data = hidden global i32 2, align 4
 
-define hidden i64 @unused_function() {
+define hidden i64 @unused_function(i64 %arg) {
   %1 = load i64, i64* @unused_data, align 4
   ret i64 %1
 }
@@ -20,24 +24,45 @@
   ret i32 %1
 }
 
+declare i64 @use_global()
+
 define hidden void @_start() {
 entry:
   call i32 @used_function()
+  call i64 @use_global()
   ret void
 }
 
 ; RUN: obj2yaml %t1.wasm | FileCheck %s
 
 ; CHECK:        - Type:            TYPE
-; CHECK-NEXT:     Signatures:      
+; CHECK-NEXT:     Signatures:
 ; CHECK-NEXT:       - Index:           0
 ; CHECK-NEXT:         ReturnType:      NORESULT
-; CHECK-NEXT:         ParamTypes:      
+; CHECK-NEXT:         ParamTypes:
 ; CHECK-NEXT:       - Index:           1
 ; CHECK-NEXT:         ReturnType:      I32
-; CHECK-NEXT:         ParamTypes:      
+; CHECK-NEXT:         ParamTypes:
+; CHECK-NEXT:       - Index:           2
+; CHECK-NEXT:         ReturnType:      I64
+; CHECK-NEXT:         ParamTypes:
 ; CHECK-NEXT:   - Type:            FUNCTION
 
+; CHECK:        - Type:            GLOBAL
+; CHECK-NEXT:     Globals:
+; CHECK-NEXT:       - Index:           0
+; CHECK-NEXT:         Type:            I32
+; CHECK-NEXT:         Mutable:         true
+; CHECK-NEXT:         InitExpr:
+; CHECK-NEXT:           Opcode:          I32_CONST
+; CHECK-NEXT:           Value:           66576
+; CHECK-NEXT:       - Index:       1
+; CHECK-NEXT:         Type:        I64
+; CHECK-NEXT:         Mutable:     true
+; CHECK-NEXT:         InitExpr:
+; CHECK-NEXT:           Opcode:          I64_CONST
+; CHECK-NEXT:           Value:           456
+
 ; CHECK:        - Type:            DATA
 ; CHECK-NEXT:     Segments:        
 ; CHECK-NEXT:       - SectionOffset:   7
@@ -55,24 +80,52 @@
 ; CHECK-NEXT:         Name:            used_function
 ; CHECK-NEXT:       - Index:           2
 ; CHECK-NEXT:         Name:            _start
+; CHECK-NEXT:       - Index:           3
+; CHECK-NEXT:         Name:            use_global
 ; CHECK-NEXT: ...
 
-; RUN: wasm-ld -print-gc-sections --no-gc-sections -o %t1.no-gc.wasm %t.o
+; RUN: wasm-ld -print-gc-sections --no-gc-sections -o %t1.no-gc.wasm \
+; RUN:     %t.o %t_globals.o
 ; RUN: obj2yaml %t1.no-gc.wasm | FileCheck %s -check-prefix=NO-GC
 
 ; NO-GC:        - Type:            TYPE
-; NO-GC-NEXT:     Signatures:      
+; NO-GC-NEXT:     Signatures:
 ; NO-GC-NEXT:       - Index:           0
 ; NO-GC-NEXT:         ReturnType:      NORESULT
 ; NO-GC-NEXT:         ParamTypes:
 ; NO-GC-NEXT:       - Index:           1
 ; NO-GC-NEXT:         ReturnType:      I64
-; NO-GC-NEXT:         ParamTypes:      
+; NO-GC-NEXT:         ParamTypes:
+; NO-GC-NEXT:           - I64
 ; NO-GC-NEXT:       - Index:           2
 ; NO-GC-NEXT:         ReturnType:      I32
-; NO-GC-NEXT:         ParamTypes:      
+; NO-GC-NEXT:         ParamTypes:
+; NO-GC-NEXT:       - Index:           3
+; NO-GC-NEXT:         ReturnType:      I64
+; NO-GC-NEXT:         ParamTypes:
 ; NO-GC-NEXT:   - Type:            FUNCTION
 
+; NO-GC:        - Type:            GLOBAL
+; NO-GC-NEXT:     Globals:
+; NO-GC-NEXT:       - Index:           0
+; NO-GC-NEXT:         Type:            I32
+; NO-GC-NEXT:         Mutable:         true
+; NO-GC-NEXT:         InitExpr:
+; NO-GC-NEXT:           Opcode:          I32_CONST
+; NO-GC-NEXT:           Value:           66576
+; NO-GC-NEXT:       - Index:       1
+; NO-GC-NEXT:         Type:        I64
+; NO-GC-NEXT:         Mutable:     true
+; NO-GC-NEXT:         InitExpr:
+; NO-GC-NEXT:           Opcode:          I64_CONST
+; NO-GC-NEXT:           Value:           123
+; NO-GC-NEXT:       - Index:       2
+; NO-GC-NEXT:         Type:        I64
+; NO-GC-NEXT:         Mutable:     true
+; NO-GC-NEXT:         InitExpr:
+; NO-GC-NEXT:           Opcode:          I64_CONST
+; NO-GC-NEXT:           Value:           456
+
 ; NO-GC:        - Type:            DATA
 ; NO-GC-NEXT:     Segments:        
 ; NO-GC-NEXT:       - SectionOffset:   7
@@ -92,6 +145,8 @@
 ; NO-GC-NEXT:         Name:            used_function
 ; NO-GC-NEXT:       - Index:           3
 ; NO-GC-NEXT:         Name:            _start
+; NO-GC-NEXT:       - Index:           4
+; NO-GC-NEXT:         Name:            use_global
 ; NO-GC-NEXT: ...
 
 ; RUN: not wasm-ld --gc-sections --relocatable -o %t1.no-gc.wasm %t.o 2>&1 | FileCheck %s -check-prefix=CHECK-ERROR
diff --git a/test/wasm/import-memory.test b/test/wasm/import-memory.test
index 955d2df..49bf06b 100644
--- a/test/wasm/import-memory.test
+++ b/test/wasm/import-memory.test
@@ -1,5 +1,5 @@
 # RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.start.o
-# RUN: wasm-ld --check-signatures --import-memory -o %t.wasm %t.start.o
+# RUN: wasm-ld --import-memory -o %t.wasm %t.start.o
 # RUN: obj2yaml %t.wasm | FileCheck %s
 
 # Verify the --import-memory flag creates a memory import
@@ -15,7 +15,7 @@
 
 
 
-# RUN: wasm-ld --check-signatures --import-memory --initial-memory=262144 \
+# RUN: wasm-ld --import-memory --initial-memory=262144 \
 # RUN:     --max-memory=327680 -o %t.max.wasm %t.start.o
 # RUN: obj2yaml %t.max.wasm | FileCheck -check-prefix=CHECK-MAX %s
 
diff --git a/test/wasm/import-table.test b/test/wasm/import-table.test
index 98e0749..eb76709 100644
--- a/test/wasm/import-table.test
+++ b/test/wasm/import-table.test
@@ -1,5 +1,5 @@
 # RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.start.o
-# RUN: wasm-ld --check-signatures --import-table -o %t.wasm %t.start.o
+# RUN: wasm-ld --import-table -o %t.wasm %t.start.o
 # RUN: obj2yaml %t.wasm | FileCheck %s
 
 # Verify the --import-table flag creates a table import
diff --git a/test/wasm/init-fini.ll b/test/wasm/init-fini.ll
index 1ca2008..9a7f535 100644
--- a/test/wasm/init-fini.ll
+++ b/test/wasm/init-fini.ll
@@ -1,7 +1,7 @@
 ; RUN: llc -filetype=obj -o %t.o %s
 ; RUN: llc -filetype=obj %S/Inputs/global-ctor-dtor.ll -o %t.global-ctor-dtor.o
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 define hidden void @func1() {
 entry:
@@ -49,7 +49,7 @@
   { i32, void ()*, i8* } { i32 4000, void ()* @externDtor, i8* null }
 ]
 
-; RUN: wasm-ld --check-signatures --allow-undefined %t.o %t.global-ctor-dtor.o -o %t.wasm
+; RUN: wasm-ld --allow-undefined %t.o %t.global-ctor-dtor.o -o %t.wasm
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
 ; CHECK:        - Type:            IMPORT
@@ -128,11 +128,10 @@
 ; CHECK-NEXT: ...
 
 
-; RUN: wasm-ld --check-signatures -r %t.o %t.global-ctor-dtor.o -o %t.reloc.wasm
+; RUN: wasm-ld -r %t.o %t.global-ctor-dtor.o -o %t.reloc.wasm
 ; RUN: obj2yaml %t.reloc.wasm | FileCheck -check-prefix=RELOC %s
 
-; RELOC:          Name:            linking
-; RELOC-NEXT:     SymbolTable:
+; RELOC:          SymbolTable:
 ; RELOC-NEXT:       - Index:           0
 ; RELOC-NEXT:         Kind:            FUNCTION
 ; RELOC-NEXT:         Name:            func1
diff --git a/test/wasm/invalid-stack-size.test b/test/wasm/invalid-stack-size.test
index da47c68..90c9fda 100644
--- a/test/wasm/invalid-stack-size.test
+++ b/test/wasm/invalid-stack-size.test
@@ -1,4 +1,4 @@
 ; RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.o
-; RUN: not wasm-ld --check-signatures -o %t.wasm -z stack-size=1 %t.o 2>&1 | FileCheck %s
+; RUN: not wasm-ld -o %t.wasm -z stack-size=1 %t.o 2>&1 | FileCheck %s
 
 ; CHECK: error: stack size must be 16-byte aligned
diff --git a/test/wasm/load-undefined.test b/test/wasm/load-undefined.test
index 7e78bf0..52a4a04 100644
--- a/test/wasm/load-undefined.test
+++ b/test/wasm/load-undefined.test
@@ -5,7 +5,7 @@
 ; RUN: llc -filetype=obj %S/Inputs/ret32.ll -o %t2.o
 ; RUN: llc -filetype=obj %S/Inputs/start.ll -o %t.start.o
 ; RUN: llvm-ar rcs %t2.a %t2.o
-; RUN: wasm-ld --check-signatures %t.start.o %t2.a %t.o -o %t.wasm -u ret32 --undefined ret64
+; RUN: wasm-ld %t.start.o %t2.a %t.o -o %t.wasm -u ret32 --undefined ret64
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
 ; CHECK:        - Type:            EXPORT
@@ -32,8 +32,8 @@
 
 
 ; Verify that referencing a symbol that doesn't exist won't work
-; RUN: not wasm-ld --check-signatures %t.start.o -o %t.wasm -u symboldoesnotexist 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED1 %s
+; RUN: not wasm-ld %t.start.o -o %t.wasm -u symboldoesnotexist 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED1 %s
 ; CHECK-UNDEFINED1: error: undefined symbol: symboldoesnotexist
 
-; RUN: not wasm-ld --check-signatures %t.start.o -o %t.wasm --undefined symboldoesnotexist --allow-undefined 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED2 %s
-; CHECK-UNDEFINED2: function forced with --undefined not found: symboldoesnotexist
+; RUN: not wasm-ld %t.start.o -o %t.wasm --undefined symboldoesnotexist --allow-undefined 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED2 %s
+; CHECK-UNDEFINED2: symbol forced with --undefined not found: symboldoesnotexist
diff --git a/test/wasm/local-symbols.ll b/test/wasm/local-symbols.ll
index fcb3c42..5471466 100644
--- a/test/wasm/local-symbols.ll
+++ b/test/wasm/local-symbols.ll
@@ -1,8 +1,8 @@
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: wasm-ld --check-signatures -o %t.wasm %t.o
+; RUN: wasm-ld -o %t.wasm %t.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 @foo = default global i32 1, align 4
 @bar = internal default global i32 3, align 4
diff --git a/test/wasm/locals-duplicate.test b/test/wasm/locals-duplicate.test
index 017bc09..3c67cdd 100644
--- a/test/wasm/locals-duplicate.test
+++ b/test/wasm/locals-duplicate.test
@@ -1,6 +1,6 @@
 ; RUN: llc -filetype=obj %p/Inputs/locals-duplicate1.ll -o %t1.o
 ; RUN: llc -filetype=obj %p/Inputs/locals-duplicate2.ll -o %t2.o
-; RUN: wasm-ld --check-signatures --no-entry -o %t.wasm %t1.o %t2.o
+; RUN: wasm-ld --no-entry -o %t.wasm %t1.o %t2.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
 ; CHECK:      --- !WASM
@@ -236,7 +236,7 @@
 ; CHECK-NEXT: ...
 
 
-; RUN: wasm-ld --check-signatures -r --no-entry -o %t.reloc.wasm %t1.o %t2.o
+; RUN: wasm-ld -r --no-entry -o %t.reloc.wasm %t1.o %t2.o
 ; RUN: obj2yaml %t.reloc.wasm | FileCheck -check-prefix=RELOC %s
 
 ; RELOC:      --- !WASM
@@ -382,6 +382,7 @@
 ; RELOC-NEXT:         Content:         '0000000000000000'
 ; RELOC-NEXT:   - Type:            CUSTOM
 ; RELOC-NEXT:     Name:            linking
+; RELOC-NEXT:     Version:         1
 ; RELOC-NEXT:     SymbolTable:
 ; RELOC-NEXT:       - Index:           0
 ; RELOC-NEXT:         Kind:            FUNCTION
diff --git a/test/wasm/lto/Inputs/cache.ll b/test/wasm/lto/Inputs/cache.ll
new file mode 100644
index 0000000..a66f36a
--- /dev/null
+++ b/test/wasm/lto/Inputs/cache.ll
@@ -0,0 +1,10 @@
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+define i32 @_start() {
+entry:
+  call void (...) @globalfunc()
+  ret i32 0
+}
+
+declare void @globalfunc(...)
diff --git a/test/wasm/lto/Inputs/save-temps.ll b/test/wasm/lto/Inputs/save-temps.ll
new file mode 100644
index 0000000..6f4de41
--- /dev/null
+++ b/test/wasm/lto/Inputs/save-temps.ll
@@ -0,0 +1,6 @@
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+define void @bar() {
+  ret void
+}
diff --git a/test/wasm/lto/Inputs/thinlto.ll b/test/wasm/lto/Inputs/thinlto.ll
new file mode 100644
index 0000000..39e573b
--- /dev/null
+++ b/test/wasm/lto/Inputs/thinlto.ll
@@ -0,0 +1,7 @@
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+define void @g() {
+entry:
+  ret void
+}
diff --git a/test/wasm/lto/cache.ll b/test/wasm/lto/cache.ll
new file mode 100644
index 0000000..b0a7820
--- /dev/null
+++ b/test/wasm/lto/cache.ll
@@ -0,0 +1,38 @@
+; RUN: opt -module-hash -module-summary %s -o %t.o
+; RUN: opt -module-hash -module-summary %p/Inputs/cache.ll -o %t2.o
+
+; RUN: rm -Rf %t.cache && mkdir %t.cache
+; Create two files that would be removed by cache pruning due to age.
+; We should only remove files matching the pattern "llvmcache-*".
+; RUN: touch -t 197001011200 %t.cache/llvmcache-foo %t.cache/foo
+; RUN: wasm-ld --thinlto-cache-dir=%t.cache --thinlto-cache-policy prune_after=1h:prune_interval=0s -o %t.wasm %t2.o %t.o
+
+; Two cached objects, plus a timestamp file and "foo", minus the file we removed.
+; RUN: ls %t.cache | count 4
+
+; Create a file of size 64KB.
+; RUN: "%python" -c "print(' ' * 65536)" > %t.cache/llvmcache-foo
+
+; This should leave the file in place.
+; RUN: wasm-ld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=128k:prune_interval=0s -o %t.wasm %t2.o %t.o
+; RUN: ls %t.cache | count 5
+
+; This should remove it.
+; RUN: wasm-ld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=32k:prune_interval=0s -o %t.wasm %t2.o %t.o
+; RUN: ls %t.cache | count 4
+
+; Setting max number of files to 0 should disable the limit, not delete everything.
+; RUN: wasm-ld --thinlto-cache-dir=%t.cache --thinlto-cache-policy prune_after=0s:cache_size=0%:cache_size_files=0:prune_interval=0s -o %t.wasm %t2.o %t.o
+; RUN: ls %t.cache | count 4
+
+; Delete everything except for the timestamp, "foo" and one cache file.
+; RUN: wasm-ld --thinlto-cache-dir=%t.cache --thinlto-cache-policy prune_after=0s:cache_size=0%:cache_size_files=1:prune_interval=0s -o %t.wasm %t2.o %t.o
+; RUN: ls %t.cache | count 3
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown-wasm"
+
+define void @globalfunc() #0 {
+entry:
+  ret void
+}
diff --git a/test/wasm/lto/incompatible.ll b/test/wasm/lto/incompatible.ll
new file mode 100644
index 0000000..ee98cb4
--- /dev/null
+++ b/test/wasm/lto/incompatible.ll
@@ -0,0 +1,8 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.bc
+; RUN: not wasm-ld %t.bc -o out.wasm 2>&1 | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; CHECK: {{.*}}incompatible.ll.tmp.bc: machine type must be wasm32
diff --git a/test/wasm/lto/internalize-basic.ll b/test/wasm/lto/internalize-basic.ll
new file mode 100644
index 0000000..313a05e
--- /dev/null
+++ b/test/wasm/lto/internalize-basic.ll
@@ -0,0 +1,20 @@
+; RUN: llvm-as %s -o %t.o
+; RUN: wasm-ld %t.o -o %t2 -save-temps
+; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown-wasm"
+
+define void @_start() {
+  ret void
+}
+
+define hidden void @foo() {
+  ret void
+}
+
+; Check that _start is not internalized.
+; CHECK: define void @_start()
+
+; Check that foo function is correctly internalized.
+; CHECK: define internal void @foo()
diff --git a/test/wasm/lto/lto-start.ll b/test/wasm/lto/lto-start.ll
new file mode 100644
index 0000000..6e8f99c
--- /dev/null
+++ b/test/wasm/lto/lto-start.ll
@@ -0,0 +1,18 @@
+; RUN: llvm-as %s -o %t.o
+; RUN: wasm-ld %t.o -o %t.wasm
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+; CHECK:        - Type:            CUSTOM
+; CHECK-NEXT:     Name:            name
+; CHECK-NEXT:     FunctionNames:   
+; CHECK-NEXT:       - Index:           0
+; CHECK-NEXT:         Name:            __wasm_call_ctors
+; CHECK-NEXT:       - Index:           1
+; CHECK-NEXT:         Name:            _start
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown-wasm"
+
+define void @_start() {
+  ret void
+}
diff --git a/test/wasm/lto/opt-level.ll b/test/wasm/lto/opt-level.ll
new file mode 100644
index 0000000..b7e6a4c
--- /dev/null
+++ b/test/wasm/lto/opt-level.ll
@@ -0,0 +1,30 @@
+; RUN: llvm-as -o %t.o %s
+; RUN: wasm-ld -o %t0 -e main --lto-O0 %t.o
+; RUN: obj2yaml %t0 | FileCheck --check-prefix=CHECK-O0 %s
+; RUN: wasm-ld -o %t2 -e main --lto-O2 %t.o
+; RUN: obj2yaml %t2 | FileCheck --check-prefix=CHECK-O2 %s
+; RUN: wasm-ld -o %t2a -e main %t.o
+; 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:   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:   FileCheck --check-prefix=INVALIDNEGATIVE %s
+; INVALIDNEGATIVE: invalid optimization level for LTO: 4294967295
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown-wasm"
+
+; CHECK-O0: Name: foo
+; CHECK-O2-NOT: Name: foo
+define internal void @foo() {
+  ret void
+}
+
+define void @main() {
+  call void @foo()
+  ret void
+}
diff --git a/test/wasm/lto/parallel.ll b/test/wasm/lto/parallel.ll
new file mode 100644
index 0000000..a93c355
--- /dev/null
+++ b/test/wasm/lto/parallel.ll
@@ -0,0 +1,24 @@
+; RUN: llvm-as -o %t.bc %s
+; RUN: rm -f %t.lto.o %t1.lto.o
+; RUN: wasm-ld --lto-partitions=2 -save-temps -o %t %t.bc -r
+; RUN: llvm-nm %t.lto.o | FileCheck --check-prefix=CHECK0 %s
+; RUN: llvm-nm %t1.lto.o | FileCheck --check-prefix=CHECK1 %s
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown-wasm"
+
+; CHECK0-NOT: bar
+; CHECK0: T foo
+; CHECK0-NOT: bar
+define void @foo() {
+  call void @bar()
+  ret void
+}
+
+; CHECK1-NOT: foo
+; CHECK1: T bar
+; CHECK1-NOT: foo
+define void @bar() {
+  call void @foo()
+  ret void
+}
diff --git a/test/wasm/lto/save-temps.ll b/test/wasm/lto/save-temps.ll
new file mode 100644
index 0000000..2734d86
--- /dev/null
+++ b/test/wasm/lto/save-temps.ll
@@ -0,0 +1,19 @@
+; RUN: cd %T
+; RUN: rm -f a.out a.out.lto.bc a.out.lto.o
+; RUN: llvm-as %s -o %t.o
+; RUN: llvm-as %p/Inputs/save-temps.ll -o %t2.o
+; RUN: wasm-ld -r -o a.out %t.o %t2.o -save-temps
+; RUN: llvm-nm a.out | FileCheck %s
+; RUN: llvm-nm a.out.0.0.preopt.bc | FileCheck %s
+; RUN: llvm-nm a.out.lto.o | FileCheck %s
+; RUN: llvm-dis a.out.0.0.preopt.bc
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+define void @foo() {
+  ret void
+}
+
+; CHECK: T bar
+; CHECK: T foo
diff --git a/test/wasm/lto/thinlto.ll b/test/wasm/lto/thinlto.ll
new file mode 100644
index 0000000..062da1a
--- /dev/null
+++ b/test/wasm/lto/thinlto.ll
@@ -0,0 +1,34 @@
+; Basic ThinLTO tests.
+; RUN: opt -module-summary %s -o %t1.o
+; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o
+
+; First force single-threaded mode
+; RUN: rm -f %t31.lto.o %t32.lto.o
+; RUN: wasm-ld -r -save-temps --thinlto-jobs=1 %t1.o %t2.o -o %t3
+; RUN: llvm-nm %t31.lto.o | FileCheck %s --check-prefix=NM1
+; RUN: llvm-nm %t32.lto.o | FileCheck %s --check-prefix=NM2
+
+; Next force multi-threaded mode
+; RUN: rm -f %t31.lto.o %t32.lto.o
+; RUN: wasm-ld -r -save-temps --thinlto-jobs=2 %t1.o %t2.o -o %t3
+; RUN: llvm-nm %t31.lto.o | FileCheck %s --check-prefix=NM1
+; RUN: llvm-nm %t32.lto.o | FileCheck %s --check-prefix=NM2
+
+; Check without --thinlto-jobs (which currently default to hardware_concurrency)
+; RUN: wasm-ld -r %t1.o %t2.o -o %t3
+; RUN: llvm-nm %t31.lto.o | FileCheck %s --check-prefix=NM1
+; RUN: llvm-nm %t32.lto.o | FileCheck %s --check-prefix=NM2
+
+; NM1: T f
+; NM2: T g
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+declare void @g(...)
+
+define void @f() {
+entry:
+  call void (...) @g()
+  ret void
+}
diff --git a/test/wasm/lto/verify-invalid.ll b/test/wasm/lto/verify-invalid.ll
new file mode 100644
index 0000000..c4a5bcd
--- /dev/null
+++ b/test/wasm/lto/verify-invalid.ll
@@ -0,0 +1,16 @@
+; RUN: llvm-as %s -o %t.o
+; RUN: wasm-ld %t.o -o %t2 -mllvm -debug-pass=Arguments \
+; RUN:   2>&1 | FileCheck -check-prefix=DEFAULT %s
+; RUN: wasm-ld %t.o -o %t2 -mllvm -debug-pass=Arguments \
+; RUN:   -disable-verify 2>&1 | FileCheck -check-prefix=DISABLE %s
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+define void @_start() {
+  ret void
+}
+
+; -disable-verify should disable the verification of bitcode.
+; DEFAULT:     Pass Arguments: {{.*}} -verify {{.*}} -verify
+; DISABLE-NOT: Pass Arguments: {{.*}} -verify {{.*}} -verify
diff --git a/test/wasm/lto/weak.ll b/test/wasm/lto/weak.ll
new file mode 100644
index 0000000..03a017c
--- /dev/null
+++ b/test/wasm/lto/weak.ll
@@ -0,0 +1,16 @@
+; RUN: llvm-as %s -o %t.o
+; RUN: wasm-ld %t.o %t.o -o %t.wasm -r
+; RUN: llvm-readobj -t %t.wasm | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown-wasm"
+
+define weak void @f() {
+  ret void
+}
+
+; CHECK:        Symbol {
+; CHECK-NEXT:     Name: f
+; CHECK-NEXT:     Type: FUNCTION (0x0)
+; CHECK-NEXT:     Flags: 0x1
+; CHECK-NEXT:   }
diff --git a/test/wasm/many-functions.ll b/test/wasm/many-functions.ll
index 9d08c67..02ad9aa 100644
--- a/test/wasm/many-functions.ll
+++ b/test/wasm/many-functions.ll
@@ -1,6 +1,6 @@
 ; RUN: llc -filetype=obj %p/Inputs/many-funcs.ll -o %t.many.o
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: wasm-ld --check-signatures -r -o %t.wasm %t.many.o %t.o
+; RUN: wasm-ld -r -o %t.wasm %t.many.o %t.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
 ; Test that relocations within the CODE section correctly handle
@@ -8,7 +8,7 @@
 ; 128 function and so the final output requires a 2-byte LEB in
 ; the CODE section header to store the function count.
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 define i32 @func() {
 entry:
@@ -815,6 +815,7 @@
 ; CHECK-NEXT:         Content:         '01000000'
 ; CHECK-NEXT:   - Type:            CUSTOM
 ; CHECK-NEXT:     Name:            linking
+; CHECK-NEXT:     Version:         1
 ; CHECK-NEXT:     SymbolTable:
 ; CHECK-NEXT:       - Index:           0
 ; CHECK-NEXT:         Kind:            FUNCTION
diff --git a/test/wasm/reloc-addend.ll b/test/wasm/reloc-addend.ll
new file mode 100644
index 0000000..f678a3d
--- /dev/null
+++ b/test/wasm/reloc-addend.ll
@@ -0,0 +1,19 @@
+; RUN: llc -filetype=obj %s -o %t.o
+; RUN: wasm-ld -r -o %t.wasm %t.o
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+@foo = hidden global [76 x i32] zeroinitializer, align 16
+
+; bar points to the 16th element, which happens to be 64 bytes
+; This generates an addend of 64 which, is the value at which
+; signed and unsigned LEB encodes will differ.
+@bar = hidden local_unnamed_addr global i32* getelementptr inbounds ([76 x i32], [76 x i32]* @foo, i32 0, i32 16), align 4
+
+; CHECK:        - Type:            DATA
+; CHECK-NEXT:     Relocations:     
+; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_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 2c3cf61..4e8a887 100644
--- a/test/wasm/relocatable.ll
+++ b/test/wasm/relocatable.ll
@@ -1,9 +1,9 @@
 ; RUN: llc -filetype=obj %p/Inputs/hello.ll -o %t.hello.o
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: wasm-ld --check-signatures -r -o %t.wasm %t.hello.o %t.o
+; RUN: wasm-ld -r -o %t.wasm %t.hello.o %t.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 ; Function Attrs: nounwind
 define hidden i32 @my_func() local_unnamed_addr {
@@ -157,6 +157,7 @@
 ; CHECK-NEXT:         Content:         '616263'
 ; CHECK-NEXT:   - Type:            CUSTOM
 ; CHECK-NEXT:     Name:            linking
+; CHECK-NEXT:     Version:         1
 ; CHECK-NEXT:     SymbolTable:
 ; CHECK-NEXT:       - Index:           0
 ; CHECK-NEXT:         Kind:            FUNCTION
diff --git a/test/wasm/responsefile.test b/test/wasm/responsefile.test
new file mode 100644
index 0000000..d5e262c
--- /dev/null
+++ b/test/wasm/responsefile.test
@@ -0,0 +1,10 @@
+RUN: llc -filetype=obj -o %t.o %p/Inputs/ret32.ll
+
+RUN: echo "%t.o -o %t.wasm -e ret32" > %t.rsp
+RUN: wasm-ld @%t.rsp --initial-memory=655360
+RUN: llvm-readobj --sections %t.wasm | FileCheck %s
+CHECK: InitialPages: 10
+
+RUN: echo "blah\foo" > %t.rsp
+RUN: not wasm-ld @%t.rsp 2>&1 | FileCheck --check-prefix=ESCAPE %s
+ESCAPE: error: cannot open blahfoo: No such file or directory
diff --git a/test/wasm/signature-mismatch-weak.ll b/test/wasm/signature-mismatch-weak.ll
index fcf9646..8123b60 100644
--- a/test/wasm/signature-mismatch-weak.ll
+++ b/test/wasm/signature-mismatch-weak.ll
@@ -1,10 +1,9 @@
 ; RUN: llc -filetype=obj %p/Inputs/weak-symbol1.ll -o %t.weak.o
 ; RUN: llc -filetype=obj %p/Inputs/strong-symbol.ll -o %t.strong.o
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: not wasm-ld --check-signatures -o %t.wasm %t.o %t.strong.o %t.weak.o 2>&1 | FileCheck %s
-; RUN: wasm-ld -o %t.wasm %t.o %t.strong.o %t.weak.o
+; RUN: wasm-ld -o %t.wasm %t.o %t.strong.o %t.weak.o 2>&1 | FileCheck %s
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 declare i32 @weakFn() local_unnamed_addr
 
@@ -14,6 +13,6 @@
   ret void
 }
 
-; CHECK: error: Function type mismatch: weakFn
+; CHECK: warning: Function type mismatch: weakFn
 ; CHECK-NEXT: >>> defined as () -> I32 in {{.*}}signature-mismatch-weak.ll.tmp.o
 ; CHECK-NEXT: >>> defined as () -> I64 in {{.*}}signature-mismatch-weak.ll.tmp.strong.o
diff --git a/test/wasm/signature-mismatch.ll b/test/wasm/signature-mismatch.ll
index 602239d..5b91c19 100644
--- a/test/wasm/signature-mismatch.ll
+++ b/test/wasm/signature-mismatch.ll
@@ -1,12 +1,12 @@
 ; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
 ; RUN: llc -filetype=obj %s -o %t.main.o
-; RUN: not wasm-ld --check-signatures -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s
+; RUN: not wasm-ld --fatal-warnings -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s
 ; Run the test again by with the object files in the other order to verify
 ; the check works when the undefined symbol is resolved by an existing defined
 ; one.
-; RUN: not wasm-ld --check-signatures -o %t.wasm %t.ret32.o %t.main.o 2>&1 | FileCheck %s -check-prefix=REVERSE
+; RUN: not wasm-ld --fatal-warnings -o %t.wasm %t.ret32.o %t.main.o 2>&1 | FileCheck %s -check-prefix=REVERSE
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 ; Function Attrs: nounwind
 define hidden void @_start() local_unnamed_addr #0 {
diff --git a/test/wasm/stack-first.test b/test/wasm/stack-first.test
new file mode 100644
index 0000000..71d1e9d
--- /dev/null
+++ b/test/wasm/stack-first.test
@@ -0,0 +1,42 @@
+; Test that the --stack-first option places the stack at the start of linear
+; memory.  In this case the --stack-first option is being passed along with a
+; stack size of 512.  This means (since the stack grows down) the stack pointer
+; global should be initialized to 512.
+
+RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.o
+
+RUN: wasm-ld -z stack-size=512 --stack-first --allow-undefined -o %t.wasm %t.o
+RUN: obj2yaml %t.wasm | FileCheck %s
+
+CHECK:        - Type:            GLOBAL
+CHECK-NEXT:     Globals:         
+CHECK-NEXT:       - Index:           0
+CHECK-NEXT:         Type:            I32
+CHECK-NEXT:         Mutable:         true
+CHECK-NEXT:         InitExpr:        
+CHECK-NEXT:           Opcode:          I32_CONST
+CHECK-NEXT:           Value:           512
+CHECK-NEXT:       - Index:           1
+CHECK-NEXT:         Type:            I32
+CHECK-NEXT:         Mutable:         false
+CHECK-NEXT:         InitExpr:        
+CHECK-NEXT:           Opcode:          I32_CONST
+CHECK-NEXT:           Value:           512
+CHECK-NEXT:       - Index:           2
+CHECK-NEXT:         Type:            I32
+CHECK-NEXT:         Mutable:         false
+CHECK-NEXT:         InitExpr:        
+CHECK-NEXT:           Opcode:          I32_CONST
+CHECK-NEXT:           Value:           512
+CHECK-NEXT:   - Type:            EXPORT
+CHECK-NEXT:     Exports:         
+CHECK-NEXT:       - Name:            memory
+CHECK-NEXT:         Kind:            MEMORY
+CHECK-NEXT:         Index:           0
+CHECK-NEXT:       - Name:            __heap_base
+CHECK-NEXT:         Kind:            GLOBAL
+CHECK-NEXT:         Index:           1
+CHECK-NEXT:       - Name:            __data_end
+CHECK-NEXT:         Kind:            GLOBAL
+CHECK-NEXT:         Index:           2
+
diff --git a/test/wasm/stack-pointer.ll b/test/wasm/stack-pointer.ll
index 8aaa319..888c938 100644
--- a/test/wasm/stack-pointer.ll
+++ b/test/wasm/stack-pointer.ll
@@ -1,8 +1,8 @@
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: wasm-ld --check-signatures --relocatable -o %t.wasm %t.o
+; RUN: wasm-ld --relocatable -o %t.wasm %t.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 ; Function Attrs: nounwind
 define i32 @_start() local_unnamed_addr {
@@ -50,6 +50,7 @@
 ; CHECK-NEXT:         Body:            23808080800041106B1A41000B
 ; CHECK-NEXT:   - Type:            CUSTOM
 ; CHECK-NEXT:     Name:            linking
+; CHECK-NEXT:     Version:         1
 ; CHECK-NEXT:     SymbolTable:
 ; CHECK-NEXT:       - Index:           0
 ; CHECK-NEXT:         Kind:            FUNCTION
diff --git a/test/wasm/strip-debug.test b/test/wasm/strip-debug.test
index 5a74ac8..be5ba70 100644
--- a/test/wasm/strip-debug.test
+++ b/test/wasm/strip-debug.test
@@ -1,5 +1,5 @@
 RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.start.o
-RUN: wasm-ld --check-signatures --strip-debug -o %t.wasm %t.start.o
+RUN: wasm-ld --strip-debug -o %t.wasm %t.start.o
 RUN: obj2yaml %t.wasm | FileCheck %s
 
 # Check that there is no name section
diff --git a/test/wasm/symbol-type-mismatch.ll b/test/wasm/symbol-type-mismatch.ll
index 16e0f4d..4738c4b 100644
--- a/test/wasm/symbol-type-mismatch.ll
+++ b/test/wasm/symbol-type-mismatch.ll
@@ -1,11 +1,11 @@
 ; RUN: llc -filetype=obj %s -o %t.o
 ; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
-; RUN: not wasm-ld --check-signatures -o %t.wasm %t.o %t.ret32.o 2>&1 | FileCheck %s
+; RUN: not wasm-ld -o %t.wasm %t.o %t.ret32.o 2>&1 | FileCheck %s
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 @ret32 = extern_weak global i32, align 4
 
 ; CHECK: error: symbol type mismatch: ret32
-; CHECK: >>> defined as Data in {{.*}}symbol-type-mismatch.ll.tmp.o
-; CHECK: >>> defined as Function in {{.*}}.ret32.o
+; CHECK: >>> defined as WASM_SYMBOL_TYPE_DATA in {{.*}}symbol-type-mismatch.ll.tmp.o
+; CHECK: >>> defined as WASM_SYMBOL_TYPE_FUNCTION in {{.*}}.ret32.o
diff --git a/test/wasm/undefined-entry.test b/test/wasm/undefined-entry.test
index 7906ec9..ffa079c 100644
--- a/test/wasm/undefined-entry.test
+++ b/test/wasm/undefined-entry.test
@@ -1,10 +1,11 @@
 RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
-RUN: not wasm-ld --check-signatures -o %t.wasm %t.ret32.o 2>&1 | FileCheck %s
+RUN: not wasm-ld -o %t.wasm %t.ret32.o 2>&1 | FileCheck %s
+RUN: not wasm-ld -entry=foo -o %t.wasm %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-CUSTOM
+RUN: not wasm-ld --allow-undefined -o %t.wasm %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-ALLOW
 
 CHECK: error: undefined symbol: _start
-
-RUN: not wasm-ld --check-signatures -entry=foo -o %t.wasm %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-CUSTOM
-
 CHECK-CUSTOM: error: undefined symbol: foo
+CHECK-ALLOW: error: entry symbol not defined (pass --no-entry to supress):
+_start
 
-RUN: wasm-ld --check-signatures -entry=foo --allow-undefined -o %t.wasm %t.ret32.o
+RUN: wasm-ld --no-entry -o %t.wasm %t.ret32.o
diff --git a/test/wasm/undefined-weak-call.ll b/test/wasm/undefined-weak-call.ll
index cd26e05..c13f5c1 100644
--- a/test/wasm/undefined-weak-call.ll
+++ b/test/wasm/undefined-weak-call.ll
@@ -1,17 +1,20 @@
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: wasm-ld --check-signatures --no-entry %t.o -o %t.wasm
+; RUN: wasm-ld --no-entry --print-gc-sections %t.o \
+; RUN:     -o %t.wasm 2>&1 | FileCheck -check-prefix=CHECK-GC %s
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
 ; Check that calling an undefined weak function generates an appropriate stub
 ; that will fail at runtime with "unreachable".
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 declare extern_weak void @weakFunc1()
 declare extern_weak void @weakFunc2()         ; same signature
 declare extern_weak void @weakFunc3(i32 %arg) ; different
 declare extern_weak void @weakFunc4()         ; should be GC'd as not called
 
+; CHECK-GC: removing unused section {{.*}}:(weakFunc4)
+
 define i32 @callWeakFuncs() {
   call void @weakFunc1()
   call void @weakFunc2()
diff --git a/test/wasm/undefined.ll b/test/wasm/undefined.ll
index a74dd6d..7d2161d 100644
--- a/test/wasm/undefined.ll
+++ b/test/wasm/undefined.ll
@@ -1,19 +1,19 @@
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: wasm-ld --check-signatures --allow-undefined -o %t.wasm %t.o
+; RUN: wasm-ld --allow-undefined -o %t.wasm %t.o
 
 ; Fails due to undefined 'foo' and also 'baz'
-; RUN: not wasm-ld --check-signatures --undefined=baz -o %t.wasm %t.o 2>&1 | FileCheck %s
+; RUN: not wasm-ld --undefined=baz -o %t.wasm %t.o 2>&1 | FileCheck %s
 ; CHECK: error: {{.*}}.o: undefined symbol: foo
 ; CHECK: error: undefined symbol: baz
 
 ; Succeeds if we pass a file containing 'foo' as --allow-undefined-file.
 ; RUN: echo 'foo' > %t.txt
-; RUN: wasm-ld --check-signatures --allow-undefined-file=%t.txt -o %t.wasm %t.o
+; RUN: wasm-ld --allow-undefined-file=%t.txt -o %t.wasm %t.o
 
 ; Succeeds even if a missing symbol is added via --export
-; RUN: wasm-ld --check-signatures --allow-undefined --export=xxx -o %t.wasm %t.o
+; RUN: wasm-ld --allow-undefined --export=xxx -o %t.wasm %t.o
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 ; Takes the address of the external foo() resulting in undefined external
 @bar = hidden local_unnamed_addr global i8* bitcast (i32 ()* @foo to i8*), align 4
diff --git a/test/wasm/version.ll b/test/wasm/version.ll
index 3b20b39..ea5b41f 100644
--- a/test/wasm/version.ll
+++ b/test/wasm/version.ll
@@ -1,8 +1,8 @@
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: wasm-ld --check-signatures -o %t.wasm %t.o
+; RUN: wasm-ld -o %t.wasm %t.o
 ; RUN: llvm-readobj -file-headers %t.wasm | FileCheck %s
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 define hidden void @_start() local_unnamed_addr #0 {
 entry:
diff --git a/test/wasm/visibility-hidden.ll b/test/wasm/visibility-hidden.ll
index 530649b..af973df 100644
--- a/test/wasm/visibility-hidden.ll
+++ b/test/wasm/visibility-hidden.ll
@@ -1,13 +1,13 @@
 ; RUN: llc -filetype=obj -o %t.o %s
 ; RUN: llc -filetype=obj %S/Inputs/hidden.ll -o %t2.o
 ; RUN: llvm-ar rcs %t2.a %t2.o
-; RUN: wasm-ld --check-signatures %t.o %t2.a -o %t.wasm
+; RUN: wasm-ld %t.o %t2.a -o %t.wasm
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
 ; Test that hidden symbols are not exported, whether pulled in from an archive
 ; or directly.
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 define hidden i32 @objectHidden() {
 entry:
diff --git a/test/wasm/weak-alias-overide.ll b/test/wasm/weak-alias-overide.ll
index 2252298..8b98f33 100644
--- a/test/wasm/weak-alias-overide.ll
+++ b/test/wasm/weak-alias-overide.ll
@@ -1,12 +1,12 @@
 ; RUN: llc -filetype=obj -o %t.o %s
 ; RUN: llc -filetype=obj %S/Inputs/weak-alias.ll -o %t2.o
-; RUN: wasm-ld --check-signatures %t.o %t2.o -o %t.wasm
+; RUN: wasm-ld %t.o %t2.o -o %t.wasm
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
 ; Test that the strongly defined alias_fn from this file is used both here
 ; and in call_alias.
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 define i32 @alias_fn() local_unnamed_addr #1 {
   ret i32 1
diff --git a/test/wasm/weak-alias.ll b/test/wasm/weak-alias.ll
index 1df16e2..227906a 100644
--- a/test/wasm/weak-alias.ll
+++ b/test/wasm/weak-alias.ll
@@ -1,11 +1,11 @@
 ; RUN: llc -filetype=obj -o %t.o %s
 ; RUN: llc -filetype=obj %S/Inputs/weak-alias.ll -o %t2.o
-; RUN: wasm-ld --check-signatures %t.o %t2.o -o %t.wasm
+; RUN: wasm-ld %t.o %t2.o -o %t.wasm
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
 ; Test that weak aliases (alias_fn is a weak alias of direct_fn) are linked correctly
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 declare i32 @alias_fn() local_unnamed_addr #1
 
@@ -144,7 +144,7 @@
 ; CHECK-NEXT:         Name:            call_direct_ptr
 ; CHECK-NEXT: ...
 
-; RUN: wasm-ld --check-signatures --relocatable %t.o %t2.o -o %t.reloc.o
+; RUN: wasm-ld --relocatable %t.o %t2.o -o %t.reloc.o
 ; RUN: obj2yaml %t.reloc.o | FileCheck %s -check-prefix=RELOC
 
 ; RELOC:      --- !WASM
@@ -250,6 +250,7 @@
 ; RELOC-NEXT:         Body:            23808080800041106B220024808080800020004181808080003602081081808080002101200041106A24808080800020010B
 ; RELOC-NEXT:   - Type:            CUSTOM
 ; RELOC-NEXT:     Name:            linking
+; RELOC-NEXT:     Version:         1
 ; RELOC-NEXT:     SymbolTable:
 ; RELOC-NEXT:       - Index:           0
 ; RELOC-NEXT:         Kind:            FUNCTION
diff --git a/test/wasm/weak-symbols.ll b/test/wasm/weak-symbols.ll
index 7ecb900..bd45de3 100644
--- a/test/wasm/weak-symbols.ll
+++ b/test/wasm/weak-symbols.ll
@@ -1,10 +1,10 @@
 ; RUN: llc -filetype=obj %p/Inputs/weak-symbol1.ll -o %t1.o
 ; RUN: llc -filetype=obj %p/Inputs/weak-symbol2.ll -o %t2.o
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: wasm-ld -no-gc-sections --check-signatures -o %t.wasm %t.o %t1.o %t2.o
+; RUN: wasm-ld -no-gc-sections -o %t.wasm %t.o %t1.o %t2.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 declare i32 @weakFn() local_unnamed_addr
 @weakGlobal = external global i32
diff --git a/test/wasm/weak-undefined.ll b/test/wasm/weak-undefined.ll
index ce68e54..53b38bc 100644
--- a/test/wasm/weak-undefined.ll
+++ b/test/wasm/weak-undefined.ll
@@ -1,11 +1,11 @@
 ; RUN: llc -filetype=obj -o %t.o %s
-; RUN: wasm-ld --check-signatures -strip-debug %t.o -o %t.wasm
+; RUN: wasm-ld -strip-debug %t.o -o %t.wasm
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
 ; Test that undefined weak externals (global_var) and (foo) don't cause
 ; link failures and resolve to zero.
 
-target triple = "wasm32-unknown-unknown-wasm"
+target triple = "wasm32-unknown-unknown"
 
 @global_var = extern_weak global i32, align 4
 
diff --git a/tools/lld/lld.cpp b/tools/lld/lld.cpp
index 164a2aa..2c00a13 100644
--- a/tools/lld/lld.cpp
+++ b/tools/lld/lld.cpp
@@ -20,10 +20,8 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/ADT/Twine.h"
-#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/InitLLVM.h"
 #include "llvm/Support/Path.h"
-#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/Signals.h"
 #include <cstdlib>
 
 using namespace lld;
@@ -114,10 +112,7 @@
 /// Universal linker main(). This linker emulates the gnu, darwin, or
 /// windows linker based on the argv[0] or -flavor option.
 int main(int Argc, const char **Argv) {
-  // Standard set up, so program fails gracefully.
-  sys::PrintStackTraceOnErrorSignal(Argv[0]);
-  PrettyStackTraceProgram StackPrinter(Argc, Argv);
-  llvm_shutdown_obj Shutdown;
+  InitLLVM X(Argc, Argv);
 
   std::vector<const char *> Args(Argv, Argv + Argc);
   switch (parseFlavor(Args)) {
diff --git a/unittests/DriverTests/DarwinLdDriverTest.cpp b/unittests/DriverTests/DarwinLdDriverTest.cpp
index 696be69..0c1d779 100644
--- a/unittests/DriverTests/DarwinLdDriverTest.cpp
+++ b/unittests/DriverTests/DarwinLdDriverTest.cpp
@@ -8,7 +8,7 @@
 //===----------------------------------------------------------------------===//
 ///
 /// \file
-/// \brief Darwin's ld driver tests.
+/// Darwin's ld driver tests.
 ///
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/MachOTests/MachONormalizedFileBinaryReaderTests.cpp b/unittests/MachOTests/MachONormalizedFileBinaryReaderTests.cpp
index 3e8793a..336bbdb 100644
--- a/unittests/MachOTests/MachONormalizedFileBinaryReaderTests.cpp
+++ b/unittests/MachOTests/MachONormalizedFileBinaryReaderTests.cpp
@@ -12,14 +12,17 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/BinaryFormat/MachO.h"
 #include "llvm/Support/Error.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/YAMLTraits.h"
 #include "gtest/gtest.h"
 #include <cstdint>
 #include <memory>
 
+using llvm::SmallString;
 using llvm::StringRef;
 using llvm::MemoryBuffer;
+using llvm::Twine;
 
 using namespace lld::mach_o::normalized;
 using namespace llvm::MachO;
@@ -741,9 +744,11 @@
   EXPECT_EQ(printfLabel.type, N_UNDF);
   EXPECT_EQ(printfLabel.scope, SymbolScope(N_EXT));
 
-  auto ec = writeBinary(*f, "/tmp/foo.o");
-  // FIXME: We want to do EXPECT_FALSE(ec) but that fails on some Windows bots,
-  // probably due to /tmp not being available.
-  // For now just consume the error without checking it.
-  consumeError(std::move(ec));
+  SmallString<128> tmpFl;
+  std::error_code ec =
+      llvm::sys::fs::createTemporaryFile(Twine("xx"), "o", tmpFl);
+  EXPECT_FALSE(ec);
+  llvm::Error ec2 = writeBinary(*f, tmpFl);
+  EXPECT_FALSE(ec2);
+  llvm::sys::fs::remove(tmpFl);
 }
diff --git a/wasm/CMakeLists.txt b/wasm/CMakeLists.txt
index d3bef0f..308c4e2 100644
--- a/wasm/CMakeLists.txt
+++ b/wasm/CMakeLists.txt
@@ -6,6 +6,7 @@
   Driver.cpp
   InputChunks.cpp
   InputFiles.cpp
+  LTO.cpp
   MarkLive.cpp
   OutputSections.cpp
   SymbolTable.cpp
@@ -18,6 +19,8 @@
   BinaryFormat
   Core
   Demangle
+  LTO
+  MC
   Object
   Option
   Support
diff --git a/wasm/Config.h b/wasm/Config.h
index adccbfe..4b11320 100644
--- a/wasm/Config.h
+++ b/wasm/Config.h
@@ -13,31 +13,42 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSet.h"
 #include "llvm/BinaryFormat/Wasm.h"
+#include "llvm/Support/CachePruning.h"
 
 namespace lld {
 namespace wasm {
 
 struct Configuration {
   bool AllowUndefined;
-  bool CheckSignatures;
+  bool CompressRelocTargets;
   bool Demangle;
+  bool DisableVerify;
   bool ExportTable;
   bool GcSections;
   bool ImportMemory;
   bool ImportTable;
+  bool MergeDataSegments;
   bool PrintGcSections;
   bool Relocatable;
+  bool SaveTemps;
   bool StripAll;
   bool StripDebug;
+  bool StackFirst;
   uint32_t GlobalBase;
   uint32_t InitialMemory;
   uint32_t MaxMemory;
   uint32_t ZStackSize;
+  unsigned LTOPartitions;
+  unsigned LTOO;
+  unsigned Optimize;
+  unsigned ThinLTOJobs;
   llvm::StringRef Entry;
   llvm::StringRef OutputFile;
+  llvm::StringRef ThinLTOCacheDir;
 
   llvm::StringSet<> AllowUndefinedSymbols;
   std::vector<llvm::StringRef> SearchPaths;
+  llvm::CachePruningPolicy ThinLTOCachePolicy;
 };
 
 // The only instance of Configuration struct.
diff --git a/wasm/Driver.cpp b/wasm/Driver.cpp
index 97a8159..5a9fe36 100644
--- a/wasm/Driver.cpp
+++ b/wasm/Driver.cpp
@@ -26,6 +26,7 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Process.h"
+#include "llvm/Support/TargetSelect.h"
 
 #define DEBUG_TYPE "lld"
 
@@ -48,6 +49,17 @@
 #undef OPTION
 };
 
+// This function is called on startup. We need this for LTO since
+// LTO calls LLVM functions to compile bitcode files to native code.
+// Technically this can be delayed until we read bitcode files, but
+// we don't bother to do lazily because the initialization is fast.
+static void initLLVM() {
+  InitializeAllTargets();
+  InitializeAllTargetMCs();
+  InitializeAllAsmPrinters();
+  InitializeAllAsmParsers();
+}
+
 class LinkerDriver {
 public:
   void link(ArrayRef<const char *> ArgsArr);
@@ -57,7 +69,6 @@
   void addFile(StringRef Path);
   void addLibrary(StringRef Name);
   std::vector<InputFile *> Files;
-  llvm::wasm::WasmGlobal StackPointerGlobal;
 };
 } // anonymous namespace
 
@@ -73,6 +84,7 @@
   Config = make<Configuration>();
   Symtab = make<SymbolTable>();
 
+  initLLVM();
   LinkerDriver().link(Args);
 
   // Exit immediately if we don't need to return to the caller.
@@ -99,11 +111,13 @@
 #undef OPTION
 };
 
+namespace {
 class WasmOptTable : public llvm::opt::OptTable {
 public:
   WasmOptTable() : OptTable(OptInfo) {}
   opt::InputArgList parse(ArrayRef<const char *> Argv);
 };
+} // namespace
 
 // Set color diagnostics according to -color-diagnostics={auto,always,never}
 // or -no-color-diagnostics flags.
@@ -112,19 +126,18 @@
                               OPT_no_color_diagnostics);
   if (!Arg)
     return;
-
-  if (Arg->getOption().getID() == OPT_color_diagnostics)
+  if (Arg->getOption().getID() == OPT_color_diagnostics) {
     errorHandler().ColorDiagnostics = true;
-  else if (Arg->getOption().getID() == OPT_no_color_diagnostics)
+  } else if (Arg->getOption().getID() == OPT_no_color_diagnostics) {
     errorHandler().ColorDiagnostics = false;
-  else {
+  } else {
     StringRef S = Arg->getValue();
     if (S == "always")
       errorHandler().ColorDiagnostics = true;
-    if (S == "never")
+    else if (S == "never")
       errorHandler().ColorDiagnostics = false;
-    if (S != "auto")
-      error("unknown option: -color-diagnostics=" + S);
+    else if (S != "auto")
+      error("unknown option: --color-diagnostics=" + S);
   }
 }
 
@@ -142,6 +155,10 @@
 
   unsigned MissingIndex;
   unsigned MissingCount;
+
+  // Expand response files (arguments in the form of @<filename>)
+  cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Vec);
+
   opt::InputArgList Args = this->ParseArgs(Vec, MissingIndex, MissingCount);
 
   handleColorDiagnostics(Args);
@@ -169,7 +186,8 @@
     return;
   MemoryBufferRef MBRef = *Buffer;
 
-  if (identify_magic(MBRef.getBuffer()) == file_magic::archive) {
+  switch (identify_magic(MBRef.getBuffer())) {
+  case file_magic::archive: {
     SmallString<128> ImportFile = Path;
     path::replace_extension(ImportFile, ".imports");
     if (fs::exists(ImportFile))
@@ -178,8 +196,12 @@
     Files.push_back(make<ArchiveFile>(MBRef));
     return;
   }
-
-  Files.push_back(make<ObjFile>(MBRef));
+  case file_magic::bitcode:
+    Files.push_back(make<BitcodeFile>(MBRef));
+    break;
+  default:
+    Files.push_back(make<ObjFile>(MBRef));
+  }
 }
 
 // Add a given library by searching it from input search paths.
@@ -241,10 +263,11 @@
     // Add a synthetic dummy for weak undefined functions.  These dummies will
     // be GC'd if not used as the target of any "call" instructions.
     Optional<std::string> SymName = demangleItanium(Sym->getName());
-    StringRef StubName =
+    StringRef DebugName =
         Saver.save("undefined function " +
                    (SymName ? StringRef(*SymName) : Sym->getName()));
-    SyntheticFunction *Func = make<SyntheticFunction>(Sig, StubName);
+    SyntheticFunction *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).
@@ -256,6 +279,17 @@
   }
 }
 
+// Force Sym to be entered in the output. Used for -u or equivalent.
+static Symbol *addUndefined(StringRef Name) {
+  Symbol *S = Symtab->addUndefinedFunction(Name, 0, nullptr, nullptr);
+
+  // Since symbol S may not be used inside the program, LTO may
+  // eliminate it. Mark the symbol as "used" to prevent it.
+  S->IsUsedInRegularObj = true;
+
+  return S;
+}
+
 void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
   WasmOptTable Parser;
   opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));
@@ -282,22 +316,36 @@
   errorHandler().ErrorLimit = args::getInteger(Args, OPT_error_limit, 20);
 
   Config->AllowUndefined = Args.hasArg(OPT_allow_undefined);
-  Config->CheckSignatures =
-      Args.hasFlag(OPT_check_signatures, OPT_no_check_signatures, false);
   Config->Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, true);
+  Config->DisableVerify = Args.hasArg(OPT_disable_verify);
   Config->Entry = getEntry(Args, Args.hasArg(OPT_relocatable) ? "" : "_start");
   Config->ExportTable = Args.hasArg(OPT_export_table);
+  errorHandler().FatalWarnings =
+      Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false);
   Config->ImportMemory = Args.hasArg(OPT_import_memory);
   Config->ImportTable = Args.hasArg(OPT_import_table);
+  Config->LTOO = args::getInteger(Args, OPT_lto_O, 2);
+  Config->LTOPartitions = args::getInteger(Args, OPT_lto_partitions, 1);
+  Config->Optimize = args::getInteger(Args, OPT_O, 0);
   Config->OutputFile = Args.getLastArgValue(OPT_o);
   Config->Relocatable = Args.hasArg(OPT_relocatable);
   Config->GcSections =
       Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, !Config->Relocatable);
+  Config->MergeDataSegments =
+      Args.hasFlag(OPT_merge_data_segments, OPT_no_merge_data_segments,
+                   !Config->Relocatable);
   Config->PrintGcSections =
       Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
+  Config->SaveTemps = Args.hasArg(OPT_save_temps);
   Config->SearchPaths = args::getStrings(Args, OPT_L);
   Config->StripAll = Args.hasArg(OPT_strip_all);
   Config->StripDebug = Args.hasArg(OPT_strip_debug);
+  Config->StackFirst = Args.hasArg(OPT_stack_first);
+  Config->ThinLTOCacheDir = Args.getLastArgValue(OPT_thinlto_cache_dir);
+  Config->ThinLTOCachePolicy = CHECK(
+      parseCachePruningPolicy(Args.getLastArgValue(OPT_thinlto_cache_policy)),
+      "--thinlto-cache-policy: invalid cache policy");
+  Config->ThinLTOJobs = args::getInteger(Args, OPT_thinlto_jobs, -1u);
   errorHandler().Verbose = Args.hasArg(OPT_verbose);
   ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true);
 
@@ -307,6 +355,15 @@
   Config->ZStackSize =
       args::getZOptionValue(Args, OPT_z, "stack-size", WasmPageSize);
 
+  Config->CompressRelocTargets = Config->Optimize > 0 && !Config->Relocatable;
+
+  if (Config->LTOO > 3)
+    error("invalid optimization level for LTO: " + Twine(Config->LTOO));
+  if (Config->LTOPartitions == 0)
+    error("--lto-partitions: number of threads must be > 0");
+  if (Config->ThinLTOJobs == 0)
+    error("--thinlto-jobs: number of threads must be > 0");
+
   if (auto *Arg = Args.getLastArg(OPT_allow_undefined_file))
     readImportFile(Arg->getValue());
 
@@ -336,10 +393,12 @@
     // globals aren't yet supported in the official binary format.
     // TODO(sbc): Remove WASM_SYMBOL_VISIBILITY_HIDDEN if/when the
     // "mutable global" proposal is accepted.
-    StackPointerGlobal.Type = {WASM_TYPE_I32, true};
-    StackPointerGlobal.InitExpr.Value.Int32 = 0;
-    StackPointerGlobal.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
-    InputGlobal *StackPointer = make<InputGlobal>(StackPointerGlobal);
+    llvm::wasm::WasmGlobal Global;
+    Global.Type = {WASM_TYPE_I32, true};
+    Global.InitExpr.Value.Int32 = 0;
+    Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
+    Global.SymbolName = "__stack_pointer";
+    InputGlobal *StackPointer = make<InputGlobal>(Global, nullptr);
     StackPointer->Live = true;
 
     static WasmSignature NullSignature = {{}, WASM_TYPE_NORESULT};
@@ -355,13 +414,14 @@
         "__dso_handle", WASM_SYMBOL_VISIBILITY_HIDDEN);
     WasmSym::DataEnd = Symtab->addSyntheticDataSymbol("__data_end", 0);
 
+    // For now, since we don't actually use the start function as the
+    // wasm start symbol, we don't need to care about it signature.
     if (!Config->Entry.empty())
-      EntrySym = Symtab->addUndefinedFunction(Config->Entry, 0, nullptr,
-                                              &NullSignature);
+      EntrySym = addUndefined(Config->Entry);
 
     // Handle the `--undefined <sym>` options.
     for (auto *Arg : Args.filtered(OPT_undefined))
-      Symtab->addUndefinedFunction(Arg->getValue(), 0, nullptr, nullptr);
+      addUndefined(Arg->getValue());
   }
 
   createFiles(Args);
@@ -372,24 +432,36 @@
   // symbols that we need to the symbol table.
   for (InputFile *F : Files)
     Symtab->addFile(F);
+  if (errorCount())
+    return;
 
   // Add synthetic dummies for weak undefined functions.
   if (!Config->Relocatable)
     handleWeakUndefines();
 
+  // Do link-time optimization if given files are LLVM bitcode files.
+  // This compiles bitcode files into real object files.
+  Symtab->addCombinedLTOObject();
+  if (errorCount())
+    return;
+
   // Make sure we have resolved all symbols.
   if (!Config->Relocatable && !Config->AllowUndefined) {
     Symtab->reportRemainingUndefines();
   } else {
-    // When we allow undefined symbols we cannot include those defined in
-    // -u/--undefined since these undefined symbols have only names and no
-    // function signature, which means they cannot be written to the final
-    // output.
+    // Even when using --allow-undefined we still want to report the absence of
+    // our initial set of undefined symbols (i.e. the entry point and symbols
+    // specified via --undefined).
+    // Part of the reason for this is that these function don't have signatures
+    // so which means they cannot be written as wasm function imports.
     for (auto *Arg : Args.filtered(OPT_undefined)) {
       Symbol *Sym = Symtab->find(Arg->getValue());
       if (!Sym->isDefined())
-        error("function forced with --undefined not found: " + Sym->getName());
+        error("symbol forced with --undefined not found: " + Sym->getName());
     }
+    if (EntrySym && !EntrySym->isDefined())
+      error("entry symbol not defined (pass --no-entry to supress): " +
+            EntrySym->getName());
   }
   if (errorCount())
     return;
diff --git a/wasm/InputChunks.cpp b/wasm/InputChunks.cpp
index 0cac19b..fcefac7 100644
--- a/wasm/InputChunks.cpp
+++ b/wasm/InputChunks.cpp
@@ -23,7 +23,7 @@
 using namespace lld;
 using namespace lld::wasm;
 
-StringRef ReloctTypeToString(uint8_t RelocType) {
+static StringRef ReloctTypeToString(uint8_t RelocType) {
   switch (RelocType) {
 #define WASM_RELOC(NAME, REL) case REL: return #NAME;
 #include "llvm/BinaryFormat/WasmRelocs.def"
@@ -47,12 +47,49 @@
   if (Section.Relocations.empty())
     return;
   size_t Start = getInputSectionOffset();
-  size_t Size = getSize();
+  size_t Size = getInputSize();
   for (const WasmRelocation &R : Section.Relocations)
     if (R.Offset >= Start && R.Offset < Start + Size)
       Relocations.push_back(R);
 }
 
+void InputChunk::verifyRelocTargets() const {
+  for (const WasmRelocation &Rel : Relocations) {
+    uint32_t ExistingValue;
+    unsigned BytesRead = 0;
+    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_MEMORY_ADDR_LEB:
+      ExistingValue = decodeULEB128(Loc, &BytesRead);
+      break;
+    case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
+    case R_WEBASSEMBLY_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:
+      ExistingValue = static_cast<uint32_t>(read32le(Loc));
+      break;
+    default:
+      llvm_unreachable("unknown relocation type");
+    }
+
+    if (BytesRead && BytesRead != 5)
+      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) +
+           ": existing=" + Twine(ExistingValue) +
+           " expected=" + Twine(ExpectedValue));
+  }
+}
+
 // Copy this input chunk to an mmap'ed output file and apply relocations.
 void InputChunk::writeTo(uint8_t *Buf) const {
   // Copy contents
@@ -62,45 +99,42 @@
   if (Relocations.empty())
     return;
 
-  DEBUG(dbgs() << "applying relocations: " << getName()
-               << " count=" << Relocations.size() << "\n");
+#ifndef NDEBUG
+  verifyRelocTargets();
+#endif
+
+  LLVM_DEBUG(dbgs() << "applying relocations: " << getName()
+                    << " count=" << Relocations.size() << "\n");
   int32_t Off = OutputOffset - getInputSectionOffset();
 
   for (const WasmRelocation &Rel : Relocations) {
     uint8_t *Loc = Buf + Rel.Offset + Off;
     uint32_t Value = File->calcNewValue(Rel);
-    uint32_t ExistingValue;
-    DEBUG(dbgs() << "apply reloc: type=" << ReloctTypeToString(Rel.Type)
-                 << " addend=" << Rel.Addend << " index=" << Rel.Index
-                 << " value=" << Value << " offset=" << Rel.Offset << "\n");
+    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_MEMORY_ADDR_LEB:
-      ExistingValue = decodeULEB128(Loc);
       encodeULEB128(Value, Loc, 5);
       break;
     case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
     case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
-      ExistingValue = static_cast<uint32_t>(decodeSLEB128(Loc));
       encodeSLEB128(static_cast<int32_t>(Value), Loc, 5);
       break;
     case R_WEBASSEMBLY_TABLE_INDEX_I32:
     case R_WEBASSEMBLY_MEMORY_ADDR_I32:
-      ExistingValue = static_cast<uint32_t>(read32le(Loc));
+    case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
+    case R_WEBASSEMBLY_SECTION_OFFSET_I32:
       write32le(Loc, Value);
       break;
     default:
       llvm_unreachable("unknown relocation type");
     }
-
-    uint32_t ExpectedValue = File->calcExpectedValue(Rel);
-    if (ExpectedValue != ExistingValue)
-      error("unexpected existing value for " + ReloctTypeToString(Rel.Type) +
-            ": existing=" + Twine(ExistingValue) +
-            " expected=" + Twine(ExpectedValue));
   }
 }
 
@@ -112,8 +146,8 @@
     return;
 
   int32_t Off = OutputOffset - getInputSectionOffset();
-  DEBUG(dbgs() << "writeRelocations: " << File->getName()
-               << " offset=" << Twine(Off) << "\n");
+  LLVM_DEBUG(dbgs() << "writeRelocations: " << File->getName()
+                    << " offset=" << Twine(Off) << "\n");
 
   for (const WasmRelocation &Rel : Relocations) {
     writeUleb128(OS, Rel.Type, "reloc type");
@@ -124,22 +158,138 @@
     case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
     case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
     case R_WEBASSEMBLY_MEMORY_ADDR_I32:
-      writeUleb128(OS, Rel.Addend, "reloc addend");
+    case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
+    case R_WEBASSEMBLY_SECTION_OFFSET_I32:
+      writeSleb128(OS, File->calcNewAddend(Rel), "reloc addend");
       break;
     }
   }
 }
 
 void InputFunction::setFunctionIndex(uint32_t Index) {
-  DEBUG(dbgs() << "InputFunction::setFunctionIndex: " << getName() << " -> "
-               << Index << "\n");
+  LLVM_DEBUG(dbgs() << "InputFunction::setFunctionIndex: " << getName()
+                    << " -> " << Index << "\n");
   assert(!hasFunctionIndex());
   FunctionIndex = Index;
 }
 
 void InputFunction::setTableIndex(uint32_t Index) {
-  DEBUG(dbgs() << "InputFunction::setTableIndex: " << getName() << " -> "
-               << Index << "\n");
+  LLVM_DEBUG(dbgs() << "InputFunction::setTableIndex: " << getName() << " -> "
+                    << Index << "\n");
   assert(!hasTableIndex());
   TableIndex = Index;
 }
+
+// Write a relocation value without padding and return the number of bytes
+// witten.
+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_MEMORY_ADDR_LEB:
+    return encodeULEB128(Value, Buf);
+  case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
+  case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
+    return encodeSLEB128(static_cast<int32_t>(Value), Buf);
+  default:
+    llvm_unreachable("unexpected relocation type");
+  }
+}
+
+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_MEMORY_ADDR_LEB:
+  case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
+  case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
+    return 5;
+  default:
+    llvm_unreachable("unexpected relocation type");
+  }
+}
+
+static unsigned getRelocWidth(const WasmRelocation &Rel, uint32_t Value) {
+  uint8_t Buf[5];
+  return writeCompressedReloc(Buf, Rel, Value);
+}
+
+// Relocations of type LEB and SLEB in the code section are padded to 5 bytes
+// so that a fast linker can blindly overwrite them without needing to worry
+// about the number of bytes needed to encode the values.
+// However, for optimal output the code section can be compressed to remove
+// the padding then outputting non-relocatable files.
+// In this case we need to perform a size calculation based on the value at each
+// relocation.  At best we end up saving 4 bytes for each relocation entry.
+//
+// This function only computes the final output size.  It must be called
+// before getSize() is used to calculate of layout of the code section.
+void InputFunction::calculateSize() {
+  if (!File || !Config->CompressRelocTargets)
+    return;
+
+  LLVM_DEBUG(dbgs() << "calculateSize: " << getName() << "\n");
+
+  const uint8_t *SecStart = File->CodeSection->Content.data();
+  const uint8_t *FuncStart = SecStart + getInputSectionOffset();
+  uint32_t FunctionSizeLength;
+  decodeULEB128(FuncStart, &FunctionSizeLength);
+
+  uint32_t Start = getInputSectionOffset();
+  uint32_t End = Start + Function->Size;
+
+  uint32_t LastRelocEnd = Start + FunctionSizeLength;
+  for (WasmRelocation &Rel : Relocations) {
+    LLVM_DEBUG(dbgs() << "  region: " << (Rel.Offset - LastRelocEnd) << "\n");
+    CompressedFuncSize += Rel.Offset - LastRelocEnd;
+    CompressedFuncSize += getRelocWidth(Rel, File->calcNewValue(Rel));
+    LastRelocEnd = Rel.Offset + getRelocWidthPadded(Rel);
+  }
+  LLVM_DEBUG(dbgs() << "  final region: " << (End - LastRelocEnd) << "\n");
+  CompressedFuncSize += End - LastRelocEnd;
+
+  // Now we know how long the resulting function is we can add the encoding
+  // of its length
+  uint8_t Buf[5];
+  CompressedSize = CompressedFuncSize + encodeULEB128(CompressedFuncSize, Buf);
+
+  LLVM_DEBUG(dbgs() << "  calculateSize orig: " << Function->Size << "\n");
+  LLVM_DEBUG(dbgs() << "  calculateSize  new: " << CompressedSize << "\n");
+}
+
+// Override the default writeTo method so that we can (optionally) write the
+// compressed version of the function.
+void InputFunction::writeTo(uint8_t *Buf) const {
+  if (!File || !Config->CompressRelocTargets)
+    return InputChunk::writeTo(Buf);
+
+  Buf += OutputOffset;
+  uint8_t *Orig = Buf; (void)Orig;
+
+  const uint8_t *SecStart = File->CodeSection->Content.data();
+  const uint8_t *FuncStart = SecStart + getInputSectionOffset();
+  const uint8_t *End = FuncStart + Function->Size;
+  uint32_t Count;
+  decodeULEB128(FuncStart, &Count);
+  FuncStart += Count;
+
+  LLVM_DEBUG(dbgs() << "write func: " << getName() << "\n");
+  Buf += encodeULEB128(CompressedFuncSize, Buf);
+  const uint8_t *LastRelocEnd = FuncStart;
+  for (const WasmRelocation &Rel : Relocations) {
+    unsigned ChunkSize = (SecStart + Rel.Offset) - LastRelocEnd;
+    LLVM_DEBUG(dbgs() << "  write chunk: " << ChunkSize << "\n");
+    memcpy(Buf, LastRelocEnd, ChunkSize);
+    Buf += ChunkSize;
+    Buf += writeCompressedReloc(Buf, Rel, File->calcNewValue(Rel));
+    LastRelocEnd = SecStart + Rel.Offset + getRelocWidthPadded(Rel);
+  }
+
+  unsigned ChunkSize = End - LastRelocEnd;
+  LLVM_DEBUG(dbgs() << "  write final chunk: " << ChunkSize << "\n");
+  memcpy(Buf, LastRelocEnd, ChunkSize);
+  LLVM_DEBUG(dbgs() << "  total: " << (Buf + ChunkSize - Orig) << "\n");
+}
diff --git a/wasm/InputChunks.h b/wasm/InputChunks.h
index 3d6ea23..526e298 100644
--- a/wasm/InputChunks.h
+++ b/wasm/InputChunks.h
@@ -44,19 +44,20 @@
 
 class InputChunk {
 public:
-  enum Kind { DataSegment, Function, SyntheticFunction };
+  enum Kind { DataSegment, Function, SyntheticFunction, Section };
 
   Kind kind() const { return SectionKind; }
 
-  uint32_t getSize() const { return data().size(); }
+  virtual uint32_t getSize() const { return data().size(); }
 
   void copyRelocations(const WasmSection &Section);
 
-  void writeTo(uint8_t *SectionStart) const;
+  virtual void writeTo(uint8_t *SectionStart) const;
 
   ArrayRef<WasmRelocation> getRelocations() const { return Relocations; }
 
   virtual StringRef getName() const = 0;
+  virtual StringRef getDebugName() const = 0;
   virtual uint32_t getComdat() const = 0;
   StringRef getComdatName() const;
 
@@ -77,6 +78,11 @@
   virtual ~InputChunk() = default;
   virtual ArrayRef<uint8_t> data() const = 0;
   virtual uint32_t getInputSectionOffset() const = 0;
+  virtual uint32_t getInputSize() const { return getSize(); };
+
+  // Verifies the existing data at relocation targets matches our expectations.
+  // This is performed only debug builds as an extra sanity check.
+  void verifyRelocTargets() const;
 
   std::vector<WasmRelocation> Relocations;
   Kind SectionKind;
@@ -99,6 +105,7 @@
 
   uint32_t getAlignment() const { return Segment.Data.Alignment; }
   StringRef getName() const override { return Segment.Data.Name; }
+  StringRef getDebugName() const override { return StringRef(); }
   uint32_t getComdat() const override { return Segment.Data.Comdat; }
 
   const OutputSegment *OutputSeg = nullptr;
@@ -125,8 +132,19 @@
            C->kind() == InputChunk::SyntheticFunction;
   }
 
-  StringRef getName() const override { return Function->Name; }
+  void writeTo(uint8_t *SectionStart) const override;
+  StringRef getName() const override { return Function->SymbolName; }
+  StringRef getDebugName() const override { return Function->DebugName; }
   uint32_t getComdat() const override { return Function->Comdat; }
+  uint32_t getFunctionInputOffset() const { return getInputSectionOffset(); }
+  uint32_t getFunctionCodeOffset() const { return Function->CodeOffset; }
+  uint32_t getSize() const override {
+    if (Config->CompressRelocTargets && File) {
+      assert(CompressedSize);
+      return CompressedSize;
+    }
+    return data().size();
+  }
   uint32_t getFunctionIndex() const { return FunctionIndex.getValue(); }
   bool hasFunctionIndex() const { return FunctionIndex.hasValue(); }
   void setFunctionIndex(uint32_t Index);
@@ -134,13 +152,23 @@
   bool hasTableIndex() const { return TableIndex.hasValue(); }
   void setTableIndex(uint32_t Index);
 
+  // The size of a given input function can depend on the values of the
+  // LEB relocations within it.  This finalizeContents method is called after
+  // all the symbol values have be calcualted but before getSize() is ever
+  // called.
+  void calculateSize();
+
   const WasmSignature &Signature;
 
 protected:
   ArrayRef<uint8_t> data() const override {
+    assert(!Config->CompressRelocTargets);
     return File->CodeSection->Content.slice(getInputSectionOffset(),
                                             Function->Size);
   }
+
+  uint32_t getInputSize() const override { return Function->Size; }
+
   uint32_t getInputSectionOffset() const override {
     return Function->CodeSectionOffset;
   }
@@ -148,12 +176,15 @@
   const WasmFunction *Function;
   llvm::Optional<uint32_t> FunctionIndex;
   llvm::Optional<uint32_t> TableIndex;
+  uint32_t CompressedFuncSize = 0;
+  uint32_t CompressedSize = 0;
 };
 
 class SyntheticFunction : public InputFunction {
 public:
-  SyntheticFunction(const WasmSignature &S, StringRef Name)
-      : InputFunction(S, nullptr, nullptr), Name(Name) {
+  SyntheticFunction(const WasmSignature &S, StringRef Name,
+                    StringRef DebugName = {})
+      : InputFunction(S, nullptr, nullptr), Name(Name), DebugName(DebugName) {
     SectionKind = InputChunk::SyntheticFunction;
   }
 
@@ -162,6 +193,7 @@
   }
 
   StringRef getName() const override { return Name; }
+  StringRef getDebugName() const override { return DebugName; }
   uint32_t getComdat() const override { return UINT32_MAX; }
 
   void setBody(ArrayRef<uint8_t> Body_) { Body = Body_; }
@@ -170,9 +202,32 @@
   ArrayRef<uint8_t> data() const override { return Body; }
 
   StringRef Name;
+  StringRef DebugName;
   ArrayRef<uint8_t> Body;
 };
 
+// Represents a single Wasm Section within an input file.
+class InputSection : public InputChunk {
+public:
+  InputSection(const WasmSection &S, ObjFile *F)
+      : InputChunk(F, InputChunk::Section), Section(S) {
+    assert(Section.Type == llvm::wasm::WASM_SEC_CUSTOM);
+  }
+
+  StringRef getName() const override { return Section.Name; }
+  StringRef getDebugName() const override { return StringRef(); }
+  uint32_t getComdat() const override { return UINT32_MAX; }
+
+protected:
+  ArrayRef<uint8_t> data() const override { return Section.Content; }
+
+  // Offset within the input section.  This is only zero since this chunk
+  // type represents an entire input section, not part of one.
+  uint32_t getInputSectionOffset() const override { return 0; }
+
+  const WasmSection &Section;
+};
+
 } // namespace wasm
 
 std::string toString(const wasm::InputChunk *);
diff --git a/wasm/InputFiles.cpp b/wasm/InputFiles.cpp
index e743686..ee9e99b 100644
--- a/wasm/InputFiles.cpp
+++ b/wasm/InputFiles.cpp
@@ -60,6 +60,22 @@
   return Symbols[Reloc.Index]->getOutputSymbolIndex();
 }
 
+// Relocations can contain addend for combined sections. This function takes a
+// 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:
+    return Reloc.Addend;
+  case R_WEBASSEMBLY_SECTION_OFFSET_I32:
+    return getSectionSymbol(Reloc.Index)->Section->OutputOffset + Reloc.Addend;
+  default:
+    llvm_unreachable("unexpected relocation type");
+  }
+}
+
 // Calculate the value we expect to find at the relocation location.
 // This is used as a sanity check before applying a relocation to a given
 // location.  It is useful for catching bugs in the compiler and linker.
@@ -80,6 +96,14 @@
     return Segment.Data.Offset.Value.Int32 + Sym.Info.DataRef.Offset +
            Reloc.Addend;
   }
+  case R_WEBASSEMBLY_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:
+    return Reloc.Addend;
   case R_WEBASSEMBLY_TYPE_INDEX_LEB:
     return Reloc.Index;
   case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
@@ -102,7 +126,8 @@
   case R_WEBASSEMBLY_MEMORY_ADDR_I32:
   case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
     if (auto *Sym = dyn_cast<DefinedData>(getDataSymbol(Reloc.Index)))
-      return Sym->getVirtualAddress() + Reloc.Addend;
+      if (Sym->isLive())
+        return Sym->getVirtualAddress() + Reloc.Addend;
     return 0;
   case R_WEBASSEMBLY_TYPE_INDEX_LEB:
     return TypeMap[Reloc.Index];
@@ -110,6 +135,14 @@
     return getFunctionSymbol(Reloc.Index)->getFunctionIndex();
   case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
     return getGlobalSymbol(Reloc.Index)->getGlobalIndex();
+  case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
+    if (auto *Sym = dyn_cast<DefinedFunction>(getFunctionSymbol(Reloc.Index))) {
+      return Sym->Function->OutputOffset +
+             Sym->Function->getFunctionCodeOffset() + Reloc.Addend;
+    }
+    return 0;
+  case R_WEBASSEMBLY_SECTION_OFFSET_I32:
+    return getSectionSymbol(Reloc.Index)->Section->OutputOffset + Reloc.Addend;
   default:
     llvm_unreachable("unknown relocation type");
   }
@@ -117,7 +150,7 @@
 
 void ObjFile::parse() {
   // Parse a memory buffer as a wasm file.
-  DEBUG(dbgs() << "Parsing object: " << toString(this) << "\n");
+  LLVM_DEBUG(dbgs() << "Parsing object: " << toString(this) << "\n");
   std::unique_ptr<Binary> Bin = CHECK(createBinary(MB), toString(this));
 
   auto *Obj = dyn_cast<WasmObjectFile>(Bin.get());
@@ -147,12 +180,19 @@
 
   // Find the code and data sections.  Wasm objects can have at most one code
   // and one data section.
+  uint32_t SectionIndex = 0;
   for (const SectionRef &Sec : WasmObj->sections()) {
     const WasmSection &Section = WasmObj->getWasmSection(Sec);
-    if (Section.Type == WASM_SEC_CODE)
+    if (Section.Type == WASM_SEC_CODE) {
       CodeSection = &Section;
-    else if (Section.Type == WASM_SEC_DATA)
+    } else if (Section.Type == WASM_SEC_DATA) {
       DataSection = &Section;
+    } else if (Section.Type == WASM_SEC_CUSTOM) {
+      CustomSections.emplace_back(make<InputSection>(Section, this));
+      CustomSections.back()->copyRelocations(Section);
+      CustomSectionsByIndex[SectionIndex] = CustomSections.back();
+    }
+    SectionIndex++;
   }
 
   TypeMap.resize(getWasmObj()->types().size());
@@ -185,7 +225,7 @@
 
   // Populate `Globals`.
   for (const WasmGlobal &G : WasmObj->globals())
-    Globals.emplace_back(make<InputGlobal>(G));
+    Globals.emplace_back(make<InputGlobal>(G, this));
 
   // Populate `Symbols` based on the WasmSymbols in the object.
   Symbols.reserve(WasmObj->getNumberOfSymbols());
@@ -213,6 +253,10 @@
   return cast<GlobalSymbol>(Symbols[Index]);
 }
 
+SectionSymbol *ObjFile::getSectionSymbol(uint32_t Index) const {
+  return cast<SectionSymbol>(Symbols[Index]);
+}
+
 DataSymbol *ObjFile::getDataSymbol(uint32_t Index) const {
   return cast<DataSymbol>(Symbols[Index]);
 }
@@ -251,14 +295,20 @@
       return make<DefinedData>(Name, Flags, this, Seg, Offset, Size);
     return Symtab->addDefinedData(Name, Flags, this, Seg, Offset, Size);
   }
-  case WASM_SYMBOL_TYPE_GLOBAL:
+  case WASM_SYMBOL_TYPE_GLOBAL: {
     InputGlobal *Global =
         Globals[Sym.Info.ElementIndex - WasmObj->getNumImportedGlobals()];
     if (Sym.isBindingLocal())
       return make<DefinedGlobal>(Name, Flags, this, Global);
     return Symtab->addDefinedGlobal(Name, Flags, this, Global);
   }
-  llvm_unreachable("unkown symbol kind");
+  case WASM_SYMBOL_TYPE_SECTION: {
+    InputSection *Section = CustomSectionsByIndex[Sym.Info.ElementIndex];
+    assert(Sym.isBindingLocal());
+    return make<SectionSymbol>(Name, Flags, Section, this);
+  }
+  }
+  llvm_unreachable("unknown symbol kind");
 }
 
 Symbol *ObjFile::createUndefined(const WasmSymbol &Sym) {
@@ -272,13 +322,15 @@
     return Symtab->addUndefinedData(Name, Flags, this);
   case WASM_SYMBOL_TYPE_GLOBAL:
     return Symtab->addUndefinedGlobal(Name, Flags, this, Sym.GlobalType);
+  case WASM_SYMBOL_TYPE_SECTION:
+    llvm_unreachable("section symbols cannot be undefined");
   }
-  llvm_unreachable("unkown symbol kind");
+  llvm_unreachable("unknown symbol kind");
 }
 
 void ArchiveFile::parse() {
   // Parse a MemoryBufferRef as an archive file.
-  DEBUG(dbgs() << "Parsing library: " << toString(this) << "\n");
+  LLVM_DEBUG(dbgs() << "Parsing library: " << toString(this) << "\n");
   File = CHECK(Archive::create(MB), toString(this));
 
   // Read the symbol table to construct Lazy symbols.
@@ -287,7 +339,7 @@
     Symtab->addLazy(this, &Sym);
     ++Count;
   }
-  DEBUG(dbgs() << "Read " << Count << " symbols\n");
+  LLVM_DEBUG(dbgs() << "Read " << Count << " symbols\n");
 }
 
 void ArchiveFile::addMember(const Archive::Symbol *Sym) {
@@ -300,8 +352,8 @@
   if (!Seen.insert(C.getChildOffset()).second)
     return;
 
-  DEBUG(dbgs() << "loading lazy: " << Sym->getName() << "\n");
-  DEBUG(dbgs() << "from archive: " << toString(this) << "\n");
+  LLVM_DEBUG(dbgs() << "loading lazy: " << Sym->getName() << "\n");
+  LLVM_DEBUG(dbgs() << "from archive: " << toString(this) << "\n");
 
   MemoryBufferRef MB =
       CHECK(C.getMemoryBufferRef(),
@@ -318,6 +370,48 @@
   Symtab->addFile(Obj);
 }
 
+static uint8_t mapVisibility(GlobalValue::VisibilityTypes GvVisibility) {
+  switch (GvVisibility) {
+  case GlobalValue::DefaultVisibility:
+    return WASM_SYMBOL_VISIBILITY_DEFAULT;
+  case GlobalValue::HiddenVisibility:
+  case GlobalValue::ProtectedVisibility:
+    return WASM_SYMBOL_VISIBILITY_HIDDEN;
+  }
+  llvm_unreachable("unknown visibility");
+}
+
+static Symbol *createBitcodeSymbol(const lto::InputFile::Symbol &ObjSym,
+                                   BitcodeFile &F) {
+  StringRef Name = Saver.save(ObjSym.getName());
+
+  uint32_t Flags = ObjSym.isWeak() ? WASM_SYMBOL_BINDING_WEAK : 0;
+  Flags |= mapVisibility(ObjSym.getVisibility());
+
+  if (ObjSym.isUndefined()) {
+    if (ObjSym.isExecutable())
+      return Symtab->addUndefinedFunction(Name, Flags, &F, nullptr);
+    return Symtab->addUndefinedData(Name, Flags, &F);
+  }
+
+  if (ObjSym.isExecutable())
+    return Symtab->addDefinedFunction(Name, Flags, &F, nullptr);
+  return Symtab->addDefinedData(Name, Flags, &F, nullptr, 0, 0);
+}
+
+void BitcodeFile::parse() {
+  Obj = check(lto::InputFile::create(MemoryBufferRef(
+      MB.getBuffer(), Saver.save(ParentName + MB.getBufferIdentifier()))));
+  Triple T(Obj->getTargetTriple());
+  if (T.getArch() != Triple::wasm32) {
+    error(toString(MB.getBufferIdentifier()) + ": machine type must be wasm32");
+    return;
+  }
+
+  for (const lto::InputFile::Symbol &ObjSym : Obj->symbols())
+    Symbols.push_back(createBitcodeSymbol(ObjSym, *this));
+}
+
 // Returns a string in the format of "foo.o" or "foo.a(bar.o)".
 std::string lld::toString(const wasm::InputFile *File) {
   if (!File)
diff --git a/wasm/InputFiles.h b/wasm/InputFiles.h
index f0fd267..75d20e6 100644
--- a/wasm/InputFiles.h
+++ b/wasm/InputFiles.h
@@ -14,6 +14,7 @@
 #include "lld/Common/LLVM.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseSet.h"
+#include "llvm/LTO/LTO.h"
 #include "llvm/Object/Archive.h"
 #include "llvm/Object/Wasm.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -28,6 +29,12 @@
 using llvm::wasm::WasmRelocation;
 using llvm::wasm::WasmSignature;
 
+namespace llvm {
+namespace lto {
+class InputFile;
+}
+} // namespace llvm
+
 namespace lld {
 namespace wasm {
 
@@ -35,12 +42,14 @@
 class InputFunction;
 class InputSegment;
 class InputGlobal;
+class InputSection;
 
 class InputFile {
 public:
   enum Kind {
     ObjectKind,
     ArchiveKind,
+    BitcodeKind,
   };
 
   virtual ~InputFile() {}
@@ -56,10 +65,15 @@
   // An archive file name if this file is created from an archive.
   StringRef ParentName;
 
+  ArrayRef<Symbol *> getSymbols() const { return Symbols; }
+
 protected:
   InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {}
   MemoryBufferRef MB;
 
+  // List of all symbols referenced or defined by this file.
+  std::vector<Symbol *> Symbols;
+
 private:
   const Kind FileKind;
 };
@@ -94,6 +108,7 @@
 
   uint32_t calcNewIndex(const WasmRelocation &Reloc) const;
   uint32_t calcNewValue(const WasmRelocation &Reloc) const;
+  uint32_t calcNewAddend(const WasmRelocation &Reloc) const;
   uint32_t calcExpectedValue(const WasmRelocation &Reloc) const;
 
   const WasmSection *CodeSection = nullptr;
@@ -108,12 +123,14 @@
   std::vector<InputSegment *> Segments;
   std::vector<InputFunction *> Functions;
   std::vector<InputGlobal *> Globals;
+  std::vector<InputSection *> CustomSections;
+  llvm::DenseMap<uint32_t, InputSection *> CustomSectionsByIndex;
 
-  ArrayRef<Symbol *> getSymbols() const { return Symbols; }
   Symbol *getSymbol(uint32_t Index) const { return Symbols[Index]; }
   FunctionSymbol *getFunctionSymbol(uint32_t Index) const;
   DataSymbol *getDataSymbol(uint32_t Index) const;
   GlobalSymbol *getGlobalSymbol(uint32_t Index) const;
+  SectionSymbol *getSectionSymbol(uint32_t Index) const;
 
 private:
   Symbol *createDefined(const WasmSymbol &Sym);
@@ -121,12 +138,18 @@
 
   bool isExcludedByComdat(InputChunk *Chunk) const;
 
-  // List of all symbols referenced or defined by this file.
-  std::vector<Symbol *> Symbols;
-
   std::unique_ptr<WasmObjectFile> WasmObj;
 };
 
+class BitcodeFile : public InputFile {
+public:
+  explicit BitcodeFile(MemoryBufferRef M) : InputFile(BitcodeKind, M) {}
+  static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; }
+
+  void parse() override;
+  std::unique_ptr<llvm::lto::InputFile> Obj;
+};
+
 // Opens a given file.
 llvm::Optional<MemoryBufferRef> readFile(StringRef Path);
 
diff --git a/wasm/InputGlobal.h b/wasm/InputGlobal.h
index 16a6b7d..37d0ab9 100644
--- a/wasm/InputGlobal.h
+++ b/wasm/InputGlobal.h
@@ -26,8 +26,10 @@
 // combined to form the final GLOBALS section.
 class InputGlobal {
 public:
-  InputGlobal(const WasmGlobal &G) : Global(G) {}
+  InputGlobal(const WasmGlobal &G, ObjFile *F)
+      : File(F), Global(G), Live(!Config->GcSections) {}
 
+  StringRef getName() const { return Global.SymbolName; }
   const WasmGlobalType &getType() const { return Global.Type; }
 
   uint32_t getGlobalIndex() const { return GlobalIndex.getValue(); }
@@ -37,16 +39,21 @@
     GlobalIndex = Index;
   }
 
-  bool Live = false;
-
+  ObjFile *File;
   WasmGlobal Global;
 
+  bool Live = false;
+
 protected:
   llvm::Optional<uint32_t> GlobalIndex;
 };
 
 } // namespace wasm
 
+inline std::string toString(const wasm::InputGlobal *G) {
+  return (toString(G->File) + ":(" + G->getName() + ")").str();
+}
+
 } // namespace lld
 
 #endif // LLD_WASM_INPUT_GLOBAL_H
diff --git a/wasm/LTO.cpp b/wasm/LTO.cpp
new file mode 100644
index 0000000..58f32aa
--- /dev/null
+++ b/wasm/LTO.cpp
@@ -0,0 +1,151 @@
+//===- LTO.cpp ------------------------------------------------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LTO.h"
+#include "Config.h"
+#include "InputFiles.h"
+#include "Symbols.h"
+#include "lld/Common/ErrorHandler.h"
+#include "lld/Common/Strings.h"
+#include "lld/Common/TargetOptionsCommandFlags.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/IR/DiagnosticPrinter.h"
+#include "llvm/LTO/Caching.h"
+#include "llvm/LTO/Config.h"
+#include "llvm/LTO/LTO.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cstddef>
+#include <memory>
+#include <string>
+#include <system_error>
+#include <vector>
+
+using namespace llvm;
+using namespace llvm::object;
+
+using namespace lld;
+using namespace lld::wasm;
+
+static std::unique_ptr<lto::LTO> createLTO() {
+  lto::Config C;
+  C.Options = InitTargetOptionsFromCodeGenFlags();
+
+  // Always emit a section per function/datum with LTO.
+  C.Options.FunctionSections = true;
+  C.Options.DataSections = true;
+
+  C.DisableVerify = Config->DisableVerify;
+  C.DiagHandler = diagnosticHandler;
+  C.OptLevel = Config->LTOO;
+
+  if (Config->SaveTemps)
+    checkError(C.addSaveTemps(Config->OutputFile.str() + ".",
+                              /*UseInputModulePath*/ true));
+
+  lto::ThinBackend Backend;
+  if (Config->ThinLTOJobs != -1U)
+    Backend = lto::createInProcessThinBackend(Config->ThinLTOJobs);
+  return llvm::make_unique<lto::LTO>(std::move(C), Backend,
+                                     Config->LTOPartitions);
+}
+
+BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) {}
+
+BitcodeCompiler::~BitcodeCompiler() = default;
+
+static void undefine(Symbol *S) {
+  if (isa<DefinedFunction>(S))
+    replaceSymbol<UndefinedFunction>(S, S->getName(), 0);
+  else if (isa<DefinedData>(S))
+    replaceSymbol<UndefinedData>(S, S->getName(), 0);
+  else
+    llvm_unreachable("unexpected symbol kind");
+}
+
+void BitcodeCompiler::add(BitcodeFile &F) {
+  lto::InputFile &Obj = *F.Obj;
+  unsigned SymNum = 0;
+  ArrayRef<Symbol *> Syms = F.getSymbols();
+  std::vector<lto::SymbolResolution> Resols(Syms.size());
+
+  // Provide a resolution to the LTO API for each symbol.
+  for (const lto::InputFile::Symbol &ObjSym : Obj.symbols()) {
+    Symbol *Sym = Syms[SymNum];
+    lto::SymbolResolution &R = Resols[SymNum];
+    ++SymNum;
+
+    // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile
+    // reports two symbols for module ASM defined. Without this check, lld
+    // flags an undefined in IR with a definition in ASM as prevailing.
+    // Once IRObjectFile is fixed to report only one symbol this hack can
+    // be removed.
+    R.Prevailing = !ObjSym.isUndefined() && Sym->getFile() == &F;
+    R.VisibleToRegularObj = Config->Relocatable || Sym->IsUsedInRegularObj;
+    if (R.Prevailing)
+      undefine(Sym);
+  }
+  checkError(LTOObj->add(std::move(F.Obj), Resols));
+}
+
+// Merge all the bitcode files we have seen, codegen the result
+// and return the resulting objects.
+std::vector<StringRef> BitcodeCompiler::compile() {
+  unsigned MaxTasks = LTOObj->getMaxTasks();
+  Buf.resize(MaxTasks);
+  Files.resize(MaxTasks);
+
+  // The --thinlto-cache-dir option specifies the path to a directory in which
+  // to cache native object files for ThinLTO incremental builds. If a path was
+  // specified, configure LTO to use it as the cache directory.
+  lto::NativeObjectCache Cache;
+  if (!Config->ThinLTOCacheDir.empty())
+    Cache = check(
+        lto::localCache(Config->ThinLTOCacheDir,
+                        [&](size_t Task, std::unique_ptr<MemoryBuffer> MB) {
+                          Files[Task] = std::move(MB);
+                        }));
+
+  checkError(LTOObj->run(
+      [&](size_t Task) {
+        return llvm::make_unique<lto::NativeObjectStream>(
+            llvm::make_unique<raw_svector_ostream>(Buf[Task]));
+      },
+      Cache));
+
+  if (!Config->ThinLTOCacheDir.empty())
+    pruneCache(Config->ThinLTOCacheDir, Config->ThinLTOCachePolicy);
+
+  std::vector<StringRef> Ret;
+  for (unsigned I = 0; I != MaxTasks; ++I) {
+    if (Buf[I].empty())
+      continue;
+    if (Config->SaveTemps) {
+      if (I == 0)
+        saveBuffer(Buf[I], Config->OutputFile + ".lto.o");
+      else
+        saveBuffer(Buf[I], Config->OutputFile + Twine(I) + ".lto.o");
+    }
+    Ret.emplace_back(Buf[I].data(), Buf[I].size());
+  }
+
+  for (std::unique_ptr<MemoryBuffer> &File : Files)
+    if (File)
+      Ret.push_back(File->getBuffer());
+
+  return Ret;
+}
diff --git a/wasm/LTO.h b/wasm/LTO.h
new file mode 100644
index 0000000..cf726de
--- /dev/null
+++ b/wasm/LTO.h
@@ -0,0 +1,57 @@
+//===- LTO.h ----------------------------------------------------*- C++ -*-===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a way to combine bitcode files into one wasm
+// file by compiling them using LLVM.
+//
+// If LTO is in use, your input files are not in regular wasm files
+// but instead LLVM bitcode files. In that case, the linker has to
+// convert bitcode files into the native format so that we can create
+// a wasm file that contains native code. This file provides that
+// functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_WASM_LTO_H
+#define LLD_WASM_LTO_H
+
+#include "lld/Common/LLVM.h"
+#include "llvm/ADT/SmallString.h"
+#include <memory>
+#include <vector>
+
+namespace llvm {
+namespace lto {
+class LTO;
+}
+} // namespace llvm
+
+namespace lld {
+namespace wasm {
+
+class BitcodeFile;
+class InputFile;
+
+class BitcodeCompiler {
+public:
+  BitcodeCompiler();
+  ~BitcodeCompiler();
+
+  void add(BitcodeFile &F);
+  std::vector<StringRef> compile();
+
+private:
+  std::unique_ptr<llvm::lto::LTO> LTOObj;
+  std::vector<SmallString<0>> Buf;
+  std::vector<std::unique_ptr<MemoryBuffer>> Files;
+};
+} // namespace wasm
+} // namespace lld
+
+#endif
diff --git a/wasm/MarkLive.cpp b/wasm/MarkLive.cpp
index 9b72697..7c4670d 100644
--- a/wasm/MarkLive.cpp
+++ b/wasm/MarkLive.cpp
@@ -22,6 +22,7 @@
 #include "MarkLive.h"
 #include "Config.h"
 #include "InputChunks.h"
+#include "InputGlobal.h"
 #include "SymbolTable.h"
 #include "Symbols.h"
 
@@ -36,17 +37,15 @@
   if (!Config->GcSections)
     return;
 
-  DEBUG(dbgs() << "markLive\n");
+  LLVM_DEBUG(dbgs() << "markLive\n");
   SmallVector<InputChunk *, 256> Q;
 
   auto Enqueue = [&](Symbol *Sym) {
-    if (!Sym)
+    if (!Sym || Sym->isLive())
       return;
-    InputChunk *Chunk = Sym->getChunk();
-    if (!Chunk || Chunk->Live)
-      return;
-    Chunk->Live = true;
-    Q.push_back(Chunk);
+    Sym->markLive();
+    if (InputChunk *Chunk = Sym->getChunk())
+      Q.push_back(Chunk);
   };
 
   // Add GC root symbols.
@@ -104,6 +103,15 @@
       for (InputChunk *C : Obj->Segments)
         if (!C->Live)
           message("removing unused section " + toString(C));
+      for (InputGlobal *G : Obj->Globals)
+        if (!G->Live)
+          message("removing unused section " + toString(G));
     }
+    for (InputChunk *C : Symtab->SyntheticFunctions)
+      if (!C->Live)
+        message("removing unused section " + toString(C));
+    for (InputGlobal *G : Symtab->SyntheticGlobals)
+      if (!G->Live)
+        message("removing unused section " + toString(G));
   }
 }
diff --git a/wasm/Options.td b/wasm/Options.td
index a68e350..4dbed35 100644
--- a/wasm/Options.td
+++ b/wasm/Options.td
@@ -21,7 +21,7 @@
   HelpText<"Use colors in diagnostics">;
 
 def color_diagnostics_eq: J<"color-diagnostics=">,
-  HelpText<"Use colors in diagnostics">;
+  HelpText<"Use colors in diagnostics; one of 'always', 'never', 'auto'">;
 
 defm demangle: B<"demangle",
     "Demangle symbol names",
@@ -40,6 +40,10 @@
     "Enable garbage collection of unused sections",
     "Disable garbage collection of unused sections">;
 
+defm merge_data_segments: B<"merge-data-segments",
+    "Enable merging data segments",
+    "Disable merging data segments">;
+
 def help: F<"help">, HelpText<"Print option help">;
 
 def l: JoinedOrSeparate<["-"], "l">, MetaVarName<"<libName>">,
@@ -61,6 +65,8 @@
 def o: JoinedOrSeparate<["-"], "o">, MetaVarName<"<path>">,
   HelpText<"Path to file to write output">;
 
+def O: JoinedOrSeparate<["-"], "O">, HelpText<"Optimize output file size">;
+
 defm print_gc_sections: B<"print-gc-sections",
     "List removed unused sections",
     "Do not list removed unused sections">;
@@ -96,10 +102,6 @@
 def allow_undefined_file_s: Separate<["-"], "allow-undefined-file">,
   Alias<allow_undefined_file>;
 
-defm check_signatures: B<"check-signatures",
-    "Check function signatures",
-    "Don't check function signatures">;
-
 defm export: Eq<"export">,
   HelpText<"Force a symbol to be exported">;
 
@@ -124,6 +126,9 @@
 def no_entry: F<"no-entry">,
   HelpText<"Do not output any entry point">;
 
+def stack_first: F<"stack-first">,
+  HelpText<"Place stack at start of linear memory rather than after data">;
+
 // Aliases
 def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>;
 def alias_entry_entry: J<"entry=">, Alias<entry>;
@@ -131,3 +136,16 @@
 def alias_max_memory_m: Flag<["-"], "m">, Alias<max_memory>;
 def alias_relocatable_r: Flag<["-"], "r">, Alias<relocatable>;
 def alias_undefined_u: JoinedOrSeparate<["-"], "u">, Alias<undefined>;
+
+// LTO-related options.
+def lto_O: J<"lto-O">, MetaVarName<"<opt-level>">,
+  HelpText<"Optimization level for LTO">;
+def lto_partitions: J<"lto-partitions=">,
+  HelpText<"Number of LTO codegen partitions">;
+def disable_verify: F<"disable-verify">;
+def save_temps: F<"save-temps">;
+def thinlto_cache_dir: J<"thinlto-cache-dir=">,
+  HelpText<"Path to ThinLTO cached object file directory">;
+defm thinlto_cache_policy: Eq<"thinlto-cache-policy">,
+  HelpText<"Pruning policy for the ThinLTO cache">;
+def thinlto_jobs: J<"thinlto-jobs=">, HelpText<"Number of ThinLTO jobs">;
diff --git a/wasm/OutputSections.cpp b/wasm/OutputSections.cpp
index 9683a2d..256a988 100644
--- a/wasm/OutputSections.cpp
+++ b/wasm/OutputSections.cpp
@@ -85,8 +85,9 @@
   OS.flush();
   BodySize = CodeSectionHeader.size();
 
-  for (InputChunk *Func : Functions) {
+  for (InputFunction *Func : Functions) {
     Func->OutputOffset = BodySize;
+    Func->calculateSize();
     BodySize += Func->getSize();
   }
 
@@ -140,12 +141,13 @@
     writeUleb128(OS, WASM_OPCODE_END, "opcode:end");
     writeUleb128(OS, Segment->Size, "segment size");
     OS.flush();
-    Segment->setSectionOffset(BodySize);
+
+    Segment->SectionOffset = BodySize;
     BodySize += Segment->Header.size() + Segment->Size;
     log("Data segment: size=" + Twine(Segment->Size));
+
     for (InputSegment *InputSeg : Segment->InputSegments)
-      InputSeg->OutputOffset = Segment->getSectionOffset() +
-                               Segment->Header.size() +
+      InputSeg->OutputOffset = Segment->SectionOffset + Segment->Header.size() +
                                InputSeg->OutputSegmentOffset;
   }
 
@@ -166,7 +168,7 @@
 
   parallelForEach(Segments, [&](const OutputSegment *Segment) {
     // Write data segment header
-    uint8_t *SegStart = Buf + Segment->getSectionOffset();
+    uint8_t *SegStart = Buf + Segment->SectionOffset;
     memcpy(SegStart, Segment->Header.data(), Segment->Header.size());
 
     // Write segment data payload
@@ -188,3 +190,50 @@
     for (const InputChunk *C : Seg->InputSegments)
       C->writeRelocations(OS);
 }
+
+CustomSection::CustomSection(std::string Name,
+                             ArrayRef<InputSection *> InputSections)
+    : OutputSection(WASM_SEC_CUSTOM, Name), PayloadSize(0),
+      InputSections(InputSections) {
+  raw_string_ostream OS(NameData);
+  encodeULEB128(Name.size(), OS);
+  OS << Name;
+  OS.flush();
+
+  for (InputSection *Section : InputSections) {
+    Section->OutputOffset = PayloadSize;
+    PayloadSize += Section->getSize();
+  }
+
+  createHeader(PayloadSize + NameData.size());
+}
+
+void CustomSection::writeTo(uint8_t *Buf) {
+  log("writing " + toString(*this) + " size=" + Twine(getSize()) +
+      " chunks=" + Twine(InputSections.size()));
+
+  assert(Offset);
+  Buf += Offset;
+
+  // Write section header
+  memcpy(Buf, Header.data(), Header.size());
+  Buf += Header.size();
+  memcpy(Buf, NameData.data(), NameData.size());
+  Buf += NameData.size();
+
+  // Write custom sections payload
+  parallelForEach(InputSections,
+                  [&](const InputSection *Section) { Section->writeTo(Buf); });
+}
+
+uint32_t CustomSection::numRelocations() const {
+  uint32_t Count = 0;
+  for (const InputSection *InputSect : InputSections)
+    Count += InputSect->NumRelocations();
+  return Count;
+}
+
+void CustomSection::writeRelocations(raw_ostream &OS) const {
+  for (const InputSection *S : InputSections)
+    S->writeRelocations(OS);
+}
diff --git a/wasm/OutputSections.h b/wasm/OutputSections.h
index 2ecee95..189d650 100644
--- a/wasm/OutputSections.h
+++ b/wasm/OutputSections.h
@@ -113,6 +113,29 @@
   size_t BodySize = 0;
 };
 
+// Represents a custom section in the output file.  Wasm custom sections are 
+// used for storing user-defined metadata.  Unlike the core sections types
+// they are identified by their string name.
+// The linker combines custom sections that have the same name by simply
+// concatenating them.
+// Note that some custom sections such as "name" and "linking" are handled
+// separately and are instead synthesized by the linker.
+class CustomSection : public OutputSection {
+public:
+  CustomSection(std::string Name, ArrayRef<InputSection *> InputSections);
+  size_t getSize() const override {
+    return Header.size() + NameData.size() + PayloadSize;
+  }
+  void writeTo(uint8_t *Buf) override;
+  uint32_t numRelocations() const override;
+  void writeRelocations(raw_ostream &OS) const override;
+
+protected:
+  size_t PayloadSize;
+  ArrayRef<InputSection *> InputSections;
+  std::string NameData;
+};
+
 } // namespace wasm
 } // namespace lld
 
diff --git a/wasm/OutputSegment.h b/wasm/OutputSegment.h
index 7973013..d5c89cd 100644
--- a/wasm/OutputSegment.h
+++ b/wasm/OutputSegment.h
@@ -32,12 +32,9 @@
     Size += InSeg->getSize();
   }
 
-  uint32_t getSectionOffset() const { return SectionOffset; }
-
-  void setSectionOffset(uint32_t Offset) { SectionOffset = Offset; }
-
   StringRef Name;
   const uint32_t Index;
+  uint32_t SectionOffset = 0;
   uint32_t Alignment = 0;
   uint32_t StartVA = 0;
   std::vector<InputSegment *> InputSegments;
@@ -47,9 +44,6 @@
 
   // Segment header
   std::string Header;
-
-private:
-  uint32_t SectionOffset = 0;
 };
 
 } // namespace wasm
diff --git a/wasm/SymbolTable.cpp b/wasm/SymbolTable.cpp
index 153b507..6cc7c36 100644
--- a/wasm/SymbolTable.cpp
+++ b/wasm/SymbolTable.cpp
@@ -29,17 +29,46 @@
   log("Processing: " + toString(File));
   File->parse();
 
-  if (auto *F = dyn_cast<ObjFile>(File))
+  // LLVM bitcode file
+  if (auto *F = dyn_cast<BitcodeFile>(File))
+    BitcodeFiles.push_back(F);
+  else if (auto *F = dyn_cast<ObjFile>(File))
     ObjectFiles.push_back(F);
 }
 
+// This function is where all the optimizations of link-time
+// optimization happens. When LTO is in use, some input files are
+// not in native object file format but in the LLVM bitcode format.
+// This function compiles bitcode files into a few big native files
+// using LLVM functions and replaces bitcode symbols with the results.
+// Because all bitcode files that the program consists of are passed
+// to the compiler at once, it can do whole-program optimization.
+void SymbolTable::addCombinedLTOObject() {
+  if (BitcodeFiles.empty())
+    return;
+
+  // Compile bitcode files and replace bitcode symbols.
+  LTO.reset(new BitcodeCompiler);
+  for (BitcodeFile *F : BitcodeFiles)
+    LTO->add(*F);
+
+  for (StringRef Filename : LTO->compile()) {
+    auto *Obj = make<ObjFile>(MemoryBufferRef(Filename, "lto.tmp"));
+    Obj->parse();
+    ObjectFiles.push_back(Obj);
+  }
+}
+
 void SymbolTable::reportRemainingUndefines() {
   SetVector<Symbol *> Undefs;
   for (Symbol *Sym : SymVector) {
-    if (Sym->isUndefined() && !Sym->isWeak() &&
-        Config->AllowUndefinedSymbols.count(Sym->getName()) == 0) {
-      Undefs.insert(Sym);
-    }
+    if (!Sym->isUndefined() || Sym->isWeak())
+      continue;
+    if (Config->AllowUndefinedSymbols.count(Sym->getName()) != 0)
+      continue;
+    if (!Sym->IsUsedInRegularObj)
+      continue;
+    Undefs.insert(Sym);
   }
 
   if (Undefs.empty())
@@ -64,35 +93,33 @@
   if (Sym)
     return {Sym, false};
   Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
+  Sym->IsUsedInRegularObj = false;
   SymVector.emplace_back(Sym);
   return {Sym, true};
 }
 
 static void reportTypeError(const Symbol *Existing, const InputFile *File,
-                            StringRef Type) {
+                            llvm::wasm::WasmSymbolType Type) {
   error("symbol type mismatch: " + toString(*Existing) + "\n>>> defined as " +
         toString(Existing->getWasmType()) + " in " +
-        toString(Existing->getFile()) + "\n>>> defined as " + Type + " in " +
-        toString(File));
+        toString(Existing->getFile()) + "\n>>> defined as " + toString(Type) +
+        " in " + toString(File));
 }
 
 static void checkFunctionType(const Symbol *Existing, const InputFile *File,
                               const WasmSignature *NewSig) {
-  if (!isa<FunctionSymbol>(Existing)) {
-    reportTypeError(Existing, File, "Function");
+  auto ExistingFunction = dyn_cast<FunctionSymbol>(Existing);
+  if (!ExistingFunction) {
+    reportTypeError(Existing, File, WASM_SYMBOL_TYPE_FUNCTION);
     return;
   }
 
-  if (!Config->CheckSignatures)
-    return;
-
-  const WasmSignature *OldSig =
-      cast<FunctionSymbol>(Existing)->getFunctionType();
-  if (OldSig && *NewSig != *OldSig) {
-    error("Function type mismatch: " + Existing->getName() +
-          "\n>>> defined as " + toString(*OldSig) + " in " +
-          toString(Existing->getFile()) + "\n>>> defined as " +
-          toString(*NewSig) + " in " + toString(File));
+  const WasmSignature *OldSig = ExistingFunction->getFunctionType();
+  if (OldSig && NewSig && *NewSig != *OldSig) {
+    warn("Function type mismatch: " + Existing->getName() +
+         "\n>>> defined as " + toString(*OldSig) + " in " +
+         toString(Existing->getFile()) + "\n>>> defined as " +
+         toString(*NewSig) + " in " + toString(File));
   }
 }
 
@@ -101,7 +128,7 @@
 static void checkGlobalType(const Symbol *Existing, const InputFile *File,
                             const WasmGlobalType *NewType) {
   if (!isa<GlobalSymbol>(Existing)) {
-    reportTypeError(Existing, File, "Global");
+    reportTypeError(Existing, File, WASM_SYMBOL_TYPE_GLOBAL);
     return;
   }
 
@@ -115,13 +142,13 @@
 
 static void checkDataType(const Symbol *Existing, const InputFile *File) {
   if (!isa<DataSymbol>(Existing))
-    reportTypeError(Existing, File, "Data");
+    reportTypeError(Existing, File, WASM_SYMBOL_TYPE_DATA);
 }
 
 DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name,
                                                    uint32_t Flags,
                                                    InputFunction *Function) {
-  DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n");
+  LLVM_DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n");
   assert(!find(Name));
   SyntheticFunctions.emplace_back(Function);
   return replaceSymbol<DefinedFunction>(insert(Name).first, Name, Flags,
@@ -130,14 +157,15 @@
 
 DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name,
                                                  uint32_t Flags) {
-  DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n");
+  LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n");
   assert(!find(Name));
   return replaceSymbol<DefinedData>(insert(Name).first, Name, Flags);
 }
 
 DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags,
                                                InputGlobal *Global) {
-  DEBUG(dbgs() << "addSyntheticGlobal: " << Name << " -> " << Global << "\n");
+  LLVM_DEBUG(dbgs() << "addSyntheticGlobal: " << Name << " -> " << Global
+                    << "\n");
   assert(!find(Name));
   SyntheticGlobals.emplace_back(Global);
   return replaceSymbol<DefinedGlobal>(insert(Name).first, Name, Flags, nullptr,
@@ -148,20 +176,20 @@
                           uint32_t NewFlags) {
   // If existing symbol is undefined, replace it.
   if (!Existing->isDefined()) {
-    DEBUG(dbgs() << "resolving existing undefined symbol: "
-                 << Existing->getName() << "\n");
+    LLVM_DEBUG(dbgs() << "resolving existing undefined symbol: "
+                      << Existing->getName() << "\n");
     return true;
   }
 
   // Now we have two defined symbols. If the new one is weak, we can ignore it.
   if ((NewFlags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) {
-    DEBUG(dbgs() << "existing symbol takes precedence\n");
+    LLVM_DEBUG(dbgs() << "existing symbol takes precedence\n");
     return false;
   }
 
   // If the existing symbol is weak, we should replace it.
   if (Existing->isWeak()) {
-    DEBUG(dbgs() << "replacing existing weak symbol\n");
+    LLVM_DEBUG(dbgs() << "replacing existing weak symbol\n");
     return true;
   }
 
@@ -175,17 +203,21 @@
 Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags,
                                         InputFile *File,
                                         InputFunction *Function) {
-  DEBUG(dbgs() << "addDefinedFunction: " << Name << "\n");
+  LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << "\n");
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name);
 
+  if (!File || File->kind() == InputFile::ObjectKind)
+    S->IsUsedInRegularObj = true;
+
   if (WasInserted || S->isLazy()) {
     replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function);
     return S;
   }
 
-  checkFunctionType(S, File, &Function->Signature);
+  if (Function)
+    checkFunctionType(S, File, &Function->Signature);
 
   if (shouldReplace(S, File, Flags))
     replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function);
@@ -195,11 +227,15 @@
 Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags,
                                     InputFile *File, InputSegment *Segment,
                                     uint32_t Address, uint32_t Size) {
-  DEBUG(dbgs() << "addDefinedData:" << Name << " addr:" << Address << "\n");
+  LLVM_DEBUG(dbgs() << "addDefinedData:" << Name << " addr:" << Address
+                    << "\n");
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name);
 
+  if (!File || File->kind() == InputFile::ObjectKind)
+    S->IsUsedInRegularObj = true;
+
   if (WasInserted || S->isLazy()) {
     replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size);
     return S;
@@ -214,11 +250,14 @@
 
 Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags,
                                       InputFile *File, InputGlobal *Global) {
-  DEBUG(dbgs() << "addDefinedGlobal:" << Name << "\n");
+  LLVM_DEBUG(dbgs() << "addDefinedGlobal:" << Name << "\n");
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name);
 
+  if (!File || File->kind() == InputFile::ObjectKind)
+    S->IsUsedInRegularObj = true;
+
   if (WasInserted || S->isLazy()) {
     replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global);
     return S;
@@ -234,12 +273,15 @@
 Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags,
                                           InputFile *File,
                                           const WasmSignature *Sig) {
-  DEBUG(dbgs() << "addUndefinedFunction: " << Name << "\n");
+  LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << "\n");
 
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name);
 
+  if (!File || File->kind() == InputFile::ObjectKind)
+    S->IsUsedInRegularObj = true;
+
   if (WasInserted)
     replaceSymbol<UndefinedFunction>(S, Name, Flags, File, Sig);
   else if (auto *Lazy = dyn_cast<LazySymbol>(S))
@@ -251,7 +293,7 @@
 
 Symbol *SymbolTable::addUndefinedData(StringRef Name, uint32_t Flags,
                                       InputFile *File) {
-  DEBUG(dbgs() << "addUndefinedData: " << Name << "\n");
+  LLVM_DEBUG(dbgs() << "addUndefinedData: " << Name << "\n");
 
   Symbol *S;
   bool WasInserted;
@@ -269,12 +311,15 @@
 Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, uint32_t Flags,
                                         InputFile *File,
                                         const WasmGlobalType *Type) {
-  DEBUG(dbgs() << "addUndefinedGlobal: " << Name << "\n");
+  LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << Name << "\n");
 
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name);
 
+  if (!File || File->kind() == InputFile::ObjectKind)
+    S->IsUsedInRegularObj = true;
+
   if (WasInserted)
     replaceSymbol<UndefinedGlobal>(S, Name, Flags, File, Type);
   else if (auto *Lazy = dyn_cast<LazySymbol>(S))
@@ -285,7 +330,7 @@
 }
 
 void SymbolTable::addLazy(ArchiveFile *File, const Archive::Symbol *Sym) {
-  DEBUG(dbgs() << "addLazy: " << Sym->getName() << "\n");
+  LLVM_DEBUG(dbgs() << "addLazy: " << Sym->getName() << "\n");
   StringRef Name = Sym->getName();
 
   Symbol *S;
@@ -299,7 +344,7 @@
 
   // If there is an existing undefined symbol, load a new one from the archive.
   if (S->isUndefined()) {
-    DEBUG(dbgs() << "replacing existing undefined\n");
+    LLVM_DEBUG(dbgs() << "replacing existing undefined\n");
     File->addMember(Sym);
   }
 }
diff --git a/wasm/SymbolTable.h b/wasm/SymbolTable.h
index 6fb5c15..26242e6 100644
--- a/wasm/SymbolTable.h
+++ b/wasm/SymbolTable.h
@@ -11,6 +11,7 @@
 #define LLD_WASM_SYMBOL_TABLE_H
 
 #include "InputFiles.h"
+#include "LTO.h"
 #include "Symbols.h"
 #include "llvm/ADT/CachedHashString.h"
 #include "llvm/ADT/DenseSet.h"
@@ -39,8 +40,10 @@
 class SymbolTable {
 public:
   void addFile(InputFile *File);
+  void addCombinedLTOObject();
 
   std::vector<ObjFile *> ObjectFiles;
+  std::vector<BitcodeFile *> BitcodeFiles;
   std::vector<InputFunction *> SyntheticFunctions;
   std::vector<InputGlobal *> SyntheticGlobals;
 
@@ -80,6 +83,9 @@
   std::vector<Symbol *> SymVector;
 
   llvm::DenseSet<llvm::CachedHashStringRef> Comdats;
+
+  // For LTO.
+  std::unique_ptr<BitcodeCompiler> LTO;
 };
 
 extern SymbolTable *Symtab;
diff --git a/wasm/Symbols.cpp b/wasm/Symbols.cpp
index bcebcdc..6b43eb3 100644
--- a/wasm/Symbols.cpp
+++ b/wasm/Symbols.cpp
@@ -31,11 +31,13 @@
 
 WasmSymbolType Symbol::getWasmType() const {
   if (isa<FunctionSymbol>(this))
-    return llvm::wasm::WASM_SYMBOL_TYPE_FUNCTION;
+    return WASM_SYMBOL_TYPE_FUNCTION;
   if (isa<DataSymbol>(this))
-    return llvm::wasm::WASM_SYMBOL_TYPE_DATA;
+    return WASM_SYMBOL_TYPE_DATA;
   if (isa<GlobalSymbol>(this))
-    return llvm::wasm::WASM_SYMBOL_TYPE_GLOBAL;
+    return WASM_SYMBOL_TYPE_GLOBAL;
+  if (isa<SectionSymbol>(this))
+    return WASM_SYMBOL_TYPE_SECTION;
   llvm_unreachable("invalid symbol kind");
 }
 
@@ -52,8 +54,15 @@
     return G->Global->Live;
   if (InputChunk *C = getChunk())
     return C->Live;
-  // Assume any other kind of symbol is live.
-  return true;
+  return Referenced;
+}
+
+void Symbol::markLive() {
+  if (auto *G = dyn_cast<DefinedGlobal>(this))
+    G->Global->Live = true;
+  if (InputChunk *C = getChunk())
+    C->Live = true;
+  Referenced = true;
 }
 
 uint32_t Symbol::getOutputSymbolIndex() const {
@@ -62,7 +71,8 @@
 }
 
 void Symbol::setOutputSymbolIndex(uint32_t Index) {
-  DEBUG(dbgs() << "setOutputSymbolIndex " << Name << " -> " << Index << "\n");
+  LLVM_DEBUG(dbgs() << "setOutputSymbolIndex " << Name << " -> " << Index
+                    << "\n");
   assert(OutputSymbolIndex == INVALID_INDEX);
   OutputSymbolIndex = Index;
 }
@@ -80,7 +90,7 @@
 }
 
 void Symbol::setHidden(bool IsHidden) {
-  DEBUG(dbgs() << "setHidden: " << Name << " -> " << IsHidden << "\n");
+  LLVM_DEBUG(dbgs() << "setHidden: " << Name << " -> " << IsHidden << "\n");
   Flags &= ~WASM_SYMBOL_VISIBILITY_MASK;
   if (IsHidden)
     Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
@@ -96,7 +106,7 @@
 }
 
 void FunctionSymbol::setFunctionIndex(uint32_t Index) {
-  DEBUG(dbgs() << "setFunctionIndex " << Name << " -> " << Index << "\n");
+  LLVM_DEBUG(dbgs() << "setFunctionIndex " << Name << " -> " << Index << "\n");
   assert(FunctionIndex == INVALID_INDEX);
   FunctionIndex = Index;
 }
@@ -128,7 +138,7 @@
     F->Function->setTableIndex(Index);
     return;
   }
-  DEBUG(dbgs() << "setTableIndex " << Name << " -> " << Index << "\n");
+  LLVM_DEBUG(dbgs() << "setTableIndex " << Name << " -> " << Index << "\n");
   assert(TableIndex == INVALID_INDEX);
   TableIndex = Index;
 }
@@ -140,25 +150,25 @@
       Function(Function) {}
 
 uint32_t DefinedData::getVirtualAddress() const {
-  DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");
+  LLVM_DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");
   if (Segment)
     return Segment->OutputSeg->StartVA + Segment->OutputSegmentOffset + Offset;
   return Offset;
 }
 
 void DefinedData::setVirtualAddress(uint32_t Value) {
-  DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n");
+  LLVM_DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n");
   assert(!Segment);
   Offset = Value;
 }
 
 uint32_t DefinedData::getOutputSegmentOffset() const {
-  DEBUG(dbgs() << "getOutputSegmentOffset: " << getName() << "\n");
+  LLVM_DEBUG(dbgs() << "getOutputSegmentOffset: " << getName() << "\n");
   return Segment->OutputSegmentOffset + Offset;
 }
 
 uint32_t DefinedData::getOutputSegmentIndex() const {
-  DEBUG(dbgs() << "getOutputSegmentIndex: " << getName() << "\n");
+  LLVM_DEBUG(dbgs() << "getOutputSegmentIndex: " << getName() << "\n");
   return Segment->OutputSeg->Index;
 }
 
@@ -170,7 +180,7 @@
 }
 
 void GlobalSymbol::setGlobalIndex(uint32_t Index) {
-  DEBUG(dbgs() << "setGlobalIndex " << Name << " -> " << Index << "\n");
+  LLVM_DEBUG(dbgs() << "setGlobalIndex " << Name << " -> " << Index << "\n");
   assert(GlobalIndex == INVALID_INDEX);
   GlobalIndex = Index;
 }
@@ -187,6 +197,19 @@
                    Global ? &Global->getType() : nullptr),
       Global(Global) {}
 
+uint32_t SectionSymbol::getOutputSectionIndex() const {
+  LLVM_DEBUG(dbgs() << "getOutputSectionIndex: " << getName() << "\n");
+  assert(OutputSectionIndex != INVALID_INDEX);
+  return OutputSectionIndex;
+}
+
+void SectionSymbol::setOutputSectionIndex(uint32_t Index) {
+  LLVM_DEBUG(dbgs() << "setOutputSectionIndex: " << getName() << " -> " << Index
+                    << "\n");
+  assert(Index != INVALID_INDEX);
+  OutputSectionIndex = Index;
+}
+
 void LazySymbol::fetch() { cast<ArchiveFile>(File)->addMember(&ArchiveSymbol); }
 
 std::string lld::toString(const wasm::Symbol &Sym) {
@@ -212,18 +235,8 @@
     return "UndefinedGlobal";
   case wasm::Symbol::LazyKind:
     return "LazyKind";
+  case wasm::Symbol::SectionKind:
+    return "SectionKind";
   }
   llvm_unreachable("invalid symbol kind");
 }
-
-std::string lld::toString(WasmSymbolType Type) {
-  switch (Type) {
-  case llvm::wasm::WASM_SYMBOL_TYPE_FUNCTION:
-    return "Function";
-  case llvm::wasm::WASM_SYMBOL_TYPE_DATA:
-    return "Data";
-  case llvm::wasm::WASM_SYMBOL_TYPE_GLOBAL:
-    return "Global";
-  }
-  llvm_unreachable("invalid symbol type");
-}
diff --git a/wasm/Symbols.h b/wasm/Symbols.h
index 92084f7..b2ec1e8 100644
--- a/wasm/Symbols.h
+++ b/wasm/Symbols.h
@@ -10,6 +10,7 @@
 #ifndef LLD_WASM_SYMBOLS_H
 #define LLD_WASM_SYMBOLS_H
 
+#include "Config.h"
 #include "lld/Common/LLVM.h"
 #include "llvm/Object/Archive.h"
 #include "llvm/Object/Wasm.h"
@@ -29,6 +30,7 @@
 class InputSegment;
 class InputFunction;
 class InputGlobal;
+class InputSection;
 
 #define INVALID_INDEX UINT32_MAX
 
@@ -39,6 +41,7 @@
     DefinedFunctionKind,
     DefinedDataKind,
     DefinedGlobalKind,
+    SectionKind,
     UndefinedFunctionKind,
     UndefinedDataKind,
     UndefinedGlobalKind,
@@ -49,7 +52,7 @@
 
   bool isDefined() const {
     return SymbolKind == DefinedFunctionKind || SymbolKind == DefinedDataKind ||
-           SymbolKind == DefinedGlobalKind;
+           SymbolKind == DefinedGlobalKind || SymbolKind == SectionKind;
   }
 
   bool isUndefined() const {
@@ -71,9 +74,14 @@
 
   InputChunk *getChunk() const;
 
-  // Indicates that this symbol will be included in the final image.
+  // Indicates that the section or import for this symbol will be included in
+  // the final image.
   bool isLive() const;
 
+  // Marks the symbol's InputChunk as Live, so that it will be included in the
+  // final image.
+  void markLive();
+
   void setHidden(bool IsHidden);
 
   // Get/set the index in the output symbol table.  This is only used for
@@ -83,15 +91,20 @@
 
   WasmSymbolType getWasmType() const;
 
+  // True if this symbol was referenced by a regular (non-bitcode) object.
+  unsigned IsUsedInRegularObj : 1;
+
 protected:
   Symbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F)
-      : Name(Name), SymbolKind(K), Flags(Flags), File(F) {}
+      : IsUsedInRegularObj(false), Name(Name), SymbolKind(K), Flags(Flags),
+        File(F), Referenced(!Config->GcSections) {}
 
   StringRef Name;
   Kind SymbolKind;
   uint32_t Flags;
   InputFile *File;
   uint32_t OutputSymbolIndex = INVALID_INDEX;
+  bool Referenced = false;
 };
 
 class FunctionSymbol : public Symbol {
@@ -147,6 +160,23 @@
   }
 };
 
+class SectionSymbol : public Symbol {
+public:
+  static bool classof(const Symbol *S) { return S->kind() == SectionKind; }
+
+  SectionSymbol(StringRef Name, uint32_t Flags, const InputSection *S,
+                InputFile *F = nullptr)
+      : Symbol(Name, SectionKind, Flags, F), Section(S) {}
+
+  const InputSection *Section;
+
+  uint32_t getOutputSectionIndex() const;
+  void setOutputSectionIndex(uint32_t Index);
+
+protected:
+  uint32_t OutputSectionIndex = INVALID_INDEX;
+};
+
 class DataSymbol : public Symbol {
 public:
   static bool classof(const Symbol *S) {
@@ -160,7 +190,7 @@
 
 class DefinedData : public DataSymbol {
 public:
-  // Constructor for for regular data symbols originating from input files.
+  // Constructor for regular data symbols originating from input files.
   DefinedData(StringRef Name, uint32_t Flags, InputFile *F,
               InputSegment *Segment, uint32_t Offset, uint32_t Size)
       : DataSymbol(Name, DefinedDataKind, Flags, F), Segment(Segment),
@@ -293,6 +323,7 @@
   alignas(UndefinedFunction) char E[sizeof(UndefinedFunction)];
   alignas(UndefinedData) char F[sizeof(UndefinedData)];
   alignas(UndefinedGlobal) char G[sizeof(UndefinedGlobal)];
+  alignas(SectionSymbol) char I[sizeof(SectionSymbol)];
 };
 
 template <typename T, typename... ArgT>
@@ -304,7 +335,12 @@
                 "SymbolUnion not aligned enough");
   assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
          "Not a Symbol");
-  return new (S) T(std::forward<ArgT>(Arg)...);
+
+  Symbol SymCopy = *S;
+
+  T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
+  S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
+  return S2;
 }
 
 } // namespace wasm
@@ -312,7 +348,6 @@
 // Returns a symbol name for an error message.
 std::string toString(const wasm::Symbol &Sym);
 std::string toString(wasm::Symbol::Kind Kind);
-std::string toString(WasmSymbolType Type);
 
 } // namespace lld
 
diff --git a/wasm/Writer.cpp b/wasm/Writer.cpp
index a98cfc6..ee6056a 100644
--- a/wasm/Writer.cpp
+++ b/wasm/Writer.cpp
@@ -20,6 +20,7 @@
 #include "lld/Common/Strings.h"
 #include "lld/Common/Threads.h"
 #include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/StringMap.h"
 #include "llvm/BinaryFormat/Wasm.h"
 #include "llvm/Object/WasmTraits.h"
 #include "llvm/Support/FileOutputBuffer.h"
@@ -66,6 +67,7 @@
   void assignIndexes();
   void calculateImports();
   void calculateExports();
+  void calculateCustomSections();
   void assignSymtab();
   void calculateTypes();
   void createOutputSegments();
@@ -85,6 +87,7 @@
   void createElemSection();
   void createCodeSection();
   void createDataSection();
+  void createCustomSections();
 
   // Custom sections
   void createRelocSections();
@@ -103,7 +106,7 @@
   std::vector<const Symbol *> ImportedSymbols;
   unsigned NumImportedFunctions = 0;
   unsigned NumImportedGlobals = 0;
-  std::vector<Symbol *> ExportedSymbols;
+  std::vector<WasmExport> Exports;
   std::vector<const DefinedData *> DefinedFakeGlobals;
   std::vector<InputGlobal *> InputGlobals;
   std::vector<InputFunction *> InputFunctions;
@@ -111,6 +114,9 @@
   std::vector<const Symbol *> SymtabEntries;
   std::vector<WasmInitEntry> InitFunctions;
 
+  llvm::StringMap<std::vector<InputSection *>> CustomSectionMapping;
+  llvm::StringMap<SectionSymbol *> CustomSectionSymbols;
+
   // Elements that are used to construct the final output
   std::string Header;
   std::vector<OutputSection *> OutputSections;
@@ -258,40 +264,48 @@
 }
 
 void Writer::createExportSection() {
-  bool ExportMemory = !Config->Relocatable && !Config->ImportMemory;
-  bool ExportTable = !Config->Relocatable && Config->ExportTable;
-
-  uint32_t NumExports =
-      (ExportMemory ? 1 : 0) + (ExportTable ? 1 : 0) + ExportedSymbols.size();
-  if (!NumExports)
+  if (!Exports.size())
     return;
 
   SyntheticSection *Section = createSyntheticSection(WASM_SEC_EXPORT);
   raw_ostream &OS = Section->getStream();
 
-  writeUleb128(OS, NumExports, "export count");
-
-  if (ExportMemory)
-    writeExport(OS, {"memory", WASM_EXTERNAL_MEMORY, 0});
-  if (ExportTable)
-    writeExport(OS, {kFunctionTableName, WASM_EXTERNAL_TABLE, 0});
-
-  unsigned FakeGlobalIndex = NumImportedGlobals + InputGlobals.size();
-
-  for (const Symbol *Sym : ExportedSymbols) {
-    StringRef Name = Sym->getName();
-    WasmExport Export;
-    DEBUG(dbgs() << "Export: " << Name << "\n");
-
-    if (auto *F = dyn_cast<DefinedFunction>(Sym))
-      Export = {Name, WASM_EXTERNAL_FUNCTION, F->getFunctionIndex()};
-    else if (auto *G = dyn_cast<DefinedGlobal>(Sym))
-      Export = {Name, WASM_EXTERNAL_GLOBAL, G->getGlobalIndex()};
-    else if (isa<DefinedData>(Sym))
-      Export = {Name, WASM_EXTERNAL_GLOBAL, FakeGlobalIndex++};
-    else
-      llvm_unreachable("unexpected symbol type");
+  writeUleb128(OS, Exports.size(), "export count");
+  for (const WasmExport &Export : Exports)
     writeExport(OS, Export);
+}
+
+void Writer::calculateCustomSections() {
+  log("calculateCustomSections");
+  bool StripDebug = Config->StripDebug || Config->StripAll;
+  for (ObjFile *File : Symtab->ObjectFiles) {
+    for (InputSection *Section : File->CustomSections) {
+      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."))
+        continue;
+      // .. or it is a debug section
+      if (StripDebug && Name.startswith(".debug_"))
+        continue;
+      CustomSectionMapping[Name].push_back(Section);
+    }
+  }
+}
+
+void Writer::createCustomSections() {
+  log("createCustomSections");
+  for (auto &Pair : CustomSectionMapping) {
+    StringRef Name = Pair.first();
+
+    auto P = CustomSectionSymbols.find(Name);
+    if (P != CustomSectionSymbols.end()) {
+      uint32_t SectionIndex = OutputSections.size();
+      P->second->setOutputSectionIndex(SectionIndex);
+    }
+
+    LLVM_DEBUG(dbgs() << "createCustomSection: " << Name << "\n");
+    OutputSections.push_back(make<CustomSection>(Name, Pair.second));
   }
 }
 
@@ -343,8 +357,8 @@
   log("createRelocSections");
   // Don't use iterator here since we are adding to OutputSection
   size_t OrigSize = OutputSections.size();
-  for (size_t i = 0; i < OrigSize; i++) {
-    OutputSection *OSec = OutputSections[i];
+  for (size_t I = 0; I < OrigSize; I++) {
+    OutputSection *OSec = OutputSections[I];
     uint32_t Count = OSec->numRelocations();
     if (!Count)
       continue;
@@ -354,12 +368,15 @@
       Name = "reloc.DATA";
     else if (OSec->Type == WASM_SEC_CODE)
       Name = "reloc.CODE";
+    else if (OSec->Type == WASM_SEC_CUSTOM)
+      Name = Saver.save("reloc." + OSec->Name);
     else
-      llvm_unreachable("relocations only supported for code and data");
+      llvm_unreachable(
+          "relocations only supported for code, data, or custom sections");
 
     SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, Name);
     raw_ostream &OS = Section->getStream();
-    writeUleb128(OS, OSec->Type, "reloc section");
+    writeUleb128(OS, I, "reloc section");
     writeUleb128(OS, Count, "reloc count");
     OSec->writeRelocations(OS);
   }
@@ -409,8 +426,7 @@
       createSyntheticSection(WASM_SEC_CUSTOM, "linking");
   raw_ostream &OS = Section->getStream();
 
-  if (!Config->Relocatable)
-    return;
+  writeUleb128(OS, WasmMetadataVersion, "Version");
 
   if (!SymtabEntries.empty()) {
     SubSection Sub(WASM_SYMBOL_TABLE);
@@ -432,8 +448,7 @@
         writeUleb128(Sub.OS, G->getGlobalIndex(), "index");
         if (Sym->isDefined())
           writeStr(Sub.OS, Sym->getName(), "sym name");
-      } else {
-        assert(isa<DataSymbol>(Sym));
+      } else if (isa<DataSymbol>(Sym)) {
         writeStr(Sub.OS, Sym->getName(), "sym name");
         if (auto *DataSym = dyn_cast<DefinedData>(Sym)) {
           writeUleb128(Sub.OS, DataSym->getOutputSegmentIndex(), "index");
@@ -441,6 +456,9 @@
                        "data offset");
           writeUleb128(Sub.OS, DataSym->getSize(), "data size");
         }
+      } else {
+        auto *S = cast<SectionSymbol>(Sym);
+        writeUleb128(Sub.OS, S->getOutputSectionIndex(), "sym section index");
       }
     }
 
@@ -513,7 +531,7 @@
 void Writer::createNameSection() {
   unsigned NumNames = NumImportedFunctions;
   for (const InputFunction *F : InputFunctions)
-    if (!F->getName().empty())
+    if (!F->getName().empty() || !F->getDebugName().empty())
       ++NumNames;
 
   if (NumNames == 0)
@@ -537,8 +555,12 @@
   for (const InputFunction *F : InputFunctions) {
     if (!F->getName().empty()) {
       writeUleb128(Sub.OS, F->getFunctionIndex(), "func index");
-      Optional<std::string> Name = demangleItanium(F->getName());
-      writeStr(Sub.OS, Name ? StringRef(*Name) : F->getName(), "symbol name");
+      if (!F->getDebugName().empty()) {
+        writeStr(Sub.OS, F->getDebugName(), "symbol name");
+      } else {
+        Optional<std::string> Name = demangleItanium(F->getName());
+        writeStr(Sub.OS, Name ? StringRef(*Name) : F->getName(), "symbol name");
+      }
     }
   }
 
@@ -556,22 +578,48 @@
 
 // Fix the memory layout of the output binary.  This assigns memory offsets
 // to each of the input data sections as well as the explicit stack region.
-// The memory layout is as follows, from low to high.
+// The default memory layout is as follows, from low to high.
+//
 //  - initialized data (starting at Config->GlobalBase)
 //  - BSS data (not currently implemented in llvm)
 //  - explicit stack (Config->ZStackSize)
 //  - heap start / unallocated
+//
+// The --stack-first option means that stack is placed before any static data.
+// This can be useful since it means that stack overflow traps immediately rather
+// than overwriting global data, but also increases code size since all static
+// data loads and stores requires larger offsets.
 void Writer::layoutMemory() {
-  uint32_t MemoryPtr = 0;
-  MemoryPtr = Config->GlobalBase;
-  log("mem: global base = " + Twine(Config->GlobalBase));
-
   createOutputSegments();
 
+  uint32_t MemoryPtr = 0;
+
+  auto PlaceStack = [&]() {
+    if (Config->Relocatable)
+      return;
+    MemoryPtr = alignTo(MemoryPtr, kStackAlignment);
+    if (Config->ZStackSize != alignTo(Config->ZStackSize, kStackAlignment))
+      error("stack size must be " + Twine(kStackAlignment) + "-byte aligned");
+    log("mem: stack size  = " + Twine(Config->ZStackSize));
+    log("mem: stack base  = " + Twine(MemoryPtr));
+    MemoryPtr += Config->ZStackSize;
+    WasmSym::StackPointer->Global->Global.InitExpr.Value.Int32 = MemoryPtr;
+    log("mem: stack top   = " + Twine(MemoryPtr));
+  };
+
+  if (Config->StackFirst) {
+    PlaceStack();
+  } else {
+    MemoryPtr = Config->GlobalBase;
+    log("mem: global base = " + Twine(Config->GlobalBase));
+  }
+
+  uint32_t DataStart = MemoryPtr;
+
   // Arbitrarily set __dso_handle handle to point to the start of the data
   // segments.
   if (WasmSym::DsoHandle)
-    WasmSym::DsoHandle->setVirtualAddress(MemoryPtr);
+    WasmSym::DsoHandle->setVirtualAddress(DataStart);
 
   for (OutputSegment *Seg : Segments) {
     MemoryPtr = alignTo(MemoryPtr, Seg->Alignment);
@@ -585,22 +633,15 @@
   if (WasmSym::DataEnd)
     WasmSym::DataEnd->setVirtualAddress(MemoryPtr);
 
-  log("mem: static data = " + Twine(MemoryPtr - Config->GlobalBase));
+  log("mem: static data = " + Twine(MemoryPtr - DataStart));
 
-  // Stack comes after static data and bss
+  if (!Config->StackFirst)
+    PlaceStack();
+
+  // Set `__heap_base` to directly follow the end of the stack or global data.
+  // The fact that this comes last means that a malloc/brk implementation
+  // can grow the heap at runtime.
   if (!Config->Relocatable) {
-    MemoryPtr = alignTo(MemoryPtr, kStackAlignment);
-    if (Config->ZStackSize != alignTo(Config->ZStackSize, kStackAlignment))
-      error("stack size must be " + Twine(kStackAlignment) + "-byte aligned");
-    log("mem: stack size  = " + Twine(Config->ZStackSize));
-    log("mem: stack base  = " + Twine(MemoryPtr));
-    MemoryPtr += Config->ZStackSize;
-    WasmSym::StackPointer->Global->Global.InitExpr.Value.Int32 = MemoryPtr;
-    log("mem: stack top   = " + Twine(MemoryPtr));
-
-    // Set `__heap_base` to directly follow the end of the stack.  We don't
-    // allocate any heap memory up front, but instead really on the malloc/brk
-    // implementation growing the memory at runtime.
     WasmSym::HeapBase->setVirtualAddress(MemoryPtr);
     log("mem: heap base   = " + Twine(MemoryPtr));
   }
@@ -647,6 +688,7 @@
   createElemSection();
   createCodeSection();
   createDataSection();
+  createCustomSections();
 
   // Custom sections
   if (Config->Relocatable) {
@@ -671,8 +713,12 @@
       continue;
     if (Sym->isWeak() && !Config->Relocatable)
       continue;
+    if (!Sym->isLive())
+      continue;
+    if (!Sym->IsUsedInRegularObj)
+      continue;
 
-    DEBUG(dbgs() << "import: " << Sym->getName() << "\n");
+    LLVM_DEBUG(dbgs() << "import: " << Sym->getName() << "\n");
     ImportedSymbols.emplace_back(Sym);
     if (auto *F = dyn_cast<FunctionSymbol>(Sym))
       F->setFunctionIndex(NumImportedFunctions++);
@@ -685,6 +731,14 @@
   if (Config->Relocatable)
     return;
 
+  if (!Config->Relocatable && !Config->ImportMemory)
+    Exports.push_back(WasmExport{"memory", WASM_EXTERNAL_MEMORY, 0});
+
+  if (!Config->Relocatable && Config->ExportTable)
+    Exports.push_back(WasmExport{kFunctionTableName, WASM_EXTERNAL_TABLE, 0});
+
+  unsigned FakeGlobalIndex = NumImportedGlobals + InputGlobals.size();
+
   for (Symbol *Sym : Symtab->getSymbols()) {
     if (!Sym->isDefined())
       continue;
@@ -693,11 +747,20 @@
     if (!Sym->isLive())
       continue;
 
-    DEBUG(dbgs() << "exporting sym: " << Sym->getName() << "\n");
-
-    if (auto *D = dyn_cast<DefinedData>(Sym))
+    StringRef Name = Sym->getName();
+    WasmExport Export;
+    if (auto *F = dyn_cast<DefinedFunction>(Sym)) {
+      Export = {Name, WASM_EXTERNAL_FUNCTION, F->getFunctionIndex()};
+    } else if (auto *G = dyn_cast<DefinedGlobal>(Sym)) {
+      Export = {Name, WASM_EXTERNAL_GLOBAL, G->getGlobalIndex()};
+    } else {
+      auto *D = cast<DefinedData>(Sym);
       DefinedFakeGlobals.emplace_back(D);
-    ExportedSymbols.emplace_back(Sym);
+      Export = {Name, WASM_EXTERNAL_GLOBAL, FakeGlobalIndex++};
+    }
+
+    LLVM_DEBUG(dbgs() << "Export: " << Name << "\n");
+    Exports.push_back(Export);
   }
 }
 
@@ -705,12 +768,32 @@
   if (!Config->Relocatable)
     return;
 
+  StringMap<uint32_t> SectionSymbolIndices;
+
   unsigned SymbolIndex = SymtabEntries.size();
   for (ObjFile *File : Symtab->ObjectFiles) {
-    DEBUG(dbgs() << "Symtab entries: " << File->getName() << "\n");
+    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 SSI = SectionSymbolIndices.find(Name);
+        if (SSI != SectionSymbolIndices.end()) {
+          Sym->setOutputSymbolIndex(SSI->second);
+          continue;
+        }
+
+        SectionSymbolIndices[Name] = SymbolIndex;
+        CustomSectionSymbols[Name] = cast<SectionSymbol>(Sym);
+
+        Sym->markLive();
+      }
+
       // (Since this is relocatable output, GC is not performed so symbols must
       // be live.)
       assert(Sym->isLive());
@@ -736,7 +819,7 @@
 uint32_t Writer::registerType(const WasmSignature &Sig) {
   auto Pair = TypeIndices.insert(std::make_pair(Sig, Types.size()));
   if (Pair.second) {
-    DEBUG(dbgs() << "type " << toString(Sig) << "\n");
+    LLVM_DEBUG(dbgs() << "type " << toString(Sig) << "\n");
     Types.push_back(&Sig);
   }
   return Pair.first->second;
@@ -776,7 +859,7 @@
     AddDefinedFunction(Func);
 
   for (ObjFile *File : Symtab->ObjectFiles) {
-    DEBUG(dbgs() << "Functions: " << File->getName() << "\n");
+    LLVM_DEBUG(dbgs() << "Functions: " << File->getName() << "\n");
     for (InputFunction *Func : File->Functions)
       AddDefinedFunction(Func);
   }
@@ -799,29 +882,24 @@
         // Mark target type as live
         File->TypeMap[Reloc.Index] = registerType(Types[Reloc.Index]);
         File->TypeIsUsed[Reloc.Index] = true;
-      } else if (Reloc.Type == R_WEBASSEMBLY_GLOBAL_INDEX_LEB) {
-        // Mark target global as live
-        GlobalSymbol *Sym = File->getGlobalSymbol(Reloc.Index);
-        if (auto *G = dyn_cast<DefinedGlobal>(Sym)) {
-          DEBUG(dbgs() << "marking global live: " << Sym->getName() << "\n");
-          G->Global->Live = true;
-        }
       }
     }
   };
 
   for (ObjFile *File : Symtab->ObjectFiles) {
-    DEBUG(dbgs() << "Handle relocs: " << File->getName() << "\n");
+    LLVM_DEBUG(dbgs() << "Handle relocs: " << File->getName() << "\n");
     for (InputChunk *Chunk : File->Functions)
       HandleRelocs(Chunk);
     for (InputChunk *Chunk : File->Segments)
       HandleRelocs(Chunk);
+    for (auto &P : File->CustomSections)
+      HandleRelocs(P);
   }
 
   uint32_t GlobalIndex = NumImportedGlobals + InputGlobals.size();
   auto AddDefinedGlobal = [&](InputGlobal *Global) {
     if (Global->Live) {
-      DEBUG(dbgs() << "AddDefinedGlobal: " << GlobalIndex << "\n");
+      LLVM_DEBUG(dbgs() << "AddDefinedGlobal: " << GlobalIndex << "\n");
       Global->setGlobalIndex(GlobalIndex++);
       InputGlobals.push_back(Global);
     }
@@ -831,14 +909,14 @@
     AddDefinedGlobal(Global);
 
   for (ObjFile *File : Symtab->ObjectFiles) {
-    DEBUG(dbgs() << "Globals: " << File->getName() << "\n");
+    LLVM_DEBUG(dbgs() << "Globals: " << File->getName() << "\n");
     for (InputGlobal *Global : File->Globals)
       AddDefinedGlobal(Global);
   }
 }
 
 static StringRef getOutputDataSegmentName(StringRef Name) {
-  if (Config->Relocatable)
+  if (!Config->MergeDataSegments)
     return Name;
   if (Name.startswith(".text."))
     return ".text";
@@ -857,12 +935,12 @@
       StringRef Name = getOutputDataSegmentName(Segment->getName());
       OutputSegment *&S = SegmentMap[Name];
       if (S == nullptr) {
-        DEBUG(dbgs() << "new segment: " << Name << "\n");
+        LLVM_DEBUG(dbgs() << "new segment: " << Name << "\n");
         S = make<OutputSegment>(Name, Segments.size());
         Segments.push_back(S);
       }
       S->addInputSegment(Segment);
-      DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n");
+      LLVM_DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n");
     }
   }
 }
@@ -937,6 +1015,8 @@
   layoutMemory();
   log("-- calculateExports");
   calculateExports();
+  log("-- calculateCustomSections");
+  calculateCustomSections();
   log("-- assignSymtab");
   assignSymtab();
 
diff --git a/wasm/WriterUtils.cpp b/wasm/WriterUtils.cpp
index 4c0d09e..201529e 100644
--- a/wasm/WriterUtils.cpp
+++ b/wasm/WriterUtils.cpp
@@ -37,7 +37,7 @@
 namespace lld {
 
 void wasm::debugWrite(uint64_t Offset, const Twine &Msg) {
-  DEBUG(dbgs() << format("  | %08lld: ", Offset) << Msg << "\n");
+  LLVM_DEBUG(dbgs() << format("  | %08lld: ", Offset) << Msg << "\n");
 }
 
 void wasm::writeUleb128(raw_ostream &OS, uint32_t Number, const Twine &Msg) {
@@ -70,7 +70,7 @@
 
 void wasm::writeU32(raw_ostream &OS, uint32_t Number, const Twine &Msg) {
   debugWrite(OS.tell(), Msg + "[0x" + utohexstr(Number) + "]");
-  support::endian::Writer<support::little>(OS).write(Number);
+  support::endian::write(OS, Number, support::little);
 }
 
 void wasm::writeValueType(raw_ostream &OS, uint8_t Type, const Twine &Msg) {