Merge 7ca8107c6 for LLVM update to 344140

Change-Id: I77eb0bfb34e9fff28f2d2dd7fa1c201484365a41
diff --git a/COFF/Chunks.cpp b/COFF/Chunks.cpp
index 412ff78..5fb33e1 100644
--- a/COFF/Chunks.cpp
+++ b/COFF/Chunks.cpp
@@ -44,6 +44,22 @@
   Live = !Config->DoGC || !isCOMDAT();
 }
 
+// Initialize the RelocTargets vector, to allow redirecting certain relocations
+// to a thunk instead of the actual symbol the relocation's symbol table index
+// indicates.
+void SectionChunk::readRelocTargets() {
+  assert(RelocTargets.empty());
+  RelocTargets.reserve(Relocs.size());
+  for (const coff_relocation &Rel : Relocs)
+    RelocTargets.push_back(File->getSymbol(Rel.SymbolTableIndex));
+}
+
+// Reset RelocTargets to their original targets before thunks were added.
+void SectionChunk::resetRelocTargets() {
+  for (size_t I = 0, E = Relocs.size(); I < E; ++I)
+    RelocTargets[I] = File->getSymbol(Relocs[I].SymbolTableIndex);
+}
+
 static void add16(uint8_t *P, int16_t V) { write16le(P, read16le(P) + V); }
 static void add32(uint8_t *P, int32_t V) { write32le(P, read32le(P) + V); }
 static void add64(uint8_t *P, int64_t V) { write64le(P, read64le(P) + V); }
@@ -58,7 +74,8 @@
     return true;
   if (Sec->isCodeView())
     return false;
-  fatal("SECREL relocation cannot be applied to absolute symbols");
+  error("SECREL relocation cannot be applied to absolute symbols");
+  return false;
 }
 
 static void applySecRel(const SectionChunk *Sec, uint8_t *Off,
@@ -98,7 +115,7 @@
   case IMAGE_REL_AMD64_SECTION:  applySecIdx(Off, OS); break;
   case IMAGE_REL_AMD64_SECREL:   applySecRel(this, Off, OS, S); break;
   default:
-    fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
+    error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
           toString(File));
   }
 }
@@ -113,7 +130,7 @@
   case IMAGE_REL_I386_SECTION:  applySecIdx(Off, OS); break;
   case IMAGE_REL_I386_SECREL:   applySecRel(this, Off, OS, S); break;
   default:
-    fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
+    error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
           toString(File));
   }
 }
@@ -123,16 +140,22 @@
   write16le(Off + 2, (read16le(Off + 2) & 0x8f00) | ((V & 0x700) << 4) | (V & 0xff));
 }
 
-static uint16_t readMOV(uint8_t *Off) {
+static uint16_t readMOV(uint8_t *Off, bool MOVT) {
   uint16_t Op1 = read16le(Off);
+  if ((Op1 & 0xfbf0) != (MOVT ? 0xf2c0 : 0xf240))
+    error("unexpected instruction in " + Twine(MOVT ? "MOVT" : "MOVW") +
+          " instruction in MOV32T relocation");
   uint16_t Op2 = read16le(Off + 2);
+  if ((Op2 & 0x8000) != 0)
+    error("unexpected instruction in " + Twine(MOVT ? "MOVT" : "MOVW") +
+          " instruction in MOV32T relocation");
   return (Op2 & 0x00ff) | ((Op2 >> 4) & 0x0700) | ((Op1 << 1) & 0x0800) |
          ((Op1 & 0x000f) << 12);
 }
 
 void applyMOV32T(uint8_t *Off, uint32_t V) {
-  uint16_t ImmW = readMOV(Off);     // read MOVW operand
-  uint16_t ImmT = readMOV(Off + 4); // read MOVT operand
+  uint16_t ImmW = readMOV(Off, false);    // read MOVW operand
+  uint16_t ImmT = readMOV(Off + 4, true); // read MOVT operand
   uint32_t Imm = ImmW | (ImmT << 16);
   V += Imm;                         // add the immediate offset
   applyMOV(Off, V);           // set MOVW operand
@@ -141,7 +164,7 @@
 
 static void applyBranch20T(uint8_t *Off, int32_t V) {
   if (!isInt<21>(V))
-    fatal("relocation out of range");
+    error("relocation out of range");
   uint32_t S = V < 0 ? 1 : 0;
   uint32_t J1 = (V >> 19) & 1;
   uint32_t J2 = (V >> 18) & 1;
@@ -151,7 +174,7 @@
 
 void applyBranch24T(uint8_t *Off, int32_t V) {
   if (!isInt<25>(V))
-    fatal("relocation out of range");
+    error("relocation out of range");
   uint32_t S = V < 0 ? 1 : 0;
   uint32_t J1 = ((~V >> 23) & 1) ^ S;
   uint32_t J2 = ((~V >> 22) & 1) ^ S;
@@ -176,7 +199,7 @@
   case IMAGE_REL_ARM_SECTION:   applySecIdx(Off, OS); break;
   case IMAGE_REL_ARM_SECREL:    applySecRel(this, Off, OS, S); break;
   default:
-    fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
+    error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
           toString(File));
   }
 }
@@ -184,7 +207,7 @@
 // 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, int Shift) {
+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;
@@ -198,7 +221,7 @@
 // Update the immediate field in a AARCH64 ldr, str, and add instruction.
 // Optionally limit the range of the written immediate by one or more bits
 // (RangeLimit).
-static void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit) {
+void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit) {
   uint32_t Orig = read32le(Off);
   Imm += (Orig >> 10) & 0xFFF;
   Orig &= ~(0xFFF << 10);
@@ -221,7 +244,7 @@
   if ((Orig & 0x4800000) == 0x4800000)
     Size += 4;
   if ((Imm & ((1 << Size) - 1)) != 0)
-    fatal("misaligned ldr/str offset");
+    error("misaligned ldr/str offset");
   applyArm64Imm(Off, Imm >> Size, Size);
 }
 
@@ -250,21 +273,21 @@
     applyArm64Ldr(Off, (S - OS->getRVA()) & 0xfff);
 }
 
-static void applyArm64Branch26(uint8_t *Off, int64_t V) {
+void applyArm64Branch26(uint8_t *Off, int64_t V) {
   if (!isInt<28>(V))
-    fatal("relocation out of range");
+    error("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");
+    error("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");
+    error("relocation out of range");
   or32(Off, (V & 0x0000FFFC) << 3);
 }
 
@@ -287,7 +310,7 @@
   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) + " in " +
+    error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
           toString(File));
   }
 }
@@ -302,21 +325,23 @@
 
   // Apply relocations.
   size_t InputSize = getSize();
-  for (const coff_relocation &Rel : Relocs) {
+  for (size_t I = 0, E = Relocs.size(); I < E; I++) {
+    const coff_relocation &Rel = Relocs[I];
+
     // Check for an invalid relocation offset. This check isn't perfect, because
     // we don't have the relocation size, which is only known after checking the
     // machine and relocation type. As a result, a relocation may overwrite the
     // beginning of the following input section.
-    if (Rel.VirtualAddress >= InputSize)
-      fatal("relocation points beyond the end of its parent section");
+    if (Rel.VirtualAddress >= InputSize) {
+      error("relocation points beyond the end of its parent section");
+      continue;
+    }
 
     uint8_t *Off = Buf + OutputSectionOff + Rel.VirtualAddress;
 
-    // Get the output section of the symbol for this relocation.  The output
-    // section is needed to compute SECREL and SECTION relocations used in debug
-    // info.
-    auto *Sym =
-        dyn_cast_or_null<Defined>(File->getSymbol(Rel.SymbolTableIndex));
+    // Use the potentially remapped Symbol instead of the one that the
+    // relocation points to.
+    auto *Sym = dyn_cast_or_null<Defined>(RelocTargets[I]);
     if (!Sym) {
       if (isCodeView() || isDWARF())
         continue;
@@ -326,8 +351,17 @@
           check(File->getCOFFObj()->getSymbol(Rel.SymbolTableIndex));
       StringRef Name;
       File->getCOFFObj()->getSymbolName(Sym, Name);
-      fatal("relocation against symbol in discarded section: " + Name);
+
+      // MinGW mode object files (built by GCC) can have leftover sections
+      // with relocations against discarded comdat sections. Such sections
+      // are left as is, with relocations untouched.
+      if (!Config->MinGW)
+        error("relocation against symbol in discarded section: " + Name);
+      continue;
     }
+    // Get the output section of the symbol for this relocation.  The output
+    // section is needed to compute SECREL and SECTION relocations used in debug
+    // info.
     Chunk *C = Sym->getChunk();
     OutputSection *OS = C ? C->getOutputSection() : nullptr;
 
@@ -339,8 +373,9 @@
     if (!OS && !isa<DefinedAbsolute>(Sym) && !isa<DefinedSynthetic>(Sym)) {
       if (isCodeView() || isDWARF())
         continue;
-      fatal("relocation against symbol in discarded section: " +
+      error("relocation against symbol in discarded section: " +
             Sym->getName());
+      continue;
     }
     uint64_t S = Sym->getRVA();
 
@@ -399,17 +434,125 @@
 // fixed by the loader if load-time relocation is needed.
 // Only called when base relocation is enabled.
 void SectionChunk::getBaserels(std::vector<Baserel> *Res) {
-  for (const coff_relocation &Rel : Relocs) {
+  for (size_t I = 0, E = Relocs.size(); I < E; I++) {
+    const coff_relocation &Rel = Relocs[I];
     uint8_t Ty = getBaserelType(Rel);
     if (Ty == IMAGE_REL_BASED_ABSOLUTE)
       continue;
-    Symbol *Target = File->getSymbol(Rel.SymbolTableIndex);
+    // Use the potentially remapped Symbol instead of the one that the
+    // relocation points to.
+    Symbol *Target = RelocTargets[I];
     if (!Target || isa<DefinedAbsolute>(Target))
       continue;
     Res->emplace_back(RVA + Rel.VirtualAddress, Ty);
   }
 }
 
+// MinGW specific.
+// Check whether a static relocation of type Type can be deferred and
+// handled at runtime as a pseudo relocation (for references to a module
+// local variable, which turned out to actually need to be imported from
+// another DLL) This returns the size the relocation is supposed to update,
+// in bits, or 0 if the relocation cannot be handled as a runtime pseudo
+// relocation.
+static int getRuntimePseudoRelocSize(uint16_t Type) {
+  // Relocations that either contain an absolute address, or a plain
+  // relative offset, since the runtime pseudo reloc implementation
+  // adds 8/16/32/64 bit values to a memory address.
+  //
+  // Given a pseudo relocation entry,
+  //
+  // typedef struct {
+  //   DWORD sym;
+  //   DWORD target;
+  //   DWORD flags;
+  // } runtime_pseudo_reloc_item_v2;
+  //
+  // the runtime relocation performs this adjustment:
+  //     *(base + .target) += *(base + .sym) - (base + .sym)
+  //
+  // This works for both absolute addresses (IMAGE_REL_*_ADDR32/64,
+  // IMAGE_REL_I386_DIR32, where the memory location initially contains
+  // the address of the IAT slot, and for relative addresses (IMAGE_REL*_REL32),
+  // where the memory location originally contains the relative offset to the
+  // IAT slot.
+  //
+  // This requires the target address to be writable, either directly out of
+  // the image, or temporarily changed at runtime with VirtualProtect.
+  // Since this only operates on direct address values, it doesn't work for
+  // ARM/ARM64 relocations, other than the plain ADDR32/ADDR64 relocations.
+  switch (Config->Machine) {
+  case AMD64:
+    switch (Type) {
+    case IMAGE_REL_AMD64_ADDR64:
+      return 64;
+    case IMAGE_REL_AMD64_ADDR32:
+    case IMAGE_REL_AMD64_REL32:
+    case IMAGE_REL_AMD64_REL32_1:
+    case IMAGE_REL_AMD64_REL32_2:
+    case IMAGE_REL_AMD64_REL32_3:
+    case IMAGE_REL_AMD64_REL32_4:
+    case IMAGE_REL_AMD64_REL32_5:
+      return 32;
+    default:
+      return 0;
+    }
+  case I386:
+    switch (Type) {
+    case IMAGE_REL_I386_DIR32:
+    case IMAGE_REL_I386_REL32:
+      return 32;
+    default:
+      return 0;
+    }
+  case ARMNT:
+    switch (Type) {
+    case IMAGE_REL_ARM_ADDR32:
+      return 32;
+    default:
+      return 0;
+    }
+  case ARM64:
+    switch (Type) {
+    case IMAGE_REL_ARM64_ADDR64:
+      return 64;
+    case IMAGE_REL_ARM64_ADDR32:
+      return 32;
+    default:
+      return 0;
+    }
+  default:
+    llvm_unreachable("unknown machine type");
+  }
+}
+
+// MinGW specific.
+// Append information to the provided vector about all relocations that
+// need to be handled at runtime as runtime pseudo relocations (references
+// to a module local variable, which turned out to actually need to be
+// imported from another DLL).
+void SectionChunk::getRuntimePseudoRelocs(
+    std::vector<RuntimePseudoReloc> &Res) {
+  for (const coff_relocation &Rel : Relocs) {
+    auto *Target =
+        dyn_cast_or_null<Defined>(File->getSymbol(Rel.SymbolTableIndex));
+    if (!Target || !Target->IsRuntimePseudoReloc)
+      continue;
+    int SizeInBits = getRuntimePseudoRelocSize(Rel.Type);
+    if (SizeInBits == 0) {
+      error("unable to automatically import from " + Target->getName() +
+            " with relocation type " +
+            File->getCOFFObj()->getRelocationTypeName(Rel.Type) + " in " +
+            toString(File));
+      continue;
+    }
+    // SizeInBits is used to initialize the Flags field; currently no
+    // other flags are defined.
+    Res.emplace_back(
+        RuntimePseudoReloc(Target, this, Rel.VirtualAddress, SizeInBits));
+  }
+}
+
 bool SectionChunk::hasData() const {
   return !(Header->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA);
 }
@@ -447,6 +590,13 @@
   Other->Live = false;
 }
 
+uint32_t SectionChunk::getSectionNumber() const {
+  DataRefImpl R;
+  R.p = reinterpret_cast<uintptr_t>(Header);
+  SectionRef S(R, File->getCOFFObj());
+  return S.getIndex() + 1;
+}
+
 CommonChunk::CommonChunk(const COFFSymbolRef S) : Sym(S) {
   // Common symbols are aligned on natural boundaries up to 32 bytes.
   // This is what MSVC link.exe does.
@@ -502,6 +652,25 @@
   applyArm64Ldr(Buf + OutputSectionOff + 4, Off);
 }
 
+// A Thumb2, PIC, non-interworking range extension thunk.
+const uint8_t ArmThunk[] = {
+    0x40, 0xf2, 0x00, 0x0c, // P:  movw ip,:lower16:S - (P + (L1-P) + 4)
+    0xc0, 0xf2, 0x00, 0x0c, //     movt ip,:upper16:S - (P + (L1-P) + 4)
+    0xe7, 0x44,             // L1: add  pc, ip
+};
+
+size_t RangeExtensionThunk::getSize() const {
+  assert(Config->Machine == ARMNT);
+  return sizeof(ArmThunk);
+}
+
+void RangeExtensionThunk::writeTo(uint8_t *Buf) const {
+  assert(Config->Machine == ARMNT);
+  uint64_t Offset = Target->getRVA() - RVA - 12;
+  memcpy(Buf + OutputSectionOff, ArmThunk, sizeof(ArmThunk));
+  applyMOV32T(Buf + OutputSectionOff, uint32_t(Offset));
+}
+
 void LocalImportChunk::getBaserels(std::vector<Baserel> *Res) {
   Res->emplace_back(getRVA());
 }
@@ -528,6 +697,34 @@
          "RVA tables should be de-duplicated");
 }
 
+// MinGW specific, for the "automatic import of variables from DLLs" feature.
+size_t PseudoRelocTableChunk::getSize() const {
+  if (Relocs.empty())
+    return 0;
+  return 12 + 12 * Relocs.size();
+}
+
+// MinGW specific.
+void PseudoRelocTableChunk::writeTo(uint8_t *Buf) const {
+  if (Relocs.empty())
+    return;
+
+  ulittle32_t *Table = reinterpret_cast<ulittle32_t *>(Buf + OutputSectionOff);
+  // This is the list header, to signal the runtime pseudo relocation v2
+  // format.
+  Table[0] = 0;
+  Table[1] = 0;
+  Table[2] = 1;
+
+  size_t Idx = 3;
+  for (const RuntimePseudoReloc &RPR : Relocs) {
+    Table[Idx + 0] = RPR.Sym->getRVA();
+    Table[Idx + 1] = RPR.Target->getRVA() + RPR.TargetOffset;
+    Table[Idx + 2] = RPR.Flags;
+    Idx += 3;
+  }
+}
+
 // Windows-specific. This class represents a block in .reloc section.
 // The format is described here.
 //
@@ -613,13 +810,16 @@
 }
 
 void MergeChunk::finalizeContents() {
-  for (SectionChunk *C : Sections)
-    if (C->isLive())
-      Builder.add(toStringRef(C->getContents()));
-  Builder.finalize();
+  if (!Finalized) {
+    for (SectionChunk *C : Sections)
+      if (C->Live)
+        Builder.add(toStringRef(C->getContents()));
+    Builder.finalize();
+    Finalized = true;
+  }
 
   for (SectionChunk *C : Sections) {
-    if (!C->isLive())
+    if (!C->Live)
       continue;
     size_t Off = Builder.getOffset(toStringRef(C->getContents()));
     C->setOutputSection(Out);
@@ -640,5 +840,18 @@
   Builder.write(Buf + OutputSectionOff);
 }
 
+// MinGW specific.
+size_t AbsolutePointerChunk::getSize() const {
+  return Config->is64() ? 8 : 4;
+}
+
+void AbsolutePointerChunk::writeTo(uint8_t *Buf) const {
+  if (Config->is64()) {
+    write64le(Buf + OutputSectionOff, Value);
+  } else {
+    write32le(Buf + OutputSectionOff, Value);
+  }
+}
+
 } // namespace coff
 } // namespace lld
diff --git a/COFF/Chunks.h b/COFF/Chunks.h
index 9e89653..bdfff7c 100644
--- a/COFF/Chunks.h
+++ b/COFF/Chunks.h
@@ -36,6 +36,7 @@
 class DefinedRegular;
 class ObjFile;
 class OutputSection;
+class RuntimePseudoReloc;
 class Symbol;
 
 // Mask for permissions (discardable, writable, readable, executable, etc).
@@ -63,6 +64,13 @@
   // before calling this function.
   virtual void writeTo(uint8_t *Buf) const {}
 
+  // Called by the writer once before assigning addresses and writing
+  // the output.
+  virtual void readRelocTargets() {}
+
+  // Called if restarting thunk addition.
+  virtual void resetRelocTargets() {}
+
   // Called by the writer after an RVA is assigned, but before calling
   // getSize().
   virtual void finalizeContents() {}
@@ -114,6 +122,10 @@
 public:
   // The offset from beginning of the output section. The writer sets a value.
   uint64_t OutputSectionOff = 0;
+
+  // Whether this section needs to be kept distinct from other sections during
+  // ICF. This is set by the driver using address-significance tables.
+  bool KeepUnique = false;
 };
 
 // A chunk corresponding a section of an input file.
@@ -140,6 +152,8 @@
 
   SectionChunk(ObjFile *File, const coff_section *Header);
   static bool classof(const Chunk *C) { return C->kind() == SectionKind; }
+  void readRelocTargets() override;
+  void resetRelocTargets() override;
   size_t getSize() const override { return Header->SizeOfRawData; }
   ArrayRef<uint8_t> getContents() const;
   void writeTo(uint8_t *Buf) const override;
@@ -157,6 +171,8 @@
   void applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S,
                      uint64_t P) const;
 
+  void getRuntimePseudoRelocs(std::vector<RuntimePseudoReloc> &Res);
+
   // Called if the garbage collector decides to not include this chunk
   // in a final output. It's supposed to print out a log message to stdout.
   void printDiscardedMessage() const;
@@ -167,16 +183,6 @@
 
   StringRef getDebugName() override;
 
-  // Returns true if the chunk was not dropped by GC.
-  bool isLive() { return Live; }
-
-  // Used by the garbage collector.
-  void markLive() {
-    assert(Config->DoGC && "should only mark things live from GC");
-    assert(!isLive() && "Cannot mark an already live section!");
-    Live = true;
-  }
-
   // True if this is a codeview debug info chunk. These will not be laid out in
   // the image. Instead they will end up in the PDB, if one is requested.
   bool isCodeView() const {
@@ -197,10 +203,13 @@
   // Allow iteration over the associated child chunks for this section.
   ArrayRef<SectionChunk *> children() const { return AssocChildren; }
 
+  // The section ID this chunk belongs to in its Obj.
+  uint32_t getSectionNumber() const;
+
   // A pointer pointing to a replacement for this chunk.
   // Initially it points to "this" object. If this chunk is merged
   // with other chunk by ICF, it points to another chunk,
-  // and this chunk is considrered as dead.
+  // and this chunk is considered as dead.
   SectionChunk *Repl;
 
   // The CRC of the contents as described in the COFF spec 4.5.5.
@@ -217,13 +226,17 @@
 
   ArrayRef<coff_relocation> Relocs;
 
+  // Used by the garbage collector.
+  bool Live;
+
+  // When inserting a thunk, we need to adjust a relocation to point to
+  // the thunk instead of the actual original target Symbol.
+  std::vector<Symbol *> RelocTargets;
+
 private:
   StringRef SectionName;
   std::vector<SectionChunk *> AssocChildren;
 
-  // Used by the garbage collector.
-  bool Live;
-
   // Used for ICF (Identical COMDAT Folding)
   void replace(SectionChunk *Other);
   uint32_t Class[2] = {0, 0};
@@ -254,6 +267,7 @@
 
 private:
   llvm::StringTableBuilder Builder;
+  bool Finalized = false;
 };
 
 // A chunk for common symbols. Common chunks don't have actual data.
@@ -341,6 +355,15 @@
   Defined *ImpSymbol;
 };
 
+class RangeExtensionThunk : public Chunk {
+public:
+  explicit RangeExtensionThunk(Defined *T) : Target(T) {}
+  size_t getSize() const override;
+  void writeTo(uint8_t *Buf) const override;
+
+  Defined *Target;
+};
+
 // Windows-specific.
 // See comments for DefinedLocalImport class.
 class LocalImportChunk : public Chunk {
@@ -414,9 +437,73 @@
   uint8_t Type;
 };
 
+// This is a placeholder Chunk, to allow attaching a DefinedSynthetic to a
+// specific place in a section, without any data. This is used for the MinGW
+// specific symbol __RUNTIME_PSEUDO_RELOC_LIST_END__, even though the concept
+// of an empty chunk isn't MinGW specific.
+class EmptyChunk : public Chunk {
+public:
+  EmptyChunk() {}
+  size_t getSize() const override { return 0; }
+  void writeTo(uint8_t *Buf) const override {}
+};
+
+// MinGW specific, for the "automatic import of variables from DLLs" feature.
+// This provides the table of runtime pseudo relocations, for variable
+// references that turned out to need to be imported from a DLL even though
+// the reference didn't use the dllimport attribute. The MinGW runtime will
+// process this table after loading, before handling control over to user
+// code.
+class PseudoRelocTableChunk : public Chunk {
+public:
+  PseudoRelocTableChunk(std::vector<RuntimePseudoReloc> &Relocs)
+      : Relocs(std::move(Relocs)) {
+    Alignment = 4;
+  }
+  size_t getSize() const override;
+  void writeTo(uint8_t *Buf) const override;
+
+private:
+  std::vector<RuntimePseudoReloc> Relocs;
+};
+
+// MinGW specific; information about one individual location in the image
+// that needs to be fixed up at runtime after loading. This represents
+// one individual element in the PseudoRelocTableChunk table.
+class RuntimePseudoReloc {
+public:
+  RuntimePseudoReloc(Defined *Sym, SectionChunk *Target, uint32_t TargetOffset,
+                     int Flags)
+      : Sym(Sym), Target(Target), TargetOffset(TargetOffset), Flags(Flags) {}
+
+  Defined *Sym;
+  SectionChunk *Target;
+  uint32_t TargetOffset;
+  // The Flags field contains the size of the relocation, in bits. No other
+  // flags are currently defined.
+  int Flags;
+};
+
+// MinGW specific. A Chunk that contains one pointer-sized absolute value.
+class AbsolutePointerChunk : public Chunk {
+public:
+  AbsolutePointerChunk(uint64_t Value) : Value(Value) {
+    Alignment = getSize();
+  }
+  size_t getSize() const override;
+  void writeTo(uint8_t *Buf) const override;
+
+private:
+  uint64_t Value;
+};
+
 void applyMOV32T(uint8_t *Off, uint32_t V);
 void applyBranch24T(uint8_t *Off, int32_t V);
 
+void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P, int Shift);
+void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit);
+void applyArm64Branch26(uint8_t *Off, int64_t V);
+
 } // namespace coff
 } // namespace lld
 
diff --git a/COFF/Config.h b/COFF/Config.h
index 3ae50b8..e639b77 100644
--- a/COFF/Config.h
+++ b/COFF/Config.h
@@ -94,7 +94,8 @@
   bool DoICF = true;
   bool TailMerge;
   bool Relocatable = true;
-  bool Force = false;
+  bool ForceMultiple = false;
+  bool ForceUnresolved = false;
   bool Debug = false;
   bool DebugDwarf = false;
   bool DebugGHashes = false;
diff --git a/COFF/DLL.cpp b/COFF/DLL.cpp
index 464abe8..093eaa5 100644
--- a/COFF/DLL.cpp
+++ b/COFF/DLL.cpp
@@ -230,6 +230,36 @@
     0x60, 0x47,             // bx      ip
 };
 
+static const uint8_t ThunkARM64[] = {
+    0x11, 0x00, 0x00, 0x90, // adrp    x17, #0      __imp_<FUNCNAME>
+    0x31, 0x02, 0x00, 0x91, // add     x17, x17, #0 :lo12:__imp_<FUNCNAME>
+    0xfd, 0x7b, 0xb3, 0xa9, // stp     x29, x30, [sp, #-208]!
+    0xfd, 0x03, 0x00, 0x91, // mov     x29, sp
+    0xe0, 0x07, 0x01, 0xa9, // stp     x0, x1, [sp, #16]
+    0xe2, 0x0f, 0x02, 0xa9, // stp     x2, x3, [sp, #32]
+    0xe4, 0x17, 0x03, 0xa9, // stp     x4, x5, [sp, #48]
+    0xe6, 0x1f, 0x04, 0xa9, // stp     x6, x7, [sp, #64]
+    0xe0, 0x87, 0x02, 0xad, // stp     q0, q1, [sp, #80]
+    0xe2, 0x8f, 0x03, 0xad, // stp     q2, q3, [sp, #112]
+    0xe4, 0x97, 0x04, 0xad, // stp     q4, q5, [sp, #144]
+    0xe6, 0x9f, 0x05, 0xad, // stp     q6, q7, [sp, #176]
+    0xe1, 0x03, 0x11, 0xaa, // mov     x1, x17
+    0x00, 0x00, 0x00, 0x90, // adrp    x0, #0     DELAY_IMPORT_DESCRIPTOR
+    0x00, 0x00, 0x00, 0x91, // add     x0, x0, #0 :lo12:DELAY_IMPORT_DESCRIPTOR
+    0x00, 0x00, 0x00, 0x94, // bl      #0 __delayLoadHelper2
+    0xf0, 0x03, 0x00, 0xaa, // mov     x16, x0
+    0xe6, 0x9f, 0x45, 0xad, // ldp     q6, q7, [sp, #176]
+    0xe4, 0x97, 0x44, 0xad, // ldp     q4, q5, [sp, #144]
+    0xe2, 0x8f, 0x43, 0xad, // ldp     q2, q3, [sp, #112]
+    0xe0, 0x87, 0x42, 0xad, // ldp     q0, q1, [sp, #80]
+    0xe6, 0x1f, 0x44, 0xa9, // ldp     x6, x7, [sp, #64]
+    0xe4, 0x17, 0x43, 0xa9, // ldp     x4, x5, [sp, #48]
+    0xe2, 0x0f, 0x42, 0xa9, // ldp     x2, x3, [sp, #32]
+    0xe0, 0x07, 0x41, 0xa9, // ldp     x0, x1, [sp, #16]
+    0xfd, 0x7b, 0xcd, 0xa8, // ldp     x29, x30, [sp], #208
+    0x00, 0x02, 0x1f, 0xd6, // br      x16
+};
+
 // A chunk for the delay import thunk.
 class ThunkChunkX64 : public Chunk {
 public:
@@ -298,6 +328,28 @@
   Defined *Helper = nullptr;
 };
 
+class ThunkChunkARM64 : public Chunk {
+public:
+  ThunkChunkARM64(Defined *I, Chunk *D, Defined *H)
+      : Imp(I), Desc(D), Helper(H) {}
+
+  size_t getSize() const override { return sizeof(ThunkARM64); }
+
+  void writeTo(uint8_t *Buf) const override {
+    memcpy(Buf + OutputSectionOff, ThunkARM64, sizeof(ThunkARM64));
+    applyArm64Addr(Buf + OutputSectionOff + 0, Imp->getRVA(), RVA + 0, 12);
+    applyArm64Imm(Buf + OutputSectionOff + 4, Imp->getRVA() & 0xfff, 0);
+    applyArm64Addr(Buf + OutputSectionOff + 52, Desc->getRVA(), RVA + 52, 12);
+    applyArm64Imm(Buf + OutputSectionOff + 56, Desc->getRVA() & 0xfff, 0);
+    applyArm64Branch26(Buf + OutputSectionOff + 60,
+                       Helper->getRVA() - RVA - 60);
+  }
+
+  Defined *Imp = nullptr;
+  Chunk *Desc = nullptr;
+  Defined *Helper = nullptr;
+};
+
 // A chunk for the import descriptor table.
 class DelayAddressChunk : public Chunk {
 public:
@@ -418,30 +470,6 @@
 
 } // anonymous namespace
 
-uint64_t IdataContents::getDirSize() {
-  return Dirs.size() * sizeof(ImportDirectoryTableEntry);
-}
-
-uint64_t IdataContents::getIATSize() {
-  return Addresses.size() * ptrSize();
-}
-
-// Returns a list of .idata contents.
-// See Microsoft PE/COFF spec 5.4 for details.
-std::vector<Chunk *> IdataContents::getChunks() {
-  create();
-
-  // The loader assumes a specific order of data.
-  // Add each type in the correct order.
-  std::vector<Chunk *> V;
-  V.insert(V.end(), Dirs.begin(), Dirs.end());
-  V.insert(V.end(), Lookups.begin(), Lookups.end());
-  V.insert(V.end(), Addresses.begin(), Addresses.end());
-  V.insert(V.end(), Hints.begin(), Hints.end());
-  V.insert(V.end(), DLLNames.begin(), DLLNames.end());
-  return V;
-}
-
 void IdataContents::create() {
   std::vector<std::vector<DefinedImportData *>> V = binImports(Imports);
 
@@ -555,6 +583,8 @@
     return make<ThunkChunkX86>(S, Dir, Helper);
   case ARMNT:
     return make<ThunkChunkARM>(S, Dir, Helper);
+  case ARM64:
+    return make<ThunkChunkARM64>(S, Dir, Helper);
   default:
     llvm_unreachable("unsupported machine type");
   }
diff --git a/COFF/DLL.h b/COFF/DLL.h
index c5d6e7c..a298271 100644
--- a/COFF/DLL.h
+++ b/COFF/DLL.h
@@ -19,19 +19,12 @@
 // Windows-specific.
 // IdataContents creates all chunks for the DLL import table.
 // You are supposed to call add() to add symbols and then
-// call getChunks() to get a list of chunks.
+// call create() to populate the chunk vectors.
 class IdataContents {
 public:
   void add(DefinedImportData *Sym) { Imports.push_back(Sym); }
   bool empty() { return Imports.empty(); }
-  std::vector<Chunk *> getChunks();
 
-  uint64_t getDirRVA() { return Dirs[0]->getRVA(); }
-  uint64_t getDirSize();
-  uint64_t getIATRVA() { return Addresses[0]->getRVA(); }
-  uint64_t getIATSize();
-
-private:
   void create();
 
   std::vector<DefinedImportData *> Imports;
diff --git a/COFF/Driver.cpp b/COFF/Driver.cpp
index c21f0b4..ce6d4ac 100644
--- a/COFF/Driver.cpp
+++ b/COFF/Driver.cpp
@@ -32,6 +32,7 @@
 #include "llvm/Option/ArgList.h"
 #include "llvm/Option/Option.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/LEB128.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Process.h"
 #include "llvm/Support/TarWriter.h"
@@ -56,7 +57,7 @@
 LinkerDriver *Driver;
 
 bool link(ArrayRef<const char *> Args, bool CanExitEarly, raw_ostream &Diag) {
-  errorHandler().LogName = sys::path::filename(Args[0]);
+  errorHandler().LogName = args::getFilenameWithoutExe(Args[0]);
   errorHandler().ErrorOS = &Diag;
   errorHandler().ColorDiagnostics = Diag.has_colors();
   errorHandler().ErrorLimitExceededMsg =
@@ -370,13 +371,30 @@
   return Path;
 }
 
+// MinGW specific. If an embedded directive specified to link to
+// foo.lib, but it isn't found, try libfoo.a instead.
+StringRef LinkerDriver::doFindLibMinGW(StringRef Filename) {
+  if (Filename.contains('/') || Filename.contains('\\'))
+    return Filename;
+
+  SmallString<128> S = Filename;
+  sys::path::replace_extension(S, ".a");
+  StringRef LibName = Saver.save("lib" + S.str());
+  return doFindFile(LibName);
+}
+
 // Find library file from search path.
 StringRef LinkerDriver::doFindLib(StringRef Filename) {
   // Add ".lib" to Filename if that has no file extension.
   bool HasExt = Filename.contains('.');
   if (!HasExt)
     Filename = Saver.save(Filename + ".lib");
-  return doFindFile(Filename);
+  StringRef Ret = doFindFile(Filename);
+  // For MinGW, if the find above didn't turn up anything, try
+  // looking for a MinGW formatted library name.
+  if (Config->MinGW && Ret == Filename)
+    return doFindLibMinGW(Filename);
+  return Ret;
 }
 
 // Resolves a library path. /nodefaultlib options are taken into
@@ -429,29 +447,48 @@
   assert(Config->Subsystem != IMAGE_SUBSYSTEM_UNKNOWN &&
          "must handle /subsystem before calling this");
 
-  // As a special case, if /nodefaultlib is given, we directly look for an
-  // entry point. This is because, if no default library is linked, users
-  // need to define an entry point instead of a "main".
-  bool FindMain = !Config->NoDefaultLibAll;
+  if (Config->MinGW)
+    return mangle(Config->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI
+                      ? "WinMainCRTStartup"
+                      : "mainCRTStartup");
+
   if (Config->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) {
-    if (findUnderscoreMangle(FindMain ? "WinMain" : "WinMainCRTStartup"))
-      return mangle("WinMainCRTStartup");
-    if (findUnderscoreMangle(FindMain ? "wWinMain" : "wWinMainCRTStartup"))
-      return mangle("wWinMainCRTStartup");
+    if (findUnderscoreMangle("wWinMain")) {
+      if (!findUnderscoreMangle("WinMain"))
+        return mangle("wWinMainCRTStartup");
+      warn("found both wWinMain and WinMain; using latter");
+    }
+    return mangle("WinMainCRTStartup");
   }
-  if (findUnderscoreMangle(FindMain ? "main" : "mainCRTStartup"))
-    return mangle("mainCRTStartup");
-  if (findUnderscoreMangle(FindMain ? "wmain" : "wmainCRTStartup"))
-    return mangle("wmainCRTStartup");
-  return "";
+  if (findUnderscoreMangle("wmain")) {
+    if (!findUnderscoreMangle("main"))
+      return mangle("wmainCRTStartup");
+    warn("found both wmain and main; using latter");
+  }
+  return mangle("mainCRTStartup");
 }
 
 WindowsSubsystem LinkerDriver::inferSubsystem() {
   if (Config->DLL)
     return IMAGE_SUBSYSTEM_WINDOWS_GUI;
-  if (findUnderscoreMangle("main") || findUnderscoreMangle("wmain"))
+  if (Config->MinGW)
     return IMAGE_SUBSYSTEM_WINDOWS_CUI;
-  if (findUnderscoreMangle("WinMain") || findUnderscoreMangle("wWinMain"))
+  // Note that link.exe infers the subsystem from the presence of these
+  // functions even if /entry: or /nodefaultlib are passed which causes them
+  // to not be called.
+  bool HaveMain = findUnderscoreMangle("main");
+  bool HaveWMain = findUnderscoreMangle("wmain");
+  bool HaveWinMain = findUnderscoreMangle("WinMain");
+  bool HaveWWinMain = findUnderscoreMangle("wWinMain");
+  if (HaveMain || HaveWMain) {
+    if (HaveWinMain || HaveWWinMain) {
+      warn(std::string("found ") + (HaveMain ? "main" : "wmain") + " and " +
+           (HaveWinMain ? "WinMain" : "wWinMain") +
+           "; defaulting to /subsystem:console");
+    }
+    return IMAGE_SUBSYSTEM_WINDOWS_CUI;
+  }
+  if (HaveWinMain || HaveWWinMain)
     return IMAGE_SUBSYSTEM_WINDOWS_GUI;
   return IMAGE_SUBSYSTEM_UNKNOWN;
 }
@@ -497,26 +534,65 @@
   return Data.str();
 }
 
-static unsigned getDefaultDebugType(const opt::InputArgList &Args) {
-  unsigned DebugTypes = static_cast<unsigned>(DebugType::CV);
+enum class DebugKind { Unknown, None, Full, FastLink, GHash, Dwarf, Symtab };
+
+static DebugKind parseDebugKind(const opt::InputArgList &Args) {
+  auto *A = Args.getLastArg(OPT_debug, OPT_debug_opt);
+  if (!A)
+    return DebugKind::None;
+  if (A->getNumValues() == 0)
+    return DebugKind::Full;
+
+  DebugKind Debug = StringSwitch<DebugKind>(A->getValue())
+                     .CaseLower("none", DebugKind::None)
+                     .CaseLower("full", DebugKind::Full)
+                     .CaseLower("fastlink", DebugKind::FastLink)
+                     // LLD extensions
+                     .CaseLower("ghash", DebugKind::GHash)
+                     .CaseLower("dwarf", DebugKind::Dwarf)
+                     .CaseLower("symtab", DebugKind::Symtab)
+                     .Default(DebugKind::Unknown);
+
+  if (Debug == DebugKind::FastLink) {
+    warn("/debug:fastlink unsupported; using /debug:full");
+    return DebugKind::Full;
+  }
+  if (Debug == DebugKind::Unknown) {
+    error("/debug: unknown option: " + Twine(A->getValue()));
+    return DebugKind::None;
+  }
+  return Debug;
+}
+
+static unsigned parseDebugTypes(const opt::InputArgList &Args) {
+  unsigned DebugTypes = static_cast<unsigned>(DebugType::None);
+
+  if (auto *A = Args.getLastArg(OPT_debugtype)) {
+    SmallVector<StringRef, 3> Types;
+    A->getSpelling().split(Types, ',', /*KeepEmpty=*/false);
+
+    for (StringRef Type : Types) {
+      unsigned V = StringSwitch<unsigned>(Type.lower())
+                       .Case("cv", static_cast<unsigned>(DebugType::CV))
+                       .Case("pdata", static_cast<unsigned>(DebugType::PData))
+                       .Case("fixup", static_cast<unsigned>(DebugType::Fixup))
+                       .Default(0);
+      if (V == 0) {
+        warn("/debugtype: unknown option: " + Twine(A->getValue()));
+        continue;
+      }
+      DebugTypes |= V;
+    }
+    return DebugTypes;
+  }
+
+  // Default debug types
+  DebugTypes = static_cast<unsigned>(DebugType::CV);
   if (Args.hasArg(OPT_driver))
     DebugTypes |= static_cast<unsigned>(DebugType::PData);
   if (Args.hasArg(OPT_profile))
     DebugTypes |= static_cast<unsigned>(DebugType::Fixup);
-  return DebugTypes;
-}
 
-static unsigned parseDebugType(StringRef Arg) {
-  SmallVector<StringRef, 3> Types;
-  Arg.split(Types, ',', /*KeepEmpty=*/false);
-
-  unsigned DebugTypes = static_cast<unsigned>(DebugType::None);
-  for (StringRef Type : Types)
-    DebugTypes |= StringSwitch<unsigned>(Type.lower())
-                      .Case("cv", static_cast<unsigned>(DebugType::CV))
-                      .Case("pdata", static_cast<unsigned>(DebugType::PData))
-                      .Case("fixup", static_cast<unsigned>(DebugType::Fixup))
-                      .Default(0);
   return DebugTypes;
 }
 
@@ -731,6 +807,97 @@
   }
 }
 
+static void markAddrsig(Symbol *S) {
+  if (auto *D = dyn_cast_or_null<Defined>(S))
+    if (Chunk *C = D->getChunk())
+      C->KeepUnique = true;
+}
+
+static void findKeepUniqueSections() {
+  // Exported symbols could be address-significant in other executables or DSOs,
+  // so we conservatively mark them as address-significant.
+  for (Export &R : Config->Exports)
+    markAddrsig(R.Sym);
+
+  // Visit the address-significance table in each object file and mark each
+  // referenced symbol as address-significant.
+  for (ObjFile *Obj : ObjFile::Instances) {
+    ArrayRef<Symbol *> Syms = Obj->getSymbols();
+    if (Obj->AddrsigSec) {
+      ArrayRef<uint8_t> Contents;
+      Obj->getCOFFObj()->getSectionContents(Obj->AddrsigSec, Contents);
+      const uint8_t *Cur = Contents.begin();
+      while (Cur != Contents.end()) {
+        unsigned Size;
+        const char *Err;
+        uint64_t SymIndex = decodeULEB128(Cur, &Size, Contents.end(), &Err);
+        if (Err)
+          fatal(toString(Obj) + ": could not decode addrsig section: " + Err);
+        if (SymIndex >= Syms.size())
+          fatal(toString(Obj) + ": invalid symbol index in addrsig section");
+        markAddrsig(Syms[SymIndex]);
+        Cur += Size;
+      }
+    } else {
+      // If an object file does not have an address-significance table,
+      // conservatively mark all of its symbols as address-significant.
+      for (Symbol *S : Syms)
+        markAddrsig(S);
+    }
+  }
+}
+
+// link.exe replaces each %foo% in AltPath with the contents of environment
+// variable foo, and adds the two magic env vars _PDB (expands to the basename
+// of pdb's output path) and _EXT (expands to the extension of the output
+// binary).
+// lld only supports %_PDB% and %_EXT% and warns on references to all other env
+// vars.
+static void parsePDBAltPath(StringRef AltPath) {
+  SmallString<128> Buf;
+  StringRef PDBBasename =
+      sys::path::filename(Config->PDBPath, sys::path::Style::windows);
+  StringRef BinaryExtension =
+      sys::path::extension(Config->OutputFile, sys::path::Style::windows);
+  if (!BinaryExtension.empty())
+    BinaryExtension = BinaryExtension.substr(1); // %_EXT% does not include '.'.
+
+  // Invariant:
+  //   +--------- Cursor ('a...' might be the empty string).
+  //   |   +----- FirstMark
+  //   |   |   +- SecondMark
+  //   v   v   v
+  //   a...%...%...
+  size_t Cursor = 0;
+  while (Cursor < AltPath.size()) {
+    size_t FirstMark, SecondMark;
+    if ((FirstMark = AltPath.find('%', Cursor)) == StringRef::npos ||
+        (SecondMark = AltPath.find('%', FirstMark + 1)) == StringRef::npos) {
+      // Didn't find another full fragment, treat rest of string as literal.
+      Buf.append(AltPath.substr(Cursor));
+      break;
+    }
+
+    // Found a full fragment. Append text in front of first %, and interpret
+    // text between first and second % as variable name.
+    Buf.append(AltPath.substr(Cursor, FirstMark - Cursor));
+    StringRef Var = AltPath.substr(FirstMark, SecondMark - FirstMark + 1);
+    if (Var.equals_lower("%_pdb%"))
+      Buf.append(PDBBasename);
+    else if (Var.equals_lower("%_ext%"))
+      Buf.append(BinaryExtension);
+    else {
+      warn("only %_PDB% and %_EXT% supported in /pdbaltpath:, keeping " +
+           Var + " as literal");
+      Buf.append(Var);
+    }
+
+    Cursor = SecondMark + 1;
+  }
+
+  Config->PDBAltPath = Buf;
+}
+
 void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
   // If the first command line argument is "/lib", link.exe acts like lib.exe.
   // We call our own implementation of lib.exe that understands bitcode files.
@@ -837,20 +1004,26 @@
 
   // Handle /force or /force:unresolved
   if (Args.hasArg(OPT_force, OPT_force_unresolved))
-    Config->Force = true;
+    Config->ForceUnresolved = true;
+
+  // Handle /force or /force:multiple
+  if (Args.hasArg(OPT_force, OPT_force_multiple))
+    Config->ForceMultiple = true;
 
   // Handle /debug
-  if (Args.hasArg(OPT_debug, OPT_debug_dwarf, OPT_debug_ghash)) {
+  DebugKind Debug = parseDebugKind(Args);
+  if (Debug == DebugKind::Full || Debug == DebugKind::Dwarf ||
+      Debug == DebugKind::GHash) {
     Config->Debug = true;
     Config->Incremental = true;
-    if (auto *Arg = Args.getLastArg(OPT_debugtype))
-      Config->DebugTypes = parseDebugType(Arg->getValue());
-    else
-      Config->DebugTypes = getDefaultDebugType(Args);
   }
 
+  // Handle /debugtype
+  Config->DebugTypes = parseDebugTypes(Args);
+
   // Handle /pdb
-  bool ShouldCreatePDB = Args.hasArg(OPT_debug, OPT_debug_ghash);
+  bool ShouldCreatePDB =
+      (Debug == DebugKind::Full || Debug == DebugKind::GHash);
   if (ShouldCreatePDB) {
     if (auto *Arg = Args.getLastArg(OPT_pdb))
       Config->PDBPath = Arg->getValue();
@@ -971,7 +1144,7 @@
     Config->Implib = Arg->getValue();
 
   // Handle /opt.
-  bool DoGC = !Args.hasArg(OPT_debug) || Args.hasArg(OPT_profile);
+  bool DoGC = Debug == DebugKind::None || Args.hasArg(OPT_profile);
   unsigned ICFLevel =
       Args.hasArg(OPT_profile) ? 0 : 1; // 0: off, 1: limited, 2: on
   unsigned TailMerge = 1;
@@ -1056,6 +1229,12 @@
   parseMerge(".xdata=.rdata");
   parseMerge(".bss=.data");
 
+  if (Config->MinGW) {
+    parseMerge(".ctors=.rdata");
+    parseMerge(".dtors=.rdata");
+    parseMerge(".CRT=.rdata");
+  }
+
   // Handle /section
   for (auto *Arg : Args.filtered(OPT_section))
     parseSection(Arg->getValue());
@@ -1109,9 +1288,9 @@
   Config->NxCompat = Args.hasFlag(OPT_nxcompat, OPT_nxcompat_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);
-  Config->DebugSymtab = Args.hasArg(OPT_debug_symtab);
+  Config->DebugDwarf = Debug == DebugKind::Dwarf;
+  Config->DebugGHashes = Debug == DebugKind::GHash;
+  Config->DebugSymtab = Debug == DebugKind::Symtab;
 
   Config->MapFile = getMapFile(Args);
 
@@ -1141,10 +1320,14 @@
     return;
 
   std::set<sys::fs::UniqueID> WholeArchives;
-  for (auto *Arg : Args.filtered(OPT_wholearchive_file))
-    if (Optional<StringRef> Path = doFindFile(Arg->getValue()))
+  AutoExporter Exporter;
+  for (auto *Arg : Args.filtered(OPT_wholearchive_file)) {
+    if (Optional<StringRef> Path = doFindFile(Arg->getValue())) {
       if (Optional<sys::fs::UniqueID> ID = getUniqueID(*Path))
         WholeArchives.insert(*ID);
+      Exporter.addWholeArchive(*Path);
+    }
+  }
 
   // A predicate returning true if a given path is an argument for
   // /wholearchive:, or /wholearchive is enabled globally.
@@ -1175,6 +1358,9 @@
   // Read all input files given via the command line.
   run();
 
+  if (errorCount())
+    return;
+
   // We should have inferred a machine type by now from the input files, but if
   // not we assume x64.
   if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) {
@@ -1293,6 +1479,9 @@
       // tools won't work correctly if these assumptions are not held.
       sys::fs::make_absolute(Config->PDBAltPath);
       sys::path::remove_dots(Config->PDBAltPath);
+    } else {
+      // Don't do this earlier, so that Config->OutputFile is ready.
+      parsePDBAltPath(Config->PDBAltPath);
     }
   }
 
@@ -1316,6 +1505,13 @@
   // Needed for MSVC 2017 15.5 CRT.
   Symtab->addAbsolute(mangle("__enclave_config"), 0);
 
+  if (Config->MinGW) {
+    Symtab->addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST__"), 0);
+    Symtab->addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST_END__"), 0);
+    Symtab->addAbsolute(mangle("__CTOR_LIST__"), 0);
+    Symtab->addAbsolute(mangle("__DTOR_LIST__"), 0);
+  }
+
   // This code may add new undefined symbols to the link, which may enqueue more
   // symbol resolution tasks, so we need to continue executing tasks until we
   // converge.
@@ -1360,6 +1556,24 @@
   Symtab->addCombinedLTOObjects();
   run();
 
+  if (Config->MinGW) {
+    // Load any further object files that might be needed for doing automatic
+    // imports.
+    //
+    // For cases with no automatically imported symbols, this iterates once
+    // over the symbol table and doesn't do anything.
+    //
+    // For the normal case with a few automatically imported symbols, this
+    // should only need to be run once, since each new object file imported
+    // is an import library and wouldn't add any new undefined references,
+    // but there's nothing stopping the __imp_ symbols from coming from a
+    // normal object file as well (although that won't be used for the
+    // actual autoimport later on). If this pass adds new undefined references,
+    // we won't iterate further to resolve them.
+    Symtab->loadMinGWAutomaticImports();
+    run();
+  }
+
   // Make sure we have resolved all symbols.
   Symtab->reportRemainingUndefines();
   if (errorCount())
@@ -1378,7 +1592,7 @@
   // are chosen to be exported.
   if (Config->DLL && ((Config->MinGW && Config->Exports.empty()) ||
                       Args.hasArg(OPT_export_all_symbols))) {
-    AutoExporter Exporter;
+    Exporter.initSymbolExcludes();
 
     Symtab->forEachSymbol([=](Symbol *S) {
       auto *Def = dyn_cast<Defined>(S);
@@ -1442,8 +1656,10 @@
     markLive(Symtab->getChunks());
 
   // Identify identical COMDAT sections to merge them.
-  if (Config->DoICF)
+  if (Config->DoICF) {
+    findKeepUniqueSections();
     doICF(Symtab->getChunks());
+  }
 
   // Write the result.
   writeResult();
diff --git a/COFF/Driver.h b/COFF/Driver.h
index e917955..e779721 100644
--- a/COFF/Driver.h
+++ b/COFF/Driver.h
@@ -89,6 +89,7 @@
   Optional<StringRef> findLib(StringRef Filename);
   StringRef doFindFile(StringRef Filename);
   StringRef doFindLib(StringRef Filename);
+  StringRef doFindLibMinGW(StringRef Filename);
 
   // Parses LIB environment which contains a list of search paths.
   void addLibSearchPaths();
diff --git a/COFF/DriverUtils.cpp b/COFF/DriverUtils.cpp
index f7d8fe5..9bb8348 100644
--- a/COFF/DriverUtils.cpp
+++ b/COFF/DriverUtils.cpp
@@ -28,6 +28,7 @@
 #include "llvm/Option/Option.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Process.h"
 #include "llvm/Support/Program.h"
@@ -863,7 +864,8 @@
 }
 
 void printHelp(const char *Argv0) {
-  COFFOptTable().PrintHelp(outs(), Argv0, "LLVM Linker", false);
+  std::string Usage = formatv("{0} [options] file...", Argv0).str();
+  COFFOptTable().PrintHelp(outs(), Usage.c_str(), "LLVM Linker", false);
 }
 
 } // namespace coff
diff --git a/COFF/ICF.cpp b/COFF/ICF.cpp
index 7feb3c4..9acd6e0 100644
--- a/COFF/ICF.cpp
+++ b/COFF/ICF.cpp
@@ -80,7 +80,7 @@
 bool ICF::isEligible(SectionChunk *C) {
   // Non-comdat chunks, dead chunks, and writable chunks are not elegible.
   bool Writable = C->getOutputCharacteristics() & llvm::COFF::IMAGE_SCN_MEM_WRITE;
-  if (!C->isCOMDAT() || !C->isLive() || Writable)
+  if (!C->isCOMDAT() || !C->Live || Writable)
     return false;
 
   // Code sections are eligible.
@@ -93,7 +93,11 @@
     return true;
 
   // So are vtables.
-  return C->Sym && C->Sym->getName().startswith("??_7");
+  if (C->Sym && C->Sym->getName().startswith("??_7"))
+    return true;
+
+  // Anything else not in an address-significance table is eligible.
+  return !C->KeepUnique;
 }
 
 // Split an equivalence class into smaller classes.
diff --git a/COFF/InputFiles.cpp b/COFF/InputFiles.cpp
index 289cdb1..cdbde0c 100644
--- a/COFF/InputFiles.cpp
+++ b/COFF/InputFiles.cpp
@@ -54,8 +54,16 @@
 static void checkAndSetWeakAlias(SymbolTable *Symtab, InputFile *F,
                                  Symbol *Source, Symbol *Target) {
   if (auto *U = dyn_cast<Undefined>(Source)) {
-    if (U->WeakAlias && U->WeakAlias != Target)
+    if (U->WeakAlias && U->WeakAlias != Target) {
+      // Weak aliases as produced by GCC are named in the form
+      // .weak.<weaksymbol>.<othersymbol>, where <othersymbol> is the name
+      // of another symbol emitted near the weak symbol.
+      // Just use the definition from the first object file that defined
+      // this weak symbol.
+      if (Config->MinGW)
+        return;
       Symtab->reportDuplicate(Source, F);
+    }
     U->WeakAlias = Target;
   }
 }
@@ -161,6 +169,11 @@
     return nullptr;
   }
 
+  if (Name == ".llvm_addrsig") {
+    AddrsigSec = Sec;
+    return nullptr;
+  }
+
   // Object files may have DWARF debug info or MS CodeView debug info
   // (or both).
   //
@@ -267,6 +280,13 @@
     COFFObj->getSymbolName(Sym, Name);
     if (SC)
       return Symtab->addRegular(this, Name, Sym.getGeneric(), SC);
+    // For MinGW symbols named .weak.* that point to a discarded section,
+    // don't create an Undefined symbol. If nothing ever refers to the symbol,
+    // everything should be fine. If something actually refers to the symbol
+    // (e.g. the undefined weak alias), linking will fail due to undefined
+    // references at the end.
+    if (Config->MinGW && Name.startswith(".weak."))
+      return nullptr;
     return Symtab->addUndefined(Name, this, false);
   }
   if (SC)
diff --git a/COFF/InputFiles.h b/COFF/InputFiles.h
index 2bfb9e4..2b04535 100644
--- a/COFF/InputFiles.h
+++ b/COFF/InputFiles.h
@@ -145,6 +145,8 @@
   // if we are not producing a PDB.
   llvm::pdb::DbiModuleDescriptorBuilder *ModuleDBI = nullptr;
 
+  const coff_section *AddrsigSec = nullptr;
+
 private:
   void initializeChunks();
   void initializeSymbols();
diff --git a/COFF/MapFile.cpp b/COFF/MapFile.cpp
index 6ca1b66..fd48942 100644
--- a/COFF/MapFile.cpp
+++ b/COFF/MapFile.cpp
@@ -110,7 +110,7 @@
     writeHeader(OS, Sec->getRVA(), Sec->getVirtualSize(), /*Align=*/PageSize);
     OS << Sec->Name << '\n';
 
-    for (Chunk *C : Sec->getChunks()) {
+    for (Chunk *C : Sec->Chunks) {
       auto *SC = dyn_cast<SectionChunk>(C);
       if (!SC)
         continue;
diff --git a/COFF/MarkLive.cpp b/COFF/MarkLive.cpp
index 57ae450..18b1c9c 100644
--- a/COFF/MarkLive.cpp
+++ b/COFF/MarkLive.cpp
@@ -32,13 +32,13 @@
   // COMDAT section chunks are dead by default. Add non-COMDAT chunks.
   for (Chunk *C : Chunks)
     if (auto *SC = dyn_cast<SectionChunk>(C))
-      if (SC->isLive())
+      if (SC->Live)
         Worklist.push_back(SC);
 
   auto Enqueue = [&](SectionChunk *C) {
-    if (C->isLive())
+    if (C->Live)
       return;
-    C->markLive();
+    C->Live = true;
     Worklist.push_back(C);
   };
 
@@ -57,7 +57,7 @@
 
   while (!Worklist.empty()) {
     SectionChunk *SC = Worklist.pop_back_val();
-    assert(SC->isLive() && "We mark as live when pushing onto the worklist!");
+    assert(SC->Live && "We mark as live when pushing onto the worklist!");
 
     // Mark all symbols listed in the relocation table for this section.
     for (Symbol *B : SC->symbols())
diff --git a/COFF/MinGW.cpp b/COFF/MinGW.cpp
index 2ca0058..505a134 100644
--- a/COFF/MinGW.cpp
+++ b/COFF/MinGW.cpp
@@ -19,7 +19,23 @@
 using namespace llvm;
 using namespace llvm::COFF;
 
-AutoExporter::AutoExporter() {
+void AutoExporter::initSymbolExcludes() {
+  ExcludeSymbolPrefixes = {
+      // Import symbols
+      "__imp_",
+      "__IMPORT_DESCRIPTOR_",
+      // Extra import symbols from GNU import libraries
+      "__nm_",
+      // C++ symbols
+      "__rtti_",
+      "__builtin_",
+      // Artifical symbols such as .refptr
+      ".",
+  };
+  ExcludeSymbolSuffixes = {
+      "_iname",
+      "_NULL_THUNK_DATA",
+  };
   if (Config->Machine == I386) {
     ExcludeSymbols = {
         "__NULL_IMPORT_DESCRIPTOR",
@@ -36,9 +52,10 @@
         "_DllEntryPoint@12",
         "_DllMainCRTStartup@12",
     };
+    ExcludeSymbolPrefixes.insert("__head_");
   } else {
     ExcludeSymbols = {
-        "_NULL_IMPORT_DESCRIPTOR",
+        "__NULL_IMPORT_DESCRIPTOR",
         "_pei386_runtime_relocator",
         "do_pseudo_reloc",
         "impure_ptr",
@@ -52,8 +69,11 @@
         "DllEntryPoint",
         "DllMainCRTStartup",
     };
+    ExcludeSymbolPrefixes.insert("_head_");
   }
+}
 
+AutoExporter::AutoExporter() {
   ExcludeLibs = {
       "libgcc",
       "libgcc_s",
@@ -90,6 +110,13 @@
   };
 }
 
+void AutoExporter::addWholeArchive(StringRef Path) {
+  StringRef LibName = sys::path::filename(Path);
+  // Drop the file extension, to match the processing below.
+  LibName = LibName.substr(0, LibName.rfind('.'));
+  ExcludeLibs.erase(LibName);
+}
+
 bool AutoExporter::shouldExport(Defined *Sym) const {
   if (!Sym || !Sym->isLive() || !Sym->getChunk())
     return false;
@@ -101,10 +128,12 @@
   if (ExcludeSymbols.count(Sym->getName()))
     return false;
 
-  // Don't export anything that looks like an import symbol (which also can be
-  // a manually defined data symbol with such a name).
-  if (Sym->getName().startswith("__imp_"))
-    return false;
+  for (StringRef Prefix : ExcludeSymbolPrefixes.keys())
+    if (Sym->getName().startswith(Prefix))
+      return false;
+  for (StringRef Suffix : ExcludeSymbolSuffixes.keys())
+    if (Sym->getName().endswith(Suffix))
+      return false;
 
   // If a corresponding __imp_ symbol exists and is defined, don't export it.
   if (Symtab->find(("__imp_" + Sym->getName()).str()))
diff --git a/COFF/MinGW.h b/COFF/MinGW.h
index fe6cc55..f9c5e3e 100644
--- a/COFF/MinGW.h
+++ b/COFF/MinGW.h
@@ -23,7 +23,13 @@
 public:
   AutoExporter();
 
+  void initSymbolExcludes();
+
+  void addWholeArchive(StringRef Path);
+
   llvm::StringSet<> ExcludeSymbols;
+  llvm::StringSet<> ExcludeSymbolPrefixes;
+  llvm::StringSet<> ExcludeSymbolSuffixes;
   llvm::StringSet<> ExcludeLibs;
   llvm::StringSet<> ExcludeObjects;
 
diff --git a/COFF/Options.td b/COFF/Options.td
index 8536763..f5dcd27 100644
--- a/COFF/Options.td
+++ b/COFF/Options.td
@@ -85,7 +85,7 @@
     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 debug_opt : P<"debug", "Embed a symbol table in the image with option">;
 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">;
@@ -99,8 +99,11 @@
 def wholearchive_flag : F<"wholearchive">;
 
 def force : F<"force">,
+    HelpText<"Allow undefined and multiply defined symbols when creating executables">;
+def force_unresolved : F<"force:unresolved">,
     HelpText<"Allow undefined symbols when creating executables">;
-def force_unresolved : F<"force:unresolved">;
+def force_multiple : F<"force:multiple">,
+    HelpText<"Allow multiply defined symbols when creating executables">;
 defm WX : B<"WX", "Treat warnings as errors", "Don't treat warnings as errors">;
 
 defm allowbind : B<"allowbind", "Enable DLL binding (default)",
@@ -139,9 +142,6 @@
 def help_q : Flag<["/?", "-?"], "">, Alias<help>;
 
 // LLD extensions
-def debug_ghash : F<"debug:ghash">;
-def debug_dwarf : F<"debug:dwarf">;
-def debug_symtab : F<"debug:symtab">;
 def export_all_symbols : F<"export-all-symbols">;
 def kill_at : F<"kill-at">;
 def lldmingw : F<"lldmingw">;
diff --git a/COFF/PDB.cpp b/COFF/PDB.cpp
index 766bf3f..6790ae6 100644
--- a/COFF/PDB.cpp
+++ b/COFF/PDB.cpp
@@ -16,6 +16,7 @@
 #include "Writer.h"
 #include "lld/Common/ErrorHandler.h"
 #include "lld/Common/Timer.h"
+#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
 #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
 #include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"
 #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
@@ -81,7 +82,11 @@
   bool IsTypeServerMap = false;
 };
 
+class DebugSHandler;
+
 class PDBLinker {
+  friend DebugSHandler;
+
 public:
   PDBLinker(SymbolTable *Symtab)
       : Alloc(), Symtab(Symtab), Builder(Alloc), TypeTable(Alloc),
@@ -93,7 +98,7 @@
   }
 
   /// Emit the basic PDB structure: initial streams, headers, etc.
-  void initialize(const llvm::codeview::DebugInfo &BuildId);
+  void initialize(llvm::codeview::DebugInfo *BuildId);
 
   /// Add natvis files specified on the command line.
   void addNatvisFiles();
@@ -125,8 +130,8 @@
   void addSections(ArrayRef<OutputSection *> OutputSections,
                    ArrayRef<uint8_t> SectionTable);
 
-  /// Write the PDB to disk.
-  void commit();
+  /// Write the PDB to disk and store the Guid generated for it in *Guid.
+  void commit(codeview::GUID *Guid);
 
 private:
   BumpPtrAllocator Alloc;
@@ -165,8 +170,79 @@
 
   /// List of TypeServer PDBs which cannot be loaded.
   /// Cached to prevent repeated load attempts.
-  std::set<GUID> MissingTypeServerPDBs;
+  std::map<GUID, std::string> MissingTypeServerPDBs;
 };
+
+class DebugSHandler {
+  PDBLinker &Linker;
+
+  /// The object file whose .debug$S sections we're processing.
+  ObjFile &File;
+
+  /// The result of merging type indices.
+  const CVIndexMap &IndexMap;
+
+  /// The DEBUG_S_STRINGTABLE subsection.  These strings are referred to by
+  /// index from other records in the .debug$S section.  All of these strings
+  /// need to be added to the global PDB string table, and all references to
+  /// these strings need to have their indices re-written to refer to the
+  /// global PDB string table.
+  DebugStringTableSubsectionRef CVStrTab;
+
+  /// The DEBUG_S_FILECHKSMS subsection.  As above, these are referred to
+  /// by other records in the .debug$S section and need to be merged into the
+  /// PDB.
+  DebugChecksumsSubsectionRef Checksums;
+
+  /// The DEBUG_S_FRAMEDATA subsection(s).  There can be more than one of
+  /// these and they need not appear in any specific order.  However, they
+  /// contain string table references which need to be re-written, so we
+  /// collect them all here and re-write them after all subsections have been
+  /// discovered and processed.
+  std::vector<DebugFrameDataSubsectionRef> NewFpoFrames;
+
+  /// Pointers to raw memory that we determine have string table references
+  /// that need to be re-written.  We first process all .debug$S subsections
+  /// to ensure that we can handle subsections written in any order, building
+  /// up this list as we go.  At the end, we use the string table (which must
+  /// have been discovered by now else it is an error) to re-write these
+  /// references.
+  std::vector<ulittle32_t *> StringTableReferences;
+
+public:
+  DebugSHandler(PDBLinker &Linker, ObjFile &File, const CVIndexMap &IndexMap)
+      : Linker(Linker), File(File), IndexMap(IndexMap) {}
+
+  void handleDebugS(lld::coff::SectionChunk &DebugS);
+  void finish();
+};
+}
+
+// Visual Studio's debugger requires absolute paths in various places in the
+// PDB to work without additional configuration:
+// https://docs.microsoft.com/en-us/visualstudio/debugger/debug-source-files-common-properties-solution-property-pages-dialog-box
+static void pdbMakeAbsolute(SmallVectorImpl<char> &FileName) {
+  if (sys::path::is_absolute(FileName, sys::path::Style::windows))
+    return;
+  if (Config->PDBSourcePath.empty()) {
+    // Debuggers generally want that PDB files contain absolute, Windows-style
+    // paths. On POSIX hosts, this here will produce an absolute POSIX-style
+    // path, which is weird -- but it's not clear what else to do.
+    // People doing cross builds should probably just always pass
+    // /pbdsourcepath: and make sure paths to input obj files and to lld-link
+    // itself are relative.
+    sys::fs::make_absolute(FileName);
+    return;
+  }
+  // Using /pdbsourcepath: with absolute POSIX paths will prepend
+  // PDBSourcePath to the absolute POSIX path. Since absolute POSIX paths
+  // don't make sense in PDB files anyways, this is gargabe-in-garbage-out.
+  SmallString<128> AbsoluteFileName = Config->PDBSourcePath;
+  sys::path::append(AbsoluteFileName, sys::path::Style::windows, FileName);
+  sys::path::native(AbsoluteFileName, sys::path::Style::windows);
+  sys::path::remove_dots(AbsoluteFileName, /*remove_dot_dots=*/true,
+                         sys::path::Style::windows);
+  FileName = std::move(AbsoluteFileName);
 }
 
 static SectionChunk *findByName(ArrayRef<SectionChunk *> Sections,
@@ -302,6 +378,12 @@
 
 static Expected<std::unique_ptr<pdb::NativeSession>>
 tryToLoadPDB(const GUID &GuidFromObj, StringRef TSPath) {
+  // Ensure the file exists before anything else. We want to return ENOENT,
+  // "file not found", even if the path points to a removable device (in which
+  // case the return message would be EAGAIN, "resource unavailable try again")
+  if (!llvm::sys::fs::exists(TSPath))
+    return errorCodeToError(std::error_code(ENOENT, std::generic_category()));
+
   ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getFile(
       TSPath, /*FileSize=*/-1, /*RequiresNullTerminator=*/false);
   if (!MBOrErr)
@@ -326,21 +408,22 @@
   // PDB file doesn't mean it matches.  For it to match the InfoStream's GUID
   // must match the GUID specified in the TypeServer2 record.
   if (ExpectedInfo->getGuid() != GuidFromObj)
-    return make_error<pdb::GenericError>(
-        pdb::generic_error_code::type_server_not_found, TSPath);
+    return make_error<pdb::PDBError>(pdb::pdb_error_code::signature_out_of_date);
 
   return std::move(NS);
 }
 
-Expected<const CVIndexMap&> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,
-                                                               TypeServer2Record &TS) {
-  const GUID& TSId = TS.getGuid();
+Expected<const CVIndexMap &>
+PDBLinker::maybeMergeTypeServerPDB(ObjFile *File, TypeServer2Record &TS) {
+  const GUID &TSId = TS.getGuid();
   StringRef TSPath = TS.getName();
 
   // First, check if the PDB has previously failed to load.
-  if (MissingTypeServerPDBs.count(TSId))
-    return make_error<pdb::GenericError>(
-      pdb::generic_error_code::type_server_not_found, TSPath);
+  auto PrevErr = MissingTypeServerPDBs.find(TSId);
+  if (PrevErr != MissingTypeServerPDBs.end())
+    return createFileError(
+        TSPath,
+        make_error<StringError>(PrevErr->second, inconvertibleErrorCode()));
 
   // Second, check if we already loaded a PDB with this GUID. Return the type
   // index mapping if we have it.
@@ -355,20 +438,37 @@
   // Check for a PDB at:
   // 1. The given file path
   // 2. Next to the object file or archive file
-  auto ExpectedSession = tryToLoadPDB(TSId, TSPath);
-  if (!ExpectedSession) {
-    consumeError(ExpectedSession.takeError());
-    StringRef LocalPath =
-        !File->ParentName.empty() ? File->ParentName : File->getName();
-    SmallString<128> Path = sys::path::parent_path(LocalPath);
-    sys::path::append(
-        Path, sys::path::filename(TSPath, sys::path::Style::windows));
-    ExpectedSession = tryToLoadPDB(TSId, Path);
-  }
+  auto ExpectedSession = handleExpected(
+      tryToLoadPDB(TSId, TSPath),
+      [&]() {
+        StringRef LocalPath =
+            !File->ParentName.empty() ? File->ParentName : File->getName();
+        SmallString<128> Path = sys::path::parent_path(LocalPath);
+        sys::path::append(
+            Path, sys::path::filename(TSPath, sys::path::Style::windows));
+        return tryToLoadPDB(TSId, Path);
+      },
+      [&](std::unique_ptr<ECError> EC) -> Error {
+        auto SysErr = EC->convertToErrorCode();
+        // Only re-try loading if the previous error was "No such file or
+        // directory"
+        if (SysErr.category() == std::generic_category() &&
+            SysErr.value() == ENOENT)
+          return Error::success();
+        return Error(std::move(EC));
+      });
+
   if (auto E = ExpectedSession.takeError()) {
     TypeServerIndexMappings.erase(TSId);
-    MissingTypeServerPDBs.emplace(TSId);
-    return std::move(E);
+
+    // Flatten the error to a string, for later display, if the error occurs
+    // again on the same PDB.
+    std::string ErrMsg;
+    raw_string_ostream S(ErrMsg);
+    S << E;
+    MissingTypeServerPDBs.emplace(TSId, S.str());
+
+    return createFileError(TSPath, std::move(E));
   }
 
   pdb::NativeSession *Session = ExpectedSession->get();
@@ -766,15 +866,15 @@
   cantFail(std::move(EC));
 }
 
-// Allocate memory for a .debug$S section and relocate it.
+// Allocate memory for a .debug$S / .debug$F section and relocate it.
 static ArrayRef<uint8_t> relocateDebugChunk(BumpPtrAllocator &Alloc,
-                                            SectionChunk *DebugChunk) {
-  uint8_t *Buffer = Alloc.Allocate<uint8_t>(DebugChunk->getSize());
-  assert(DebugChunk->OutputSectionOff == 0 &&
+                                            SectionChunk &DebugChunk) {
+  uint8_t *Buffer = Alloc.Allocate<uint8_t>(DebugChunk.getSize());
+  assert(DebugChunk.OutputSectionOff == 0 &&
          "debug sections should not be in output sections");
-  DebugChunk->writeTo(Buffer);
-  return consumeDebugMagic(makeArrayRef(Buffer, DebugChunk->getSize()),
-                           ".debug$S");
+  DebugChunk.readRelocTargets();
+  DebugChunk.writeTo(Buffer);
+  return makeArrayRef(Buffer, DebugChunk.getSize());
 }
 
 static pdb::SectionContrib createSectionContrib(const Chunk *C, uint32_t Modi) {
@@ -803,101 +903,76 @@
   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
-  // path absolute. If it's an object in an archive, we make the archive path
-  // absolute.
-  bool InArchive = !File->ParentName.empty();
-  SmallString<128> Path = InArchive ? File->ParentName : File->getName();
-  sys::fs::make_absolute(Path);
-  sys::path::native(Path, sys::path::Style::windows);
-  StringRef Name = InArchive ? File->getName() : StringRef(Path);
-
-  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;
+static uint32_t
+translateStringTableIndex(uint32_t ObjIndex,
+                          const DebugStringTableSubsectionRef &ObjStrTable,
+                          DebugStringTableSubsection &PdbStrTable) {
+  auto ExpectedString = ObjStrTable.getString(ObjIndex);
+  if (!ExpectedString) {
+    warn("Invalid string table reference");
+    consumeError(ExpectedString.takeError());
+    return 0;
   }
 
-  // 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
-  // indices to PDB type and item indices.
-  CVIndexMap ObjectIndexMap;
-  auto IndexMapResult = mergeDebugT(File, ObjectIndexMap);
+  return PdbStrTable.insert(*ExpectedString);
+}
 
-  // If the .debug$T sections fail to merge, assume there is no debug info.
-  if (!IndexMapResult) {
-    warn("Type server PDB for " + Name + " is invalid, ignoring debug info. " +
-         toString(IndexMapResult.takeError()));
-    return;
-  }
+void DebugSHandler::handleDebugS(lld::coff::SectionChunk &DebugS) {
+  DebugSubsectionArray Subsections;
 
-  const CVIndexMap &IndexMap = *IndexMapResult;
+  ArrayRef<uint8_t> RelocatedDebugContents = consumeDebugMagic(
+      relocateDebugChunk(Linker.Alloc, DebugS), DebugS.getSectionName());
 
-  ScopedTimer T(SymbolMergingTimer);
+  BinaryStreamReader Reader(RelocatedDebugContents, support::little);
+  ExitOnErr(Reader.readArray(Subsections, RelocatedDebugContents.size()));
 
-  // Now do all live .debug$S sections.
-  DebugStringTableSubsectionRef CVStrTab;
-  DebugChecksumsSubsectionRef Checksums;
-  std::vector<ulittle32_t *> StringTableReferences;
-  for (SectionChunk *DebugChunk : File->getDebugChunks()) {
-    if (!DebugChunk->isLive() || DebugChunk->getSectionName() != ".debug$S")
-      continue;
-
-    ArrayRef<uint8_t> RelocatedDebugContents =
-        relocateDebugChunk(Alloc, DebugChunk);
-    if (RelocatedDebugContents.empty())
-      continue;
-
-    DebugSubsectionArray Subsections;
-    BinaryStreamReader Reader(RelocatedDebugContents, support::little);
-    ExitOnErr(Reader.readArray(Subsections, RelocatedDebugContents.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;
+  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:
+      // We can add the relocated line table directly to the PDB without
+      // modification because the file checksum offsets will stay the same.
+      File.ModuleDBI->addDebugSubsection(SS);
+      break;
+    case DebugSubsectionKind::FrameData: {
+      // We need to re-write string table indices here, so save off all
+      // frame data subsections until we've processed the entire list of
+      // subsections so that we can be sure we have the string table.
+      DebugFrameDataSubsectionRef FDS;
+      ExitOnErr(FDS.initialize(SS.getRecordData()));
+      NewFpoFrames.push_back(std::move(FDS));
+      break;
+    }
+    case DebugSubsectionKind::Symbols:
+      if (Config->DebugGHashes) {
+        mergeSymbolRecords(Linker.Alloc, &File, Linker.Builder.getGsiBuilder(),
+                           IndexMap, Linker.GlobalIDTable,
+                           StringTableReferences, SS.getRecordData());
+      } else {
+        mergeSymbolRecords(Linker.Alloc, &File, Linker.Builder.getGsiBuilder(),
+                           IndexMap, Linker.IDTable, StringTableReferences,
+                           SS.getRecordData());
       }
-      case DebugSubsectionKind::FileChecksums:
-        assert(!Checksums.valid() &&
-               "Encountered multiple checksum subsections!");
-        ExitOnErr(Checksums.initialize(SS.getRecordData()));
-        break;
-      case DebugSubsectionKind::Lines:
-        // We can add the relocated line table directly to the PDB without
-        // modification because the file checksum offsets will stay the same.
-        File->ModuleDBI->addDebugSubsection(SS);
-        break;
-      case DebugSubsectionKind::Symbols:
-        if (Config->DebugGHashes) {
-          mergeSymbolRecords(Alloc, File, Builder.getGsiBuilder(), IndexMap,
-                             GlobalIDTable, StringTableReferences,
-                             SS.getRecordData());
-        } else {
-          mergeSymbolRecords(Alloc, File, Builder.getGsiBuilder(), IndexMap,
-                             IDTable, StringTableReferences,
-                             SS.getRecordData());
-        }
-        break;
-      default:
-        // FIXME: Process the rest of the subsections.
-        break;
-      }
+      break;
+    default:
+      // FIXME: Process the rest of the subsections.
+      break;
     }
   }
+}
+
+void DebugSHandler::finish() {
+  pdb::DbiStreamBuilder &DbiBuilder = Linker.Builder.getDbiBuilder();
 
   // We should have seen all debug subsections across the entire object file now
   // which means that if a StringTable subsection and Checksums subsection were
@@ -913,39 +988,111 @@
     return;
   }
 
-  // Rewrite each string table reference based on the value that the string
-  // assumes in the final PDB.
-  for (ulittle32_t *Ref : StringTableReferences) {
-    auto ExpectedString = CVStrTab.getString(*Ref);
-    if (!ExpectedString) {
-      warn("Invalid string table reference");
-      consumeError(ExpectedString.takeError());
-      continue;
+  // Rewrite string table indices in the Fpo Data and symbol records to refer to
+  // the global PDB string table instead of the object file string table.
+  for (DebugFrameDataSubsectionRef &FDS : NewFpoFrames) {
+    const uint32_t *Reloc = FDS.getRelocPtr();
+    for (codeview::FrameData FD : FDS) {
+      FD.RvaStart += *Reloc;
+      FD.FrameFunc =
+          translateStringTableIndex(FD.FrameFunc, CVStrTab, Linker.PDBStrTab);
+      DbiBuilder.addNewFpoData(FD);
     }
-
-    *Ref = PDBStrTab.insert(*ExpectedString);
   }
 
+  for (ulittle32_t *Ref : StringTableReferences)
+    *Ref = translateStringTableIndex(*Ref, CVStrTab, Linker.PDBStrTab);
+
   // Make a new file checksum table that refers to offsets in the PDB-wide
   // string table. Generally the string table subsection appears after the
   // checksum table, so we have to do this after looping over all the
   // subsections.
-  auto NewChecksums = make_unique<DebugChecksumsSubsection>(PDBStrTab);
+  auto NewChecksums = make_unique<DebugChecksumsSubsection>(Linker.PDBStrTab);
   for (FileChecksumEntry &FC : Checksums) {
-    SmallString<128> FileName = ExitOnErr(CVStrTab.getString(FC.FileNameOffset));
-    if (!sys::path::is_absolute(FileName) &&
-        !Config->PDBSourcePath.empty()) {
-      SmallString<128> AbsoluteFileName = Config->PDBSourcePath;
-      sys::path::append(AbsoluteFileName, FileName);
-      sys::path::native(AbsoluteFileName);
-      sys::path::remove_dots(AbsoluteFileName, /*remove_dot_dots=*/true);
-      FileName = std::move(AbsoluteFileName);
-    }
-    ExitOnErr(Builder.getDbiBuilder().addModuleSourceFile(*File->ModuleDBI,
-                                                          FileName));
+    SmallString<128> FileName =
+        ExitOnErr(CVStrTab.getString(FC.FileNameOffset));
+    pdbMakeAbsolute(FileName);
+    ExitOnErr(Linker.Builder.getDbiBuilder().addModuleSourceFile(
+        *File.ModuleDBI, FileName));
     NewChecksums->addChecksum(FileName, FC.Kind, FC.Checksum);
   }
-  File->ModuleDBI->addDebugSubsection(std::move(NewChecksums));
+  File.ModuleDBI->addDebugSubsection(std::move(NewChecksums));
+}
+
+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
+  // path absolute. If it's an object in an archive, we make the archive path
+  // absolute.
+  bool InArchive = !File->ParentName.empty();
+  SmallString<128> Path = InArchive ? File->ParentName : File->getName();
+  pdbMakeAbsolute(Path);
+  sys::path::native(Path, sys::path::Style::windows);
+  StringRef Name = InArchive ? File->getName() : StringRef(Path);
+
+  pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
+  File->ModuleDBI = &ExitOnErr(DbiBuilder.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->Live)
+      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
+  // indices to PDB type and item indices.
+  CVIndexMap ObjectIndexMap;
+  auto IndexMapResult = mergeDebugT(File, ObjectIndexMap);
+
+  // If the .debug$T sections fail to merge, assume there is no debug info.
+  if (!IndexMapResult) {
+    auto FileName = sys::path::filename(Path);
+    warn("Cannot use debug info for '" + FileName + "'\n" +
+         ">>> failed to load reference " +
+         StringRef(toString(IndexMapResult.takeError())));
+    return;
+  }
+
+  ScopedTimer T(SymbolMergingTimer);
+
+  DebugSHandler DSH(*this, *File, *IndexMapResult);
+  // Now do all live .debug$S and .debug$F sections.
+  for (SectionChunk *DebugChunk : File->getDebugChunks()) {
+    if (!DebugChunk->Live || DebugChunk->getSize() == 0)
+      continue;
+
+    if (DebugChunk->getSectionName() == ".debug$S") {
+      DSH.handleDebugS(*DebugChunk);
+      continue;
+    }
+
+    if (DebugChunk->getSectionName() == ".debug$F") {
+      ArrayRef<uint8_t> RelocatedDebugContents =
+          relocateDebugChunk(Alloc, *DebugChunk);
+
+      FixedStreamArray<object::FpoData> FpoRecords;
+      BinaryStreamReader Reader(RelocatedDebugContents, support::little);
+      uint32_t Count = RelocatedDebugContents.size() / sizeof(object::FpoData);
+      ExitOnErr(Reader.readArray(FpoRecords, Count));
+
+      // These are already relocated and don't refer to the string table, so we
+      // can just copy it.
+      for (const object::FpoData &FD : FpoRecords)
+        DbiBuilder.addOldFpoData(FD);
+      continue;
+    }
+  }
+
+  // Do any post-processing now that all .debug$S sections have been processed.
+  DSH.finish();
 }
 
 static PublicSym32 createPublic(Defined *Def) {
@@ -1075,11 +1222,14 @@
   std::string ArgStr = llvm::join(Args, " ");
   EBS.Fields.push_back("cwd");
   SmallString<64> cwd;
-  sys::fs::current_path(cwd);
+  if (Config->PDBSourcePath.empty()) 
+    sys::fs::current_path(cwd);
+  else
+    cwd = Config->PDBSourcePath;
   EBS.Fields.push_back(cwd);
   EBS.Fields.push_back("exe");
   SmallString<64> exe = Config->Argv[0];
-  llvm::sys::fs::make_absolute(exe);
+  pdbMakeAbsolute(exe);
   EBS.Fields.push_back(exe);
   EBS.Fields.push_back("pdb");
   EBS.Fields.push_back(Path);
@@ -1111,7 +1261,7 @@
 void coff::createPDB(SymbolTable *Symtab,
                      ArrayRef<OutputSection *> OutputSections,
                      ArrayRef<uint8_t> SectionTable,
-                     const llvm::codeview::DebugInfo &BuildId) {
+                     llvm::codeview::DebugInfo *BuildId) {
   ScopedTimer T1(TotalPdbLinkTimer);
   PDBLinker PDB(Symtab);
 
@@ -1121,12 +1271,19 @@
   PDB.addNatvisFiles();
 
   ScopedTimer T2(DiskCommitTimer);
-  PDB.commit();
+  codeview::GUID Guid;
+  PDB.commit(&Guid);
+  memcpy(&BuildId->PDB70.Signature, &Guid, 16);
 }
 
-void PDBLinker::initialize(const llvm::codeview::DebugInfo &BuildId) {
+void PDBLinker::initialize(llvm::codeview::DebugInfo *BuildId) {
   ExitOnErr(Builder.initialize(4096)); // 4096 is blocksize
 
+  BuildId->Signature.CVSignature = OMF::Signature::PDB70;
+  // Signature is set to a hash of the PDB contents when the PDB is done.
+  memset(BuildId->PDB70.Signature, 0, 16);
+  BuildId->PDB70.Age = 1;
+
   // Create streams in MSF for predefined streams, namely
   // PDB, TPI, DBI and IPI.
   for (int I = 0; I < (int)pdb::kSpecialStreamCount; ++I)
@@ -1134,15 +1291,12 @@
 
   // Add an Info stream.
   auto &InfoBuilder = Builder.getInfoBuilder();
-  GUID uuid;
-  memcpy(&uuid, &BuildId.PDB70.Signature, sizeof(uuid));
-  InfoBuilder.setAge(BuildId.PDB70.Age);
-  InfoBuilder.setGuid(uuid);
   InfoBuilder.setVersion(pdb::PdbRaw_ImplVer::PdbImplVC70);
+  InfoBuilder.setHashPDBContentsToGUID(true);
 
   // Add an empty DBI stream.
   pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
-  DbiBuilder.setAge(BuildId.PDB70.Age);
+  DbiBuilder.setAge(BuildId->PDB70.Age);
   DbiBuilder.setVersionHeader(pdb::PdbDbiV70);
   DbiBuilder.setMachineType(Config->Machine);
   // Technically we are not link.exe 14.11, but there are known cases where
@@ -1157,7 +1311,7 @@
   // It's not entirely clear what this is, but the * Linker * module uses it.
   pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
   NativePath = Config->PDBPath;
-  sys::fs::make_absolute(NativePath);
+  pdbMakeAbsolute(NativePath);
   sys::path::native(NativePath, sys::path::Style::windows);
   uint32_t PdbFilePathNI = DbiBuilder.addECName(NativePath);
   auto &LinkerModule = ExitOnErr(DbiBuilder.addModuleInfo("* Linker *"));
@@ -1167,7 +1321,7 @@
   // Add section contributions. They must be ordered by ascending RVA.
   for (OutputSection *OS : OutputSections) {
     addLinkerModuleSectionSymbol(LinkerModule, *OS, Alloc);
-    for (Chunk *C : OS->getChunks()) {
+    for (Chunk *C : OS->Chunks) {
       pdb::SectionContrib SC =
           createSectionContrib(C, LinkerModule.getModuleIndex());
       Builder.getDbiBuilder().addSectionContrib(SC);
@@ -1186,9 +1340,9 @@
       DbiBuilder.addDbgStream(pdb::DbgHeaderType::SectionHdr, SectionTable));
 }
 
-void PDBLinker::commit() {
+void PDBLinker::commit(codeview::GUID *Guid) {
   // Write to a file.
-  ExitOnErr(Builder.commit(Config->PDBPath));
+  ExitOnErr(Builder.commit(Config->PDBPath, Guid));
 }
 
 static Expected<StringRef>
diff --git a/COFF/PDB.h b/COFF/PDB.h
index a98d129..ea7a999 100644
--- a/COFF/PDB.h
+++ b/COFF/PDB.h
@@ -28,7 +28,7 @@
 void createPDB(SymbolTable *Symtab,
                llvm::ArrayRef<OutputSection *> OutputSections,
                llvm::ArrayRef<uint8_t> SectionTable,
-               const llvm::codeview::DebugInfo &BuildId);
+               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 62188b5..f451beb 100644
--- a/COFF/SymbolTable.cpp
+++ b/COFF/SymbolTable.cpp
@@ -60,16 +60,16 @@
 }
 
 static void errorOrWarn(const Twine &S) {
-  if (Config->Force)
+  if (Config->ForceUnresolved)
     warn(S);
   else
     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) {
+// Returns the symbol in SC whose value is <= Addr that is closest to Addr.
+// This is generally the global variable or function whose definition contains
+// Addr.
+static Symbol *getSymbol(SectionChunk *SC, uint32_t Addr) {
   DefinedRegular *Candidate = nullptr;
 
   for (Symbol *S : SC->File->getSymbols()) {
@@ -81,14 +81,12 @@
     Candidate = D;
   }
 
-  if (!Candidate)
-    return "";
-  return Candidate->getName();
+  return Candidate;
 }
 
 static std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex) {
   struct Location {
-    StringRef SymName;
+    Symbol *Sym;
     std::pair<StringRef, uint32_t> FileLine;
   };
   std::vector<Location> Locations;
@@ -102,14 +100,14 @@
         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});
+      Symbol *Sym = getSymbol(SC, R.VirtualAddress);
+      if (!FileLine.first.empty() || Sym)
+        Locations.push_back({Sym, FileLine});
     }
   }
 
   if (Locations.empty())
-    return "\n>>> referenced by " + toString(File) + "\n";
+    return "\n>>> referenced by " + toString(File);
 
   std::string Out;
   llvm::raw_string_ostream OS(Out);
@@ -119,13 +117,88 @@
       OS << Loc.FileLine.first << ":" << Loc.FileLine.second
          << "\n>>>               ";
     OS << toString(File);
-    if (!Loc.SymName.empty())
-      OS << ":(" << Loc.SymName << ')';
+    if (Loc.Sym)
+      OS << ":(" << toString(*Loc.Sym) << ')';
   }
-  OS << '\n';
   return OS.str();
 }
 
+void SymbolTable::loadMinGWAutomaticImports() {
+  for (auto &I : SymMap) {
+    Symbol *Sym = I.second;
+    auto *Undef = dyn_cast<Undefined>(Sym);
+    if (!Undef)
+      continue;
+    if (!Sym->IsUsedInRegularObj)
+      continue;
+
+    StringRef Name = Undef->getName();
+
+    if (Name.startswith("__imp_"))
+      continue;
+    // If we have an undefined symbol, but we have a Lazy representing a
+    // symbol we could load from file, make sure to load that.
+    Lazy *L = dyn_cast_or_null<Lazy>(find(("__imp_" + Name).str()));
+    if (!L || L->PendingArchiveLoad)
+      continue;
+
+    log("Loading lazy " + L->getName() + " from " + L->File->getName() +
+        " for automatic import");
+    L->PendingArchiveLoad = true;
+    L->File->addMember(&L->Sym);
+  }
+}
+
+bool SymbolTable::handleMinGWAutomaticImport(Symbol *Sym, StringRef Name) {
+  if (Name.startswith("__imp_"))
+    return false;
+  Defined *Imp = dyn_cast_or_null<Defined>(find(("__imp_" + Name).str()));
+  if (!Imp)
+    return false;
+
+  // Replace the reference directly to a variable with a reference
+  // to the import address table instead. This obviously isn't right,
+  // but we mark the symbol as IsRuntimePseudoReloc, and a later pass
+  // will add runtime pseudo relocations for every relocation against
+  // this Symbol. The runtime pseudo relocation framework expects the
+  // reference itself to point at the IAT entry.
+  size_t ImpSize = 0;
+  if (isa<DefinedImportData>(Imp)) {
+    log("Automatically importing " + Name + " from " +
+        cast<DefinedImportData>(Imp)->getDLLName());
+    ImpSize = sizeof(DefinedImportData);
+  } else if (isa<DefinedRegular>(Imp)) {
+    log("Automatically importing " + Name + " from " +
+        toString(cast<DefinedRegular>(Imp)->File));
+    ImpSize = sizeof(DefinedRegular);
+  } else {
+    warn("unable to automatically import " + Name + " from " + Imp->getName() +
+         " from " + toString(cast<DefinedRegular>(Imp)->File) +
+         "; unexpected symbol type");
+    return false;
+  }
+  Sym->replaceKeepingName(Imp, ImpSize);
+  Sym->IsRuntimePseudoReloc = true;
+
+  // There may exist symbols named .refptr.<name> which only consist
+  // of a single pointer to <name>. If it turns out <name> is
+  // automatically imported, we don't need to keep the .refptr.<name>
+  // pointer at all, but redirect all accesses to it to the IAT entry
+  // for __imp_<name> instead, and drop the whole .refptr.<name> chunk.
+  DefinedRegular *Refptr =
+      dyn_cast_or_null<DefinedRegular>(find((".refptr." + Name).str()));
+  size_t PtrSize = Config->is64() ? 8 : 4;
+  if (Refptr && Refptr->getChunk()->getSize() == PtrSize) {
+    SectionChunk *SC = dyn_cast_or_null<SectionChunk>(Refptr->getChunk());
+    if (SC && SC->Relocs.size() == 1 && *SC->symbols().begin() == Sym) {
+      log("Replacing .refptr." + Name + " with " + Imp->getName());
+      Refptr->getChunk()->Live = false;
+      Refptr->replaceKeepingName(Imp, ImpSize);
+    }
+  }
+  return true;
+}
+
 void SymbolTable::reportRemainingUndefines() {
   SmallPtrSet<Symbol *, 8> Undefs;
   DenseMap<Symbol *, Symbol *> LocalImports;
@@ -169,9 +242,12 @@
       }
     }
 
+    if (Config->MinGW && handleMinGWAutomaticImport(Sym, Name))
+      continue;
+
     // Remaining undefined symbols are not fatal if /force is specified.
     // They are replaced with dummy defined symbols.
-    if (Config->Force)
+    if (Config->ForceUnresolved)
       replaceSymbol<DefinedAbsolute>(Sym, Name, 0);
     Undefs.insert(Sym);
   }
@@ -181,10 +257,10 @@
 
   for (Symbol *B : Config->GCRoot) {
     if (Undefs.count(B))
-      errorOrWarn("<root>: undefined symbol: " + B->getName());
+      errorOrWarn("<root>: undefined symbol: " + toString(*B));
     if (Config->WarnLocallyDefinedImported)
       if (Symbol *Imp = LocalImports.lookup(B))
-        warn("<root>: locally defined symbol imported: " + Imp->getName() +
+        warn("<root>: locally defined symbol imported: " + toString(*Imp) +
              " (defined in " + toString(Imp->getFile()) + ") [LNK4217]");
   }
 
@@ -195,18 +271,18 @@
       if (!Sym)
         continue;
       if (Undefs.count(Sym))
-        errorOrWarn("undefined symbol: " + Sym->getName() +
+        errorOrWarn("undefined symbol: " + toString(*Sym) +
                     getSymbolLocations(File, SymIndex));
       if (Config->WarnLocallyDefinedImported)
         if (Symbol *Imp = LocalImports.lookup(Sym))
-          warn(toString(File) + ": locally defined symbol imported: " +
-               Imp->getName() + " (defined in " + toString(Imp->getFile()) +
-               ") [LNK4217]");
+          warn(toString(File) +
+               ": locally defined symbol imported: " + toString(*Imp) +
+               " (defined in " + toString(Imp->getFile()) + ") [LNK4217]");
     }
   }
 }
 
-std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, InputFile *File) {
+std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {
   bool Inserted = false;
   Symbol *&Sym = SymMap[CachedHashStringRef(Name)];
   if (!Sym) {
@@ -215,11 +291,16 @@
     Sym->PendingArchiveLoad = false;
     Inserted = true;
   }
-  if (!File || !isa<BitcodeFile>(File))
-    Sym->IsUsedInRegularObj = true;
   return {Sym, Inserted};
 }
 
+std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, InputFile *File) {
+  std::pair<Symbol *, bool> Result = insert(Name);
+  if (!File || !isa<BitcodeFile>(File))
+    Result.first->IsUsedInRegularObj = true;
+  return Result;
+}
+
 Symbol *SymbolTable::addUndefined(StringRef Name, InputFile *F,
                                   bool IsWeakAlias) {
   Symbol *S;
@@ -242,7 +323,7 @@
   StringRef Name = Sym.getName();
   Symbol *S;
   bool WasInserted;
-  std::tie(S, WasInserted) = insert(Name, nullptr);
+  std::tie(S, WasInserted) = insert(Name);
   if (WasInserted) {
     replaceSymbol<Lazy>(S, F, Sym);
     return;
@@ -255,8 +336,14 @@
 }
 
 void SymbolTable::reportDuplicate(Symbol *Existing, InputFile *NewFile) {
-  error("duplicate symbol: " + toString(*Existing) + " in " +
-        toString(Existing->getFile()) + " and in " + toString(NewFile));
+  std::string Msg = "duplicate symbol: " + toString(*Existing) + " in " +
+                    toString(Existing->getFile()) + " and in " +
+                    toString(NewFile);
+
+  if (Config->ForceMultiple)
+    warn(Msg);
+  else
+    error(Msg);
 }
 
 Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) {
diff --git a/COFF/SymbolTable.h b/COFF/SymbolTable.h
index 2258257..dc40b14 100644
--- a/COFF/SymbolTable.h
+++ b/COFF/SymbolTable.h
@@ -54,6 +54,9 @@
   // symbols.
   void reportRemainingUndefines();
 
+  void loadMinGWAutomaticImports();
+  bool handleMinGWAutomaticImport(Symbol *Sym, StringRef Name);
+
   // Returns a list of chunks of selected symbols.
   std::vector<Chunk *> getChunks();
 
@@ -108,6 +111,9 @@
   }
 
 private:
+  /// Inserts symbol if not already present.
+  std::pair<Symbol *, bool> insert(StringRef Name);
+  /// Same as insert(Name), but also sets IsUsedInRegularObj.
   std::pair<Symbol *, bool> insert(StringRef Name, InputFile *F);
   StringRef findByPrefix(StringRef Prefix);
 
diff --git a/COFF/Symbols.cpp b/COFF/Symbols.cpp
index 7c8b7d5..ccaf864 100644
--- a/COFF/Symbols.cpp
+++ b/COFF/Symbols.cpp
@@ -54,7 +54,7 @@
 
 bool Symbol::isLive() const {
   if (auto *R = dyn_cast<DefinedRegular>(this))
-    return R->getChunk()->isLive();
+    return R->getChunk()->Live;
   if (auto *Imp = dyn_cast<DefinedImportData>(this))
     return Imp->File->Live;
   if (auto *Imp = dyn_cast<DefinedImportThunk>(this))
@@ -63,6 +63,13 @@
   return true;
 }
 
+// MinGW specific.
+void Symbol::replaceKeepingName(Symbol *Other, size_t Size) {
+  StringRef OrigName = Name;
+  memcpy(this, Other, Size);
+  Name = OrigName;
+}
+
 COFFSymbolRef DefinedCOFF::getCOFFSymbol() {
   size_t SymSize = cast<ObjFile>(File)->getCOFFObj()->getSymbolTableEntrySize();
   if (SymSize == sizeof(coff_symbol16))
diff --git a/COFF/Symbols.h b/COFF/Symbols.h
index 7414376..9e9bd73 100644
--- a/COFF/Symbols.h
+++ b/COFF/Symbols.h
@@ -41,7 +41,7 @@
     // The order of these is significant. We start with the regular defined
     // symbols as those are the most prevelant and the zero tag is the cheapest
     // to set. Among the defined kinds, the lower the kind is preferred over
-    // the higher kind when testing wether one symbol should take precedence
+    // the higher kind when testing whether one symbol should take precedence
     // over another.
     DefinedRegularKind = 0,
     DefinedCommonKind,
@@ -66,6 +66,8 @@
   // Returns the symbol name.
   StringRef getName();
 
+  void replaceKeepingName(Symbol *Other, size_t Size);
+
   // Returns the file from which this symbol was created.
   InputFile *getFile();
 
@@ -78,7 +80,7 @@
   explicit Symbol(Kind K, StringRef N = "")
       : SymbolKind(K), IsExternal(true), IsCOMDAT(false),
         WrittenToSymtab(false), PendingArchiveLoad(false), IsGCRoot(false),
-        Name(N) {}
+        IsRuntimePseudoReloc(false), Name(N) {}
 
   const unsigned SymbolKind : 8;
   unsigned IsExternal : 1;
@@ -102,6 +104,8 @@
   /// True if we've already added this symbol to the list of GC roots.
   unsigned IsGCRoot : 1;
 
+  unsigned IsRuntimePseudoReloc : 1;
+
 protected:
   StringRef Name;
 };
diff --git a/COFF/Writer.cpp b/COFF/Writer.cpp
index 925a8e4..d42c82c 100644
--- a/COFF/Writer.cpp
+++ b/COFF/Writer.cpp
@@ -83,30 +83,32 @@
 
 class DebugDirectoryChunk : public Chunk {
 public:
-  DebugDirectoryChunk(const std::vector<Chunk *> &R) : Records(R) {}
+  DebugDirectoryChunk(const std::vector<Chunk *> &R, bool WriteRepro)
+      : Records(R), WriteRepro(WriteRepro) {}
 
   size_t getSize() const override {
-    return Records.size() * sizeof(debug_directory);
+    return (Records.size() + int(WriteRepro)) * sizeof(debug_directory);
   }
 
   void writeTo(uint8_t *B) const override {
     auto *D = reinterpret_cast<debug_directory *>(B + OutputSectionOff);
 
     for (const Chunk *Record : Records) {
-      D->Characteristics = 0;
-      D->TimeDateStamp = 0;
-      D->MajorVersion = 0;
-      D->MinorVersion = 0;
-      D->Type = COFF::IMAGE_DEBUG_TYPE_CODEVIEW;
-      D->SizeOfData = Record->getSize();
-      D->AddressOfRawData = Record->getRVA();
       OutputSection *OS = Record->getOutputSection();
       uint64_t Offs = OS->getFileOff() + (Record->getRVA() - OS->getRVA());
-      D->PointerToRawData = Offs;
-
-      TimeDateStamps.push_back(&D->TimeDateStamp);
+      fillEntry(D, COFF::IMAGE_DEBUG_TYPE_CODEVIEW, Record->getSize(),
+                Record->getRVA(), Offs);
       ++D;
     }
+
+    if (WriteRepro) {
+      // FIXME: The COFF spec allows either a 0-sized entry to just say
+      // "the timestamp field is really a hash", or a 4-byte size field
+      // followed by that many bytes containing a longer hash (with the
+      // lowest 4 bytes usually being the timestamp in little-endian order).
+      // Consider storing the full 8 bytes computed by xxHash64 here.
+      fillEntry(D, COFF::IMAGE_DEBUG_TYPE_REPRO, 0, 0, 0);
+    }
   }
 
   void setTimeDateStamp(uint32_t TimeDateStamp) {
@@ -115,8 +117,23 @@
   }
 
 private:
+  void fillEntry(debug_directory *D, COFF::DebugType DebugType, size_t Size,
+                 uint64_t RVA, uint64_t Offs) const {
+    D->Characteristics = 0;
+    D->TimeDateStamp = 0;
+    D->MajorVersion = 0;
+    D->MinorVersion = 0;
+    D->Type = DebugType;
+    D->SizeOfData = Size;
+    D->AddressOfRawData = RVA;
+    D->PointerToRawData = Offs;
+
+    TimeDateStamps.push_back(&D->TimeDateStamp);
+  }
+
   mutable std::vector<support::ulittle32_t *> TimeDateStamps;
   const std::vector<Chunk *> &Records;
+  bool WriteRepro;
 };
 
 class CVDebugRecordChunk : public Chunk {
@@ -150,14 +167,21 @@
   void createSections();
   void createMiscChunks();
   void createImportTables();
+  void appendImportThunks();
+  void locateImportTables(
+      std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> &Map);
   void createExportTable();
   void mergeSections();
+  void readRelocTargets();
   void assignAddresses();
+  void finalizeAddresses();
   void removeEmptySections();
   void createSymbolAndStringTable();
   void openFile(StringRef OutputPath);
   template <typename PEHeaderTy> void writeHeader();
   void createSEHTable();
+  void createRuntimePseudoRelocs();
+  void insertCtorDtorSymbols();
   void createGuardCFTables();
   void markSymbolsForRVATable(ObjFile *File,
                               ArrayRef<SectionChunk *> SymIdxChunks,
@@ -168,6 +192,7 @@
   void writeSections();
   void writeBuildId();
   void sortExceptionTable();
+  void sortCRTSectionChunks(std::vector<Chunk *> &Chunks);
 
   llvm::Optional<coff_symbol16> createSymbol(Defined *D);
   size_t addEntryToStringTable(StringRef Str);
@@ -184,6 +209,10 @@
   std::vector<char> Strtab;
   std::vector<llvm::object::coff_symbol16> OutputSymtab;
   IdataContents Idata;
+  Chunk *ImportTableStart = nullptr;
+  uint64_t ImportTableSize = 0;
+  Chunk *IATStart = nullptr;
+  uint64_t IATSize = 0;
   DelayLoadContents DelayIdata;
   EdataContents Edata;
   bool SetNoSEHCharacteristic = false;
@@ -191,7 +220,6 @@
   DebugDirectoryChunk *DebugDirectory = nullptr;
   std::vector<Chunk *> DebugRecords;
   CVDebugRecordChunk *BuildId = nullptr;
-  Optional<codeview::DebugInfo> PreviousBuildId;
   ArrayRef<uint8_t> SectionTable;
 
   uint64_t FileSize;
@@ -209,6 +237,8 @@
   OutputSection *DidatSec;
   OutputSection *RsrcSec;
   OutputSection *RelocSec;
+  OutputSection *CtorsSec;
+  OutputSection *DtorsSec;
 
   // The first and last .pdata sections in the output file.
   //
@@ -237,6 +267,11 @@
   C->setOutputSection(this);
 }
 
+void OutputSection::insertChunkAtStart(Chunk *C) {
+  Chunks.insert(Chunks.begin(), C);
+  C->setOutputSection(this);
+}
+
 void OutputSection::setPermissions(uint32_t C) {
   Header.Characteristics &= ~PermMask;
   Header.Characteristics |= C;
@@ -267,77 +302,205 @@
 } // namespace coff
 } // namespace lld
 
-// PDBs are matched against executables using a build id which consists of three
-// components:
-//   1. A 16-bit GUID
-//   2. An age
-//   3. A time stamp.
-//
-// Debuggers and symbol servers match executables against debug info by checking
-// each of these components of the EXE/DLL against the corresponding value in
-// the PDB and failing a match if any of the components differ.  In the case of
-// symbol servers, symbols are cached in a folder that is a function of the
-// GUID.  As a result, in order to avoid symbol cache pollution where every
-// incremental build copies a new PDB to the symbol cache, we must try to re-use
-// the existing GUID if one exists, but bump the age.  This way the match will
-// fail, so the symbol cache knows to use the new PDB, but the GUID matches, so
-// it overwrites the existing item in the symbol cache rather than making a new
-// one.
-static Optional<codeview::DebugInfo> loadExistingBuildId(StringRef Path) {
-  // We don't need to incrementally update a previous build id if we're not
-  // writing codeview debug info.
-  if (!Config->Debug)
-    return None;
-
-  auto ExpectedBinary = llvm::object::createBinary(Path);
-  if (!ExpectedBinary) {
-    consumeError(ExpectedBinary.takeError());
-    return None;
+// Check whether the target address S is in range from a relocation
+// of type RelType at address P.
+static bool isInRange(uint16_t RelType, uint64_t S, uint64_t P, int Margin) {
+  assert(Config->Machine == ARMNT);
+  int64_t Diff = AbsoluteDifference(S, P + 4) + Margin;
+  switch (RelType) {
+  case IMAGE_REL_ARM_BRANCH20T:
+    return isInt<21>(Diff);
+  case IMAGE_REL_ARM_BRANCH24T:
+  case IMAGE_REL_ARM_BLX23T:
+    return isInt<25>(Diff);
+  default:
+    return true;
   }
+}
 
-  auto Binary = std::move(*ExpectedBinary);
-  if (!Binary.getBinary()->isCOFF())
-    return None;
+// Return the last thunk for the given target if it is in range,
+// or create a new one.
+static std::pair<Defined *, bool>
+getThunk(DenseMap<uint64_t, Defined *> &LastThunks, Defined *Target, uint64_t P,
+         uint16_t Type, int Margin) {
+  Defined *&LastThunk = LastThunks[Target->getRVA()];
+  if (LastThunk && isInRange(Type, LastThunk->getRVA(), P, Margin))
+    return {LastThunk, false};
+  RangeExtensionThunk *C = make<RangeExtensionThunk>(Target);
+  Defined *D = make<DefinedSynthetic>("", C);
+  LastThunk = D;
+  return {D, true};
+}
 
-  std::error_code EC;
-  COFFObjectFile File(Binary.getBinary()->getMemoryBufferRef(), EC);
-  if (EC)
-    return None;
+// This checks all relocations, and for any relocation which isn't in range
+// it adds a thunk after the section chunk that contains the relocation.
+// If the latest thunk for the specific target is in range, that is used
+// instead of creating a new thunk. All range checks are done with the
+// specified margin, to make sure that relocations that originally are in
+// range, but only barely, also get thunks - in case other added thunks makes
+// the target go out of range.
+//
+// After adding thunks, we verify that all relocations are in range (with
+// no extra margin requirements). If this failed, we restart (throwing away
+// the previously created thunks) and retry with a wider margin.
+static bool createThunks(std::vector<Chunk *> &Chunks, int Margin) {
+  bool AddressesChanged = false;
+  DenseMap<uint64_t, Defined *> LastThunks;
+  size_t ThunksSize = 0;
+  // Recheck Chunks.size() each iteration, since we can insert more
+  // elements into it.
+  for (size_t I = 0; I != Chunks.size(); ++I) {
+    SectionChunk *SC = dyn_cast_or_null<SectionChunk>(Chunks[I]);
+    if (!SC)
+      continue;
+    size_t ThunkInsertionSpot = I + 1;
 
-  // If the machine of the binary we're outputting doesn't match the machine
-  // of the existing binary, don't try to re-use the build id.
-  if (File.is64() != Config->is64() || File.getMachine() != Config->Machine)
-    return None;
+    // Try to get a good enough estimate of where new thunks will be placed.
+    // Offset this by the size of the new thunks added so far, to make the
+    // estimate slightly better.
+    size_t ThunkInsertionRVA = SC->getRVA() + SC->getSize() + ThunksSize;
+    for (size_t J = 0, E = SC->Relocs.size(); J < E; ++J) {
+      const coff_relocation &Rel = SC->Relocs[J];
+      Symbol *&RelocTarget = SC->RelocTargets[J];
 
-  for (const auto &DebugDir : File.debug_directories()) {
-    if (DebugDir.Type != IMAGE_DEBUG_TYPE_CODEVIEW)
+      // The estimate of the source address P should be pretty accurate,
+      // but we don't know whether the target Symbol address should be
+      // offset by ThunkSize or not (or by some of ThunksSize but not all of
+      // it), giving us some uncertainty once we have added one thunk.
+      uint64_t P = SC->getRVA() + Rel.VirtualAddress + ThunksSize;
+
+      Defined *Sym = dyn_cast_or_null<Defined>(RelocTarget);
+      if (!Sym)
+        continue;
+
+      uint64_t S = Sym->getRVA();
+
+      if (isInRange(Rel.Type, S, P, Margin))
+        continue;
+
+      // If the target isn't in range, hook it up to an existing or new
+      // thunk.
+      Defined *Thunk;
+      bool WasNew;
+      std::tie(Thunk, WasNew) = getThunk(LastThunks, Sym, P, Rel.Type, Margin);
+      if (WasNew) {
+        Chunk *ThunkChunk = Thunk->getChunk();
+        ThunkChunk->setRVA(
+            ThunkInsertionRVA); // Estimate of where it will be located.
+        Chunks.insert(Chunks.begin() + ThunkInsertionSpot, ThunkChunk);
+        ThunkInsertionSpot++;
+        ThunksSize += ThunkChunk->getSize();
+        ThunkInsertionRVA += ThunkChunk->getSize();
+        AddressesChanged = true;
+      }
+      RelocTarget = Thunk;
+    }
+  }
+  return AddressesChanged;
+}
+
+// Verify that all relocations are in range, with no extra margin requirements.
+static bool verifyRanges(const std::vector<Chunk *> Chunks) {
+  for (Chunk *C : Chunks) {
+    SectionChunk *SC = dyn_cast_or_null<SectionChunk>(C);
+    if (!SC)
       continue;
 
-    const codeview::DebugInfo *ExistingDI = nullptr;
-    StringRef PDBFileName;
-    if (auto EC = File.getDebugPDBInfo(ExistingDI, PDBFileName)) {
-      (void)EC;
-      return None;
+    for (size_t J = 0, E = SC->Relocs.size(); J < E; ++J) {
+      const coff_relocation &Rel = SC->Relocs[J];
+      Symbol *RelocTarget = SC->RelocTargets[J];
+
+      Defined *Sym = dyn_cast_or_null<Defined>(RelocTarget);
+      if (!Sym)
+        continue;
+
+      uint64_t P = SC->getRVA() + Rel.VirtualAddress;
+      uint64_t S = Sym->getRVA();
+
+      if (!isInRange(Rel.Type, S, P, 0))
+        return false;
     }
-    // We only support writing PDBs in v70 format.  So if this is not a build
-    // id that we recognize / support, ignore it.
-    if (ExistingDI->Signature.CVSignature != OMF::Signature::PDB70)
-      return None;
-    return *ExistingDI;
   }
-  return None;
+  return true;
+}
+
+// Assign addresses and add thunks if necessary.
+void Writer::finalizeAddresses() {
+  assignAddresses();
+  if (Config->Machine != ARMNT)
+    return;
+
+  size_t OrigNumChunks = 0;
+  for (OutputSection *Sec : OutputSections) {
+    Sec->OrigChunks = Sec->Chunks;
+    OrigNumChunks += Sec->Chunks.size();
+  }
+
+  int Pass = 0;
+  int Margin = 1024 * 100;
+  while (true) {
+    // First check whether we need thunks at all, or if the previous pass of
+    // adding them turned out ok.
+    bool RangesOk = true;
+    size_t NumChunks = 0;
+    for (OutputSection *Sec : OutputSections) {
+      if (!verifyRanges(Sec->Chunks)) {
+        RangesOk = false;
+        break;
+      }
+      NumChunks += Sec->Chunks.size();
+    }
+    if (RangesOk) {
+      if (Pass > 0)
+        log("Added " + Twine(NumChunks - OrigNumChunks) + " thunks with " +
+            "margin " + Twine(Margin) + " in " + Twine(Pass) + " passes");
+      return;
+    }
+
+    if (Pass >= 10)
+      fatal("adding thunks hasn't converged after " + Twine(Pass) + " passes");
+
+    if (Pass > 0) {
+      // If the previous pass didn't work out, reset everything back to the
+      // original conditions before retrying with a wider margin. This should
+      // ideally never happen under real circumstances.
+      for (OutputSection *Sec : OutputSections) {
+        Sec->Chunks = Sec->OrigChunks;
+        for (Chunk *C : Sec->Chunks)
+          C->resetRelocTargets();
+      }
+      Margin *= 2;
+    }
+
+    // Try adding thunks everywhere where it is needed, with a margin
+    // to avoid things going out of range due to the added thunks.
+    bool AddressesChanged = false;
+    for (OutputSection *Sec : OutputSections)
+      AddressesChanged |= createThunks(Sec->Chunks, Margin);
+    // If the verification above thought we needed thunks, we should have
+    // added some.
+    assert(AddressesChanged);
+
+    // Recalculate the layout for the whole image (and verify the ranges at
+    // the start of the next round).
+    assignAddresses();
+
+    Pass++;
+  }
 }
 
 // The main function of the writer.
 void Writer::run() {
   ScopedTimer T1(CodeLayoutTimer);
 
+  createImportTables();
   createSections();
   createMiscChunks();
-  createImportTables();
+  appendImportThunks();
   createExportTable();
   mergeSections();
-  assignAddresses();
+  readRelocTargets();
+  finalizeAddresses();
   removeEmptySections();
   setSectionPermissions();
   createSymbolAndStringTable();
@@ -346,9 +509,6 @@
     fatal("image size (" + Twine(FileSize) + ") " +
         "exceeds maximum allowable size (" + Twine(UINT32_MAX) + ")");
 
-  // We must do this before opening the output file, as it depends on being able
-  // to read the contents of the existing output file.
-  PreviousBuildId = loadExistingBuildId(Config->OutputFile);
   openFile(Config->OutputFile);
   if (Config->is64()) {
     writeHeader<pe32plus_header>();
@@ -357,14 +517,14 @@
   }
   writeSections();
   sortExceptionTable();
-  writeBuildId();
 
   T1.stop();
 
   if (!Config->PDBPath.empty() && Config->Debug) {
     assert(BuildId);
-    createPDB(Symtab, OutputSections, SectionTable, *BuildId->BuildId);
+    createPDB(Symtab, OutputSections, SectionTable, BuildId->BuildId);
   }
+  writeBuildId();
 
   writeMapFile(OutputSections);
 
@@ -396,6 +556,110 @@
                    });
 }
 
+// Sort concrete section chunks from GNU import libraries.
+//
+// GNU binutils doesn't use short import files, but instead produces import
+// libraries that consist of object files, with section chunks for the .idata$*
+// sections. These are linked just as regular static libraries. Each import
+// library consists of one header object, one object file for every imported
+// symbol, and one trailer object. In order for the .idata tables/lists to
+// be formed correctly, the section chunks within each .idata$* section need
+// to be grouped by library, and sorted alphabetically within each library
+// (which makes sure the header comes first and the trailer last).
+static bool fixGnuImportChunks(
+    std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> &Map) {
+  uint32_t RDATA = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
+
+  // Make sure all .idata$* section chunks are mapped as RDATA in order to
+  // be sorted into the same sections as our own synthesized .idata chunks.
+  for (auto &Pair : Map) {
+    StringRef SectionName = Pair.first.first;
+    uint32_t OutChars = Pair.first.second;
+    if (!SectionName.startswith(".idata"))
+      continue;
+    if (OutChars == RDATA)
+      continue;
+    std::vector<Chunk *> &SrcVect = Pair.second;
+    std::vector<Chunk *> &DestVect = Map[{SectionName, RDATA}];
+    DestVect.insert(DestVect.end(), SrcVect.begin(), SrcVect.end());
+    SrcVect.clear();
+  }
+
+  bool HasIdata = false;
+  // Sort all .idata$* chunks, grouping chunks from the same library,
+  // with alphabetical ordering of the object fils within a library.
+  for (auto &Pair : Map) {
+    StringRef SectionName = Pair.first.first;
+    if (!SectionName.startswith(".idata"))
+      continue;
+
+    std::vector<Chunk *> &Chunks = Pair.second;
+    if (!Chunks.empty())
+      HasIdata = true;
+    std::stable_sort(Chunks.begin(), Chunks.end(), [&](Chunk *S, Chunk *T) {
+      SectionChunk *SC1 = dyn_cast_or_null<SectionChunk>(S);
+      SectionChunk *SC2 = dyn_cast_or_null<SectionChunk>(T);
+      if (!SC1 || !SC2) {
+        // if SC1, order them ascending. If SC2 or both null,
+        // S is not less than T.
+        return SC1 != nullptr;
+      }
+      // Make a string with "libraryname/objectfile" for sorting, achieving
+      // both grouping by library and sorting of objects within a library,
+      // at once.
+      std::string Key1 =
+          (SC1->File->ParentName + "/" + SC1->File->getName()).str();
+      std::string Key2 =
+          (SC2->File->ParentName + "/" + SC2->File->getName()).str();
+      return Key1 < Key2;
+    });
+  }
+  return HasIdata;
+}
+
+// Add generated idata chunks, for imported symbols and DLLs, and a
+// terminator in .idata$2.
+static void addSyntheticIdata(
+    IdataContents &Idata,
+    std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> &Map) {
+  uint32_t RDATA = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
+  Idata.create();
+
+  // Add the .idata content in the right section groups, to allow
+  // chunks from other linked in object files to be grouped together.
+  // See Microsoft PE/COFF spec 5.4 for details.
+  auto Add = [&](StringRef N, std::vector<Chunk *> &V) {
+    std::vector<Chunk *> &DestVect = Map[{N, RDATA}];
+    DestVect.insert(DestVect.end(), V.begin(), V.end());
+  };
+
+  // The loader assumes a specific order of data.
+  // Add each type in the correct order.
+  Add(".idata$2", Idata.Dirs);
+  Add(".idata$4", Idata.Lookups);
+  Add(".idata$5", Idata.Addresses);
+  Add(".idata$6", Idata.Hints);
+  Add(".idata$7", Idata.DLLNames);
+}
+
+// Locate the first Chunk and size of the import directory list and the
+// IAT.
+void Writer::locateImportTables(
+    std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> &Map) {
+  uint32_t RDATA = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
+  std::vector<Chunk *> &ImportTables = Map[{".idata$2", RDATA}];
+  if (!ImportTables.empty())
+    ImportTableStart = ImportTables.front();
+  for (Chunk *C : ImportTables)
+    ImportTableSize += C->getSize();
+
+  std::vector<Chunk *> &IAT = Map[{".idata$5", RDATA}];
+  if (!IAT.empty())
+    IATStart = IAT.front();
+  for (Chunk *C : IAT)
+    IATSize += C->getSize();
+}
+
 // Create output section objects and add them to OutputSections.
 void Writer::createSections() {
   // First, create the builtin sections.
@@ -429,12 +693,14 @@
   DidatSec = CreateSection(".didat", DATA | R);
   RsrcSec = CreateSection(".rsrc", DATA | R);
   RelocSec = CreateSection(".reloc", DATA | DISCARDABLE | R);
+  CtorsSec = CreateSection(".ctors", DATA | R | W);
+  DtorsSec = CreateSection(".dtors", DATA | R | W);
 
   // Then bin chunks by name and output characteristics.
   std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> Map;
   for (Chunk *C : Symtab->getChunks()) {
     auto *SC = dyn_cast<SectionChunk>(C);
-    if (SC && !SC->isLive()) {
+    if (SC && !SC->Live) {
       if (Config->Verbose)
         SC->printDiscardedMessage();
       continue;
@@ -442,26 +708,43 @@
     Map[{C->getSectionName(), C->getOutputCharacteristics()}].push_back(C);
   }
 
+  // Even in non MinGW cases, we might need to link against GNU import
+  // libraries.
+  bool HasIdata = fixGnuImportChunks(Map);
+  if (!Idata.empty())
+    HasIdata = true;
+
+  if (HasIdata)
+    addSyntheticIdata(Idata, Map);
+
   // Process an /order option.
   if (!Config->Order.empty())
     for (auto &Pair : Map)
       sortBySectionOrder(Pair.second);
 
+  if (HasIdata)
+    locateImportTables(Map);
+
   // Then create an OutputSection for each section.
   // '$' and all following characters in input section names are
   // discarded when determining output section. So, .text$foo
   // contributes to .text, for example. See PE/COFF spec 3.2.
-  for (auto Pair : Map) {
+  for (auto &Pair : Map) {
     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")
+    if (Name == ".CRT") {
+      // 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.
       OutChars = DATA | R;
 
+      log("Processing section " + Pair.first.first + " -> " + Name);
+
+      sortCRTSectionChunks(Pair.second);
+    }
+
     OutputSection *Sec = CreateSection(Name, OutChars);
     std::vector<Chunk *> &Chunks = Pair.second;
     for (Chunk *C : Chunks)
@@ -499,20 +782,20 @@
   }
 
   // Create Debug Information Chunks
+  OutputSection *DebugInfoSec = Config->MinGW ? BuildidSec : RdataSec;
+  if (Config->Debug || Config->Repro) {
+    DebugDirectory = make<DebugDirectoryChunk>(DebugRecords, Config->Repro);
+    DebugInfoSec->addChunk(DebugDirectory);
+  }
+
   if (Config->Debug) {
-    DebugDirectory = make<DebugDirectoryChunk>(DebugRecords);
-
-    OutputSection *DebugInfoSec = Config->MinGW ? BuildidSec : RdataSec;
-
     // Make a CVDebugRecordChunk even when /DEBUG:CV is not specified.  We
     // output a PDB no matter what, and this chunk provides the only means of
     // allowing a debugger to match a PDB and an executable.  So we need it even
     // if we're ultimately not going to write CodeView data to the PDB.
-    auto *CVChunk = make<CVDebugRecordChunk>();
-    BuildId = CVChunk;
-    DebugRecords.push_back(CVChunk);
+    BuildId = make<CVDebugRecordChunk>();
+    DebugRecords.push_back(BuildId);
 
-    DebugInfoSec->addChunk(DebugDirectory);
     for (Chunk *C : DebugRecords)
       DebugInfoSec->addChunk(C);
   }
@@ -524,6 +807,12 @@
   // Create /guard:cf tables if requested.
   if (Config->GuardCF != GuardCFLevel::Off)
     createGuardCFTables();
+
+  if (Config->MinGW) {
+    createRuntimePseudoRelocs();
+
+    insertCtorDtorSymbols();
+  }
 }
 
 // Create .idata section for the DLL-imported symbol table.
@@ -531,9 +820,6 @@
 // IdataContents class abstracted away the details for us,
 // so we just let it create chunks and add them to the section.
 void Writer::createImportTables() {
-  if (ImportFile::Instances.empty())
-    return;
-
   // Initialize DLLOrder so that import entries are ordered in
   // the same order as in the command line. (That affects DLL
   // initialization order, and this ordering is MSVC-compatible.)
@@ -545,14 +831,6 @@
     if (Config->DLLOrder.count(DLL) == 0)
       Config->DLLOrder[DLL] = Config->DLLOrder.size();
 
-    if (File->ThunkSym) {
-      if (!isa<DefinedImportThunk>(File->ThunkSym))
-        fatal(toString(*File->ThunkSym) + " was replaced");
-      DefinedImportThunk *Thunk = cast<DefinedImportThunk>(File->ThunkSym);
-      if (File->ThunkLive)
-        TextSec->addChunk(Thunk->getChunk());
-    }
-
     if (File->ImpSym && !isa<DefinedImportData>(File->ImpSym))
       fatal(toString(*File->ImpSym) + " was replaced");
     DefinedImportData *ImpSym = cast_or_null<DefinedImportData>(File->ImpSym);
@@ -565,10 +843,25 @@
       Idata.add(ImpSym);
     }
   }
+}
 
-  if (!Idata.empty())
-    for (Chunk *C : Idata.getChunks())
-      IdataSec->addChunk(C);
+void Writer::appendImportThunks() {
+  if (ImportFile::Instances.empty())
+    return;
+
+  for (ImportFile *File : ImportFile::Instances) {
+    if (!File->Live)
+      continue;
+
+    if (!File->ThunkSym)
+      continue;
+
+    if (!isa<DefinedImportThunk>(File->ThunkSym))
+      fatal(toString(*File->ThunkSym) + " was replaced");
+    DefinedImportThunk *Thunk = cast<DefinedImportThunk>(File->ThunkSym);
+    if (File->ThunkLive)
+      TextSec->addChunk(Thunk->getChunk());
+  }
 
   if (!DelayIdata.empty()) {
     Defined *Helper = cast<Defined>(Config->DelayLoadHelper);
@@ -699,9 +992,9 @@
 }
 
 void Writer::mergeSections() {
-  if (!PdataSec->getChunks().empty()) {
-    FirstPdata = PdataSec->getChunks().front();
-    LastPdata = PdataSec->getChunks().back();
+  if (!PdataSec->Chunks.empty()) {
+    FirstPdata = PdataSec->Chunks.front();
+    LastPdata = PdataSec->Chunks.back();
   }
 
   for (auto &P : Config->Merge) {
@@ -729,6 +1022,13 @@
   }
 }
 
+// Visits all sections to initialize their relocation targets.
+void Writer::readRelocTargets() {
+  for (OutputSection *Sec : OutputSections)
+    for_each(parallel::par, Sec->Chunks.begin(), Sec->Chunks.end(),
+             [&](Chunk *C) { C->readRelocTargets(); });
+}
+
 // Visits all sections to assign incremental, non-overlapping RVAs and
 // file offsets.
 void Writer::assignAddresses() {
@@ -746,7 +1046,7 @@
       addBaserels();
     uint64_t RawSize = 0, VirtualSize = 0;
     Sec->Header.VirtualAddress = RVA;
-    for (Chunk *C : Sec->getChunks()) {
+    for (Chunk *C : Sec->Chunks) {
       VirtualSize = alignTo(VirtualSize, C->Alignment);
       C->setRVA(RVA + VirtualSize);
       C->OutputSectionOff = VirtualSize;
@@ -880,11 +1180,13 @@
     Dir[EXPORT_TABLE].RelativeVirtualAddress = Edata.getRVA();
     Dir[EXPORT_TABLE].Size = Edata.getSize();
   }
-  if (!Idata.empty()) {
-    Dir[IMPORT_TABLE].RelativeVirtualAddress = Idata.getDirRVA();
-    Dir[IMPORT_TABLE].Size = Idata.getDirSize();
-    Dir[IAT].RelativeVirtualAddress = Idata.getIATRVA();
-    Dir[IAT].Size = Idata.getIATSize();
+  if (ImportTableStart) {
+    Dir[IMPORT_TABLE].RelativeVirtualAddress = ImportTableStart->getRVA();
+    Dir[IMPORT_TABLE].Size = ImportTableSize;
+  }
+  if (IATStart) {
+    Dir[IAT].RelativeVirtualAddress = IATStart->getRVA();
+    Dir[IAT].Size = IATSize;
   }
   if (RsrcSec->getVirtualSize()) {
     Dir[RESOURCE_TABLE].RelativeVirtualAddress = RsrcSec->getRVA();
@@ -907,7 +1209,7 @@
                                 : sizeof(object::coff_tls_directory32);
     }
   }
-  if (Config->Debug) {
+  if (DebugDirectory) {
     Dir[DEBUG_DIRECTORY].RelativeVirtualAddress = DebugDirectory->getRVA();
     Dir[DEBUG_DIRECTORY].Size = DebugDirectory->getSize();
   }
@@ -1010,7 +1312,7 @@
     // We only care about live section chunks. Common chunks and other chunks
     // don't generally contain relocations.
     SectionChunk *SC = dyn_cast<SectionChunk>(C);
-    if (!SC || !SC->isLive())
+    if (!SC || !SC->Live)
       continue;
 
     for (const coff_relocation &Reloc : SC->Relocs) {
@@ -1093,7 +1395,7 @@
     // is associated with something like a vtable and the vtable is discarded.
     // In this case, the associated gfids section is discarded, and we don't
     // mark the virtual member functions as address-taken by the vtable.
-    if (!C->isLive())
+    if (!C->Live)
       continue;
 
     // Validate that the contents look like symbol table indices.
@@ -1140,6 +1442,56 @@
   cast<DefinedAbsolute>(C)->setVA(TableChunk->getSize() / 4);
 }
 
+// MinGW specific. Gather all relocations that are imported from a DLL even
+// though the code didn't expect it to, produce the table that the runtime
+// uses for fixing them up, and provide the synthetic symbols that the
+// runtime uses for finding the table.
+void Writer::createRuntimePseudoRelocs() {
+  std::vector<RuntimePseudoReloc> Rels;
+
+  for (Chunk *C : Symtab->getChunks()) {
+    auto *SC = dyn_cast<SectionChunk>(C);
+    if (!SC || !SC->Live)
+      continue;
+    SC->getRuntimePseudoRelocs(Rels);
+  }
+
+  if (!Rels.empty())
+    log("Writing " + Twine(Rels.size()) + " runtime pseudo relocations");
+  PseudoRelocTableChunk *Table = make<PseudoRelocTableChunk>(Rels);
+  RdataSec->addChunk(Table);
+  EmptyChunk *EndOfList = make<EmptyChunk>();
+  RdataSec->addChunk(EndOfList);
+
+  Symbol *HeadSym = Symtab->findUnderscore("__RUNTIME_PSEUDO_RELOC_LIST__");
+  Symbol *EndSym = Symtab->findUnderscore("__RUNTIME_PSEUDO_RELOC_LIST_END__");
+  replaceSymbol<DefinedSynthetic>(HeadSym, HeadSym->getName(), Table);
+  replaceSymbol<DefinedSynthetic>(EndSym, EndSym->getName(), EndOfList);
+}
+
+// MinGW specific.
+// The MinGW .ctors and .dtors lists have sentinels at each end;
+// a (uintptr_t)-1 at the start and a (uintptr_t)0 at the end.
+// There's a symbol pointing to the start sentinel pointer, __CTOR_LIST__
+// and __DTOR_LIST__ respectively.
+void Writer::insertCtorDtorSymbols() {
+  AbsolutePointerChunk *CtorListHead = make<AbsolutePointerChunk>(-1);
+  AbsolutePointerChunk *CtorListEnd = make<AbsolutePointerChunk>(0);
+  AbsolutePointerChunk *DtorListHead = make<AbsolutePointerChunk>(-1);
+  AbsolutePointerChunk *DtorListEnd = make<AbsolutePointerChunk>(0);
+  CtorsSec->insertChunkAtStart(CtorListHead);
+  CtorsSec->addChunk(CtorListEnd);
+  DtorsSec->insertChunkAtStart(DtorListHead);
+  DtorsSec->addChunk(DtorListEnd);
+
+  Symbol *CtorListSym = Symtab->findUnderscore("__CTOR_LIST__");
+  Symbol *DtorListSym = Symtab->findUnderscore("__DTOR_LIST__");
+  replaceSymbol<DefinedSynthetic>(CtorListSym, CtorListSym->getName(),
+                                  CtorListHead);
+  replaceSymbol<DefinedSynthetic>(DtorListSym, DtorListSym->getName(),
+                                  DtorListHead);
+}
+
 // Handles /section options to allow users to overwrite
 // section attributes.
 void Writer::setSectionPermissions() {
@@ -1166,7 +1518,7 @@
     // ADD instructions).
     if (Sec->Header.Characteristics & IMAGE_SCN_CNT_CODE)
       memset(SecBuf, 0xCC, Sec->getRawSize());
-    for_each(parallel::par, Sec->getChunks().begin(), Sec->getChunks().end(),
+    for_each(parallel::par, Sec->Chunks.begin(), Sec->Chunks.end(),
              [&](Chunk *C) { C->writeTo(SecBuf); });
   }
 }
@@ -1177,25 +1529,10 @@
   //    timestamp as well as a Guid and Age of the PDB.
   // 2) In all cases, the PE COFF file header also contains a timestamp.
   // For reproducibility, instead of a timestamp we want to use a hash of the
-  // binary, however when building with debug info the hash needs to take into
-  // account the debug info, since it's possible to add blank lines to a file
-  // which causes the debug info to change but not the generated code.
-  //
-  // To handle this, we first set the Guid and Age in the debug directory (but
-  // only if we're doing a debug build).  Then, we hash the binary (thus causing
-  // the hash to change if only the debug info changes, since the Age will be
-  // different).  Finally, we write that hash into the debug directory (if
-  // present) as well as the COFF file header (always).
+  // PE contents.
   if (Config->Debug) {
     assert(BuildId && "BuildId is not set!");
-    if (PreviousBuildId.hasValue()) {
-      *BuildId->BuildId = *PreviousBuildId;
-      BuildId->BuildId->PDB70.Age = BuildId->BuildId->PDB70.Age + 1;
-    } else {
-      BuildId->BuildId->Signature.CVSignature = OMF::Signature::PDB70;
-      BuildId->BuildId->PDB70.Age = 1;
-      llvm::getRandomBytes(BuildId->BuildId->PDB70.Signature, 16);
-    }
+    // BuildId->BuildId was filled in when the PDB was written.
   }
 
   // At this point the only fields in the COFF file which remain unset are the
@@ -1246,6 +1583,42 @@
   errs() << "warning: don't know how to handle .pdata.\n";
 }
 
+// The CRT section contains, among other things, the array of function
+// pointers that initialize every global variable that is not trivially
+// constructed. The CRT calls them one after the other prior to invoking
+// main().
+//
+// As per C++ spec, 3.6.2/2.3,
+// "Variables with ordered initialization defined within a single
+// translation unit shall be initialized in the order of their definitions
+// in the translation unit"
+//
+// It is therefore critical to sort the chunks containing the function
+// pointers in the order that they are listed in the object file (top to
+// bottom), otherwise global objects might not be initialized in the
+// correct order.
+void Writer::sortCRTSectionChunks(std::vector<Chunk *> &Chunks) {
+  auto SectionChunkOrder = [](const Chunk *A, const Chunk *B) {
+    auto SA = dyn_cast<SectionChunk>(A);
+    auto SB = dyn_cast<SectionChunk>(B);
+    assert(SA && SB && "Non-section chunks in CRT section!");
+
+    StringRef SAObj = SA->File->MB.getBufferIdentifier();
+    StringRef SBObj = SB->File->MB.getBufferIdentifier();
+
+    return SAObj == SBObj && SA->getSectionNumber() < SB->getSectionNumber();
+  };
+  std::stable_sort(Chunks.begin(), Chunks.end(), SectionChunkOrder);
+
+  if (Config->Verbose) {
+    for (auto &C : Chunks) {
+      auto SC = dyn_cast<SectionChunk>(C);
+      log("  " + SC->File->MB.getBufferIdentifier().str() +
+          ", SectionID: " + Twine(SC->getSectionNumber()));
+    }
+  }
+}
+
 OutputSection *Writer::findSection(StringRef Name) {
   for (OutputSection *Sec : OutputSections)
     if (Sec->Name == Name)
@@ -1265,12 +1638,13 @@
 void Writer::addBaserels() {
   if (!Config->Relocatable)
     return;
+  RelocSec->Chunks.clear();
   std::vector<Baserel> V;
   for (OutputSection *Sec : OutputSections) {
     if (Sec->Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
       continue;
     // Collect all locations for base relocations.
-    for (Chunk *C : Sec->getChunks())
+    for (Chunk *C : Sec->Chunks)
       C->getBaserels(&V);
     // Add the addresses to .reloc section.
     if (!V.empty())
diff --git a/COFF/Writer.h b/COFF/Writer.h
index d37276c..7275824 100644
--- a/COFF/Writer.h
+++ b/COFF/Writer.h
@@ -34,8 +34,8 @@
     Header.Characteristics = Chars;
   }
   void addChunk(Chunk *C);
+  void insertChunkAtStart(Chunk *C);
   void merge(OutputSection *Other);
-  ArrayRef<Chunk *> getChunks() { return Chunks; }
   void addPermissions(uint32_t C);
   void setPermissions(uint32_t C);
   uint64_t getRVA() { return Header.VirtualAddress; }
@@ -62,9 +62,11 @@
   llvm::StringRef Name;
   llvm::object::coff_section Header = {};
 
+  std::vector<Chunk *> Chunks;
+  std::vector<Chunk *> OrigChunks;
+
 private:
   uint32_t StringTableOff = 0;
-  std::vector<Chunk *> Chunks;
 };
 
 }
diff --git a/Common/Args.cpp b/Common/Args.cpp
index ff77bfc..3f0671d 100644
--- a/Common/Args.cpp
+++ b/Common/Args.cpp
@@ -13,6 +13,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Option/ArgList.h"
+#include "llvm/Support/Path.h"
 
 using namespace llvm;
 using namespace lld;
@@ -40,7 +41,7 @@
 
 uint64_t lld::args::getZOptionValue(opt::InputArgList &Args, int Id,
                                     StringRef Key, uint64_t Default) {
-  for (auto *Arg : Args.filtered(Id)) {
+  for (auto *Arg : Args.filtered_reverse(Id)) {
     std::pair<StringRef, StringRef> KV = StringRef(Arg->getValue()).split('=');
     if (KV.first == Key) {
       uint64_t Result = Default;
@@ -64,3 +65,9 @@
   }
   return Ret;
 }
+
+StringRef lld::args::getFilenameWithoutExe(StringRef Path) {
+  if (Path.endswith_lower(".exe"))
+    return sys::path::stem(Path);
+  return sys::path::filename(Path);
+}
diff --git a/Common/ErrorHandler.cpp b/Common/ErrorHandler.cpp
index d1cb3db..c059516 100644
--- a/Common/ErrorHandler.cpp
+++ b/Common/ErrorHandler.cpp
@@ -47,8 +47,9 @@
 }
 
 void lld::exitLld(int Val) {
-  // Delete the output buffer so that any tempory file is deleted.
-  errorHandler().OutputBuffer.reset();
+  // Delete any temporary file, while keeping the memory mapping open.
+  if (errorHandler().OutputBuffer)
+    errorHandler().OutputBuffer->discard();
 
   // Dealloc/destroy ManagedStatic variables before calling
   // _exit(). In a non-LTO build, this is a nop. In an LTO
diff --git a/Common/Strings.cpp b/Common/Strings.cpp
index 36f4f77..6f74865 100644
--- a/Common/Strings.cpp
+++ b/Common/Strings.cpp
@@ -16,14 +16,6 @@
 #include <mutex>
 #include <vector>
 
-#if defined(_MSC_VER)
-#include <Windows.h>
-
-// DbgHelp.h must be included after Windows.h.
-#include <DbgHelp.h>
-#pragma comment(lib, "dbghelp.lib")
-#endif
-
 using namespace llvm;
 using namespace lld;
 
@@ -45,18 +37,21 @@
   return S;
 }
 
-Optional<std::string> lld::demangleMSVC(StringRef S) {
-#if defined(_MSC_VER)
-  // UnDecorateSymbolName is not thread-safe, so we need a mutex.
-  static std::mutex Mu;
-  std::lock_guard<std::mutex> Lock(Mu);
+Optional<std::string> lld::demangleMSVC(StringRef Name) {
+  std::string Prefix;
+  if (Name.consume_front("__imp_"))
+    Prefix = "__declspec(dllimport) ";
 
-  char Buf[4096];
-  if (S.startswith("?"))
-    if (size_t Len = UnDecorateSymbolName(S.str().c_str(), Buf, sizeof(Buf), 0))
-      return std::string(Buf, Len);
-#endif
-  return None;
+  // Demangle only C++ names.
+  if (!Name.startswith("?"))
+    return None;
+
+  char *Buf = microsoftDemangle(Name.str().c_str(), nullptr, nullptr, nullptr);
+  if (!Buf)
+    return None;
+  std::string S(Buf);
+  free(Buf);
+  return Prefix + S;
 }
 
 StringMatcher::StringMatcher(ArrayRef<StringRef> Pat) {
diff --git a/ELF/AArch64ErrataFix.cpp b/ELF/AArch64ErrataFix.cpp
index 7551919..db83129 100644
--- a/ELF/AArch64ErrataFix.cpp
+++ b/ELF/AArch64ErrataFix.cpp
@@ -356,7 +356,7 @@
   }
 
   uint64_t PatchOff = 0;
-  const uint8_t *Buf = IS->Data.begin();
+  const uint8_t *Buf = IS->data().begin();
   const ulittle32_t *InstBuf = reinterpret_cast<const ulittle32_t *>(Buf + Off);
   uint32_t Instr1 = *InstBuf++;
   uint32_t Instr2 = *InstBuf++;
@@ -411,7 +411,7 @@
 void lld::elf::Patch843419Section::writeTo(uint8_t *Buf) {
   // Copy the instruction that we will be replacing with a branch in the
   // Patchee Section.
-  write32le(Buf, read32le(Patchee->Data.begin() + PatcheeOffset));
+  write32le(Buf, read32le(Patchee->data().begin() + PatcheeOffset));
 
   // Apply any relocation transferred from the original PatcheeSection.
   // For a SyntheticSection Buf already has OutSecOff added, but relocateAlloc
@@ -451,7 +451,7 @@
         continue;
       if (!IsCodeMapSymbol(Def) && !IsDataMapSymbol(Def))
         continue;
-      if (auto *Sec = dyn_cast<InputSection>(Def->Section))
+      if (auto *Sec = dyn_cast_or_null<InputSection>(Def->Section))
         if (Sec->Flags & SHF_EXECINSTR)
           SectionMap[Sec].push_back(Def);
     }
@@ -487,7 +487,7 @@
     InputSectionDescription &ISD, std::vector<Patch843419Section *> &Patches) {
   uint64_t ISLimit;
   uint64_t PrevISLimit = ISD.Sections.front()->OutSecOff;
-  uint64_t PatchUpperBound = PrevISLimit + Target->ThunkSectionSpacing;
+  uint64_t PatchUpperBound = PrevISLimit + Target->getThunkSectionSpacing();
 
   // Set the OutSecOff of patches to the place where we want to insert them.
   // We use a similar strategy to Thunk placement. Place patches roughly
@@ -503,7 +503,7 @@
         (*PatchIt)->OutSecOff = PrevISLimit;
         ++PatchIt;
       }
-      PatchUpperBound = PrevISLimit + Target->ThunkSectionSpacing;
+      PatchUpperBound = PrevISLimit + Target->getThunkSectionSpacing();
     }
     PrevISLimit = ISLimit;
   }
@@ -598,7 +598,7 @@
       auto DataSym = std::next(CodeSym);
       uint64_t Off = (*CodeSym)->Value;
       uint64_t Limit =
-          (DataSym == MapSyms.end()) ? IS->Data.size() : (*DataSym)->Value;
+          (DataSym == MapSyms.end()) ? IS->data().size() : (*DataSym)->Value;
 
       while (Off < Limit) {
         uint64_t StartAddr = IS->getVA(Off);
diff --git a/ELF/Arch/AArch64.cpp b/ELF/Arch/AArch64.cpp
index c7b3c08..be77109 100644
--- a/ELF/Arch/AArch64.cpp
+++ b/ELF/Arch/AArch64.cpp
@@ -41,6 +41,7 @@
                 int32_t Index, unsigned RelOff) const override;
   bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
                   uint64_t BranchAddr, const Symbol &S) const override;
+  uint32_t getThunkSectionSpacing() const override;
   bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
   bool usesOnlyLowPageBits(RelType Type) const override;
   void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
@@ -57,6 +58,7 @@
   RelativeRel = R_AARCH64_RELATIVE;
   IRelativeRel = R_AARCH64_IRELATIVE;
   GotRel = R_AARCH64_GLOB_DAT;
+  NoneRel = R_AARCH64_NONE;
   PltRel = R_AARCH64_JUMP_SLOT;
   TlsDescRel = R_AARCH64_TLSDESC;
   TlsGotRel = R_AARCH64_TLS_TPREL64;
@@ -66,15 +68,14 @@
   PltHeaderSize = 32;
   DefaultMaxPageSize = 65536;
 
+  // Align to the 2 MiB page size (known as a superpage or huge page).
+  // FreeBSD automatically promotes 2 MiB-aligned allocations.
+  DefaultImageBase = 0x200000;
+
   // It doesn't seem to be documented anywhere, but tls on aarch64 uses variant
   // 1 of the tls structures and the tcb size is 16.
   TcbSize = 16;
   NeedsThunks = true;
-
-  // See comment in Arch/ARM.cpp for a more detailed explanation of
-  // ThunkSectionSpacing. For AArch64 the only branches we are permitted to
-  // Thunk have a range of +/- 128 MiB
-  ThunkSectionSpacing = (128 * 1024 * 1024) - 0x30000;
 }
 
 RelExpr AArch64::getRelExpr(RelType Type, const Symbol &S,
@@ -156,7 +157,7 @@
 }
 
 void AArch64::writeGotPlt(uint8_t *Buf, const Symbol &) const {
-  write64le(Buf, InX::Plt->getVA());
+  write64le(Buf, In.Plt->getVA());
 }
 
 void AArch64::writePltHeader(uint8_t *Buf) const {
@@ -172,8 +173,8 @@
   };
   memcpy(Buf, PltData, sizeof(PltData));
 
-  uint64_t Got = InX::GotPlt->getVA();
-  uint64_t Plt = InX::Plt->getVA();
+  uint64_t Got = In.GotPlt->getVA();
+  uint64_t Plt = In.Plt->getVA();
   relocateOne(Buf + 4, R_AARCH64_ADR_PREL_PG_HI21,
               getAArch64Page(Got + 16) - getAArch64Page(Plt + 4));
   relocateOne(Buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, Got + 16);
@@ -208,6 +209,13 @@
   return !inBranchRange(Type, BranchAddr, Dst);
 }
 
+uint32_t AArch64::getThunkSectionSpacing() const {
+  // See comment in Arch/ARM.cpp for a more detailed explanation of
+  // getThunkSectionSpacing(). For AArch64 the only branches we are permitted to
+  // Thunk have a range of +/- 128 MiB
+  return (128 * 1024 * 1024) - 0x30000;
+}
+
 bool AArch64::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
   if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26)
     return true;
@@ -338,7 +346,7 @@
     or32le(Loc, (Val & 0xFFFC) << 3);
     break;
   case R_AARCH64_TLSLE_ADD_TPREL_HI12:
-    checkInt(Loc, Val, 24, Type);
+    checkUInt(Loc, Val, 24, Type);
     or32AArch64Imm(Loc, Val >> 12);
     break;
   case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
diff --git a/ELF/Arch/AMDGPU.cpp b/ELF/Arch/AMDGPU.cpp
index 48b27f2..a7c6c84 100644
--- a/ELF/Arch/AMDGPU.cpp
+++ b/ELF/Arch/AMDGPU.cpp
@@ -35,6 +35,7 @@
 AMDGPU::AMDGPU() {
   RelativeRel = R_AMDGPU_RELATIVE64;
   GotRel = R_AMDGPU_ABS64;
+  NoneRel = R_AMDGPU_NONE;
   GotEntrySize = 8;
 }
 
diff --git a/ELF/Arch/ARM.cpp b/ELF/Arch/ARM.cpp
index acf9a61..13a04fe 100644
--- a/ELF/Arch/ARM.cpp
+++ b/ELF/Arch/ARM.cpp
@@ -40,6 +40,7 @@
   void addPltHeaderSymbols(InputSection &ISD) const override;
   bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
                   uint64_t BranchAddr, const Symbol &S) const override;
+  uint32_t getThunkSectionSpacing() const override;
   bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
   void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
 };
@@ -50,6 +51,7 @@
   RelativeRel = R_ARM_RELATIVE;
   IRelativeRel = R_ARM_IRELATIVE;
   GotRel = R_ARM_GLOB_DAT;
+  NoneRel = R_ARM_NONE;
   PltRel = R_ARM_JUMP_SLOT;
   TlsGotRel = R_ARM_TLS_TPOFF32;
   TlsModuleIndexRel = R_ARM_TLS_DTPMOD32;
@@ -63,37 +65,6 @@
   // ARM uses Variant 1 TLS
   TcbSize = 8;
   NeedsThunks = true;
-
-  // The placing of pre-created ThunkSections is controlled by the
-  // ThunkSectionSpacing parameter. The aim is to place the
-  // ThunkSection such that all branches from the InputSections prior to the
-  // ThunkSection can reach a Thunk placed at the end of the ThunkSection.
-  // Graphically:
-  // | up to ThunkSectionSpacing .text input sections |
-  // | ThunkSection                                   |
-  // | up to ThunkSectionSpacing .text input sections |
-  // | ThunkSection                                   |
-
-  // Pre-created ThunkSections are spaced roughly 16MiB apart on ARM. This is to
-  // match the most common expected case of a Thumb 2 encoded BL, BLX or B.W
-  // ARM B, BL, BLX range +/- 32MiB
-  // Thumb B.W, BL, BLX range +/- 16MiB
-  // Thumb B<cc>.W range +/- 1MiB
-  // If a branch cannot reach a pre-created ThunkSection a new one will be
-  // created so we can handle the rare cases of a Thumb 2 conditional branch.
-  // We intentionally use a lower size for ThunkSectionSpacing than the maximum
-  // branch range so the end of the ThunkSection is more likely to be within
-  // range of the branch instruction that is furthest away. The value we shorten
-  // ThunkSectionSpacing by is set conservatively to allow us to create 16,384
-  // 12 byte Thunks at any offset in a ThunkSection without risk of a branch to
-  // one of the Thunks going out of range.
-
-  // FIXME: lld assumes that the Thumb BL and BLX encoding permits the J1 and
-  // J2 bits to be used to extend the branch range. On earlier Architectures
-  // such as ARMv4, ARMv5 and ARMv6 (except ARMv6T2) the range is +/- 4MiB. If
-  // support for the earlier encodings is added then when they are used the
-  // ThunkSectionSpacing will need lowering.
-  ThunkSectionSpacing = 0x1000000 - 0x30000;
 }
 
 uint32_t ARM::calcEFlags() const {
@@ -177,7 +148,7 @@
 }
 
 void ARM::writeGotPlt(uint8_t *Buf, const Symbol &) const {
-  write32le(Buf, InX::Plt->getVA());
+  write32le(Buf, In.Plt->getVA());
 }
 
 void ARM::writeIgotPlt(uint8_t *Buf, const Symbol &S) const {
@@ -198,8 +169,8 @@
       0xd4, 0xd4, 0xd4, 0xd4, //     Pad to 32-byte boundary
       0xd4, 0xd4, 0xd4, 0xd4};
   memcpy(Buf, PltData, sizeof(PltData));
-  uint64_t GotPlt = InX::GotPlt->getVA();
-  uint64_t L1 = InX::Plt->getVA() + 8;
+  uint64_t GotPlt = In.GotPlt->getVA();
+  uint64_t L1 = In.Plt->getVA() + 8;
   write32le(Buf + 16, GotPlt - L1 - 8);
 }
 
@@ -217,7 +188,7 @@
       0xe5bef000, //     ldr pc, [lr, #0x00000NNN] &(.got.plt -L1 - 4)
   };
 
-  uint64_t Offset = InX::GotPlt->getVA() - InX::Plt->getVA() - 4;
+  uint64_t Offset = In.GotPlt->getVA() - In.Plt->getVA() - 4;
   if (!llvm::isUInt<27>(Offset)) {
     // We cannot encode the Offset, use the long form.
     writePltHeaderLong(Buf);
@@ -324,6 +295,40 @@
   return false;
 }
 
+uint32_t ARM::getThunkSectionSpacing() const {
+  // The placing of pre-created ThunkSections is controlled by the value
+  // ThunkSectionSpacing returned by getThunkSectionSpacing(). The aim is to
+  // place the ThunkSection such that all branches from the InputSections
+  // prior to the ThunkSection can reach a Thunk placed at the end of the
+  // ThunkSection. Graphically:
+  // | up to ThunkSectionSpacing .text input sections |
+  // | ThunkSection                                   |
+  // | up to ThunkSectionSpacing .text input sections |
+  // | ThunkSection                                   |
+
+  // Pre-created ThunkSections are spaced roughly 16MiB apart on ARMv7. This
+  // is to match the most common expected case of a Thumb 2 encoded BL, BLX or
+  // B.W:
+  // ARM B, BL, BLX range +/- 32MiB
+  // Thumb B.W, BL, BLX range +/- 16MiB
+  // Thumb B<cc>.W range +/- 1MiB
+  // If a branch cannot reach a pre-created ThunkSection a new one will be
+  // created so we can handle the rare cases of a Thumb 2 conditional branch.
+  // We intentionally use a lower size for ThunkSectionSpacing than the maximum
+  // branch range so the end of the ThunkSection is more likely to be within
+  // range of the branch instruction that is furthest away. The value we shorten
+  // ThunkSectionSpacing by is set conservatively to allow us to create 16,384
+  // 12 byte Thunks at any offset in a ThunkSection without risk of a branch to
+  // one of the Thunks going out of range.
+
+  // On Arm the ThunkSectionSpacing depends on the range of the Thumb Branch
+  // range. On earlier Architectures such as ARMv4, ARMv5 and ARMv6 (except
+  // ARMv6T2) the range is +/- 4MiB.
+
+  return (Config->ARMJ1J2BranchEncoding) ? 0x1000000 - 0x30000
+                                         : 0x400000 - 0x7500;
+}
+
 bool ARM::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
   uint64_t Range;
   uint64_t InstrSize;
@@ -342,7 +347,7 @@
     break;
   case R_ARM_THM_JUMP24:
   case R_ARM_THM_CALL:
-    Range = 0x1000000;
+    Range = Config->ARMJ1J2BranchEncoding ? 0x1000000 : 0x400000;
     InstrSize = 2;
     break;
   default:
@@ -447,11 +452,23 @@
     }
     // Bit 12 is 0 for BLX, 1 for BL
     write16le(Loc + 2, (read16le(Loc + 2) & ~0x1000) | (Val & 1) << 12);
+    if (!Config->ARMJ1J2BranchEncoding) {
+      // Older Arm architectures do not support R_ARM_THM_JUMP24 and have
+      // different encoding rules and range due to J1 and J2 always being 1.
+      checkInt(Loc, Val, 23, Type);
+      write16le(Loc,
+                0xf000 |                     // opcode
+                    ((Val >> 12) & 0x07ff)); // imm11
+      write16le(Loc + 2,
+                (read16le(Loc + 2) & 0xd000) | // opcode
+                    0x2800 |                   // J1 == J2 == 1
+                    ((Val >> 1) & 0x07ff));    // imm11
+      break;
+    }
     // Fall through as rest of encoding is the same as B.W
     LLVM_FALLTHROUGH;
   case R_ARM_THM_JUMP24:
     // Encoding B  T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0
-    // FIXME: Use of I1 and I2 require v6T2ops
     checkInt(Loc, Val, 25, Type);
     write16le(Loc,
               0xf000 |                     // opcode
@@ -542,10 +559,19 @@
                             ((Lo & 0x07ff) << 1));  // imm11:0
   }
   case R_ARM_THM_CALL:
+    if (!Config->ARMJ1J2BranchEncoding) {
+      // Older Arm architectures do not support R_ARM_THM_JUMP24 and have
+      // different encoding rules and range due to J1 and J2 always being 1.
+      uint16_t Hi = read16le(Buf);
+      uint16_t Lo = read16le(Buf + 2);
+      return SignExtend64<22>(((Hi & 0x7ff) << 12) | // imm11
+                              ((Lo & 0x7ff) << 1));  // imm11:0
+      break;
+    }
+    LLVM_FALLTHROUGH;
   case R_ARM_THM_JUMP24: {
     // Encoding B T4, BL T1, BLX T2: A = S:I1:I2:imm10:imm11:0
     // I1 = NOT(J1 EOR S), I2 = NOT(J2 EOR S)
-    // FIXME: I1 and I2 require v6T2ops
     uint16_t Hi = read16le(Buf);
     uint16_t Lo = read16le(Buf + 2);
     return SignExtend64<24>(((Hi & 0x0400) << 14) |                    // S
diff --git a/ELF/Arch/AVR.cpp b/ELF/Arch/AVR.cpp
index 02ac770..637da37 100644
--- a/ELF/Arch/AVR.cpp
+++ b/ELF/Arch/AVR.cpp
@@ -43,12 +43,15 @@
 namespace {
 class AVR final : public TargetInfo {
 public:
+  AVR();
   RelExpr getRelExpr(RelType Type, const Symbol &S,
                      const uint8_t *Loc) const override;
   void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
 };
 } // namespace
 
+AVR::AVR() { NoneRel = R_AVR_NONE; }
+
 RelExpr AVR::getRelExpr(RelType Type, const Symbol &S,
                         const uint8_t *Loc) const {
   return R_ABS;
diff --git a/ELF/Arch/Hexagon.cpp b/ELF/Arch/Hexagon.cpp
index c3c4aba..19bfa3e 100644
--- a/ELF/Arch/Hexagon.cpp
+++ b/ELF/Arch/Hexagon.cpp
@@ -9,6 +9,7 @@
 
 #include "InputFiles.h"
 #include "Symbols.h"
+#include "SyntheticSections.h"
 #include "Target.h"
 #include "lld/Common/ErrorHandler.h"
 #include "llvm/BinaryFormat/ELF.h"
@@ -25,13 +26,35 @@
 namespace {
 class Hexagon final : public TargetInfo {
 public:
+  Hexagon();
   uint32_t calcEFlags() const override;
   RelExpr getRelExpr(RelType Type, const Symbol &S,
                      const uint8_t *Loc) const override;
   void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
+  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;
 };
 } // namespace
 
+Hexagon::Hexagon() {
+  PltRel = R_HEX_JMP_SLOT;
+  RelativeRel = R_HEX_RELATIVE;
+  GotRel = R_HEX_GLOB_DAT;
+  GotEntrySize = 4;
+  // The zero'th GOT entry is reserved for the address of _DYNAMIC.  The
+  // next 3 are reserved for the dynamic loader.
+  GotPltHeaderEntriesNum = 4;
+  GotPltEntrySize = 4;
+
+  PltEntrySize = 16;
+  PltHeaderSize = 32;
+
+  // Hexagon Linux uses 64K pages by default.
+  DefaultMaxPageSize = 0x10000;
+  NoneRel = R_HEX_NONE;
+}
+
 // Support V60 only at the moment.
 uint32_t Hexagon::calcEFlags() const { return 0x60; }
 
@@ -53,13 +76,23 @@
 RelExpr Hexagon::getRelExpr(RelType Type, const Symbol &S,
                             const uint8_t *Loc) const {
   switch (Type) {
+  case R_HEX_B9_PCREL:
+  case R_HEX_B9_PCREL_X:
+  case R_HEX_B13_PCREL:
   case R_HEX_B15_PCREL:
   case R_HEX_B15_PCREL_X:
+  case R_HEX_6_PCREL_X:
+  case R_HEX_32_PCREL:
+    return R_PC;
   case R_HEX_B22_PCREL:
+  case R_HEX_PLT_B22_PCREL:
   case R_HEX_B22_PCREL_X:
   case R_HEX_B32_PCREL_X:
-  case R_HEX_6_PCREL_X:
-    return R_PC;
+    return R_PLT_PC;
+  case R_HEX_GOT_11_X:
+  case R_HEX_GOT_16_X:
+  case R_HEX_GOT_32_6_X:
+    return R_HEXAGON_GOT;
   default:
     return R_ABS;
   }
@@ -104,6 +137,35 @@
   return 0;
 }
 
+static uint32_t findMaskR8(uint32_t Insn) {
+  if ((0xff000000 & Insn) == 0xde000000)
+    return 0x00e020e8;
+  if ((0xff000000 & Insn) == 0x3c000000)
+    return 0x0000207f;
+  return 0x00001fe0;
+}
+
+static uint32_t findMaskR11(uint32_t Insn) {
+  if ((0xff000000 & Insn) == 0xa1000000)
+    return 0x060020ff;
+  return 0x06003fe0;
+}
+
+static uint32_t findMaskR16(uint32_t Insn) {
+  if ((0xff000000 & Insn) == 0x48000000)
+    return 0x061f20ff;
+  if ((0xff000000 & Insn) == 0x49000000)
+    return 0x061f3fe0;
+  if ((0xff000000 & Insn) == 0x78000000)
+    return 0x00df3fe0;
+  if ((0xff000000 & Insn) == 0xb0000000)
+    return 0x0fe03fe0;
+
+  error("unrecognized instruction for R_HEX_16_X relocation: 0x" +
+        utohexstr(Insn));
+  return 0;
+}
+
 static void or32le(uint8_t *P, int32_t V) { write32le(P, read32le(P) | V); }
 
 void Hexagon::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
@@ -114,12 +176,43 @@
   case R_HEX_6_X:
     or32le(Loc, applyMask(findMaskR6(read32le(Loc)), Val));
     break;
+  case R_HEX_8_X:
+    or32le(Loc, applyMask(findMaskR8(read32le(Loc)), Val));
+    break;
+  case R_HEX_9_X:
+    or32le(Loc, applyMask(0x00003fe0, Val & 0x3f));
+    break;
+  case R_HEX_10_X:
+    or32le(Loc, applyMask(0x00203fe0, Val & 0x3f));
+    break;
+  case R_HEX_11_X:
+  case R_HEX_GOT_11_X:
+    or32le(Loc, applyMask(findMaskR11(read32le(Loc)), Val & 0x3f));
+    break;
   case R_HEX_12_X:
     or32le(Loc, applyMask(0x000007e0, Val));
     break;
+  case R_HEX_16_X: // These relocs only have 6 effective bits.
+  case R_HEX_GOT_16_X:
+    or32le(Loc, applyMask(findMaskR16(read32le(Loc)), Val & 0x3f));
+    break;
+  case R_HEX_32:
+  case R_HEX_32_PCREL:
+    or32le(Loc, Val);
+    break;
   case R_HEX_32_6_X:
+  case R_HEX_GOT_32_6_X:
     or32le(Loc, applyMask(0x0fff3fff, Val >> 6));
     break;
+  case R_HEX_B9_PCREL:
+    or32le(Loc, applyMask(0x003000fe, Val >> 2));
+    break;
+  case R_HEX_B9_PCREL_X:
+    or32le(Loc, applyMask(0x003000fe, Val & 0x3f));
+    break;
+  case R_HEX_B13_PCREL:
+    or32le(Loc, applyMask(0x00202ffe, Val >> 2));
+    break;
   case R_HEX_B15_PCREL:
     or32le(Loc, applyMask(0x00df20fe, Val >> 2));
     break;
@@ -127,6 +220,7 @@
     or32le(Loc, applyMask(0x00df20fe, Val & 0x3f));
     break;
   case R_HEX_B22_PCREL:
+  case R_HEX_PLT_B22_PCREL:
     or32le(Loc, applyMask(0x1ff3ffe, Val >> 2));
     break;
   case R_HEX_B22_PCREL_X:
@@ -147,6 +241,40 @@
   }
 }
 
+void Hexagon::writePltHeader(uint8_t *Buf) const {
+  const uint8_t PltData[] = {
+      0x00, 0x40, 0x00, 0x00, // { immext (#0)
+      0x1c, 0xc0, 0x49, 0x6a, //   r28 = add (pc, ##GOT0@PCREL) } # @GOT0
+      0x0e, 0x42, 0x9c, 0xe2, // { r14 -= add (r28, #16)  # offset of GOTn
+      0x4f, 0x40, 0x9c, 0x91, //   r15 = memw (r28 + #8)  # object ID at GOT2
+      0x3c, 0xc0, 0x9c, 0x91, //   r28 = memw (r28 + #4) }# dynamic link at GOT1
+      0x0e, 0x42, 0x0e, 0x8c, // { r14 = asr (r14, #2)    # index of PLTn
+      0x00, 0xc0, 0x9c, 0x52, //   jumpr r28 }            # call dynamic linker
+      0x0c, 0xdb, 0x00, 0x54, // trap0(#0xdb) # bring plt0 into 16byte alignment
+  };
+  memcpy(Buf, PltData, sizeof(PltData));
+
+  // Offset from PLT0 to the GOT.
+  uint64_t Off = In.GotPlt->getVA() - In.Plt->getVA();
+  relocateOne(Buf, R_HEX_B32_PCREL_X, Off);
+  relocateOne(Buf + 4, R_HEX_6_PCREL_X, Off);
+}
+
+void Hexagon::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
+                       uint64_t PltEntryAddr, int32_t Index,
+                       unsigned RelOff) const {
+  const uint8_t Inst[] = {
+      0x00, 0x40, 0x00, 0x00, // { immext (#0)
+      0x0e, 0xc0, 0x49, 0x6a, //   r14 = add (pc, ##GOTn@PCREL) }
+      0x1c, 0xc0, 0x8e, 0x91, // r28 = memw (r14)
+      0x00, 0xc0, 0x9c, 0x52, // jumpr r28
+  };
+  memcpy(Buf, Inst, sizeof(Inst));
+
+  relocateOne(Buf, R_HEX_B32_PCREL_X, GotPltEntryAddr - PltEntryAddr);
+  relocateOne(Buf + 4, R_HEX_6_PCREL_X, GotPltEntryAddr - PltEntryAddr);
+}
+
 TargetInfo *elf::getHexagonTargetInfo() {
   static Hexagon Target;
   return &Target;
diff --git a/ELF/Arch/Mips.cpp b/ELF/Arch/Mips.cpp
index dc70401..f6402f8 100644
--- a/ELF/Arch/Mips.cpp
+++ b/ELF/Arch/Mips.cpp
@@ -53,6 +53,7 @@
   PltEntrySize = 16;
   PltHeaderSize = 32;
   CopyRel = R_MIPS_COPY;
+  NoneRel = R_MIPS_NONE;
   PltRel = R_MIPS_JUMP_SLOT;
   NeedsThunks = true;
   TrapInstr = 0xefefefef;
@@ -185,7 +186,7 @@
 
 template <class ELFT>
 void MIPS<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &) const {
-  uint64_t VA = InX::Plt->getVA();
+  uint64_t VA = In.Plt->getVA();
   if (isMicroMips())
     VA |= 1;
   write32<ELFT::TargetEndianness>(Buf, VA);
@@ -239,8 +240,8 @@
 template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *Buf) const {
   const endianness E = ELFT::TargetEndianness;
   if (isMicroMips()) {
-    uint64_t GotPlt = InX::GotPlt->getVA();
-    uint64_t Plt = InX::Plt->getVA();
+    uint64_t GotPlt = In.GotPlt->getVA();
+    uint64_t Plt = In.Plt->getVA();
     // Overwrite trap instructions written by Writer::writeTrapInstr.
     memset(Buf, 0, PltHeaderSize);
 
@@ -292,7 +293,7 @@
   write32<E>(Buf + 24, JalrInst); // jalr.hb $25 or jalr $25
   write32<E>(Buf + 28, 0x2718fffe); // subu  $24, $24, 2
 
-  uint64_t GotPlt = InX::GotPlt->getVA();
+  uint64_t GotPlt = In.GotPlt->getVA();
   writeValue<E>(Buf, GotPlt + 0x8000, 16, 16);
   writeValue<E>(Buf + 4, GotPlt, 16, 0);
   writeValue<E>(Buf + 8, GotPlt, 16, 0);
diff --git a/ELF/Arch/PPC.cpp b/ELF/Arch/PPC.cpp
index 20cae0e..a01068c 100644
--- a/ELF/Arch/PPC.cpp
+++ b/ELF/Arch/PPC.cpp
@@ -29,6 +29,7 @@
 } // namespace
 
 PPC::PPC() {
+  NoneRel = R_PPC_NONE;
   GotBaseSymOff = 0x8000;
   GotBaseSymInGotPlt = false;
 }
diff --git a/ELF/Arch/PPC64.cpp b/ELF/Arch/PPC64.cpp
index fa3bf6c..eb01955 100644
--- a/ELF/Arch/PPC64.cpp
+++ b/ELF/Arch/PPC64.cpp
@@ -23,12 +23,49 @@
 static uint64_t PPC64TocOffset = 0x8000;
 static uint64_t DynamicThreadPointerOffset = 0x8000;
 
+// The instruction encoding of bits 21-30 from the ISA for the Xform and Dform
+// instructions that can be used as part of the initial exec TLS sequence.
+enum XFormOpcd {
+  LBZX = 87,
+  LHZX = 279,
+  LWZX = 23,
+  LDX = 21,
+  STBX = 215,
+  STHX = 407,
+  STWX = 151,
+  STDX = 149,
+  ADD = 266,
+};
+
+enum DFormOpcd {
+  LBZ = 34,
+  LBZU = 35,
+  LHZ = 40,
+  LHZU = 41,
+  LHAU = 43,
+  LWZ = 32,
+  LWZU = 33,
+  LFSU = 49,
+  LD = 58,
+  LFDU = 51,
+  STB = 38,
+  STBU = 39,
+  STH = 44,
+  STHU = 45,
+  STW = 36,
+  STWU = 37,
+  STFSU = 53,
+  STFDU = 55,
+  STD = 62,
+  ADDI = 14
+};
+
 uint64_t elf::getPPC64TocBase() {
   // The TOC consists of sections .got, .toc, .tocbss, .plt in that order. The
   // TOC starts where the first of these sections starts. We always create a
   // .got when we see a relocation that uses it, so for us the start is always
   // the .got.
-  uint64_t TocVA = InX::Got->getVA();
+  uint64_t TocVA = In.Got->getVA();
 
   // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000
   // thus permitting a full 64 Kbytes segment. Note that the glibc startup
@@ -37,6 +74,32 @@
   return TocVA + PPC64TocOffset;
 }
 
+
+unsigned elf::getPPC64GlobalEntryToLocalEntryOffset(uint8_t StOther) {
+  // The offset is encoded into the 3 most significant bits of the st_other
+  // field, with some special values described in section 3.4.1 of the ABI:
+  // 0   --> Zero offset between the GEP and LEP, and the function does NOT use
+  //         the TOC pointer (r2). r2 will hold the same value on returning from
+  //         the function as it did on entering the function.
+  // 1   --> Zero offset between the GEP and LEP, and r2 should be treated as a
+  //         caller-saved register for all callers.
+  // 2-6 --> The  binary logarithm of the offset eg:
+  //         2 --> 2^2 = 4 bytes -->  1 instruction.
+  //         6 --> 2^6 = 64 bytes --> 16 instructions.
+  // 7   --> Reserved.
+  uint8_t GepToLep = (StOther >> 5) & 7;
+  if (GepToLep < 2)
+    return 0;
+
+  // The value encoded in the st_other bits is the
+  // log-base-2(offset).
+  if (GepToLep < 7)
+    return 1 << GepToLep;
+
+  error("reserved value of 7 in the 3 most-significant-bits of st_other");
+  return 0;
+}
+
 namespace {
 class PPC64 final : public TargetInfo {
 public:
@@ -56,6 +119,7 @@
   void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
   void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
   void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
+  void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
 };
 } // namespace
 
@@ -71,8 +135,64 @@
 static uint16_t highest(uint64_t V) { return V >> 48; }
 static uint16_t highesta(uint64_t V) { return (V + 0x8000) >> 48; }
 
+// Extracts the 'PO' field of an instruction encoding.
+static uint8_t getPrimaryOpCode(uint32_t Encoding) { return (Encoding >> 26); }
+
+static bool isDQFormInstruction(uint32_t Encoding) {
+  switch (getPrimaryOpCode(Encoding)) {
+  default:
+    return false;
+  case 56:
+    // The only instruction with a primary opcode of 56 is `lq`.
+    return true;
+  case 61:
+    // There are both DS and DQ instruction forms with this primary opcode.
+    // Namely `lxv` and `stxv` are the DQ-forms that use it.
+    // The DS 'XO' bits being set to 01 is restricted to DQ form.
+    return (Encoding & 3) == 0x1;
+  }
+}
+
+static bool isInstructionUpdateForm(uint32_t Encoding) {
+  switch (getPrimaryOpCode(Encoding)) {
+  default:
+    return false;
+  case LBZU:
+  case LHAU:
+  case LHZU:
+  case LWZU:
+  case LFSU:
+  case LFDU:
+  case STBU:
+  case STHU:
+  case STWU:
+  case STFSU:
+  case STFDU:
+    return true;
+    // LWA has the same opcode as LD, and the DS bits is what differentiates
+    // between LD/LDU/LWA
+  case LD:
+  case STD:
+    return (Encoding & 3) == 1;
+  }
+}
+
+// There are a number of places when we either want to read or write an
+// instruction when handling a half16 relocation type. On big-endian the buffer
+// pointer is pointing into the middle of the word we want to extract, and on
+// little-endian it is pointing to the start of the word. These 2 helpers are to
+// simplify reading and writing in that context.
+static void writeInstrFromHalf16(uint8_t *Loc, uint32_t Instr) {
+  write32(Loc - (Config->EKind == ELF64BEKind ? 2 : 0), Instr);
+}
+
+static uint32_t readInstrFromHalf16(const uint8_t *Loc) {
+  return read32(Loc - (Config->EKind == ELF64BEKind ? 2 : 0));
+}
+
 PPC64::PPC64() {
   GotRel = R_PPC64_GLOB_DAT;
+  NoneRel = R_PPC64_NONE;
   PltRel = R_PPC64_JMP_SLOT;
   RelativeRel = R_PPC64_RELATIVE;
   IRelativeRel = R_PPC64_IRELATIVE;
@@ -146,27 +266,29 @@
   // bl __tls_get_addr(x@tlsgd)      into      nop
   // nop                             into      addi r3, r3, x@tprel@l
 
-  uint32_t EndianOffset = Config->EKind == ELF64BEKind ? 2U : 0U;
-
   switch (Type) {
   case R_PPC64_GOT_TLSGD16_HA:
-    write32(Loc - EndianOffset, 0x60000000); // nop
+    writeInstrFromHalf16(Loc, 0x60000000); // nop
     break;
+  case R_PPC64_GOT_TLSGD16:
   case R_PPC64_GOT_TLSGD16_LO:
-    write32(Loc - EndianOffset, 0x3c6d0000); // addis r3, r13
+    writeInstrFromHalf16(Loc, 0x3c6d0000); // addis r3, r13
     relocateOne(Loc, R_PPC64_TPREL16_HA, Val);
     break;
   case R_PPC64_TLSGD:
     write32(Loc, 0x60000000);     // nop
     write32(Loc + 4, 0x38630000); // addi r3, r3
-    relocateOne(Loc + 4 + EndianOffset, R_PPC64_TPREL16_LO, Val);
+    // Since we are relocating a half16 type relocation and Loc + 4 points to
+    // the start of an instruction we need to advance the buffer by an extra
+    // 2 bytes on BE.
+    relocateOne(Loc + 4 + (Config->EKind == ELF64BEKind ? 2 : 0),
+                R_PPC64_TPREL16_LO, Val);
     break;
   default:
     llvm_unreachable("unsupported relocation for TLS GD to LE relaxation");
   }
 }
 
-
 void PPC64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
   // Reference: 3.7.4.3 of the 64-bit ELF V2 abi supplement.
   // The local dynamic code sequence for a global `x` will look like:
@@ -183,13 +305,12 @@
   // bl __tls_get_addr(x@tlsgd)     into      nop
   // nop                            into      addi r3, r3, 4096
 
-  uint32_t EndianOffset = Config->EKind == ELF64BEKind ? 2U : 0U;
   switch (Type) {
   case R_PPC64_GOT_TLSLD16_HA:
-    write32(Loc - EndianOffset, 0x60000000); // nop
+    writeInstrFromHalf16(Loc, 0x60000000); // nop
     break;
   case R_PPC64_GOT_TLSLD16_LO:
-    write32(Loc - EndianOffset, 0x3c6d0000); // addis r3, r13, 0
+    writeInstrFromHalf16(Loc, 0x3c6d0000); // addis r3, r13, 0
     break;
   case R_PPC64_TLSLD:
     write32(Loc, 0x60000000);     // nop
@@ -212,6 +333,80 @@
   }
 }
 
+static unsigned getDFormOp(unsigned SecondaryOp) {
+  switch (SecondaryOp) {
+  case LBZX:
+    return LBZ;
+  case LHZX:
+    return LHZ;
+  case LWZX:
+    return LWZ;
+  case LDX:
+    return LD;
+  case STBX:
+    return STB;
+  case STHX:
+    return STH;
+  case STWX:
+    return STW;
+  case STDX:
+    return STD;
+  case ADD:
+    return ADDI;
+  default:
+    error("unrecognized instruction for IE to LE R_PPC64_TLS");
+    return 0;
+  }
+}
+
+void PPC64::relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
+  // The initial exec code sequence for a global `x` will look like:
+  // Instruction                    Relocation                Symbol
+  // addis r9, r2, x@got@tprel@ha   R_PPC64_GOT_TPREL16_HA      x
+  // ld    r9, x@got@tprel@l(r9)    R_PPC64_GOT_TPREL16_LO_DS   x
+  // add r9, r9, x@tls              R_PPC64_TLS                 x
+
+  // Relaxing to local exec entails converting:
+  // addis r9, r2, x@got@tprel@ha       into        nop
+  // ld r9, x@got@tprel@l(r9)           into        addis r9, r13, x@tprel@ha
+  // add r9, r9, x@tls                  into        addi r9, r9, x@tprel@l
+
+  // x@tls R_PPC64_TLS is a relocation which does not compute anything,
+  // it is replaced with r13 (thread pointer).
+
+  // The add instruction in the initial exec sequence has multiple variations
+  // that need to be handled. If we are building an address it will use an add
+  // instruction, if we are accessing memory it will use any of the X-form
+  // indexed load or store instructions.
+
+  unsigned Offset = (Config->EKind == ELF64BEKind) ? 2 : 0;
+  switch (Type) {
+  case R_PPC64_GOT_TPREL16_HA:
+    write32(Loc - Offset, 0x60000000); // nop
+    break;
+  case R_PPC64_GOT_TPREL16_LO_DS:
+  case R_PPC64_GOT_TPREL16_DS: {
+    uint32_t RegNo = read32(Loc - Offset) & 0x03E00000; // bits 6-10
+    write32(Loc - Offset, 0x3C0D0000 | RegNo);          // addis RegNo, r13
+    relocateOne(Loc, R_PPC64_TPREL16_HA, Val);
+    break;
+  }
+  case R_PPC64_TLS: {
+    uint32_t PrimaryOp = getPrimaryOpCode(read32(Loc));
+    if (PrimaryOp != 31)
+      error("unrecognized instruction for IE to LE R_PPC64_TLS");
+    uint32_t SecondaryOp = (read32(Loc) & 0x000007FE) >> 1; // bits 21-30
+    uint32_t DFormOp = getDFormOp(SecondaryOp);
+    write32(Loc, ((DFormOp << 26) | (read32(Loc) & 0x03FFFFFF)));
+    relocateOne(Loc + Offset, R_PPC64_TPREL16_LO, Val);
+    break;
+  }
+  default:
+    llvm_unreachable("unknown relocation for IE to LE");
+    break;
+  }
+}
+
 RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
                           const uint8_t *Loc) const {
   switch (Type) {
@@ -279,7 +474,7 @@
   case R_PPC64_TLSLD:
     return R_TLSLD_HINT;
   case R_PPC64_TLS:
-    return R_HINT;
+    return R_TLSIE_HINT;
   default:
     return R_ABS;
   }
@@ -308,7 +503,7 @@
   // 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);
+  int64_t GotPltOffset = In.GotPlt->getVA() - (In.Plt->getVA() + 8);
   write64(Buf + 52, GotPltOffset);
 }
 
@@ -386,9 +581,15 @@
   }
 }
 
+static bool isTocRelType(RelType Type) {
+  return Type == R_PPC64_TOC16_HA || Type == R_PPC64_TOC16_LO_DS ||
+         Type == R_PPC64_TOC16_LO;
+}
+
 void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
   // For a TOC-relative relocation, proceed in terms of the corresponding
   // ADDR16 relocation type.
+  bool IsTocRelType = isTocRelType(Type);
   std::tie(Type, Val) = toAddr16Rel(Type, Val);
 
   switch (Type) {
@@ -405,14 +606,21 @@
     write16(Loc, Val);
     break;
   case R_PPC64_ADDR16_DS:
-  case R_PPC64_TPREL16_DS:
+  case R_PPC64_TPREL16_DS: {
     checkInt(Loc, Val, 16, Type);
-    write16(Loc, (read16(Loc) & 3) | (Val & ~3));
-    break;
+    // DQ-form instructions use bits 28-31 as part of the instruction encoding
+    // DS-form instructions only use bits 30-31.
+    uint16_t Mask = isDQFormInstruction(readInstrFromHalf16(Loc)) ? 0xF : 0x3;
+    checkAlignment(Loc, lo(Val), Mask + 1, Type);
+    write16(Loc, (read16(Loc) & Mask) | lo(Val));
+  } break;
   case R_PPC64_ADDR16_HA:
   case R_PPC64_REL16_HA:
   case R_PPC64_TPREL16_HA:
-    write16(Loc, ha(Val));
+    if (Config->TocOptimize && IsTocRelType && ha(Val) == 0)
+      writeInstrFromHalf16(Loc, 0x60000000);
+    else
+      write16(Loc, ha(Val));
     break;
   case R_PPC64_ADDR16_HI:
   case R_PPC64_REL16_HI:
@@ -438,12 +646,40 @@
   case R_PPC64_ADDR16_LO:
   case R_PPC64_REL16_LO:
   case R_PPC64_TPREL16_LO:
+    // When the high-adjusted part of a toc relocation evalutes to 0, it is
+    // changed into a nop. The lo part then needs to be updated to use the
+    // toc-pointer register r2, as the base register.
+    if (Config->TocOptimize && IsTocRelType && ha(Val) == 0) {
+      uint32_t Instr = readInstrFromHalf16(Loc);
+      if (isInstructionUpdateForm(Instr))
+        error(getErrorLocation(Loc) +
+              "can't toc-optimize an update instruction: 0x" +
+              utohexstr(Instr));
+      Instr = (Instr & 0xFFE00000) | 0x00020000;
+      writeInstrFromHalf16(Loc, Instr);
+    }
     write16(Loc, lo(Val));
     break;
   case R_PPC64_ADDR16_LO_DS:
-  case R_PPC64_TPREL16_LO_DS:
-    write16(Loc, (read16(Loc) & 3) | (lo(Val) & ~3));
-    break;
+  case R_PPC64_TPREL16_LO_DS: {
+    // DQ-form instructions use bits 28-31 as part of the instruction encoding
+    // DS-form instructions only use bits 30-31.
+    uint32_t Inst = readInstrFromHalf16(Loc);
+    uint16_t Mask = isDQFormInstruction(Inst) ? 0xF : 0x3;
+    checkAlignment(Loc, lo(Val), Mask + 1, Type);
+    if (Config->TocOptimize && IsTocRelType && ha(Val) == 0) {
+      // When the high-adjusted part of a toc relocation evalutes to 0, it is
+      // changed into a nop. The lo part then needs to be updated to use the toc
+      // pointer register r2, as the base register.
+      if (isInstructionUpdateForm(Inst))
+        error(getErrorLocation(Loc) +
+              "Can't toc-optimize an update instruction: 0x" +
+              Twine::utohexstr(Inst));
+      Inst = (Inst & 0xFFE0000F) | 0x00020000;
+      writeInstrFromHalf16(Loc, Inst);
+    }
+    write16(Loc, (read16(Loc) & Mask) | lo(Val));
+  } break;
   case R_PPC64_ADDR32:
   case R_PPC64_REL32:
     checkInt(Loc, Val, 32, Type);
@@ -511,9 +747,8 @@
   case R_PPC64_GOT_TLSGD16_LO: {
     // Relax from addi  r3, rA, sym@got@tlsgd@l to
     //            ld r3, sym@got@tprel@l(rA)
-    uint32_t EndianOffset = Config->EKind == ELF64BEKind ? 2U : 0U;
-    uint32_t InputRegister = (read32(Loc - EndianOffset) & (0x1f << 16));
-    write32(Loc - EndianOffset, 0xE8600000 | InputRegister);
+    uint32_t InputRegister = (readInstrFromHalf16(Loc) & (0x1f << 16));
+    writeInstrFromHalf16(Loc, 0xE8600000 | InputRegister);
     relocateOne(Loc, R_PPC64_GOT_TPREL16_LO_DS, Val);
     return;
   }
diff --git a/ELF/Arch/RISCV.cpp b/ELF/Arch/RISCV.cpp
index 18a9c51..ef72722 100644
--- a/ELF/Arch/RISCV.cpp
+++ b/ELF/Arch/RISCV.cpp
@@ -21,6 +21,7 @@
 
 class RISCV final : public TargetInfo {
 public:
+  RISCV();
   virtual uint32_t calcEFlags() const override;
   RelExpr getRelExpr(RelType Type, const Symbol &S,
                      const uint8_t *Loc) const override;
@@ -29,6 +30,8 @@
 
 } // end anonymous namespace
 
+RISCV::RISCV() { NoneRel = R_RISCV_NONE; }
+
 static uint32_t getEFlags(InputFile *F) {
   if (Config->Is64)
     return cast<ObjFile<ELF64LE>>(F)->getObj().getHeader()->e_flags;
diff --git a/ELF/Arch/SPARCV9.cpp b/ELF/Arch/SPARCV9.cpp
index 36f5c83..831aa20 100644
--- a/ELF/Arch/SPARCV9.cpp
+++ b/ELF/Arch/SPARCV9.cpp
@@ -35,6 +35,7 @@
 SPARCV9::SPARCV9() {
   CopyRel = R_SPARC_COPY;
   GotRel = R_SPARC_GLOB_DAT;
+  NoneRel = R_SPARC_NONE;
   PltRel = R_SPARC_JMP_SLOT;
   RelativeRel = R_SPARC_RELATIVE;
   GotEntrySize = 8;
diff --git a/ELF/Arch/X86.cpp b/ELF/Arch/X86.cpp
index 19a0b60..82246e6 100644
--- a/ELF/Arch/X86.cpp
+++ b/ELF/Arch/X86.cpp
@@ -48,6 +48,7 @@
 X86::X86() {
   CopyRel = R_386_COPY;
   GotRel = R_386_GLOB_DAT;
+  NoneRel = R_386_NONE;
   PltRel = R_386_JUMP_SLOT;
   IRelativeRel = R_386_IRELATIVE;
   RelativeRel = R_386_RELATIVE;
@@ -60,6 +61,10 @@
   PltHeaderSize = 16;
   TlsGdRelaxSkip = 2;
   TrapInstr = 0xcccccccc; // 0xcc = INT3
+
+  // Align to the non-PAE large page size (known as a superpage or huge page).
+  // FreeBSD automatically promotes large, superpage-aligned allocations.
+  DefaultImageBase = 0x400000;
 }
 
 static bool hasBaseReg(uint8_t ModRM) { return (ModRM & 0xc7) != 0x5; }
@@ -152,7 +157,7 @@
 }
 
 void X86::writeGotPltHeader(uint8_t *Buf) const {
-  write32le(Buf, InX::Dynamic->getVA());
+  write32le(Buf, In.Dynamic->getVA());
 }
 
 void X86::writeGotPlt(uint8_t *Buf, const Symbol &S) const {
@@ -183,8 +188,8 @@
     };
     memcpy(Buf, V, sizeof(V));
 
-    uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize();
-    uint32_t GotPlt = InX::GotPlt->getVA() - Ebx;
+    uint32_t Ebx = In.Got->getVA() + In.Got->getSize();
+    uint32_t GotPlt = In.GotPlt->getVA() - Ebx;
     write32le(Buf + 2, GotPlt + 4);
     write32le(Buf + 8, GotPlt + 8);
     return;
@@ -196,7 +201,7 @@
       0x90, 0x90, 0x90, 0x90, // nop
   };
   memcpy(Buf, PltData, sizeof(PltData));
-  uint32_t GotPlt = InX::GotPlt->getVA();
+  uint32_t GotPlt = In.GotPlt->getVA();
   write32le(Buf + 2, GotPlt + 4);
   write32le(Buf + 8, GotPlt + 8);
 }
@@ -213,7 +218,7 @@
 
   if (Config->Pic) {
     // jmp *foo@GOT(%ebx)
-    uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize();
+    uint32_t Ebx = In.Got->getVA() + In.Got->getSize();
     Buf[1] = 0xa3;
     write32le(Buf + 2, GotPltEntryAddr - Ebx);
   } else {
@@ -447,8 +452,8 @@
   };
   memcpy(Buf, Insn, sizeof(Insn));
 
-  uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize();
-  uint32_t GotPlt = InX::GotPlt->getVA() - Ebx;
+  uint32_t Ebx = In.Got->getVA() + In.Got->getSize();
+  uint32_t GotPlt = In.GotPlt->getVA() - Ebx;
   write32le(Buf + 2, GotPlt + 4);
   write32le(Buf + 9, GotPlt + 8);
 }
@@ -467,7 +472,7 @@
   };
   memcpy(Buf, Insn, sizeof(Insn));
 
-  uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize();
+  uint32_t Ebx = In.Got->getVA() + In.Got->getSize();
   unsigned Off = getPltEntryOffset(Index);
   write32le(Buf + 3, GotPltEntryAddr - Ebx);
   write32le(Buf + 8, -Off - 12 + 32);
@@ -506,7 +511,7 @@
   };
   memcpy(Buf, Insn, sizeof(Insn));
 
-  uint32_t GotPlt = InX::GotPlt->getVA();
+  uint32_t GotPlt = In.GotPlt->getVA();
   write32le(Buf + 2, GotPlt + 4);
   write32le(Buf + 8, GotPlt + 8);
 }
diff --git a/ELF/Arch/X86_64.cpp b/ELF/Arch/X86_64.cpp
index 795de8d..960bf78 100644
--- a/ELF/Arch/X86_64.cpp
+++ b/ELF/Arch/X86_64.cpp
@@ -55,6 +55,7 @@
 template <class ELFT> X86_64<ELFT>::X86_64() {
   CopyRel = R_X86_64_COPY;
   GotRel = R_X86_64_GLOB_DAT;
+  NoneRel = R_X86_64_NONE;
   PltRel = R_X86_64_JUMP_SLOT;
   RelativeRel = R_X86_64_RELATIVE;
   IRelativeRel = R_X86_64_IRELATIVE;
@@ -124,7 +125,7 @@
   // required, but it is documented in the psabi and the glibc dynamic linker
   // seems to use it (note that this is relevant for linking ld.so, not any
   // other program).
-  write64le(Buf, InX::Dynamic->getVA());
+  write64le(Buf, In.Dynamic->getVA());
 }
 
 template <class ELFT>
@@ -140,8 +141,8 @@
       0x0f, 0x1f, 0x40, 0x00, // nop
   };
   memcpy(Buf, PltData, sizeof(PltData));
-  uint64_t GotPlt = InX::GotPlt->getVA();
-  uint64_t Plt = InX::Plt->getVA();
+  uint64_t GotPlt = In.GotPlt->getVA();
+  uint64_t Plt = In.Plt->getVA();
   write32le(Buf + 2, GotPlt - Plt + 2); // GOTPLT+8
   write32le(Buf + 8, GotPlt - Plt + 4); // GOTPLT+16
 }
@@ -569,8 +570,8 @@
   };
   memcpy(Buf, Insn, sizeof(Insn));
 
-  uint64_t GotPlt = InX::GotPlt->getVA();
-  uint64_t Plt = InX::Plt->getVA();
+  uint64_t GotPlt = In.GotPlt->getVA();
+  uint64_t Plt = In.Plt->getVA();
   write32le(Buf + 2, GotPlt - Plt - 6 + 8);
   write32le(Buf + 9, GotPlt - Plt - 13 + 16);
 }
diff --git a/ELF/CMakeLists.txt b/ELF/CMakeLists.txt
index 5d080a7..51fc1e5 100644
--- a/ELF/CMakeLists.txt
+++ b/ELF/CMakeLists.txt
@@ -22,11 +22,11 @@
   Arch/X86.cpp
   Arch/X86_64.cpp
   CallGraphSort.cpp
+  DWARF.cpp
   Driver.cpp
   DriverUtils.cpp
   EhFrame.cpp
   Filesystem.cpp
-  GdbIndex.cpp
   ICF.cpp
   InputFiles.cpp
   InputSection.cpp
diff --git a/ELF/CallGraphSort.cpp b/ELF/CallGraphSort.cpp
index 33ac159..113ae57 100644
--- a/ELF/CallGraphSort.cpp
+++ b/ELF/CallGraphSort.cpp
@@ -72,7 +72,7 @@
   size_t Size = 0;
   uint64_t Weight = 0;
   uint64_t InitialWeight = 0;
-  std::vector<Edge> Preds;
+  Edge BestPred = {-1, 0};
 };
 
 class CallGraphSort {
@@ -136,8 +136,12 @@
     if (From == To)
       continue;
 
-    // Add an edge
-    Clusters[To].Preds.push_back({From, Weight});
+    // Remember the best edge.
+    Cluster &ToC = Clusters[To];
+    if (ToC.BestPred.From == -1 || ToC.BestPred.Weight < Weight) {
+      ToC.BestPred.From = From;
+      ToC.BestPred.Weight = Weight;
+    }
   }
   for (Cluster &C : Clusters)
     C.InitialWeight = C.Weight;
@@ -167,9 +171,9 @@
   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];
+  for (size_t I = 0; I < Clusters.size(); ++I) {
+    SortedSecs[I] = I;
+    SecToCluster[I] = &Clusters[I];
   }
 
   std::stable_sort(SortedSecs.begin(), SortedSecs.end(), [&](int A, int B) {
@@ -181,21 +185,11 @@
     // 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)
+    // Don't consider merging if the edge is unlikely.
+    if (C.BestPred.From == -1 || C.BestPred.Weight * 10 <= C.InitialWeight)
       continue;
 
-    Cluster *PredC = SecToCluster[BestPred];
+    Cluster *PredC = SecToCluster[C.BestPred.From];
     if (PredC == &C)
       continue;
 
diff --git a/ELF/Config.h b/ELF/Config.h
index 763111c..f9fc10c 100644
--- a/ELF/Config.h
+++ b/ELF/Config.h
@@ -47,7 +47,7 @@
 enum class StripPolicy { None, All, Debug };
 
 // For --unresolved-symbols.
-enum class UnresolvedPolicy { ReportError, Warn, Ignore, IgnoreAll };
+enum class UnresolvedPolicy { ReportError, Warn, Ignore };
 
 // For --orphan-handling.
 enum class OrphanHandlingPolicy { Place, Warn, Error };
@@ -171,18 +171,22 @@
   bool Trace;
   bool ThinLTOEmitImportsFiles;
   bool ThinLTOIndexOnly;
+  bool TocOptimize;
   bool UndefinedVersion;
   bool UseAndroidRelrTags = false;
   bool WarnBackrefs;
   bool WarnCommon;
+  bool WarnIfuncTextrel;
   bool WarnMissingEntry;
   bool WarnSymbolOrdering;
   bool WriteAddends;
   bool ZCombreloc;
   bool ZCopyreloc;
   bool ZExecstack;
+  bool ZGlobal;
   bool ZHazardplt;
   bool ZInitfirst;
+  bool ZInterpose;
   bool ZKeepTextSectionPrefix;
   bool ZNodelete;
   bool ZNodlopen;
diff --git a/ELF/GdbIndex.cpp b/ELF/DWARF.cpp
similarity index 83%
rename from ELF/GdbIndex.cpp
rename to ELF/DWARF.cpp
index 85449a2..4c12cfd 100644
--- a/ELF/GdbIndex.cpp
+++ b/ELF/DWARF.cpp
@@ -1,4 +1,4 @@
-//===- GdbIndex.cpp -------------------------------------------------------===//
+//===- DWARF.cpp ----------------------------------------------------------===//
 //
 //                             The LLVM Linker
 //
@@ -14,8 +14,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "GdbIndex.h"
+#include "DWARF.h"
 #include "Symbols.h"
+#include "Target.h"
 #include "lld/Common/Memory.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
 #include "llvm/Object/ELFObjectFile.h"
@@ -29,24 +30,27 @@
   for (InputSectionBase *Sec : Obj->getSections()) {
     if (!Sec)
       continue;
+
     if (LLDDWARFSection *M = StringSwitch<LLDDWARFSection *>(Sec->Name)
                                  .Case(".debug_info", &InfoSection)
                                  .Case(".debug_ranges", &RangeSection)
                                  .Case(".debug_line", &LineSection)
                                  .Default(nullptr)) {
-      Sec->maybeDecompress();
-      M->Data = toStringRef(Sec->Data);
+      M->Data = toStringRef(Sec->data());
       M->Sec = Sec;
       continue;
     }
+
     if (Sec->Name == ".debug_abbrev")
-      AbbrevSection = toStringRef(Sec->Data);
+      AbbrevSection = toStringRef(Sec->data());
     else if (Sec->Name == ".debug_gnu_pubnames")
-      GnuPubNamesSection = toStringRef(Sec->Data);
+      GnuPubNamesSection = toStringRef(Sec->data());
     else if (Sec->Name == ".debug_gnu_pubtypes")
-      GnuPubTypesSection = toStringRef(Sec->Data);
+      GnuPubTypesSection = toStringRef(Sec->data());
     else if (Sec->Name == ".debug_str")
-      StrSection = toStringRef(Sec->Data);
+      StrSection = toStringRef(Sec->data());
+    else if (Sec->Name == ".debug_line_str")
+      LineStringSection = toStringRef(Sec->data());
   }
 }
 
@@ -73,7 +77,10 @@
   // Broken debug info can point to a non-Defined symbol.
   auto *DR = dyn_cast<Defined>(&File->getRelocTargetSym(Rel));
   if (!DR) {
-    error("unsupported relocation target while parsing debug info");
+    RelType Type = Rel.getType(Config->IsMips64EL);
+    if (Type != Target->NoneRel)
+      error(toString(File) + ": relocation " + lld::toString(Type) + " at 0x" +
+            llvm::utohexstr(Rel.r_offset) + " has unsupported target");
     return None;
   }
   uint64_t Val = DR->Value + getAddend<ELFT>(Rel);
diff --git a/ELF/GdbIndex.h b/ELF/DWARF.h
similarity index 89%
rename from ELF/GdbIndex.h
rename to ELF/DWARF.h
index eba1ba2..f168ab3 100644
--- a/ELF/GdbIndex.h
+++ b/ELF/DWARF.h
@@ -1,4 +1,4 @@
-//===- GdbIndex.h --------------------------------------------*- C++ -*-===//
+//===- DWARF.h -----------------------------------------------*- C++ -*-===//
 //
 //                             The LLVM Linker
 //
@@ -7,8 +7,8 @@
 //
 //===-------------------------------------------------------------------===//
 
-#ifndef LLD_ELF_GDB_INDEX_H
-#define LLD_ELF_GDB_INDEX_H
+#ifndef LLD_ELF_DWARF_H
+#define LLD_ELF_DWARF_H
 
 #include "InputFiles.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
@@ -24,44 +24,56 @@
 };
 
 template <class ELFT> class LLDDwarfObj final : public llvm::DWARFObject {
-  LLDDWARFSection InfoSection;
-  LLDDWARFSection RangeSection;
-  LLDDWARFSection LineSection;
-  StringRef AbbrevSection;
-  StringRef GnuPubNamesSection;
-  StringRef GnuPubTypesSection;
-  StringRef StrSection;
+public:
+  explicit LLDDwarfObj(ObjFile<ELFT> *Obj);
 
+  const llvm::DWARFSection &getInfoSection() const override {
+    return InfoSection;
+  }
+
+  const llvm::DWARFSection &getRangeSection() const override {
+    return RangeSection;
+  }
+
+  const llvm::DWARFSection &getLineSection() const override {
+    return LineSection;
+  }
+
+  StringRef getFileName() const override { return ""; }
+  StringRef getAbbrevSection() const override { return AbbrevSection; }
+  StringRef getStringSection() const override { return StrSection; }
+  StringRef getLineStringSection() const override { return LineStringSection; }
+
+  StringRef getGnuPubNamesSection() const override {
+    return GnuPubNamesSection;
+  }
+
+  StringRef getGnuPubTypesSection() const override {
+    return GnuPubTypesSection;
+  }
+
+  bool isLittleEndian() const override {
+    return ELFT::TargetEndianness == llvm::support::little;
+  }
+
+  llvm::Optional<llvm::RelocAddrEntry> find(const llvm::DWARFSection &Sec,
+                                            uint64_t Pos) const override;
+
+private:
   template <class RelTy>
   llvm::Optional<llvm::RelocAddrEntry> findAux(const InputSectionBase &Sec,
                                                uint64_t Pos,
                                                ArrayRef<RelTy> Rels) const;
 
-public:
-  explicit LLDDwarfObj(ObjFile<ELFT> *Obj);
-  const llvm::DWARFSection &getInfoSection() const override {
-    return InfoSection;
-  }
-  const llvm::DWARFSection &getRangeSection() const override {
-    return RangeSection;
-  }
-  const llvm::DWARFSection &getLineSection() const override {
-    return LineSection;
-  }
-  StringRef getFileName() const override { return ""; }
-  StringRef getAbbrevSection() const override { return AbbrevSection; }
-  StringRef getStringSection() const override { return StrSection; }
-  StringRef getGnuPubNamesSection() const override {
-    return GnuPubNamesSection;
-  }
-  StringRef getGnuPubTypesSection() const override {
-    return GnuPubTypesSection;
-  }
-  bool isLittleEndian() const override {
-    return ELFT::TargetEndianness == llvm::support::little;
-  }
-  llvm::Optional<llvm::RelocAddrEntry> find(const llvm::DWARFSection &Sec,
-                                            uint64_t Pos) const override;
+  LLDDWARFSection InfoSection;
+  LLDDWARFSection RangeSection;
+  LLDDWARFSection LineSection;
+
+  StringRef AbbrevSection;
+  StringRef GnuPubNamesSection;
+  StringRef GnuPubTypesSection;
+  StringRef StrSection;
+  StringRef LineStringSection;
 };
 
 } // namespace elf
diff --git a/ELF/Driver.cpp b/ELF/Driver.cpp
index a030d11..bb80bc2 100644
--- a/ELF/Driver.cpp
+++ b/ELF/Driver.cpp
@@ -63,6 +63,7 @@
 using namespace llvm::ELF;
 using namespace llvm::object;
 using namespace llvm::sys;
+using namespace llvm::support;
 
 using namespace lld;
 using namespace lld::elf;
@@ -74,7 +75,7 @@
 
 bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,
                raw_ostream &Error) {
-  errorHandler().LogName = sys::path::filename(Args[0]);
+  errorHandler().LogName = args::getFilenameWithoutExe(Args[0]);
   errorHandler().ErrorLimitExceededMsg =
       "too many errors emitted, stopping now (use "
       "-error-limit=0 to see all errors)";
@@ -84,7 +85,6 @@
 
   InputSections.clear();
   OutputSections.clear();
-  Tar = nullptr;
   BinaryFiles.clear();
   BitcodeFiles.clear();
   ObjectFiles.clear();
@@ -94,6 +94,10 @@
   Driver = make<LinkerDriver>();
   Script = make<LinkerScript>();
   Symtab = make<SymbolTable>();
+
+  Tar = nullptr;
+  memset(&In, 0, sizeof(In));
+
   Config->ProgName = Args[0];
 
   Driver->main(Args);
@@ -280,6 +284,9 @@
   if (Config->FixCortexA53Errata843419 && Config->EMachine != EM_AARCH64)
     error("--fix-cortex-a53-843419 is only supported on AArch64 targets.");
 
+  if (Config->TocOptimize && Config->EMachine != EM_PPC64)
+      error("--toc-optimize is only supported on the PowerPC64 target.");
+
   if (Config->Pie && Config->Shared)
     error("-shared and -pie may not be used together");
 
@@ -338,9 +345,10 @@
   return Default;
 }
 
-static bool isKnown(StringRef S) {
+static bool isKnownZFlag(StringRef S) {
   return S == "combreloc" || S == "copyreloc" || S == "defs" ||
-         S == "execstack" || S == "hazardplt" || S == "initfirst" ||
+         S == "execstack" || S == "global" || S == "hazardplt" ||
+         S == "initfirst" || S == "interpose" ||
          S == "keep-text-section-prefix" || S == "lazy" || S == "muldefs" ||
          S == "nocombreloc" || S == "nocopyreloc" || S == "nodelete" ||
          S == "nodlopen" || S == "noexecstack" ||
@@ -353,7 +361,7 @@
 // Report an error for an unknown -z option.
 static void checkZOptions(opt::InputArgList &Args) {
   for (auto *Arg : Args.filtered(OPT_z))
-    if (!isKnown(Arg->getValue()))
+    if (!isKnownZFlag(Arg->getValue()))
       error("unknown -z value: " + StringRef(Arg->getValue()));
 }
 
@@ -450,9 +458,6 @@
 // Determines what we should do if there are remaining unresolved
 // symbols after the name resolution.
 static UnresolvedPolicy getUnresolvedSymbolPolicy(opt::InputArgList &Args) {
-  if (Args.hasArg(OPT_relocatable))
-    return UnresolvedPolicy::IgnoreAll;
-
   UnresolvedPolicy ErrorOrWarn = Args.hasFlag(OPT_error_unresolved_symbols,
                                               OPT_warn_unresolved_symbols, true)
                                      ? UnresolvedPolicy::ReportError
@@ -674,6 +679,27 @@
   }
 }
 
+template <class ELFT> static void readCallGraphsFromObjectFiles() {
+  auto FindSection = [&](const Symbol *Sym) -> const InputSectionBase * {
+    warnUnorderableSymbol(Sym);
+    if (const auto *SymD = dyn_cast<Defined>(Sym))
+      return dyn_cast_or_null<InputSectionBase>(SymD->Section);
+    return nullptr;
+  };
+
+  for (auto File : ObjectFiles) {
+    auto *Obj = cast<ObjFile<ELFT>>(File);
+    for (const Elf_CGProfile_Impl<ELFT> &CGPE : Obj->CGProfile) {
+      const InputSectionBase *FromSB =
+          FindSection(&Obj->getSymbol(CGPE.cgp_from));
+      const InputSectionBase *ToSB = FindSection(&Obj->getSymbol(CGPE.cgp_to));
+      if (!FromSB || !ToSB)
+        continue;
+      Config->CallGraphProfile[{FromSB, ToSB}] += CGPE.cgp_weight;
+    }
+  }
+}
+
 static bool getCompressDebugSections(opt::InputArgList &Args) {
   StringRef S = Args.getLastArgValue(OPT_compress_debug_sections, "none");
   if (S == "none")
@@ -831,13 +857,17 @@
   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->WarnIfuncTextrel =
+      Args.hasFlag(OPT_warn_ifunc_textrel, OPT_no_warn_ifunc_textrel, false);
   Config->WarnSymbolOrdering =
       Args.hasFlag(OPT_warn_symbol_ordering, OPT_no_warn_symbol_ordering, true);
   Config->ZCombreloc = getZFlag(Args, "combreloc", "nocombreloc", true);
   Config->ZCopyreloc = getZFlag(Args, "copyreloc", "nocopyreloc", true);
   Config->ZExecstack = getZFlag(Args, "execstack", "noexecstack", false);
+  Config->ZGlobal = hasZOption(Args, "global");
   Config->ZHazardplt = hasZOption(Args, "hazardplt");
   Config->ZInitfirst = hasZOption(Args, "initfirst");
+  Config->ZInterpose = hasZOption(Args, "interpose");
   Config->ZKeepTextSectionPrefix = getZFlag(
       Args, "keep-text-section-prefix", "nokeep-text-section-prefix", false);
   Config->ZNodelete = hasZOption(Args, "nodelete");
@@ -958,22 +988,17 @@
 // This function initialize such members. See Config.h for the details
 // of these values.
 static void setConfigs(opt::InputArgList &Args) {
-  ELFKind Kind = Config->EKind;
-  uint16_t Machine = Config->EMachine;
+  ELFKind K = Config->EKind;
+  uint16_t M = Config->EMachine;
 
   Config->CopyRelocs = (Config->Relocatable || Config->EmitRelocs);
-  Config->Is64 = (Kind == ELF64LEKind || Kind == ELF64BEKind);
-  Config->IsLE = (Kind == ELF32LEKind || Kind == ELF64LEKind);
-  Config->Endianness =
-      Config->IsLE ? support::endianness::little : support::endianness::big;
-  Config->IsMips64EL = (Kind == ELF64LEKind && Machine == EM_MIPS);
+  Config->Is64 = (K == ELF64LEKind || K == ELF64BEKind);
+  Config->IsLE = (K == ELF32LEKind || K == ELF64LEKind);
+  Config->Endianness = Config->IsLE ? endianness::little : endianness::big;
+  Config->IsMips64EL = (K == ELF64LEKind && M == EM_MIPS);
   Config->Pic = Config->Pie || Config->Shared;
   Config->Wordsize = Config->Is64 ? 8 : 4;
 
-  // There is an ILP32 ABI for x86-64, although it's not very popular.
-  // It is called the x32 ABI.
-  bool IsX32 = (Kind == ELF32LEKind && Machine == EM_X86_64);
-
   // ELF defines two different ways to store relocation addends as shown below:
   //
   //  Rel:  Addends are stored to the location where relocations are applied.
@@ -987,9 +1012,9 @@
   // You cannot choose which one, Rel or Rela, you want to use. Instead each
   // ABI defines which one you need to use. The following expression expresses
   // that.
-  Config->IsRela =
-      (Config->Is64 || IsX32 || Machine == EM_PPC || Machine == EM_RISCV) &&
-      Machine != EM_MIPS;
+  Config->IsRela = M == EM_AARCH64 || M == EM_AMDGPU || M == EM_HEXAGON ||
+                   M == EM_PPC || M == EM_PPC64 || M == EM_RISCV ||
+                   M == EM_X86_64;
 
   // If the output uses REL relocations we must store the dynamic relocation
   // addends to the output sections. We also store addends for RELA relocations
@@ -999,6 +1024,9 @@
   Config->WriteAddends = Args.hasFlag(OPT_apply_dynamic_relocs,
                                       OPT_no_apply_dynamic_relocs, false) ||
                          !Config->IsRela;
+
+  Config->TocOptimize =
+      Args.hasFlag(OPT_toc_optimize, OPT_no_toc_optimize, M == EM_PPC64);
 }
 
 // Returns a value of "-format" option.
@@ -1029,7 +1057,10 @@
       StringRef From;
       StringRef To;
       std::tie(From, To) = StringRef(Arg->getValue()).split('=');
-      readDefsym(From, MemoryBufferRef(To, "-defsym"));
+      if (From.empty() || To.empty())
+        error("-defsym: syntax error: " + StringRef(Arg->getValue()));
+      else
+        readDefsym(From, MemoryBufferRef(To, "-defsym"));
       break;
     }
     case OPT_script:
@@ -1230,33 +1261,19 @@
     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;
-}
-
-// Some files, such as .so or files between -{start,end}-lib may be removed
-// after their symbols are added to the symbol table. If that happens, we
-// need to remove symbols that refer files that no longer exist, so that
-// they won't appear in the symbol table of the output file.
-//
-// We remove symbols by demoting them to undefined symbol.
-template <class ELFT> static void demoteSymbols() {
+// 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.
+template <class ELFT> static void demoteSharedSymbols() {
   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;
+    if (auto *S = dyn_cast<SharedSymbol>(Sym)) {
+      if (!S->getFile<ELFT>().IsNeeded) {
+        bool Used = S->Used;
+        replaceSymbol<Undefined>(S, nullptr, S->getName(), STB_WEAK, S->StOther,
+                                 S->Type);
+        S->Used = Used;
+      }
     }
   }
 }
@@ -1325,6 +1342,80 @@
   }
 }
 
+// The --wrap option is a feature to rename symbols so that you can write
+// wrappers for existing functions. If you pass `-wrap=foo`, all
+// occurrences of symbol `foo` are resolved to `wrap_foo` (so, you are
+// expected to write `wrap_foo` function as a wrapper). The original
+// symbol becomes accessible as `real_foo`, so you can call that from your
+// wrapper.
+//
+// This data structure is instantiated for each -wrap option.
+struct WrappedSymbol {
+  Symbol *Sym;
+  Symbol *Real;
+  Symbol *Wrap;
+};
+
+// Handles -wrap option.
+//
+// This function instantiates wrapper symbols. At this point, they seem
+// like they are not being used at all, so we explicitly set some flags so
+// that LTO won't eliminate them.
+template <class ELFT>
+static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &Args) {
+  std::vector<WrappedSymbol> V;
+  DenseSet<StringRef> Seen;
+
+  for (auto *Arg : Args.filtered(OPT_wrap)) {
+    StringRef Name = Arg->getValue();
+    if (!Seen.insert(Name).second)
+      continue;
+
+    Symbol *Sym = Symtab->find(Name);
+    if (!Sym)
+      continue;
+
+    Symbol *Real = Symtab->addUndefined<ELFT>(Saver.save("__real_" + Name));
+    Symbol *Wrap = Symtab->addUndefined<ELFT>(Saver.save("__wrap_" + Name));
+    V.push_back({Sym, Real, Wrap});
+
+    // We want to tell LTO not to inline symbols to be overwritten
+    // because LTO doesn't know the final symbol contents after renaming.
+    Real->CanInline = false;
+    Sym->CanInline = false;
+
+    // Tell LTO not to eliminate these symbols.
+    Sym->IsUsedInRegularObj = true;
+    Wrap->IsUsedInRegularObj = true;
+  }
+  return V;
+}
+
+// Do renaming for -wrap by updating pointers to symbols.
+//
+// When this function is executed, only InputFiles and symbol table
+// contain pointers to symbol objects. We visit them to replace pointers,
+// so that wrapped symbols are swapped as instructed by the command line.
+template <class ELFT> static void wrapSymbols(ArrayRef<WrappedSymbol> Wrapped) {
+  DenseMap<Symbol *, Symbol *> Map;
+  for (const WrappedSymbol &W : Wrapped) {
+    Map[W.Sym] = W.Wrap;
+    Map[W.Real] = W.Sym;
+  }
+
+  // Update pointers in input files.
+  parallelForEach(ObjectFiles, [&](InputFile *File) {
+    std::vector<Symbol *> &Syms = File->getMutableSymbols();
+    for (size_t I = 0, E = Syms.size(); I != E; ++I)
+      if (Symbol *S = Map.lookup(Syms[I]))
+        Syms[I] = S;
+  });
+
+  // Update pointers in the symbol table.
+  for (const WrappedSymbol &W : Wrapped)
+    Symtab->wrap(W.Sym, W.Real, W.Wrap);
+}
+
 static const char *LibcallRoutineNames[] = {
 #define HANDLE_LIBCALL(code, name) name,
 #include "llvm/IR/RuntimeLibcalls.def"
@@ -1335,6 +1426,8 @@
 // all linker scripts have already been parsed.
 template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
   Target = getTarget();
+  InX<ELFT>::VerSym = nullptr;
+  InX<ELFT>::VerNeed = nullptr;
 
   Config->MaxPageSize = getMaxPageSize(Args);
   Config->ImageBase = getImageBase(Args);
@@ -1456,8 +1549,7 @@
     Symtab->scanVersionScript();
 
   // Create wrapped symbols for -wrap option.
-  for (auto *Arg : Args.filtered(OPT_wrap))
-    Symtab->addSymbolWrap<ELFT>(Arg->getValue());
+  std::vector<WrappedSymbol> Wrapped = addWrappedSymbols<ELFT>(Args);
 
   // Do link-time optimization if given files are LLVM bitcode files.
   // This compiles bitcode files into real object files.
@@ -1475,7 +1567,8 @@
     return;
 
   // Apply symbol renames for -wrap.
-  Symtab->applySymbolWrap();
+  if (!Wrapped.empty())
+    wrapSymbols<ELFT>(Wrapped);
 
   // Now that we have a complete list of input files.
   // Beyond this point, no new files are added.
@@ -1504,26 +1597,18 @@
     if (Config->ARMHasBlx == false)
       warn("lld uses blx instruction, no object with architecture supporting "
            "feature detected.");
-    if (Config->ARMJ1J2BranchEncoding == false)
-      warn("lld uses extended branch encoding, no object with architecture "
-           "supporting feature detected.");
-    if (Config->ARMHasMovtMovw == false)
-      warn("lld may use movt/movw, no object with architecture supporting "
-           "feature detected.");
   }
 
   // This adds a .comment section containing a version string. We have to add it
-  // before decompressAndMergeSections because the .comment section is a
-  // mergeable section.
+  // before mergeSections because the .comment section is a mergeable section.
   if (!Config->Relocatable)
     InputSections.push_back(createCommentSection());
 
   // Do size optimizations: garbage collection, merging of SHF_MERGE sections
   // and identical code folding.
-  decompressSections();
   splitSections<ELFT>();
   markLive<ELFT>();
-  demoteSymbols<ELFT>();
+  demoteSharedSymbols<ELFT>();
   mergeSections();
   if (Config->ICF != ICFLevel::None) {
     findKeepUniqueSections<ELFT>(Args);
@@ -1534,6 +1619,7 @@
   if (auto *Arg = Args.getLastArg(OPT_call_graph_ordering_file))
     if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
       readCallGraph(*Buffer);
+  readCallGraphsFromObjectFiles<ELFT>();
 
   // Write the result to the file.
   writeResult<ELFT>();
diff --git a/ELF/DriverUtils.cpp b/ELF/DriverUtils.cpp
index 698e06e..d8d317a 100644
--- a/ELF/DriverUtils.cpp
+++ b/ELF/DriverUtils.cpp
@@ -24,6 +24,7 @@
 #include "llvm/Option/Option.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Process.h"
 
@@ -139,8 +140,9 @@
 }
 
 void elf::printHelp() {
-  ELFOptTable().PrintHelp(outs(), Config->ProgName.data(), "lld",
-                          false /*ShowHidden*/, true /*ShowAllAliases*/);
+  std::string Usage = formatv("{0} [options] file...", Config->ProgName).str();
+  ELFOptTable().PrintHelp(outs(), Usage.c_str(), "lld", false /*ShowHidden*/,
+                          true /*ShowAllAliases*/);
   outs() << "\n";
 
   // Scripts generated by Libtool versions up to at least 2.4.6 (the most
diff --git a/ELF/EhFrame.cpp b/ELF/EhFrame.cpp
index 20b32c0..95d444b 100644
--- a/ELF/EhFrame.cpp
+++ b/ELF/EhFrame.cpp
@@ -44,7 +44,7 @@
 private:
   template <class P> void failOn(const P *Loc, const Twine &Msg) {
     fatal("corrupted .eh_frame: " + Msg + "\n>>> defined in " +
-          IS->getObjMsg((const uint8_t *)Loc - IS->Data.data()));
+          IS->getObjMsg((const uint8_t *)Loc - IS->data().data()));
   }
 
   uint8_t readByte();
@@ -59,7 +59,7 @@
 }
 
 size_t elf::readEhRecordSize(InputSectionBase *S, size_t Off) {
-  return EhReader(S, S->Data.slice(Off)).readEhRecordSize();
+  return EhReader(S, S->data().slice(Off)).readEhRecordSize();
 }
 
 // .eh_frame section is a sequence of records. Each record starts with
diff --git a/ELF/ICF.cpp b/ELF/ICF.cpp
index 075938b..176c627 100644
--- a/ELF/ICF.cpp
+++ b/ELF/ICF.cpp
@@ -252,7 +252,10 @@
 
     auto *DA = dyn_cast<Defined>(&SA);
     auto *DB = dyn_cast<Defined>(&SB);
-    if (!DA || !DB)
+
+    // Placeholder symbols generated by linker scripts look the same now but
+    // may have different values later.
+    if (!DA || !DB || DA->ScriptDefined || DB->ScriptDefined)
       return false;
 
     // Relocations referring to absolute symbols are constant-equal if their
@@ -298,7 +301,7 @@
 template <class ELFT>
 bool ICF<ELFT>::equalsConstant(const InputSection *A, const InputSection *B) {
   if (A->NumRelocations != B->NumRelocations || A->Flags != B->Flags ||
-      A->getSize() != B->getSize() || A->Data != B->Data)
+      A->getSize() != B->getSize() || A->data() != B->data())
     return false;
 
   // If two sections have different output sections, we cannot merge them.
@@ -436,7 +439,7 @@
   // Initially, we use hash values to partition sections.
   parallelForEach(Sections, [&](InputSection *S) {
     // Set MSB to 1 to avoid collisions with non-hash IDs.
-    S->Class[0] = xxHash64(S->Data) | (1U << 31);
+    S->Class[0] = xxHash64(S->data()) | (1U << 31);
   });
 
   // From now on, sections in Sections vector are ordered so that sections
diff --git a/ELF/InputFiles.cpp b/ELF/InputFiles.cpp
index e4a32be..3980403 100644
--- a/ELF/InputFiles.cpp
+++ b/ELF/InputFiles.cpp
@@ -125,10 +125,6 @@
 
 template <class ELFT> void ObjFile<ELFT>::initializeDwarf() {
   Dwarf = llvm::make_unique<DWARFContext>(make_unique<LLDDwarfObj<ELFT>>(this));
-  const DWARFObject &Obj = Dwarf->getDWARFObj();
-  DWARFDataExtractor LineData(Obj, Obj.getLineSection(), Config->IsLE,
-                              Config->Wordsize);
-
   for (std::unique_ptr<DWARFUnit> &CU : Dwarf->compile_units()) {
     auto Report = [](Error Err) {
       handleAllErrors(std::move(Err),
@@ -416,6 +412,11 @@
       continue;
     const Elf_Shdr &Sec = ObjSections[I];
 
+    if (Sec.sh_type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE)
+      CGProfile = check(
+          this->getObj().template getSectionContentsAsArray<Elf_CGProfile>(
+              &Sec));
+
     // SHF_EXCLUDE'ed sections are discarded by the linker. However,
     // if -r is given, we'll let the final link discard such sections.
     // This is compatible with GNU.
@@ -442,6 +443,10 @@
       bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second;
       this->Sections[I] = &InputSection::Discarded;
 
+      // We only support GRP_COMDAT type of group. Get the all entries of the
+      // section here to let getShtGroupEntries to check the type early for us.
+      ArrayRef<Elf_Word> Entries = getShtGroupEntries(Sec);
+
       // If it is a new section group, we want to keep group members.
       // Group leader sections, which contain indices of group members, are
       // discarded because they are useless beyond this point. The only
@@ -454,7 +459,7 @@
       }
 
       // Otherwise, discard group members.
-      for (uint32_t SecIndex : getShtGroupEntries(Sec)) {
+      for (uint32_t SecIndex : Entries) {
         if (SecIndex >= Size)
           fatal(toString(this) +
                 ": invalid section index in group: " + Twine(SecIndex));
@@ -478,11 +483,13 @@
     // .ARM.exidx sections have a reverse dependency on the InputSection they
     // have a SHF_LINK_ORDER dependency, this is identified by the sh_link.
     if (Sec.sh_flags & SHF_LINK_ORDER) {
-      if (Sec.sh_link >= this->Sections.size())
+      InputSectionBase *LinkSec = nullptr;
+      if (Sec.sh_link < this->Sections.size())
+        LinkSec = this->Sections[Sec.sh_link];
+      if (!LinkSec)
         fatal(toString(this) +
               ": invalid sh_link index: " + Twine(Sec.sh_link));
 
-      InputSectionBase *LinkSec = this->Sections[Sec.sh_link];
       InputSection *IS = cast<InputSection>(this->Sections[I]);
       LinkSec->DependentSections.push_back(IS);
       if (!isa<InputSection>(LinkSec))
@@ -598,7 +605,7 @@
 // as a given section.
 static InputSection *toRegularSection(MergeInputSection *Sec) {
   return make<InputSection>(Sec->File, Sec->Flags, Sec->Type, Sec->Alignment,
-                            Sec->Data, Sec->Name);
+                            Sec->data(), Sec->Name);
 }
 
 template <class ELFT>
@@ -618,9 +625,9 @@
     // FIXME: Retain the first attribute section we see. The eglibc ARM
     // dynamic loaders require the presence of an attribute section for dlopen
     // to work. In a full implementation we would merge all attribute sections.
-    if (InX::ARMAttributes == nullptr) {
-      InX::ARMAttributes = make<InputSection>(*this, Sec, Name);
-      return InX::ARMAttributes;
+    if (In.ARMAttributes == nullptr) {
+      In.ARMAttributes = make<InputSection>(*this, Sec, Name);
+      return In.ARMAttributes;
     }
     return &InputSection::Discarded;
   }
@@ -704,7 +711,7 @@
   // for split stack will include a .note.GNU-split-stack section.
   if (Name == ".note.GNU-split-stack") {
     if (Config->Relocatable) {
-      error("Cannot mix split-stack and non-split-stack in a relocatable link");
+      error("cannot mix split-stack and non-split-stack in a relocatable link");
       return &InputSection::Discarded;
     }
     this->SplitStack = true;
@@ -992,7 +999,17 @@
   for (size_t I = 0; I < Syms.size(); ++I) {
     const Elf_Sym &Sym = Syms[I];
 
+    // ELF spec requires that all local symbols precede weak or global
+    // symbols in each symbol table, and the index of first non-local symbol
+    // is stored to sh_info. If a local symbol appears after some non-local
+    // symbol, that's a violation of the spec.
     StringRef Name = CHECK(Sym.getName(this->StringTable), this);
+    if (Sym.getBinding() == STB_LOCAL) {
+      warn("found local symbol '" + Name +
+           "' in global part of symbol table in file " + toString(this));
+      continue;
+    }
+
     if (Sym.isUndefined()) {
       Symbol *S = Symtab->addUndefined<ELFT>(Name, Sym.getBinding(),
                                              Sym.st_other, Sym.getType(),
@@ -1001,16 +1018,6 @@
       continue;
     }
 
-    // ELF spec requires that all local symbols precede weak or global
-    // symbols in each symbol table, and the index of first non-local symbol
-    // is stored to sh_info. If a local symbol appears after some non-local
-    // symbol, that's a violation of the spec.
-    if (Sym.getBinding() == STB_LOCAL) {
-      warn("found local symbol '" + Name +
-           "' in global part of symbol table in file " + toString(this));
-      continue;
-    }
-
     // MIPS BFD linker puts _gp_disp symbol into DSO files and incorrectly
     // assigns VER_NDX_LOCAL to this section global symbol. Here is a
     // workaround for this bug.
@@ -1053,6 +1060,9 @@
   switch (T.getArch()) {
   case Triple::aarch64:
     return EM_AARCH64;
+  case Triple::amdgcn:
+  case Triple::r600:
+    return EM_AMDGPU;
   case Triple::arm:
   case Triple::thumb:
     return EM_ARM;
@@ -1066,6 +1076,7 @@
   case Triple::ppc:
     return EM_PPC;
   case Triple::ppc64:
+  case Triple::ppc64le:
     return EM_PPC64;
   case Triple::x86:
     return T.isOSIAMCU() ? EM_IAMCU : EM_386;
@@ -1261,25 +1272,11 @@
     return;
   }
 
-  switch (getELFKind(this->MB)) {
-  case ELF32LEKind:
-    addElfSymbols<ELF32LE>();
+  if (getELFKind(this->MB) != Config->EKind) {
+    error("incompatible file: " + this->MB.getBufferIdentifier());
     return;
-  case ELF32BEKind:
-    addElfSymbols<ELF32BE>();
-    return;
-  case ELF64LEKind:
-    addElfSymbols<ELF64LE>();
-    return;
-  case ELF64BEKind:
-    addElfSymbols<ELF64BE>();
-    return;
-  default:
-    llvm_unreachable("getELFKind");
   }
-}
 
-template <class ELFT> void LazyObjFile::addElfSymbols() {
   ELFFile<ELFT> Obj = check(ELFFile<ELFT>::create(MB.getBuffer()));
   ArrayRef<typename ELFT::Shdr> Sections = CHECK(Obj.sections(), this);
 
@@ -1304,12 +1301,9 @@
   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();
+  if (Path.consume_back(Suffix))
+    return (Path + Repl).str();
+  return Path;
 }
 
 template void ArchiveFile::parse<ELF32LE>();
diff --git a/ELF/InputFiles.h b/ELF/InputFiles.h
index 0db3203..3481a0a 100644
--- a/ELF/InputFiles.h
+++ b/ELF/InputFiles.h
@@ -86,7 +86,9 @@
 
   // Returns object file symbols. It is a runtime error to call this
   // function on files of other types.
-  ArrayRef<Symbol *> getSymbols() {
+  ArrayRef<Symbol *> getSymbols() { return getMutableSymbols(); }
+
+  std::vector<Symbol *> &getMutableSymbols() {
     assert(FileKind == BinaryKind || FileKind == ObjKind ||
            FileKind == BitcodeKind);
     return Symbols;
@@ -169,6 +171,7 @@
   typedef typename ELFT::Sym Elf_Sym;
   typedef typename ELFT::Shdr Elf_Shdr;
   typedef typename ELFT::Word Elf_Word;
+  typedef typename ELFT::CGProfile Elf_CGProfile;
 
   StringRef getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
                                  const Elf_Shdr &Sec);
@@ -218,6 +221,9 @@
   // Pointer to this input file's .llvm_addrsig section, if it has one.
   const Elf_Shdr *AddrsigSec = nullptr;
 
+  // SHT_LLVM_CALL_GRAPH_PROFILE table
+  ArrayRef<Elf_CGProfile> CGProfile;
+
 private:
   void
   initializeSections(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
@@ -272,8 +278,6 @@
   bool AddedToLink = false;
 
 private:
-  template <class ELFT> void addElfSymbols();
-
   uint64_t OffsetInArchive;
 };
 
diff --git a/ELF/InputSection.cpp b/ELF/InputSection.cpp
index 48603a3..9da4af6 100644
--- a/ELF/InputSection.cpp
+++ b/ELF/InputSection.cpp
@@ -21,7 +21,6 @@
 #include "Thunks.h"
 #include "lld/Common/ErrorHandler.h"
 #include "lld/Common/Memory.h"
-#include "llvm/Object/Decompressor.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Compression.h"
 #include "llvm/Support/Endian.h"
@@ -64,11 +63,11 @@
                                    StringRef Name, Kind SectionKind)
     : SectionBase(SectionKind, Name, Flags, Entsize, Alignment, Type, Info,
                   Link),
-      File(File), Data(Data) {
+      File(File), RawData(Data) {
   // In order to reduce memory allocation, we assume that mergeable
   // sections are smaller than 4 GiB, which is not an unreasonable
   // assumption as of 2017.
-  if (SectionKind == SectionBase::Merge && Data.size() > UINT32_MAX)
+  if (SectionKind == SectionBase::Merge && RawData.size() > UINT32_MAX)
     error(toString(this) + ": section too large");
 
   NumRelocations = 0;
@@ -80,6 +79,17 @@
   if (!isPowerOf2_64(V))
     fatal(toString(File) + ": section sh_addralign is not a power of 2");
   this->Alignment = V;
+
+  // In ELF, each section can be compressed by zlib, and if compressed,
+  // section name may be mangled by appending "z" (e.g. ".zdebug_info").
+  // If that's the case, demangle section name so that we can handle a
+  // section as if it weren't compressed.
+  if ((Flags & SHF_COMPRESSED) || Name.startswith(".zdebug")) {
+    if (!zlib::isAvailable())
+      error(toString(File) + ": contains a compressed section, " +
+            "but zlib is not available");
+    parseCompressedHeader();
+  }
 }
 
 // Drop SHF_GROUP bit unless we are producing a re-linkable object file.
@@ -128,13 +138,25 @@
 size_t InputSectionBase::getSize() const {
   if (auto *S = dyn_cast<SyntheticSection>(this))
     return S->getSize();
+  if (UncompressedSize >= 0)
+    return UncompressedSize;
+  return RawData.size();
+}
 
-  return Data.size();
+void InputSectionBase::uncompress() const {
+  size_t Size = UncompressedSize;
+  UncompressedBuf.reset(new char[Size]);
+
+  if (Error E =
+          zlib::uncompress(toStringRef(RawData), UncompressedBuf.get(), Size))
+    fatal(toString(this) +
+          ": uncompress failed: " + llvm::toString(std::move(E)));
+  RawData = makeArrayRef((uint8_t *)UncompressedBuf.get(), Size);
 }
 
 uint64_t InputSectionBase::getOffsetInFile() const {
   const uint8_t *FileStart = (const uint8_t *)File->MB.getBufferStart();
-  const uint8_t *SecStart = Data.begin();
+  const uint8_t *SecStart = data().begin();
   return SecStart - FileStart;
 }
 
@@ -180,34 +202,70 @@
   return Sec ? Sec->getParent() : nullptr;
 }
 
-// Decompress section contents if required. Note that this function
-// is called from parallelForEach, so it must be thread-safe.
-void InputSectionBase::maybeDecompress() {
-  if (DecompressBuf)
+// When a section is compressed, `RawData` consists with a header followed
+// by zlib-compressed data. This function parses a header to initialize
+// `UncompressedSize` member and remove the header from `RawData`.
+void InputSectionBase::parseCompressedHeader() {
+  typedef typename ELF64LE::Chdr Chdr64;
+  typedef typename ELF32LE::Chdr Chdr32;
+
+  // Old-style header
+  if (Name.startswith(".zdebug")) {
+    if (!toStringRef(RawData).startswith("ZLIB")) {
+      error(toString(this) + ": corrupted compressed section header");
+      return;
+    }
+    RawData = RawData.slice(4);
+
+    if (RawData.size() < 8) {
+      error(toString(this) + ": corrupted compressed section header");
+      return;
+    }
+
+    UncompressedSize = read64be(RawData.data());
+    RawData = RawData.slice(8);
+
+    // Restore the original section name.
+    // (e.g. ".zdebug_info" -> ".debug_info")
+    Name = Saver.save("." + Name.substr(2));
     return;
-  if (!(Flags & SHF_COMPRESSED) && !Name.startswith(".zdebug"))
-    return;
+  }
 
-  // Decompress a section.
-  Decompressor Dec = check(Decompressor::create(Name, toStringRef(Data),
-                                                Config->IsLE, Config->Is64));
-
-  size_t Size = Dec.getDecompressedSize();
-  DecompressBuf.reset(new char[Size + Name.size()]());
-  if (Error E = Dec.decompress({DecompressBuf.get(), Size}))
-    fatal(toString(this) +
-          ": decompress failed: " + llvm::toString(std::move(E)));
-
-  Data = makeArrayRef((uint8_t *)DecompressBuf.get(), Size);
+  assert(Flags & SHF_COMPRESSED);
   Flags &= ~(uint64_t)SHF_COMPRESSED;
 
-  // A section name may have been altered if compressed. If that's
-  // the case, restore the original name. (i.e. ".zdebug_" -> ".debug_")
-  if (Name.startswith(".zdebug")) {
-    DecompressBuf[Size] = '.';
-    memcpy(&DecompressBuf[Size + 1], Name.data() + 2, Name.size() - 2);
-    Name = StringRef(&DecompressBuf[Size], Name.size() - 1);
+  // New-style 64-bit header
+  if (Config->Is64) {
+    if (RawData.size() < sizeof(Chdr64)) {
+      error(toString(this) + ": corrupted compressed section");
+      return;
+    }
+
+    auto *Hdr = reinterpret_cast<const Chdr64 *>(RawData.data());
+    if (Hdr->ch_type != ELFCOMPRESS_ZLIB) {
+      error(toString(this) + ": unsupported compression type");
+      return;
+    }
+
+    UncompressedSize = Hdr->ch_size;
+    RawData = RawData.slice(sizeof(*Hdr));
+    return;
   }
+
+  // New-style 32-bit header
+  if (RawData.size() < sizeof(Chdr32)) {
+    error(toString(this) + ": corrupted compressed section");
+    return;
+  }
+
+  auto *Hdr = reinterpret_cast<const Chdr32 *>(RawData.data());
+  if (Hdr->ch_type != ELFCOMPRESS_ZLIB) {
+    error(toString(this) + ": unsupported compression type");
+    return;
+  }
+
+  UncompressedSize = Hdr->ch_size;
+  RawData = RawData.slice(sizeof(*Hdr));
 }
 
 InputSection *InputSectionBase::getLinkOrderDep() const {
@@ -356,7 +414,7 @@
     // Output section VA is zero for -r, so r_offset is an offset within the
     // section, but for --emit-relocs it is an virtual address.
     P->r_offset = Sec->getVA(Rel.r_offset);
-    P->setSymbolAndType(InX::SymTab->getSymbolIndex(&Sym), Type,
+    P->setSymbolAndType(In.SymTab->getSymbolIndex(&Sym), Type,
                         Config->IsMips64EL);
 
     if (Sym.Type == STT_SECTION) {
@@ -381,7 +439,7 @@
       }
 
       int64_t Addend = getAddend<ELFT>(Rel);
-      const uint8_t *BufLoc = Sec->Data.begin() + Rel.r_offset;
+      const uint8_t *BufLoc = Sec->data().begin() + Rel.r_offset;
       if (!RelTy::IsRela)
         Addend = Target->getImplicitAddend(BufLoc, Type);
 
@@ -402,7 +460,7 @@
       }
 
       if (RelTy::IsRela)
-        P->r_addend = Sym.getVA(Addend) - Section->getOutputSection()->Addr;
+        P->r_addend = Sym.getVA(Addend) - Section->Repl->getOutputSection()->Addr;
       else if (Config->Relocatable)
         Sec->Relocations.push_back({R_ABS, Type, Rel.r_offset, Addend, &Sym});
     }
@@ -525,16 +583,16 @@
   case R_RELAX_TLS_GD_TO_IE_ABS:
     return Sym.getGotVA() + A;
   case R_GOTONLY_PC:
-    return InX::Got->getVA() + A - P;
+    return In.Got->getVA() + A - P;
   case R_GOTONLY_PC_FROM_END:
-    return InX::Got->getVA() + A - P + InX::Got->getSize();
+    return In.Got->getVA() + A - P + In.Got->getSize();
   case R_GOTREL:
-    return Sym.getVA(A) - InX::Got->getVA();
+    return Sym.getVA(A) - In.Got->getVA();
   case R_GOTREL_FROM_END:
-    return Sym.getVA(A) - InX::Got->getVA() - InX::Got->getSize();
+    return Sym.getVA(A) - In.Got->getVA() - In.Got->getSize();
   case R_GOT_FROM_END:
   case R_RELAX_TLS_GD_TO_IE_END:
-    return Sym.getGotOffset() + A - InX::Got->getSize();
+    return Sym.getGotOffset() + A - In.Got->getSize();
   case R_TLSLD_GOT_OFF:
   case R_GOT_OFF:
   case R_RELAX_TLS_GD_TO_IE_GOT_OFF:
@@ -545,10 +603,12 @@
   case R_GOT_PC:
   case R_RELAX_TLS_GD_TO_IE:
     return Sym.getGotVA() + A - P;
+  case R_HEXAGON_GOT:
+    return Sym.getGotVA() - In.GotPlt->getVA();
   case R_MIPS_GOTREL:
-    return Sym.getVA(A) - InX::MipsGot->getGp(File);
+    return Sym.getVA(A) - In.MipsGot->getGp(File);
   case R_MIPS_GOT_GP:
-    return InX::MipsGot->getGp(File) + A;
+    return In.MipsGot->getGp(File) + A;
   case R_MIPS_GOT_GP_PC: {
     // R_MIPS_LO16 expression has R_MIPS_GOT_GP_PC type iif the target
     // is _gp_disp symbol. In that case we should use the following
@@ -557,7 +617,7 @@
     // microMIPS variants of these relocations use slightly different
     // expressions: AHL + GP - P + 3 for %lo() and AHL + GP - P - 1 for %hi()
     // to correctly handle less-sugnificant bit of the microMIPS symbol.
-    uint64_t V = InX::MipsGot->getGp(File) + A - P;
+    uint64_t V = In.MipsGot->getGp(File) + A - P;
     if (Type == R_MIPS_LO16 || Type == R_MICROMIPS_LO16)
       V += 4;
     if (Type == R_MICROMIPS_LO16 || Type == R_MICROMIPS_HI16)
@@ -568,23 +628,21 @@
     // If relocation against MIPS local symbol requires GOT entry, this entry
     // should be initialized by 'page address'. This address is high 16-bits
     // of sum the symbol's value and the addend.
-    return InX::MipsGot->getVA() +
-           InX::MipsGot->getPageEntryOffset(File, Sym, A) -
-           InX::MipsGot->getGp(File);
+    return In.MipsGot->getVA() + In.MipsGot->getPageEntryOffset(File, Sym, A) -
+           In.MipsGot->getGp(File);
   case R_MIPS_GOT_OFF:
   case R_MIPS_GOT_OFF32:
     // In case of MIPS if a GOT relocation has non-zero addend this addend
     // should be applied to the GOT entry content not to the GOT entry offset.
     // That is why we use separate expression type.
-    return InX::MipsGot->getVA() +
-           InX::MipsGot->getSymEntryOffset(File, Sym, A) -
-           InX::MipsGot->getGp(File);
+    return In.MipsGot->getVA() + In.MipsGot->getSymEntryOffset(File, Sym, A) -
+           In.MipsGot->getGp(File);
   case R_MIPS_TLSGD:
-    return InX::MipsGot->getVA() + InX::MipsGot->getGlobalDynOffset(File, Sym) -
-           InX::MipsGot->getGp(File);
+    return In.MipsGot->getVA() + In.MipsGot->getGlobalDynOffset(File, Sym) -
+           In.MipsGot->getGp(File);
   case R_MIPS_TLSLD:
-    return InX::MipsGot->getVA() + InX::MipsGot->getTlsIndexOffset(File) -
-           InX::MipsGot->getGp(File);
+    return In.MipsGot->getVA() + In.MipsGot->getTlsIndexOffset(File) -
+           In.MipsGot->getGp(File);
   case R_PAGE_PC:
   case R_PLT_PAGE_PC: {
     uint64_t Dest;
@@ -631,16 +689,12 @@
       return 0;
 
     // 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);
+    // point is used for calls where the caller and callee (may) have different
+    // TOC base pointers and r2 needs to be modified to hold the TOC base for
+    // the callee. For local calls the caller and callee share the same
+    // TOC base and so the TOC pointer initialization code should be skipped by
+    // branching to the local entry point.
+    return SymVA - P + getPPC64GlobalEntryToLocalEntryOffset(Sym.StOther);
   }
   case R_PPC_TOC:
     return getPPC64TocBase() + A;
@@ -681,22 +735,22 @@
   case R_SIZE:
     return Sym.getSize() + A;
   case R_TLSDESC:
-    return InX::Got->getGlobalDynAddr(Sym) + A;
+    return In.Got->getGlobalDynAddr(Sym) + A;
   case R_TLSDESC_PAGE:
-    return getAArch64Page(InX::Got->getGlobalDynAddr(Sym) + A) -
+    return getAArch64Page(In.Got->getGlobalDynAddr(Sym) + A) -
            getAArch64Page(P);
   case R_TLSGD_GOT:
-    return InX::Got->getGlobalDynOffset(Sym) + A;
+    return In.Got->getGlobalDynOffset(Sym) + A;
   case R_TLSGD_GOT_FROM_END:
-    return InX::Got->getGlobalDynOffset(Sym) + A - InX::Got->getSize();
+    return In.Got->getGlobalDynOffset(Sym) + A - In.Got->getSize();
   case R_TLSGD_PC:
-    return InX::Got->getGlobalDynAddr(Sym) + A - P;
+    return In.Got->getGlobalDynAddr(Sym) + A - P;
   case R_TLSLD_GOT_FROM_END:
-    return InX::Got->getTlsIndexOff() + A - InX::Got->getSize();
+    return In.Got->getTlsIndexOff() + A - In.Got->getSize();
   case R_TLSLD_GOT:
-    return InX::Got->getTlsIndexOff() + A;
+    return In.Got->getTlsIndexOff() + A;
   case R_TLSLD_PC:
-    return InX::Got->getTlsIndexVA() + A - P;
+    return In.Got->getTlsIndexVA() + A - P;
   default:
     llvm_unreachable("invalid expression");
   }
@@ -879,14 +933,13 @@
   }
 
   // Sort both collections to compare addresses efficiently.
-  llvm::sort(MorestackCalls.begin(), MorestackCalls.end(),
-             [](const Relocation *L, const Relocation *R) {
-               return L->Offset < R->Offset;
-             });
+  llvm::sort(MorestackCalls, [](const Relocation *L, const Relocation *R) {
+    return L->Offset < R->Offset;
+  });
   std::vector<Defined *> Functions(Prologues.begin(), Prologues.end());
-  llvm::sort(
-      Functions.begin(), Functions.end(),
-      [](const Defined *L, const Defined *R) { return L->Value < R->Value; });
+  llvm::sort(Functions, [](const Defined *L, const Defined *R) {
+    return L->Value < R->Value;
+  });
 
   auto It = MorestackCalls.begin();
   for (Defined *F : Functions) {
@@ -928,9 +981,8 @@
       continue;
 
     // Ignore calls into the split-stack api.
-    Defined *D = cast<Defined>(Rel.Sym);
-    if (D->getName().startswith("__morestack")) {
-      if (D->getName().equals("__morestack"))
+    if (Rel.Sym->getName().startswith("__morestack")) {
+      if (Rel.Sym->getName().equals("__morestack"))
         MorestackCalls.push_back(&Rel);
       continue;
     }
@@ -938,13 +990,18 @@
     // A relocation to non-function isn't relevant. Sometimes
     // __morestack is not marked as a function, so this check comes
     // after the name check.
-    if (D->Type != STT_FUNC)
+    if (Rel.Sym->Type != STT_FUNC)
       continue;
 
-    // If the callee's-file was compiled with split stack, nothing to do.
-    auto *IS = cast_or_null<InputSection>(D->Section);
-    if (!IS || IS->getFile<ELFT>()->SplitStack)
-      continue;
+    // If the callee's-file was compiled with split stack, nothing to do.  In
+    // this context, a "Defined" symbol is one "defined by the binary currently
+    // being produced". So an "undefined" symbol might be provided by a shared
+    // library. It is not possible to tell how such symbols were compiled, so be
+    // conservative.
+    if (Defined *D = dyn_cast<Defined>(Rel.Sym))
+      if (InputSection *IS = cast_or_null<InputSection>(D->Section))
+        if (!IS || !IS->getFile<ELFT>() || IS->getFile<ELFT>()->SplitStack)
+          continue;
 
     if (enclosingPrologueAttempted(Rel.Offset, Prologues))
       continue;
@@ -956,7 +1013,7 @@
         continue;
       if (!getFile<ELFT>()->SomeNoSplitStack)
         error(lld::toString(this) + ": " + F->getName() +
-              " (with -fsplit-stack) calls " + D->getName() +
+              " (with -fsplit-stack) calls " + Rel.Sym->getName() +
               " (without -fsplit-stack), but couldn't adjust its prologue");
     }
   }
@@ -989,10 +1046,23 @@
     return;
   }
 
+  // If this is a compressed section, uncompress section contents directly
+  // to the buffer.
+  if (UncompressedSize >= 0 && !UncompressedBuf) {
+    size_t Size = UncompressedSize;
+    if (Error E = zlib::uncompress(toStringRef(RawData),
+                                   (char *)(Buf + OutSecOff), Size))
+      fatal(toString(this) +
+            ": uncompress failed: " + llvm::toString(std::move(E)));
+    uint8_t *BufEnd = Buf + OutSecOff + Size;
+    relocate<ELFT>(Buf, BufEnd);
+    return;
+  }
+
   // Copy section contents from source object file to output file
   // and then apply relocations.
-  memcpy(Buf + OutSecOff, Data.data(), Data.size());
-  uint8_t *BufEnd = Buf + OutSecOff + Data.size();
+  memcpy(Buf + OutSecOff, data().data(), data().size());
+  uint8_t *BufEnd = Buf + OutSecOff + data().size();
   relocate<ELFT>(Buf, BufEnd);
 }
 
@@ -1043,7 +1113,7 @@
 template <class ELFT, class RelTy>
 void EhInputSection::split(ArrayRef<RelTy> Rels) {
   unsigned RelI = 0;
-  for (size_t Off = 0, End = Data.size(); Off != End;) {
+  for (size_t Off = 0, End = data().size(); Off != End;) {
     size_t Size = readEhRecordSize(this, Off);
     Pieces.emplace_back(Off, this, Size, getReloc(Off, Size, Rels, RelI));
     // The empty record is the end marker.
@@ -1123,9 +1193,9 @@
   assert(Pieces.empty());
 
   if (Flags & SHF_STRINGS)
-    splitStrings(Data, Entsize);
+    splitStrings(data(), Entsize);
   else
-    splitNonStrings(Data, Entsize);
+    splitNonStrings(data(), Entsize);
 
   OffsetMap.reserve(Pieces.size());
   for (size_t I = 0, E = Pieces.size(); I != E; ++I)
@@ -1145,43 +1215,32 @@
   return Comp(Value, *First) ? First : First + 1;
 }
 
-// Do binary search to get a section piece at a given input offset.
-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(
-      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) {
+  if (this->data().size() <= Offset)
+    fatal(toString(this) + ": offset is outside the section");
+
   // 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);
+  // In that case we need to  do a binary search of the original section piece vector.
+  auto I = fastUpperBound(
+      Pieces.begin(), Pieces.end(), Offset,
+      [](const uint64_t &A, const SectionPiece &B) { return A < B.InputOff; });
+  --I;
+  return &*I;
 }
 
 // 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::getParentOffset(uint64_t Offset) const {
-  // Find a string starting at a given offset.
-  auto It = OffsetMap.find(Offset);
-  if (It != OffsetMap.end())
-    return Pieces[It->second].OutputOff;
-
   // 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 =
-      *findSectionPiece(const_cast<MergeInputSection *>(this), Offset);
+      *(const_cast<MergeInputSection *>(this)->getSectionPiece (Offset));
   uint64_t Addend = Offset - Piece.InputOff;
   return Piece.OutputOff + Addend;
 }
diff --git a/ELF/InputSection.h b/ELF/InputSection.h
index c68b7d1..88dcadd 100644
--- a/ELF/InputSection.h
+++ b/ELF/InputSection.h
@@ -115,7 +115,12 @@
     return cast_or_null<ObjFile<ELFT>>(File);
   }
 
-  ArrayRef<uint8_t> Data;
+  ArrayRef<uint8_t> data() const {
+    if (UncompressedSize >= 0 && !UncompressedBuf)
+      uncompress();
+    return RawData;
+  }
+
   uint64_t getOffsetInFile() const;
 
   // True if this section has already been placed to a linker script
@@ -169,11 +174,6 @@
   template <class ELFT>
   Defined *getEnclosingFunction(uint64_t Offset);
 
-  // Compilers emit zlib-compressed debug sections if the -gz option
-  // is given. This function checks if this section is compressed, and
-  // if so, decompress in memory.
-  void maybeDecompress();
-
   // Returns a source location string. Used to construct an error message.
   template <class ELFT> std::string getLocation(uint64_t Offset);
   std::string getSrcMsg(const Symbol &Sym, uint64_t Offset);
@@ -200,15 +200,21 @@
 
 
   template <typename T> llvm::ArrayRef<T> getDataAs() const {
-    size_t S = Data.size();
+    size_t S = data().size();
     assert(S % sizeof(T) == 0);
-    return llvm::makeArrayRef<T>((const T *)Data.data(), S / sizeof(T));
+    return llvm::makeArrayRef<T>((const T *)data().data(), S / sizeof(T));
   }
 
-private:
-  // A pointer that owns decompressed data if a section is compressed by zlib.
+protected:
+  void parseCompressedHeader();
+  void uncompress() const;
+
+  mutable ArrayRef<uint8_t> RawData;
+
+  // A pointer that owns uncompressed data if a section is compressed by zlib.
   // Since the feature is not used often, this is usually a nullptr.
-  std::unique_ptr<char[]> DecompressBuf;
+  mutable std::unique_ptr<char[]> UncompressedBuf;
+  int64_t UncompressedSize = -1;
 };
 
 // SectionPiece represents a piece of splittable section contents.
@@ -255,8 +261,8 @@
   llvm::CachedHashStringRef getData(size_t I) const {
     size_t Begin = Pieces[I].InputOff;
     size_t End =
-        (Pieces.size() - 1 == I) ? Data.size() : Pieces[I + 1].InputOff;
-    return {toStringRef(Data.slice(Begin, End - Begin)), Pieces[I].Hash};
+        (Pieces.size() - 1 == I) ? data().size() : Pieces[I + 1].InputOff;
+    return {toStringRef(data().slice(Begin, End - Begin)), Pieces[I].Hash};
   }
 
   // Returns the SectionPiece at a given input section offset.
@@ -277,7 +283,9 @@
                  unsigned FirstRelocation)
       : InputOff(Off), Sec(Sec), Size(Size), FirstRelocation(FirstRelocation) {}
 
-  ArrayRef<uint8_t> data() { return {Sec->Data.data() + this->InputOff, Size}; }
+  ArrayRef<uint8_t> data() {
+    return {Sec->data().data() + this->InputOff, Size};
+  }
 
   size_t InputOff;
   ssize_t OutputOff = -1;
diff --git a/ELF/LTO.cpp b/ELF/LTO.cpp
index cb5bb64..e640106 100644
--- a/ELF/LTO.cpp
+++ b/ELF/LTO.cpp
@@ -109,18 +109,14 @@
 }
 
 BitcodeCompiler::BitcodeCompiler() {
+  // Initialize IndexFile.
+  if (!Config->ThinLTOIndexOnlyArg.empty())
+    IndexFile = openFile(Config->ThinLTOIndexOnlyArg);
+
   // 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;
-    };
-
+    auto OnIndexWrite = [&](StringRef S) { ThinIndices.erase(S); };
     Backend = lto::createWriteIndexesThinBackend(
         Config->ThinLTOPrefixReplace.first, Config->ThinLTOPrefixReplace.second,
         Config->ThinLTOEmitImportsFiles, IndexFile.get(), OnIndexWrite);
@@ -133,10 +129,10 @@
 
   // Initialize UsedStartStop.
   for (Symbol *Sym : Symtab->getSymbols()) {
-    StringRef Name = Sym->getName();
+    StringRef S = Sym->getName();
     for (StringRef Prefix : {"__start_", "__stop_"})
-      if (Name.startswith(Prefix))
-        UsedStartStop.insert(Name.substr(Prefix.size()));
+      if (S.startswith(Prefix))
+        UsedStartStop.insert(S.substr(Prefix.size()));
   }
 }
 
@@ -152,7 +148,7 @@
   bool IsExec = !Config->Shared && !Config->Relocatable;
 
   if (Config->ThinLTOIndexOnly)
-    ObjectToIndexFileState.insert({Obj.getName(), false});
+    ThinIndices.insert(Obj.getName());
 
   ArrayRef<Symbol *> Syms = F.getSymbols();
   ArrayRef<lto::InputFile::Symbol> ObjSyms = Obj.symbols();
@@ -241,15 +237,11 @@
       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");
-      }
+  for (StringRef S : ThinIndices) {
+    std::string Path = getThinLTOOutputFile(S);
+    openFile(Path + ".thinlto.bc");
+    if (Config->ThinLTOEmitImportsFiles)
+      openFile(Path + ".imports");
   }
 
   // If LazyObjFile has not been added to link, emit empty index files.
diff --git a/ELF/LTO.h b/ELF/LTO.h
index 8803078..a190da3 100644
--- a/ELF/LTO.h
+++ b/ELF/LTO.h
@@ -55,7 +55,7 @@
   std::vector<std::unique_ptr<MemoryBuffer>> Files;
   llvm::DenseSet<StringRef> UsedStartStop;
   std::unique_ptr<llvm::raw_fd_ostream> IndexFile;
-  llvm::StringMap<bool> ObjectToIndexFileState;
+  llvm::DenseSet<StringRef> ThinIndices;
 };
 } // namespace elf
 } // namespace lld
diff --git a/ELF/LinkerScript.cpp b/ELF/LinkerScript.cpp
index c865e9b..d189862 100644
--- a/ELF/LinkerScript.cpp
+++ b/ELF/LinkerScript.cpp
@@ -209,6 +209,7 @@
                          STT_NOTYPE, 0, 0, nullptr);
   Cmd->Sym = cast<Defined>(Sym);
   Cmd->Provide = false;
+  Sym->ScriptDefined = true;
 }
 
 // This method is used to handle INSERT AFTER statement. Here we rebuild
@@ -414,18 +415,18 @@
 
 void LinkerScript::discard(ArrayRef<InputSection *> V) {
   for (InputSection *S : V) {
-    if (S == InX::ShStrTab || S == InX::Dynamic || S == InX::DynSymTab ||
-        S == InX::DynStrTab || S == InX::RelaPlt || S == InX::RelaDyn ||
-        S == InX::RelrDyn)
+    if (S == In.ShStrTab || S == In.Dynamic || S == In.DynSymTab ||
+        S == In.DynStrTab || S == In.RelaPlt || S == In.RelaDyn ||
+        S == In.RelrDyn)
       error("discarding " + S->Name + " section is not allowed");
 
     // You can discard .hash and .gnu.hash sections by linker scripts. Since
     // they are synthesized sections, we need to handle them differently than
     // other regular sections.
-    if (S == InX::GnuHashTab)
-      InX::GnuHashTab = nullptr;
-    if (S == InX::HashTab)
-      InX::HashTab = nullptr;
+    if (S == In.GnuHashTab)
+      In.GnuHashTab = nullptr;
+    if (S == In.HashTab)
+      In.HashTab = nullptr;
 
     S->Assigned = false;
     S->Live = false;
diff --git a/ELF/MapFile.cpp b/ELF/MapFile.cpp
index 54fddfb..870705c 100644
--- a/ELF/MapFile.cpp
+++ b/ELF/MapFile.cpp
@@ -126,7 +126,7 @@
   };
 
   // Gather section pieces.
-  for (const CieRecord *Rec : InX::EhFrame->getCieRecords()) {
+  for (const CieRecord *Rec : In.EhFrame->getCieRecords()) {
     Add(*Rec->Cie);
     for (const EhSectionPiece *Fde : Rec->Fdes)
       Add(*Fde);
@@ -181,7 +181,7 @@
     for (BaseCommand *Base : OSec->SectionCommands) {
       if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) {
         for (InputSection *IS : ISD->Sections) {
-          if (IS == InX::EhFrame) {
+          if (IS == In.EhFrame) {
             printEhFrame(OS, OSec);
             continue;
           }
diff --git a/ELF/MarkLive.cpp b/ELF/MarkLive.cpp
index a8371e2..7264e1c 100644
--- a/ELF/MarkLive.cpp
+++ b/ELF/MarkLive.cpp
@@ -45,7 +45,7 @@
 template <class ELFT>
 static typename ELFT::uint getAddend(InputSectionBase &Sec,
                                      const typename ELFT::Rel &Rel) {
-  return Target->getImplicitAddend(Sec.Data.begin() + Rel.r_offset,
+  return Target->getImplicitAddend(Sec.data().begin() + Rel.r_offset,
                                    Rel.getType(Config->IsMips64EL));
 }
 
diff --git a/ELF/Options.td b/ELF/Options.td
index 04a4f8f..67d3dc6 100644
--- a/ELF/Options.td
+++ b/ELF/Options.td
@@ -132,7 +132,7 @@
 defm exclude_libs: Eq<"exclude-libs", "Exclude static libraries from automatic export">;
 
 defm execute_only: B<"execute-only",
-    "Do not mark executable sections readable",
+    "Mark executable sections unreadable",
     "Mark executable sections readable (default)">;
 
 defm export_dynamic: B<"export-dynamic",
@@ -315,6 +315,10 @@
     "Run the linker multi-threaded (default)",
     "Do not run the linker multi-threaded">;
 
+defm toc_optimize : B<"toc-optimize",
+    "(PowerPC64) Enable TOC related optimizations (default)",
+    "(PowerPC64) Disable TOC related optimizations">;
+
 def trace: F<"trace">, HelpText<"Print the names of the input files">;
 
 defm trace_symbol: Eq<"trace-symbol", "Trace references to symbols">;
@@ -348,6 +352,10 @@
     "Warn about duplicate common symbols",
     "Do not warn about duplicate common symbols (default)">;
 
+defm warn_ifunc_textrel: B<"warn-ifunc-textrel",
+    "Warn about using ifunc symbols with text relocations",
+    "Do not warn about using ifunc symbols with text relocations (default)">;
+
 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">;
diff --git a/ELF/OutputSections.cpp b/ELF/OutputSections.cpp
index 8253b18..0e8e406 100644
--- a/ELF/OutputSections.cpp
+++ b/ELF/OutputSections.cpp
@@ -270,13 +270,13 @@
 
   // sh_link field for SHT_GROUP sections should contain the section index of
   // the symbol table.
-  OS->Link = InX::SymTab->getParent()->SectionIndex;
+  OS->Link = In.SymTab->getParent()->SectionIndex;
 
   // sh_info then contain index of an entry in symbol table section which
   // provides signature of the section group.
   ObjFile<ELFT> *Obj = Section->getFile<ELFT>();
   ArrayRef<Symbol *> Symbols = Obj->getSymbols();
-  OS->Info = InX::SymTab->getSymbolIndex(Symbols[Section->Info]);
+  OS->Info = In.SymTab->getSymbolIndex(Symbols[Section->Info]);
 }
 
 template <class ELFT> void OutputSection::finalize() {
@@ -308,7 +308,7 @@
   if (isa<SyntheticSection>(First))
     return;
 
-  Link = InX::SymTab->getParent()->SectionIndex;
+  Link = In.SymTab->getParent()->SectionIndex;
   // sh_info for SHT_REL[A] sections should contain the section header index of
   // the section to which the relocation applies.
   InputSectionBase *S = First->getRelocatedSection();
diff --git a/ELF/Relocations.cpp b/ELF/Relocations.cpp
index 113f871..d7f79c1 100644
--- a/ELF/Relocations.cpp
+++ b/ELF/Relocations.cpp
@@ -50,6 +50,7 @@
 #include "SyntheticSections.h"
 #include "Target.h"
 #include "Thunks.h"
+#include "lld/Common/ErrorHandler.h"
 #include "lld/Common/Memory.h"
 #include "lld/Common/Strings.h"
 #include "llvm/ADT/SmallSet.h"
@@ -90,12 +91,12 @@
                                         InputSectionBase &C, uint64_t Offset,
                                         int64_t Addend, RelExpr Expr) {
   if (Expr == R_MIPS_TLSLD) {
-    InX::MipsGot->addTlsIndex(*C.File);
+    In.MipsGot->addTlsIndex(*C.File);
     C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
     return 1;
   }
   if (Expr == R_MIPS_TLSGD) {
-    InX::MipsGot->addDynTlsEntry(*C.File, Sym);
+    In.MipsGot->addDynTlsEntry(*C.File, Sym);
     C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
     return 1;
   }
@@ -128,17 +129,17 @@
 
   auto AddTlsReloc = [&](uint64_t Off, RelType Type, Symbol *Dest, bool Dyn) {
     if (Dyn)
-      InX::RelaDyn->addReloc(Type, InX::Got, Off, Dest);
+      In.RelaDyn->addReloc(Type, In.Got, Off, Dest);
     else
-      InX::Got->Relocations.push_back({R_ABS, Type, Off, 0, Dest});
+      In.Got->Relocations.push_back({R_ABS, Type, Off, 0, Dest});
   };
 
   // Local Dynamic is for access to module local TLS variables, while still
   // being suitable for being dynamically loaded via dlopen.
   // GOT[e0] is the module index, with a special value of 0 for the current
   // module. GOT[e1] is unused. There only needs to be one module index entry.
-  if (Expr == R_TLSLD_PC && InX::Got->addTlsIndex()) {
-    AddTlsReloc(InX::Got->getTlsIndexOff(), Target->TlsModuleIndexRel,
+  if (Expr == R_TLSLD_PC && In.Got->addTlsIndex()) {
+    AddTlsReloc(In.Got->getTlsIndexOff(), Target->TlsModuleIndexRel,
                 NeedDynId ? nullptr : &Sym, NeedDynId);
     C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
     return 1;
@@ -148,8 +149,8 @@
   // the module index and offset of symbol in TLS block we can fill these in
   // using static GOT relocations.
   if (Expr == R_TLSGD_PC) {
-    if (InX::Got->addDynTlsEntry(Sym)) {
-      uint64_t Off = InX::Got->getGlobalDynOffset(Sym);
+    if (In.Got->addDynTlsEntry(Sym)) {
+      uint64_t Off = In.Got->getGlobalDynOffset(Sym);
       AddTlsReloc(Off, Target->TlsModuleIndexRel, &Sym, NeedDynId);
       AddTlsReloc(Off + Config->Wordsize, Target->TlsOffsetRel, &Sym,
                   NeedDynOff);
@@ -165,9 +166,6 @@
 static unsigned
 handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,
                     typename ELFT::uint Offset, int64_t Addend, RelExpr Expr) {
-  if (!(C.Flags & SHF_ALLOC))
-    return 0;
-
   if (!Sym.isTls())
     return 0;
 
@@ -178,10 +176,10 @@
 
   if (isRelExprOneOf<R_TLSDESC, R_TLSDESC_PAGE, R_TLSDESC_CALL>(Expr) &&
       Config->Shared) {
-    if (InX::Got->addDynTlsEntry(Sym)) {
-      uint64_t Off = InX::Got->getGlobalDynOffset(Sym);
-      InX::RelaDyn->addReloc(
-          {Target->TlsDescRel, InX::Got, Off, !Sym.IsPreemptible, &Sym, 0});
+    if (In.Got->addDynTlsEntry(Sym)) {
+      uint64_t Off = In.Got->getGlobalDynOffset(Sym);
+      In.RelaDyn->addReloc(
+          {Target->TlsDescRel, In.Got, Off, !Sym.IsPreemptible, &Sym, 0});
     }
     if (Expr != R_TLSDESC_CALL)
       C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
@@ -199,9 +197,9 @@
     }
     if (Expr == R_TLSLD_HINT)
       return 1;
-    if (InX::Got->addTlsIndex())
-      InX::RelaDyn->addReloc(Target->TlsModuleIndexRel, InX::Got,
-                             InX::Got->getTlsIndexOff(), nullptr);
+    if (In.Got->addTlsIndex())
+      In.RelaDyn->addReloc(Target->TlsModuleIndexRel, In.Got,
+                           In.Got->getTlsIndexOff(), nullptr);
     C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
     return 1;
   }
@@ -223,9 +221,10 @@
       return 1;
     }
     if (!Sym.isInGot()) {
-      InX::Got->addEntry(Sym);
+      In.Got->addEntry(Sym);
       uint64_t Off = Sym.getGotOffset();
-      InX::Got->Relocations.push_back({R_ABS, Target->TlsOffsetRel, Off, 0, &Sym});
+      In.Got->Relocations.push_back(
+          {R_ABS, Target->TlsOffsetRel, Off, 0, &Sym});
     }
     C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
     return 1;
@@ -234,18 +233,17 @@
   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);
-        InX::RelaDyn->addReloc(Target->TlsModuleIndexRel, InX::Got, Off, &Sym);
+      if (In.Got->addDynTlsEntry(Sym)) {
+        uint64_t Off = In.Got->getGlobalDynOffset(Sym);
+        In.RelaDyn->addReloc(Target->TlsModuleIndexRel, In.Got, Off, &Sym);
 
         // If the symbol is preemptible we need the dynamic linker to write
         // the offset too.
         uint64_t OffsetOff = Off + Config->Wordsize;
         if (Sym.IsPreemptible)
-          InX::RelaDyn->addReloc(Target->TlsOffsetRel, InX::Got, OffsetOff,
-                                 &Sym);
+          In.RelaDyn->addReloc(Target->TlsOffsetRel, In.Got, OffsetOff, &Sym);
         else
-          InX::Got->Relocations.push_back(
+          In.Got->Relocations.push_back(
               {R_ABS, Target->TlsOffsetRel, OffsetOff, 0, &Sym});
       }
       C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
@@ -259,9 +257,9 @@
           {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_IE), Type,
            Offset, Addend, &Sym});
       if (!Sym.isInGot()) {
-        InX::Got->addEntry(Sym);
-        InX::RelaDyn->addReloc(Target->TlsGotRel, InX::Got, Sym.getGotOffset(),
-                               &Sym);
+        In.Got->addEntry(Sym);
+        In.RelaDyn->addReloc(Target->TlsGotRel, In.Got, Sym.getGotOffset(),
+                             &Sym);
       }
     } else {
       C.Relocations.push_back(
@@ -273,13 +271,14 @@
 
   // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally
   // defined.
-  if (isRelExprOneOf<R_GOT, R_GOT_FROM_END, R_GOT_PC, R_GOT_PAGE_PC>(Expr) &&
+  if (isRelExprOneOf<R_GOT, R_GOT_FROM_END, R_GOT_PC, R_GOT_PAGE_PC, R_GOT_OFF,
+                     R_TLSIE_HINT>(Expr) &&
       !Config->Shared && !Sym.IsPreemptible) {
     C.Relocations.push_back({R_RELAX_TLS_IE_TO_LE, Type, Offset, Addend, &Sym});
     return 1;
   }
 
-  if (Expr == R_TLSDESC_CALL)
+  if (Expr == R_TLSIE_HINT)
     return 1;
   return 0;
 }
@@ -332,9 +331,9 @@
 // returns false for TLS variables even though they need GOT, because
 // TLS variables uses GOT differently than the regular variables.
 static bool needsGot(RelExpr Expr) {
-  return isRelExprOneOf<R_GOT, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOT_OFF,
-                        R_MIPS_GOT_OFF32, R_GOT_PAGE_PC, R_GOT_PC,
-                        R_GOT_FROM_END>(Expr);
+  return isRelExprOneOf<R_GOT, R_GOT_OFF, R_HEXAGON_GOT, R_MIPS_GOT_LOCAL_PAGE,
+                        R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_GOT_PAGE_PC,
+                        R_GOT_PC, R_GOT_FROM_END>(Expr);
 }
 
 // True if this expression is of the form Sym - X, where X is a position in the
@@ -358,12 +357,12 @@
                                      InputSectionBase &S, uint64_t RelOff) {
   // These expressions always compute a constant
   if (isRelExprOneOf<
-          R_GOT_FROM_END, R_GOT_OFF, R_TLSLD_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_GOT, R_TLSGD_GOT_FROM_END,
-          R_TLSGD_PC, R_PPC_CALL_PLT, R_TLSDESC_CALL, R_TLSDESC_PAGE, R_HINT,
-          R_TLSLD_HINT>(E))
+          R_GOT_FROM_END, R_GOT_OFF, R_HEXAGON_GOT, R_TLSLD_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_GOT,
+          R_TLSGD_GOT_FROM_END, R_TLSGD_PC, R_PPC_CALL_PLT, R_TLSDESC_CALL,
+          R_TLSDESC_PAGE, R_HINT, R_TLSLD_HINT, R_TLSIE_HINT>(E))
     return true;
 
   // These never do, except if the entire file is position dependent or if
@@ -549,9 +548,9 @@
   BssSection *Sec = make<BssSection>(IsReadOnly ? ".bss.rel.ro" : ".bss",
                                      SymSize, SS.Alignment);
   if (IsReadOnly)
-    InX::BssRelRo->getParent()->addSection(Sec);
+    In.BssRelRo->getParent()->addSection(Sec);
   else
-    InX::Bss->getParent()->addSection(Sec);
+    In.Bss->getParent()->addSection(Sec);
 
   // 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
@@ -559,7 +558,7 @@
   for (SharedSymbol *Sym : getSymbolsAt<ELFT>(SS))
     replaceWithDefined(*Sym, Sec, 0, Sym->Size);
 
-  InX::RelaDyn->addReloc(Target->CopyRel, Sec, 0, &SS);
+  In.RelaDyn->addReloc(Target->CopyRel, Sec, 0, &SS);
 }
 
 // MIPS has an odd notion of "paired" relocations to calculate addends.
@@ -583,7 +582,7 @@
   if (PairTy == R_MIPS_NONE)
     return 0;
 
-  const uint8_t *Buf = Sec.Data.data();
+  const uint8_t *Buf = Sec.data().data();
   uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
 
   // To make things worse, paired relocations might not be contiguous in
@@ -611,7 +610,7 @@
   if (RelTy::IsRela) {
     Addend = getAddend<ELFT>(Rel);
   } else {
-    const uint8_t *Buf = Sec.Data.data();
+    const uint8_t *Buf = Sec.data().data();
     Addend = Target->getImplicitAddend(Buf + Rel.r_offset, Type);
   }
 
@@ -627,9 +626,6 @@
 // Returns true if this function printed out an error message.
 static bool maybeReportUndefined(Symbol &Sym, InputSectionBase &Sec,
                                  uint64_t Offset) {
-  if (Config->UnresolvedSymbols == UnresolvedPolicy::IgnoreAll)
-    return false;
-
   if (Sym.isLocal() || !Sym.isUndefined() || Sym.isWeak())
     return false;
 
@@ -700,7 +696,7 @@
     while (I != Pieces.size() && Pieces[I].InputOff + Pieces[I].Size <= Off)
       ++I;
     if (I == Pieces.size())
-      return Off;
+      fatal(".eh_frame: relocation is not in any piece");
 
     // Pieces must be contiguous, so there must be no holes in between.
     assert(Pieces[I].InputOff <= Off && "Relocation not in any piece");
@@ -726,13 +722,13 @@
   // RelrDyn sections don't support odd offsets. Also, RelrDyn sections
   // don't store the addend values, so we must write it to the relocated
   // address.
-  if (InX::RelrDyn && IS->Alignment >= 2 && OffsetInSec % 2 == 0) {
+  if (In.RelrDyn && IS->Alignment >= 2 && OffsetInSec % 2 == 0) {
     IS->Relocations.push_back({Expr, Type, OffsetInSec, Addend, Sym});
-    InX::RelrDyn->Relocs.push_back({IS, OffsetInSec});
+    In.RelrDyn->Relocs.push_back({IS, OffsetInSec});
     return;
   }
-  InX::RelaDyn->addReloc(Target->RelativeRel, IS, OffsetInSec, Sym, Addend,
-                         Expr, Type);
+  In.RelaDyn->addReloc(Target->RelativeRel, IS, OffsetInSec, Sym, Addend, Expr,
+                       Type);
 }
 
 template <class ELFT, class GotPltSection>
@@ -745,7 +741,7 @@
 }
 
 template <class ELFT> static void addGotEntry(Symbol &Sym) {
-  InX::Got->addEntry(Sym);
+  In.Got->addEntry(Sym);
 
   RelExpr Expr = Sym.isTls() ? R_TLS : R_ABS;
   uint64_t Off = Sym.getGotOffset();
@@ -760,19 +756,19 @@
   bool IsLinkTimeConstant =
       !Sym.IsPreemptible && (!Config->Pic || isAbsolute(Sym));
   if (IsLinkTimeConstant) {
-    InX::Got->Relocations.push_back({Expr, Target->GotRel, Off, 0, &Sym});
+    In.Got->Relocations.push_back({Expr, Target->GotRel, Off, 0, &Sym});
     return;
   }
 
   // Otherwise, we emit a dynamic relocation to .rel[a].dyn so that
   // the GOT slot will be fixed at load-time.
   if (!Sym.isTls() && !Sym.IsPreemptible && Config->Pic && !isAbsolute(Sym)) {
-    addRelativeReloc(InX::Got, Off, &Sym, 0, R_ABS, Target->GotRel);
+    addRelativeReloc(In.Got, Off, &Sym, 0, R_ABS, Target->GotRel);
     return;
   }
-  InX::RelaDyn->addReloc(Sym.isTls() ? Target->TlsGotRel : Target->GotRel,
-                         InX::Got, Off, &Sym, 0,
-                         Sym.IsPreemptible ? R_ADDEND : R_ABS, Target->GotRel);
+  In.RelaDyn->addReloc(Sym.isTls() ? Target->TlsGotRel : Target->GotRel, In.Got,
+                       Off, &Sym, 0, Sym.IsPreemptible ? R_ADDEND : R_ABS,
+                       Target->GotRel);
 }
 
 // Return true if we can define a symbol in the executable that
@@ -825,7 +821,7 @@
       addRelativeReloc(&Sec, Offset, &Sym, Addend, Expr, Type);
       return;
     } else if (RelType Rel = Target->getDynRel(Type)) {
-      InX::RelaDyn->addReloc(Rel, &Sec, Offset, &Sym, Addend, R_ADDEND, Type);
+      In.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
@@ -843,7 +839,7 @@
       // a dynamic relocation.
       // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf p.4-19
       if (Config->EMachine == EM_MIPS)
-        InX::MipsGot->addEntry(*Sec.File, Sym, Addend, Expr);
+        In.MipsGot->addEntry(*Sec.File, Sym, Addend, Expr);
       return;
     }
   }
@@ -930,10 +926,9 @@
                   "' cannot be preempted; recompile with -fPIE" +
                   getLocation(Sec, Sym, Offset));
     if (!Sym.isInPlt())
-      addPltEntry<ELFT>(InX::Plt, InX::GotPlt, InX::RelaPlt, Target->PltRel,
-                        Sym);
+      addPltEntry<ELFT>(In.Plt, In.GotPlt, In.RelaPlt, Target->PltRel, Sym);
     if (!Sym.isDefined())
-      replaceWithDefined(Sym, InX::Plt, Sym.getPltOffset(), 0);
+      replaceWithDefined(Sym, In.Plt, Sym.getPltOffset(), 0);
     Sym.NeedsPltAddr = true;
     Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
     return;
@@ -967,7 +962,7 @@
   if (maybeReportUndefined(Sym, Sec, Rel.r_offset))
     return;
 
-  const uint8_t *RelocatedAddr = Sec.Data.begin() + Rel.r_offset;
+  const uint8_t *RelocatedAddr = Sec.data().begin() + Rel.r_offset;
   RelExpr Expr = Target->getRelExpr(Type, Sym, RelocatedAddr);
 
   // Ignore "hint" relocations because they are only markers for relaxation.
@@ -985,18 +980,28 @@
   // all dynamic symbols that can be resolved within the executable will
   // actually be resolved that way at runtime, because the main exectuable
   // is always at the beginning of a search list. We can leverage that fact.
-  if (Sym.isGnuIFunc())
+  if (Sym.isGnuIFunc()) {
+    if (!Config->ZText && Config->WarnIfuncTextrel) {
+      warn("using ifunc symbols when text relocations are allowed may produce "
+           "a binary that will segfault, if the object file is linked with "
+           "old version of glibc (glibc 2.28 and earlier). If this applies to "
+           "you, consider recompiling the object files without -fPIC and "
+           "without -Wl,-z,notext option. Use -no-warn-ifunc-textrel to "
+           "turn off this warning." +
+           getLocation(Sec, Sym, Offset));
+    }
     Expr = toPlt(Expr);
-  else if (!Sym.IsPreemptible && Expr == R_GOT_PC && !isAbsoluteValue(Sym))
+  } else if (!Sym.IsPreemptible && Expr == R_GOT_PC && !isAbsoluteValue(Sym)) {
     Expr = Target->adjustRelaxExpr(Type, RelocatedAddr, Expr);
-  else if (!Sym.IsPreemptible)
+  } else if (!Sym.IsPreemptible) {
     Expr = fromPlt(Expr);
+  }
 
   // This relocation does not require got entry, but it is relative to got and
   // needs it to be created. Here we request for that.
   if (isRelExprOneOf<R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_GOTREL,
                      R_GOTREL_FROM_END, R_PPC_TOC>(Expr))
-    InX::Got->HasGotOffRel = true;
+    In.Got->HasGotOffRel = true;
 
   // Read an addend.
   int64_t Addend = computeAddend<ELFT>(Rel, End, Sec, Expr, Sym.isLocal());
@@ -1012,11 +1017,10 @@
   // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.
   if (needsPlt(Expr) && !Sym.isInPlt()) {
     if (Sym.isGnuIFunc() && !Sym.IsPreemptible)
-      addPltEntry<ELFT>(InX::Iplt, InX::IgotPlt, InX::RelaIplt,
-                        Target->IRelativeRel, Sym);
-    else
-      addPltEntry<ELFT>(InX::Plt, InX::GotPlt, InX::RelaPlt, Target->PltRel,
+      addPltEntry<ELFT>(In.Iplt, In.IgotPlt, In.RelaIplt, Target->IRelativeRel,
                         Sym);
+    else
+      addPltEntry<ELFT>(In.Plt, In.GotPlt, In.RelaPlt, Target->PltRel, Sym);
   }
 
   // Create a GOT slot if a relocation needs GOT.
@@ -1029,7 +1033,7 @@
       // See "Global Offset Table" in Chapter 5 in the following document
       // for detailed description:
       // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
-      InX::MipsGot->addEntry(*Sec.File, Sym, Addend, Expr);
+      In.MipsGot->addEntry(*Sec.File, Sym, Addend, Expr);
     } else if (!Sym.isInGot()) {
       addGotEntry<ELFT>(Sym);
     }
@@ -1061,6 +1065,29 @@
     scanRelocs<ELFT>(S, S.rels<ELFT>());
 }
 
+static bool mergeCmp(const InputSection *A, const InputSection *B) {
+  // std::merge requires a strict weak ordering.
+  if (A->OutSecOff < B->OutSecOff)
+    return true;
+
+  if (A->OutSecOff == B->OutSecOff) {
+    auto *TA = dyn_cast<ThunkSection>(A);
+    auto *TB = dyn_cast<ThunkSection>(B);
+
+    // Check if Thunk is immediately before any specific Target
+    // InputSection for example Mips LA25 Thunks.
+    if (TA && TA->getTargetInputSection() == B)
+      return true;
+
+    // Place Thunk Sections without specific targets before
+    // non-Thunk Sections.
+    if (TA && !TB && !TA->getTargetInputSection())
+      return true;
+  }
+
+  return false;
+}
+
 // Thunk Implementation
 //
 // Thunks (sometimes called stubs, veneers or branch islands) are small pieces
@@ -1163,6 +1190,7 @@
                        [](const std::pair<ThunkSection *, uint32_t> &TS) {
                          return TS.first->getSize() == 0;
                        });
+
         // ISD->ThunkSections contains all created ThunkSections, including
         // those inserted in previous passes. Extract the Thunks created this
         // pass and order them in ascending OutSecOff.
@@ -1178,27 +1206,11 @@
         // Merge sorted vectors of Thunks and InputSections by OutSecOff
         std::vector<InputSection *> Tmp;
         Tmp.reserve(ISD->Sections.size() + NewThunks.size());
-        auto MergeCmp = [](const InputSection *A, const InputSection *B) {
-          // std::merge requires a strict weak ordering.
-          if (A->OutSecOff < B->OutSecOff)
-            return true;
-          if (A->OutSecOff == B->OutSecOff) {
-            auto *TA = dyn_cast<ThunkSection>(A);
-            auto *TB = dyn_cast<ThunkSection>(B);
-            // Check if Thunk is immediately before any specific Target
-            // InputSection for example Mips LA25 Thunks.
-            if (TA && TA->getTargetInputSection() == B)
-              return true;
-            if (TA && !TB && !TA->getTargetInputSection())
-              // Place Thunk Sections without specific targets before
-              // non-Thunk Sections.
-              return true;
-          }
-          return false;
-        };
+
         std::merge(ISD->Sections.begin(), ISD->Sections.end(),
                    NewThunks.begin(), NewThunks.end(), std::back_inserter(Tmp),
-                   MergeCmp);
+                   mergeCmp);
+
         ISD->Sections = std::move(Tmp);
       });
 }
@@ -1242,20 +1254,23 @@
   // Find InputSectionRange within Target Output Section (TOS) that the
   // InputSection (IS) that we need to precede is in.
   OutputSection *TOS = IS->getParent();
-  for (BaseCommand *BC : TOS->SectionCommands)
-    if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) {
-      if (ISD->Sections.empty())
-        continue;
-      InputSection *first = ISD->Sections.front();
-      InputSection *last = ISD->Sections.back();
-      if (IS->OutSecOff >= first->OutSecOff &&
-          IS->OutSecOff <= last->OutSecOff) {
-        TS = addThunkSection(TOS, ISD, IS->OutSecOff);
-        ThunkedSections[IS] = TS;
-        break;
-      }
-    }
-  return TS;
+  for (BaseCommand *BC : TOS->SectionCommands) {
+    auto *ISD = dyn_cast<InputSectionDescription>(BC);
+    if (!ISD || ISD->Sections.empty())
+      continue;
+
+    InputSection *First = ISD->Sections.front();
+    InputSection *Last = ISD->Sections.back();
+
+    if (IS->OutSecOff < First->OutSecOff || Last->OutSecOff < IS->OutSecOff)
+      continue;
+
+    TS = addThunkSection(TOS, ISD, IS->OutSecOff);
+    ThunkedSections[IS] = TS;
+    return TS;
+  }
+
+  return nullptr;
 }
 
 // Create one or more ThunkSections per OS that can be used to place Thunks.
@@ -1276,26 +1291,29 @@
 // allow for the creation of a short thunk.
 void ThunkCreator::createInitialThunkSections(
     ArrayRef<OutputSection *> OutputSections) {
+  uint32_t ThunkSectionSpacing = Target->getThunkSectionSpacing();
+
   forEachInputSectionDescription(
       OutputSections, [&](OutputSection *OS, InputSectionDescription *ISD) {
         if (ISD->Sections.empty())
           return;
+
         uint32_t ISDBegin = ISD->Sections.front()->OutSecOff;
         uint32_t ISDEnd =
             ISD->Sections.back()->OutSecOff + ISD->Sections.back()->getSize();
         uint32_t LastThunkLowerBound = -1;
-        if (ISDEnd - ISDBegin > Target->ThunkSectionSpacing * 2)
-          LastThunkLowerBound = ISDEnd - Target->ThunkSectionSpacing;
+        if (ISDEnd - ISDBegin > ThunkSectionSpacing * 2)
+          LastThunkLowerBound = ISDEnd - ThunkSectionSpacing;
 
         uint32_t ISLimit;
         uint32_t PrevISLimit = ISDBegin;
-        uint32_t ThunkUpperBound = ISDBegin + Target->ThunkSectionSpacing;
+        uint32_t ThunkUpperBound = ISDBegin + ThunkSectionSpacing;
 
         for (const InputSection *IS : ISD->Sections) {
           ISLimit = IS->OutSecOff + IS->getSize();
           if (ISLimit > ThunkUpperBound) {
             addThunkSection(OS, ISD, PrevISLimit);
-            ThunkUpperBound = PrevISLimit + Target->ThunkSectionSpacing;
+            ThunkUpperBound = PrevISLimit + ThunkSectionSpacing;
           }
           if (ISLimit > LastThunkLowerBound)
             break;
@@ -1309,13 +1327,14 @@
                                             InputSectionDescription *ISD,
                                             uint64_t Off) {
   auto *TS = make<ThunkSection>(OS, Off);
-  ISD->ThunkSections.push_back(std::make_pair(TS, Pass));
+  ISD->ThunkSections.push_back({TS, Pass});
   return TS;
 }
 
 std::pair<Thunk *, bool> ThunkCreator::getThunk(Symbol &Sym, RelType Type,
                                                 uint64_t Src) {
   std::vector<Thunk *> *ThunkVec = nullptr;
+
   // We use (section, offset) pair to find the thunk position if possible so
   // that we create only one thunk for aliased symbols or ICFed sections.
   if (auto *D = dyn_cast<Defined>(&Sym))
@@ -1323,11 +1342,13 @@
       ThunkVec = &ThunkedSymbolsBySection[{D->Section->Repl, D->Value}];
   if (!ThunkVec)
     ThunkVec = &ThunkedSymbols[&Sym];
+
   // Check existing Thunks for Sym to see if they can be reused
-  for (Thunk *ET : *ThunkVec)
-    if (ET->isCompatibleWith(Type) &&
-        Target->inBranchRange(Type, Src, ET->getThunkTargetSym()->getVA()))
-      return std::make_pair(ET, false);
+  for (Thunk *T : *ThunkVec)
+    if (T->isCompatibleWith(Type) &&
+        Target->inBranchRange(Type, Src, T->getThunkTargetSym()->getVA()))
+      return std::make_pair(T, false);
+
   // No existing compatible Thunk in range, create a new one
   Thunk *T = addThunk(Type, Sym);
   ThunkVec->push_back(T);
@@ -1353,10 +1374,10 @@
 // was originally to a Thunk, but is no longer in range we revert the
 // relocation back to its original non-Thunk target.
 bool ThunkCreator::normalizeExistingThunk(Relocation &Rel, uint64_t Src) {
-  if (Thunk *ET = Thunks.lookup(Rel.Sym)) {
+  if (Thunk *T = Thunks.lookup(Rel.Sym)) {
     if (Target->inBranchRange(Rel.Type, Src, Rel.Sym->getVA()))
       return true;
-    Rel.Sym = &ET->Destination;
+    Rel.Sym = &T->Destination;
     if (Rel.Sym->isInPlt())
       Rel.Expr = toPlt(Rel.Expr);
   }
@@ -1390,11 +1411,13 @@
 // relocation out of range error.
 bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) {
   bool AddressesChanged = false;
-  if (Pass == 0 && Target->ThunkSectionSpacing)
+
+  if (Pass == 0 && Target->getThunkSectionSpacing())
     createInitialThunkSections(OutputSections);
-  else if (Pass == 10)
-    // With Thunk Size much smaller than branch range we expect to
-    // converge quickly; if we get to 10 something has gone wrong.
+
+  // With Thunk Size much smaller than branch range we expect to
+  // converge quickly; if we get to 10 something has gone wrong.
+  if (Pass == 10)
     fatal("thunk creation not converged");
 
   // Create all the Thunks and insert them into synthetic ThunkSections. The
@@ -1417,9 +1440,11 @@
             if (!Target->needsThunk(Rel.Expr, Rel.Type, IS->File, Src,
                                     *Rel.Sym))
               continue;
+
             Thunk *T;
             bool IsNew;
             std::tie(T, IsNew) = getThunk(*Rel.Sym, Rel.Type, Src);
+
             if (IsNew) {
               // Find or create a ThunkSection for the new Thunk
               ThunkSection *TS;
@@ -1430,13 +1455,16 @@
               TS->addThunk(T);
               Thunks[T->getThunkTargetSym()] = T;
             }
+
             // Redirect relocation to Thunk, we never go via the PLT to a Thunk
             Rel.Sym = T->getThunkTargetSym();
             Rel.Expr = fromPlt(Rel.Expr);
           }
+
         for (auto &P : ISD->ThunkSections)
           AddressesChanged |= P.first->assignOffsets();
       });
+
   for (auto &P : ThunkedSections)
     AddressesChanged |= P.second->assignOffsets();
 
diff --git a/ELF/Relocations.h b/ELF/Relocations.h
index 76bb41d..d482b4e 100644
--- a/ELF/Relocations.h
+++ b/ELF/Relocations.h
@@ -43,6 +43,7 @@
   R_GOT_OFF,
   R_GOT_PAGE_PC,
   R_GOT_PC,
+  R_HEXAGON_GOT,
   R_HINT,
   R_MIPS_GOTREL,
   R_MIPS_GOT_GP,
@@ -83,6 +84,7 @@
   R_TLSGD_GOT,
   R_TLSGD_GOT_FROM_END,
   R_TLSGD_PC,
+  R_TLSIE_HINT,
   R_TLSLD_GOT,
   R_TLSLD_GOT_FROM_END,
   R_TLSLD_GOT_OFF,
diff --git a/ELF/ScriptLexer.cpp b/ELF/ScriptLexer.cpp
index d4b1f6d..9a372c6 100644
--- a/ELF/ScriptLexer.cpp
+++ b/ELF/ScriptLexer.cpp
@@ -244,6 +244,15 @@
   return Tok;
 }
 
+StringRef ScriptLexer::peek2() {
+  skip();
+  StringRef Tok = next();
+  if (errorCount())
+    return "";
+  Pos = Pos - 2;
+  return Tok;
+}
+
 bool ScriptLexer::consume(StringRef Tok) {
   if (peek() == Tok) {
     skip();
diff --git a/ELF/ScriptLexer.h b/ELF/ScriptLexer.h
index e7c8b28..fc6b5b1 100644
--- a/ELF/ScriptLexer.h
+++ b/ELF/ScriptLexer.h
@@ -29,6 +29,7 @@
   bool atEOF();
   StringRef next();
   StringRef peek();
+  StringRef peek2();
   void skip();
   bool consume(StringRef Tok);
   void expect(StringRef Expect);
diff --git a/ELF/ScriptParser.cpp b/ELF/ScriptParser.cpp
index ffc69b2..4d1dd75 100644
--- a/ELF/ScriptParser.cpp
+++ b/ELF/ScriptParser.cpp
@@ -80,6 +80,7 @@
   ByteCommand *readByteCommand(StringRef Tok);
   uint32_t readFill();
   uint32_t parseFill(StringRef Tok);
+  bool readSectionDirective(OutputSection *Cmd, StringRef Tok1, StringRef Tok2);
   void readSectionAddressType(OutputSection *Cmd);
   OutputSection *readOverlaySectionDescription();
   OutputSection *readOutputSectionDescription(StringRef OutSec);
@@ -699,6 +700,26 @@
   return V;
 }
 
+// Tries to read the special directive for an output section definition which
+// can be one of following: "(NOLOAD)", "(COPY)", "(INFO)" or "(OVERLAY)".
+// Tok1 and Tok2 are next 2 tokens peeked. See comment for readSectionAddressType below.
+bool ScriptParser::readSectionDirective(OutputSection *Cmd, StringRef Tok1, StringRef Tok2) {
+  if (Tok1 != "(")
+    return false;
+  if (Tok2 != "NOLOAD" && Tok2 != "COPY" && Tok2 != "INFO" && Tok2 != "OVERLAY")
+    return false;
+
+  expect("(");
+  if (consume("NOLOAD")) {
+    Cmd->Noload = true;
+  } else {
+    skip(); // This is "COPY", "INFO" or "OVERLAY".
+    Cmd->NonAlloc = true;
+  }
+  expect(")");
+  return true;
+}
+
 // Reads an expression and/or the special directive for an output
 // section definition. Directive is one of following: "(NOLOAD)",
 // "(COPY)", "(INFO)" or "(OVERLAY)".
@@ -711,28 +732,12 @@
 // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html
 // https://sourceware.org/binutils/docs/ld/Output-Section-Type.html
 void ScriptParser::readSectionAddressType(OutputSection *Cmd) {
-  if (consume("(")) {
-    if (consume("NOLOAD")) {
-      expect(")");
-      Cmd->Noload = true;
-      return;
-    }
-    if (consume("COPY") || consume("INFO") || consume("OVERLAY")) {
-      expect(")");
-      Cmd->NonAlloc = true;
-      return;
-    }
-    Cmd->AddrExpr = readExpr();
-    expect(")");
-  } else {
-    Cmd->AddrExpr = readExpr();
-  }
+  if (readSectionDirective(Cmd, peek(), peek2()))
+    return;
 
-  if (consume("(")) {
-    expect("NOLOAD");
-    expect(")");
-    Cmd->Noload = true;
-  }
+  Cmd->AddrExpr = readExpr();
+  if (peek() == "(" && !readSectionDirective(Cmd, "(", peek2()))
+    setError("unknown section directive: " + peek2());
 }
 
 static Expr checkAlignment(Expr E, std::string &Loc) {
diff --git a/ELF/SymbolTable.cpp b/ELF/SymbolTable.cpp
index 1f5a84e..61247e3 100644
--- a/ELF/SymbolTable.cpp
+++ b/ELF/SymbolTable.cpp
@@ -152,64 +152,21 @@
   SymMap.insert({CachedHashStringRef(Name), -1});
 }
 
-// Rename SYM as __wrap_SYM. The original symbol is preserved as __real_SYM.
-// Used to implement --wrap.
-template <class ELFT> void SymbolTable::addSymbolWrap(StringRef Name) {
-  Symbol *Sym = find(Name);
-  if (!Sym)
-    return;
+void SymbolTable::wrap(Symbol *Sym, Symbol *Real, Symbol *Wrap) {
+  // Swap symbols as instructed by -wrap.
+  int &Idx1 = SymMap[CachedHashStringRef(Sym->getName())];
+  int &Idx2 = SymMap[CachedHashStringRef(Real->getName())];
+  int &Idx3 = SymMap[CachedHashStringRef(Wrap->getName())];
 
-  // Do not wrap the same symbol twice.
-  for (const WrappedSymbol &S : WrappedSymbols)
-    if (S.Sym == Sym)
-      return;
+  Idx2 = Idx1;
+  Idx1 = Idx3;
 
-  Symbol *Real = addUndefined<ELFT>(Saver.save("__real_" + Name));
-  Symbol *Wrap = addUndefined<ELFT>(Saver.save("__wrap_" + Name));
-  WrappedSymbols.push_back({Sym, Real, Wrap});
-
-  // We want to tell LTO not to inline symbols to be overwritten
-  // because LTO doesn't know the final symbol contents after renaming.
-  Real->CanInline = false;
-  Sym->CanInline = false;
-
-  // Tell LTO not to eliminate these symbols.
-  Sym->IsUsedInRegularObj = true;
-  Wrap->IsUsedInRegularObj = true;
-}
-
-// Apply symbol renames created by -wrap. The renames are created
-// before LTO in addSymbolWrap() to have a chance to inform LTO (if
-// LTO is running) not to include these symbols in IPO. Now that the
-// symbols are finalized, we can perform the replacement.
-void SymbolTable::applySymbolWrap() {
-  // This function rotates 3 symbols:
-  //
-  // __real_sym becomes sym
-  // sym        becomes __wrap_sym
-  // __wrap_sym becomes __real_sym
-  //
-  // The last part is special in that we don't want to change what references to
-  // __wrap_sym point to, we just want have __real_sym in the symbol table.
-
-  for (WrappedSymbol &W : WrappedSymbols) {
-    // First, make a copy of __real_sym.
-    Symbol *Real = nullptr;
-    if (W.Real->isDefined()) {
-      Real = reinterpret_cast<Symbol *>(make<SymbolUnion>());
-      memcpy(Real, W.Real, sizeof(SymbolUnion));
-    }
-
-    // Replace __real_sym with sym and sym with __wrap_sym.
-    memcpy(W.Real, W.Sym, sizeof(SymbolUnion));
-    memcpy(W.Sym, W.Wrap, sizeof(SymbolUnion));
-
-    // We now have two copies of __wrap_sym. Drop one.
-    W.Wrap->IsUsedInRegularObj = false;
-
-    if (Real)
-      SymVector.push_back(Real);
-  }
+  // Now renaming is complete. No one refers Real symbol. We could leave
+  // Real as-is, but if Real is written to the symbol table, that may
+  // contain irrelevant values. So, we copy all values from Sym to Real.
+  StringRef S = Real->getName();
+  memcpy(Real, Sym, sizeof(SymbolUnion));
+  Real->setName(S);
 }
 
 static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
@@ -239,23 +196,22 @@
 
   if (SymIndex == -1) {
     SymIndex = SymVector.size();
-    IsNew = Traced = true;
+    IsNew = true;
+    Traced = true;
   }
 
-  Symbol *Sym;
-  if (IsNew) {
-    Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
-    Sym->Visibility = STV_DEFAULT;
-    Sym->IsUsedInRegularObj = false;
-    Sym->ExportDynamic = false;
-    Sym->CanInline = true;
-    Sym->Traced = Traced;
-    Sym->VersionId = Config->DefaultSymbolVersion;
-    SymVector.push_back(Sym);
-  } else {
-    Sym = SymVector[SymIndex];
-  }
-  return {Sym, IsNew};
+  if (!IsNew)
+    return {SymVector[SymIndex], false};
+
+  auto *Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
+  Sym->Visibility = STV_DEFAULT;
+  Sym->IsUsedInRegularObj = false;
+  Sym->ExportDynamic = false;
+  Sym->CanInline = true;
+  Sym->Traced = Traced;
+  Sym->VersionId = Config->DefaultSymbolVersion;
+  SymVector.push_back(Sym);
+  return {Sym, true};
 }
 
 // Find an existing symbol or create and insert a new one, then apply the given
@@ -277,11 +233,10 @@
   if (!File || File->kind() == InputFile::ObjKind)
     S->IsUsedInRegularObj = true;
 
-  if (!WasInserted && S->Type != Symbol::UnknownType &&
-      ((Type == STT_TLS) != S->isTls())) {
+  bool HasTlsAttr = !WasInserted && (!S->isLazy() || S->isTls());
+  if (HasTlsAttr && (Type == STT_TLS) != S->isTls())
     error("TLS attribute mismatch: " + toString(*S) + "\n>>> defined in " +
           toString(S->File) + "\n>>> defined in " + toString(File));
-  }
 
   return {S, WasInserted};
 }
@@ -487,12 +442,6 @@
   return S;
 }
 
-static void reportDuplicate(Symbol *Sym, InputFile *NewFile) {
-  if (!Config->AllowMultipleDefinition)
-    error("duplicate symbol: " + toString(*Sym) + "\n>>> defined in " +
-          toString(Sym->File) + "\n>>> defined in " + toString(NewFile));
-}
-
 static void reportDuplicate(Symbol *Sym, InputFile *NewFile,
                             InputSectionBase *ErrSec, uint64_t ErrOffset) {
   if (Config->AllowMultipleDefinition)
@@ -500,7 +449,8 @@
 
   Defined *D = cast<Defined>(Sym);
   if (!D->Section || !ErrSec) {
-    reportDuplicate(Sym, NewFile);
+    error("duplicate symbol: " + toString(*Sym) + "\n>>> defined in " +
+          toString(Sym->File) + "\n>>> defined in " + toString(NewFile));
     return;
   }
 
@@ -589,7 +539,7 @@
   if (Cmp > 0)
     replaceSymbol<Defined>(S, &F, Name, Binding, StOther, Type, 0, 0, nullptr);
   else if (Cmp == 0)
-    reportDuplicate(S, &F);
+    reportDuplicate(S, &F, nullptr, 0);
   return S;
 }
 
@@ -602,18 +552,14 @@
   return SymVector[It->second];
 }
 
-// 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) {
+template <class ELFT>
+void SymbolTable::addLazyArchive(StringRef Name, ArchiveFile &File,
+                                 const object::Archive::Symbol Sym) {
   Symbol *S;
   bool WasInserted;
-  std::tie(S, WasInserted) = Symtab->insert(Name);
+  std::tie(S, WasInserted) = insert(Name);
   if (WasInserted) {
-    replaceSymbol<LazyT>(S, File, Symbol::UnknownType,
-                         std::forward<ArgT>(Arg)...);
+    replaceSymbol<LazyArchive>(S, File, STT_NOTYPE, Sym);
     return;
   }
   if (!S->isUndefined())
@@ -622,26 +568,37 @@
   // An undefined weak will not fetch archive members. See comment on Lazy in
   // Symbols.h for the details.
   if (S->isWeak()) {
-    replaceSymbol<LazyT>(S, File, S->Type, std::forward<ArgT>(Arg)...);
+    replaceSymbol<LazyArchive>(S, File, S->Type, Sym);
     S->Binding = STB_WEAK;
     return;
   }
 
-  if (InputFile *F = Fetch())
-    Symtab->addFile<ELFT>(F);
+  if (InputFile *F = File.fetch(Sym))
+    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);
-}
+void SymbolTable::addLazyObject(StringRef Name, LazyObjFile &File) {
+  Symbol *S;
+  bool WasInserted;
+  std::tie(S, WasInserted) = insert(Name);
+  if (WasInserted) {
+    replaceSymbol<LazyObject>(S, File, STT_NOTYPE, Name);
+    return;
+  }
+  if (!S->isUndefined())
+    return;
 
-template <class ELFT>
-void SymbolTable::addLazyObject(StringRef Name, LazyObjFile &Obj) {
-  replaceOrFetchLazy<ELFT, LazyObject>(Name, Obj, [&]() { return Obj.fetch(); },
-                                       Name);
+  // An undefined weak will not fetch archive members. See comment on Lazy in
+  // Symbols.h for the details.
+  if (S->isWeak()) {
+    replaceSymbol<LazyObject>(S, File, S->Type, Name);
+    S->Binding = STB_WEAK;
+    return;
+  }
+
+  if (InputFile *F = File.fetch())
+    addFile<ELFT>(F);
 }
 
 template <class ELFT> void SymbolTable::fetchLazy(Symbol *Sym) {
@@ -822,11 +779,6 @@
 template void SymbolTable::addFile<ELF64LE>(InputFile *);
 template void SymbolTable::addFile<ELF64BE>(InputFile *);
 
-template void SymbolTable::addSymbolWrap<ELF32LE>(StringRef);
-template void SymbolTable::addSymbolWrap<ELF32BE>(StringRef);
-template void SymbolTable::addSymbolWrap<ELF64LE>(StringRef);
-template void SymbolTable::addSymbolWrap<ELF64BE>(StringRef);
-
 template Symbol *SymbolTable::addUndefined<ELF32LE>(StringRef);
 template Symbol *SymbolTable::addUndefined<ELF32BE>(StringRef);
 template Symbol *SymbolTable::addUndefined<ELF64LE>(StringRef);
diff --git a/ELF/SymbolTable.h b/ELF/SymbolTable.h
index 5e6d44d..668ea0e 100644
--- a/ELF/SymbolTable.h
+++ b/ELF/SymbolTable.h
@@ -37,8 +37,7 @@
 public:
   template <class ELFT> void addFile(InputFile *File);
   template <class ELFT> void addCombinedLTOObject();
-  template <class ELFT> void addSymbolWrap(StringRef Name);
-  void applySymbolWrap();
+  void wrap(Symbol *Sym, Symbol *Real, Symbol *Wrap);
 
   ArrayRef<Symbol *> getSymbols() const { return SymVector; }
 
@@ -121,15 +120,6 @@
   // directive in version scripts.
   llvm::Optional<llvm::StringMap<std::vector<Symbol *>>> DemangledSyms;
 
-  struct WrappedSymbol {
-    Symbol *Sym;
-    Symbol *Real;
-    Symbol *Wrap;
-  };
-
-  // For -wrap.
-  std::vector<WrappedSymbol> WrappedSymbols;
-
   // For LTO.
   std::unique_ptr<BitcodeCompiler> LTO;
 };
diff --git a/ELF/Symbols.cpp b/ELF/Symbols.cpp
index c16bda8..94706a9 100644
--- a/ELF/Symbols.cpp
+++ b/ELF/Symbols.cpp
@@ -91,10 +91,15 @@
     uint64_t VA = IS->getVA(Offset);
 
     if (D.isTls() && !Config->Relocatable) {
-      if (!Out::TlsPhdr)
+      // Use the address of the TLS segment's first section rather than the
+      // segment's address, because segment addresses aren't initialized until
+      // after sections are finalized. (e.g. Measuring the size of .rela.dyn
+      // for Android relocation packing requires knowing TLS symbol addresses
+      // during section finalization.)
+      if (!Out::TlsPhdr || !Out::TlsPhdr->FirstSec)
         fatal(toString(D.File) +
               " has an STT_TLS symbol but doesn't have an SHF_TLS section");
-      return VA - Out::TlsPhdr->p_vaddr;
+      return VA - Out::TlsPhdr->FirstSec->Addr;
     }
     return VA;
   }
@@ -103,7 +108,8 @@
     return 0;
   case Symbol::LazyArchiveKind:
   case Symbol::LazyObjectKind:
-    llvm_unreachable("lazy symbol reached writer");
+    assert(Sym.IsUsedInRegularObj && "lazy symbol reached writer");
+    return 0;
   }
   llvm_unreachable("invalid symbol kind");
 }
@@ -113,7 +119,7 @@
   return OutVA + Addend;
 }
 
-uint64_t Symbol::getGotVA() const { return InX::Got->getVA() + getGotOffset(); }
+uint64_t Symbol::getGotVA() const { return In.Got->getVA() + getGotOffset(); }
 
 uint64_t Symbol::getGotOffset() const {
   return GotIndex * Target->GotEntrySize;
@@ -121,8 +127,8 @@
 
 uint64_t Symbol::getGotPltVA() const {
   if (this->IsInIgot)
-    return InX::IgotPlt->getVA() + getGotPltOffset();
-  return InX::GotPlt->getVA() + getGotPltOffset();
+    return In.IgotPlt->getVA() + getGotPltOffset();
+  return In.GotPlt->getVA() + getGotPltOffset();
 }
 
 uint64_t Symbol::getGotPltOffset() const {
@@ -133,8 +139,8 @@
 
 uint64_t Symbol::getPltVA() const {
   if (this->IsInIplt)
-    return InX::Iplt->getVA() + PltIndex * Target->PltEntrySize;
-  return InX::Plt->getVA() + Target->getPltEntryOffset(PltIndex);
+    return In.Iplt->getVA() + PltIndex * Target->PltEntrySize;
+  return In.Plt->getVA() + Target->getPltEntryOffset(PltIndex);
 }
 
 uint64_t Symbol::getPltOffset() const {
@@ -219,7 +225,7 @@
     return Binding;
   if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
     return STB_LOCAL;
-  if (VersionId == VER_NDX_LOCAL && isDefined())
+  if (VersionId == VER_NDX_LOCAL && isDefined() && !IsPreemptible)
     return STB_LOCAL;
   if (!Config->GnuUnique && Binding == STB_GNU_UNIQUE)
     return STB_GLOBAL;
diff --git a/ELF/Symbols.h b/ELF/Symbols.h
index a1bab2e..7bae773 100644
--- a/ELF/Symbols.h
+++ b/ELF/Symbols.h
@@ -128,8 +128,12 @@
     return SymbolKind == LazyArchiveKind || SymbolKind == LazyObjectKind;
   }
 
-  // True if this is an undefined weak symbol.
-  bool isUndefWeak() const { return isWeak() && isUndefined(); }
+  // True if this is an undefined weak symbol. This only works once
+  // all input files have been added.
+  bool isUndefWeak() const {
+    // See comment on lazy symbols for details.
+    return isWeak() && (isUndefined() || isLazy());
+  }
 
   StringRef getName() const {
     if (NameSize == (uint32_t)-1)
@@ -137,6 +141,11 @@
     return {NameData, NameSize};
   }
 
+  void setName(StringRef S) {
+    NameData = S.data();
+    NameSize = S.size();
+  }
+
   void parseSymbolVersion();
 
   bool isInGot() const { return GotIndex != -1U; }
@@ -159,7 +168,8 @@
       : File(File), NameData(Name.Data), NameSize(Name.Size), Binding(Binding),
         Type(Type), StOther(StOther), SymbolKind(K), NeedsPltAddr(false),
         IsInIplt(false), IsInIgot(false), IsPreemptible(false),
-        Used(!Config->GcSections), NeedsTocRestore(false) {}
+        Used(!Config->GcSections), NeedsTocRestore(false),
+        ScriptDefined(false) {}
 
 public:
   // True the symbol should point to its PLT entry.
@@ -182,12 +192,8 @@
   // 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
-  // Type field is normally set to this value for Lazy symbols unless we saw a
-  // weak undefined symbol first, in which case we need to remember the original
-  // symbol's type in order to check for TLS mismatches.
-  enum { UnknownType = 255 };
+  // True if this symbol is defined by a linker script.
+  unsigned ScriptDefined : 1;
 
   bool isSection() const { return Type == llvm::ELF::STT_SECTION; }
   bool isTls() const { return Type == llvm::ELF::STT_TLS; }
@@ -371,6 +377,7 @@
   S->ExportDynamic = Sym.ExportDynamic;
   S->CanInline = Sym.CanInline;
   S->Traced = Sym.Traced;
+  S->ScriptDefined = Sym.ScriptDefined;
 
   // Print out a log message if --trace-symbol was specified.
   // This is for debugging.
diff --git a/ELF/SyntheticSections.cpp b/ELF/SyntheticSections.cpp
index 907eaf1..bc398fe 100644
--- a/ELF/SyntheticSections.cpp
+++ b/ELF/SyntheticSections.cpp
@@ -30,10 +30,11 @@
 #include "lld/Common/Threads.h"
 #include "lld/Common/Version.h"
 #include "llvm/ADT/SetOperations.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/BinaryFormat/Dwarf.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
-#include "llvm/Object/Decompressor.h"
 #include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Support/Compression.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/LEB128.h"
 #include "llvm/Support/MD5.h"
@@ -104,7 +105,7 @@
     Create = true;
 
     std::string Filename = toString(Sec->File);
-    const size_t Size = Sec->Data.size();
+    const size_t Size = Sec->data().size();
     // Older version of BFD (such as the default FreeBSD linker) concatenate
     // .MIPS.abiflags instead of merging. To allow for this case (or potential
     // zero padding) we ignore everything after the first Elf_Mips_ABIFlags
@@ -113,7 +114,7 @@
             Twine(Size) + " instead of " + Twine(sizeof(Elf_Mips_ABIFlags)));
       return nullptr;
     }
-    auto *S = reinterpret_cast<const Elf_Mips_ABIFlags *>(Sec->Data.data());
+    auto *S = reinterpret_cast<const Elf_Mips_ABIFlags *>(Sec->data().data());
     if (S->version != 0) {
       error(Filename + ": unexpected .MIPS.abiflags version " +
             Twine(S->version));
@@ -153,7 +154,7 @@
   Options->size = getSize();
 
   if (!Config->Relocatable)
-    Reginfo.ri_gp_value = InX::MipsGot->getGp();
+    Reginfo.ri_gp_value = In.MipsGot->getGp();
   memcpy(Buf + sizeof(Elf_Mips_Options), &Reginfo, sizeof(Reginfo));
 }
 
@@ -176,7 +177,7 @@
     Sec->Live = false;
 
     std::string Filename = toString(Sec->File);
-    ArrayRef<uint8_t> D = Sec->Data;
+    ArrayRef<uint8_t> D = Sec->data();
 
     while (!D.empty()) {
       if (D.size() < sizeof(Elf_Mips_Options)) {
@@ -210,7 +211,7 @@
 
 template <class ELFT> void MipsReginfoSection<ELFT>::writeTo(uint8_t *Buf) {
   if (!Config->Relocatable)
-    Reginfo.ri_gp_value = InX::MipsGot->getGp();
+    Reginfo.ri_gp_value = In.MipsGot->getGp();
   memcpy(Buf, &Reginfo, sizeof(Reginfo));
 }
 
@@ -232,12 +233,12 @@
   for (InputSectionBase *Sec : Sections) {
     Sec->Live = false;
 
-    if (Sec->Data.size() != sizeof(Elf_Mips_RegInfo)) {
+    if (Sec->data().size() != sizeof(Elf_Mips_RegInfo)) {
       error(toString(Sec->File) + ": invalid size of .reginfo section");
       return nullptr;
     }
 
-    auto *R = reinterpret_cast<const Elf_Mips_RegInfo *>(Sec->Data.data());
+    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;
   };
@@ -260,8 +261,8 @@
                                 uint64_t Size, InputSectionBase &Section) {
   auto *S = make<Defined>(Section.File, Name, STB_LOCAL, STV_DEFAULT, Type,
                           Value, Size, &Section);
-  if (InX::SymTab)
-    InX::SymTab->addSymbol(S);
+  if (In.SymTab)
+    In.SymTab->addSymbol(S);
   return S;
 }
 
@@ -502,7 +503,7 @@
   uint8_t *Buf = getParent()->Loc + OutSecOff;
   std::vector<FdeData> Ret;
 
-  uint64_t VA = InX::EhFrameHdr->getVA();
+  uint64_t VA = In.EhFrameHdr->getVA();
   for (CieRecord *Rec : CieRecords) {
     uint8_t Enc = getFdeEncoding(Rec->Cie);
     for (EhSectionPiece *Fde : Rec->Fdes) {
@@ -937,7 +938,7 @@
       Symbol *S = P.first;
       uint64_t Offset = P.second * Config->Wordsize;
       if (S->IsPreemptible)
-        InX::RelaDyn->addReloc(Target->TlsGotRel, this, Offset, S);
+        In.RelaDyn->addReloc(Target->TlsGotRel, this, Offset, S);
     }
     for (std::pair<Symbol *, size_t> &P : Got.DynTlsSymbols) {
       Symbol *S = P.first;
@@ -945,7 +946,7 @@
       if (S == nullptr) {
         if (!Config->Pic)
           continue;
-        InX::RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S);
+        In.RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S);
       } else {
         // When building a shared library we still need a dynamic relocation
         // for the module index. Therefore only checking for
@@ -953,13 +954,13 @@
         // thread-locals that have been marked as local through a linker script)
         if (!S->IsPreemptible && !Config->Pic)
           continue;
-        InX::RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S);
+        In.RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S);
         // However, we can skip writing the TLS offset reloc for non-preemptible
         // symbols since it is known even in shared libraries
         if (!S->IsPreemptible)
           continue;
         Offset += Config->Wordsize;
-        InX::RelaDyn->addReloc(Target->TlsOffsetRel, this, Offset, S);
+        In.RelaDyn->addReloc(Target->TlsOffsetRel, this, Offset, S);
       }
     }
 
@@ -971,7 +972,7 @@
     // Dynamic relocations for "global" entries.
     for (const std::pair<Symbol *, size_t> &P : Got.Global) {
       uint64_t Offset = P.second * Config->Wordsize;
-      InX::RelaDyn->addReloc(Target->RelativeRel, this, Offset, P.first);
+      In.RelaDyn->addReloc(Target->RelativeRel, this, Offset, P.first);
     }
     if (!Config->Pic)
       continue;
@@ -981,14 +982,14 @@
       size_t PageCount = L.second.Count;
       for (size_t PI = 0; PI < PageCount; ++PI) {
         uint64_t Offset = (L.second.FirstIndex + PI) * Config->Wordsize;
-        InX::RelaDyn->addReloc({Target->RelativeRel, this, Offset, L.first,
-                                int64_t(PI * 0x10000)});
+        In.RelaDyn->addReloc({Target->RelativeRel, this, Offset, L.first,
+                              int64_t(PI * 0x10000)});
       }
     }
     for (const std::pair<GotEntry, size_t> &P : Got.Local16) {
       uint64_t Offset = P.second * Config->Wordsize;
-      InX::RelaDyn->addReloc({Target->RelativeRel, this, Offset, true,
-                              P.first.first, P.first.second});
+      In.RelaDyn->addReloc({Target->RelativeRel, this, Offset, true,
+                            P.first.first, P.first.second});
     }
   }
 }
@@ -1200,21 +1201,21 @@
   // Add strings to .dynstr early so that .dynstr's size will be
   // fixed early.
   for (StringRef S : Config->FilterList)
-    addInt(DT_FILTER, InX::DynStrTab->addString(S));
+    addInt(DT_FILTER, In.DynStrTab->addString(S));
   for (StringRef S : Config->AuxiliaryList)
-    addInt(DT_AUXILIARY, InX::DynStrTab->addString(S));
+    addInt(DT_AUXILIARY, In.DynStrTab->addString(S));
 
   if (!Config->Rpath.empty())
     addInt(Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
-           InX::DynStrTab->addString(Config->Rpath));
+           In.DynStrTab->addString(Config->Rpath));
 
   for (InputFile *File : SharedFiles) {
     SharedFile<ELFT> *F = cast<SharedFile<ELFT>>(File);
     if (F->IsNeeded)
-      addInt(DT_NEEDED, InX::DynStrTab->addString(F->SoName));
+      addInt(DT_NEEDED, In.DynStrTab->addString(F->SoName));
   }
   if (!Config->SoName.empty())
-    addInt(DT_SONAME, InX::DynStrTab->addString(Config->SoName));
+    addInt(DT_SONAME, In.DynStrTab->addString(Config->SoName));
 }
 
 template <class ELFT>
@@ -1264,8 +1265,12 @@
   uint32_t DtFlags1 = 0;
   if (Config->Bsymbolic)
     DtFlags |= DF_SYMBOLIC;
+  if (Config->ZGlobal)
+    DtFlags1 |= DF_1_GLOBAL;
   if (Config->ZInitfirst)
     DtFlags1 |= DF_1_INITFIRST;
+  if (Config->ZInterpose)
+    DtFlags1 |= DF_1_INTERPOSE;
   if (Config->ZNodelete)
     DtFlags1 |= DF_1_NODELETE;
   if (Config->ZNodlopen)
@@ -1297,10 +1302,10 @@
   if (!Config->Shared && !Config->Relocatable && !Config->ZRodynamic)
     addInt(DT_DEBUG, 0);
 
-  this->Link = InX::DynStrTab->getParent()->SectionIndex;
-  if (!InX::RelaDyn->empty()) {
-    addInSec(InX::RelaDyn->DynamicTag, InX::RelaDyn);
-    addSize(InX::RelaDyn->SizeDynamicTag, InX::RelaDyn->getParent());
+  this->Link = In.DynStrTab->getParent()->SectionIndex;
+  if (!In.RelaDyn->empty()) {
+    addInSec(In.RelaDyn->DynamicTag, In.RelaDyn);
+    addSize(In.RelaDyn->SizeDynamicTag, In.RelaDyn->getParent());
 
     bool IsRela = Config->IsRela;
     addInt(IsRela ? DT_RELAENT : DT_RELENT,
@@ -1310,16 +1315,16 @@
     // The problem is in the tight relation between dynamic
     // relocations and GOT. So do not emit this tag on MIPS.
     if (Config->EMachine != EM_MIPS) {
-      size_t NumRelativeRels = InX::RelaDyn->getRelativeRelocCount();
+      size_t NumRelativeRels = In.RelaDyn->getRelativeRelocCount();
       if (Config->ZCombreloc && NumRelativeRels)
         addInt(IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels);
     }
   }
-  if (InX::RelrDyn && !InX::RelrDyn->Relocs.empty()) {
+  if (In.RelrDyn && !In.RelrDyn->Relocs.empty()) {
     addInSec(Config->UseAndroidRelrTags ? DT_ANDROID_RELR : DT_RELR,
-             InX::RelrDyn);
+             In.RelrDyn);
     addSize(Config->UseAndroidRelrTags ? DT_ANDROID_RELRSZ : DT_RELRSZ,
-            InX::RelrDyn->getParent());
+            In.RelrDyn->getParent());
     addInt(Config->UseAndroidRelrTags ? DT_ANDROID_RELRENT : DT_RELRENT,
            sizeof(Elf_Relr));
   }
@@ -1329,33 +1334,33 @@
   // as RelaIplt have. And we still want to emit proper dynamic tags for that
   // case, so here we always use RelaPlt as marker for the begining of
   // .rel[a].plt section.
-  if (InX::RelaPlt->getParent()->Live) {
-    addInSec(DT_JMPREL, InX::RelaPlt);
-    addSize(DT_PLTRELSZ, InX::RelaPlt->getParent());
+  if (In.RelaPlt->getParent()->Live) {
+    addInSec(DT_JMPREL, In.RelaPlt);
+    addSize(DT_PLTRELSZ, In.RelaPlt->getParent());
     switch (Config->EMachine) {
     case EM_MIPS:
-      addInSec(DT_MIPS_PLTGOT, InX::GotPlt);
+      addInSec(DT_MIPS_PLTGOT, In.GotPlt);
       break;
     case EM_SPARCV9:
-      addInSec(DT_PLTGOT, InX::Plt);
+      addInSec(DT_PLTGOT, In.Plt);
       break;
     default:
-      addInSec(DT_PLTGOT, InX::GotPlt);
+      addInSec(DT_PLTGOT, In.GotPlt);
       break;
     }
     addInt(DT_PLTREL, Config->IsRela ? DT_RELA : DT_REL);
   }
 
-  addInSec(DT_SYMTAB, InX::DynSymTab);
+  addInSec(DT_SYMTAB, In.DynSymTab);
   addInt(DT_SYMENT, sizeof(Elf_Sym));
-  addInSec(DT_STRTAB, InX::DynStrTab);
-  addInt(DT_STRSZ, InX::DynStrTab->getSize());
+  addInSec(DT_STRTAB, In.DynStrTab);
+  addInt(DT_STRSZ, In.DynStrTab->getSize());
   if (!Config->ZText)
     addInt(DT_TEXTREL, 0);
-  if (InX::GnuHashTab)
-    addInSec(DT_GNU_HASH, InX::GnuHashTab);
-  if (InX::HashTab)
-    addInSec(DT_HASH, InX::HashTab);
+  if (In.GnuHashTab)
+    addInSec(DT_GNU_HASH, In.GnuHashTab);
+  if (In.HashTab)
+    addInSec(DT_HASH, In.HashTab);
 
   if (Out::PreinitArray) {
     addOutSec(DT_PREINIT_ARRAY, Out::PreinitArray);
@@ -1377,47 +1382,47 @@
     if (B->isDefined())
       addSym(DT_FINI, B);
 
-  bool HasVerNeed = In<ELFT>::VerNeed->getNeedNum() != 0;
-  if (HasVerNeed || In<ELFT>::VerDef)
-    addInSec(DT_VERSYM, In<ELFT>::VerSym);
-  if (In<ELFT>::VerDef) {
-    addInSec(DT_VERDEF, In<ELFT>::VerDef);
+  bool HasVerNeed = InX<ELFT>::VerNeed->getNeedNum() != 0;
+  if (HasVerNeed || In.VerDef)
+    addInSec(DT_VERSYM, InX<ELFT>::VerSym);
+  if (In.VerDef) {
+    addInSec(DT_VERDEF, In.VerDef);
     addInt(DT_VERDEFNUM, getVerDefNum());
   }
   if (HasVerNeed) {
-    addInSec(DT_VERNEED, In<ELFT>::VerNeed);
-    addInt(DT_VERNEEDNUM, In<ELFT>::VerNeed->getNeedNum());
+    addInSec(DT_VERNEED, InX<ELFT>::VerNeed);
+    addInt(DT_VERNEEDNUM, InX<ELFT>::VerNeed->getNeedNum());
   }
 
   if (Config->EMachine == EM_MIPS) {
     addInt(DT_MIPS_RLD_VERSION, 1);
     addInt(DT_MIPS_FLAGS, RHF_NOTPOT);
     addInt(DT_MIPS_BASE_ADDRESS, Target->getImageBase());
-    addInt(DT_MIPS_SYMTABNO, InX::DynSymTab->getNumSymbols());
+    addInt(DT_MIPS_SYMTABNO, In.DynSymTab->getNumSymbols());
 
-    add(DT_MIPS_LOCAL_GOTNO, [] { return InX::MipsGot->getLocalEntriesNum(); });
+    add(DT_MIPS_LOCAL_GOTNO, [] { return In.MipsGot->getLocalEntriesNum(); });
 
-    if (const Symbol *B = InX::MipsGot->getFirstGlobalEntry())
+    if (const Symbol *B = In.MipsGot->getFirstGlobalEntry())
       addInt(DT_MIPS_GOTSYM, B->DynsymIndex);
     else
-      addInt(DT_MIPS_GOTSYM, InX::DynSymTab->getNumSymbols());
-    addInSec(DT_PLTGOT, InX::MipsGot);
-    if (InX::MipsRldMap) {
+      addInt(DT_MIPS_GOTSYM, In.DynSymTab->getNumSymbols());
+    addInSec(DT_PLTGOT, In.MipsGot);
+    if (In.MipsRldMap) {
       if (!Config->Pie)
-        addInSec(DT_MIPS_RLD_MAP, InX::MipsRldMap);
+        addInSec(DT_MIPS_RLD_MAP, In.MipsRldMap);
       // Store the offset to the .rld_map section
       // relative to the address of the tag.
-      addInSecRelative(DT_MIPS_RLD_MAP_REL, InX::MipsRldMap);
+      addInSecRelative(DT_MIPS_RLD_MAP_REL, In.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()) {
+  if (Config->EMachine == EM_PPC64 && !In.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;
+                         return In.Plt->getVA(0) + Offset;
                        }});
   }
 
@@ -1489,10 +1494,8 @@
   // If all relocations are R_*_RELATIVE they don't refer to any
   // dynamic symbol and we don't need a dynamic symbol table. If that
   // is the case, just use 0 as the link.
-  Link = InX::DynSymTab ? InX::DynSymTab->getParent()->SectionIndex : 0;
-
-  // Set required output section properties.
-  getParent()->Link = Link;
+  getParent()->Link =
+      In.DynSymTab ? In.DynSymTab->getParent()->SectionIndex : 0;
 }
 
 RelrBaseSection::RelrBaseSection()
@@ -1621,10 +1624,9 @@
       NonRelatives.push_back(R);
   }
 
-  llvm::sort(Relatives.begin(), Relatives.end(),
-             [](const Elf_Rel &A, const Elf_Rel &B) {
-               return A.r_offset < B.r_offset;
-             });
+  llvm::sort(Relatives, [](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
@@ -1702,10 +1704,9 @@
   }
 
   // Finally the non-relative relocations.
-  llvm::sort(NonRelatives.begin(), NonRelatives.end(),
-             [](const Elf_Rela &A, const Elf_Rela &B) {
-               return A.r_offset < B.r_offset;
-             });
+  llvm::sort(NonRelatives, [](const Elf_Rela &A, const Elf_Rela &B) {
+    return A.r_offset < B.r_offset;
+  });
   if (!NonRelatives.empty()) {
     Add(NonRelatives.size());
     Add(HasAddendIfRela);
@@ -1845,8 +1846,10 @@
 void SymbolTableBaseSection::finalizeContents() {
   getParent()->Link = StrTabSec.getParent()->SectionIndex;
 
-  if (this->Type != SHT_DYNSYM)
+  if (this->Type != SHT_DYNSYM) {
+    sortSymTabSymbols();
     return;
+  }
 
   // If it is a .dynsym, there should be no local symbols, but we need
   // to do a few things for the dynamic linker.
@@ -1855,9 +1858,9 @@
   // Because the first symbol entry is a null entry, 1 is the first.
   getParent()->Info = 1;
 
-  if (InX::GnuHashTab) {
+  if (In.GnuHashTab) {
     // NB: It also sorts Symbols to meet the GNU hash table requirements.
-    InX::GnuHashTab->addSymbols(Symbols);
+    In.GnuHashTab->addSymbols(Symbols);
   } else if (Config->EMachine == EM_MIPS) {
     std::stable_sort(Symbols.begin(), Symbols.end(), sortMipsSymbols);
   }
@@ -1874,9 +1877,7 @@
 // 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() {
-  assert(this->Type == SHT_SYMTAB);
-
+void SymbolTableBaseSection::sortSymTabSymbols() {
   // Move all local symbols before global symbols.
   auto E = std::stable_partition(
       Symbols.begin(), Symbols.end(), [](const SymbolTableEntry &S) {
@@ -1948,7 +1949,8 @@
   if (!isa<Defined>(Sym) || Sym->NeedsPltAddr)
     return SHN_UNDEF;
   if (const OutputSection *OS = Sym->getOutputSection())
-    return OS->SectionIndex >= SHN_LORESERVE ? SHN_XINDEX : OS->SectionIndex;
+    return OS->SectionIndex >= SHN_LORESERVE ? (uint32_t)SHN_XINDEX
+                                             : OS->SectionIndex;
   return SHN_ABS;
 }
 
@@ -2038,7 +2040,7 @@
   // with an entry in .symtab. If the corresponding entry contains SHN_XINDEX,
   // we need to write actual index, otherwise, we must write SHN_UNDEF(0).
   Buf += 4; // Ignore .symtab[0] entry.
-  for (const SymbolTableEntry &Entry : InX::SymTab->getSymbols()) {
+  for (const SymbolTableEntry &Entry : In.SymTab->getSymbols()) {
     if (getSymSectionIndex(Entry.Sym) == SHN_XINDEX)
       write32(Buf, Entry.Sym->getOutputSection()->SectionIndex);
     Buf += 4;
@@ -2059,11 +2061,11 @@
 }
 
 void SymtabShndxSection::finalizeContents() {
-  getParent()->Link = InX::SymTab->getParent()->SectionIndex;
+  getParent()->Link = In.SymTab->getParent()->SectionIndex;
 }
 
 size_t SymtabShndxSection::getSize() const {
-  return InX::SymTab->getNumSymbols() * 4;
+  return In.SymTab->getNumSymbols() * 4;
 }
 
 // .hash and .gnu.hash sections contain on-disk hash tables that map
@@ -2102,7 +2104,7 @@
 }
 
 void GnuHashTableSection::finalizeContents() {
-  getParent()->Link = InX::DynSymTab->getParent()->SectionIndex;
+  getParent()->Link = In.DynSymTab->getParent()->SectionIndex;
 
   // Computes bloom filter size in word size. We want to allocate 12
   // bits for each symbol. It must be a power of two.
@@ -2127,7 +2129,7 @@
 
   // Write a header.
   write32(Buf, NBuckets);
-  write32(Buf + 4, InX::DynSymTab->getNumSymbols() - Symbols.size());
+  write32(Buf + 4, In.DynSymTab->getNumSymbols() - Symbols.size());
   write32(Buf + 8, MaskWords);
   write32(Buf + 12, Shift2);
   Buf += 16;
@@ -2232,13 +2234,13 @@
 }
 
 void HashTableSection::finalizeContents() {
-  getParent()->Link = InX::DynSymTab->getParent()->SectionIndex;
+  getParent()->Link = In.DynSymTab->getParent()->SectionIndex;
 
   unsigned NumEntries = 2;                       // nbucket and nchain.
-  NumEntries += InX::DynSymTab->getNumSymbols(); // The chain entries.
+  NumEntries += In.DynSymTab->getNumSymbols();   // The chain entries.
 
   // Create as many buckets as there are symbols.
-  NumEntries += InX::DynSymTab->getNumSymbols();
+  NumEntries += In.DynSymTab->getNumSymbols();
   this->Size = NumEntries * 4;
 }
 
@@ -2246,7 +2248,7 @@
   // See comment in GnuHashTableSection::writeTo.
   memset(Buf, 0, Size);
 
-  unsigned NumSymbols = InX::DynSymTab->getNumSymbols();
+  unsigned NumSymbols = In.DynSymTab->getNumSymbols();
 
   uint32_t *P = reinterpret_cast<uint32_t *>(Buf);
   write32(P++, NumSymbols); // nbucket
@@ -2255,7 +2257,7 @@
   uint32_t *Buckets = P;
   uint32_t *Chains = P + NumSymbols;
 
-  for (const SymbolTableEntry &S : InX::DynSymTab->getSymbols()) {
+  for (const SymbolTableEntry &S : In.DynSymTab->getSymbols()) {
     Symbol *Sym = S.Sym;
     StringRef Name = Sym->getName();
     unsigned I = Sym->DynsymIndex;
@@ -2298,9 +2300,9 @@
 
 template <class ELFT> void PltSection::addEntry(Symbol &Sym) {
   Sym.PltIndex = Entries.size();
-  RelocationBaseSection *PltRelocSection = InX::RelaPlt;
+  RelocationBaseSection *PltRelocSection = In.RelaPlt;
   if (IsIplt) {
-    PltRelocSection = InX::RelaIplt;
+    PltRelocSection = In.RelaIplt;
     Sym.IsInIplt = true;
   }
   unsigned RelOff =
@@ -2326,14 +2328,14 @@
 }
 
 unsigned PltSection::getPltRelocOff() const {
-  return IsIplt ? InX::Plt->getSize() : 0;
+  return IsIplt ? In.Plt->getSize() : 0;
 }
 
 // The string hash function for .gdb_index.
 static uint32_t computeGdbHash(StringRef S) {
   uint32_t H = 0;
   for (uint8_t C : S)
-    H = H * 67 + tolower(C) - 113;
+    H = H * 67 + toLower(C) - 113;
   return H;
 }
 
@@ -2570,8 +2572,9 @@
 
   // Write the string pool.
   Hdr->ConstantPoolOff = Buf - Start;
-  for (GdbSymbol &Sym : Symbols)
+  parallelForEach(Symbols, [&](GdbSymbol &Sym) {
     memcpy(Buf + Sym.NameOff, Sym.Name.data(), Sym.Name.size());
+  });
 
   // Write the CU vectors.
   for (GdbSymbol &Sym : Symbols) {
@@ -2596,13 +2599,13 @@
 void EhFrameHeader::writeTo(uint8_t *Buf) {
   typedef EhFrameSection::FdeData FdeData;
 
-  std::vector<FdeData> Fdes = InX::EhFrame->getFdeData();
+  std::vector<FdeData> Fdes = In.EhFrame->getFdeData();
 
   Buf[0] = 1;
   Buf[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4;
   Buf[2] = DW_EH_PE_udata4;
   Buf[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4;
-  write32(Buf + 4, InX::EhFrame->getParent()->Addr - this->getVA() - 4);
+  write32(Buf + 4, In.EhFrame->getParent()->Addr - this->getVA() - 4);
   write32(Buf + 8, Fdes.size());
   Buf += 12;
 
@@ -2615,13 +2618,12 @@
 
 size_t EhFrameHeader::getSize() const {
   // .eh_frame_hdr has a 12 bytes header followed by an array of FDEs.
-  return 12 + InX::EhFrame->NumFdes * 8;
+  return 12 + In.EhFrame->NumFdes * 8;
 }
 
-bool EhFrameHeader::empty() const { return InX::EhFrame->empty(); }
+bool EhFrameHeader::empty() const { return In.EhFrame->empty(); }
 
-template <class ELFT>
-VersionDefinitionSection<ELFT>::VersionDefinitionSection()
+VersionDefinitionSection::VersionDefinitionSection()
     : SyntheticSection(SHF_ALLOC, SHT_GNU_verdef, sizeof(uint32_t),
                        ".gnu.version_d") {}
 
@@ -2631,12 +2633,12 @@
   return Config->OutputFile;
 }
 
-template <class ELFT> void VersionDefinitionSection<ELFT>::finalizeContents() {
-  FileDefNameOff = InX::DynStrTab->addString(getFileDefName());
+void VersionDefinitionSection::finalizeContents() {
+  FileDefNameOff = In.DynStrTab->addString(getFileDefName());
   for (VersionDefinition &V : Config->VersionDefinitions)
-    V.NameOff = InX::DynStrTab->addString(V.Name);
+    V.NameOff = In.DynStrTab->addString(V.Name);
 
-  getParent()->Link = InX::DynStrTab->getParent()->SectionIndex;
+  getParent()->Link = In.DynStrTab->getParent()->SectionIndex;
 
   // sh_info should be set to the number of definitions. This fact is missed in
   // documentation, but confirmed by binutils community:
@@ -2644,68 +2646,68 @@
   getParent()->Info = getVerDefNum();
 }
 
-template <class ELFT>
-void VersionDefinitionSection<ELFT>::writeOne(uint8_t *Buf, uint32_t Index,
-                                              StringRef Name, size_t NameOff) {
-  auto *Verdef = reinterpret_cast<Elf_Verdef *>(Buf);
-  Verdef->vd_version = 1;
-  Verdef->vd_cnt = 1;
-  Verdef->vd_aux = sizeof(Elf_Verdef);
-  Verdef->vd_next = sizeof(Elf_Verdef) + sizeof(Elf_Verdaux);
-  Verdef->vd_flags = (Index == 1 ? VER_FLG_BASE : 0);
-  Verdef->vd_ndx = Index;
-  Verdef->vd_hash = hashSysV(Name);
+void VersionDefinitionSection::writeOne(uint8_t *Buf, uint32_t Index,
+                                        StringRef Name, size_t NameOff) {
+  uint16_t Flags = Index == 1 ? VER_FLG_BASE : 0;
 
-  auto *Verdaux = reinterpret_cast<Elf_Verdaux *>(Buf + sizeof(Elf_Verdef));
-  Verdaux->vda_name = NameOff;
-  Verdaux->vda_next = 0;
+  // Write a verdef.
+  write16(Buf, 1);                  // vd_version
+  write16(Buf + 2, Flags);          // vd_flags
+  write16(Buf + 4, Index);          // vd_ndx
+  write16(Buf + 6, 1);              // vd_cnt
+  write32(Buf + 8, hashSysV(Name)); // vd_hash
+  write32(Buf + 12, 20);            // vd_aux
+  write32(Buf + 16, 28);            // vd_next
+
+  // Write a veraux.
+  write32(Buf + 20, NameOff); // vda_name
+  write32(Buf + 24, 0);       // vda_next
 }
 
-template <class ELFT>
-void VersionDefinitionSection<ELFT>::writeTo(uint8_t *Buf) {
+void VersionDefinitionSection::writeTo(uint8_t *Buf) {
   writeOne(Buf, 1, getFileDefName(), FileDefNameOff);
 
   for (VersionDefinition &V : Config->VersionDefinitions) {
-    Buf += sizeof(Elf_Verdef) + sizeof(Elf_Verdaux);
+    Buf += EntrySize;
     writeOne(Buf, V.Id, V.Name, V.NameOff);
   }
 
   // Need to terminate the last version definition.
-  Elf_Verdef *Verdef = reinterpret_cast<Elf_Verdef *>(Buf);
-  Verdef->vd_next = 0;
+  write32(Buf + 16, 0); // vd_next
 }
 
-template <class ELFT> size_t VersionDefinitionSection<ELFT>::getSize() const {
-  return (sizeof(Elf_Verdef) + sizeof(Elf_Verdaux)) * getVerDefNum();
+size_t VersionDefinitionSection::getSize() const {
+  return EntrySize * getVerDefNum();
 }
 
+// .gnu.version is a table where each entry is 2 byte long.
 template <class ELFT>
 VersionTableSection<ELFT>::VersionTableSection()
     : SyntheticSection(SHF_ALLOC, SHT_GNU_versym, sizeof(uint16_t),
                        ".gnu.version") {
-  this->Entsize = sizeof(Elf_Versym);
+  this->Entsize = 2;
 }
 
 template <class ELFT> void VersionTableSection<ELFT>::finalizeContents() {
   // At the moment of june 2016 GNU docs does not mention that sh_link field
   // should be set, but Sun docs do. Also readelf relies on this field.
-  getParent()->Link = InX::DynSymTab->getParent()->SectionIndex;
+  getParent()->Link = In.DynSymTab->getParent()->SectionIndex;
 }
 
 template <class ELFT> size_t VersionTableSection<ELFT>::getSize() const {
-  return sizeof(Elf_Versym) * (InX::DynSymTab->getSymbols().size() + 1);
+  return (In.DynSymTab->getSymbols().size() + 1) * 2;
 }
 
 template <class ELFT> void VersionTableSection<ELFT>::writeTo(uint8_t *Buf) {
-  auto *OutVersym = reinterpret_cast<Elf_Versym *>(Buf) + 1;
-  for (const SymbolTableEntry &S : InX::DynSymTab->getSymbols()) {
-    OutVersym->vs_index = S.Sym->VersionId;
-    ++OutVersym;
+  Buf += 2;
+  for (const SymbolTableEntry &S : In.DynSymTab->getSymbols()) {
+    write16(Buf, S.Sym->VersionId);
+    Buf += 2;
   }
 }
 
 template <class ELFT> bool VersionTableSection<ELFT>::empty() const {
-  return !In<ELFT>::VerDef && In<ELFT>::VerNeed->empty();
+  return !In.VerDef && InX<ELFT>::VerNeed->empty();
 }
 
 template <class ELFT>
@@ -2729,7 +2731,7 @@
   // to create one by adding it to our needed list and creating a dynstr entry
   // for the soname.
   if (File.VerdefMap.empty())
-    Needed.push_back({&File, InX::DynStrTab->addString(File.SoName)});
+    Needed.push_back({&File, In.DynStrTab->addString(File.SoName)});
   const typename ELFT::Verdef *Ver = File.Verdefs[SS->VerdefIndex];
   typename SharedFile<ELFT>::NeededVer &NV = File.VerdefMap[Ver];
 
@@ -2737,8 +2739,8 @@
   // prepare to create one by allocating a version identifier and creating a
   // dynstr entry for the version name.
   if (NV.Index == 0) {
-    NV.StrTab = InX::DynStrTab->addString(File.getStringTable().data() +
-                                          Ver->getAux()->vda_name);
+    NV.StrTab = In.DynStrTab->addString(File.getStringTable().data() +
+                                        Ver->getAux()->vda_name);
     NV.Index = NextIndex++;
   }
   SS->VersionId = NV.Index;
@@ -2780,7 +2782,7 @@
 }
 
 template <class ELFT> void VersionNeedSection<ELFT>::finalizeContents() {
-  getParent()->Link = InX::DynStrTab->getParent()->SectionIndex;
+  getParent()->Link = In.DynStrTab->getParent()->SectionIndex;
   getParent()->Info = Needed.size();
 }
 
@@ -2896,12 +2898,6 @@
   return make<MergeNoTailSection>(Name, Type, Flags, Alignment);
 }
 
-// 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().
@@ -2929,8 +2925,10 @@
 
     // We do not want to handle sections that are not alive, so just remove
     // them instead of trying to merge.
-    if (!MS->Live)
+    if (!MS->Live) {
+      S = nullptr;
       continue;
+    }
 
     StringRef OutsecName = getOutputSectionName(MS);
     uint32_t Alignment = std::max<uint32_t>(MS->Alignment, MS->Entsize);
@@ -3038,34 +3036,7 @@
   return Changed;
 }
 
-InputSection *InX::ARMAttributes;
-BssSection *InX::Bss;
-BssSection *InX::BssRelRo;
-BuildIdSection *InX::BuildId;
-EhFrameHeader *InX::EhFrameHdr;
-EhFrameSection *InX::EhFrame;
-SyntheticSection *InX::Dynamic;
-StringTableSection *InX::DynStrTab;
-SymbolTableBaseSection *InX::DynSymTab;
-InputSection *InX::Interp;
-GdbIndexSection *InX::GdbIndex;
-GotSection *InX::Got;
-GotPltSection *InX::GotPlt;
-GnuHashTableSection *InX::GnuHashTab;
-HashTableSection *InX::HashTab;
-IgotPltSection *InX::IgotPlt;
-MipsGotSection *InX::MipsGot;
-MipsRldMapSection *InX::MipsRldMap;
-PltSection *InX::Plt;
-PltSection *InX::Iplt;
-RelocationBaseSection *InX::RelaDyn;
-RelrBaseSection *InX::RelrDyn;
-RelocationBaseSection *InX::RelaPlt;
-RelocationBaseSection *InX::RelaIplt;
-StringTableSection *InX::ShStrTab;
-StringTableSection *InX::StrTab;
-SymbolTableBaseSection *InX::SymTab;
-SymtabShndxSection *InX::SymTabShndx;
+InStruct elf::In;
 
 template GdbIndexSection *GdbIndexSection::create<ELF32LE>();
 template GdbIndexSection *GdbIndexSection::create<ELF32BE>();
@@ -3141,8 +3112,3 @@
 template class elf::VersionNeedSection<ELF32BE>;
 template class elf::VersionNeedSection<ELF64LE>;
 template class elf::VersionNeedSection<ELF64BE>;
-
-template class elf::VersionDefinitionSection<ELF32LE>;
-template class elf::VersionDefinitionSection<ELF32BE>;
-template class elf::VersionDefinitionSection<ELF64LE>;
-template class elf::VersionDefinitionSection<ELF64BE>;
diff --git a/ELF/SyntheticSections.h b/ELF/SyntheticSections.h
index a780c66..51a0441 100644
--- a/ELF/SyntheticSections.h
+++ b/ELF/SyntheticSections.h
@@ -21,8 +21,8 @@
 #ifndef LLD_ELF_SYNTHETIC_SECTION_H
 #define LLD_ELF_SYNTHETIC_SECTION_H
 
+#include "DWARF.h"
 #include "EhFrame.h"
-#include "GdbIndex.h"
 #include "InputSection.h"
 #include "llvm/ADT/MapVector.h"
 #include "llvm/MC/StringTableBuilder.h"
@@ -50,8 +50,6 @@
   // If the section has the SHF_ALLOC flag and the size may be changed if
   // thunks are added, update the section size.
   virtual bool updateAllocSize() { return false; }
-  // If any additional finalization of contents are needed post thunk creation.
-  virtual void postThunkContents() {}
   virtual bool empty() const { return false; }
 
   static bool classof(const SectionBase *D) {
@@ -137,6 +135,15 @@
   uint64_t Size = 0;
 };
 
+// .note.GNU-stack section.
+class GnuStackSection : public SyntheticSection {
+public:
+  GnuStackSection()
+      : SyntheticSection(0, llvm::ELF::SHT_PROGBITS, 1, ".note.GNU-stack") {}
+  void writeTo(uint8_t *Buf) override {}
+  size_t getSize() const override { return 0; }
+};
+
 // .note.gnu.build-id section.
 class BuildIdSection : public SyntheticSection {
   // First 16 bytes are a header.
@@ -529,6 +536,7 @@
 class RelrBaseSection : public SyntheticSection {
 public:
   RelrBaseSection();
+  bool empty() const override { return Relocs.empty(); }
   std::vector<RelativeReloc> Relocs;
 };
 
@@ -561,7 +569,6 @@
 public:
   SymbolTableBaseSection(StringTableSection &StrTabSec);
   void finalizeContents() override;
-  void postThunkContents() override;
   size_t getSize() const override { return getNumSymbols() * Entsize; }
   void addSymbol(Symbol *Sym);
   unsigned getNumSymbols() const { return Symbols.size() + 1; }
@@ -569,6 +576,8 @@
   ArrayRef<SymbolTableEntry> getSymbols() const { return Symbols; }
 
 protected:
+  void sortSymTabSymbols();
+
   // A vector of symbols and their string table offsets.
   std::vector<SymbolTableEntry> Symbols;
 
@@ -748,11 +757,7 @@
 // shall be contained in the DT_VERDEFNUM entry of the .dynamic section.
 // The section shall contain an array of Elf_Verdef structures, optionally
 // followed by an array of Elf_Verdaux structures.
-template <class ELFT>
 class VersionDefinitionSection final : public SyntheticSection {
-  typedef typename ELFT::Verdef Elf_Verdef;
-  typedef typename ELFT::Verdaux Elf_Verdaux;
-
 public:
   VersionDefinitionSection();
   void finalizeContents() override;
@@ -760,6 +765,7 @@
   void writeTo(uint8_t *Buf) override;
 
 private:
+  enum { EntrySize = 28 };
   void writeOne(uint8_t *Buf, uint32_t Index, StringRef Name, size_t NameOff);
 
   unsigned FileDefNameOff;
@@ -773,8 +779,6 @@
 // the own object or in any of the dependencies.
 template <class ELFT>
 class VersionTableSection final : public SyntheticSection {
-  typedef typename ELFT::Versym Elf_Versym;
-
 public:
   VersionTableSection();
   void finalizeContents() override;
@@ -966,7 +970,6 @@
 
 InputSection *createInterpSection();
 MergeInputSection *createCommentSection();
-void decompressSections();
 template <class ELFT> void splitSections();
 void mergeSections();
 
@@ -974,46 +977,47 @@
                            uint64_t Size, InputSectionBase &Section);
 
 // Linker generated sections which can be used as inputs.
-struct InX {
-  static InputSection *ARMAttributes;
-  static BssSection *Bss;
-  static BssSection *BssRelRo;
-  static BuildIdSection *BuildId;
-  static EhFrameHeader *EhFrameHdr;
-  static EhFrameSection *EhFrame;
-  static SyntheticSection *Dynamic;
-  static StringTableSection *DynStrTab;
-  static SymbolTableBaseSection *DynSymTab;
-  static GnuHashTableSection *GnuHashTab;
-  static HashTableSection *HashTab;
-  static InputSection *Interp;
-  static GdbIndexSection *GdbIndex;
-  static GotSection *Got;
-  static GotPltSection *GotPlt;
-  static IgotPltSection *IgotPlt;
-  static MipsGotSection *MipsGot;
-  static MipsRldMapSection *MipsRldMap;
-  static PltSection *Plt;
-  static PltSection *Iplt;
-  static RelocationBaseSection *RelaDyn;
-  static RelrBaseSection *RelrDyn;
-  static RelocationBaseSection *RelaPlt;
-  static RelocationBaseSection *RelaIplt;
-  static StringTableSection *ShStrTab;
-  static StringTableSection *StrTab;
-  static SymbolTableBaseSection *SymTab;
-  static SymtabShndxSection* SymTabShndx;
+struct InStruct {
+  InputSection *ARMAttributes;
+  BssSection *Bss;
+  BssSection *BssRelRo;
+  BuildIdSection *BuildId;
+  EhFrameHeader *EhFrameHdr;
+  EhFrameSection *EhFrame;
+  SyntheticSection *Dynamic;
+  StringTableSection *DynStrTab;
+  SymbolTableBaseSection *DynSymTab;
+  GnuHashTableSection *GnuHashTab;
+  HashTableSection *HashTab;
+  InputSection *Interp;
+  GdbIndexSection *GdbIndex;
+  GotSection *Got;
+  GotPltSection *GotPlt;
+  IgotPltSection *IgotPlt;
+  MipsGotSection *MipsGot;
+  MipsRldMapSection *MipsRldMap;
+  PltSection *Plt;
+  PltSection *Iplt;
+  RelocationBaseSection *RelaDyn;
+  RelrBaseSection *RelrDyn;
+  RelocationBaseSection *RelaPlt;
+  RelocationBaseSection *RelaIplt;
+  StringTableSection *ShStrTab;
+  StringTableSection *StrTab;
+  SymbolTableBaseSection *SymTab;
+  SymtabShndxSection *SymTabShndx;
+  VersionDefinitionSection *VerDef;
 };
 
-template <class ELFT> struct In {
-  static VersionDefinitionSection<ELFT> *VerDef;
+extern InStruct In;
+
+template <class ELFT> struct InX {
   static VersionTableSection<ELFT> *VerSym;
   static VersionNeedSection<ELFT> *VerNeed;
 };
 
-template <class ELFT> VersionDefinitionSection<ELFT> *In<ELFT>::VerDef;
-template <class ELFT> VersionTableSection<ELFT> *In<ELFT>::VerSym;
-template <class ELFT> VersionNeedSection<ELFT> *In<ELFT>::VerNeed;
+template <class ELFT> VersionTableSection<ELFT> *InX<ELFT>::VerSym;
+template <class ELFT> VersionNeedSection<ELFT> *InX<ELFT>::VerNeed;
 } // namespace elf
 } // namespace lld
 
diff --git a/ELF/Target.h b/ELF/Target.h
index b897095..1764963 100644
--- a/ELF/Target.h
+++ b/ELF/Target.h
@@ -61,6 +61,11 @@
                           const InputFile *File, uint64_t BranchAddr,
                           const Symbol &S) const;
 
+  // On systems with range extensions we place collections of Thunks at
+  // regular spacings that enable the majority of branches reach the Thunks.
+  // a value of 0 means range extension thunks are not supported.
+  virtual uint32_t getThunkSectionSpacing() const { return 0; }
+
   // The function with a prologue starting at Loc was compiled with
   // -fsplit-stack and it calls a function compiled without. Adjust the prologue
   // to do the right thing. See https://gcc.gnu.org/wiki/SplitStacks.
@@ -88,12 +93,9 @@
   // True if _GLOBAL_OFFSET_TABLE_ is relative to .got.plt, false if .got.
   bool GotBaseSymInGotPlt = true;
 
-  // On systems with range extensions we place collections of Thunks at
-  // regular spacings that enable the majority of branches reach the Thunks.
-  uint32_t ThunkSectionSpacing = 0;
-
   RelType CopyRel;
   RelType GotRel;
+  RelType NoneRel;
   RelType PltRel;
   RelType RelativeRel;
   RelType IRelativeRel;
@@ -170,6 +172,15 @@
   return getErrorPlace(Loc).Loc;
 }
 
+// In the PowerPC64 Elf V2 abi a function can have 2 entry points.  The first is
+// a global entry point (GEP) which typically is used to intiailzie the TOC
+// pointer in general purpose register 2.  The second is a local entry
+// point (LEP) which bypasses the TOC pointer initialization code. The
+// offset between GEP and LEP is encoded in a function's st_other flags.
+// This function will return the offset (in bytes) from the global entry-point
+// to the local entry-point.
+unsigned getPPC64GlobalEntryToLocalEntryOffset(uint8_t StOther);
+
 uint64_t getPPC64TocBase();
 uint64_t getAArch64Page(uint64_t Expr);
 
diff --git a/ELF/Thunks.cpp b/ELF/Thunks.cpp
index 2cd7e51..901de37 100644
--- a/ELF/Thunks.cpp
+++ b/ELF/Thunks.cpp
@@ -159,6 +159,31 @@
   void addSymbols(ThunkSection &IS) override;
 };
 
+// Implementations of Thunks for older Arm architectures that do not support
+// the movt/movw instructions. These thunks require at least Architecture v5
+// as used on processors such as the Arm926ej-s. There are no Thumb entry
+// points as there is no Thumb branch instruction on these architecture that
+// can result in a thunk
+class ARMV5ABSLongThunk final : public ARMThunk {
+public:
+  ARMV5ABSLongThunk(Symbol &Dest) : ARMThunk(Dest) {}
+
+  uint32_t sizeLong() override { return 8; }
+  void writeLong(uint8_t *Buf) override;
+  void addSymbols(ThunkSection &IS) override;
+  bool isCompatibleWith(uint32_t RelocType) const override;
+};
+
+class ARMV5PILongThunk final : public ARMThunk {
+public:
+  ARMV5PILongThunk(Symbol &Dest) : ARMThunk(Dest) {}
+
+  uint32_t sizeLong() override { return 16; }
+  void writeLong(uint8_t *Buf) override;
+  void addSymbols(ThunkSection &IS) override;
+  bool isCompatibleWith(uint32_t RelocType) const override;
+};
+
 // MIPS LA25 thunk
 class MipsThunk final : public Thunk {
 public:
@@ -395,8 +420,8 @@
   const uint8_t Data[] = {
       0xf0, 0xcf, 0x0f, 0xe3, // P:  movw ip,:lower16:S - (P + (L1-P) + 8)
       0x00, 0xc0, 0x40, 0xe3, //     movt ip,:upper16:S - (P + (L1-P) + 8)
-      0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc
-      0x1c, 0xff, 0x2f, 0xe1, //     bx r12
+      0x0f, 0xc0, 0x8c, 0xe0, // L1: add  ip, ip, pc
+      0x1c, 0xff, 0x2f, 0xe1, //     bx   ip
   };
   uint64_t S = getARMThunkDestVA(Destination);
   uint64_t P = getThunkTargetSym()->getVA();
@@ -416,8 +441,8 @@
   const uint8_t Data[] = {
       0x4f, 0xf6, 0xf4, 0x7c, // P:  movw ip,:lower16:S - (P + (L1-P) + 4)
       0xc0, 0xf2, 0x00, 0x0c, //     movt ip,:upper16:S - (P + (L1-P) + 4)
-      0xfc, 0x44,             // L1: add  r12, pc
-      0x60, 0x47,             //     bx   r12
+      0xfc, 0x44,             // L1: add  ip, pc
+      0x60, 0x47,             //     bx   ip
   };
   uint64_t S = getARMThunkDestVA(Destination);
   uint64_t P = getThunkTargetSym()->getVA() & ~0x1;
@@ -433,6 +458,52 @@
   addSymbol("$t", STT_NOTYPE, 0, IS);
 }
 
+void ARMV5ABSLongThunk::writeLong(uint8_t *Buf) {
+  const uint8_t Data[] = {
+      0x04, 0xf0, 0x1f, 0xe5, //     ldr pc, [pc,#-4] ; L1
+      0x00, 0x00, 0x00, 0x00, // L1: .word S
+  };
+  memcpy(Buf, Data, sizeof(Data));
+  Target->relocateOne(Buf + 4, R_ARM_ABS32, getARMThunkDestVA(Destination));
+}
+
+void ARMV5ABSLongThunk::addSymbols(ThunkSection &IS) {
+  addSymbol(Saver.save("__ARMv5ABSLongThunk_" + Destination.getName()),
+            STT_FUNC, 0, IS);
+  addSymbol("$a", STT_NOTYPE, 0, IS);
+  addSymbol("$d", STT_NOTYPE, 4, IS);
+}
+
+bool ARMV5ABSLongThunk::isCompatibleWith(uint32_t RelocType) const {
+  // Thumb branch relocations can't use BLX
+  return RelocType != R_ARM_THM_JUMP19 && RelocType != R_ARM_THM_JUMP24;
+}
+
+void ARMV5PILongThunk::writeLong(uint8_t *Buf) {
+  const uint8_t Data[] = {
+      0x04, 0xc0, 0x9f, 0xe5, // P:  ldr ip, [pc,#4] ; L2
+      0x0c, 0xc0, 0x8f, 0xe0, // L1: add ip, pc, ip
+      0x1c, 0xff, 0x2f, 0xe1, //     bx ip
+      0x00, 0x00, 0x00, 0x00, // L2: .word S - (P + (L1 - P) + 8)
+  };
+  uint64_t S = getARMThunkDestVA(Destination);
+  uint64_t P = getThunkTargetSym()->getVA() & ~0x1;
+  memcpy(Buf, Data, sizeof(Data));
+  Target->relocateOne(Buf + 12, R_ARM_REL32, S - P - 12);
+}
+
+void ARMV5PILongThunk::addSymbols(ThunkSection &IS) {
+  addSymbol(Saver.save("__ARMV5PILongThunk_" + Destination.getName()), STT_FUNC,
+            0, IS);
+  addSymbol("$a", STT_NOTYPE, 0, IS);
+  addSymbol("$d", STT_NOTYPE, 12, IS);
+}
+
+bool ARMV5PILongThunk::isCompatibleWith(uint32_t RelocType) const {
+  // Thumb branch relocations can't use BLX
+  return RelocType != R_ARM_THM_JUMP19 && RelocType != R_ARM_THM_JUMP24;
+}
+
 // Write MIPS LA25 thunk code to call PIC function from the non-PIC one.
 void MipsThunk::writeTo(uint8_t *Buf) {
   uint64_t S = Destination.getVA();
@@ -534,10 +605,49 @@
 }
 
 // Creates a thunk for Thumb-ARM interworking.
+// Arm Architectures v5 and v6 do not support Thumb2 technology. This means
+// - MOVT and MOVW instructions cannot be used
+// - Only Thumb relocation that can generate a Thunk is a BL, this can always
+//   be transformed into a BLX
+static Thunk *addThunkPreArmv7(RelType Reloc, Symbol &S) {
+  switch (Reloc) {
+  case R_ARM_PC24:
+  case R_ARM_PLT32:
+  case R_ARM_JUMP24:
+  case R_ARM_CALL:
+  case R_ARM_THM_CALL:
+    if (Config->Pic)
+      return make<ARMV5PILongThunk>(S);
+    return make<ARMV5ABSLongThunk>(S);
+  }
+  fatal("relocation " + toString(Reloc) + " to " + toString(S) +
+        " not supported for Armv5 or Armv6 targets");
+}
+
+// Creates a thunk for Thumb-ARM interworking or branch range extension.
 static Thunk *addThunkArm(RelType Reloc, Symbol &S) {
-  // ARM relocations need ARM to Thumb interworking Thunks.
-  // Thumb relocations need Thumb to ARM relocations.
-  // Use position independent Thunks if we require position independent code.
+  // Decide which Thunk is needed based on:
+  // Available instruction set
+  // - An Arm Thunk can only be used if Arm state is available.
+  // - A Thumb Thunk can only be used if Thumb state is available.
+  // - Can only use a Thunk if it uses instructions that the Target supports.
+  // Relocation is branch or branch and link
+  // - Branch instructions cannot change state, can only select Thunk that
+  //   starts in the same state as the caller.
+  // - Branch and link relocations can change state, can select Thunks from
+  //   either Arm or Thumb.
+  // Position independent Thunks if we require position independent code.
+
+  if (!Config->ARMHasMovtMovw) {
+    if (!Config->ARMJ1J2BranchEncoding)
+      return addThunkPreArmv7(Reloc, S);
+    else
+      // The Armv6-m architecture (Cortex-M0) does not have Arm instructions or
+      // support the MOVT MOVW instructions so it cannot use any of the Thunks
+      // currently implemented.
+      fatal("thunks not supported for architecture Armv6-m");
+  }
+
   switch (Reloc) {
   case R_ARM_PC24:
   case R_ARM_PLT32:
diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp
index 6e561bb..6f652ac 100644
--- a/ELF/Writer.cpp
+++ b/ELF/Writer.cpp
@@ -77,7 +77,6 @@
   void addRelIpltSymbols();
   void addStartEndSymbols();
   void addStartStopSymbols(OutputSection *Sec);
-  uint64_t getEntryAddr();
 
   std::vector<PhdrEntry *> Phdrs;
 
@@ -114,18 +113,16 @@
   // for instance.
   if (Config->ZKeepTextSectionPrefix)
     for (StringRef V :
-         {".text.hot.", ".text.unlikely.", ".text.startup.", ".text.exit."}) {
+         {".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."}) {
+        ".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab."})
     if (isSectionPrefix(V, S->Name))
       return V.drop_back();
-  }
 
   // CommonSection is identified as "COMMON" in linker scripts.
   // By default, it should go to .bss section.
@@ -159,7 +156,7 @@
     if (!ES || !ES->Live)
       continue;
 
-    InX::EhFrame->addSection<ELFT>(ES);
+    In.EhFrame->addSection<ELFT>(ES);
     S = nullptr;
   }
 
@@ -263,54 +260,52 @@
 
   auto Add = [](InputSectionBase *Sec) { InputSections.push_back(Sec); };
 
-  InX::DynStrTab = make<StringTableSection>(".dynstr", true);
-  InX::Dynamic = make<DynamicSection<ELFT>>();
+  In.DynStrTab = make<StringTableSection>(".dynstr", true);
+  In.Dynamic = make<DynamicSection<ELFT>>();
   if (Config->AndroidPackDynRelocs) {
-    InX::RelaDyn = make<AndroidPackedRelocationSection<ELFT>>(
+    In.RelaDyn = make<AndroidPackedRelocationSection<ELFT>>(
         Config->IsRela ? ".rela.dyn" : ".rel.dyn");
   } else {
-    InX::RelaDyn = make<RelocationSection<ELFT>>(
+    In.RelaDyn = make<RelocationSection<ELFT>>(
         Config->IsRela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc);
   }
-  InX::ShStrTab = make<StringTableSection>(".shstrtab", false);
+  In.ShStrTab = make<StringTableSection>(".shstrtab", false);
 
   Out::ProgramHeaders = make<OutputSection>("", 0, SHF_ALLOC);
   Out::ProgramHeaders->Alignment = Config->Wordsize;
 
   if (needsInterpSection()) {
-    InX::Interp = createInterpSection();
-    Add(InX::Interp);
-  } else {
-    InX::Interp = nullptr;
+    In.Interp = createInterpSection();
+    Add(In.Interp);
   }
 
   if (Config->Strip != StripPolicy::All) {
-    InX::StrTab = make<StringTableSection>(".strtab", false);
-    InX::SymTab = make<SymbolTableSection<ELFT>>(*InX::StrTab);
-    InX::SymTabShndx = make<SymtabShndxSection>();
+    In.StrTab = make<StringTableSection>(".strtab", false);
+    In.SymTab = make<SymbolTableSection<ELFT>>(*In.StrTab);
+    In.SymTabShndx = make<SymtabShndxSection>();
   }
 
   if (Config->BuildId != BuildIdKind::None) {
-    InX::BuildId = make<BuildIdSection>();
-    Add(InX::BuildId);
+    In.BuildId = make<BuildIdSection>();
+    Add(In.BuildId);
   }
 
-  InX::Bss = make<BssSection>(".bss", 0, 1);
-  Add(InX::Bss);
+  In.Bss = make<BssSection>(".bss", 0, 1);
+  Add(In.Bss);
 
   // If there is a SECTIONS command and a .data.rel.ro section name use name
   // .data.rel.ro.bss so that we match in the .data.rel.ro output section.
   // This makes sure our relro is contiguous.
   bool HasDataRelRo = Script->HasSectionsCommand && findSection(".data.rel.ro");
-  InX::BssRelRo =
+  In.BssRelRo =
       make<BssSection>(HasDataRelRo ? ".data.rel.ro.bss" : ".bss.rel.ro", 0, 1);
-  Add(InX::BssRelRo);
+  Add(In.BssRelRo);
 
   // Add MIPS-specific sections.
   if (Config->EMachine == EM_MIPS) {
     if (!Config->Shared && Config->HasDynSymTab) {
-      InX::MipsRldMap = make<MipsRldMapSection>();
-      Add(InX::MipsRldMap);
+      In.MipsRldMap = make<MipsRldMapSection>();
+      Add(In.MipsRldMap);
     }
     if (auto *Sec = MipsAbiFlagsSection<ELFT>::create())
       Add(Sec);
@@ -321,65 +316,65 @@
   }
 
   if (Config->HasDynSymTab) {
-    InX::DynSymTab = make<SymbolTableSection<ELFT>>(*InX::DynStrTab);
-    Add(InX::DynSymTab);
+    In.DynSymTab = make<SymbolTableSection<ELFT>>(*In.DynStrTab);
+    Add(In.DynSymTab);
 
-    In<ELFT>::VerSym = make<VersionTableSection<ELFT>>();
-    Add(In<ELFT>::VerSym);
+    InX<ELFT>::VerSym = make<VersionTableSection<ELFT>>();
+    Add(InX<ELFT>::VerSym);
 
     if (!Config->VersionDefinitions.empty()) {
-      In<ELFT>::VerDef = make<VersionDefinitionSection<ELFT>>();
-      Add(In<ELFT>::VerDef);
+      In.VerDef = make<VersionDefinitionSection>();
+      Add(In.VerDef);
     }
 
-    In<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>();
-    Add(In<ELFT>::VerNeed);
+    InX<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>();
+    Add(InX<ELFT>::VerNeed);
 
     if (Config->GnuHash) {
-      InX::GnuHashTab = make<GnuHashTableSection>();
-      Add(InX::GnuHashTab);
+      In.GnuHashTab = make<GnuHashTableSection>();
+      Add(In.GnuHashTab);
     }
 
     if (Config->SysvHash) {
-      InX::HashTab = make<HashTableSection>();
-      Add(InX::HashTab);
+      In.HashTab = make<HashTableSection>();
+      Add(In.HashTab);
     }
 
-    Add(InX::Dynamic);
-    Add(InX::DynStrTab);
-    Add(InX::RelaDyn);
+    Add(In.Dynamic);
+    Add(In.DynStrTab);
+    Add(In.RelaDyn);
   }
 
   if (Config->RelrPackDynRelocs) {
-    InX::RelrDyn = make<RelrSection<ELFT>>();
-    Add(InX::RelrDyn);
+    In.RelrDyn = make<RelrSection<ELFT>>();
+    Add(In.RelrDyn);
   }
 
   // Add .got. MIPS' .got is so different from the other archs,
   // it has its own class.
   if (Config->EMachine == EM_MIPS) {
-    InX::MipsGot = make<MipsGotSection>();
-    Add(InX::MipsGot);
+    In.MipsGot = make<MipsGotSection>();
+    Add(In.MipsGot);
   } else {
-    InX::Got = make<GotSection>();
-    Add(InX::Got);
+    In.Got = make<GotSection>();
+    Add(In.Got);
   }
 
-  InX::GotPlt = make<GotPltSection>();
-  Add(InX::GotPlt);
-  InX::IgotPlt = make<IgotPltSection>();
-  Add(InX::IgotPlt);
+  In.GotPlt = make<GotPltSection>();
+  Add(In.GotPlt);
+  In.IgotPlt = make<IgotPltSection>();
+  Add(In.IgotPlt);
 
   if (Config->GdbIndex) {
-    InX::GdbIndex = GdbIndexSection::create<ELFT>();
-    Add(InX::GdbIndex);
+    In.GdbIndex = GdbIndexSection::create<ELFT>();
+    Add(In.GdbIndex);
   }
 
   // We always need to add rel[a].plt to output if it has entries.
   // Even for static linking it can contain R_[*]_IRELATIVE relocations.
-  InX::RelaPlt = make<RelocationSection<ELFT>>(
+  In.RelaPlt = make<RelocationSection<ELFT>>(
       Config->IsRela ? ".rela.plt" : ".rel.plt", false /*Sort*/);
-  Add(InX::RelaPlt);
+  Add(In.RelaPlt);
 
   // The RelaIplt immediately follows .rel.plt (.rel.dyn for ARM) to ensure
   // that the IRelative relocations are processed last by the dynamic loader.
@@ -387,34 +382,42 @@
   // packing is enabled because that would cause a section type mismatch.
   // However, because the Android dynamic loader reads .rel.plt after .rel.dyn,
   // we can get the desired behaviour by placing the iplt section in .rel.plt.
-  InX::RelaIplt = make<RelocationSection<ELFT>>(
+  In.RelaIplt = make<RelocationSection<ELFT>>(
       (Config->EMachine == EM_ARM && !Config->AndroidPackDynRelocs)
           ? ".rel.dyn"
-          : InX::RelaPlt->Name,
+          : In.RelaPlt->Name,
       false /*Sort*/);
-  Add(InX::RelaIplt);
+  Add(In.RelaIplt);
 
-  InX::Plt = make<PltSection>(false);
-  Add(InX::Plt);
-  InX::Iplt = make<PltSection>(true);
-  Add(InX::Iplt);
+  In.Plt = make<PltSection>(false);
+  Add(In.Plt);
+  In.Iplt = make<PltSection>(true);
+  Add(In.Iplt);
+
+  // .note.GNU-stack is always added when we are creating a re-linkable
+  // object file. Other linkers are using the presence of this marker
+  // section to control the executable-ness of the stack area, but that
+  // is irrelevant these days. Stack area should always be non-executable
+  // by default. So we emit this section unconditionally.
+  if (Config->Relocatable)
+    Add(make<GnuStackSection>());
 
   if (!Config->Relocatable) {
     if (Config->EhFrameHdr) {
-      InX::EhFrameHdr = make<EhFrameHeader>();
-      Add(InX::EhFrameHdr);
+      In.EhFrameHdr = make<EhFrameHeader>();
+      Add(In.EhFrameHdr);
     }
-    InX::EhFrame = make<EhFrameSection>();
-    Add(InX::EhFrame);
+    In.EhFrame = make<EhFrameSection>();
+    Add(In.EhFrame);
   }
 
-  if (InX::SymTab)
-    Add(InX::SymTab);
-  if (InX::SymTabShndx)
-    Add(InX::SymTabShndx);
-  Add(InX::ShStrTab);
-  if (InX::StrTab)
-    Add(InX::StrTab);
+  if (In.SymTab)
+    Add(In.SymTab);
+  if (In.SymTabShndx)
+    Add(In.SymTabShndx);
+  Add(In.ShStrTab);
+  if (In.StrTab)
+    Add(In.StrTab);
 
   if (Config->EMachine == EM_ARM && !Config->Relocatable)
     // Add a sentinel to terminate .ARM.exidx. It helps an unwinder
@@ -562,7 +565,7 @@
 // Local symbols are not in the linker's symbol table. This function scans
 // each object file's symbol table to copy local symbols to the output.
 template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
-  if (!InX::SymTab)
+  if (!In.SymTab)
     return;
   for (InputFile *File : ObjectFiles) {
     ObjFile<ELFT> *F = cast<ObjFile<ELFT>>(File);
@@ -581,7 +584,7 @@
       SectionBase *Sec = DR->Section;
       if (!shouldKeepInSymtab(Sec, B->getName(), *B))
         continue;
-      InX::SymTab->addSymbol(B);
+      In.SymTab->addSymbol(B);
     }
   }
 }
@@ -617,7 +620,7 @@
     auto *Sym =
         make<Defined>(IS->File, "", STB_LOCAL, /*StOther=*/0, STT_SECTION,
                       /*Value=*/0, /*Size=*/0, IS);
-    InX::SymTab->addSymbol(Sym);
+    In.SymTab->addSymbol(Sym);
   }
 }
 
@@ -662,7 +665,7 @@
   // .got contains pointers to external symbols. They are resolved by
   // the dynamic linker when a module is loaded into memory, and after
   // that they are not expected to change. So, it can be in RELRO.
-  if (InX::Got && Sec == InX::Got->getParent())
+  if (In.Got && Sec == In.Got->getParent())
     return true;
 
   if (Sec->Name.equals(".toc"))
@@ -672,13 +675,13 @@
   // by default resolved lazily, so we usually cannot put it into RELRO.
   // However, if "-z now" is given, the lazy symbol resolution is
   // disabled, which enables us to put it into RELRO.
-  if (Sec == InX::GotPlt->getParent())
+  if (Sec == In.GotPlt->getParent())
     return Config->ZNow;
 
   // .dynamic section contains data for the dynamic linker, and
   // there's no need to write to it at runtime, so it's better to put
   // it into RELRO.
-  if (Sec == InX::Dynamic->getParent())
+  if (Sec == In.Dynamic->getParent())
     return true;
 
   // Sections with some special names are put into RELRO. This is a
@@ -877,11 +880,11 @@
   if (needsInterpSection())
     return;
   StringRef S = Config->IsRela ? "__rela_iplt_start" : "__rel_iplt_start";
-  addOptionalRegular(S, InX::RelaIplt, 0, STV_HIDDEN, STB_WEAK);
+  addOptionalRegular(S, In.RelaIplt, 0, STV_HIDDEN, STB_WEAK);
 
   S = Config->IsRela ? "__rela_iplt_end" : "__rel_iplt_end";
   ElfSym::RelaIpltEnd =
-      addOptionalRegular(S, InX::RelaIplt, 0, STV_HIDDEN, STB_WEAK);
+      addOptionalRegular(S, In.RelaIplt, 0, STV_HIDDEN, STB_WEAK);
 }
 
 template <class ELFT>
@@ -895,7 +898,7 @@
   for (InputSectionBase *IS : InputSections)
     if (IS->Live && isa<InputSection>(IS) && (IS->Flags & SHF_ALLOC))
       Fn(*IS);
-  for (EhInputSection *ES : InX::EhFrame->Sections)
+  for (EhInputSection *ES : In.EhFrame->Sections)
     Fn(*ES);
 }
 
@@ -908,15 +911,15 @@
   if (ElfSym::GlobalOffsetTable) {
     // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention usually
     // to the start of the .got or .got.plt section.
-    InputSection *GotSection = InX::GotPlt;
+    InputSection *GotSection = In.GotPlt;
     if (!Target->GotBaseSymInGotPlt)
-      GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot)
-                                : cast<InputSection>(InX::Got);
+      GotSection = In.MipsGot ? cast<InputSection>(In.MipsGot)
+                              : cast<InputSection>(In.Got);
     ElfSym::GlobalOffsetTable->Section = GotSection;
   }
 
   if (ElfSym::RelaIpltEnd)
-    ElfSym::RelaIpltEnd->Value = InX::RelaIplt->getSize();
+    ElfSym::RelaIpltEnd->Value = In.RelaIplt->getSize();
 
   PhdrEntry *Last = nullptr;
   PhdrEntry *LastRO = nullptr;
@@ -1132,11 +1135,10 @@
     }
     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;
-      });
+  llvm::sort(OrderedSections, [&](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
@@ -1166,7 +1168,7 @@
   // 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()) {
+  if (Target->getThunkSectionSpacing() && !OrderedSections.empty()) {
     uint64_t UnorderedPos = 0;
     for (; InsPt != UnorderedSections.size(); ++InsPt) {
       UnorderedPos += UnorderedSections[InsPt]->getSize();
@@ -1547,9 +1549,9 @@
   // It should be okay as no one seems to care about the type.
   // Even the author of gold doesn't remember why gold behaves that way.
   // https://sourceware.org/ml/binutils/2002-03/msg00360.html
-  if (InX::DynSymTab)
+  if (In.DynSymTab)
     Symtab->addRegular("_DYNAMIC", STV_HIDDEN, STT_NOTYPE, 0 /*Value*/,
-                       /*Size=*/0, STB_WEAK, InX::Dynamic,
+                       /*Size=*/0, STB_WEAK, In.Dynamic,
                        /*File=*/nullptr);
 
   // Define __rel[a]_iplt_{start,end} symbols if needed.
@@ -1567,7 +1569,7 @@
   // This responsible for splitting up .eh_frame section into
   // pieces. The relocation scan uses those pieces, so this has to be
   // earlier.
-  applySynthetic({InX::EhFrame},
+  applySynthetic({In.EhFrame},
                  [](SyntheticSection *SS) { SS->finalizeContents(); });
 
   for (Symbol *S : Symtab->getSymbols())
@@ -1578,24 +1580,24 @@
   if (!Config->Relocatable)
     forEachRelSec(scanRelocations<ELFT>);
 
-  if (InX::Plt && !InX::Plt->empty())
-    InX::Plt->addSymbols();
-  if (InX::Iplt && !InX::Iplt->empty())
-    InX::Iplt->addSymbols();
+  if (In.Plt && !In.Plt->empty())
+    In.Plt->addSymbols();
+  if (In.Iplt && !In.Iplt->empty())
+    In.Iplt->addSymbols();
 
   // Now that we have defined all possible global symbols including linker-
   // synthesized ones. Visit all symbols to give the finishing touches.
   for (Symbol *Sym : Symtab->getSymbols()) {
     if (!includeInSymtab(*Sym))
       continue;
-    if (InX::SymTab)
-      InX::SymTab->addSymbol(Sym);
+    if (In.SymTab)
+      In.SymTab->addSymbol(Sym);
 
-    if (InX::DynSymTab && Sym->includeInDynsym()) {
-      InX::DynSymTab->addSymbol(Sym);
+    if (In.DynSymTab && Sym->includeInDynsym()) {
+      In.DynSymTab->addSymbol(Sym);
       if (auto *File = dyn_cast_or_null<SharedFile<ELFT>>(Sym->File))
         if (File->IsNeeded && !Sym->isUndefined())
-          In<ELFT>::VerNeed->addSymbol(Sym);
+          InX<ELFT>::VerNeed->addSymbol(Sym);
     }
   }
 
@@ -1603,8 +1605,8 @@
   if (errorCount())
     return;
 
-  if (InX::MipsGot)
-    InX::MipsGot->build<ELFT>();
+  if (In.MipsGot)
+    In.MipsGot->build<ELFT>();
 
   removeUnusedSyntheticSections();
 
@@ -1640,7 +1642,7 @@
   unsigned I = 1;
   for (OutputSection *Sec : OutputSections) {
     Sec->SectionIndex = I++;
-    Sec->ShName = InX::ShStrTab->addString(Sec->Name);
+    Sec->ShName = In.ShStrTab->addString(Sec->Name);
   }
 
   // Binary and relocatable output does not have PHDRS.
@@ -1650,6 +1652,12 @@
     Phdrs = Script->hasPhdrsCommands() ? Script->createPhdrs() : createPhdrs();
     addPtArmExid(Phdrs);
     Out::ProgramHeaders->Size = sizeof(Elf_Phdr) * Phdrs.size();
+
+    // Find the TLS segment. This happens before the section layout loop so that
+    // Android relocation packing can look up TLS symbol addresses.
+    for (PhdrEntry *P : Phdrs)
+      if (P->p_type == PT_TLS)
+        Out::TlsPhdr = P;
   }
 
   // Some symbols are defined in term of program headers. Now that we
@@ -1658,15 +1666,31 @@
 
   // Dynamic section must be the last one in this list and dynamic
   // symbol table section (DynSymTab) must be the first one.
-  applySynthetic(
-      {InX::DynSymTab, InX::Bss,         InX::BssRelRo,    InX::GnuHashTab,
-       InX::HashTab,   InX::SymTab,      InX::SymTabShndx, InX::ShStrTab,
-       InX::StrTab,    In<ELFT>::VerDef, InX::DynStrTab,   InX::Got,
-       InX::MipsGot,   InX::IgotPlt,     InX::GotPlt,      InX::RelaDyn,
-       InX::RelrDyn,   InX::RelaIplt,    InX::RelaPlt,     InX::Plt,
-       InX::Iplt,      InX::EhFrameHdr,  In<ELFT>::VerSym, In<ELFT>::VerNeed,
-       InX::Dynamic},
-      [](SyntheticSection *SS) { SS->finalizeContents(); });
+  applySynthetic({In.DynSymTab,
+                  In.Bss,
+                  In.BssRelRo,
+                  In.GnuHashTab,
+                  In.HashTab,
+                  In.SymTabShndx,
+                  In.ShStrTab,
+                  In.StrTab,
+                  In.VerDef,
+                  In.DynStrTab,
+                  In.Got,
+                  In.MipsGot,
+                  In.IgotPlt,
+                  In.GotPlt,
+                  In.RelaDyn,
+                  In.RelrDyn,
+                  In.RelaIplt,
+                  In.RelaPlt,
+                  In.Plt,
+                  In.Iplt,
+                  In.EhFrameHdr,
+                  InX<ELFT>::VerSym,
+                  InX<ELFT>::VerNeed,
+                  In.Dynamic},
+                 [](SyntheticSection *SS) { SS->finalizeContents(); });
 
   if (!Script->HasSectionsCommand && !Config->Relocatable)
     fixSectionAlignments();
@@ -1695,17 +1719,17 @@
           Script->assignAddresses();
         Changed |= A64P.createFixes();
       }
-      if (InX::MipsGot)
-        InX::MipsGot->updateAllocSize();
-      Changed |= InX::RelaDyn->updateAllocSize();
-      if (InX::RelrDyn)
-        Changed |= InX::RelrDyn->updateAllocSize();
+      if (In.MipsGot)
+        In.MipsGot->updateAllocSize();
+      Changed |= In.RelaDyn->updateAllocSize();
+      if (In.RelrDyn)
+        Changed |= In.RelrDyn->updateAllocSize();
     } while (Changed);
   }
 
   // createThunks may have added local symbols to the static symbol table
-  applySynthetic({InX::SymTab},
-                 [](SyntheticSection *SS) { SS->postThunkContents(); });
+  applySynthetic({In.SymTab},
+                 [](SyntheticSection *SS) { SS->finalizeContents(); });
 
   // Fill other section headers. The dynamic table is finalized
   // at the end because some tags like RELSZ depend on result
@@ -1850,9 +1874,9 @@
     Ret.push_back(TlsHdr);
 
   // Add an entry for .dynamic.
-  if (InX::DynSymTab)
-    AddHdr(PT_DYNAMIC, InX::Dynamic->getParent()->getPhdrFlags())
-        ->add(InX::Dynamic->getParent());
+  if (In.DynSymTab)
+    AddHdr(PT_DYNAMIC, In.Dynamic->getParent()->getPhdrFlags())
+        ->add(In.Dynamic->getParent());
 
   // PT_GNU_RELRO includes all sections that should be marked as
   // read-only by dynamic linker after proccessing relocations.
@@ -1880,10 +1904,10 @@
     Ret.push_back(RelRo);
 
   // PT_GNU_EH_FRAME is a special section pointing on .eh_frame_hdr.
-  if (!InX::EhFrame->empty() && InX::EhFrameHdr && InX::EhFrame->getParent() &&
-      InX::EhFrameHdr->getParent())
-    AddHdr(PT_GNU_EH_FRAME, InX::EhFrameHdr->getParent()->getPhdrFlags())
-        ->add(InX::EhFrameHdr->getParent());
+  if (!In.EhFrame->empty() && In.EhFrameHdr && In.EhFrame->getParent() &&
+      In.EhFrameHdr->getParent())
+    AddHdr(PT_GNU_EH_FRAME, In.EhFrameHdr->getParent()->getPhdrFlags())
+        ->add(In.EhFrameHdr->getParent());
 
   // PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes
   // the dynamic linker fill the segment with random data.
@@ -2088,13 +2112,11 @@
       P->p_memsz = alignTo(P->p_memsz, Target->PageSize);
     }
 
-    // The TLS pointer goes after PT_TLS. At least glibc will align it,
-    // so round up the size to make sure the offsets are correct.
-    if (P->p_type == PT_TLS) {
-      Out::TlsPhdr = P;
-      if (P->p_memsz)
-        P->p_memsz = alignTo(P->p_memsz, P->p_align);
-    }
+    // The TLS pointer goes after PT_TLS for variant 2 targets. At least glibc
+    // will align it, so round up the size to make sure the offsets are
+    // correct.
+    if (P->p_type == PT_TLS && P->p_memsz)
+      P->p_memsz = alignTo(P->p_memsz, P->p_align);
   }
 }
 
@@ -2110,10 +2132,9 @@
 // load and virtual adresses).
 static void checkOverlap(StringRef Name, std::vector<SectionOffset> &Sections,
                          bool IsVirtualAddr) {
-  llvm::sort(Sections.begin(), Sections.end(),
-             [=](const SectionOffset &A, const SectionOffset &B) {
-               return A.Offset < B.Offset;
-             });
+  llvm::sort(Sections, [=](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.
@@ -2197,7 +2218,7 @@
 // 4. the number represented by the entry symbol, if it is a number;
 // 5. the address of the first byte of the .text section, if present;
 // 6. the address 0.
-template <class ELFT> uint64_t Writer<ELFT>::getEntryAddr() {
+static uint64_t getEntryAddr() {
   // Case 1, 2 or 3
   if (Symbol *B = Symtab->find(Config->Entry))
     return B->getVA();
@@ -2298,7 +2319,7 @@
   else
     EHdr->e_shnum = Num;
 
-  uint32_t StrTabIndex = InX::ShStrTab->getParent()->SectionIndex;
+  uint32_t StrTabIndex = In.ShStrTab->getParent()->SectionIndex;
   if (StrTabIndex >= SHN_LORESERVE) {
     SHdrs->sh_link = StrTabIndex;
     EHdr->e_shstrndx = SHN_XINDEX;
@@ -2377,8 +2398,8 @@
   uint8_t *Buf = Buffer->getBufferStart();
 
   OutputSection *EhFrameHdr = nullptr;
-  if (InX::EhFrameHdr && !InX::EhFrameHdr->empty())
-    EhFrameHdr = InX::EhFrameHdr->getParent();
+  if (In.EhFrameHdr && !In.EhFrameHdr->empty())
+    EhFrameHdr = In.EhFrameHdr->getParent();
 
   // In -r or -emit-relocs mode, write the relocation sections first as in
   // ELf_Rel targets we might find out that we need to modify the relocated
@@ -2398,13 +2419,13 @@
 }
 
 template <class ELFT> void Writer<ELFT>::writeBuildId() {
-  if (!InX::BuildId || !InX::BuildId->getParent())
+  if (!In.BuildId || !In.BuildId->getParent())
     return;
 
   // Compute a hash of all sections of the output file.
   uint8_t *Start = Buffer->getBufferStart();
   uint8_t *End = Start + FileSize;
-  InX::BuildId->writeBuildId({Start, End});
+  In.BuildId->writeBuildId({Start, End});
 }
 
 template void elf::writeResult<ELF32LE>();
diff --git a/MinGW/Driver.cpp b/MinGW/Driver.cpp
index 27a5550..d682baf 100644
--- a/MinGW/Driver.cpp
+++ b/MinGW/Driver.cpp
@@ -212,9 +212,14 @@
   else
     Add("-alternatename:__image_base__=__ImageBase");
 
+  for (auto *A : Args.filtered(OPT_require_defined))
+    Add("-include:" + StringRef(A->getValue()));
+
   std::vector<StringRef> SearchPaths;
-  for (auto *A : Args.filtered(OPT_L))
+  for (auto *A : Args.filtered(OPT_L)) {
     SearchPaths.push_back(A->getValue());
+    Add("-libpath:" + StringRef(A->getValue()));
+  }
 
   StringRef Prefix = "";
   bool Static = false;
diff --git a/MinGW/Options.td b/MinGW/Options.td
index ad699f7..948faa6 100644
--- a/MinGW/Options.td
+++ b/MinGW/Options.td
@@ -40,6 +40,9 @@
 def whole_archive: F<"whole-archive">,
     HelpText<"Include all object files for following archives">;
 def verbose: F<"verbose">, HelpText<"Verbose mode">;
+def require_defined: S<"require-defined">,
+    HelpText<"Force symbol to be added to symbol table as an undefined one">;
+def require_defined_eq: J<"require-defined=">, Alias<require_defined>;
 
 // LLD specific options
 def _HASH_HASH_HASH : Flag<["-"], "###">,
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index a1ed6b2..aeed10a 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -1,5 +1,5 @@
 =======================
-LLD 8.0.0 Release Notes
+lld 8.0.0 Release Notes
 =======================
 
 .. contents::
@@ -8,7 +8,7 @@
 .. warning::
    These are in-progress notes for the upcoming LLVM 8.0.0 release.
    Release notes for previous releases can be found on
-   `the Download Page <http://releases.llvm.org/download.html>`_.
+   `the Download Page <https://releases.llvm.org/download.html>`_.
 
 Introduction
 ============
@@ -16,7 +16,7 @@
 This document contains the release notes for the lld linker, release 8.0.0.
 Here we describe the status of lld, including major improvements
 from the previous release. All lld releases may be downloaded
-from the `LLVM releases web site <http://llvm.org/releases/>`_.
+from the `LLVM releases web site <https://llvm.org/releases/>`_.
 
 Non-comprehensive list of changes in this release
 =================================================
@@ -24,12 +24,42 @@
 ELF Improvements
 ----------------
 
-* Item 1.
+* lld now supports RISC-V. (`r339364
+  <https://reviews.llvm.org/rL339364>`_)
+
+* Default image base address has changed from 65536 to 2 MiB for i386
+  and 4 MiB for AArch64 to make lld-generated executables work better
+  with automatic superpage promotion. FreeBSD can promote contiguous
+  non-superpages to a superpage if they are aligned to the superpage
+  size. (`r342746 <https://reviews.llvm.org/rL342746>`_)
+
+* lld/Hexagon can now link Linux kernel and musl libc for Qualcomm
+  Hexagon ISA.
+
+* The following flags have been added: ``-z interpose``, ``-z global``
 
 COFF Improvements
 -----------------
 
-* Item 1.
+* PDB GUID is set to hash of PDB contents instead to a random byte
+  sequence for build reproducibility.
+
+* The following flags have been added: ``/force:multiple``
+
+* lld now can link against import libraries produced by GNU tools.
+
+* lld can create thunks for ARM, to allow linking images over 16 MB.
+
+MinGW Improvements
+------------------
+
+* lld can now automatically import data variables from DLLs without the
+  use of the dllimport attribute.
+
+* lld can now use existing normal MinGW sysroots with import libraries and
+  CRT startup object files for GNU binutils. lld can handle most object
+  files produced by GCC, and thus works as a drop-in replacement for
+  ld.bfd in such environments.
 
 MachO Improvements
 ------------------
diff --git a/docs/ld.lld.1 b/docs/ld.lld.1
index 0fdfe0a..0a520f2 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 July 30, 2018
+.Dd September 26, 2018
 .Dt LD.LLD 1
 .Os
 .Sh NAME
@@ -13,6 +13,7 @@
 .Nm ld.lld
 .Op Ar options
 .Ar objfile ...
+
 .Sh DESCRIPTION
 A linker takes one or more object, archive, and library files, and combines
 them into an output file (an executable, a shared library, or another object
@@ -25,7 +26,21 @@
 It accepts most of the same command line arguments and linker scripts
 as GNU linkers.
 .Pp
-These options are available:
+.Nm
+currently supports i386, x86-64, ARM, AArch64, PowerPC32, PowerPC64,
+MIPS32, MIPS64, RISC-V, AMDGPU, Hexagon and SPARC V9 targets.
+.Nm
+acts as a Microsoft link.exe-compatible linker if invoked as
+.Nm lld-link
+and as macOS's ld if invoked as
+.Nm ld.ld64.
+All these targets are always supported however
+.Nm
+was built, so you can always use
+.Nm
+as a native linker as well as a cross linker.
+
+.Sh OPTIONS
 .Bl -tag -width indent
 .It Fl -allow-multiple-definition
 Do not error if a symbol is defined multiple times.
@@ -144,6 +159,9 @@
 A value of zero indicates that there is no limit.
 .It Fl -error-unresolved-symbols
 Report unresolved symbols as errors.
+.It Fl -execute-only
+Mark executable sections unreadable. This option is currently only
+supported on AArch64.
 .It Fl -exclude-libs Ns = Ns Ar value
 Exclude static libraries from automatic export.
 .It Fl -export-dynamic , Fl E
@@ -297,6 +315,8 @@
 Create a position independent executable.
 .It Fl -print-gc-sections
 List removed unused sections.
+.It Fl -print-icf-sections
+List identical folded sections.
 .It Fl -print-map
 Print a link map to the standard output.
 .It Fl -push-state
@@ -304,7 +324,7 @@
 .Fl -as-needed ,
 .Fl -static ,
 and
-.Fl -while-archive.
+.Fl -whole-archive.
 .It Fl -pop-state
 Undo the effect of
 .Fl -push-state.
@@ -426,6 +446,17 @@
 traditional Unix-like linkers.
 .It Fl -warn-common
 Warn about duplicate common symbols.
+.It Fl -warn-ifunc-textrel
+Warn about using ifunc symbols in conjunction with text relocations.
+Older versions of glibc library (2.28 and earlier) has a bug that causes
+the segment that includes ifunc symbols to be marked as not executable when
+they are relocated. As a result, although the program compiles and links
+successfully, it gives segmentation fault when the instruction pointer reaches
+an ifunc symbol. Use -warn-ifunc-textrel to let lld give a warning, if the
+code may include ifunc symbols, may do text relocations and be linked with
+an older glibc version. Otherwise, there is no need to use it, as the default
+value does not give a warning. This flag has been introduced in late 2018,
+has no counter part in ld and gold linkers, and may be removed in the future.
 .It Fl -warn-unresolved-symbols
 Report unresolved symbols as warnings.
 .It Fl -whole-archive
@@ -440,10 +471,22 @@
 Stack permissions are recorded in the
 .Dv PT_GNU_STACK
 segment.
+.It Cm global
+Sets the
+.Dv DF_1_GLOBAL flag in the
+.Dv DYNAMIC
+section.
+Different loaders can decide how to handle this flag on their own.
 .It Cm initfirst
 Sets the
 .Dv DF_1_INITFIRST
 flag to indicate the module should be initialized first.
+.It Cm interpose
+Set the
+.Dv DF_1_INTERPOSE
+flag to indicate to the runtime linker that the object is an interposer.
+During symbol resolution interposers are searched after the application
+but before other dependencies.
 .It Cm muldefs
 Do not error if a symbol is defined multiple times.
 The first definition will be used.
diff --git a/include/lld/Common/Args.h b/include/lld/Common/Args.h
index c49a6a7..769d484 100644
--- a/include/lld/Common/Args.h
+++ b/include/lld/Common/Args.h
@@ -29,6 +29,9 @@
                          uint64_t Default);
 
 std::vector<StringRef> getLines(MemoryBufferRef MB);
+
+StringRef getFilenameWithoutExe(StringRef Path);
+
 } // namespace args
 } // namespace lld
 
diff --git a/include/lld/Common/ErrorHandler.h b/include/lld/Common/ErrorHandler.h
index f17f7cc..c169f7b 100644
--- a/include/lld/Common/ErrorHandler.h
+++ b/include/lld/Common/ErrorHandler.h
@@ -153,7 +153,7 @@
 inline std::string toString(const Twine &S) { return S.str(); }
 
 // To evaluate the second argument lazily, we use C macro.
-#define CHECK(E, S) check2(E, [&] { return toString(S); })
+#define CHECK(E, S) check2((E), [&] { return toString(S); })
 
 } // namespace lld
 
diff --git a/lib/Driver/DarwinLdDriver.cpp b/lib/Driver/DarwinLdDriver.cpp
index ad22845..7521d6e 100644
--- a/lib/Driver/DarwinLdDriver.cpp
+++ b/lib/Driver/DarwinLdDriver.cpp
@@ -44,6 +44,7 @@
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ErrorOr.h"
 #include "llvm/Support/Format.h"
+#include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
@@ -382,10 +383,13 @@
     if (arch == MachOLinkingContext::arch_unknown &&
         !parsedArgs.getLastArg(OPT_test_file_usage)) {
       // If no -arch and no options at all, print usage message.
-      if (parsedArgs.size() == 0)
-        table.PrintHelp(llvm::outs(), args[0], "LLVM Linker", false);
-      else
+      if (parsedArgs.size() == 0) {
+        std::string Usage =
+            llvm::formatv("{0} [options] file...", args[0]).str();
+        table.PrintHelp(llvm::outs(), Usage.c_str(), "LLVM Linker", false);
+      } else {
         error("-arch not specified and could not be inferred");
+      }
       return false;
     }
   }
@@ -1143,7 +1147,7 @@
 /// This is where the link is actually performed.
 bool link(llvm::ArrayRef<const char *> args, bool CanExitEarly,
           raw_ostream &Error) {
-  errorHandler().LogName = llvm::sys::path::filename(args[0]);
+  errorHandler().LogName = args::getFilenameWithoutExe(args[0]);
   errorHandler().ErrorLimitExceededMsg =
       "too many errors emitted, stopping now (use "
       "'-error-limit 0' to see all errors)";
diff --git a/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h b/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h
index 407bd9b..ee9e174 100644
--- a/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h
+++ b/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h
@@ -186,11 +186,10 @@
 }
 
 inline StringRef getString16(const char s[16]) {
-  StringRef x = s;
-  if ( x.size() > 16 )
-    return x.substr(0, 16);
-  else
-    return x;
+  // The StringRef(const char *) constructor passes the const char * to
+  // strlen(), so we can't use this constructor here, because if there is no
+  // null terminator in s, then strlen() will read past the end of the array.
+  return StringRef(s, strnlen(s, 16));
 }
 
 inline void setString16(StringRef str, char s[16]) {
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 12fb7c3..1b90833 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -53,6 +53,9 @@
   DEPENDS ${LLD_TEST_DEPS}
   )
 
+add_custom_target(lld-test-depends DEPENDS ${LLD_TEST_DEPS})
+set_target_properties(lld-test-depends PROPERTIES FOLDER "lld tests")
+
 add_lit_testsuites(LLD ${CMAKE_CURRENT_SOURCE_DIR}
   PARAMS lld_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
        lld_unit_site_config=${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
diff --git a/test/COFF/Inputs/bad-block-size.pdb b/test/COFF/Inputs/bad-block-size.pdb
new file mode 100644
index 0000000..fadd883
--- /dev/null
+++ b/test/COFF/Inputs/bad-block-size.pdb
@@ -0,0 +1,2 @@
+Microsoft C/C++ MSF 7.00

+DS
\ No newline at end of file
diff --git a/test/COFF/Inputs/comdat-jumptable2.s b/test/COFF/Inputs/comdat-jumptable2.s
new file mode 100644
index 0000000..8990d4c
--- /dev/null
+++ b/test/COFF/Inputs/comdat-jumptable2.s
@@ -0,0 +1,35 @@
+        .section .text@comdatfunc, "x"
+        .linkonce discard
+        .globl comdatfunc
+comdatfunc:
+        leaq .Ljumptable(%rip), %rax
+        movslq (%rax, %rcx, 4), %rcx
+        addq %rcx, %rax
+        jmp *%rax
+
+        .section .rdata, "dr"
+        .long 0xcccccccc
+.Ljumptable:
+        .long .Ltail1-.Ljumptable
+        .long .Ltail2-.Ljumptable
+        .long .Ltail3-.Ljumptable
+        .long 0xdddddddd
+
+        .section .text@comdatfunc, "x"
+# If assembled with binutils, the following line can be kept in:
+#       .linkonce discard
+.Ltail1:
+        movl $1, %eax
+        ret
+.Ltail2:
+        movl $2, %eax
+        ret
+.Ltail3:
+        movl $3, %eax
+        ret
+
+        .text
+        .globl otherfunc
+otherfunc:
+        call comdatfunc
+        ret
diff --git a/test/COFF/Inputs/crt-dyn-initializer-order_1.yaml b/test/COFF/Inputs/crt-dyn-initializer-order_1.yaml
new file mode 100644
index 0000000..302f6f2
--- /dev/null
+++ b/test/COFF/Inputs/crt-dyn-initializer-order_1.yaml
@@ -0,0 +1,15 @@
+--- !COFF

+header:

+  Machine:         IMAGE_FILE_MACHINE_AMD64

+  Characteristics: [  ]

+sections:

+  - Name:            '.CRT$XCU'

+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]

+    Alignment:       1

+    SectionData:     55

+  - Name:            '.CRT$XCU'

+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]

+    Alignment:       1

+    SectionData:     70

+symbols:

+...

diff --git a/test/COFF/Inputs/crt-dyn-initializer-order_2.yaml b/test/COFF/Inputs/crt-dyn-initializer-order_2.yaml
new file mode 100644
index 0000000..a2d0e5e
--- /dev/null
+++ b/test/COFF/Inputs/crt-dyn-initializer-order_2.yaml
@@ -0,0 +1,19 @@
+--- !COFF

+header:

+  Machine:         IMAGE_FILE_MACHINE_AMD64

+  Characteristics: [  ]

+sections:

+  - Name:            '.CRT$XCU'

+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]

+    Alignment:       1

+    SectionData:     10

+  - Name:            '.CRT$XCU'

+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]

+    Alignment:       1

+    SectionData:     11

+  - Name:            '.CRT$XCU'

+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]

+    Alignment:       1

+    SectionData:     12

+symbols:

+...

diff --git a/test/COFF/Inputs/empty.yaml b/test/COFF/Inputs/empty.yaml
new file mode 100644
index 0000000..6396f8a
--- /dev/null
+++ b/test/COFF/Inputs/empty.yaml
@@ -0,0 +1,67 @@
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_I386
+  Characteristics: [  ]
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     31C0C3
+  - Name:            .data
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       4
+    SectionData:     ''
+  - Name:            .bss
+    Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       4
+    SectionData:     ''
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          3
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        3963538403
+      Number:          1
+  - Name:            .data
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          0
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          2
+  - Name:            .bss
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          0
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          3
+  - Name:            '@feat.00'
+    Value:           1
+    SectionNumber:   -1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            _main
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/test/COFF/Inputs/far-arm-thumb-abs.s b/test/COFF/Inputs/far-arm-thumb-abs.s
deleted file mode 100644
index 9f1b59a..0000000
--- a/test/COFF/Inputs/far-arm-thumb-abs.s
+++ /dev/null
@@ -1,2 +0,0 @@
-.global too_far1
-too_far1 = 0x1401004
diff --git a/test/COFF/Inputs/far-arm-thumb-abs20.s b/test/COFF/Inputs/far-arm-thumb-abs20.s
deleted file mode 100644
index 8483e32..0000000
--- a/test/COFF/Inputs/far-arm-thumb-abs20.s
+++ /dev/null
@@ -1,2 +0,0 @@
-.global too_far20
-too_far20 = 0x501004
diff --git a/test/COFF/Inputs/gnu-implib-data.s b/test/COFF/Inputs/gnu-implib-data.s
new file mode 100644
index 0000000..d9af775
--- /dev/null
+++ b/test/COFF/Inputs/gnu-implib-data.s
@@ -0,0 +1,23 @@
+        .global         __imp_data
+
+        # The data that is emitted into .idata$7 here is isn't needed for
+        # the import data structures, but we need to emit something which
+        # produces a relocation against _head_test_lib, to pull in the
+        # header and trailer objects.
+
+        .section        .idata$7
+        .rva            _head_test_lib
+
+        .section        .idata$5
+__imp_data:
+        .rva            .Lhint_name
+        .long           0
+
+        .section        .idata$4
+        .rva            .Lhint_name
+        .long           0
+
+        .section        .idata$6
+.Lhint_name:
+        .short          0
+        .asciz          "data"
diff --git a/test/COFF/Inputs/gnu-implib-func.s b/test/COFF/Inputs/gnu-implib-func.s
new file mode 100644
index 0000000..5f37ee1
--- /dev/null
+++ b/test/COFF/Inputs/gnu-implib-func.s
@@ -0,0 +1,27 @@
+        .text
+        .global         func
+        .global         __imp_func
+func:
+        jmp             *__imp_func
+
+        # The data that is emitted into .idata$7 here is isn't needed for
+        # the import data structures, but we need to emit something which
+        # produces a relocation against _head_test_lib, to pull in the
+        # header and trailer objects.
+
+        .section        .idata$7
+        .rva            _head_test_lib
+
+        .section        .idata$5
+__imp_func:
+        .rva            .Lhint_name
+        .long           0
+
+        .section        .idata$4
+        .rva            .Lhint_name
+        .long           0
+
+        .section        .idata$6
+.Lhint_name:
+        .short          0
+        .asciz          "func"
diff --git a/test/COFF/Inputs/gnu-implib-head.s b/test/COFF/Inputs/gnu-implib-head.s
new file mode 100644
index 0000000..b32acf0
--- /dev/null
+++ b/test/COFF/Inputs/gnu-implib-head.s
@@ -0,0 +1,13 @@
+        .section        .idata$2
+        .global         _head_test_lib
+_head_test_lib:
+        .rva            hname
+        .long           0
+        .long           0
+        .rva            __test_lib_iname
+        .rva            fthunk
+
+        .section        .idata$5
+fthunk:
+        .section        .idata$4
+hname:
diff --git a/test/COFF/Inputs/gnu-implib-tail.s b/test/COFF/Inputs/gnu-implib-tail.s
new file mode 100644
index 0000000..784d51f
--- /dev/null
+++ b/test/COFF/Inputs/gnu-implib-tail.s
@@ -0,0 +1,11 @@
+        .section        .idata$4
+        .long           0
+        .long           0
+        .section        .idata$5
+        .long           0
+        .long           0
+
+        .section        .idata$7
+        .global         __test_lib_iname
+__test_lib_iname:
+       .asciz           "foo.dll"
diff --git a/test/COFF/Inputs/gnu-weak.o b/test/COFF/Inputs/gnu-weak.o
new file mode 100644
index 0000000..997f004
--- /dev/null
+++ b/test/COFF/Inputs/gnu-weak.o
Binary files differ
diff --git a/test/COFF/Inputs/gnu-weak2.o b/test/COFF/Inputs/gnu-weak2.o
new file mode 100644
index 0000000..15b5d4d
--- /dev/null
+++ b/test/COFF/Inputs/gnu-weak2.o
Binary files differ
diff --git a/test/COFF/Inputs/icf-safe.s b/test/COFF/Inputs/icf-safe.s
new file mode 100644
index 0000000..3a2b3b1
--- /dev/null
+++ b/test/COFF/Inputs/icf-safe.s
@@ -0,0 +1,9 @@
+.section .rdata,"dr",one_only,non_addrsig1
+.globl non_addrsig1
+non_addrsig1:
+.byte 3
+
+.section .rdata,"dr",one_only,non_addrsig2
+.globl non_addrsig2
+non_addrsig2:
+.byte 3
diff --git a/test/COFF/Inputs/inline-weak.o b/test/COFF/Inputs/inline-weak.o
new file mode 100644
index 0000000..5987e60
--- /dev/null
+++ b/test/COFF/Inputs/inline-weak.o
Binary files differ
diff --git a/test/COFF/Inputs/inline-weak2.o b/test/COFF/Inputs/inline-weak2.o
new file mode 100644
index 0000000..b413f5b
--- /dev/null
+++ b/test/COFF/Inputs/inline-weak2.o
Binary files differ
diff --git a/test/COFF/Inputs/pdb-file-statics-a.yaml b/test/COFF/Inputs/pdb-file-statics-a.yaml
index 957eb5a..1a0dbdb 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:        CVRegRSP
+              Register:        RSP
               VarName:         __formal
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
@@ -1528,13 +1528,13 @@
             RegRelativeSym:
               Offset:          48
               Type:            116
-              Register:        CVRegRSP
+              Register:        RSP
               VarName:         argc
           - Kind:            S_REGREL32
             RegRelativeSym:
               Offset:          56
               Type:            4098
-              Register:        CVRegRSP
+              Register:        RSP
               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 8b7a311..f74bab7 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:        CVRegRSP
+              Register:        RSP
               VarName:         __formal
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
diff --git a/test/COFF/Inputs/pdb-scopes-a.yaml b/test/COFF/Inputs/pdb-scopes-a.yaml
index 0fc4172..e422a62 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:        CVRegRSP
+              Register:        RSP
               VarName:         x
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
@@ -93,7 +93,7 @@
             RegRelativeSym:
               Offset:          64
               Type:            116
-              Register:        CVRegRSP
+              Register:        RSP
               VarName:         argc
           - Kind:            S_BLOCK32
             BlockSym:
@@ -104,7 +104,7 @@
             RegRelativeSym:
               Offset:          32
               Type:            116
-              Register:        CVRegRSP
+              Register:        RSP
               VarName:         x
           - Kind:            S_END
             ScopeEndSym:
@@ -117,7 +117,7 @@
             RegRelativeSym:
               Offset:          36
               Type:            116
-              Register:        CVRegRSP
+              Register:        RSP
               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 c0ee98b..b1c6021 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:        CVRegRSP
+              Register:        RSP
               VarName:         x
           - Kind:            S_BLOCK32
             BlockSym:
@@ -64,7 +64,7 @@
             RegRelativeSym:
               Offset:          32
               Type:            116
-              Register:        CVRegRSP
+              Register:        RSP
               VarName:         y
           - Kind:            S_END
             ScopeEndSym:
@@ -77,7 +77,7 @@
             RegRelativeSym:
               Offset:          36
               Type:            116
-              Register:        CVRegRSP
+              Register:        RSP
               VarName:         w
           - Kind:            S_END
             ScopeEndSym:
diff --git a/test/COFF/Inputs/pdb-type-server-missing-2.yaml b/test/COFF/Inputs/pdb-type-server-missing-2.yaml
new file mode 100644
index 0000000..e71bcec
--- /dev/null
+++ b/test/COFF/Inputs/pdb-type-server-missing-2.yaml
@@ -0,0 +1,32 @@
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [  ]
+sections:
+  - Name:            '.debug$T'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    Types:
+      - Kind:            LF_TYPESERVER2
+        TypeServer2:
+          Guid:            '{01DF191B-22BF-6B42-96CE-5258B8329FE5}'
+          Age:             18
+          Name:            'C:\src\llvm-project\build\definitely_not_found_for_sure.pdb'
+  - Name:            '.text$mn'
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       16
+    SectionData:     33C0C3
+symbols:
+  - Name:            '.debug$T'
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          564
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+...
diff --git a/test/COFF/Inputs/pdb-type-server-simple-a.yaml b/test/COFF/Inputs/pdb-type-server-simple-a.yaml
index 8425c4f..78c6816 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:        CVRegRSP
+              Register:        RSP
               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 3b511cb..56e97d5 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:        CVRegRSP
+              Register:        RSP
               VarName:         p
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
diff --git a/test/COFF/Inputs/pdb-type-server-valid-signature.yaml b/test/COFF/Inputs/pdb-type-server-valid-signature.yaml
new file mode 100644
index 0000000..dd95a3d
--- /dev/null
+++ b/test/COFF/Inputs/pdb-type-server-valid-signature.yaml
@@ -0,0 +1,121 @@
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [  ]
+sections:
+  - Name:            '.debug$S'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    Subsections:
+      - !Symbols
+        Records:
+          - Kind:            S_GPROC32_ID
+            ProcSym:
+              CodeSize:        3
+              DbgStart:        0
+              DbgEnd:          2
+              FunctionType:    4199
+              Flags:           [  ]
+              DisplayName:     main
+          - Kind:            S_FRAMEPROC
+            FrameProcSym:
+              TotalFrameBytes: 0
+              PaddingFrameBytes: 0
+              OffsetToPadding: 0
+              BytesOfCalleeSavedRegisters: 0
+              OffsetOfExceptionHandler: 0
+              SectionIdOfExceptionHandler: 0
+              Flags:           [ AsynchronousExceptionHandling, OptimizedForSpeed ]
+          - Kind:            S_PROC_ID_END
+            ScopeEndSym:
+      - !Lines
+        CodeSize:        3
+        Flags:           [  ]
+        RelocOffset:     0
+        RelocSegment:    0
+        Blocks:
+          - FileName:        'c:\src\llvm-project\build\t.c'
+            Lines:
+              - Offset:          0
+                LineStart:       1
+                IsStatement:     true
+                EndDelta:        0
+            Columns:
+      - !FileChecksums
+        Checksums:
+          - FileName:        'c:\src\llvm-project\build\t.c'
+            Kind:            MD5
+            Checksum:        270A878DCC1B845655B162F56C4F5020
+      - !StringTable
+        Strings:
+          - 'c:\src\llvm-project\build\t.c'
+    Relocations:
+      - VirtualAddress:  44
+        SymbolName:      main
+        Type:            IMAGE_REL_AMD64_SECREL
+      - VirtualAddress:  48
+        SymbolName:      main
+        Type:            IMAGE_REL_AMD64_SECTION
+      - VirtualAddress:  100
+        SymbolName:      main
+        Type:            IMAGE_REL_AMD64_SECREL
+      - VirtualAddress:  104
+        SymbolName:      main
+        Type:            IMAGE_REL_AMD64_SECTION
+  - Name:            '.debug$T'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    Types:
+      - Kind:            LF_TYPESERVER2
+        TypeServer2:
+          Guid:            '{8DABD2A0-28FF-CB43-9BAF-175B77B76414}'
+          Age:             18
+          Name:            'pdb-diff-cl.pdb'
+  - Name:            '.text$mn'
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       16
+    SectionData:     33C0C3
+symbols:
+  - Name:            '.debug$S'
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          328
+      NumberOfRelocations: 4
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            '.debug$T'
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          564
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            '.text$mn'
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          3
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        4021952397
+      Number:          0
+  - Name:            main
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/test/COFF/arm-thumb-branch-error.s b/test/COFF/arm-thumb-branch-error.s
deleted file mode 100644
index 00b835c..0000000
--- a/test/COFF/arm-thumb-branch-error.s
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-windows-gnu %s -o %t
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-windows-gnu %S/Inputs/far-arm-thumb-abs.s -o %tfar
-// RUN: not lld-link -entry:_start -subsystem:console %t %tfar -out:%t2 2>&1 | FileCheck %s
-// REQUIRES: arm
- .syntax unified
- .globl _start
-_start:
- bl  too_far1
-
-// CHECK: relocation out of range
diff --git a/test/COFF/arm-thumb-branch20-error.s b/test/COFF/arm-thumb-branch20-error.s
index ec7d23b..fbbc0d4 100644
--- a/test/COFF/arm-thumb-branch20-error.s
+++ b/test/COFF/arm-thumb-branch20-error.s
@@ -1,10 +1,16 @@
 // REQUIRES: arm
 // RUN: llvm-mc -filetype=obj -triple=thumbv7a-windows-gnu %s -o %t.obj
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-windows-gnu %S/Inputs/far-arm-thumb-abs20.s -o %t.far.obj
-// RUN: not lld-link -entry:_start -subsystem:console %t.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s
+// RUN: not lld-link -entry:_start -subsystem:console %t.obj -out:%t.exe 2>&1 | FileCheck %s
  .syntax unified
  .globl _start
 _start:
  bne too_far20
+ .space 0x100000
+ .section .text$a, "xr"
+too_far20:
+ bx lr
 
-// CHECK: relocation out of range
+// When trying to add a thunk at the end of the section, the thunk itself
+// will be too far away, so this won't converge.
+
+// CHECK: adding thunks hasn't converged
diff --git a/test/COFF/arm-thumb-thunks-multipass.s b/test/COFF/arm-thumb-thunks-multipass.s
new file mode 100644
index 0000000..5e64e8d
--- /dev/null
+++ b/test/COFF/arm-thumb-thunks-multipass.s
@@ -0,0 +1,70 @@
+// REQUIRES: arm
+// RUN: llvm-mc -filetype=obj -triple=thumbv7-windows %s -o %t.obj
+// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s
+// RUN: llvm-objdump -d %t.exe -start-address=0x403000 -stop-address=0x403008 | FileCheck -check-prefix=FUNC01 %s
+// RUN: llvm-objdump -d %t.exe -start-address=0x404ffa -stop-address=0x405012 | FileCheck -check-prefix=FUNC01-THUNKS %s
+
+// VERBOSE: Added {{.*}} thunks with margin 204800 in 2 passes
+
+    .syntax unified
+    .globl main
+    .text
+main:
+    b  func01
+    bx lr
+
+.irp i, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, 17, 18
+    .section .text$\i\()a, "xr"
+    .balign 8192
+func\i:
+    bne far_func\i
+    bne func_within_margin\i
+    // Originally, the first section is less than 8192 bytes large, and the
+    // second one follows almost directly. After adding one thunk after
+    // the first section, the second one will move forward by 8192 bytes
+    // due to the alignment.
+    .space 8192 - 8 - 4
+
+    .section .text$\i\()b, "xr"
+    .balign 8192
+align\i:
+    nop
+.endr
+
+    .section .text$999, "xr"
+tail:
+    .space 0x100000 - 100*1024 - 18*8192*2
+    // Initially, these symbols are within range from all the sections above,
+    // even when taking the initial margin into account. After adding thunks
+    // to all the sections above, some of these are also out of range, forcing
+    // running a second pass.
+.irp i, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, 17, 18
+func_within_margin\i:
+    nop
+.endr
+    .space 0x100000
+
+    // These are always out of range.
+.irp i, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, 17, 18
+far_func\i:
+    nop
+.endr
+    bx lr
+
+// FUNC01: 403000:       41 f0 fc 87     bne.w   #8184 <.text+0x3ffc>
+// FUNC01: 403004:       41 f0 ff 87     bne.w   #8190 <.text+0x4006>
+
+// Check that we only have two thunks here, even if we created the first
+// thunk twice (once in the first pass, then thrown away and recreated
+// in the second pass).
+
+// FUNC01-THUNKS: 404ffa:       00 00           movs    r0,  r0
+// The instruction above is padding from the .space
+// FUNC01-THUNKS: 404ffc:       47 f2 1e 0c     movw    r12, #28702
+// FUNC01-THUNKS: 405000:       c0 f2 20 0c     movt    r12, #32
+// FUNC01-THUNKS: 405004:       e7 44           add     pc,  r12
+// FUNC01-THUNKS: 405006:       46 f6 f0 7c     movw    r12, #28656
+// FUNC01-THUNKS: 40500a:       c0 f2 10 0c     movt    r12, #16
+// FUNC01-THUNKS: 40500e:       e7 44           add     pc, r12
+// The instruction below is padding from the .balign
+// FUNC01-THUNKS: 405010:       cc cc           ldm     r4!, {r2, r3, r6, r7}
diff --git a/test/COFF/arm-thumb-thunks.s b/test/COFF/arm-thumb-thunks.s
new file mode 100644
index 0000000..33c3740
--- /dev/null
+++ b/test/COFF/arm-thumb-thunks.s
@@ -0,0 +1,75 @@
+// REQUIRES: arm
+// RUN: llvm-mc -filetype=obj -triple=thumbv7-windows %s -o %t.obj
+// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s
+// RUN: llvm-objdump -d %t.exe -start-address=0x401000 -stop-address=0x401022 | FileCheck -check-prefix=MAIN %s
+// RUN: llvm-objdump -d %t.exe -start-address=0x501022 -stop-address=0x501032 | FileCheck -check-prefix=FUNC1 %s
+// RUN: llvm-objdump -d %t.exe -start-address=0x601032 | FileCheck -check-prefix=FUNC2 %s
+
+// VERBOSE: Added 3 thunks with margin {{.*}} in 1 passes
+
+    .syntax unified
+    .globl main
+    .globl func1
+    .text
+main:
+    bne func1
+    bne func2
+    // This should reuse the same thunk as func1 above
+    bne func1_alias
+    bx lr
+    .section .text$a, "xr"
+    .space 0x100000
+    .section .text$b, "xr"
+func1:
+func1_alias:
+    // This shouldn't reuse the func2 thunk from above, since it is out
+    // of range.
+    bne func2
+    bx lr
+    .section .text$c, "xr"
+    .space 0x100000
+    .section .text$d, "xr"
+func2:
+// Test using string tail merging. This is irrelevant to the thunking itself,
+// but running multiple passes of assignAddresses() calls finalizeAddresses()
+// multiple times; check that MergeChunk handles this correctly.
+    movw r0, :lower16:"??_C@string1"
+    movt r0, :upper16:"??_C@string1"
+    movw r1, :lower16:"??_C@string2"
+    movt r1, :upper16:"??_C@string2"
+    bx lr
+
+    .section .rdata,"dr",discard,"??_C@string1"
+    .globl "??_C@string1"
+"??_C@string1":
+    .asciz "foobar"
+    .section .rdata,"dr",discard,"??_C@string2"
+    .globl "??_C@string2"
+"??_C@string2":
+    .asciz "bar"
+
+// MAIN:    401000:       40 f0 05 80     bne.w   #10 <.text+0xe>
+// MAIN:    401004:       40 f0 08 80     bne.w   #16 <.text+0x18>
+// MAIN:    401008:       40 f0 01 80     bne.w   #2 <.text+0xe>
+// MAIN:    40100c:       70 47           bx      lr
+// func1 thunk
+// MAIN:    40100e:       40 f2 08 0c     movw    r12, #8
+// MAIN:    401012:       c0 f2 10 0c     movt    r12, #16
+// MAIN:    401016:       e7 44           add     pc,  r12
+// func2 thunk
+// MAIN:    401018:       40 f2 0e 0c     movw    r12, #14
+// MAIN:    40101c:       c0 f2 20 0c     movt    r12, #32
+// MAIN:    401020:       e7 44           add     pc,  r12
+
+// FUNC1:   501022:       40 f0 01 80     bne.w   #2 <.text+0x100028>
+// FUNC1:   501026:       70 47           bx      lr
+// func2 thunk
+// FUNC1:   501028:       4f f6 fe 7c     movw    r12, #65534
+// FUNC1:   50102c:       c0 f2 0f 0c     movt    r12, #15
+// FUNC1:   501030:       e7 44           add     pc,  r12
+
+// FUNC2:   601032:       42 f2 00 00     movw    r0, #8192
+// FUNC2:   601036:       c0 f2 60 00     movt    r0, #96
+// FUNC2:   60103a:       42 f2 03 01     movw    r1, #8195
+// FUNC2:   60103e:       c0 f2 60 01     movt    r1, #96
+// FUNC2:   601042:       70 47   bx      lr
diff --git a/test/COFF/arm64-delayimport.yaml b/test/COFF/arm64-delayimport.yaml
new file mode 100644
index 0000000..6d3d705
--- /dev/null
+++ b/test/COFF/arm64-delayimport.yaml
@@ -0,0 +1,91 @@
+# REQUIRES: aarch64
+
+# RUN: yaml2obj < %s > %t.obj
+# RUN: lld-link /entry:main /subsystem:console /out:%t.exe %t.obj %p/Inputs/library-arm64.lib /alternatename:__delayLoadHelper2=main /delayload:library.dll
+# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix DISASM
+# RUN: llvm-readobj -coff-imports %t.exe | FileCheck %s -check-prefix IMPORTS
+
+# DISASM:  140001014:      11 00 00 d0     adrp    x17, #8192
+# DISASM:  140001018:      31 22 00 91     add     x17, x17, #8
+# DISASM:  14000101c:      fd 7b b3 a9     stp     x29, x30, [sp, #-208]!
+# DISASM:  140001020:      fd 03 00 91     mov     x29, sp
+# DISASM:  140001024:      e0 07 01 a9     stp     x0, x1, [sp, #16]
+# DISASM:  140001028:      e2 0f 02 a9     stp     x2, x3, [sp, #32]
+# DISASM:  14000102c:      e4 17 03 a9     stp     x4, x5, [sp, #48]
+# DISASM:  140001030:      e6 1f 04 a9     stp     x6, x7, [sp, #64]
+# DISASM:  140001034:      e0 87 02 ad     stp     q0, q1, [sp, #80]
+# DISASM:  140001038:      e2 8f 03 ad     stp     q2, q3, [sp, #112]
+# DISASM:  14000103c:      e4 97 04 ad     stp     q4, q5, [sp, #144]
+# DISASM:  140001040:      e6 9f 05 ad     stp     q6, q7, [sp, #176]
+# DISASM:  140001044:      e1 03 11 aa     mov     x1, x17
+# DISASM:  140001048:      00 00 00 b0     adrp    x0, #4096
+# DISASM:  14000104c:      00 00 00 91     add     x0, x0, #0
+# DISASM:  140001050:      ec ff ff 97     bl      #-80 <.text>
+# DISASM:  140001054:      f0 03 00 aa     mov     x16, x0
+# DISASM:  140001058:      e6 9f 45 ad     ldp     q6, q7, [sp, #176]
+# DISASM:  14000105c:      e4 97 44 ad     ldp     q4, q5, [sp, #144]
+# DISASM:  140001060:      e2 8f 43 ad     ldp     q2, q3, [sp, #112]
+# DISASM:  140001064:      e0 87 42 ad     ldp     q0, q1, [sp, #80]
+# DISASM:  140001068:      e6 1f 44 a9     ldp     x6, x7, [sp, #64]
+# DISASM:  14000106c:      e4 17 43 a9     ldp     x4, x5, [sp, #48]
+# DISASM:  140001070:      e2 0f 42 a9     ldp     x2, x3, [sp, #32]
+# DISASM:  140001074:      e0 07 41 a9     ldp     x0, x1, [sp, #16]
+# DISASM:  140001078:      fd 7b cd a8     ldp     x29, x30, [sp], #208
+# DISASM:  14000107c:      00 02 1f d6     br      x16
+
+# IMPORTS: Format: COFF-ARM64
+# IMPORTS: Arch: aarch64
+# IMPORTS: AddressSize: 64bit
+# IMPORTS: DelayImport {
+# IMPORTS:   Name: library.dll
+# IMPORTS:   Attributes: 0x1
+# IMPORTS:   ModuleHandle: 0x3000
+# IMPORTS:   ImportAddressTable: 0x3008
+# IMPORTS:   ImportNameTable: 0x2040
+# IMPORTS:   BoundDelayImportTable: 0x0
+# IMPORTS:   UnloadDelayImportTable: 0x0
+# IMPORTS:   Import {
+# IMPORTS:     Symbol: function (0)
+# IMPORTS:     Address: 0x140001014
+# IMPORTS:   }
+# IMPORTS: }
+
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_ARM64
+  Characteristics: [  ]
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     00000094C0035FD6
+    Relocations:
+      - VirtualAddress:  0
+        SymbolName:      function
+        Type:            IMAGE_REL_ARM64_BRANCH26
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          8
+      NumberOfRelocations: 1
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          1
+  - Name:            main
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            function
+    Value:           0
+    SectionNumber:   0
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/test/COFF/associative-comdat-mingw.s b/test/COFF/associative-comdat-mingw.s
index 09cba9c..def20cd 100644
--- a/test/COFF/associative-comdat-mingw.s
+++ b/test/COFF/associative-comdat-mingw.s
@@ -11,10 +11,11 @@
 # 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
-#             .xdata$foo was retained. This *must* be 4.
+#             .xdata$foo was retained. This *must* be 0x24 (0x4 for the .xdata
+#             section and 0x20 for the .ctors/.dtors headers/ends).
 #             Make sure that no other .xdata sections get included, which would
 #             increase the size here.
-# CHECK-NEXT:     VirtualSize: 0x4
+# CHECK-NEXT:     VirtualSize: 0x24
 
         .text
         .def            main;
diff --git a/test/COFF/autoimport-arm-code.s b/test/COFF/autoimport-arm-code.s
new file mode 100644
index 0000000..562a1a9
--- /dev/null
+++ b/test/COFF/autoimport-arm-code.s
@@ -0,0 +1,19 @@
+# REQUIRES: arm
+
+# RUN: echo -e ".global variable\n.global DllMainCRTStartup\n.thumb\n.text\nDllMainCRTStartup:\nbx lr\n.data\nvariable:\n.long 42" > %t-lib.s
+# RUN: llvm-mc -triple=armv7-windows-gnu %t-lib.s -filetype=obj -o %t-lib.obj
+# RUN: lld-link -out:%t-lib.dll -dll -entry:DllMainCRTStartup %t-lib.obj -lldmingw -implib:%t-lib.lib
+
+# RUN: llvm-mc -triple=armv7-windows-gnu %s -filetype=obj -o %t.obj
+# RUN: not lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib 2>&1 | FileCheck %s
+
+# CHECK: error: unable to automatically import from variable with relocation type IMAGE_REL_ARM_MOV32T
+
+    .global main
+    .text
+    .thumb
+main:
+    movw r0, :lower16:variable
+    movt r0, :upper16:variable
+    ldr  r0, [r0]
+    bx   lr
diff --git a/test/COFF/autoimport-arm-data.s b/test/COFF/autoimport-arm-data.s
new file mode 100644
index 0000000..945d51c
--- /dev/null
+++ b/test/COFF/autoimport-arm-data.s
@@ -0,0 +1,42 @@
+# REQUIRES: arm
+
+# RUN: echo -e ".global variable\n.global DllMainCRTStartup\n.thumb\n.text\nDllMainCRTStartup:\nbx lr\n.data\nvariable:\n.long 42" > %t-lib.s
+# RUN: llvm-mc -triple=armv7-windows-gnu %t-lib.s -filetype=obj -o %t-lib.obj
+# RUN: lld-link -out:%t-lib.dll -dll -entry:DllMainCRTStartup %t-lib.obj -lldmingw -implib:%t-lib.lib
+
+# RUN: llvm-mc -triple=armv7-windows-gnu %s -filetype=obj -o %t.obj
+# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib -verbose
+
+# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
+# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=CONTENTS %s
+
+# IMPORTS: Import {
+# IMPORTS-NEXT: Name: autoimport-arm-data.s.tmp-lib.dll
+# IMPORTS-NEXT: ImportLookupTableRVA: 0x2050
+# IMPORTS-NEXT: ImportAddressTableRVA: 0x2058
+# IMPORTS-NEXT: Symbol: variable (0)
+# IMPORTS-NEXT: }
+
+# Runtime pseudo reloc list header consisting of 0x0, 0x0, 0x1.
+# First runtime pseudo reloc, with import from 0x2058,
+# applied at 0x3000, with a size of 32 bits.
+# CONTENTS: Contents of section .rdata:
+# CONTENTS:  402000 00000000 00000000 01000000 58200000
+# CONTENTS:  402010 00300000 20000000
+# ptr: pointing at the IAT RVA at 0x2058
+# relocs: pointing at the runtime pseudo reloc list at
+# 0x2000 - 0x2018.
+# CONTENTS: Contents of section .data:
+# CONTENTS:  403000 58204000 00204000 18204000
+
+    .global main
+    .text
+    .thumb
+main:
+    bx lr
+    .data
+ptr:
+    .long variable
+relocs:
+    .long __RUNTIME_PSEUDO_RELOC_LIST__
+    .long __RUNTIME_PSEUDO_RELOC_LIST_END__
diff --git a/test/COFF/autoimport-arm64-code.s b/test/COFF/autoimport-arm64-code.s
new file mode 100644
index 0000000..9f5cc8f
--- /dev/null
+++ b/test/COFF/autoimport-arm64-code.s
@@ -0,0 +1,18 @@
+# REQUIRES: aarch64
+
+# RUN: echo -e ".global variable\n.global DllMainCRTStartup\n.text\nDllMainCRTStartup:\nret\n.data\nvariable:\n.long 42" > %t-lib.s
+# RUN: llvm-mc -triple=aarch64-windows-gnu %t-lib.s -filetype=obj -o %t-lib.obj
+# RUN: lld-link -out:%t-lib.dll -dll -entry:DllMainCRTStartup %t-lib.obj -lldmingw -implib:%t-lib.lib
+
+# RUN: llvm-mc -triple=aarch64-windows-gnu %s -filetype=obj -o %t.obj
+# RUN: not lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib 2>&1 | FileCheck %s
+
+# CHECK: error: unable to automatically import from variable with relocation type IMAGE_REL_ARM64_PAGEBASE_REL21
+# CHECK: error: unable to automatically import from variable with relocation type IMAGE_REL_ARM64_PAGEOFFSET_12L
+
+    .global main
+    .text
+main:
+    adrp x0, variable
+    ldr  w0, [x0, :lo12:variable]
+    ret
diff --git a/test/COFF/autoimport-arm64-data.s b/test/COFF/autoimport-arm64-data.s
new file mode 100644
index 0000000..be4d870
--- /dev/null
+++ b/test/COFF/autoimport-arm64-data.s
@@ -0,0 +1,42 @@
+# REQUIRES: aarch64
+
+# RUN: echo -e ".global variable\n.global DllMainCRTStartup\n.text\nDllMainCRTStartup:\nret\n.data\nvariable:\n.long 42" > %t-lib.s
+# RUN: llvm-mc -triple=aarch64-windows-gnu %t-lib.s -filetype=obj -o %t-lib.obj
+# RUN: lld-link -out:%t-lib.dll -dll -entry:DllMainCRTStartup %t-lib.obj -lldmingw -implib:%t-lib.lib
+
+# RUN: llvm-mc -triple=aarch64-windows-gnu %s -filetype=obj -o %t.obj
+# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib -verbose
+
+# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
+# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=CONTENTS %s
+
+# IMPORTS: Import {
+# IMPORTS-NEXT: Name: autoimport-arm64-data.s.tmp-lib.dll
+# IMPORTS-NEXT: ImportLookupTableRVA: 0x2060
+# IMPORTS-NEXT: ImportAddressTableRVA: 0x2070
+# IMPORTS-NEXT: Symbol: variable (0)
+# IMPORTS-NEXT: }
+
+# Runtime pseudo reloc list header consisting of 0x0, 0x0, 0x1.
+# First runtime pseudo reloc, with import from 0x2070,
+# applied at 0x3000, with a size of 32 bits.
+# CONTENTS: Contents of section .rdata:
+# CONTENTS:  140002000 00000000 00000000 01000000 70200000
+# CONTENTS:  140002010 00300000 40000000
+# ptr: pointing at the IAT RVA at 0x2070
+# relocs: pointing at the runtime pseudo reloc list at
+# 0x2000 - 0x2018.
+# CONTENTS: Contents of section .data:
+# CONTENTS:  140003000 70200040 01000000 00200040 01000000
+# CONTENTS:  140003010 18200040 01000000
+
+    .global main
+    .text
+main:
+    ret
+    .data
+ptr:
+    .quad variable
+relocs:
+    .quad __RUNTIME_PSEUDO_RELOC_LIST__
+    .quad __RUNTIME_PSEUDO_RELOC_LIST_END__
diff --git a/test/COFF/autoimport-gnu-implib.s b/test/COFF/autoimport-gnu-implib.s
new file mode 100644
index 0000000..375e0a5
--- /dev/null
+++ b/test/COFF/autoimport-gnu-implib.s
@@ -0,0 +1,26 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-head.s -filetype=obj -o %t-dabcdh.o
+# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-data.s -filetype=obj -o %t-dabcds00000.o
+# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-tail.s -filetype=obj -o %t-dabcdt.o
+# RUN: rm -f %t-implib.a
+# RUN: llvm-ar rcs %t-implib.a %t-dabcdh.o %t-dabcds00000.o %t-dabcdt.o
+
+# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj
+# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-implib.a -verbose
+
+# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
+
+# IMPORTS: Import {
+# IMPORTS-NEXT: Name: foo.dll
+# IMPORTS-NEXT: ImportLookupTableRVA:
+# IMPORTS-NEXT: ImportAddressTableRVA:
+# IMPORTS-NEXT: Symbol: data (0)
+# IMPORTS-NEXT: }
+
+    .global main
+    .text
+main:
+    movl data(%rip), %eax
+    ret
+    .data
diff --git a/test/COFF/autoimport-list-ptrs.s b/test/COFF/autoimport-list-ptrs.s
new file mode 100644
index 0000000..d3c9d3d
--- /dev/null
+++ b/test/COFF/autoimport-list-ptrs.s
@@ -0,0 +1,20 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj
+# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj -verbose
+
+# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=CONTENTS %s
+
+# Even if we didn't actually write any pseudo relocations,
+# check that the synthetic pointers still are set to a non-null value
+# CONTENTS: Contents of section .data:
+# CONTENTS:  140003000 00200040 01000000 00200040 01000000
+
+    .global main
+    .text
+main:
+    retq
+    .data
+relocs:
+    .quad __RUNTIME_PSEUDO_RELOC_LIST__
+    .quad __RUNTIME_PSEUDO_RELOC_LIST_END__
diff --git a/test/COFF/autoimport-refptr.s b/test/COFF/autoimport-refptr.s
new file mode 100644
index 0000000..4b11a8a
--- /dev/null
+++ b/test/COFF/autoimport-refptr.s
@@ -0,0 +1,65 @@
+# REQUIRES: x86
+
+# RUN: echo -e ".global variable\n.global DllMainCRTStartup\n.text\nDllMainCRTStartup:\nret\n.data\nvariable:\n.long 42" > %t-lib.s
+# RUN: llvm-mc -triple=x86_64-windows-gnu %t-lib.s -filetype=obj -o %t-lib.obj
+# RUN: lld-link -out:%t-lib.dll -dll -entry:DllMainCRTStartup %t-lib.obj -lldmingw -implib:%t-lib.lib
+
+# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj
+# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib -verbose
+
+# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
+# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s
+# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=CONTENTS %s
+
+# IMPORTS: Import {
+# IMPORTS-NEXT: Name: autoimport-refptr.s.tmp-lib.dll
+# IMPORTS-NEXT: ImportLookupTableRVA: 0x2050
+# IMPORTS-NEXT: ImportAddressTableRVA: 0x2060
+# IMPORTS-NEXT: Symbol: variable (0)
+# IMPORTS-NEXT: }
+
+# DISASM: Disassembly of section .text:
+# DISASM: .text:
+# Relative offset at 0x1002 pointing at the IAT at 0x2060
+# DISASM: 140001000:      48 8b 05 59 10 00 00    movq    4185(%rip), %rax
+# DISASM: 140001007:      8b 00   movl    (%rax), %eax
+# Relative offset at 0x100b pointing at the .refptr.localvar stub at
+# 0x2000
+# DISASM: 140001009:      48 8b 0d f0 0f 00 00    movq    4080(%rip), %rcx
+# DISASM: 140001010:      03 01   addl    (%rcx), %eax
+# DISASM: 140001012:      c3      retq
+
+# relocs: pointing at an empty list of runtime pseudo relocs.
+# localvar: 42
+# CONTENTS: Contents of section .data:
+# CONTENTS:  140003000 08200040 01000000 08200040 01000000
+# CONTENTS:  140003010 2a000000
+
+    .global main
+    .global localvar
+    .text
+main:
+    movq .refptr.variable(%rip), %rax
+    movl (%rax), %eax
+    movq .refptr.localvar(%rip), %rcx
+    addl (%rcx), %eax
+    ret
+
+    .data
+relocs:
+    .quad __RUNTIME_PSEUDO_RELOC_LIST__
+    .quad __RUNTIME_PSEUDO_RELOC_LIST_END__
+localvar:
+    .int 42
+
+# Normally the compiler wouldn't emit a stub for a variable that is
+# emitted in the same translation unit.
+    .section .rdata$.refptr.localvar,"dr",discard,.refptr.localvar
+    .global .refptr.localvar
+.refptr.localvar:
+    .quad localvar
+
+    .section .rdata$.refptr.variable,"dr",discard,.refptr.variable
+    .global .refptr.variable
+.refptr.variable:
+    .quad variable
diff --git a/test/COFF/autoimport-x86.s b/test/COFF/autoimport-x86.s
new file mode 100644
index 0000000..379985e
--- /dev/null
+++ b/test/COFF/autoimport-x86.s
@@ -0,0 +1,53 @@
+# REQUIRES: x86
+
+# RUN: echo -e ".global variable\n.global DllMainCRTStartup\n.text\nDllMainCRTStartup:\nret\n.data\nvariable:\n.long 42" > %t-lib.s
+# RUN: llvm-mc -triple=x86_64-windows-gnu %t-lib.s -filetype=obj -o %t-lib.obj
+# RUN: lld-link -out:%t-lib.dll -dll -entry:DllMainCRTStartup %t-lib.obj -lldmingw -implib:%t-lib.lib
+
+# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj
+# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib -verbose
+
+# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
+# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s
+# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=CONTENTS %s
+
+# IMPORTS: Import {
+# IMPORTS-NEXT: Name: autoimport-x86.s.tmp-lib.dll
+# IMPORTS-NEXT: ImportLookupTableRVA: 0x2070
+# IMPORTS-NEXT: ImportAddressTableRVA: 0x2080
+# IMPORTS-NEXT: Symbol: variable (0)
+# IMPORTS-NEXT: }
+
+# DISASM: Disassembly of section .text:
+# DISASM: .text:
+# Relative offset at 0x1002 pointing at the IAT at 0x2080.
+# DISASM: 140001000:      8b 05 7a 10 00 00       movl    4218(%rip), %eax
+# DISASM: 140001006:      c3      retq
+
+# Runtime pseudo reloc list header consisting of 0x0, 0x0, 0x1.
+# First runtime pseudo reloc, with import from 0x2080,
+# applied at 0x1002, with a size of 32 bits.
+# Second runtime pseudo reloc, with import from 0x2080,
+# applied at 0x3000, with a size of 64 bits.
+# CONTENTS: Contents of section .rdata:
+# CONTENTS:  140002000 00000000 00000000 01000000 80200000
+# CONTENTS:  140002010 02100000 20000000 80200000 00300000
+# CONTENTS:  140002020 40000000
+# ptr: pointing at the IAT RVA at 0x2080
+# relocs: pointing at the runtime pseudo reloc list at
+# 0x2000 - 0x2024.
+# CONTENTS: Contents of section .data:
+# CONTENTS:  140003000 80200040 01000000 00200040 01000000
+# CONTENTS:  140003010 24200040 01000000
+
+    .global main
+    .text
+main:
+    movl variable(%rip), %eax
+    ret
+    .data
+ptr:
+    .quad variable
+relocs:
+    .quad __RUNTIME_PSEUDO_RELOC_LIST__
+    .quad __RUNTIME_PSEUDO_RELOC_LIST_END__
diff --git a/test/COFF/baserel.test b/test/COFF/baserel.test
index 6441bb2..a10d6ed 100644
--- a/test/COFF/baserel.test
+++ b/test/COFF/baserel.test
@@ -47,9 +47,9 @@
 # RUN: llvm-readobj -file-headers -sections %t.exe | FileCheck %s \
 # RUN:   --check-prefix=BASEREL-HEADER
 #
-# RN: lld-link /out:%t.exe /entry:main /fixed %t.obj %p/Inputs/std64.lib
-# RN: llvm-readobj -file-headers %t.exe | FileCheck %s \
-# RN:   --check-prefix=NOBASEREL-HEADER
+# RUN: lld-link /out:%t.exe /entry:main /fixed %t.obj %p/Inputs/std64.lib
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s \
+# RUN:   --check-prefix=NOBASEREL-HEADER
 #
 # BASEREL-HEADER-NOT: IMAGE_FILE_RELOCS_STRIPPED
 #
diff --git a/test/COFF/broken-arm-reloc.yaml b/test/COFF/broken-arm-reloc.yaml
new file mode 100644
index 0000000..ad4328b
--- /dev/null
+++ b/test/COFF/broken-arm-reloc.yaml
@@ -0,0 +1,92 @@
+# REQUIRES: arm
+
+#    .global main
+#    .global variable
+#    .text
+#    .thumb
+#main:
+#    movw r0, :lower16:variable
+#    nop
+#    movt r0, :upper16:variable
+#    ldr  r0, [r0]
+#    bx   lr
+#    .data
+#variable:
+#    .long 42
+
+# RUN: yaml2obj %s > %t.obj
+# RUN: not lld-link -out:%t.exe -entry:main %t.obj 2>&1 | FileCheck %s
+
+# CHECK: error: unexpected instruction in MOVT instruction in MOV32T relocation
+
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_ARMNT
+  Characteristics: [  ]
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     40F2000000BFC0F2000000687047
+    Relocations:
+      - VirtualAddress:  0
+        SymbolName:      variable
+        Type:            IMAGE_REL_ARM_MOV32T
+  - Name:            .data
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       4
+    SectionData:     2A000000
+  - Name:            .bss
+    Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       4
+    SectionData:     ''
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          14
+      NumberOfRelocations: 1
+      NumberOfLinenumbers: 0
+      CheckSum:        2762100735
+      Number:          1
+  - 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:        3482275674
+      Number:          2
+  - Name:            .bss
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          0
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          3
+  - Name:            main
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            variable
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/test/COFF/comdat-jumptable.s b/test/COFF/comdat-jumptable.s
new file mode 100644
index 0000000..31a7c5f
--- /dev/null
+++ b/test/COFF/comdat-jumptable.s
@@ -0,0 +1,70 @@
+# REQUIRES: x86
+# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t1.obj
+# RUN: llvm-mc -triple=x86_64-windows-gnu %S/Inputs/comdat-jumptable2.s -filetype=obj -o %t2.obj
+
+# RUN: llvm-objdump -s %t1.obj | FileCheck --check-prefix=OBJ1 %s
+# RUN: llvm-objdump -s %t2.obj | FileCheck --check-prefix=OBJ2 %s
+
+# RUN: lld-link -lldmingw -entry:main %t1.obj %t2.obj -out:%t.exe
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=EXE %s
+
+# Test linking cases where comdat functions have an associated jump table
+# in a non-comdat rdata (which GCC produces for functions with jump tables).
+# In these cases, ld.bfd keeps all rdata sections, but the relocations that
+# refer to discarded comdat sections just are emitted as they were originally.
+
+# In real scenarios, the jump table .rdata section should be identical across
+# all object files; here it is different to illustrate more clearly what
+# the linker actually does.
+
+# OBJ1: Contents of section .rdata:
+# OBJ1:  0000 aaaaaaaa 14000000 1e000000 28000000
+# OBJ1:  0010 bbbbbbbb
+
+# OBJ2: Contents of section .rdata:
+# OBJ2:  0000 cccccccc 14000000 1e000000 28000000
+# OBJ2:  0010 dddddddd
+
+# EXE: Contents of section .rdata:
+# EXE:  140002000 aaaaaaaa 0c100000 12100000 18100000
+# EXE:  140002010 bbbbbbbb cccccccc 14000000 1e000000
+# EXE:  140002020 28000000 dddddddd
+
+
+        .section .text@comdatfunc, "x"
+        .linkonce discard
+        .globl comdatfunc
+comdatfunc:
+        leaq .Ljumptable(%rip), %rax
+        movslq (%rax, %rcx, 4), %rcx
+        addq %rcx, %rax
+        jmp *%rax
+
+        .section .rdata, "dr"
+        .long 0xaaaaaaaa
+.Ljumptable:
+        .long .Ltail1-.Ljumptable
+        .long .Ltail2-.Ljumptable
+        .long .Ltail3-.Ljumptable
+        .long 0xbbbbbbbb
+
+        .section .text@comdatfunc, "x"
+# If assembled with binutils, the following line can be kept in:
+#       .linkonce discard
+.Ltail1:
+        movl $1, %eax
+        ret
+.Ltail2:
+        movl $2, %eax
+        ret
+.Ltail3:
+        movl $3, %eax
+        ret
+
+
+        .text
+        .globl main
+main:
+        call comdatfunc
+        call otherfunc
+        ret
diff --git a/test/COFF/comdat-weak.test b/test/COFF/comdat-weak.test
new file mode 100644
index 0000000..a2b4688
--- /dev/null
+++ b/test/COFF/comdat-weak.test
@@ -0,0 +1,82 @@
+RUN: lld-link -lldmingw %S/Inputs/inline-weak.o %S/Inputs/inline-weak2.o -out:%t.exe
+
+When compiling certain forms of templated inline functions, some
+versions of GCC (tested with 5.4) produces a weak symbol for the function.
+Newer versions of GCC don't do this though.
+
+The bundled object files are an example of that, they can be produced
+with test code like this:
+
+$ cat inline-weak.h
+class MyClass {
+public:
+    template<typename... _Args> int get(_Args&&... args) {
+        return a;
+    }
+private:
+    int a;
+};
+
+$ cat inline-weak.cpp
+#include "inline-weak.h"
+
+int get(MyClass& a);
+
+int main(int argc, char* argv[]) {
+    MyClass a;
+    int ret = a.get();
+    ret += get(a);
+    return ret;
+}
+extern "C" void mainCRTStartup(void) {
+    main(0, (char**)0);
+}
+extern "C" void __main(void) {
+}
+
+$ cat inline-weak2.cpp
+#include "inline-weak.h"
+
+int get(MyClass& a) {
+    return a.get();
+}
+
+$ x86_64-w64-mingw32-g++ -std=c++11 -c inline-weak.cpp
+$ x86_64-w64-mingw32-g++ -std=c++11 -c inline-weak2.cpp
+
+$ x86_64-w64-mingw32-nm inline-weak.o | grep MyClass3get
+0000000000000000 p .pdata$_ZN7MyClass3getIJEEEiDpOT_
+0000000000000000 t .text$_ZN7MyClass3getIJEEEiDpOT_
+0000000000000000 T .weak._ZN7MyClass3getIIEEEiDpOT_.main
+0000000000000000 r .xdata$_ZN7MyClass3getIJEEEiDpOT_
+                 w _ZN7MyClass3getIIEEEiDpOT_
+0000000000000000 T _ZN7MyClass3getIJEEEiDpOT_
+
+$ x86_64-w64-mingw32-nm inline-weak2.o | grep MyClass3get
+0000000000000000 p .pdata$_ZN7MyClass3getIJEEEiDpOT_
+0000000000000000 t .text$_ZN7MyClass3getIJEEEiDpOT_
+0000000000000000 T .weak._ZN7MyClass3getIIEEEiDpOT_._Z3getR7MyClass
+0000000000000000 r .xdata$_ZN7MyClass3getIJEEEiDpOT_
+                 w _ZN7MyClass3getIIEEEiDpOT_
+0000000000000000 T _ZN7MyClass3getIJEEEiDpOT_
+
+This can't be reproduced by assembling .s files with llvm-mc, since that
+always produces a symbol named .weak.<weaksymbol>.default, therefore
+the test uses prebuilt object files instead.
+
+In these cases, the undefined weak symbol points to the regular symbol
+.weak._ZN7MyClass3getIIEEEiDpOT_.<othersymbol>, where <othersymbol>
+varies among the object files that emit the same function. This regular
+symbol points to the same location as the comdat function
+_ZN7MyClass3getIJEEEiDpOT_.
+
+When linking, the comdat section from the second object file gets
+discarded, as it matches the one that already exists. This means that
+the uniquely named symbol .weak.<weakname>.<othername> points to a
+discarded section chunk.
+
+Previously, this would have triggered adding an Undefined symbol for
+this case, which would later break linking. However, also previously,
+if the second object file is linked in via a static library, this
+leftover symbol is retained as a Lazy symbol, which would make the link
+succeed.
diff --git a/test/COFF/common-replacement.s b/test/COFF/common-replacement.s
index 51e31fa..115ebe5 100644
--- a/test/COFF/common-replacement.s
+++ b/test/COFF/common-replacement.s
@@ -14,7 +14,7 @@
 
 # SECTIONS:         Name: .data (2E 64 61 74 61 00 00 00)
 # SECTIONS-NEXT:    VirtualSize: 0x8
-# SECTIONS-NEXT:    VirtualAddress: 0x2000
+# SECTIONS-NEXT:    VirtualAddress: 0x3000
 # SECTIONS-NEXT:    RawDataSize: 512
 
 
diff --git a/test/COFF/could-not-open.test b/test/COFF/could-not-open.test
new file mode 100644
index 0000000..87f11c3
--- /dev/null
+++ b/test/COFF/could-not-open.test
@@ -0,0 +1,5 @@
+RUN: not lld-link 01 2>&1 | FileCheck %s
+
+CHECK:     could not open 01
+CHECK-NOT: /machine is not specified
+CHECK-NOT: subsystem must be defined
diff --git a/test/COFF/crt-dyn-initializer-order.test b/test/COFF/crt-dyn-initializer-order.test
new file mode 100644
index 0000000..963b065
--- /dev/null
+++ b/test/COFF/crt-dyn-initializer-order.test
@@ -0,0 +1,100 @@
+# // a.cpp

+# #include <iostream>

+# #include <vector>

+# 

+# template <int Magic> struct TemplatedObject {

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

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

+# };

+# 

+# using Object = TemplatedObject<0>;

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

+# Object idle{};

+# 

+# int main() {

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

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

+#   else

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

+#   return 0;

+# }

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

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

+

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

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

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

+

+# CHECK: Name: .CRT

+# CHECK: Characteristics [

+# CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA

+# CHECK-NEXT: IMAGE_SCN_MEM_READ

+# CHECK-NEXT: ]

+# CHECK-NEXT: SectionData (

+

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

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

+# CASE1-NEXT: 01020304 55701011 1205

+

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

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

+# CASE2-NEXT: 01020304 10111255 7005

+

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

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

+# CASE3-NEXT: 01557010 11120203 0405

+

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

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

+# CASE4-NEXT: 01557002 03041011 1205

+

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

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

+# CASE5-NEXT: 01101112 55700203 0405

+

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

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

+# CASE6-NEXT: 01101112 02030455 7005

+

+# CHECK-NEXT: )

+

+--- !COFF

+header:

+  Machine:         IMAGE_FILE_MACHINE_AMD64

+  Characteristics: [  ]

+sections:

+  - Name:            '.CRT$XCA'

+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]

+    Alignment:       1

+    SectionData:     01

+  - Name:            '.CRT$XCU'

+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]

+    Alignment:       1

+    SectionData:     02

+  - Name:            '.CRT$XCU'

+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_LNK_COMDAT ]

+    Alignment:       1

+    SectionData:     03

+  - Name:            '.CRT$XCU'

+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]

+    Alignment:       1

+    SectionData:     04

+  - Name:            '.CRT$XCZ'

+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]

+    Alignment:       1

+    SectionData:     05

+symbols:

+  - Name:            '.CRT$XCU'

+    Value:           0

+    SectionNumber:   3

+    SimpleType:      IMAGE_SYM_TYPE_NULL

+    ComplexType:     IMAGE_SYM_DTYPE_NULL

+    StorageClass:    IMAGE_SYM_CLASS_STATIC

+    SectionDefinition:

+      Length:          1

+      NumberOfRelocations: 0

+      NumberOfLinenumbers: 0

+      CheckSum:        1

+      Number:          2

+      Selection:       IMAGE_COMDAT_SELECT_ASSOCIATIVE

+...

diff --git a/test/COFF/ctors_dtors_priority.s b/test/COFF/ctors_dtors_priority.s
index efa0354..d50877f 100644
--- a/test/COFF/ctors_dtors_priority.s
+++ b/test/COFF/ctors_dtors_priority.s
@@ -1,12 +1,17 @@
 # REQUIRES: x86
 # RUN: llvm-mc -triple=x86_64-windows-gnu -filetype=obj -o %t.obj %s
-# RUN: lld-link -entry:main %t.obj -out:%t.exe
+# RUN: lld-link -lldmingw -entry:main %t.obj -out:%t.exe
 # RUN: llvm-objdump -s %t.exe | FileCheck %s
 
 .globl main
 main:
   nop
 
+# Check that these symbols point at the right spots.
+.data
+  .quad __CTOR_LIST__
+  .quad __DTOR_LIST__
+
 .section .ctors.00005, "w"
   .quad 2
 .section .ctors, "w"
@@ -15,16 +20,26 @@
   .quad 3
 
 .section .dtors, "w"
-  .quad 1
+  .quad 4
 .section .dtors.00100, "w"
-  .quad 3
+  .quad 6
 .section .dtors.00005, "w"
-  .quad 2
+  .quad 5
 
-# CHECK:      Contents of section .ctors:
-# CHECK-NEXT: 140002000 01000000 00000000 02000000 00000000
-# CHECK-NEXT: 140002010 03000000 00000000
+# Also test that the .CRT section is merged into .rdata
 
-# CHECK:      Contents of section .dtors:
-# CHECK-NEXT: 140003000 01000000 00000000 02000000 00000000
-# CHECK-NEXT: 140003010 03000000 00000000
+.section .CRT$XCA, "dw"
+  .quad 7
+  .quad 8
+
+# CHECK:      Contents of section .rdata:
+# CHECK-NEXT: 140002000 07000000 00000000 08000000 00000000
+# CHECK-NEXT: 140002010 ffffffff ffffffff 01000000 00000000
+# CHECK-NEXT: 140002020 02000000 00000000 03000000 00000000
+# CHECK-NEXT: 140002030 00000000 00000000 ffffffff ffffffff
+# CHECK-NEXT: 140002040 04000000 00000000 05000000 00000000
+# CHECK-NEXT: 140002050 06000000 00000000 00000000 00000000
+# __CTOR_LIST__ pointing at 0x140002010 and
+# __DTOR_LIST__ pointing at 0x140002038.
+# CHECK-NEXT: Contents of section .data:
+# CHECK-NEXT: 140003000 10200040 01000000 38200040 01000000
diff --git a/test/COFF/debug-fastlink.test b/test/COFF/debug-fastlink.test
new file mode 100644
index 0000000..10b4141
--- /dev/null
+++ b/test/COFF/debug-fastlink.test
@@ -0,0 +1,12 @@
+# RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj
+# RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj
+
+; If /DEBUG:FASTLINK is specified, /DEBUG:FULL is used instead
+# RUN: rm -f %t.pdb
+# RUN: lld-link /DEBUG /pdb:%t.pdb /DEBUG:FASTLINK /entry:main /nodefaultlib %t1.obj %t2.obj \
+# RUN: 2>&1 | FileCheck %s
+
+# CHECK: /debug:fastlink unsupported; using /debug:full
+
+# RUN: ls %t.pdb
+
diff --git a/test/COFF/debug-reloc.s b/test/COFF/debug-reloc.s
index 57ab9bf..897f31a 100644
--- a/test/COFF/debug-reloc.s
+++ b/test/COFF/debug-reloc.s
@@ -8,35 +8,35 @@
 # RUN: llvm-readobj -file-headers %t.exe | FileCheck %s -check-prefix HEADERS
 # RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck %s -check-prefix DEBUG
 
-# SECTIONS:         Number: 2
+# SECTIONS:         Number: 3
 # SECTIONS-NEXT:    Name: .buildid (2E 62 75 69 6C 64 69 64)
 # SECTIONS-NEXT:    VirtualSize: 0x35
-# SECTIONS-NEXT:    VirtualAddress: 0x2000
-# SECTIONS:         Number: 3
+# SECTIONS-NEXT:    VirtualAddress: 0x3000
+# SECTIONS:         Number: 4
 # SECTIONS-NEXT:    Name: .data (2E 64 61 74 61 00 00 00)
 # SECTIONS-NEXT:    VirtualSize: 0x8
-# SECTIONS-NEXT:    VirtualAddress: 0x3000
+# SECTIONS-NEXT:    VirtualAddress: 0x4000
 
 # RELOCS:      BaseReloc [
 # RELOCS-NEXT:   Entry {
 # RELOCS-NEXT:     Type: DIR64
-# RELOCS-NEXT:     Address: 0x3000
+# RELOCS-NEXT:     Address: 0x4000
 # RELOCS-NEXT:   }
 # RELOCS-NEXT:   Entry {
 # RELOCS-NEXT:     Type: ABSOLUTE
-# RELOCS-NEXT:     Address: 0x3000
+# RELOCS-NEXT:     Address: 0x4000
 # RELOCS-NEXT:   }
 # RELOCS-NEXT: ]
 
-# HEADERS:     DebugRVA: 0x2000
+# HEADERS:     DebugRVA: 0x3000
 # HEADERS:     DebugSize: 0x1C
 
 # DEBUG: DebugDirectory [
 # DEBUG:   DebugEntry {
 # DEBUG:     Type: CodeView (0x2)
 # DEBUG:     SizeOfData: 0x19
-# DEBUG:     AddressOfRawData: 0x201C
-# DEBUG:     PointerToRawData: 0x61C
+# DEBUG:     AddressOfRawData: 0x301C
+# DEBUG:     PointerToRawData: 0x81C
 
 	.text
 	.def	 mainfunc;
diff --git a/test/COFF/directives.s b/test/COFF/directives.s
new file mode 100644
index 0000000..9c4b7ef
--- /dev/null
+++ b/test/COFF/directives.s
@@ -0,0 +1,46 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -triple=x86_64-windows %s -filetype=obj -o %t.obj
+
+# RUN: lld-link -dll -out:%t.dll -entry:entry %t.obj -subsystem:console
+# RUN: llvm-objdump -p %t.dll | FileCheck %s
+
+# CHECK:      Export Table:
+# CHECK:      DLL name: directives.s.tmp.dll
+# CHECK:      Ordinal      RVA  Name
+# CHECK-NEXT:       0        0
+# CHECK-NEXT:       1   0x1000  exportfn1
+# CHECK-NEXT:       2   0x1000  exportfn2
+# CHECK-NEXT:       3   0x1000  exportfn3
+# CHECK-NEXT:       4   0x1000  exportfn4
+# CHECK-NEXT:       5   0x1000  exportfn5
+# CHECK-NEXT:       6   0x1000  exportfn6
+
+  .global entry
+  .global exportfn1
+  .global exportfn2
+  .global exportfn3
+  .global exportfn4
+  .global exportfn5
+  .global exportfn6
+  .text
+entry:
+exportfn1:
+exportfn2:
+exportfn3:
+exportfn4:
+exportfn5:
+exportfn6:
+  ret
+  .section .drectve
+# Test that directive strings can be separated by any combination of
+# spaces and null bytes.
+  .ascii "-export:exportfn1 "
+  .asciz "-export:exportfn2"
+  .asciz "-export:exportfn3"
+  .asciz "-export:exportfn4 "
+  .byte 0
+  .ascii " "
+  .byte 0
+  .asciz "-export:exportfn5"
+  .asciz " -export:exportfn6"
diff --git a/test/COFF/entry-inference-mingw.s b/test/COFF/entry-inference-mingw.s
new file mode 100644
index 0000000..cf35620
--- /dev/null
+++ b/test/COFF/entry-inference-mingw.s
@@ -0,0 +1,44 @@
+# REQUIRES: x86
+# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.o
+
+# RUN: lld-link -lldmingw %t.o -out:%t-default.exe 2>&1 | FileCheck -allow-empty -check-prefix=LINK %s
+# RUN: lld-link -lldmingw %t.o -out:%t-cui.exe -subsystem:console 2>&1 | FileCheck -allow-empty -check-prefix=LINK %s
+# RUN: lld-link -lldmingw %t.o -out:%t-gui.exe -subsystem:windows 2>&1 | FileCheck -allow-empty -check-prefix=LINK %s
+
+# RUN: llvm-readobj -file-headers %t-default.exe | FileCheck -check-prefix=CUI %s
+# RUN: llvm-readobj -file-headers %t-cui.exe | FileCheck -check-prefix=CUI %s
+# RUN: llvm-readobj -file-headers %t-gui.exe | FileCheck -check-prefix=GUI %s
+
+# Check that this doesn't print any warnings.
+# LINK-NOT: found both wmain and main
+
+# CUI: AddressOfEntryPoint: 0x1001
+# CUI: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI (0x3)
+
+# GUI: AddressOfEntryPoint: 0x1002
+# GUI: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_GUI (0x2)
+
+
+        .text
+        .globl mainCRTStartup
+        .globl WinMainCRTStartup
+# MinGW only uses the entry points above, these other ones aren't
+# used as entry.
+        .globl main
+        .globl wmain
+        .globl wmainCRTStartup
+        .globl wWinMainCRTStartup
+foo:
+        ret
+mainCRTStartup:
+        ret
+WinMainCRTStartup:
+        ret
+main:
+        ret
+wmain:
+        ret
+wmainCRTStartup:
+        ret
+wWinMainCRTStartup:
+        ret
diff --git a/test/COFF/entry-inference.test b/test/COFF/entry-inference.test
index 294870b..b58a23a 100644
--- a/test/COFF/entry-inference.test
+++ b/test/COFF/entry-inference.test
@@ -1,18 +1,26 @@
 # RUN: sed -e s/ENTRYNAME/main/ %s | yaml2obj > %t.obj
 # RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
 # RUN: FileCheck -check-prefix=MAIN %s < %t.log
+# RUN: not lld-link /nodefaultlib /out:%t.exe %t.obj > %t.log 2>&1
+# RUN: FileCheck -check-prefix=MAIN %s < %t.log
 
 # RUN: sed s/ENTRYNAME/wmain/ %s | yaml2obj > %t.obj
 # RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
 # RUN: FileCheck -check-prefix=WMAIN %s < %t.log
+# RUN: not lld-link /nodefaultlib /out:%t.exe %t.obj > %t.log 2>&1
+# RUN: FileCheck -check-prefix=WMAIN %s < %t.log
 
 # RUN: sed s/ENTRYNAME/WinMain/ %s | yaml2obj > %t.obj
 # RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
 # RUN: FileCheck -check-prefix=WINMAIN %s < %t.log
+# RUN: not lld-link /nodefaultlib /out:%t.exe %t.obj > %t.log 2>&1
+# RUN: FileCheck -check-prefix=WINMAIN %s < %t.log
 
 # RUN: sed s/ENTRYNAME/wWinMain/ %s | yaml2obj > %t.obj
 # RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
 # RUN: FileCheck -check-prefix=WWINMAIN %s < %t.log
+# RUN: not lld-link /nodefaultlib /out:%t.exe %t.obj > %t.log 2>&1
+# RUN: FileCheck -check-prefix=WWINMAIN %s < %t.log
 
 # MAIN:     error: <root>: undefined symbol: mainCRTStartup
 # WMAIN:    error: <root>: undefined symbol: wmainCRTStartup
diff --git a/test/COFF/entry-inference4.test b/test/COFF/entry-inference4.test
index 513c9cf..6b6a581 100644
--- a/test/COFF/entry-inference4.test
+++ b/test/COFF/entry-inference4.test
@@ -14,10 +14,22 @@
 # RUN: not lld-link /subsystem:console /out:%t.exe %t.obj > %t.log 2>&1
 # RUN: FileCheck -check-prefix=WMAIN %s < %t.log
 
-# MAIN:     error: <root>: undefined symbol: mainCRTStartup
-# WMAIN:    error: <root>: undefined symbol: wmainCRTStartup
-# WINMAIN:  error: <root>: undefined symbol: WinMainCRTStartup
-# WWINMAIN: error: <root>: undefined symbol: wWinMainCRTStartup
+# RUN: sed 's/ENTRY1/wmain/;s/ENTRY2/main/' %s | yaml2obj > %t.obj
+# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
+# RUN: FileCheck -check-prefix=MAINWMAIN %s < %t.log
+
+# RUN: sed 's/ENTRY1/wWinMain/;s/ENTRY2/WinMain/' %s | yaml2obj > %t.obj
+# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
+# RUN: FileCheck -check-prefix=WINMAINWWINMAIN %s < %t.log
+
+# MAIN:            error: <root>: undefined symbol: mainCRTStartup
+# WMAIN:           error: <root>: undefined symbol: wmainCRTStartup
+# MAINWMAIN:       warning: found both wmain and main; using latter
+# MAINWMAIN:       error: <root>: undefined symbol: mainCRTStartup
+# WINMAIN:         error: <root>: undefined symbol: WinMainCRTStartup
+# WWINMAIN:        error: <root>: undefined symbol: wWinMainCRTStartup
+# WINMAINWWINMAIN: warning: found both wWinMain and WinMain; using latter
+# WINMAINWWINMAIN: error: <root>: undefined symbol: WinMainCRTStartup
 
 --- !COFF
 header:
diff --git a/test/COFF/export-all.s b/test/COFF/export-all.s
index 78a2527..3d80603 100644
--- a/test/COFF/export-all.s
+++ b/test/COFF/export-all.s
@@ -3,14 +3,13 @@
 # RUN: llvm-mc -triple=i686-windows-gnu %s -filetype=obj -o %t.obj
 
 # RUN: lld-link -lldmingw -dll -out:%t.dll -entry:DllMainCRTStartup@12 %t.obj -implib:%t.lib
-# RUN: llvm-readobj -coff-exports %t.dll | FileCheck %s
+# RUN: llvm-readobj -coff-exports %t.dll | grep Name: | FileCheck %s
 # RUN: llvm-readobj %t.lib | FileCheck -check-prefix=IMPLIB %s
 
-# CHECK-NOT: Name: DllMainCRTStartup
-# CHECK-NOT: Name: _imp__unexported
-# CHECK: Name: dataSym
-# CHECK: Name: foobar
-# CHECK-NOT: Name: unexported
+# CHECK: Name:
+# CHECK-NEXT: Name: dataSym
+# CHECK-NEXT: Name: foobar
+# CHECK-EMPTY:
 
 # IMPLIB: Symbol: __imp__dataSym
 # IMPLIB-NOT: Symbol: _dataSym
@@ -22,6 +21,7 @@
 .global _dataSym
 .global _unexported
 .global __imp__unexported
+.global .refptr._foobar
 .text
 _DllMainCRTStartup@12:
   ret
@@ -34,6 +34,8 @@
   .int 4
 __imp__unexported:
   .int _unexported
+.refptr._foobar:
+  .int _foobar
 
 # Test specifying -export-all-symbols, on an object file that contains
 # dllexport directive for some of the symbols.
@@ -75,6 +77,18 @@
 # CHECK-EXCLUDE-NEXT: foobar @1
 # CHECK-EXCLUDE-NEXT: EOF
 
+# Test that libraries included with -wholearchive: are autoexported, even if
+# they are in a library that otherwise normally would be excluded.
+
+# RUN: lld-link -out:%t.dll -dll -entry:DllMainCRTStartup %t.main.obj -lldmingw %T/libs/crt2.o -wholearchive:%T/libs/libmingwex.a -output-def:%t.def
+# RUN: echo "EOF" >> %t.def
+# RUN: cat %t.def | FileCheck -check-prefix=CHECK-WHOLEARCHIVE %s
+
+# CHECK-WHOLEARCHIVE: EXPORTS
+# CHECK-WHOLEARCHIVE-NEXT: foobar @1
+# CHECK-WHOLEARCHIVE-NEXT: mingwfunc @2
+# CHECK-WHOLEARCHIVE-NEXT: EOF
+
 # Test that we handle import libraries together with -opt:noref.
 
 # RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj
diff --git a/test/COFF/force-multiple.test b/test/COFF/force-multiple.test
new file mode 100644
index 0000000..9f60e13
--- /dev/null
+++ b/test/COFF/force-multiple.test
@@ -0,0 +1,45 @@
+# RUN: yaml2obj < %s > %t1.obj
+# RUN: yaml2obj < %s > %t2.obj
+
+# RUN: not lld-link /out:%t.exe /entry:main %t1.obj %t2.obj >& %t.log
+# RUN: FileCheck -check-prefix=ERROR %s < %t.log
+
+# RUN: lld-link /out:%t.exe /entry:main %t1.obj %t2.obj /force >& %t.log
+# RUN: FileCheck -check-prefix=WARN %s < %t.log
+
+# RUN: lld-link /out:%t.exe /entry:main %t1.obj %t2.obj /force:multiple >& %t.log
+# RUN: FileCheck -check-prefix=WARN %s < %t.log
+
+# ERROR: error: duplicate symbol: main
+
+# WARN: warning: duplicate symbol: main
+
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: []
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     000000000000
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          6
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            main
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/test/COFF/gnu-weak.test b/test/COFF/gnu-weak.test
new file mode 100644
index 0000000..20284d7
--- /dev/null
+++ b/test/COFF/gnu-weak.test
@@ -0,0 +1,52 @@
+RUN: lld-link -lldmingw %S/Inputs/gnu-weak.o %S/Inputs/gnu-weak2.o -out:%t.exe
+
+GNU ld can handle several definitions of the same weak symbol, and
+unless there is a strong definition of it, it just picks the first
+weak definition encountered.
+
+For each of the weak definitions, GNU tools produce a regular symbol
+named .weak.<weaksymbol>.<othersymbol>, where the other symbol name is
+another symbol defined close by.
+
+This can't be reproduced by assembling with llvm-mc, as llvm-mc always
+produces similar regular symbols named .weak.<weaksymbol>.default.
+
+The bundled object files can be produced from test code that looks like
+this:
+
+$ cat gnu-weak.c
+void weakfunc(void) __attribute__((weak));
+void otherfunc(void);
+
+__attribute__((weak)) void weakfunc() {
+}
+
+int main(int argc, char* argv[]) {
+    otherfunc();
+    weakfunc();
+    return 0;
+}
+void mainCRTStartup(void) {
+    main(0, (char**)0);
+}
+void __main(void) {
+}
+
+$ cat gnu-weak2.c
+void weakfunc(void) __attribute__((weak));
+
+__attribute__((weak)) void weakfunc() {
+}
+
+void otherfunc(void) {
+}
+
+$ x86_64-w64-mingw32-gcc -c -O2 gnu-weak.c
+$ x86_64-w64-mingw32-gcc -c -O2 gnu-weak2.c
+
+$ x86_64-w64-mingw32-nm gnu-weak.o | grep weakfunc
+0000000000000000 T .weak.weakfunc.main
+                 w weakfunc
+$ x86_64-w64-mingw32-nm gnu-weak2.o | grep weakfunc
+0000000000000000 T .weak.weakfunc.otherfunc
+                 w weakfunc
diff --git a/test/COFF/icf-safe.s b/test/COFF/icf-safe.s
new file mode 100644
index 0000000..d16f21f
--- /dev/null
+++ b/test/COFF/icf-safe.s
@@ -0,0 +1,37 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-win32 %s -o %t1.obj
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-win32 %S/Inputs/icf-safe.s -o %t2.obj
+# RUN: lld-link /dll /noentry /out:%t.dll /verbose /opt:noref,icf %t1.obj %t2.obj 2>&1 | FileCheck %s
+# RUN: lld-link /dll /noentry /out:%t.dll /verbose /opt:noref,icf /export:g3 /export:g4 %t1.obj %t2.obj 2>&1 | FileCheck --check-prefix=EXPORT %s
+
+# CHECK-NOT: Selected
+# CHECK: Selected g3
+# CHECK-NEXT:   Removed g4
+# CHECK-NOT: Removed
+# CHECK-NOT: Selected
+
+# EXPORT-NOT: Selected
+
+.section .rdata,"dr",one_only,g1
+.globl g1
+g1:
+.byte 1
+
+.section .rdata,"dr",one_only,g2
+.globl g2
+g2:
+.byte 1
+
+.section .rdata,"dr",one_only,g3
+.globl g3
+g3:
+.byte 2
+
+.section .rdata,"dr",one_only,g4
+.globl g4
+g4:
+.byte 2
+
+.addrsig
+.addrsig_sym g1
+.addrsig_sym g2
diff --git a/test/COFF/imports-gnu-autoexport.s b/test/COFF/imports-gnu-autoexport.s
new file mode 100644
index 0000000..8c204e1
--- /dev/null
+++ b/test/COFF/imports-gnu-autoexport.s
@@ -0,0 +1,25 @@
+# REQUIRES: x86
+#
+# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-head.s -filetype=obj -o %t-dabcdh.o
+# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-func.s -filetype=obj -o %t-dabcds00000.o
+# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-tail.s -filetype=obj -o %t-dabcdt.o
+# RUN: rm -f %t-implib.a
+# RUN: llvm-ar rcs %t-implib.a %t-dabcdh.o %t-dabcds00000.o %t-dabcdt.o
+# RUN: lld-link -lldmingw -dll -out:%t.dll -entry:main -subsystem:console \
+# RUN:   %p/Inputs/hello64.obj %p/Inputs/std64.lib %t-implib.a -include:func
+# RUN: llvm-readobj -coff-exports %t.dll | FileCheck -check-prefix=EXPORT %s
+
+# Check that only the single normal symbol was exported, none of the symbols
+# from the import library.
+
+EXPORT:      Export {
+EXPORT-NEXT:   Ordinal: 0
+EXPORT-NEXT:   Name:
+EXPORT-NEXT:   RVA: 0x0
+EXPORT-NEXT: }
+EXPORT-NEXT: Export {
+EXPORT-NEXT:   Ordinal: 1
+EXPORT-NEXT:   Name: main
+EXPORT-NEXT:   RVA: 0x1010
+EXPORT-NEXT: }
+EXPORT-NEXT-EMPTY:
diff --git a/test/COFF/imports-gnu-only.s b/test/COFF/imports-gnu-only.s
new file mode 100644
index 0000000..8483598
--- /dev/null
+++ b/test/COFF/imports-gnu-only.s
@@ -0,0 +1,28 @@
+# REQUIRES: x86
+#
+# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-head.s -filetype=obj -o %t-dabcdh.o
+# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-func.s -filetype=obj -o %t-dabcds00000.o
+# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-tail.s -filetype=obj -o %t-dabcdt.o
+# RUN: rm -f %t-implib.a
+# RUN: llvm-ar rcs %t-implib.a %t-dabcdh.o %t-dabcds00000.o %t-dabcdt.o
+# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj
+# RUN: lld-link -out:%t.exe -entry:main -subsystem:console \
+# RUN:   %t.obj %t-implib.a
+# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=DATA %s
+
+        .text
+        .global main
+main:
+        call func
+        ret
+
+# Check that the linker inserted the null terminating import descriptor,
+# even if there were no normal import libraries, only gnu ones.
+
+# DATA: Contents of section .rdata:
+# First import descriptor
+# DATA:  140002000 28200000 00000000 00000000 53200000
+# Last word from first import descriptor, null terminator descriptor
+# DATA:  140002010 38200000 00000000 00000000 00000000
+# Null terminator descriptor and import lookup table.
+# DATA:  140002020 00000000 00000000 48200000 00000000
diff --git a/test/COFF/imports-gnu.test b/test/COFF/imports-gnu.test
new file mode 100644
index 0000000..e56be2f
--- /dev/null
+++ b/test/COFF/imports-gnu.test
@@ -0,0 +1,29 @@
+# REQUIRES: x86
+# Verify that the lld can link to GNU import libs.
+#
+# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-head.s -filetype=obj -o %t-dabcdh.o
+# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-func.s -filetype=obj -o %t-dabcds00000.o
+# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-tail.s -filetype=obj -o %t-dabcdt.o
+# RUN: rm -f %t-implib.a
+# RUN: llvm-ar rcs %t-implib.a %t-dabcdh.o %t-dabcds00000.o %t-dabcdt.o
+# Not linking with -lldmingw; one can link to GNU import libs even if not targeting MinGW.
+# RUN: lld-link -out:%t.exe -entry:main -subsystem:console \
+# RUN:   %p/Inputs/hello64.obj %p/Inputs/std64.lib %t-implib.a -include:func
+# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s
+
+# Check that import entries from both libraries show up.
+
+IMPORT:      Import {
+IMPORT-NEXT:   Name: foo.dll
+IMPORT-NEXT:   ImportLookupTableRVA:
+IMPORT-NEXT:   ImportAddressTableRVA:
+IMPORT-NEXT:   Symbol: func (0)
+IMPORT-NEXT: }
+IMPORT-NEXT: Import {
+IMPORT-NEXT:   Name: std64.dll
+IMPORT-NEXT:   ImportLookupTableRVA:
+IMPORT-NEXT:   ImportAddressTableRVA:
+IMPORT-NEXT:   Symbol: ExitProcess (0)
+IMPORT-NEXT:   Symbol:  (50)
+IMPORT-NEXT:   Symbol: MessageBoxA (1)
+IMPORT-NEXT: }
diff --git a/test/COFF/invalid-debug-type.test b/test/COFF/invalid-debug-type.test
index 1026418..0fa40b0 100644
--- a/test/COFF/invalid-debug-type.test
+++ b/test/COFF/invalid-debug-type.test
@@ -1,5 +1,6 @@
 # RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj
 # RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj
 # RUN: lld-link /debug /debugtype:invalid /pdb:%t.pdb /dll /out:%t.dll /entry:main /nodefaultlib \
-# RUN:   %t1.obj %t2.obj
+# RUN:   %t1.obj %t2.obj 2>&1 | FileCheck %s
 
+# CHECK: /debugtype: unknown option: invalid
\ No newline at end of file
diff --git a/test/COFF/invalid-debug.test b/test/COFF/invalid-debug.test
new file mode 100644
index 0000000..67f794f
--- /dev/null
+++ b/test/COFF/invalid-debug.test
@@ -0,0 +1,6 @@
+# RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj
+# RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj
+# RUN: not lld-link /debug /debug:invalid /pdb:%t.pdb /dll /out:%t.dll /entry:main /nodefaultlib \
+# RUN:   %t1.obj %t2.obj 2>&1 | FileCheck %s
+
+# CHECK: /debug: unknown option: invalid
diff --git a/test/COFF/libname-mingw.test b/test/COFF/libname-mingw.test
new file mode 100644
index 0000000..171164f
--- /dev/null
+++ b/test/COFF/libname-mingw.test
@@ -0,0 +1,8 @@
+# RUN: mkdir -p %t/a
+# RUN: cp %p/Inputs/std64.lib %t/a/libstd64.a
+
+# RUN: lld-link /lldmingw /out:%t.exe /entry:main /verbose \
+# RUN:   /defaultlib:std64.lib /subsystem:console %p/Inputs/hello64.obj \
+# RUN:   /libpath:%t/a 2>&1 | FileCheck %s
+
+CHECK: a{{[/\\]}}libstd64.a
diff --git a/test/COFF/no-idata.s b/test/COFF/no-idata.s
new file mode 100644
index 0000000..d2f78d5
--- /dev/null
+++ b/test/COFF/no-idata.s
@@ -0,0 +1,20 @@
+# REQUIRES: x86
+#
+# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj
+# RUN: lld-link -out:%t.exe -entry:main -subsystem:console %t.obj
+# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=DUMP %s
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=DIRECTORY %s
+
+        .text
+        .global main
+main:
+        ret
+
+# Check that no .idata (.rdata) entries were added, no null terminator
+# for the import descriptor table.
+# DUMP: Contents of section .text:
+# DUMP-NEXT: 140001000 c3
+# DUMP-NEXT-EMPTY:
+
+# DIRECTORY: ImportTableRVA: 0x0
+# DIRECTORY: ImportTableSize: 0x0
diff --git a/test/COFF/pdb-debug-f.s b/test/COFF/pdb-debug-f.s
new file mode 100644
index 0000000..624c119
--- /dev/null
+++ b/test/COFF/pdb-debug-f.s
@@ -0,0 +1,28 @@
+# REQUIRES: x86
+# RUN: llvm-mc -triple=i386-pc-win32 -filetype=obj -o %t.obj %s
+# RUN: lld-link /subsystem:console /debug /nodefaultlib /entry:foo /out:%t.exe /pdb:%t.pdb %t.obj
+# RUN: llvm-pdbutil dump -fpo %t.pdb | FileCheck %s
+
+# CHECK:                         Old FPO Data
+# CHECK-NEXT: ============================================================
+# CHECK-NEXT:   RVA    | Code | Locals | Params | Prolog | Saved Regs | Use BP | Has SEH | Frame Type
+# CHECK-NEXT: 00001002 |    1 |      2 |      3 |      4 |          0 |  false |   false |       FPO
+
+.text
+_foo:
+ret
+
+.global _foo
+
+.section .debug$F,"dr"
+	.long _foo@IMGREL+2
+	.long 1 #  cbProc
+	.long 2 # cdwLocals;
+	.short 3 # cdwParams;
+	.short 4 # flags
+  # cbProlog : 8;
+  # cbRegs : 3;
+  # fHasSEH : 1;
+  # fUseBP : 1;
+  # reserved : 1;
+  # cbFrame : 2;
\ No newline at end of file
diff --git a/test/COFF/pdb-framedata.yaml b/test/COFF/pdb-framedata.yaml
new file mode 100644
index 0000000..fad042f
--- /dev/null
+++ b/test/COFF/pdb-framedata.yaml
@@ -0,0 +1,462 @@
+# // Compile with clang-cl -m32 /Z7 /GS- /c t.obj pdb-framedata.cpp
+#
+# int func(int x, int y) {
+#  return x + y;
+# }
+#
+# int main(int argc, char **argv) {
+#   return func(argc, argc+1);
+# }
+
+# RUN: yaml2obj %s -o %t.obj
+# RUN: lld-link %t.obj -debug -entry:main -nodefaultlib -debug -out:%t.exe -pdb:%t.pdb
+# RUN: llvm-pdbutil dump -fpo %t.pdb | FileCheck %s
+
+# CHECK:                         New FPO Data
+# CHECK-NEXT: ============================================================
+# CHECK-NEXT:   RVA    | Code | Locals | Params | Stack | Prolog | Saved Regs | Has SEH | Has C++EH | Start | Program
+# CHECK-NEXT: 00001000 |   31 |      0 |      8 |     0 |      6 |          0 |   false |     false | false | $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + =
+# CHECK-NEXT: 00001001 |   30 |      0 |      8 |     0 |      5 |          4 |   false |     false | false | $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ =
+# CHECK-NEXT: 00001003 |   28 |      0 |      8 |     0 |      3 |          4 |   false |     false | false | $T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ =
+# CHECK-NEXT: 00001020 |   53 |      0 |      8 |     0 |      7 |          0 |   false |     false | false | $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + =
+# CHECK-NEXT: 00001021 |   52 |      0 |      8 |     0 |      6 |          4 |   false |     false | false | $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ =
+# CHECK-NEXT: 00001023 |   50 |      0 |      8 |     0 |      4 |          4 |   false |     false | false | $T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ =
+# CHECK-NEXT: 00001024 |   49 |      0 |      8 |     0 |      3 |          8 |   false |     false | false | $T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $esi $T0 8 - ^ =
+
+
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_I386
+  Characteristics: [  ]
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       16
+    SectionData:     5589E583EC088B450C8B4D088B550803550C8945FC89D0894DF883C4085DC3905589E55683EC148B450C8B4D08C745F8000000008B550883C2018B7508893424895424048945F4894DF0E80000000083C4145E5DC3
+    Relocations:
+      - VirtualAddress:  75
+        SymbolName:      '?func@@YAHHH@Z'
+        Type:            IMAGE_REL_I386_REL32
+  - Name:            .data
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       4
+    SectionData:     ''
+  - Name:            .bss
+    Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       4
+    SectionData:     ''
+  - Name:            .drectve
+    Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
+    Alignment:       1
+    SectionData:     202F44454641554C544C49423A6C6962636D742E6C6962202F44454641554C544C49423A6F6C646E616D65732E6C6962
+  - Name:            '.debug$S'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    Subsections:
+      - !Symbols
+        Records:
+          - Kind:            S_COMPILE3
+            Compile3Sym:
+              Flags:           [  ]
+              Machine:         Pentium3
+              FrontendMajor:   8
+              FrontendMinor:   0
+              FrontendBuild:   0
+              FrontendQFE:     0
+              BackendMajor:    8000
+              BackendMinor:    0
+              BackendBuild:    0
+              BackendQFE:      0
+              Version:         'clang version 8.0.0 '
+      - !FrameData
+        Frames:
+          - CodeSize:        31
+            FrameFunc:       '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = '
+            LocalSize:       0
+            MaxStackSize:    0
+            ParamsSize:      8
+            PrologSize:      6
+            RvaStart:        0
+            SavedRegsSize:   0
+          - CodeSize:        30
+            FrameFunc:       '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
+            LocalSize:       0
+            MaxStackSize:    0
+            ParamsSize:      8
+            PrologSize:      5
+            RvaStart:        1
+            SavedRegsSize:   4
+          - CodeSize:        28
+            FrameFunc:       '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
+            LocalSize:       0
+            MaxStackSize:    0
+            ParamsSize:      8
+            PrologSize:      3
+            RvaStart:        3
+            SavedRegsSize:   4
+      - !Symbols
+        Records:
+          - Kind:            S_GPROC32_ID
+            ProcSym:
+              CodeSize:        31
+              DbgStart:        0
+              DbgEnd:          0
+              FunctionType:    4098
+              Flags:           [  ]
+              DisplayName:     func
+          - Kind:            S_LOCAL
+            LocalSym:
+              Type:            116
+              Flags:           [ IsParameter ]
+              VarName:         x
+          - Kind:            S_DEFRANGE_REGISTER_REL
+            DefRangeRegisterRelSym:
+              Register:        22
+              Flags:           0
+              BasePointerOffset: 8
+              Range:
+                OffsetStart:     12
+                ISectStart:      0
+                Range:           19
+              Gaps:
+          - Kind:            S_LOCAL
+            LocalSym:
+              Type:            116
+              Flags:           [ IsParameter ]
+              VarName:         y
+          - Kind:            S_DEFRANGE_REGISTER_REL
+            DefRangeRegisterRelSym:
+              Register:        22
+              Flags:           0
+              BasePointerOffset: 12
+              Range:
+                OffsetStart:     12
+                ISectStart:      0
+                Range:           19
+              Gaps:
+          - Kind:            S_PROC_ID_END
+            ScopeEndSym:
+      - !Lines
+        CodeSize:        31
+        Flags:           [  ]
+        RelocOffset:     0
+        RelocSegment:    0
+        Blocks:
+          - FileName:        'D:\src\llvmbuild\cl\Debug\x64\pdb-framedata.cpp'
+            Lines:
+              - Offset:          0
+                LineStart:       3
+                IsStatement:     false
+                EndDelta:        0
+              - Offset:          12
+                LineStart:       4
+                IsStatement:     false
+                EndDelta:        0
+            Columns:
+      - !FrameData
+        Frames:
+          - CodeSize:        53
+            FrameFunc:       '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = '
+            LocalSize:       0
+            MaxStackSize:    0
+            ParamsSize:      8
+            PrologSize:      7
+            RvaStart:        0
+            SavedRegsSize:   0
+          - CodeSize:        52
+            FrameFunc:       '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
+            LocalSize:       0
+            MaxStackSize:    0
+            ParamsSize:      8
+            PrologSize:      6
+            RvaStart:        1
+            SavedRegsSize:   4
+          - CodeSize:        50
+            FrameFunc:       '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = '
+            LocalSize:       0
+            MaxStackSize:    0
+            ParamsSize:      8
+            PrologSize:      4
+            RvaStart:        3
+            SavedRegsSize:   4
+          - CodeSize:        49
+            FrameFunc:       '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $esi $T0 8 - ^ = '
+            LocalSize:       0
+            MaxStackSize:    0
+            ParamsSize:      8
+            PrologSize:      3
+            RvaStart:        4
+            SavedRegsSize:   8
+      - !Symbols
+        Records:
+          - Kind:            S_GPROC32_ID
+            ProcSym:
+              CodeSize:        53
+              DbgStart:        0
+              DbgEnd:          0
+              FunctionType:    4102
+              Flags:           [  ]
+              DisplayName:     main
+          - Kind:            S_LOCAL
+            LocalSym:
+              Type:            116
+              Flags:           [ IsParameter ]
+              VarName:         argc
+          - Kind:            S_DEFRANGE_REGISTER_REL
+            DefRangeRegisterRelSym:
+              Register:        22
+              Flags:           0
+              BasePointerOffset: 8
+              Range:
+                OffsetStart:     52
+                ISectStart:      0
+                Range:           33
+              Gaps:
+          - Kind:            S_LOCAL
+            LocalSym:
+              Type:            4099
+              Flags:           [ IsParameter ]
+              VarName:         argv
+          - Kind:            S_DEFRANGE_REGISTER_REL
+            DefRangeRegisterRelSym:
+              Register:        22
+              Flags:           0
+              BasePointerOffset: 12
+              Range:
+                OffsetStart:     52
+                ISectStart:      0
+                Range:           33
+              Gaps:
+          - Kind:            S_PROC_ID_END
+            ScopeEndSym:
+      - !Lines
+        CodeSize:        53
+        Flags:           [  ]
+        RelocOffset:     0
+        RelocSegment:    0
+        Blocks:
+          - FileName:        'D:\src\llvmbuild\cl\Debug\x64\pdb-framedata.cpp'
+            Lines:
+              - Offset:          0
+                LineStart:       7
+                IsStatement:     false
+                EndDelta:        0
+              - Offset:          20
+                LineStart:       8
+                IsStatement:     false
+                EndDelta:        0
+            Columns:
+      - !FileChecksums
+        Checksums:
+          - FileName:        'D:\src\llvmbuild\cl\Debug\x64\pdb-framedata.cpp'
+            Kind:            MD5
+            Checksum:        A611B73E19B77B02646FAAF7CAEB025D
+      - !StringTable
+        Strings:
+          - 'D:\src\llvmbuild\cl\Debug\x64\pdb-framedata.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 - ^ = '
+          - '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $esi $T0 8 - ^ = '
+          - ''
+    Relocations:
+      - VirtualAddress:  68
+        SymbolName:      '?func@@YAHHH@Z'
+        Type:            IMAGE_REL_I386_DIR32NB
+      - VirtualAddress:  208
+        SymbolName:      '?func@@YAHHH@Z'
+        Type:            IMAGE_REL_I386_SECREL
+      - VirtualAddress:  212
+        SymbolName:      '?func@@YAHHH@Z'
+        Type:            IMAGE_REL_I386_SECTION
+      - VirtualAddress:  244
+        SymbolName:      .text
+        Type:            IMAGE_REL_I386_SECREL
+      - VirtualAddress:  248
+        SymbolName:      .text
+        Type:            IMAGE_REL_I386_SECTION
+      - VirtualAddress:  276
+        SymbolName:      .text
+        Type:            IMAGE_REL_I386_SECREL
+      - VirtualAddress:  280
+        SymbolName:      .text
+        Type:            IMAGE_REL_I386_SECTION
+      - VirtualAddress:  296
+        SymbolName:      '?func@@YAHHH@Z'
+        Type:            IMAGE_REL_I386_SECREL
+      - VirtualAddress:  300
+        SymbolName:      '?func@@YAHHH@Z'
+        Type:            IMAGE_REL_I386_SECTION
+      - VirtualAddress:  344
+        SymbolName:      _main
+        Type:            IMAGE_REL_I386_DIR32NB
+      - VirtualAddress:  516
+        SymbolName:      _main
+        Type:            IMAGE_REL_I386_SECREL
+      - VirtualAddress:  520
+        SymbolName:      _main
+        Type:            IMAGE_REL_I386_SECTION
+      - VirtualAddress:  555
+        SymbolName:      .text
+        Type:            IMAGE_REL_I386_SECREL
+      - VirtualAddress:  559
+        SymbolName:      .text
+        Type:            IMAGE_REL_I386_SECTION
+      - VirtualAddress:  590
+        SymbolName:      .text
+        Type:            IMAGE_REL_I386_SECREL
+      - VirtualAddress:  594
+        SymbolName:      .text
+        Type:            IMAGE_REL_I386_SECTION
+      - VirtualAddress:  612
+        SymbolName:      _main
+        Type:            IMAGE_REL_I386_SECREL
+      - VirtualAddress:  616
+        SymbolName:      _main
+        Type:            IMAGE_REL_I386_SECTION
+  - Name:            '.debug$T'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    Types:
+      - Kind:            LF_ARGLIST
+        ArgList:
+          ArgIndices:      [ 116, 116 ]
+      - Kind:            LF_PROCEDURE
+        Procedure:
+          ReturnType:      116
+          CallConv:        NearC
+          Options:         [ None ]
+          ParameterCount:  2
+          ArgumentList:    4096
+      - Kind:            LF_FUNC_ID
+        FuncId:
+          ParentScope:     0
+          FunctionType:    4097
+          Name:            func
+      - Kind:            LF_POINTER
+        Pointer:
+          ReferentType:    1136
+          Attrs:           32778
+      - Kind:            LF_ARGLIST
+        ArgList:
+          ArgIndices:      [ 116, 4099 ]
+      - Kind:            LF_PROCEDURE
+        Procedure:
+          ReturnType:      116
+          CallConv:        NearC
+          Options:         [ None ]
+          ParameterCount:  2
+          ArgumentList:    4100
+      - Kind:            LF_FUNC_ID
+        FuncId:
+          ParentScope:     0
+          FunctionType:    4101
+          Name:            main
+  - Name:            .llvm_addrsig
+    Characteristics: [ IMAGE_SCN_LNK_REMOVE ]
+    Alignment:       1
+    SectionData:     0F
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          85
+      NumberOfRelocations: 1
+      NumberOfLinenumbers: 0
+      CheckSum:        1989857796
+      Number:          1
+  - Name:            .data
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          0
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          2
+  - Name:            .bss
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          0
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          3
+  - Name:            .drectve
+    Value:           0
+    SectionNumber:   4
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          48
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        149686238
+      Number:          4
+  - Name:            '.debug$S'
+    Value:           0
+    SectionNumber:   5
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          988
+      NumberOfRelocations: 18
+      NumberOfLinenumbers: 0
+      CheckSum:        2571438511
+      Number:          5
+  - Name:            '.debug$T'
+    Value:           0
+    SectionNumber:   6
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          120
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        3148269371
+      Number:          6
+  - Name:            .llvm_addrsig
+    Value:           0
+    SectionNumber:   7
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          1
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        2428444049
+      Number:          7
+  - Name:            '@feat.00'
+    Value:           1
+    SectionNumber:   -1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            '?func@@YAHHH@Z'
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            _main
+    Value:           32
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/test/COFF/pdb-global-hashes.test b/test/COFF/pdb-global-hashes.test
index 238613c..0ca6005 100644
--- a/test/COFF/pdb-global-hashes.test
+++ b/test/COFF/pdb-global-hashes.test
@@ -4,9 +4,9 @@
 RUN: lld-link /debug %t.1.obj %t.2.obj /entry:main /nodefaultlib /PDB:%t.nohash.pdb
 RUN: lld-link /debug:ghash %t.1.obj %t.2.obj /entry:main /nodefaultlib /PDB:%t.hash.pdb
 RUN: lld-link /debug:ghash %t.1.obj %t.2.missing.obj /entry:main /nodefaultlib /PDB:%t.mixed.pdb
-RUN: llvm-pdbutil dump -types -ids %t.nohash.pdb | FileCheck %s
-RUN: llvm-pdbutil dump -types -ids %t.hash.pdb | FileCheck %s
-RUN: llvm-pdbutil dump -types -ids %t.mixed.pdb | FileCheck %s
+RUN: llvm-pdbutil dump -types -ids -dont-resolve-forward-refs %t.nohash.pdb | FileCheck %s
+RUN: llvm-pdbutil dump -types -ids -dont-resolve-forward-refs %t.hash.pdb | FileCheck %s
+RUN: llvm-pdbutil dump -types -ids -dont-resolve-forward-refs %t.mixed.pdb | FileCheck %s
 
 ; These object files were generated via the following inputs and commands:
 ; ----------------------------------------------
diff --git a/test/COFF/pdb-heapsite.yaml b/test/COFF/pdb-heapsite.yaml
index bfdd7b4..966ae42 100644
--- a/test/COFF/pdb-heapsite.yaml
+++ b/test/COFF/pdb-heapsite.yaml
@@ -69,7 +69,7 @@
             RegRelativeSym:
               Offset:          8
               Type:            35
-              Register:        CVRegRSP
+              Register:        RSP
               VarName:         __formal
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
diff --git a/test/COFF/pdb-linker-module.test b/test/COFF/pdb-linker-module.test
index 022a447..70d17c5 100644
--- a/test/COFF/pdb-linker-module.test
+++ b/test/COFF/pdb-linker-module.test
@@ -5,7 +5,7 @@
 
 MODS:      Mod 0001 | `* Linker *`
 MODS-NEXT:             Obj: ``:
-MODS-NEXT:             debug stream: 12, # files: 0, has ec info: false
+MODS-NEXT:             debug stream: 13, # files: 0, has ec info: false
 MODS-NEXT:             pdb file ni: 1 `{{.*}}pdb-linker-module.test.tmp.pdb`, src file ni: 0 ``
 
 SYMS:      Mod 0001 | `* Linker *`
diff --git a/test/COFF/pdb-options.test b/test/COFF/pdb-options.test
index 2bd1d92..f0edc2f 100644
--- a/test/COFF/pdb-options.test
+++ b/test/COFF/pdb-options.test
@@ -6,6 +6,11 @@
 # RUN: lld-link /pdb:%t.pdb /entry:main /nodefaultlib %t1.obj %t2.obj
 # RUN: not ls %t.pdb
 
+; If /DEBUG:NONE is specified after /DEBUG, /pdb is ignored.
+# RUN: rm -f %t.pdb
+# RUN: lld-link /DEBUG /pdb:%t.pdb /DEBUG:NONE /entry:main /nodefaultlib %t1.obj %t2.obj
+# RUN: not ls %t.pdb
+
 ; If /DEBUG and /pdb are specified, it uses the specified name.
 # RUN: lld-link /DEBUG /pdb:%t.pdb /entry:main /nodefaultlib %t1.obj %t2.obj
 # RUN: ls %t.pdb
diff --git a/test/COFF/pdb-procid-remapping.test b/test/COFF/pdb-procid-remapping.test
index e42616d..d9b4faa 100644
--- a/test/COFF/pdb-procid-remapping.test
+++ b/test/COFF/pdb-procid-remapping.test
@@ -14,6 +14,7 @@
 CHECK-NEXT:          136 | S_FRAMEPROC [size = 32]
 CHECK-NEXT:                size = 40, padding size = 0, offset to padding = 0
 CHECK-NEXT:                bytes of callee saved registers = 0, exception handler addr = 0000:0000
+CHECK-NEXT:                local fp reg = NONE, param fp reg = NONE
 CHECK-NEXT:                flags = has async eh | opt speed
 CHECK-NEXT:          168 | S_END [size = 4]
 CHECK-LABEL:    Mod 0001 |
@@ -23,6 +24,7 @@
 CHECK-NEXT:          136 | S_FRAMEPROC [size = 32]
 CHECK-NEXT:                size = 0, padding size = 0, offset to padding = 0
 CHECK-NEXT:                bytes of callee saved registers = 0, exception handler addr = 0000:0000
+CHECK-NEXT:                local fp reg = NONE, param fp reg = NONE
 CHECK-NEXT:                flags = has async eh | opt speed
 CHECK-NEXT:          168 | S_END [size = 4]
 CHECK-LABEL:    Mod 0002 |
diff --git a/test/COFF/pdb-relative-source-lines.test b/test/COFF/pdb-relative-source-lines.test
index 8c0894c..8931828 100644
--- a/test/COFF/pdb-relative-source-lines.test
+++ b/test/COFF/pdb-relative-source-lines.test
@@ -17,14 +17,26 @@
 
 $ clang-cl -Xclang -fdebug-compilation-dir -Xclang . -c -Z7 pdb_lines*.c
 
-RUN: yaml2obj %S/Inputs/pdb_lines_1_relative.yaml -o %t.pdb_lines_1_relative.obj
-RUN: yaml2obj %S/Inputs/pdb_lines_2_relative.yaml -o %t.pdb_lines_2_relative.obj
-RUN: rm -f %t.exe %t.pdb
-RUN: lld-link -debug -pdbsourcepath:c:\\src -entry:main -nodefaultlib -out:%t.exe -pdb:%t.pdb %t.pdb_lines_1_relative.obj %t.pdb_lines_2_relative.obj
-RUN: llvm-pdbutil pdb2yaml -modules -module-files -subsections=lines,fc %t.pdb | FileCheck %s
+/pdbsourcepath: only sets the directory that relative paths are considered
+relative to, so this test needs to pass relative paths to lld-link for:
+1. The input obj files
+2. The /pdb: switch
+3. The lld-link invocation itself
+To achieve this, put all inputs of the lld-link invocation (including lld-link
+itself) in a temp directory that's cwd and then make sure to only use relative
+arguments when calling ./lld-link below.
+RUN: rm -rf %t
+RUN: mkdir %t
+RUN: cp lld-link %t/lld-link
+RUN: cd %t
 
-CHECK-LABEL:  - Module:          {{.*}}pdb_lines_1_relative.obj
-CHECK-NEXT:     ObjFile:         {{.*}}pdb_lines_1_relative.obj
+RUN: yaml2obj %S/Inputs/pdb_lines_1_relative.yaml -o %t/pdb_lines_1_relative.obj
+RUN: yaml2obj %S/Inputs/pdb_lines_2_relative.yaml -o %t/pdb_lines_2_relative.obj
+RUN: ./lld-link -debug "-pdbsourcepath:c:\src" -entry:main -nodefaultlib -out:out.exe -pdb:out.pdb pdb_lines_1_relative.obj pdb_lines_2_relative.obj
+RUN: llvm-pdbutil pdb2yaml -modules -module-files -module-syms -subsections=lines,fc %t/out.pdb | FileCheck %s
+
+CHECK-LABEL:  - Module:          'c:\src\pdb_lines_1_relative.obj'
+CHECK-NEXT:     ObjFile:         'c:\src\pdb_lines_1_relative.obj'
 CHECK:          SourceFiles:
 CHECK-NEXT:       - 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_1.c'
 CHECK-NEXT:       - 'c:{{[\\/]}}src{{[\\/]}}foo.h'
@@ -35,11 +47,23 @@
 CHECK:                - FileName:        'c:{{[\\/]}}src{{[\\/]}}pdb_lines_1.c'
 CHECK:                - FileName:        'c:{{[\\/]}}src{{[\\/]}}foo.h'
 
-CHECK-LABEL:  - Module:          {{.*}}pdb_lines_2_relative.obj
-CHECK-NEXT:     ObjFile:         {{.*}}pdb_lines_2_relative.obj
+CHECK-LABEL:  - Module:          'c:\src\pdb_lines_2_relative.obj'
+CHECK-NEXT:     ObjFile:         'c:\src\pdb_lines_2_relative.obj'
 CHECK:          SourceFiles:
 CHECK-NEXT:       - 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_2.c'
 CHECK:          Subsections:
 CHECK:                - FileName:        'c:{{[\\/]}}src{{[\\/]}}pdb_lines_2.c'
 CHECK:            - !FileChecksums
 CHECK:                - FileName:        'c:{{[\\/]}}src{{[\\/]}}pdb_lines_2.c'
+
+CHECK-LABEL:  - Kind:            S_ENVBLOCK
+CHECK-NEXT:     EnvBlockSym:     
+CHECK-NEXT:       Entries:     
+CHECK-NEXT:         - cwd
+CHECK-NEXT:         - 'c:\src'
+CHECK-NEXT:         - exe
+CHECK-NEXT:         - 'c:\src\lld-link'
+CHECK-NEXT:         - pdb 
+CHECK-NEXT:         - 'c:\src\out.pdb'
+CHECK-NEXT:         - cmd
+CHECK-NEXT:         - '-debug -pdbsourcepath:c:\src -entry:main -nodefaultlib -out:out.exe -pdb:out.pdb pdb_lines_1_relative.obj pdb_lines_2_relative.obj'
diff --git a/test/COFF/pdb-thunk.yaml b/test/COFF/pdb-thunk.yaml
index 444800f..6435a17 100644
--- a/test/COFF/pdb-thunk.yaml
+++ b/test/COFF/pdb-thunk.yaml
@@ -84,7 +84,7 @@
             RegRelativeSym:
               Offset:          8
               Type:            4097
-              Register:        CVRegRSP
+              Register:        RSP
               VarName:         this
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
@@ -124,7 +124,7 @@
             RegRelativeSym:
               Offset:          8
               Type:            4121
-              Register:        CVRegRSP
+              Register:        RSP
               VarName:         this
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
@@ -164,7 +164,7 @@
             RegRelativeSym:
               Offset:          48
               Type:            4143
-              Register:        CVRegRSP
+              Register:        RSP
               VarName:         this
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
@@ -208,7 +208,7 @@
             RegRelativeSym:
               Offset:          8
               Type:            4143
-              Register:        CVRegRSP
+              Register:        RSP
               VarName:         this
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
@@ -2176,7 +2176,7 @@
             RegRelativeSym:
               Offset:          8
               Type:            4097
-              Register:        CVRegRSP
+              Register:        RSP
               VarName:         this
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
@@ -2222,7 +2222,7 @@
             RegRelativeSym:
               Offset:          8
               Type:            4121
-              Register:        CVRegRSP
+              Register:        RSP
               VarName:         this
           - Kind:            S_PROC_ID_END
             ScopeEndSym:
diff --git a/test/COFF/pdb-type-server-invalid-signature.yaml b/test/COFF/pdb-type-server-invalid-signature.yaml
new file mode 100644
index 0000000..247e000
--- /dev/null
+++ b/test/COFF/pdb-type-server-invalid-signature.yaml
@@ -0,0 +1,140 @@
+
+# RUN: cd %S/Inputs
+# RUN: yaml2obj %s -o %t.obj
+# RUN: lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s
+# RUN: cd %S
+
+# CHECK: warning: Cannot use debug info for {{.*}}.obj
+# CHECK-NEXT: The signature does not match; the file(s) might be out of date
+
+# Also test a valid match
+
+# RUN: cd %S/Inputs
+# RUN: yaml2obj %S/Inputs/pdb-type-server-valid-signature.yaml -o %t2.obj
+# RUN: lld-link %t2.obj -out:%t2.exe -debug -pdb:%t2.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s -check-prefix=VALID-SIGNATURE -allow-empty
+# RUN: cd %S
+
+# VALID-SIGNATURE-NOT: warning: Cannot use debug info for {{.*}}.obj
+# VALID-SIGNATURE-NOT: The signature does not match; the file(s) might be out of date
+
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [  ]
+sections:
+  - Name:            '.debug$S'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    Subsections:
+      - !Symbols
+        Records:
+          - Kind:            S_GPROC32_ID
+            ProcSym:
+              CodeSize:        3
+              DbgStart:        0
+              DbgEnd:          2
+              FunctionType:    4199
+              Flags:           [  ]
+              DisplayName:     main
+          - Kind:            S_FRAMEPROC
+            FrameProcSym:
+              TotalFrameBytes: 0
+              PaddingFrameBytes: 0
+              OffsetToPadding: 0
+              BytesOfCalleeSavedRegisters: 0
+              OffsetOfExceptionHandler: 0
+              SectionIdOfExceptionHandler: 0
+              Flags:           [ AsynchronousExceptionHandling, OptimizedForSpeed ]
+          - Kind:            S_PROC_ID_END
+            ScopeEndSym:
+      - !Lines
+        CodeSize:        3
+        Flags:           [  ]
+        RelocOffset:     0
+        RelocSegment:    0
+        Blocks:
+          - FileName:        'c:\src\llvm-project\build\t.c'
+            Lines:
+              - Offset:          0
+                LineStart:       1
+                IsStatement:     true
+                EndDelta:        0
+            Columns:
+      - !FileChecksums
+        Checksums:
+          - FileName:        'c:\src\llvm-project\build\t.c'
+            Kind:            MD5
+            Checksum:        270A878DCC1B845655B162F56C4F5020
+      - !StringTable
+        Strings:
+          - 'c:\src\llvm-project\build\t.c'
+    Relocations:
+      - VirtualAddress:  44
+        SymbolName:      main
+        Type:            IMAGE_REL_AMD64_SECREL
+      - VirtualAddress:  48
+        SymbolName:      main
+        Type:            IMAGE_REL_AMD64_SECTION
+      - VirtualAddress:  100
+        SymbolName:      main
+        Type:            IMAGE_REL_AMD64_SECREL
+      - VirtualAddress:  104
+        SymbolName:      main
+        Type:            IMAGE_REL_AMD64_SECTION
+  - Name:            '.debug$T'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    Types:
+      - Kind:            LF_TYPESERVER2
+        TypeServer2:
+          Guid:            '{01DF191B-22BF-6B42-96CE-5258B8329FE5}'
+          Age:             18
+          Name:            'pdb-diff-cl.pdb'
+  - Name:            '.text$mn'
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       16
+    SectionData:     33C0C3
+symbols:
+  - Name:            '.debug$S'
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          328
+      NumberOfRelocations: 4
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            '.debug$T'
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          564
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            '.text$mn'
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          3
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        4021952397
+      Number:          0
+  - Name:            main
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/test/COFF/pdb-type-server-missing.yaml b/test/COFF/pdb-type-server-missing.yaml
index fbbb46f..7766a48 100644
--- a/test/COFF/pdb-type-server-missing.yaml
+++ b/test/COFF/pdb-type-server-missing.yaml
@@ -1,10 +1,16 @@
 # This is an object compiled with /Zi (see the LF_TYPESERVER2 record) without an
 # adjacent type server PDB. Test that LLD fails gracefully on it.
+# Also try linking another OBJ with a reference to the same PDB
 
-# RUN: yaml2obj %s -o %t.obj
-# RUN: lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s
+# RUN: yaml2obj %s -o %t1.obj
+# RUN: yaml2obj %p/Inputs/pdb-type-server-missing-2.yaml -o %t2.obj
+# RUN: lld-link %t1.obj %t2.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s
 
-# CHECK: warning: Type server PDB for {{.*}}.obj is invalid, ignoring debug info.
+# CHECK: warning: Cannot use debug info for {{.*}}.obj
+# CHECK-NEXT: {{N|n}}o such file or directory
+
+# CHECK: warning: Cannot use debug info for {{.*}}.obj
+# CHECK-NEXT: {{N|n}}o such file or directory
 
 --- !COFF
 header:
diff --git a/test/COFF/pdb-type-server-native-errors.yaml b/test/COFF/pdb-type-server-native-errors.yaml
new file mode 100644
index 0000000..bc86541
--- /dev/null
+++ b/test/COFF/pdb-type-server-native-errors.yaml
@@ -0,0 +1,130 @@
+
+# RUN: cd %S/Inputs
+# RUN: yaml2obj %s -o %t.obj
+# RUN: lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s
+# RUN: cd %S
+
+# CHECK: warning: Cannot use debug info for {{.*}}.obj
+# CHECK-NEXT: The PDB file is corrupt. MSF superblock is missing
+
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [  ]
+sections:
+  - Name:            '.debug$S'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    Subsections:
+      - !Symbols
+        Records:
+          - Kind:            S_GPROC32_ID
+            ProcSym:
+              CodeSize:        3
+              DbgStart:        0
+              DbgEnd:          2
+              FunctionType:    4199
+              Flags:           [  ]
+              DisplayName:     main
+          - Kind:            S_FRAMEPROC
+            FrameProcSym:
+              TotalFrameBytes: 0
+              PaddingFrameBytes: 0
+              OffsetToPadding: 0
+              BytesOfCalleeSavedRegisters: 0
+              OffsetOfExceptionHandler: 0
+              SectionIdOfExceptionHandler: 0
+              Flags:           [ AsynchronousExceptionHandling, OptimizedForSpeed ]
+          - Kind:            S_PROC_ID_END
+            ScopeEndSym:
+      - !Lines
+        CodeSize:        3
+        Flags:           [  ]
+        RelocOffset:     0
+        RelocSegment:    0
+        Blocks:
+          - FileName:        'c:\src\llvm-project\build\t.c'
+            Lines:
+              - Offset:          0
+                LineStart:       1
+                IsStatement:     true
+                EndDelta:        0
+            Columns:
+      - !FileChecksums
+        Checksums:
+          - FileName:        'c:\src\llvm-project\build\t.c'
+            Kind:            MD5
+            Checksum:        270A878DCC1B845655B162F56C4F5020
+      - !StringTable
+        Strings:
+          - 'c:\src\llvm-project\build\t.c'
+    Relocations:
+      - VirtualAddress:  44
+        SymbolName:      main
+        Type:            IMAGE_REL_AMD64_SECREL
+      - VirtualAddress:  48
+        SymbolName:      main
+        Type:            IMAGE_REL_AMD64_SECTION
+      - VirtualAddress:  100
+        SymbolName:      main
+        Type:            IMAGE_REL_AMD64_SECREL
+      - VirtualAddress:  104
+        SymbolName:      main
+        Type:            IMAGE_REL_AMD64_SECTION
+  - Name:            '.debug$T'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    Types:
+      - Kind:            LF_TYPESERVER2
+        TypeServer2:
+          Guid:            '{01DF191B-22BF-6B42-96CE-5258B8329FE5}'
+          Age:             18
+          Name:            'bad-block-size.pdb'
+  - Name:            '.text$mn'
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       16
+    SectionData:     33C0C3
+symbols:
+  - Name:            '.debug$S'
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          328
+      NumberOfRelocations: 4
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            '.debug$T'
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          564
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            '.text$mn'
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          3
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        4021952397
+      Number:          0
+  - Name:            main
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/test/COFF/pdb-type-server-simple.test b/test/COFF/pdb-type-server-simple.test
index 51a92db..cae32af 100644
--- a/test/COFF/pdb-type-server-simple.test
+++ b/test/COFF/pdb-type-server-simple.test
@@ -89,7 +89,7 @@
 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 = CVRegRSP, offset = 8
+CHECK:            type = [[FOO_PTR]] (Foo*), register = RSP, 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 a7b2a21..5788b51 100644
--- a/test/COFF/pdb.test
+++ b/test/COFF/pdb.test
@@ -193,25 +193,6 @@
 RAW-NEXT:        0 | S_PUB32 [size = 20] `foo`
 RAW-NEXT:            flags = function, addr = 0001:0016
 RAW-NOT:             S_PUB32
-RAW-NEXT:     Hash Bitmap (
-RAW-NEXT:     0000: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
-RAW-NEXT:     0020: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
-RAW-NEXT:     0040: 00000000 20000000 00000000 00000000 00000000 00000000 00000000 00000000  |.... ...........................|
-RAW-NEXT:     0060: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
-RAW-NEXT:     0080: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
-RAW-NEXT:     00A0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
-RAW-NEXT:     00C0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
-RAW-NEXT:     00E0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
-RAW-NEXT:     0100: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
-RAW-NEXT:     0120: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
-RAW-NEXT:     0140: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
-RAW-NEXT:     0160: 01000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
-RAW-NEXT:     0180: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
-RAW-NEXT:     01A0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
-RAW-NEXT:     01C0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
-RAW-NEXT:     01E0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
-RAW-NEXT:     0200: 00000000                                                                 |....|
-RAW-NEXT:   )
 RAW-NEXT:   Hash Entries
 RAW-NEXT:     off = 21, refcnt = 1
 RAW-NEXT:     off = 1, refcnt = 1
diff --git a/test/COFF/pdbaltpath.test b/test/COFF/pdbaltpath.test
new file mode 100644
index 0000000..952e208
--- /dev/null
+++ b/test/COFF/pdbaltpath.test
@@ -0,0 +1,39 @@
+# RUN: yaml2obj %p/Inputs/empty.yaml > %t.obj
+
+# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:hello.pdb
+# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix HELLO %s
+# HELLO:       PDBFileName: hello.pdb
+
+# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:%_Pdb%
+# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix PDBVAR %s
+# PDBVAR:       PDBFileName: pdbaltpath.test.tmp.pdb
+
+# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:foo%_ExT%.pdb
+# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix EXTVAR %s
+# EXTVAR:       PDBFileName: fooexe.pdb
+
+# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:%_PDB
+# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix NOCLOSE %s
+# NOCLOSE:       PDBFileName: %_PDB
+
+# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:foo%_PDB
+# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix NOCLOSE2 %s
+# NOCLOSE2:       PDBFileName: foo%_PDB
+
+# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:foo%_PDB%bar%_EXT
+# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix CLOSEONE %s
+# CLOSEONE:       PDBFileName: foopdbaltpath.test.tmp.pdbbar%_EXT
+
+# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:foo%_PDB%bar%_EXT%
+# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix CLOSETWO %s
+# CLOSETWO:       PDBFileName: foopdbaltpath.test.tmp.pdbbarexe
+
+# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:foo%_PDB%bar%_EXT%a
+# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix CLOSETWO2 %s
+# CLOSETWO2:       PDBFileName: foopdbaltpath.test.tmp.pdbbarexea
+
+# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:foo%FoO%bar%r%a 2>&1 | FileCheck --check-prefix UNKNOWN-WARN %s
+# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix ENVVARS %s
+# UNKNOWN-WARN: only %_PDB% and %_EXT% supported in /pdbaltpath:, keeping %FoO% as literal
+# UNKNOWN-WARN: only %_PDB% and %_EXT% supported in /pdbaltpath:, keeping %r% as literal
+# ENVVARS:       PDBFileName: foo%FoO%bar%r%a
diff --git a/test/COFF/rsds.test b/test/COFF/rsds.test
index 6ce92a9..76bd018 100644
--- a/test/COFF/rsds.test
+++ b/test/COFF/rsds.test
@@ -1,9 +1,9 @@
 # RUN: yaml2obj %s > %t.obj
 
 # RUN: rm -f %t.dll %t.pdb
-# RUN: lld-link /debug /pdbaltpath:test1.pdb /dll /out:%t.dll /entry:DllMain %t.obj
+# RUN: lld-link /debug /pdbaltpath:test.pdb /dll /out:%t.dll /entry:DllMain %t.obj
 # RUN: llvm-readobj -coff-debug-directory %t.dll > %t.1.txt
-# RUN: lld-link /debug /pdbaltpath:test2.pdb /dll /out:%t.dll /entry:DllMain %t.obj
+# RUN: lld-link /debug /pdbaltpath:test.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
 
@@ -12,7 +12,15 @@
 # RUN: llvm-readobj -coff-debug-directory %t.dll > %t.3.txt
 # 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
+# RUN: cat %t.3.txt %t.4.txt | FileCheck --check-prefix TWOPDBS %s
+
+# RUN: rm -f %t.dll %t.pdb
+# RUN: lld-link /Brepro /dll /out:%t.dll /entry:DllMain %t.obj
+# RUN: llvm-readobj -coff-debug-directory %t.dll | FileCheck --check-prefix REPRO %s
+
+# RUN: rm -f %t.dll %t.pdb
+# RUN: lld-link /Brepro /debug /dll /out:%t.dll /entry:DllMain %t.obj
+# RUN: llvm-readobj -coff-debug-directory %t.dll | FileCheck --check-prefix REPRODEBUG %s
 
 # CHECK: File: [[FILE:.*]].dll
 # CHECK: DebugDirectory [
@@ -29,7 +37,7 @@
 # CHECK:       PDBSignature: 0x53445352
 # CHECK:       PDBGUID: [[GUID:\(([A-Za-z0-9]{2} ?){16}\)]]
 # CHECK:       PDBAge: 1
-# CHECK:       PDBFileName: {{.*}}1.pdb
+# CHECK:       PDBFileName: {{.*}}.pdb
 # CHECK:     }
 # CHECK:   }
 # CHECK: ]
@@ -47,12 +55,94 @@
 # CHECK:     PDBInfo {
 # CHECK:       PDBSignature: 0x53445352
 # CHECK:       PDBGUID: [[GUID]]
-# CHECK:       PDBAge: 2
-# CHECK:       PDBFileName: {{.*}}2.pdb
+# CHECK:       PDBAge: 1
+# CHECK:       PDBFileName: {{.*}}.pdb
 # CHECK:     }
 # CHECK:   }
 # CHECK: ]
 
+# TWOPDBS: File: [[FILE:.*]].dll
+# TWOPDBS: DebugDirectory [
+# TWOPDBS:   DebugEntry {
+# TWOPDBS:     Characteristics: 0x0
+# TWOPDBS:     TimeDateStamp: 
+# TWOPDBS:     MajorVersion: 0x0
+# TWOPDBS:     MinorVersion: 0x0
+# TWOPDBS:     Type: CodeView (0x2)
+# TWOPDBS:     SizeOfData: 0x{{[^0]}}
+# TWOPDBS:     AddressOfRawData: 0x{{[^0]}}
+# TWOPDBS:     PointerToRawData: 0x{{[^0]}}
+# TWOPDBS:     PDBInfo {
+# TWOPDBS:       PDBSignature: 0x53445352
+# TWOPDBS:       PDBGUID: [[GUID:\(([A-Za-z0-9]{2} ?){16}\)]]
+# TWOPDBS:       PDBAge: 1
+# TWOPDBS:       PDBFileName: {{.*}}.pdb
+# TWOPDBS:     }
+# TWOPDBS:   }
+# TWOPDBS: ]
+# TWOPDBS: File: [[FILE]].dll
+# TWOPDBS: DebugDirectory [
+# TWOPDBS:   DebugEntry {
+# TWOPDBS:     Characteristics: 0x0
+# TWOPDBS:     TimeDateStamp: 
+# TWOPDBS:     MajorVersion: 0x0
+# TWOPDBS:     MinorVersion: 0x0
+# TWOPDBS:     Type: CodeView (0x2)
+# TWOPDBS:     SizeOfData: 0x{{[^0]}}
+# TWOPDBS:     AddressOfRawData: 0x{{[^0]}}
+# TWOPDBS:     PointerToRawData: 0x{{[^0]}}
+# TWOPDBS:     PDBInfo {
+# TWOPDBS:       PDBSignature: 0x53445352
+# TWOPDBS-NOT:       PDBGUID: [[GUID]]
+# TWOPDBS:       PDBAge: 1
+# TWOPDBS:       PDBFileName: {{.*}}.pdb
+# TWOPDBS:     }
+# TWOPDBS:   }
+# TWOPDBS: ]
+
+# REPRO: File: {{.*}}.dll
+# REPRO: DebugDirectory [
+# REPRO:   DebugEntry {
+# REPRO:     Characteristics: 0x0
+# REPRO:     TimeDateStamp: 
+# REPRO:     MajorVersion: 0x0
+# REPRO:     MinorVersion: 0x0
+# REPRO:     Type: Repro (0x10)
+# REPRO:     SizeOfData: 0x0
+# REPRO:     AddressOfRawData: 0x0
+# REPRO:     PointerToRawData: 0x0
+# REPRO:   }
+# REPRO: ]
+
+# REPRODEBUG: File: {{.*}}.dll
+# REPRODEBUG: DebugDirectory [
+# REPRODEBUG:   DebugEntry {
+# REPRODEBUG:     Characteristics: 0x0
+# REPRODEBUG:     TimeDateStamp: 
+# REPRODEBUG:     MajorVersion: 0x0
+# REPRODEBUG:     MinorVersion: 0x0
+# REPRODEBUG:     Type: CodeView (0x2)
+# REPRODEBUG:     SizeOfData: 0x{{[^0]}}
+# REPRODEBUG:     AddressOfRawData: 0x{{[^0]}}
+# REPRODEBUG:     PointerToRawData: 0x{{[^0]}}
+# REPRODEBUG:     PDBInfo {
+# REPRODEBUG:       PDBSignature: 0x53445352
+# REPRODEBUG:       PDBGUID: 
+# REPRODEBUG:       PDBAge: 1
+# REPRODEBUG:       PDBFileName:
+# REPRODEBUG:     }
+# REPRODEBUG:   }
+# REPRODEBUG:   DebugEntry {
+# REPRODEBUG:     Characteristics: 0x0
+# REPRODEBUG:     TimeDateStamp: 
+# REPRODEBUG:     MajorVersion: 0x0
+# REPRODEBUG:     MinorVersion: 0x0
+# REPRODEBUG:     Type: Repro (0x10)
+# REPRODEBUG:     SizeOfData: 0x0
+# REPRODEBUG:     AddressOfRawData: 0x0
+# REPRODEBUG:     PointerToRawData: 0x0
+# REPRODEBUG:   }
+# REPRODEBUG: ]
 --- !COFF
 header:
   Machine:         IMAGE_FILE_MACHINE_I386
diff --git a/test/COFF/subsystem-inference-mingw.s b/test/COFF/subsystem-inference-mingw.s
new file mode 100644
index 0000000..3339e64
--- /dev/null
+++ b/test/COFF/subsystem-inference-mingw.s
@@ -0,0 +1,17 @@
+# REQUIRES: x86
+# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.o
+
+# RUN: lld-link -lldmingw %t.o -out:%t.exe
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
+
+# CHECK: AddressOfEntryPoint: 0x1001
+# CHECK: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI (0x3)
+
+        .text
+        .globl foo
+        .globl mainCRTStartup
+foo:
+        ret
+mainCRTStartup:
+        call foo
+        ret
diff --git a/test/COFF/subsystem-inference2.test b/test/COFF/subsystem-inference2.test
new file mode 100644
index 0000000..0c159a7
--- /dev/null
+++ b/test/COFF/subsystem-inference2.test
@@ -0,0 +1,54 @@
+# RUN: yaml2obj %s > %t.obj
+# RUN: lld-link /out:%t.exe %t.obj 2>&1 | FileCheck -check-prefix=WARN %s
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
+
+# WARN: warning: found main and WinMain; defaulting to /subsystem:console
+# CHECK:     Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
+
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: []
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     B82A000000C3
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          6
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            main
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            WinMain
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            mainCRTStartup
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            WinMainCRTStartup
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/test/COFF/thinlto-archives.ll b/test/COFF/thinlto-archives.ll
index 9a47a3a..6a27115 100644
--- a/test/COFF/thinlto-archives.ll
+++ b/test/COFF/thinlto-archives.ll
@@ -6,9 +6,17 @@
 ; RUN: opt -thinlto-bc -o %T/thinlto-archives/b/bar.obj %S/Inputs/bar.ll
 ; RUN: llvm-ar crs %T/thinlto-archives/a.lib %T/thinlto-archives/a/bar.obj
 ; RUN: llvm-ar crs %T/thinlto-archives/b.lib %T/thinlto-archives/b/bar.obj
-; RUN: lld-link /out:%T/thinlto-archives/main.exe -entry:main \
-; RUN:     -subsystem:console %T/thinlto-archives/main.obj \
+; RUN: lld-link -out:%T/thinlto-archives/main.exe -entry:main \
+; RUN:     -lldsavetemps -subsystem:console %T/thinlto-archives/main.obj \
 ; RUN:     %T/thinlto-archives/a.lib %T/thinlto-archives/b.lib
+; RUN: FileCheck %s < %T/thinlto-archives/main.exe.resolution.txt
+
+; CHECK: {{/thinlto-archives/main.obj$}}
+; CHECK: {{^-r=.*/thinlto-archives/main.obj,main,px$}}
+; CHECK: {{/thinlto-archives/a.libbar.obj$}}
+; CHECK-NEXT: {{^-r=.*/thinlto-archives/a.libbar.obj,foo,p$}}
+; CHECK-NEXT: {{/thinlto-archives/b.libbar.obj$}}
+; CHECK-NEXT: {{^-r=.*/thinlto-archives/b.libbar.obj,bar,p$}}
 
 target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-pc-windows-msvc"
diff --git a/test/COFF/undefined-symbol-cv.s b/test/COFF/undefined-symbol-cv.s
index 31a44c3..e730c5d 100644
--- a/test/COFF/undefined-symbol-cv.s
+++ b/test/COFF/undefined-symbol-cv.s
@@ -2,19 +2,19 @@
 # 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: error: undefined symbol: "int __cdecl foo(void)" (?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-EMPTY:
+# CHECK-NEXT: error: undefined symbol: "int __cdecl bar(void)" (?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-EMPTY:
+# CHECK-NEXT: error: undefined symbol: "int __cdecl baz(void)" (?baz@@YAHXZ)
 # CHECK-NEXT: >>> referenced by file1.cpp:5
 # CHECK-NEXT: >>>               {{.*}}.obj:(f2)
 
diff --git a/test/COFF/undefined-symbol.s b/test/COFF/undefined-symbol.s
index 5d002d8..31da50a 100644
--- a/test/COFF/undefined-symbol.s
+++ b/test/COFF/undefined-symbol.s
@@ -2,15 +2,15 @@
 # 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: error: undefined symbol: "int __cdecl foo(void)" (?foo@@YAHXZ)
 # CHECK-NEXT: >>> referenced by {{.*}}.obj:(main)
 # CHECK-NEXT: >>> referenced by {{.*}}.obj:(main)
-
-# CHECK: error: undefined symbol: ?bar@@YAHXZ
+# CHECK-EMPTY:
+# CHECK-NEXT: error: undefined symbol: "int __cdecl bar(void)" (?bar@@YAHXZ)
 # CHECK-NEXT: >>> referenced by {{.*}}.obj:(main)
 # CHECK-NEXT: >>> referenced by {{.*}}.obj:(f1)
-
-# CHECK: error: undefined symbol: ?baz@@YAHXZ
+# CHECK-EMPTY:
+# CHECK-NEXT: error: undefined symbol: "__declspec(dllimport) int __cdecl baz(void)" (__imp_?baz@@YAHXZ)
 # CHECK-NEXT: >>> referenced by {{.*}}.obj:(f2)
 
         .section        .text,"xr",one_only,main
@@ -27,4 +27,4 @@
         .section        .text,"xr",one_only,f2
 .globl f2
 f2:
-	call	"?baz@@YAHXZ"
+	callq	*"__imp_?baz@@YAHXZ"(%rip)
diff --git a/test/ELF/Inputs/hexagon-shared.s b/test/ELF/Inputs/hexagon-shared.s
new file mode 100644
index 0000000..a014dd1
--- /dev/null
+++ b/test/ELF/Inputs/hexagon-shared.s
@@ -0,0 +1,3 @@
+.global bar
+bar:
+   jumpr lr
diff --git a/test/ELF/Inputs/i386-linkonce.s b/test/ELF/Inputs/i386-linkonce.s
new file mode 100644
index 0000000..b5906cc
--- /dev/null
+++ b/test/ELF/Inputs/i386-linkonce.s
@@ -0,0 +1,11 @@
+.section .gnu.linkonce.t.__i686.get_pc_thunk.bx
+.global __i686.get_pc_thunk.bx
+__i686.get_pc_thunk.bx:
+    mov    (%esp),%ebx
+    ret
+
+.section .text
+.global _strchr1
+_strchr1:
+    call __i686.get_pc_thunk.bx
+    ret
diff --git a/test/ELF/Inputs/ppc64-bsymbolic-local-def.s b/test/ELF/Inputs/ppc64-bsymbolic-local-def.s
new file mode 100644
index 0000000..10eec6c
--- /dev/null
+++ b/test/ELF/Inputs/ppc64-bsymbolic-local-def.s
@@ -0,0 +1,14 @@
+        .abiversion 2
+        .section ".text"
+
+        .p2align 2
+        .global def
+        .type def, @function
+def:
+.Ldef_gep:
+    addis 2, 12, .TOC.-.Ldef_gep@ha
+    addi 2, 2, .TOC.-.Ldef_gep@l
+.Ldef_lep:
+    .localentry def, .-def
+    li 3, 55
+    blr
diff --git a/test/ELF/Inputs/ppc64-tls-ie-le.s b/test/ELF/Inputs/ppc64-tls-ie-le.s
new file mode 100644
index 0000000..1d7ccc8
--- /dev/null
+++ b/test/ELF/Inputs/ppc64-tls-ie-le.s
@@ -0,0 +1,29 @@
+	.text
+	.abiversion 2
+	.type	c,@object               # @c
+	.section	.tdata,"awT",@progbits
+	.globl	c
+c:
+	.byte	97                      # 0x61
+	.size	c, 1
+
+	.type	s,@object               # @s
+	.globl	s
+	.p2align	1
+s:
+	.short	55                      # 0x37
+	.size	s, 2
+
+	.type	i,@object               # @i
+	.globl	i
+	.p2align	2
+i:
+	.long	55                      # 0x37
+	.size	i, 4
+
+	.type	l,@object               # @l
+	.globl	l
+	.p2align	3
+l:
+	.quad	55                      # 0x37
+	.size	l, 8
diff --git a/test/ELF/Inputs/ppc64le-quadword-ldst.o b/test/ELF/Inputs/ppc64le-quadword-ldst.o
new file mode 100644
index 0000000..c17ef9e
--- /dev/null
+++ b/test/ELF/Inputs/ppc64le-quadword-ldst.o
Binary files differ
diff --git a/test/ELF/aarch64-abs16.s b/test/ELF/aarch64-abs16.s
index 20a65b1..c9d88b3 100644
--- a/test/ELF/aarch64-abs16.s
+++ b/test/ELF/aarch64-abs16.s
@@ -14,14 +14,14 @@
 // RUN: llvm-objdump -s -section=.data %t2 | FileCheck %s
 
 // CHECK: Contents of section .data:
-// 11000: S = 0x100, A = 0xfeff
-//        S + A = 0xffff
-// 11002: S = 0x100, A = -0x8100
-//        S + A = 0x8000
-// CHECK-NEXT: 20000 ffff0080
+// 210000: S = 0x100, A = 0xfeff
+//         S + A = 0xffff
+// 210002: S = 0x100, A = -0x8100
+//         S + A = 0x8000
+// CHECK-NEXT: 210000 ffff0080
 
-// RUN: not ld.lld %t.o %t255.o -o %t2
-//   | FileCheck %s --check-prefix=OVERFLOW
-// RUN: not ld.lld %t.o %t257.o -o %t2
-//   | FileCheck %s --check-prefix=OVERFLOW
-// OVERFLOW: Relocation R_AARCH64_ABS16 out of range: 65536 is not in [-32768, 65535]
+// RUN: not ld.lld %t.o %t255.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
+// OVERFLOW1: relocation R_AARCH64_ABS16 out of range: -32769 is not in [-32768, 32767]
+
+// RUN: not ld.lld %t.o %t257.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
+// OVERFLOW2: relocation R_AARCH64_ABS16 out of range: 65536 is not in [-32768, 32767]
diff --git a/test/ELF/aarch64-abs32.s b/test/ELF/aarch64-abs32.s
index b93f27a..da2005d 100644
--- a/test/ELF/aarch64-abs32.s
+++ b/test/ELF/aarch64-abs32.s
@@ -14,14 +14,14 @@
 // RUN: llvm-objdump -s -section=.data %t2 | FileCheck %s
 
 // CHECK: Contents of section .data:
-// 20000: S = 0x100, A = 0xfffffeff
-//        S + A = 0xffffffff
-// 20004: S = 0x100, A = -0x80000100
-//        S + A = 0x80000000
-// CHECK-NEXT: 20000 ffffffff 00000080
+// 210000: S = 0x100, A = 0xfffffeff
+//         S + A = 0xffffffff
+// 210004: S = 0x100, A = -0x80000100
+//         S + A = 0x80000000
+// CHECK-NEXT: 210000 ffffffff 00000080
 
-// RUN: not ld.lld %t.o %t255.o -o %t2
-//   | FileCheck %s --check-prefix=OVERFLOW
-// RUN: not ld.lld %t.o %t257.o -o %t2
-//   | FileCheck %s --check-prefix=OVERFLOW
-// OVERFLOW: Relocation R_AARCH64_ABS32 out of range: 4294967296 is not in [-2147483648, 4294967295]
+// RUN: not ld.lld %t.o %t255.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
+// OVERFLOW1: relocation R_AARCH64_ABS32 out of range: -2147483649 is not in [-2147483648, 2147483647]
+
+// RUN: not ld.lld %t.o %t257.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
+// OVERFLOW2: relocation R_AARCH64_ABS32 out of range: 4294967296 is not in [-2147483648, 2147483647]
diff --git a/test/ELF/aarch64-call26-thunk.s b/test/ELF/aarch64-call26-thunk.s
index 067f6db..1ca0799 100644
--- a/test/ELF/aarch64-call26-thunk.s
+++ b/test/ELF/aarch64-call26-thunk.s
@@ -11,11 +11,11 @@
 
 // CHECK: Disassembly of section .text:
 // CHECK-NEXT: _start:
-// CHECK-NEXT:    20000:        02 00 00 94     bl      #8
+// CHECK-NEXT:    210000:        02 00 00 94     bl      #8
 // CHECK: __AArch64AbsLongThunk_big:
-// CHECK-NEXT:    20008:        50 00 00 58     ldr     x16, #8
-// CHECK-NEXT:    2000c:        00 02 1f d6     br      x16
+// CHECK-NEXT:    210008:        50 00 00 58     ldr     x16, #8
+// CHECK-NEXT:    21000c:        00 02 1f d6     br      x16
 // CHECK: $d:
-// CHECK-NEXT:    20010:        00 00 00 00     .word   0x00000000
-// CHECK-NEXT:    20014:        10 00 00 00     .word   0x00000010
+// CHECK-NEXT:    210010:        00 00 00 00     .word   0x00000000
+// CHECK-NEXT:    210014:        10 00 00 00     .word   0x00000010
 
diff --git a/test/ELF/aarch64-condb-reloc.s b/test/ELF/aarch64-condb-reloc.s
index 8a75814..b7fe777 100644
--- a/test/ELF/aarch64-condb-reloc.s
+++ b/test/ELF/aarch64-condb-reloc.s
@@ -12,21 +12,21 @@
 # 0x1102c - 16 = 0x1101c
 # CHECK:      Disassembly of section .text:
 # CHECK-NEXT: _foo:
-# CHECK-NEXT:    20000: {{.*}} nop
-# CHECK-NEXT:    20004: {{.*}} nop
-# CHECK-NEXT:    20008: {{.*}} nop
-# CHECK-NEXT:    2000c: {{.*}} nop
+# CHECK-NEXT:    210000: {{.*}} nop
+# CHECK-NEXT:    210004: {{.*}} nop
+# CHECK-NEXT:    210008: {{.*}} nop
+# CHECK-NEXT:    21000c: {{.*}} nop
 # CHECK:      _bar:
-# CHECK-NEXT:    20010: {{.*}} nop
-# CHECK-NEXT:    20014: {{.*}} nop
-# CHECK-NEXT:    20018: {{.*}} nop
+# CHECK-NEXT:    210010: {{.*}} nop
+# CHECK-NEXT:    210014: {{.*}} nop
+# CHECK-NEXT:    210018: {{.*}} nop
 # CHECK:      _dah:
-# CHECK-NEXT:    2001c: {{.*}} nop
-# CHECK-NEXT:    20020: {{.*}} nop
+# CHECK-NEXT:    21001c: {{.*}} nop
+# CHECK-NEXT:    210020: {{.*}} nop
 # CHECK:      _start:
-# CHECK-NEXT:    20024: {{.*}} b.eq #-36
-# CHECK-NEXT:    20028: {{.*}} b.eq #-24
-# CHECK-NEXT:    2002c: {{.*}} b.eq #-16
+# CHECK-NEXT:    210024: {{.*}} b.eq #-36
+# CHECK-NEXT:    210028: {{.*}} b.eq #-24
+# CHECK-NEXT:    21002c: {{.*}} b.eq #-16
 
 #DSOREL:      Section {
 #DSOREL:        Index:
@@ -79,14 +79,20 @@
 #DSO-NEXT:     10044: {{.*}} nop
 #DSO-NEXT:     10048: {{.*}} nop
 #DSO-NEXT:     1004c: {{.*}} nop
+#DSO-EMPTY:
+#DSO-NEXT:   _foo@plt:
 #DSO-NEXT:     10050: {{.*}} adrp x16, #65536
 #DSO-NEXT:     10054: {{.*}} ldr x17, [x16, #24]
 #DSO-NEXT:     10058: {{.*}} add x16, x16, #24
 #DSO-NEXT:     1005c: {{.*}} br x17
+#DSO-EMPTY:
+#DSO-NEXT:   _bar@plt:
 #DSO-NEXT:     10060: {{.*}} adrp x16, #65536
 #DSO-NEXT:     10064: {{.*}} ldr x17, [x16, #32]
 #DSO-NEXT:     10068: {{.*}} add x16, x16, #32
 #DSO-NEXT:     1006c: {{.*}} br x17
+#DSO-EMPTY:
+#DSO-NEXT:   _dah@plt:
 #DSO-NEXT:     10070: {{.*}} adrp x16, #65536
 #DSO-NEXT:     10074: {{.*}} ldr x17, [x16, #40]
 #DSO-NEXT:     10078: {{.*}} add x16, x16, #40
diff --git a/test/ELF/aarch64-copy.s b/test/ELF/aarch64-copy.s
index 32e1c76..5a42c8d 100644
--- a/test/ELF/aarch64-copy.s
+++ b/test/ELF/aarch64-copy.s
@@ -22,7 +22,7 @@
 // CHECK-NEXT:       SHF_ALLOC
 // CHECK-NEXT:       SHF_WRITE
 // CHECK-NEXT:     ]
-// CHECK-NEXT:     Address: 0x40000
+// CHECK-NEXT:     Address: 0x230000
 // CHECK-NEXT:     Offset:
 // CHECK-NEXT:     Size: 24
 // CHECK-NEXT:     Link:
@@ -32,19 +32,19 @@
 // CHECK: Relocations [
 // CHECK-NEXT:   Section ({{.*}}) .rela.dyn {
 // CHECK-NEXT:     Relocation {
-// CHECK-NEXT:       Offset: 0x40000
+// CHECK-NEXT:       Offset: 0x230000
 // CHECK-NEXT:       Type: R_AARCH64_COPY
 // CHECK-NEXT:       Symbol: x
 // CHECK-NEXT:       Addend: 0x0
 // CHECK-NEXT:     }
 // CHECK-NEXT:     Relocation {
-// CHECK-NEXT:       Offset: 0x40010
+// CHECK-NEXT:       Offset: 0x230010
 // CHECK-NEXT:       Type: R_AARCH64_COPY
 // CHECK-NEXT:       Symbol: y
 // CHECK-NEXT:       Addend: 0x0
 // CHECK-NEXT:     }
 // CHECK-NEXT:     Relocation {
-// CHECK-NEXT:       Offset: 0x40014
+// CHECK-NEXT:       Offset: 0x230014
 // CHECK-NEXT:       Type: R_AARCH64_COPY
 // CHECK-NEXT:       Symbol: z
 // CHECK-NEXT:       Addend: 0x0
@@ -54,21 +54,21 @@
 
 // CHECK: Symbols [
 // CHECK:     Name: x
-// CHECK-NEXT:     Value: 0x40000
+// CHECK-NEXT:     Value: 0x230000
 // CHECK-NEXT:     Size: 4
 // CHECK-NEXT:     Binding: Global
 // CHECK-NEXT:     Type: Object
 // CHECK-NEXT:     Other:
 // CHECK-NEXT:     Section: .bss
 // CHECK:     Name: y
-// CHECK-NEXT:     Value: 0x40010
+// CHECK-NEXT:     Value: 0x230010
 // CHECK-NEXT:     Size: 4
 // CHECK-NEXT:     Binding: Global
 // CHECK-NEXT:     Type: Object
 // CHECK-NEXT:     Other:
 // CHECK-NEXT:     Section: .bss
 // CHECK:     Name: z
-// CHECK-NEXT:     Value: 0x40014
+// CHECK-NEXT:     Value: 0x230014
 // CHECK-NEXT:     Size: 4
 // CHECK-NEXT:     Binding: Global
 // CHECK-NEXT:     Type: Object
@@ -78,16 +78,16 @@
 
 // CODE: Disassembly of section .text:
 // CODE-NEXT: _start:
-// S(x) = 0x40000, A = 0, P = 0x20000
+// S(x) = 0x230000, A = 0, P = 0x210000
 // S + A - P = 0x20000 = 131072
-// CODE-NEXT:  20000: {{.*}} adr  x1, #131072
-// S(y) = 0x40010, A = 0, P = 0x20004
-// Page(S + A) - Page(P) = 0x40000 - 0x20000 = 0x20000 = 131072
-// CODE-NEXT:  20004: {{.*}} adrp x2, #131072
-// S(y) = 0x40010, A = 0
+// CODE-NEXT:  210000: {{.*}} adr  x1, #131072
+// S(y) = 0x230010, A = 0, P = 0x210004
+// Page(S + A) - Page(P) = 0x230000 - 0x210000 = 0x20000 = 131072
+// CODE-NEXT:  210004: {{.*}} adrp x2, #131072
+// S(y) = 0x230010, A = 0
 // (S + A) & 0xFFF = 0x10 = 16
-// CODE-NEXT:  20008: {{.*}} add  x2, x2, #16
+// CODE-NEXT:  210008: {{.*}} add  x2, x2, #16
 
 // RODATA: Contents of section .rodata:
-// S(z) = 0x40014
-// RODATA-NEXT:  102e0 14000400
+// S(z) = 0x230014
+// RODATA-NEXT:  2002e0 14002300
diff --git a/test/ELF/aarch64-copy2.s b/test/ELF/aarch64-copy2.s
index 6f72e21..5324c74 100644
--- a/test/ELF/aarch64-copy2.s
+++ b/test/ELF/aarch64-copy2.s
@@ -19,7 +19,7 @@
 // CHECK-NEXT: Section: Undefined
 
 // CHECK:      Name: foo
-// CHECK-NEXT: Value: 0x20030
+// CHECK-NEXT: Value: 0x210030
 // CHECK-NEXT: Size: 0
 // CHECK-NEXT: Binding: Global
 // CHECK-NEXT: Type: Function
diff --git a/test/ELF/aarch64-cortex-a53-843419-abs-mapsyms.s b/test/ELF/aarch64-cortex-a53-843419-abs-mapsyms.s
new file mode 100644
index 0000000..608b1ac
--- /dev/null
+++ b/test/ELF/aarch64-cortex-a53-843419-abs-mapsyms.s
@@ -0,0 +1,22 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t
+// RUN: ld.lld --just-symbols %t -fix-cortex-a53-843419 -o %t.axf
+// RUN: llvm-readobj --symbols %t.axf | FileCheck %s
+
+// Check that we can gracefully handle --just-symbols, which gives a local
+// absolute mapping symbol (with no Section). Previously we assumed that all
+// mapping symbols were defined relative to a section and assert failed.
+
+        .text
+        .global _start
+        .type _start, %function
+_start: ret
+
+// CHECK:     Name: $x.0
+// CHECK-NEXT:     Value: 0x0
+// CHECK-NEXT:     Size: 0
+// CHECK-NEXT:     Binding: Local (0x0)
+// CHECK-NEXT:     Type: None (0x0)
+// CHECK-NEXT:     Other: 0
+// CHECK-NEXT:     Section: Absolute (0xFFF1)
+// CHECK-NEXT:   }
diff --git a/test/ELF/aarch64-cortex-a53-843419-large.s b/test/ELF/aarch64-cortex-a53-843419-large.s
index 00c92eb..c902177 100644
--- a/test/ELF/aarch64-cortex-a53-843419-large.s
+++ b/test/ELF/aarch64-cortex-a53-843419-large.s
@@ -1,23 +1,23 @@
 // REQUIRES: aarch64
 // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o
 // RUN: ld.lld --fix-cortex-a53-843419 %t.o -o %t2
-// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=131072 -stop-address=131084 | FileCheck --check-prefix=CHECK1 %s
-// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=135168 -stop-address=135172 | FileCheck --check-prefix=CHECK2 %s
-// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=139256 -stop-address=139272 | FileCheck --check-prefix=CHECK3 %s
-// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=67256312 -stop-address=67256328 | FileCheck --check-prefix=CHECK4 %s
-// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=100810760 -stop-address=100810776 | FileCheck --check-prefix=CHECK5 %s
-// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=134352908 -stop-address=134352912 | FileCheck --check-prefix=CHECK6 %s
-// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=134356988 -stop-address=134357012 | FileCheck --check-prefix=CHECK7 %s
+// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=2162688   -stop-address=2162700   | FileCheck --check-prefix=CHECK1 %s
+// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=2166784   -stop-address=2166788   | FileCheck --check-prefix=CHECK2 %s
+// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=2170872   -stop-address=2170888   | FileCheck --check-prefix=CHECK3 %s
+// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=69287928  -stop-address=69287944  | FileCheck --check-prefix=CHECK4 %s
+// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=102842376 -stop-address=102842392 | FileCheck --check-prefix=CHECK5 %s
+// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=136384524 -stop-address=136384528 | FileCheck --check-prefix=CHECK6 %s
+// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=136388604 -stop-address=136388628 | FileCheck --check-prefix=CHECK7 %s
 // Test case for Cortex-A53 Erratum 843419 in an OutputSection exceeding
 // the maximum branch range. Both range extension thunks and patches are
-// required.
-
+// required.					      
+						      
 // CHECK1:  __AArch64AbsLongThunk_need_thunk_after_patch:
-// CHECK1-NEXT:    20000:       50 00 00 58     ldr     x16, #8
-// CHECK1-NEXT:    20004:       00 02 1f d6     br      x16
-// CHECK1: $d:
-// CHECK1-NEXT:    20008:       0c 10 02 08     .word   0x0802100c
-
+// CHECK1-NEXT:    210000:       50 00 00 58     ldr     x16, #8
+// CHECK1-NEXT:    210004:       00 02 1f d6     br      x16
+// CHECK1: $d:					      
+// CHECK1-NEXT:    210008:       0c 10 21 08     .word   0x0821100c
+						      
         .section .text.01, "ax", %progbits
         .balign 4096
         .globl _start
@@ -29,7 +29,7 @@
         .space 4096 - 12
 
 // CHECK2: _start:
-// CHECK2-NEXT:    21000:       00 fc ff 97     bl      #-4096
+// CHECK2-NEXT:    211000:       00 fc ff 97     bl      #-4096
 
         // Expect patch on pass 1
         .section .text.03, "ax", %progbits
@@ -42,10 +42,10 @@
         ret
 
 // CHECK3: t3_ff8_ldr:
-// CHECK3-NEXT:    21ff8:       60 00 04 f0     adrp    x0, #134279168
-// CHECK3-NEXT:    21ffc:       21 00 40 f9     ldr     x1, [x1]
-// CHECK3-NEXT:    22000:       02 08 80 15     b       #100671496
-// CHECK3-NEXT:    22004:       c0 03 5f d6     ret
+// CHECK3-NEXT:    211ff8:       60 00 04 f0     adrp    x0, #134279168
+// CHECK3-NEXT:    211ffc:       21 00 40 f9     ldr     x1, [x1]
+// CHECK3-NEXT:    212000:       02 08 80 15     b       #100671496
+// CHECK3-NEXT:    212004:       c0 03 5f d6     ret
 
         .section .text.04, "ax", %progbits
         .space 64 * 1024 * 1024
@@ -63,20 +63,20 @@
         ret
 
 // CHECK4: t3_ff8_str:
-// CHECK4-NEXT:  4023ff8:       60 00 02 b0     adrp    x0, #67162112
-// CHECK4-NEXT:  4023ffc:       21 00 40 f9     ldr     x1, [x1]
-// CHECK4-NEXT:  4024000:       04 00 80 14     b       #33554448
-// CHECK4-NEXT:  4024004:       c0 03 5f d6     ret
+// CHECK4-NEXT:  4213ff8:       60 00 02 b0     adrp    x0, #67162112
+// CHECK4-NEXT:  4213ffc:       21 00 40 f9     ldr     x1, [x1]
+// CHECK4-NEXT:  4214000:       04 00 80 14     b       #33554448
+// CHECK4-NEXT:  4214004:       c0 03 5f d6     ret
 
         .section .text.06, "ax", %progbits
         .space 32 * 1024 * 1024
 
-// CHECK5: __CortexA53843419_21000:
-// CHECK5-NEXT:  6024008:       00 00 40 f9     ldr     x0, [x0]
-// CHECK5-NEXT:  602400c:       fe f7 7f 16     b       #-100671496
-// CHECK5: __CortexA53843419_4023000:
-// CHECK5-NEXT:  6024010:       00 00 00 f9     str     x0, [x0]
-// CHECK5-NEXT:  6024014:       fc ff 7f 17     b       #-33554448
+// CHECK5: __CortexA53843419_211000:
+// CHECK5-NEXT:  6214008:       00 00 40 f9     ldr     x0, [x0]
+// CHECK5-NEXT:  621400c:       fe f7 7f 16     b       #-100671496
+// CHECK5: __CortexA53843419_4213000:
+// CHECK5-NEXT:  6214010:       00 00 00 f9     str     x0, [x0]
+// CHECK5-NEXT:  6214014:       fc ff 7f 17     b       #-33554448
 
         .section .text.07, "ax", %progbits
         .space (32 * 1024 * 1024) - 12300
@@ -88,7 +88,7 @@
         ret
 
 // CHECK6: need_thunk_after_patch:
-// CHECK6-NEXT:  802100c:       c0 03 5f d6     ret
+// CHECK6-NEXT:  821100c:       c0 03 5f d6     ret
 
         // Will need a patch on pass 2
         .section .text.09, "ax", %progbits
@@ -102,13 +102,13 @@
         ret
 
 // CHECK7: t3_ffc_ldr:
-// CHECK7-NEXT:  8021ffc:       60 00 00 f0     adrp    x0, #61440
-// CHECK7-NEXT:  8022000:       21 00 40 f9     ldr     x1, [x1]
-// CHECK7-NEXT:  8022004:       02 00 00 14     b       #8
-// CHECK7-NEXT:  8022008:       c0 03 5f d6     ret
-// CHECK7: __CortexA53843419_8022004:
-// CHECK7-NEXT:  802200c:       00 00 40 f9     ldr     x0, [x0]
-// CHECK7-NEXT:  8022010:       fe ff ff 17     b       #-8
+// CHECK7-NEXT:  8211ffc:       60 00 00 f0     adrp    x0, #61440
+// CHECK7-NEXT:  8212000:       21 00 40 f9     ldr     x1, [x1]
+// CHECK7-NEXT:  8212004:       02 00 00 14     b       #8
+// CHECK7-NEXT:  8212008:       c0 03 5f d6     ret
+// CHECK7: __CortexA53843419_8212004:
+// CHECK7-NEXT:  821200c:       00 00 40 f9     ldr     x0, [x0]
+// CHECK7-NEXT:  8212010:       fe ff ff 17     b       #-8
 
         .section .data
         .globl dat
diff --git a/test/ELF/aarch64-cortex-a53-843419-recognize.s b/test/ELF/aarch64-cortex-a53-843419-recognize.s
index 174f181..cde3591 100644
--- a/test/ELF/aarch64-cortex-a53-843419-recognize.s
+++ b/test/ELF/aarch64-cortex-a53-843419-recognize.s
@@ -26,13 +26,13 @@
 // - Optional instruction 3 present or not.
 // - Load or store for instruction 4.
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 21FF8 in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 211FF8 in unpatched output.
 // CHECK: t3_ff8_ldr:
-// CHECK-NEXT:    21ff8:        e0 01 00 f0     adrp    x0, #258048
-// CHECK-NEXT:    21ffc:        21 00 40 f9     ldr             x1, [x1]
-// CHECK-FIX:     22000:        03 c8 00 14     b       #204812
-// CHECK-NOFIX:   22000:        00 00 40 f9     ldr             x0, [x0]
-// CHECK-NEXT:    22004:        c0 03 5f d6     ret
+// CHECK-NEXT:    211ff8:        e0 01 00 f0     adrp    x0, #258048
+// CHECK-NEXT:    211ffc:        21 00 40 f9     ldr             x1, [x1]
+// CHECK-FIX:     212000:        03 c8 00 14     b       #204812
+// CHECK-NOFIX:   212000:        00 00 40 f9     ldr             x0, [x0]
+// CHECK-NEXT:    212004:        c0 03 5f d6     ret
         .section .text.01, "ax", %progbits
         .balign 4096
         .globl t3_ff8_ldr
@@ -44,13 +44,13 @@
         ldr x0, [x0, :got_lo12:dat1]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 23FF8 in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 213FF8 in unpatched output.
 // CHECK: t3_ff8_ldrsimd:
-// CHECK-NEXT:    23ff8:        e0 01 00 b0     adrp    x0, #249856
-// CHECK-NEXT:    23ffc:        21 00 40 bd     ldr             s1, [x1]
-// CHECK-FIX:     24000:        05 c0 00 14     b       #196628
-// CHECK-NOFIX:   24000:        02 04 40 f9     ldr     x2, [x0, #8]
-// CHECK-NEXT:    24004:        c0 03 5f d6     ret
+// CHECK-NEXT:    213ff8:        e0 01 00 b0     adrp    x0, #249856
+// CHECK-NEXT:    213ffc:        21 00 40 bd     ldr             s1, [x1]
+// CHECK-FIX:     214000:        05 c0 00 14     b       #196628
+// CHECK-NOFIX:   214000:        02 04 40 f9     ldr     x2, [x0, #8]
+// CHECK-NEXT:    214004:        c0 03 5f d6     ret
         .section .text.02, "ax", %progbits
         .balign 4096
         .globl t3_ff8_ldrsimd
@@ -62,13 +62,13 @@
         ldr x2, [x0, :got_lo12:dat2]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 25FFC in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 215FFC in unpatched output.
 // CHECK: t3_ffc_ldrpost:
-// CHECK-NEXT:    25ffc:        c0 01 00 f0     adrp    x0, #241664
-// CHECK-NEXT:    26000:        21 84 40 bc     ldr     s1, [x1], #8
-// CHECK-FIX:     26004:        06 b8 00 14     b       #188440
-// CHECK-NOFIX:   26004:        03 08 40 f9     ldr     x3, [x0, #16]
-// CHECK-NEXT:    26008:        c0 03 5f d6     ret
+// CHECK-NEXT:    215ffc:        c0 01 00 f0     adrp    x0, #241664
+// CHECK-NEXT:    216000:        21 84 40 bc     ldr     s1, [x1], #8
+// CHECK-FIX:     216004:        06 b8 00 14     b       #188440
+// CHECK-NOFIX:   216004:        03 08 40 f9     ldr     x3, [x0, #16]
+// CHECK-NEXT:    216008:        c0 03 5f d6     ret
         .section .text.03, "ax", %progbits
         .balign 4096
         .globl t3_ffc_ldrpost
@@ -80,13 +80,13 @@
         ldr x3, [x0, :got_lo12:dat3]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 27FF8 in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 217FF8 in unpatched output.
 // CHECK: t3_ff8_strpre:
-// CHECK-NEXT:    27ff8:        c0 01 00 b0     adrp    x0, #233472
-// CHECK-NEXT:    27ffc:        21 8c 00 bc     str     s1, [x1, #8]!
-// CHECK-FIX:     28000:        09 b0 00 14     b       #180260
-// CHECK-NOFIX:   28000:        02 00 40 f9     ldr             x2, [x0]
-// CHECK-NEXT:    28004:        c0 03 5f d6     ret
+// CHECK-NEXT:    217ff8:        c0 01 00 b0     adrp    x0, #233472
+// CHECK-NEXT:    217ffc:        21 8c 00 bc     str     s1, [x1, #8]!
+// CHECK-FIX:     218000:        09 b0 00 14     b       #180260
+// CHECK-NOFIX:   218000:        02 00 40 f9     ldr             x2, [x0]
+// CHECK-NEXT:    218004:        c0 03 5f d6     ret
         .section .text.04, "ax", %progbits
         .balign 4096
         .globl t3_ff8_strpre
@@ -98,13 +98,13 @@
         ldr x2, [x0, :lo12:dat1]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 29FFC in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 219FFC in unpatched output.
 // CHECK: t3_ffc_str:
-// CHECK-NEXT:    29ffc:        bc 01 00 f0     adrp    x28, #225280
-// CHECK-NEXT:    2a000:        42 00 00 f9     str             x2, [x2]
-// CHECK-FIX:     2a004:        0a a8 00 14     b       #172072
-// CHECK-NOFIX:   2a004:        9c 07 00 f9     str     x28, [x28, #8]
-// CHECK-NEXT:    2a008:        c0 03 5f d6     ret
+// CHECK-NEXT:    219ffc:        bc 01 00 f0     adrp    x28, #225280
+// CHECK-NEXT:    21a000:        42 00 00 f9     str             x2, [x2]
+// CHECK-FIX:     21a004:        0a a8 00 14     b       #172072
+// CHECK-NOFIX:   21a004:        9c 07 00 f9     str     x28, [x28, #8]
+// CHECK-NEXT:    21a008:        c0 03 5f d6     ret
         .section .text.05, "ax", %progbits
         .balign 4096
         .globl t3_ffc_str
@@ -116,13 +116,13 @@
         str x28, [x28, :lo12:dat2]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 2BFFC in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 21BFFC in unpatched output.
 // CHECK: t3_ffc_strsimd:
-// CHECK-NEXT:    2bffc:        bc 01 00 b0     adrp    x28, #217088
-// CHECK-NEXT:    2c000:        44 00 00 b9     str             w4, [x2]
-// CHECK-FIX:     2c004:        0c a0 00 14     b       #163888
-// CHECK-NOFIX:   2c004:        84 0b 00 f9     str     x4, [x28, #16]
-// CHECK-NEXT:    2c008:        c0 03 5f d6     ret
+// CHECK-NEXT:    21bffc:        bc 01 00 b0     adrp    x28, #217088
+// CHECK-NEXT:    21c000:        44 00 00 b9     str             w4, [x2]
+// CHECK-FIX:     21c004:        0c a0 00 14     b       #163888
+// CHECK-NOFIX:   21c004:        84 0b 00 f9     str     x4, [x28, #16]
+// CHECK-NEXT:    21c008:        c0 03 5f d6     ret
         .section .text.06, "ax", %progbits
         .balign 4096
         .globl t3_ffc_strsimd
@@ -134,13 +134,13 @@
         str x4, [x28, :lo12:dat3]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 2DFF8 in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 21DFF8 in unpatched output.
 // CHECK: t3_ff8_ldrunpriv:
-// CHECK-NEXT:    2dff8:        9d 01 00 f0     adrp    x29, #208896
-// CHECK-NEXT:    2dffc:        41 08 40 38     ldtrb           w1, [x2]
-// CHECK-FIX:     2e000:        0f 98 00 14     b       #155708
-// CHECK-NOFIX:   2e000:        bd 03 40 f9     ldr             x29, [x29]
-// CHECK-NEXT:    2e004:        c0 03 5f d6     ret
+// CHECK-NEXT:    21dff8:        9d 01 00 f0     adrp    x29, #208896
+// CHECK-NEXT:    21dffc:        41 08 40 38     ldtrb           w1, [x2]
+// CHECK-FIX:     21e000:        0f 98 00 14     b       #155708
+// CHECK-NOFIX:   21e000:        bd 03 40 f9     ldr             x29, [x29]
+// CHECK-NEXT:    21e004:        c0 03 5f d6     ret
         .section .text.07, "ax", %progbits
         .balign 4096
         .globl t3_ff8_ldrunpriv
@@ -152,13 +152,13 @@
         ldr x29, [x29, :got_lo12:dat1]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 2FFFC in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 21FFFC in unpatched output.
 // CHECK: t3_ffc_ldur:
-// CHECK-NEXT:    2fffc:        9d 01 00 b0     adrp    x29, #200704
-// CHECK-NEXT:    30000:        42 40 40 b8     ldur    w2, [x2, #4]
-// CHECK-FIX:     30004:        10 90 00 14     b       #147520
-// CHECK-NOFIX:   30004:        bd 07 40 f9     ldr     x29, [x29, #8]
-// CHECK-NEXT:    30008:        c0 03 5f d6     ret
+// CHECK-NEXT:    21fffc:        9d 01 00 b0     adrp    x29, #200704
+// CHECK-NEXT:    220000:        42 40 40 b8     ldur    w2, [x2, #4]
+// CHECK-FIX:     220004:        10 90 00 14     b       #147520
+// CHECK-NOFIX:   220004:        bd 07 40 f9     ldr     x29, [x29, #8]
+// CHECK-NEXT:    220008:        c0 03 5f d6     ret
         .balign 4096
         .globl t3_ffc_ldur
         .type t3_ffc_ldur, %function
@@ -169,13 +169,13 @@
         ldr x29, [x29, :got_lo12:dat2]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 31FFC in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 221FFC in unpatched output.
 // CHECK: t3_ffc_sturh:
-// CHECK-NEXT:    31ffc:        72 01 00 f0     adrp    x18, #192512
-// CHECK-NEXT:    32000:        43 40 00 78     sturh   w3, [x2, #4]
-// CHECK-FIX:     32004:        12 88 00 14     b       #139336
-// CHECK-NOFIX:   32004:        41 0a 40 f9     ldr     x1, [x18, #16]
-// CHECK-NEXT:    32008:        c0 03 5f d6     ret
+// CHECK-NEXT:    221ffc:        72 01 00 f0     adrp    x18, #192512
+// CHECK-NEXT:    222000:        43 40 00 78     sturh   w3, [x2, #4]
+// CHECK-FIX:     222004:        12 88 00 14     b       #139336
+// CHECK-NOFIX:   222004:        41 0a 40 f9     ldr     x1, [x18, #16]
+// CHECK-NEXT:    222008:        c0 03 5f d6     ret
         .section .text.09, "ax", %progbits
         .balign 4096
         .globl t3_ffc_sturh
@@ -187,13 +187,13 @@
         ldr x1, [x18, :got_lo12:dat3]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 33FF8 in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 223FF8 in unpatched output.
 // CHECK: t3_ff8_literal:
-// CHECK-NEXT:    33ff8:        72 01 00 b0     adrp    x18, #184320
-// CHECK-NEXT:    33ffc:        e3 ff ff 58     ldr     x3, #-4
-// CHECK-FIX:     34000:        15 80 00 14     b       #131156
-// CHECK-NOFIX:   34000:        52 02 40 f9     ldr             x18, [x18]
-// CHECK-NEXT:    34004:        c0 03 5f d6     ret
+// CHECK-NEXT:    223ff8:        72 01 00 b0     adrp    x18, #184320
+// CHECK-NEXT:    223ffc:        e3 ff ff 58     ldr     x3, #-4
+// CHECK-FIX:     224000:        15 80 00 14     b       #131156
+// CHECK-NOFIX:   224000:        52 02 40 f9     ldr             x18, [x18]
+// CHECK-NEXT:    224004:        c0 03 5f d6     ret
         .section .text.10, "ax", %progbits
         .balign 4096
         .globl t3_ff8_literal
@@ -205,13 +205,13 @@
         ldr x18, [x18, :lo12:dat1]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 35FFC in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 225FFC in unpatched output.
 // CHECK: t3_ffc_register:
-// CHECK-NEXT:    35ffc:        4f 01 00 f0     adrp    x15, #176128
-// CHECK-NEXT:    36000:        43 68 61 f8     ldr             x3, [x2, x1]
-// CHECK-FIX:     36004:        16 78 00 14     b       #122968
-// CHECK-NOFIX:   36004:        ea 05 40 f9     ldr     x10, [x15, #8]
-// CHECK-NEXT:    36008:        c0 03 5f d6     ret
+// CHECK-NEXT:    225ffc:        4f 01 00 f0     adrp    x15, #176128
+// CHECK-NEXT:    226000:        43 68 61 f8     ldr             x3, [x2, x1]
+// CHECK-FIX:     226004:        16 78 00 14     b       #122968
+// CHECK-NOFIX:   226004:        ea 05 40 f9     ldr     x10, [x15, #8]
+// CHECK-NEXT:    226008:        c0 03 5f d6     ret
         .section .text.11, "ax", %progbits
         .balign 4096
         .globl t3_ffc_register
@@ -223,13 +223,13 @@
         ldr x10, [x15, :lo12:dat2]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 37FF8 in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 227FF8 in unpatched output.
 // CHECK: t3_ff8_stp:
-// CHECK-NEXT:    37ff8:        50 01 00 b0     adrp    x16, #167936
-// CHECK-NEXT:    37ffc:        61 08 00 a9     stp             x1, x2, [x3]
-// CHECK-FIX:     38000:        19 70 00 14     b       #114788
-// CHECK-NOFIX:   38000:        0d 0a 40 f9     ldr     x13, [x16, #16]
-// CHECK-NEXT:    38004:        c0 03 5f d6     ret
+// CHECK-NEXT:    227ff8:        50 01 00 b0     adrp    x16, #167936
+// CHECK-NEXT:    227ffc:        61 08 00 a9     stp             x1, x2, [x3]
+// CHECK-FIX:     228000:        19 70 00 14     b       #114788
+// CHECK-NOFIX:   228000:        0d 0a 40 f9     ldr     x13, [x16, #16]
+// CHECK-NEXT:    228004:        c0 03 5f d6     ret
         .section .text.12, "ax", %progbits
         .balign 4096
         .globl t3_ff8_stp
@@ -241,13 +241,13 @@
         ldr x13, [x16, :lo12:dat3]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 39FFC in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 229FFC in unpatched output.
 // CHECK: t3_ffc_stnp:
-// CHECK-NEXT:    39ffc:        27 01 00 f0     adrp    x7, #159744
-// CHECK-NEXT:    3a000:        61 08 00 a8     stnp            x1, x2, [x3]
-// CHECK-FIX:     3a004:        1a 68 00 14     b       #106600
-// CHECK-NOFIX:   3a004:        e9 00 40 f9     ldr             x9, [x7]
-// CHECK-NEXT:    3a008:        c0 03 5f d6     ret
+// CHECK-NEXT:    229ffc:        27 01 00 f0     adrp    x7, #159744
+// CHECK-NEXT:    22a000:        61 08 00 a8     stnp            x1, x2, [x3]
+// CHECK-FIX:     22a004:        1a 68 00 14     b       #106600
+// CHECK-NOFIX:   22a004:        e9 00 40 f9     ldr             x9, [x7]
+// CHECK-NEXT:    22a008:        c0 03 5f d6     ret
         .section .text.13, "ax", %progbits
         .balign 4096
         .globl t3_ffc_stnp
@@ -259,13 +259,13 @@
         ldr x9, [x7, :lo12:dat1]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 3BFFC in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 22BFFC in unpatched output.
 // CHECK: t3_ffc_st1singlepost:
-// CHECK-NEXT:    3bffc:        37 01 00 b0     adrp    x23, #151552
-// CHECK-NEXT:    3c000:        20 04 82 0d     st1 { v0.b }[1], [x1], x2
-// CHECK-FIX:     3c004:        1c 60 00 14     b       #98416
-// CHECK-NOFIX:   3c004:        f6 06 40 f9     ldr     x22, [x23, #8]
-// CHECK-NEXT:    3c008:        c0 03 5f d6     ret
+// CHECK-NEXT:    22bffc:        37 01 00 b0     adrp    x23, #151552
+// CHECK-NEXT:    22c000:        20 04 82 0d     st1 { v0.b }[1], [x1], x2
+// CHECK-FIX:     22c004:        1c 60 00 14     b       #98416
+// CHECK-NOFIX:   22c004:        f6 06 40 f9     ldr     x22, [x23, #8]
+// CHECK-NEXT:    22c008:        c0 03 5f d6     ret
         .section .text.14, "ax", %progbits
         .balign 4096
         .globl t3_ffc_st1singlepost
@@ -277,13 +277,13 @@
         ldr x22, [x23, :lo12:dat2]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 3DFF8 in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 22DFF8 in unpatched output.
 // CHECK: t3_ff8_st1multiple:
-// CHECK-NEXT:    3dff8:        17 01 00 f0     adrp    x23, #143360
-// CHECK-NEXT:    3dffc:        20 a0 00 4c     st1     { v0.16b, v1.16b }, [x1]
-// CHECK-FIX:     3e000:        1f 58 00 14     b       #90236
-// CHECK-NOFIX:   3e000:        f8 0a 40 f9     ldr     x24, [x23, #16]
-// CHECK-NEXT:    3e004:        c0 03 5f d6     ret
+// CHECK-NEXT:    22dff8:        17 01 00 f0     adrp    x23, #143360
+// CHECK-NEXT:    22dffc:        20 a0 00 4c     st1     { v0.16b, v1.16b }, [x1]
+// CHECK-FIX:     22e000:        1f 58 00 14     b       #90236
+// CHECK-NOFIX:   22e000:        f8 0a 40 f9     ldr     x24, [x23, #16]
+// CHECK-NEXT:    22e004:        c0 03 5f d6     ret
         .section .text.15, "ax", %progbits
         .balign 4096
         .globl t3_ff8_st1multiple
@@ -295,14 +295,14 @@
         ldr x24, [x23, :lo12:dat3]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 3FFF8 in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 22FFF8 in unpatched output.
 // CHECK: t4_ff8_ldr:
-// CHECK-NEXT:    3fff8:        00 01 00 b0     adrp    x0, #135168
-// CHECK-NEXT:    3fffc:        21 00 40 f9     ldr             x1, [x1]
-// CHECK-NEXT:    40000:        42 00 00 8b     add             x2, x2, x0
-// CHECK-FIX:     40004:        20 50 00 14     b       #82048
-// CHECK-NOFIX:   40004:        02 00 40 f9     ldr             x2, [x0]
-// CHECK-NEXT:    40008:        c0 03 5f d6     ret
+// CHECK-NEXT:    22fff8:        00 01 00 b0     adrp    x0, #135168
+// CHECK-NEXT:    22fffc:        21 00 40 f9     ldr             x1, [x1]
+// CHECK-NEXT:    230000:        42 00 00 8b     add             x2, x2, x0
+// CHECK-FIX:     230004:        20 50 00 14     b       #82048
+// CHECK-NOFIX:   230004:        02 00 40 f9     ldr             x2, [x0]
+// CHECK-NEXT:    230008:        c0 03 5f d6     ret
         .section .text.16, "ax", %progbits
         .balign 4096
         .globl t4_ff8_ldr
@@ -315,14 +315,14 @@
         ldr x2, [x0, :got_lo12:dat1]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 41FFC in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 231FFC in unpatched output.
 // CHECK: t4_ffc_str:
-// CHECK-NEXT:    41ffc:        fc 00 00 f0     adrp    x28, #126976
-// CHECK-NEXT:    42000:        42 00 00 f9     str             x2, [x2]
-// CHECK-NEXT:    42004:        20 00 02 cb     sub             x0, x1, x2
-// CHECK-FIX:     42008:        21 48 00 14     b       #73860
-// CHECK-NOFIX:   42008:        9b 07 00 f9     str     x27, [x28, #8]
-// CHECK-NEXT:    4200c:        c0 03 5f d6     ret
+// CHECK-NEXT:    231ffc:        fc 00 00 f0     adrp    x28, #126976
+// CHECK-NEXT:    232000:        42 00 00 f9     str             x2, [x2]
+// CHECK-NEXT:    232004:        20 00 02 cb     sub             x0, x1, x2
+// CHECK-FIX:     232008:        21 48 00 14     b       #73860
+// CHECK-NOFIX:   232008:        9b 07 00 f9     str     x27, [x28, #8]
+// CHECK-NEXT:    23200c:        c0 03 5f d6     ret
         .section .text.17, "ax", %progbits
         .balign 4096
         .globl t4_ffc_str
@@ -335,14 +335,14 @@
         str x27, [x28, :got_lo12:dat2]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 43FF8 in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 233FF8 in unpatched output.
 // CHECK: t4_ff8_stp:
-// CHECK-NEXT:    43ff8:        f0 00 00 b0     adrp    x16, #118784
-// CHECK-NEXT:    43ffc:        61 08 00 a9     stp             x1, x2, [x3]
-// CHECK-NEXT:    44000:        03 7e 10 9b     mul             x3, x16, x16
-// CHECK-FIX:     44004:        24 40 00 14     b       #65680
-// CHECK-NOFIX:   44004:        0e 0a 40 f9     ldr     x14, [x16, #16]
-// CHECK-NEXT:    44008:        c0 03 5f d6     ret
+// CHECK-NEXT:    233ff8:        f0 00 00 b0     adrp    x16, #118784
+// CHECK-NEXT:    233ffc:        61 08 00 a9     stp             x1, x2, [x3]
+// CHECK-NEXT:    234000:        03 7e 10 9b     mul             x3, x16, x16
+// CHECK-FIX:     234004:        24 40 00 14     b       #65680
+// CHECK-NOFIX:   234004:        0e 0a 40 f9     ldr     x14, [x16, #16]
+// CHECK-NEXT:    234008:        c0 03 5f d6     ret
         .section .text.18, "ax", %progbits
         .balign 4096
         .globl t4_ff8_stp
@@ -355,14 +355,14 @@
         ldr x14, [x16, :got_lo12:dat3]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 45FF8 in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 235FF8 in unpatched output.
 // CHECK: t4_ff8_stppre:
-// CHECK-NEXT:    45ff8:        d0 00 00 f0     adrp    x16, #110592
-// CHECK-NEXT:    45ffc:        61 08 81 a9     stp     x1, x2, [x3, #16]!
-// CHECK-NEXT:    46000:        03 7e 10 9b     mul             x3, x16, x16
-// CHECK-FIX:     46004:        26 38 00 14     b       #57496
-// CHECK-NOFIX:   46004:        0e 06 40 f9     ldr     x14, [x16, #8]
-// CHECK-NEXT:    46008:        c0 03 5f d6     ret
+// CHECK-NEXT:    235ff8:        d0 00 00 f0     adrp    x16, #110592
+// CHECK-NEXT:    235ffc:        61 08 81 a9     stp     x1, x2, [x3, #16]!
+// CHECK-NEXT:    236000:        03 7e 10 9b     mul             x3, x16, x16
+// CHECK-FIX:     236004:        26 38 00 14     b       #57496
+// CHECK-NOFIX:   236004:        0e 06 40 f9     ldr     x14, [x16, #8]
+// CHECK-NEXT:    236008:        c0 03 5f d6     ret
         .section .text.19, "ax", %progbits
         .balign 4096
         .globl t4_ff8_stppre
@@ -375,14 +375,14 @@
         ldr x14, [x16, #8]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 47FF8 in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 237FF8 in unpatched output.
 // CHECK: t4_ff8_stppost:
-// CHECK-NEXT:    47ff8:        d0 00 00 b0     adrp    x16, #102400
-// CHECK-NEXT:    47ffc:        61 08 81 a8     stp     x1, x2, [x3], #16
-// CHECK-NEXT:    48000:        03 7e 10 9b     mul             x3, x16, x16
-// CHECK-FIX:     48004:        28 30 00 14     b       #49312
-// CHECK-NOFIX:   48004:        0e 06 40 f9     ldr     x14, [x16, #8]
-// CHECK-NEXT:    48008:        c0 03 5f d6     ret
+// CHECK-NEXT:    237ff8:        d0 00 00 b0     adrp    x16, #102400
+// CHECK-NEXT:    237ffc:        61 08 81 a8     stp     x1, x2, [x3], #16
+// CHECK-NEXT:    238000:        03 7e 10 9b     mul             x3, x16, x16
+// CHECK-FIX:     238004:        28 30 00 14     b       #49312
+// CHECK-NOFIX:   238004:        0e 06 40 f9     ldr     x14, [x16, #8]
+// CHECK-NEXT:    238008:        c0 03 5f d6     ret
         .section .text.20, "ax", %progbits
         .balign 4096
         .globl t4_ff8_stppost
@@ -395,14 +395,14 @@
         ldr x14, [x16, #8]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 49FFC in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 239FFC in unpatched output.
 // CHECK: t4_ffc_stpsimd:
-// CHECK-NEXT:    49ffc:        b0 00 00 f0     adrp    x16, #94208
-// CHECK-NEXT:    4a000:        61 08 00 ad     stp             q1, q2, [x3]
-// CHECK-NEXT:    4a004:        03 7e 10 9b     mul             x3, x16, x16
-// CHECK-FIX:     4a008:        29 28 00 14     b       #41124
-// CHECK-NOFIX:   4a008:        0e 06 40 f9     ldr     x14, [x16, #8]
-// CHECK-NEXT:    4a00c:        c0 03 5f d6     ret
+// CHECK-NEXT:    239ffc:        b0 00 00 f0     adrp    x16, #94208
+// CHECK-NEXT:    23a000:        61 08 00 ad     stp             q1, q2, [x3]
+// CHECK-NEXT:    23a004:        03 7e 10 9b     mul             x3, x16, x16
+// CHECK-FIX:     23a008:        29 28 00 14     b       #41124
+// CHECK-NOFIX:   23a008:        0e 06 40 f9     ldr     x14, [x16, #8]
+// CHECK-NEXT:    23a00c:        c0 03 5f d6     ret
         .section .text.21, "ax", %progbits
         .balign 4096
         .globl t4_ffc_stpsimd
@@ -415,14 +415,14 @@
         ldr x14, [x16, #8]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 4BFFC in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 23BFFC in unpatched output.
 // CHECK: t4_ffc_stnp:
-// CHECK-NEXT:    4bffc:        a7 00 00 b0     adrp    x7, #86016
-// CHECK-NEXT:    4c000:        61 08 00 a8     stnp            x1, x2, [x3]
-// CHECK-NEXT:    4c004:        1f 20 03 d5     nop
-// CHECK-FIX:     4c008:        2b 20 00 14     b       #32940
-// CHECK-NOFIX:   4c008:        ea 00 40 f9     ldr             x10, [x7]
-// CHECK-NEXT:    4c00c:        c0 03 5f d6     ret
+// CHECK-NEXT:    23bffc:        a7 00 00 b0     adrp    x7, #86016
+// CHECK-NEXT:    23c000:        61 08 00 a8     stnp            x1, x2, [x3]
+// CHECK-NEXT:    23c004:        1f 20 03 d5     nop
+// CHECK-FIX:     23c008:        2b 20 00 14     b       #32940
+// CHECK-NOFIX:   23c008:        ea 00 40 f9     ldr             x10, [x7]
+// CHECK-NEXT:    23c00c:        c0 03 5f d6     ret
         .section .text.22, "ax", %progbits
         .balign 4096
         .globl t4_ffc_stnp
@@ -435,14 +435,14 @@
         ldr x10, [x7, :got_lo12:dat1]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 4DFFC in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 23DFFC in unpatched output.
 // CHECK: t4_ffc_st1:
-// CHECK-NEXT:    4dffc:        98 00 00 f0     adrp    x24, #77824
-// 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 18 00 14     b       #24756
-// CHECK-NOFIX:   4e008:        18 ff 3f f9     str     x24, [x24, #32760]
-// CHECK-NEXT:    4e00c:        c0 03 5f d6     ret
+// CHECK-NEXT:    23dffc:        98 00 00 f0     adrp    x24, #77824
+// CHECK-NEXT:    23e000:        20 80 00 4d     st1 { v0.s }[2], [x1]
+// CHECK-NEXT:    23e004:        f6 06 40 f9     ldr     x22, [x23, #8]
+// CHECK-FIX:     23e008:        2d 18 00 14     b       #24756
+// CHECK-NOFIX:   23e008:        18 ff 3f f9     str     x24, [x24, #32760]
+// CHECK-NEXT:    23e00c:        c0 03 5f d6     ret
         .section .text.23, "ax", %progbits
         .balign 4096
         .globl t4_ffc_st1
@@ -455,14 +455,14 @@
         str x24, [x24, #32760]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 4FFF8 in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 23FFF8 in unpatched output.
 // CHECK: t3_ff8_ldr_once:
-// CHECK-NEXT:    4fff8:        80 00 00 b0     adrp    x0, #69632
-// CHECK-NEXT:    4fffc:        20 70 82 4c     st1     { v0.16b }, [x1], x2
-// CHECK-FIX:     50000:        31 10 00 14     b       #16580
-// CHECK-NOFIX:   50000:        01 08 40 f9     ldr     x1, [x0, #16]
-// CHECK-NEXT:    50004:        02 08 40 f9     ldr     x2, [x0, #16]
-// CHECK-NEXT:    50008:        c0 03 5f d6     ret
+// CHECK-NEXT:    23fff8:        80 00 00 b0     adrp    x0, #69632
+// CHECK-NEXT:    23fffc:        20 70 82 4c     st1     { v0.16b }, [x1], x2
+// CHECK-FIX:     240000:        31 10 00 14     b       #16580
+// CHECK-NOFIX:   240000:        01 08 40 f9     ldr     x1, [x0, #16]
+// CHECK-NEXT:    240004:        02 08 40 f9     ldr     x2, [x0, #16]
+// CHECK-NEXT:    240008:        c0 03 5f d6     ret
         .section .text.24, "ax", %progbits
         .balign 4096
         .globl t3_ff8_ldr_once
@@ -475,14 +475,14 @@
         ldr x2, [x0, #16]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 51FF8 in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 241FF8 in unpatched output.
 // CHECK: t3_ff8_ldxr:
-// CHECK-NEXT:    51ff8:        60 00 00 f0     adrp    x0, #61440
-// CHECK-NEXT:    51ffc:        03 7c 5f c8     ldxr    x3, [x0]
-// CHECK-FIX:     52000:        33 08 00 14     b       #8396
-// CHECK-NOFIX:   52000:        01 08 40 f9     ldr     x1, [x0, #16]
-// CHECK:         52004:        02 08 40 f9     ldr     x2, [x0, #16]
-// CHECK-NEXT:    52008:        c0 03 5f d6     ret
+// CHECK-NEXT:    241ff8:        60 00 00 f0     adrp    x0, #61440
+// CHECK-NEXT:    241ffc:        03 7c 5f c8     ldxr    x3, [x0]
+// CHECK-FIX:     242000:        33 08 00 14     b       #8396
+// CHECK-NOFIX:   242000:        01 08 40 f9     ldr     x1, [x0, #16]
+// CHECK:         242004:        02 08 40 f9     ldr     x2, [x0, #16]
+// CHECK-NEXT:    242008:        c0 03 5f d6     ret
         .section .text.25, "ax", %progbits
         .balign 4096
         .globl t3_ff8_ldxr
@@ -495,14 +495,14 @@
         ldr x2, [x0, #16]
         ret
 
-// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 53FF8 in unpatched output.
+// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 243FF8 in unpatched output.
 // CHECK: t3_ff8_stxr:
-// CHECK-NEXT:    53ff8:        60 00 00 b0     adrp    x0, #53248
-// CHECK-NEXT:    53ffc:        03 7c 04 c8     stxr    w4, x3, [x0]
-// CHECK-FIX:     54000:        35 00 00 14     b       #212
-// CHECK-NOFIX:   54000:        01 08 40 f9     ldr     x1, [x0, #16]
-// CHECK:         54004:        02 08 40 f9     ldr     x2, [x0, #16]
-// CHECK-NEXT:    54008:        c0 03 5f d6     ret
+// CHECK-NEXT:    243ff8:        60 00 00 b0     adrp    x0, #53248
+// CHECK-NEXT:    243ffc:        03 7c 04 c8     stxr    w4, x3, [x0]
+// CHECK-FIX:     244000:        35 00 00 14     b       #212
+// CHECK-NOFIX:   244000:        01 08 40 f9     ldr     x1, [x0, #16]
+// CHECK:         244004:        02 08 40 f9     ldr     x2, [x0, #16]
+// CHECK-NEXT:    244008:        c0 03 5f d6     ret
         .section .text.26, "ax", %progbits
         .balign 4096
         .globl t3_ff8_stxr
@@ -521,84 +521,84 @@
 _start:
         ret
 
-// CHECK-FIX: __CortexA53843419_22000:
-// CHECK-FIX-NEXT:    5400c:    00 00 40 f9     ldr     x0, [x0]
-// CHECK-FIX-NEXT:    54010:    fd 37 ff 17     b       #-204812
-// CHECK-FIX: __CortexA53843419_24000:
-// CHECK-FIX-NEXT:    54014:    02 04 40 f9     ldr     x2, [x0, #8]
-// CHECK-FIX-NEXT:    54018:    fb 3f ff 17     b       #-196628
-// CHECK-FIX: __CortexA53843419_26004:
-// CHECK-FIX-NEXT:    5401c:    03 08 40 f9     ldr     x3, [x0, #16]
-// CHECK-FIX-NEXT:    54020:    fa 47 ff 17     b       #-188440
-// CHECK-FIX: __CortexA53843419_28000:
-// CHECK-FIX-NEXT:    54024:    02 00 40 f9     ldr     x2, [x0]
-// CHECK-FIX-NEXT:    54028:    f7 4f ff 17     b       #-180260
-// CHECK-FIX: __CortexA53843419_2A004:
-// CHECK-FIX-NEXT:    5402c:    9c 07 00 f9     str     x28, [x28, #8]
-// CHECK-FIX-NEXT:    54030:    f6 57 ff 17     b       #-172072
-// CHECK-FIX: __CortexA53843419_2C004:
-// CHECK-FIX-NEXT:    54034:    84 0b 00 f9     str     x4, [x28, #16]
-// CHECK-FIX-NEXT:    54038:    f4 5f ff 17     b       #-163888
-// CHECK-FIX: __CortexA53843419_2E000:
-// CHECK-FIX-NEXT:    5403c:    bd 03 40 f9     ldr     x29, [x29]
-// CHECK-FIX-NEXT:    54040:    f1 67 ff 17     b       #-155708
-// CHECK-FIX: __CortexA53843419_30004:
-// CHECK-FIX-NEXT:    54044:    bd 07 40 f9     ldr     x29, [x29, #8]
-// CHECK-FIX-NEXT:    54048:    f0 6f ff 17     b       #-147520
-// CHECK-FIX: __CortexA53843419_32004:
-// CHECK-FIX-NEXT:    5404c:    41 0a 40 f9     ldr     x1, [x18, #16]
-// CHECK-FIX-NEXT:    54050:    ee 77 ff 17     b       #-139336
-// CHECK-FIX: __CortexA53843419_34000:
-// CHECK-FIX-NEXT:    54054:    52 02 40 f9     ldr     x18, [x18]
-// CHECK-FIX-NEXT:    54058:    eb 7f ff 17     b       #-131156
-// CHECK-FIX: __CortexA53843419_36004:
-// CHECK-FIX-NEXT:    5405c:    ea 05 40 f9     ldr     x10, [x15, #8]
-// CHECK-FIX-NEXT:    54060:    ea 87 ff 17     b       #-122968
-// CHECK-FIX: __CortexA53843419_38000:
-// CHECK-FIX-NEXT:    54064:    0d 0a 40 f9     ldr     x13, [x16, #16]
-// CHECK-FIX-NEXT:    54068:    e7 8f ff 17     b       #-114788
-// CHECK-FIX: __CortexA53843419_3A004:
-// CHECK-FIX-NEXT:    5406c:    e9 00 40 f9     ldr     x9, [x7]
-// CHECK-FIX-NEXT:    54070:    e6 97 ff 17     b       #-106600
-// CHECK-FIX: __CortexA53843419_3C004:
-// CHECK-FIX-NEXT:    54074:    f6 06 40 f9     ldr     x22, [x23, #8]
-// CHECK-FIX-NEXT:    54078:    e4 9f ff 17     b       #-98416
-// CHECK-FIX: __CortexA53843419_3E000:
-// CHECK-FIX-NEXT:    5407c:    f8 0a 40 f9     ldr     x24, [x23, #16]
-// CHECK-FIX-NEXT:    54080:    e1 a7 ff 17     b       #-90236
-// CHECK-FIX: __CortexA53843419_40004:
-// CHECK-FIX-NEXT:    54084:    02 00 40 f9     ldr     x2, [x0]
-// CHECK-FIX-NEXT:    54088:    e0 af ff 17     b       #-82048
-// CHECK-FIX: __CortexA53843419_42008:
-// CHECK-FIX-NEXT:    5408c:    9b 07 00 f9     str     x27, [x28, #8]
-// CHECK-FIX-NEXT:    54090:    df b7 ff 17     b       #-73860
-// CHECK-FIX: __CortexA53843419_44004:
-// CHECK-FIX-NEXT:    54094:    0e 0a 40 f9     ldr     x14, [x16, #16]
-// CHECK-FIX-NEXT:    54098:    dc bf ff 17     b       #-65680
-// CHECK-FIX: __CortexA53843419_46004:
-// CHECK-FIX-NEXT:    5409c:    0e 06 40 f9     ldr     x14, [x16, #8]
-// CHECK-FIX-NEXT:    540a0:    da c7 ff 17     b       #-57496
-// CHECK-FIX: __CortexA53843419_48004:
-// CHECK-FIX-NEXT:    540a4:    0e 06 40 f9     ldr     x14, [x16, #8]
-// CHECK-FIX-NEXT:    540a8:    d8 cf ff 17     b       #-49312
-// CHECK-FIX: __CortexA53843419_4A008:
-// CHECK-FIX-NEXT:    540ac:    0e 06 40 f9     ldr     x14, [x16, #8]
-// CHECK-FIX-NEXT:    540b0:    d7 d7 ff 17     b       #-41124
-// CHECK-FIX: __CortexA53843419_4C008:
-// CHECK-FIX-NEXT:    540b4:    ea 00 40 f9     ldr     x10, [x7]
-// CHECK-FIX-NEXT:    540b8:    d5 df ff 17     b       #-32940
-// CHECK-FIX: __CortexA53843419_4E008:
-// CHECK-FIX-NEXT:    540bc:    18 ff 3f f9     str     x24, [x24, #32760]
-// CHECK-FIX-NEXT:    540c0:    d3 e7 ff 17     b       #-24756
-// CHECK-FIX: __CortexA53843419_50000:
-// CHECK-FIX-NEXT:    540c4:    01 08 40 f9     ldr     x1, [x0, #16]
-// CHECK-FIX-NEXT:    540c8:    cf ef ff 17     b       #-16580
-// CHECK-FIX: __CortexA53843419_52000:
-// CHECK-FIX-NEXT:    540cc:    01 08 40 f9     ldr     x1, [x0, #16]
-// CHECK-FIX-NEXT:    540d0:    cd f7 ff 17     b       #-8396
-// CHECK-FIX: __CortexA53843419_54000:
-// CHECK-FIX-NEXT:    540d4:    01 08 40 f9     ldr     x1, [x0, #16]
-// CHECK-FIX-NEXT:    540d8:    cb ff ff 17     b       #-212
+// CHECK-FIX: __CortexA53843419_212000:
+// CHECK-FIX-NEXT:    24400c:    00 00 40 f9     ldr     x0, [x0]
+// CHECK-FIX-NEXT:    244010:    fd 37 ff 17     b       #-204812
+// CHECK-FIX: __CortexA53843419_214000:
+// CHECK-FIX-NEXT:    244014:    02 04 40 f9     ldr     x2, [x0, #8]
+// CHECK-FIX-NEXT:    244018:    fb 3f ff 17     b       #-196628
+// CHECK-FIX: __CortexA53843419_216004:
+// CHECK-FIX-NEXT:    24401c:    03 08 40 f9     ldr     x3, [x0, #16]
+// CHECK-FIX-NEXT:    244020:    fa 47 ff 17     b       #-188440
+// CHECK-FIX: __CortexA53843419_218000:
+// CHECK-FIX-NEXT:    244024:    02 00 40 f9     ldr     x2, [x0]
+// CHECK-FIX-NEXT:    244028:    f7 4f ff 17     b       #-180260
+// CHECK-FIX: __CortexA53843419_21A004:
+// CHECK-FIX-NEXT:    24402c:    9c 07 00 f9     str     x28, [x28, #8]
+// CHECK-FIX-NEXT:    244030:    f6 57 ff 17     b       #-172072
+// CHECK-FIX: __CortexA53843419_21C004:
+// CHECK-FIX-NEXT:    244034:    84 0b 00 f9     str     x4, [x28, #16]
+// CHECK-FIX-NEXT:    244038:    f4 5f ff 17     b       #-163888
+// CHECK-FIX: __CortexA53843419_21E000:
+// CHECK-FIX-NEXT:    24403c:    bd 03 40 f9     ldr     x29, [x29]
+// CHECK-FIX-NEXT:    244040:    f1 67 ff 17     b       #-155708
+// CHECK-FIX: __CortexA53843419_220004:
+// CHECK-FIX-NEXT:    244044:    bd 07 40 f9     ldr     x29, [x29, #8]
+// CHECK-FIX-NEXT:    244048:    f0 6f ff 17     b       #-147520
+// CHECK-FIX: __CortexA53843419_222004:
+// CHECK-FIX-NEXT:    24404c:    41 0a 40 f9     ldr     x1, [x18, #16]
+// CHECK-FIX-NEXT:    244050:    ee 77 ff 17     b       #-139336
+// CHECK-FIX: __CortexA53843419_224000:
+// CHECK-FIX-NEXT:    244054:    52 02 40 f9     ldr     x18, [x18]
+// CHECK-FIX-NEXT:    244058:    eb 7f ff 17     b       #-131156
+// CHECK-FIX: __CortexA53843419_226004:
+// CHECK-FIX-NEXT:    24405c:    ea 05 40 f9     ldr     x10, [x15, #8]
+// CHECK-FIX-NEXT:    244060:    ea 87 ff 17     b       #-122968
+// CHECK-FIX: __CortexA53843419_228000:
+// CHECK-FIX-NEXT:    244064:    0d 0a 40 f9     ldr     x13, [x16, #16]
+// CHECK-FIX-NEXT:    244068:    e7 8f ff 17     b       #-114788
+// CHECK-FIX: __CortexA53843419_22A004:
+// CHECK-FIX-NEXT:    24406c:    e9 00 40 f9     ldr     x9, [x7]
+// CHECK-FIX-NEXT:    244070:    e6 97 ff 17     b       #-106600
+// CHECK-FIX: __CortexA53843419_22C004:
+// CHECK-FIX-NEXT:    244074:    f6 06 40 f9     ldr     x22, [x23, #8]
+// CHECK-FIX-NEXT:    244078:    e4 9f ff 17     b       #-98416
+// CHECK-FIX: __CortexA53843419_22E000:
+// CHECK-FIX-NEXT:    24407c:    f8 0a 40 f9     ldr     x24, [x23, #16]
+// CHECK-FIX-NEXT:    244080:    e1 a7 ff 17     b       #-90236
+// CHECK-FIX: __CortexA53843419_230004:
+// CHECK-FIX-NEXT:    244084:    02 00 40 f9     ldr     x2, [x0]
+// CHECK-FIX-NEXT:    244088:    e0 af ff 17     b       #-82048
+// CHECK-FIX: __CortexA53843419_232008:
+// CHECK-FIX-NEXT:    24408c:    9b 07 00 f9     str     x27, [x28, #8]
+// CHECK-FIX-NEXT:    244090:    df b7 ff 17     b       #-73860
+// CHECK-FIX: __CortexA53843419_234004:
+// CHECK-FIX-NEXT:    244094:    0e 0a 40 f9     ldr     x14, [x16, #16]
+// CHECK-FIX-NEXT:    244098:    dc bf ff 17     b       #-65680
+// CHECK-FIX: __CortexA53843419_236004:
+// CHECK-FIX-NEXT:    24409c:    0e 06 40 f9     ldr     x14, [x16, #8]
+// CHECK-FIX-NEXT:    2440a0:    da c7 ff 17     b       #-57496
+// CHECK-FIX: __CortexA53843419_238004:
+// CHECK-FIX-NEXT:    2440a4:    0e 06 40 f9     ldr     x14, [x16, #8]
+// CHECK-FIX-NEXT:    2440a8:    d8 cf ff 17     b       #-49312
+// CHECK-FIX: __CortexA53843419_23A008:
+// CHECK-FIX-NEXT:    2440ac:    0e 06 40 f9     ldr     x14, [x16, #8]
+// CHECK-FIX-NEXT:    2440b0:    d7 d7 ff 17     b       #-41124
+// CHECK-FIX: __CortexA53843419_23C008:
+// CHECK-FIX-NEXT:    2440b4:    ea 00 40 f9     ldr     x10, [x7]
+// CHECK-FIX-NEXT:    2440b8:    d5 df ff 17     b       #-32940
+// CHECK-FIX: __CortexA53843419_23E008:
+// CHECK-FIX-NEXT:    2440bc:    18 ff 3f f9     str     x24, [x24, #32760]
+// CHECK-FIX-NEXT:    2440c0:    d3 e7 ff 17     b       #-24756
+// CHECK-FIX: __CortexA53843419_240000:
+// CHECK-FIX-NEXT:    2440c4:    01 08 40 f9     ldr     x1, [x0, #16]
+// CHECK-FIX-NEXT:    2440c8:    cf ef ff 17     b       #-16580
+// CHECK-FIX: __CortexA53843419_242000:
+// CHECK-FIX-NEXT:    2440cc:    01 08 40 f9     ldr     x1, [x0, #16]
+// CHECK-FIX-NEXT:    2440d0:    cd f7 ff 17     b       #-8396
+// CHECK-FIX: __CortexA53843419_244000:
+// CHECK-FIX-NEXT:    2440d4:    01 08 40 f9     ldr     x1, [x0, #16]
+// CHECK-FIX-NEXT:    2440d8:    cb ff ff 17     b       #-212
         .data
         .globl dat
         .globl dat2
diff --git a/test/ELF/aarch64-data-relocs.s b/test/ELF/aarch64-data-relocs.s
index d328715..c276975 100644
--- a/test/ELF/aarch64-data-relocs.s
+++ b/test/ELF/aarch64-data-relocs.s
@@ -12,7 +12,7 @@
 // S = 0x100, A = 0x24
 // S + A = 0x124
 // CHECK: Contents of section .R_AARCH64_ABS64:
-// CHECK-NEXT: 20000 24010000 00000000
+// CHECK-NEXT: 210000 24010000 00000000
 
 .section .R_AARCH64_PREL64, "ax",@progbits
   .xword foo - . + 0x24
@@ -20,4 +20,4 @@
 // S = 0x100, A = 0x24, P = 0x20008
 // S + A - P = 0xfffffffffffe011c
 // CHECK: Contents of section .R_AARCH64_PREL64:
-// CHECK-NEXT: 20008 1c01feff ffffffff
+// CHECK-NEXT: 210008 1c01dfff ffffffff
diff --git a/test/ELF/aarch64-gnu-ifunc-plt.s b/test/ELF/aarch64-gnu-ifunc-plt.s
index ca30316..381bcf7 100644
--- a/test/ELF/aarch64-gnu-ifunc-plt.s
+++ b/test/ELF/aarch64-gnu-ifunc-plt.s
@@ -10,19 +10,19 @@
 // Check that the IRELATIVE relocations are after the JUMP_SLOT in the plt
 // CHECK: Relocations [
 // CHECK-NEXT:   Section (4) .rela.plt {
-// CHECK:     0x30018 R_AARCH64_JUMP_SLOT bar2 0x0
-// CHECK-NEXT:     0x30020 R_AARCH64_JUMP_SLOT zed2 0x0
-// CHECK-NEXT:     0x30028 R_AARCH64_IRELATIVE - 0x20000
-// CHECK-NEXT:     0x30030 R_AARCH64_IRELATIVE - 0x20004
+// CHECK:     0x220018 R_AARCH64_JUMP_SLOT bar2 0x0
+// CHECK-NEXT:     0x220020 R_AARCH64_JUMP_SLOT zed2 0x0
+// CHECK-NEXT:     0x220028 R_AARCH64_IRELATIVE - 0x210000
+// CHECK-NEXT:     0x220030 R_AARCH64_IRELATIVE - 0x210004
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]
 
 // Check that .got.plt entries point back to PLT header
 // GOTPLT: Contents of section .got.plt:
-// GOTPLT-NEXT:  30000 00000000 00000000 00000000 00000000
-// GOTPLT-NEXT:  30010 00000000 00000000 20000200 00000000
-// GOTPLT-NEXT:  30020 20000200 00000000 20000200 00000000
-// GOTPLT-NEXT:  30030 20000200 00000000
+// GOTPLT-NEXT:  220000 00000000 00000000 00000000 00000000
+// GOTPLT-NEXT:  220010 00000000 00000000 20002100 00000000
+// GOTPLT-NEXT:  220020 20002100 00000000 20002100 00000000
+// GOTPLT-NEXT:  220030 20002100 00000000
 
 // Check that the PLTRELSZ tag includes the IRELATIVE relocations
 // CHECK: DynamicSection [
@@ -31,40 +31,44 @@
 // Check that a PLT header is written and the ifunc entries appear last
 // DISASM: Disassembly of section .text:
 // DISASM-NEXT: foo:
-// DISASM-NEXT:    20000: {{.*}} ret
+// DISASM-NEXT:    210000: {{.*}} ret
 // DISASM:      bar:
-// DISASM-NEXT:    20004: {{.*}} ret
+// DISASM-NEXT:    210004: {{.*}} ret
 // DISASM:      _start:
-// DISASM-NEXT:    20008: {{.*}} bl      #88
-// DISASM-NEXT:    2000c: {{.*}} bl      #100
-// DISASM-NEXT:    20010: {{.*}} bl      #48
-// DISASM-NEXT:    20014: {{.*}} bl      #60
+// DISASM-NEXT:    210008: {{.*}} bl      #88
+// DISASM-NEXT:    21000c: {{.*}} bl      #100
+// DISASM-NEXT:    210010: {{.*}} bl      #48
+// DISASM-NEXT:    210014: {{.*}} bl      #60
 // DISASM-NEXT: Disassembly of section .plt:
 // DISASM-NEXT: .plt:
-// DISASM-NEXT:    20020: {{.*}} stp     x16, x30, [sp, #-16]!
-// DISASM-NEXT:    20024: {{.*}} adrp    x16, #65536
-// DISASM-NEXT:    20028: {{.*}} ldr     x17, [x16, #16]
-// DISASM-NEXT:    2002c: {{.*}} add     x16, x16, #16
-// DISASM-NEXT:    20030: {{.*}} br      x17
-// DISASM-NEXT:    20034: {{.*}} nop
-// DISASM-NEXT:    20038: {{.*}} nop
-// DISASM-NEXT:    2003c: {{.*}} nop
-// DISASM-NEXT:    20040: {{.*}} adrp    x16, #65536
-// DISASM-NEXT:    20044: {{.*}} ldr     x17, [x16, #24]
-// DISASM-NEXT:    20048: {{.*}} add     x16, x16, #24
-// DISASM-NEXT:    2004c: {{.*}} br      x17
-// DISASM-NEXT:    20050: {{.*}} adrp    x16, #65536
-// DISASM-NEXT:    20054: {{.*}} ldr     x17, [x16, #32]
-// DISASM-NEXT:    20058: {{.*}} add     x16, x16, #32
-// DISASM-NEXT:    2005c: {{.*}} br      x17
-// DISASM-NEXT:    20060: {{.*}} adrp    x16, #65536
-// DISASM-NEXT:    20064: {{.*}} ldr     x17, [x16, #40]
-// DISASM-NEXT:    20068: {{.*}} add     x16, x16, #40
-// DISASM-NEXT:    2006c: {{.*}} br      x17
-// DISASM-NEXT:    20070: {{.*}} adrp    x16, #65536
-// DISASM-NEXT:    20074: {{.*}} ldr     x17, [x16, #48]
-// DISASM-NEXT:    20078: {{.*}} add     x16, x16, #48
-// DISASM-NEXT:    2007c: {{.*}} br      x17
+// DISASM-NEXT:    210020: {{.*}} stp     x16, x30, [sp, #-16]!
+// DISASM-NEXT:    210024: {{.*}} adrp    x16, #65536
+// DISASM-NEXT:    210028: {{.*}} ldr     x17, [x16, #16]
+// DISASM-NEXT:    21002c: {{.*}} add     x16, x16, #16
+// DISASM-NEXT:    210030: {{.*}} br      x17
+// DISASM-NEXT:    210034: {{.*}} nop
+// DISASM-NEXT:    210038: {{.*}} nop
+// DISASM-NEXT:    21003c: {{.*}} nop
+// DISASM-EMPTY:
+// DISASM-NEXT:   bar2@plt:
+// DISASM-NEXT:    210040: {{.*}} adrp    x16, #65536
+// DISASM-NEXT:    210044: {{.*}} ldr     x17, [x16, #24]
+// DISASM-NEXT:    210048: {{.*}} add     x16, x16, #24
+// DISASM-NEXT:    21004c: {{.*}} br      x17
+// DISASM-EMPTY:
+// DISASM-NEXT:   zed2@plt:
+// DISASM-NEXT:    210050: {{.*}} adrp    x16, #65536
+// DISASM-NEXT:    210054: {{.*}} ldr     x17, [x16, #32]
+// DISASM-NEXT:    210058: {{.*}} add     x16, x16, #32
+// DISASM-NEXT:    21005c: {{.*}} br      x17
+// DISASM-NEXT:    210060: {{.*}} adrp    x16, #65536
+// DISASM-NEXT:    210064: {{.*}} ldr     x17, [x16, #40]
+// DISASM-NEXT:    210068: {{.*}} add     x16, x16, #40
+// DISASM-NEXT:    21006c: {{.*}} br      x17
+// DISASM-NEXT:    210070: {{.*}} adrp    x16, #65536
+// DISASM-NEXT:    210074: {{.*}} ldr     x17, [x16, #48]
+// DISASM-NEXT:    210078: {{.*}} add     x16, x16, #48
+// DISASM-NEXT:    21007c: {{.*}} br      x17
 
 .text
 .type foo STT_GNU_IFUNC
diff --git a/test/ELF/aarch64-gnu-ifunc.s b/test/ELF/aarch64-gnu-ifunc.s
index b3c1571..f889b9d 100644
--- a/test/ELF/aarch64-gnu-ifunc.s
+++ b/test/ELF/aarch64-gnu-ifunc.s
@@ -22,8 +22,8 @@
 // CHECK-NEXT: }
 // CHECK:      Relocations [
 // CHECK-NEXT:   Section ({{.*}}) .rela.plt {
-// CHECK-NEXT:     0x30000 R_AARCH64_IRELATIVE
-// CHECK-NEXT:     0x30008 R_AARCH64_IRELATIVE
+// CHECK-NEXT:     0x220000 R_AARCH64_IRELATIVE
+// CHECK-NEXT:     0x220008 R_AARCH64_IRELATIVE
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]
 // CHECK:      Symbols [
@@ -38,7 +38,7 @@
 // CHECK-NEXT:  }
 // CHECK-NEXT:  Symbol {
 // CHECK-NEXT:    Name: $x.0
-// CHECK-NEXT:    Value: 0x20000
+// CHECK-NEXT:    Value: 0x210000
 // CHECK-NEXT:    Size: 0
 // CHECK-NEXT:    Binding: Local
 // CHECK-NEXT:    Type: None
@@ -47,7 +47,7 @@
 // CHECK-NEXT:  }
 // CHECK-NEXT:  Symbol {
 // CHECK-NEXT:    Name: __rela_iplt_end
-// CHECK-NEXT:    Value: 0x10188
+// CHECK-NEXT:    Value: 0x200188
 // CHECK-NEXT:    Size: 0
 // CHECK-NEXT:    Binding: Local
 // CHECK-NEXT:    Type: None
@@ -58,7 +58,7 @@
 // CHECK-NEXT:  }
 // CHECK-NEXT:  Symbol {
 // CHECK-NEXT:    Name: __rela_iplt_start
-// CHECK-NEXT:    Value: 0x10158
+// CHECK-NEXT:    Value: 0x200158
 // CHECK-NEXT:    Size: 0
 // CHECK-NEXT:    Binding: Local
 // CHECK-NEXT:    Type: None
@@ -69,7 +69,7 @@
 // CHECK-NEXT:  }
 // CHECK-NEXT:  Symbol {
 // CHECK-NEXT:    Name: _start
-// CHECK-NEXT:    Value: 0x20008
+// CHECK-NEXT:    Value: 0x210008
 // CHECK-NEXT:    Size: 0
 // CHECK-NEXT:    Binding: Global
 // CHECK-NEXT:    Type: None
@@ -78,7 +78,7 @@
 // CHECK-NEXT:  }
 // CHECK-NEXT:  Symbol {
 // CHECK-NEXT:    Name: bar
-// CHECK-NEXT:    Value: 0x20004
+// CHECK-NEXT:    Value: 0x210004
 // CHECK-NEXT:    Size: 0
 // CHECK-NEXT:    Binding: Global
 // CHECK-NEXT:    Type: GNU_IFunc
@@ -87,7 +87,7 @@
 // CHECK-NEXT:  }
 // CHECK-NEXT:  Symbol {
 // CHECK-NEXT:    Name: foo
-// CHECK-NEXT:    Value: 0x20000
+// CHECK-NEXT:    Value: 0x210000
 // CHECK-NEXT:    Size: 0
 // CHECK-NEXT:    Binding: Global
 // CHECK-NEXT:    Type: GNU_IFunc
@@ -101,24 +101,24 @@
 
 // DISASM: Disassembly of section .text:
 // DISASM-NEXT: foo:
-// DISASM-NEXT:  20000: c0 03 5f d6 ret
+// DISASM-NEXT:  210000: c0 03 5f d6 ret
 // DISASM: bar:
-// DISASM-NEXT:  20004: c0 03 5f d6 ret
+// DISASM-NEXT:  210004: c0 03 5f d6 ret
 // DISASM:      _start:
-// DISASM-NEXT:  20008: 06 00 00 94 bl #24
-// DISASM-NEXT:  2000c: 09 00 00 94     bl      #36
-// DISASM-NEXT:  20010: 42 60 05 91     add     x2, x2, #344
-// DISASM-NEXT:  20014: 42 20 06 91     add     x2, x2, #392
+// DISASM-NEXT:  210008: 06 00 00 94 bl #24
+// DISASM-NEXT:  21000c: 09 00 00 94     bl      #36
+// DISASM-NEXT:  210010: 42 60 05 91     add     x2, x2, #344
+// DISASM-NEXT:  210014: 42 20 06 91     add     x2, x2, #392
 // DISASM-NEXT: Disassembly of section .plt:
 // DISASM-NEXT: .plt:
-// DISASM-NEXT:  20020: 90 00 00 90 adrp x16, #65536
-// DISASM-NEXT:  20024: 11 02 40 f9 ldr x17, [x16]
-// DISASM-NEXT:  20028: 10 02 00 91 add x16, x16, #0
-// DISASM-NEXT:  2002c: 20 02 1f d6 br x17
-// DISASM-NEXT:  20030: 90 00 00 90 adrp x16, #65536
-// DISASM-NEXT:  20034: 11 06 40 f9 ldr x17, [x16, #8]
-// DISASM-NEXT:  20038: 10 22 00 91 add x16, x16, #8
-// DISASM-NEXT:  2003c: 20 02 1f d6 br x17
+// DISASM-NEXT:  210020: 90 00 00 90 adrp x16, #65536
+// DISASM-NEXT:  210024: 11 02 40 f9 ldr x17, [x16]
+// DISASM-NEXT:  210028: 10 02 00 91 add x16, x16, #0
+// DISASM-NEXT:  21002c: 20 02 1f d6 br x17
+// DISASM-NEXT:  210030: 90 00 00 90 adrp x16, #65536
+// DISASM-NEXT:  210034: 11 06 40 f9 ldr x17, [x16, #8]
+// DISASM-NEXT:  210038: 10 22 00 91 add x16, x16, #8
+// DISASM-NEXT:  21003c: 20 02 1f d6 br x17
 
 .text
 .type foo STT_GNU_IFUNC
diff --git a/test/ELF/aarch64-jump26-thunk.s b/test/ELF/aarch64-jump26-thunk.s
index 13c084a..a381c70 100644
--- a/test/ELF/aarch64-jump26-thunk.s
+++ b/test/ELF/aarch64-jump26-thunk.s
@@ -11,10 +11,10 @@
 
 // CHECK: Disassembly of section .text:
 // CHECK-NEXT: _start:
-// CHECK-NEXT:    20000:        02 00 00 14     b       #8
+// CHECK-NEXT:    210000:        02 00 00 14     b       #8
 // CHECK: __AArch64AbsLongThunk_big:
-// CHECK-NEXT:    20008:        50 00 00 58     ldr     x16, #8
-// CHECK-NEXT:    2000c:        00 02 1f d6     br      x16
+// CHECK-NEXT:    210008:        50 00 00 58     ldr     x16, #8
+// CHECK-NEXT:    21000c:        00 02 1f d6     br      x16
 // CHECK: $d:
-// CHECK-NEXT:    20010:        00 00 00 00     .word   0x00000000
-// CHECK-NEXT:    20014:        10 00 00 00     .word   0x00000010
+// CHECK-NEXT:    210010:        00 00 00 00     .word   0x00000000
+// CHECK-NEXT:    210014:        10 00 00 00     .word   0x00000010
diff --git a/test/ELF/aarch64-lo12-alignment.s b/test/ELF/aarch64-lo12-alignment.s
index 7edecd4..a7ed997 100644
--- a/test/ELF/aarch64-lo12-alignment.s
+++ b/test/ELF/aarch64-lo12-alignment.s
@@ -39,7 +39,7 @@
 foo8:
  .space 8
 
-// CHECK: improper alignment for relocation R_AARCH64_LDST16_ABS_LO12_NC: 0x30001 is not aligned to 2 bytes
-// CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST32_ABS_LO12_NC: 0x30002 is not aligned to 4 bytes
-// CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST64_ABS_LO12_NC: 0x30004 is not aligned to 8 bytes
-// CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST128_ABS_LO12_NC: 0x30008 is not aligned to 16 bytes
+// CHECK: improper alignment for relocation R_AARCH64_LDST16_ABS_LO12_NC: 0x220001 is not aligned to 2 bytes
+// CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST32_ABS_LO12_NC: 0x220002 is not aligned to 4 bytes
+// CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST64_ABS_LO12_NC: 0x220004 is not aligned to 8 bytes
+// CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST128_ABS_LO12_NC: 0x220008 is not aligned to 16 bytes
diff --git a/test/ELF/aarch64-prel16.s b/test/ELF/aarch64-prel16.s
index fc34f01..18a594c 100644
--- a/test/ELF/aarch64-prel16.s
+++ b/test/ELF/aarch64-prel16.s
@@ -7,8 +7,8 @@
 .globl _start
 _start:
 .data
-  .hword foo - . + 0x20eff
-  .hword foo - . + 0x8f02
+  .hword foo - . + 0x210eff
+  .hword foo - . + 0x1f8f02
 
 // Note: If this test fails, it probably happens because of
 //       the change of the address of the .data section.
@@ -18,14 +18,14 @@
 // RUN: llvm-objdump -s -section=.data %t2 | FileCheck %s
 
 // CHECK: Contents of section .data:
-// 11000: S = 0x100, A = 0x20eff, P = 0x11000
-//        S + A - P = 0xffff
-// 11002: S = 0x100, A = 0x8f02, P = 0x11002
-//        S + A - P = 0x8000
-// CHECK-NEXT: 11000 ffff0080
+// 201000: S = 0x100, A = 0x210eff, P = 0x201000
+//         S + A - P = 0xffff
+// 201002: S = 0x100, A = 0x1f8f02, P = 0x201002
+//         S + A - P = 0x8000
+// CHECK-NEXT: 201000 ffff0080
 
-// RUN: not ld.lld %t.o %t255.o -o %t2
-//   | FileCheck %s --check-prefix=OVERFLOW
-// RUN: not ld.lld %t.o %t257.o -o %t2
-//   | FileCheck %s --check-prefix=OVERFLOW
-// OVERFLOW: Relocation R_AARCH64_PREL16 out of range: -94209 is not in [-32768, 65535]
+// RUN: not ld.lld -z max-page-size=4096 %t.o %t255.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
+// OVERFLOW1: relocation R_AARCH64_PREL16 out of range: -32769 is not in [-32768, 32767]
+
+// RUN: not ld.lld -z max-page-size=4096 %t.o %t257.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
+// OVERFLOW2: relocation R_AARCH64_PREL16 out of range: 65536 is not in [-32768, 32767]
diff --git a/test/ELF/aarch64-prel32.s b/test/ELF/aarch64-prel32.s
index 7aa2903..16c8bb3 100644
--- a/test/ELF/aarch64-prel32.s
+++ b/test/ELF/aarch64-prel32.s
@@ -7,8 +7,8 @@
 .globl _start
 _start:
 .data
-  .word foo - . + 0x100010eff
-  .word foo - . - 0x7ffef0fc
+  .word foo - . + 0x100200eff
+  .word foo - . - 0x7fdff0fc
 
 // Note: If this test fails, it probably happens because of
 //       the change of the address of the .data section.
@@ -18,14 +18,14 @@
 // RUN: llvm-objdump -s -section=.data %t2 | FileCheck %s
 
 // CHECK: Contents of section .data:
-// 11000: S = 0x100, A = 0x100010eff, P = 0x11000
-//        S + A - P = 0xffffffff
-// 11004: S = 0x100, A = -0x7ffef0fc, P = 0x11004
-//        S + A - P = 0x80000000
-// CHECK-NEXT: 11000 ffffffff 00000080
+// 201000: S = 0x100, A = 0x100200eff, P = 0x201000
+//         S + A - P = 0xffffffff
+// 201004: S = 0x100, A = -0x7fdff0fc, P = 0x201004
+//         S + A - P = 0x80000000
+// CHECK-NEXT: 201000 ffffffff 00000080
 
-// RUN: not ld.lld %t.o %t255.o -o %t2
-//   | FileCheck %s --check-prefix=OVERFLOW
-// RUN: not ld.lld %t.o %t257.o -o %t2
-//   | FileCheck %s --check-prefix=OVERFLOW
-// OVERFLOW: Relocation R_AARCH64_PREL32 out of range: 18446744071562006527 is not in [-2147483648, 4294967295]
+// RUN: not ld.lld -z max-page-size=4096 %t.o %t255.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
+// OVERFLOW1: relocation R_AARCH64_PREL32 out of range: -2147483649 is not in [-2147483648, 2147483647]
+
+// RUN: not ld.lld -z max-page-size=4096 %t.o %t257.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
+// OVERFLOW2: relocation R_AARCH64_PREL32 out of range: 4294967296 is not in [-2147483648, 2147483647]
diff --git a/test/ELF/aarch64-relocs.s b/test/ELF/aarch64-relocs.s
index 79caabc..93a67c0 100644
--- a/test/ELF/aarch64-relocs.s
+++ b/test/ELF/aarch64-relocs.s
@@ -24,13 +24,13 @@
   .asciz "blah"
   .size mystr, 4
 
-# S = 0x20012, A = 0x4, P = 0x20012
-# PAGE(S + A) = 0x11000
-# PAGE(P) = 0x11000
+# S = 0x210012, A = 0x4, P = 0x210012
+# PAGE(S + A) = 0x210000
+# PAGE(P) = 0x210000
 #
 # CHECK: Disassembly of section .R_AARCH64_ADR_PREL_PG_H121:
 # CHECK-NEXT: $x.2:
-# CHECK-NEXT:   20012:       01 00 00 90     adrp    x1, #0
+# CHECK-NEXT:   210012:       01 00 00 90     adrp    x1, #0
 
 .section .R_AARCH64_ADD_ABS_LO12_NC,"ax",@progbits
   add x0, x0, :lo12:.L.str
@@ -38,13 +38,13 @@
   .asciz "blah"
   .size mystr, 4
 
-# S = 0x2001b, A = 0x4
+# S = 0x21001b, A = 0x4
 # R = (S + A) & 0xFFF = 0x1f
 # R << 10 = 0x7c00
 #
 # CHECK: Disassembly of section .R_AARCH64_ADD_ABS_LO12_NC:
 # CHECK-NEXT: $x.4:
-# CHECK-NEXT:   2001b:       00 7c 00 91     add     x0, x0, #31
+# CHECK-NEXT:   21001b:       00 7c 00 91     add     x0, x0, #31
 
 .section .R_AARCH64_LDST64_ABS_LO12_NC,"ax",@progbits
   ldr x28, [x27, :lo12:foo]
@@ -52,12 +52,12 @@
   .asciz "foo"
   .size mystr, 3
 
-# S = 0x20024, A = 0x4
+# S = 0x210024, A = 0x4
 # R = ((S + A) & 0xFFF) << 7 = 0x00001400
 # 0x00001400 | 0xf940177c = 0xf940177c
 # CHECK: Disassembly of section .R_AARCH64_LDST64_ABS_LO12_NC:
 # CHECK-NEXT: $x.6:
-# CHECK-NEXT:   20024:       7c 17 40 f9     ldr     x28, [x27, #40]
+# CHECK-NEXT:   210024:       7c 17 40 f9     ldr     x28, [x27, #40]
 
 .section .SUB,"ax",@progbits
   nop
@@ -66,33 +66,33 @@
 
 # CHECK: Disassembly of section .SUB:
 # CHECK-NEXT: $x.8:
-# CHECK-NEXT:   2002c:       1f 20 03 d5     nop
+# CHECK-NEXT:   21002c:       1f 20 03 d5     nop
 # CHECK: sub:
-# CHECK-NEXT:   20030:       1f 20 03 d5     nop
+# CHECK-NEXT:   210030:       1f 20 03 d5     nop
 
 .section .R_AARCH64_CALL26,"ax",@progbits
 call26:
         bl sub
 
-# S = 0x2002c, A = 0x4, P = 0x20034
+# S = 0x21002c, A = 0x4, P = 0x210034
 # R = S + A - P = -0x4 = 0xfffffffc
 # (R & 0x0ffffffc) >> 2 = 0x03ffffff
 # 0x94000000 | 0x03ffffff = 0x97ffffff
 # CHECK: Disassembly of section .R_AARCH64_CALL26:
 # CHECK-NEXT: call26:
-# CHECK-NEXT:   20034:       ff ff ff 97     bl     #-4
+# CHECK-NEXT:   210034:       ff ff ff 97     bl     #-4
 
 .section .R_AARCH64_JUMP26,"ax",@progbits
 jump26:
         b sub
 
-# S = 0x2002c, A = 0x4, P = 0x20038
+# S = 0x21002c, A = 0x4, P = 0x210038
 # R = S + A - P = -0x8 = 0xfffffff8
 # (R & 0x0ffffffc) >> 2 = 0x03fffffe
 # 0x14000000 | 0x03fffffe = 0x17fffffe
 # CHECK: Disassembly of section .R_AARCH64_JUMP26:
 # CHECK-NEXT: jump26:
-# CHECK-NEXT:   20038:       fe ff ff 17     b      #-8
+# CHECK-NEXT:   210038:       fe ff ff 17     b      #-8
 
 .section .R_AARCH64_LDST32_ABS_LO12_NC,"ax",@progbits
 ldst32:
@@ -101,12 +101,12 @@
   .asciz "foo"
   .size mystr, 3
 
-# S = 0x2003c, A = 0x4
+# S = 0x21003c, A = 0x4
 # R = ((S + A) & 0xFFC) << 8 = 0x00004000
 # 0x00004000 | 0xbd4000a4 = 0xbd4040a4
 # CHECK: Disassembly of section .R_AARCH64_LDST32_ABS_LO12_NC:
 # CHECK-NEXT: ldst32:
-# CHECK-NEXT:   2003c:       a4 40 40 bd     ldr s4, [x5, #64]
+# CHECK-NEXT:   21003c:       a4 40 40 bd     ldr s4, [x5, #64]
 
 .section .R_AARCH64_LDST8_ABS_LO12_NC,"ax",@progbits
 ldst8:
@@ -115,12 +115,12 @@
   .asciz "foo"
   .size mystr, 3
 
-# S = 0x20044, A = 0x4
+# S = 0x210044, A = 0x4
 # R = ((S + A) & 0xFFF) << 10 = 0x00012000
 # 0x00012000 | 0x398001ab = 0x398121ab
 # CHECK: Disassembly of section .R_AARCH64_LDST8_ABS_LO12_NC:
 # CHECK-NEXT: ldst8:
-# CHECK-NEXT:   20044:       ab 21 81 39     ldrsb x11, [x13, #72]
+# CHECK-NEXT:   210044:       ab 21 81 39     ldrsb x11, [x13, #72]
 
 .section .R_AARCH64_LDST128_ABS_LO12_NC,"ax",@progbits
 ldst128:
@@ -129,14 +129,14 @@
   .asciz "foo"
   .size mystr, 3
 
-# S = 0x2004c, A = 0x4
+# S = 0x21004c, A = 0x4
 # R = ((S + A) & 0xFF8) << 6 = 0x00001400
 # 0x00001400 | 0x3dc00274 = 0x3dc01674
 # CHECK: Disassembly of section .R_AARCH64_LDST128_ABS_LO12_NC:
 # CHECK: ldst128:
-# CHECK:   2004c:       74 16 c0 3d     ldr     q20, [x19, #80]
+# CHECK:   21004c:       74 16 c0 3d     ldr     q20, [x19, #80]
 #foo128:
-#   20050:       66 6f 6f 00     .word
+#   210050:       66 6f 6f 00     .word
 
 .section .R_AARCH64_LDST16_ABS_LO12_NC,"ax",@progbits
 ldst16:
@@ -147,14 +147,14 @@
   .asciz "foo"
   .size mystr, 4
 
-# S = 0x20054, A = 0x4
+# S = 0x210054, A = 0x4
 # R = ((S + A) & 0x0FFC) << 9 = 0xb000
 # 0xb000 | 0x7d400271 = 0x7d40b271
 # CHECK: Disassembly of section .R_AARCH64_LDST16_ABS_LO12_NC:
 # CHECK-NEXT: ldst16:
-# CHECK-NEXT:   20054:       71 c2 40 7d     ldr     h17, [x19, #96]
-# CHECK-NEXT:   20058:       61 c2 40 79     ldrh    w1, [x19, #96]
-# CHECK-NEXT:   2005c:       62 c6 40 79     ldrh    w2, [x19, #98]
+# CHECK-NEXT:   210054:       71 c2 40 7d     ldr     h17, [x19, #96]
+# CHECK-NEXT:   210058:       61 c2 40 79     ldrh    w1, [x19, #96]
+# CHECK-NEXT:   21005c:       62 c6 40 79     ldrh    w2, [x19, #98]
 
 .section .R_AARCH64_MOVW_UABS,"ax",@progbits
 movz1:
diff --git a/test/ELF/aarch64-thunk-pi.s b/test/ELF/aarch64-thunk-pi.s
index d5d956c..345e6ee 100644
--- a/test/ELF/aarch64-thunk-pi.s
+++ b/test/ELF/aarch64-thunk-pi.s
@@ -81,10 +81,14 @@
 // CHECK-NEXT: 10000034:       1f 20 03 d5     nop
 // CHECK-NEXT: 10000038:       1f 20 03 d5     nop
 // CHECK-NEXT: 1000003c:       1f 20 03 d5     nop
+// CHECK-EMPTY:
+// CHECK-NEXT:   high_target@plt:
 // CHECK-NEXT: 10000040:       10 00 00 90     adrp    x16, #0
 // CHECK-NEXT: 10000044:       11 3e 40 f9     ldr     x17, [x16, #120]
 // CHECK-NEXT: 10000048:       10 e2 01 91     add     x16, x16, #120
 // CHECK-NEXT: 1000004c:       20 02 1f d6     br      x17
+// CHECK-EMPTY:
+// CHECK-NEXT:   low_target@plt:
 // CHECK-NEXT: 10000050:       10 00 00 90     adrp    x16, #0
 // CHECK-NEXT: 10000054:       11 42 40 f9     ldr     x17, [x16, #128]
 // CHECK-NEXT: 10000058:       10 02 02 91     add     x16, x16, #128
diff --git a/test/ELF/aarch64-thunk-section-location.s b/test/ELF/aarch64-thunk-section-location.s
index 606c694..36ba338 100644
--- a/test/ELF/aarch64-thunk-section-location.s
+++ b/test/ELF/aarch64-thunk-section-location.s
@@ -1,7 +1,7 @@
 // REQUIRES: aarch64
 // RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t
 // RUN: ld.lld %t -o %t2 2>&1
-// RUN: llvm-objdump -d  -start-address=134086664 -stop-address=134086676 -triple=aarch64-linux-gnu %t2 | FileCheck %s
+// RUN: llvm-objdump -d  -start-address=136118280 -stop-address=136118292 -triple=aarch64-linux-gnu %t2 | FileCheck %s
 // Check that the range extension thunks are dumped close to the aarch64 branch
 // range of 128 MiB
  .section .text.1, "ax", %progbits
@@ -35,7 +35,7 @@
  ret
 
 // CHECK: __AArch64AbsLongThunk_high_target:
-// CHECK-NEXT:  7fe0008:        50 00 00 58     ldr     x16, #8
-// CHECK-NEXT:  7fe000c:        00 02 1f d6     br      x16
+// CHECK-NEXT:  81d0008:        50 00 00 58     ldr     x16, #8
+// CHECK-NEXT:  81d000c:        00 02 1f d6     br      x16
 // CHECK: $d:
-// CHECK-NEXT:  7fe0010:        00 10 02 08     .word   0x08021000
+// CHECK-NEXT:  81d0010:        00 10 21 08     .word   0x08211000
diff --git a/test/ELF/aarch64-tls-gdie.s b/test/ELF/aarch64-tls-gdie.s
index ab7461a..3b795f6 100644
--- a/test/ELF/aarch64-tls-gdie.s
+++ b/test/ELF/aarch64-tls-gdie.s
@@ -21,14 +21,14 @@
 // SEC-NEXT:   SHF_ALLOC
 // SEC-NEXT:   SHF_WRITE
 // SEC-NEXT: ]
-// SEC-NEXT: Address: 0x300B0
+// SEC-NEXT: Address: 0x2200B0
 
-// page(0x300B0) - page(0x20004) = 65536
+// page(0x2200B0) - page(0x20004) = 65536
 // 0x0B0 = 176
 
 // CHECK:      _start:
-// CHECK-NEXT: 20000: {{.*}} nop
-// CHECK-NEXT: 20004: {{.*}} adrp       x0, #65536
-// CHECK-NEXT: 20008: {{.*}} ldr        x0, [x0, #176]
-// CHECK-NEXT: 2000c: {{.*}} nop
-// CHECK-NEXT: 20010: {{.*}} nop
+// CHECK-NEXT: 210000: {{.*}} nop
+// CHECK-NEXT: 210004: {{.*}} adrp       x0, #65536
+// CHECK-NEXT: 210008: {{.*}} ldr        x0, [x0, #176]
+// CHECK-NEXT: 21000c: {{.*}} nop
+// CHECK-NEXT: 210010: {{.*}} nop
diff --git a/test/ELF/aarch64-tls-gdle.s b/test/ELF/aarch64-tls-gdle.s
index 6763c50..e91d397 100644
--- a/test/ELF/aarch64-tls-gdle.s
+++ b/test/ELF/aarch64-tls-gdle.s
@@ -12,10 +12,10 @@
 # TCB size = 0x16 and foo is first element from TLS register.
 # CHECK: Disassembly of section .text:
 # CHECK: _start:
-# CHECK:  20000:	00 00 a0 d2	movz	x0, #0, lsl #16
-# CHECK:  20004:	00 02 80 f2 	movk	x0, #16
-# CHECK:  20008:	1f 20 03 d5 	nop
-# CHECK:  2000c:	1f 20 03 d5 	nop
+# CHECK:  210000:	00 00 a0 d2	movz	x0, #0, lsl #16
+# CHECK:  210004:	00 02 80 f2 	movk	x0, #16
+# CHECK:  210008:	1f 20 03 d5 	nop
+# CHECK:  21000c:	1f 20 03 d5 	nop
 
 .globl _start
 _start:
diff --git a/test/ELF/aarch64-tls-ie.s b/test/ELF/aarch64-tls-ie.s
index fba7cd8..5786fe3 100644
--- a/test/ELF/aarch64-tls-ie.s
+++ b/test/ELF/aarch64-tls-ie.s
@@ -15,7 +15,7 @@
 #RELOC-NEXT:     SHF_ALLOC
 #RELOC-NEXT:     SHF_WRITE
 #RELOC-NEXT:   ]
-#RELOC-NEXT:   Address: 0x300B0
+#RELOC-NEXT:   Address: 0x2200B0
 #RELOC-NEXT:   Offset: 0x200B0
 #RELOC-NEXT:   Size: 16
 #RELOC-NEXT:   Link: 0
@@ -25,21 +25,21 @@
 #RELOC-NEXT: }
 #RELOC:      Relocations [
 #RELOC-NEXT:  Section ({{.*}}) .rela.dyn {
-#RELOC-NEXT:    0x300B8 R_AARCH64_TLS_TPREL64 bar 0x0
-#RELOC-NEXT:    0x300B0 R_AARCH64_TLS_TPREL64 foo 0x0
+#RELOC-NEXT:    0x2200B8 R_AARCH64_TLS_TPREL64 bar 0x0
+#RELOC-NEXT:    0x2200B0 R_AARCH64_TLS_TPREL64 foo 0x0
 #RELOC-NEXT:  }
 #RELOC-NEXT:]
 
-# Page(0x300B0) - Page(0x20000) = 0x10000 = 65536
-# 0x300B0 & 0xff8 = 0xB0 = 176
-# Page(0x300B8) - Page(0x20000) = 0x10000 = 65536
-# 0x300B8 & 0xff8 = 0xB8 = 184
+# Page(0x2200B0) - Page(0x210000) = 0x10000 = 65536
+# 0x2200B0 & 0xff8 = 0xB0 = 176
+# Page(0x2200B8) - Page(0x210000) = 0x10000 = 65536
+# 0x2200B8 & 0xff8 = 0xB8 = 184
 #CHECK: Disassembly of section .text:
 #CHECK: _start:
-#CHECK:  20000: 80 00 00 90 adrp x0, #65536
-#CHECK:  20004: 00 58 40 f9 ldr  x0, [x0, #176]
-#CHECK:  20008: 80 00 00 90 adrp x0, #65536
-#CHECK:  2000c: 00 5c 40 f9 ldr  x0, [x0, #184]
+#CHECK:  210000: 80 00 00 90 adrp x0, #65536
+#CHECK:  210004: 00 58 40 f9 ldr  x0, [x0, #176]
+#CHECK:  210008: 80 00 00 90 adrp x0, #65536
+#CHECK:  21000c: 00 5c 40 f9 ldr  x0, [x0, #184]
 
 .globl _start
 _start:
diff --git a/test/ELF/aarch64-tls-iele.s b/test/ELF/aarch64-tls-iele.s
index c97a578..9fec4ee 100644
--- a/test/ELF/aarch64-tls-iele.s
+++ b/test/ELF/aarch64-tls-iele.s
@@ -12,10 +12,10 @@
 # TCB size = 0x16 and foo is first element from TLS register.
 # CHECK: Disassembly of section .text:
 # CHECK: _start:
-# CHECK-NEXT: 20000:  00 00 a0 d2   movz   x0, #0, lsl #16
-# CHECK-NEXT: 20004:  80 02 80 f2   movk   x0, #20
-# CHECK-NEXT: 20008:  00 00 a0 d2   movz   x0, #0, lsl #16
-# CHECK-NEXT: 2000c:  00 02 80 f2   movk   x0, #16
+# CHECK-NEXT: 210000:  00 00 a0 d2   movz   x0, #0, lsl #16
+# CHECK-NEXT: 210004:  80 02 80 f2   movk   x0, #20
+# CHECK-NEXT: 210008:  00 00 a0 d2   movz   x0, #0, lsl #16
+# CHECK-NEXT: 21000c:  00 02 80 f2   movk   x0, #16
 
 .section .tdata
 .align 2
diff --git a/test/ELF/aarch64-tls-le.s b/test/ELF/aarch64-tls-le.s
index e5b1c20..85cd3be 100644
--- a/test/ELF/aarch64-tls-le.s
+++ b/test/ELF/aarch64-tls-le.s
@@ -13,19 +13,36 @@
  mrs x0, TPIDR_EL0
  add x0, x0, :tprel_hi12:v1
  add x0, x0, :tprel_lo12_nc:v1
+ mrs x0, TPIDR_EL0
+ add x0, x0, :tprel_hi12:v2
+ add x0, x0, :tprel_lo12_nc:v2
 
 # TCB size = 0x16 and foo is first element from TLS register.
 #CHECK: Disassembly of section .text:
 #CHECK: _start:
-#CHECK:  20000: 40 d0 3b d5     mrs     x0, TPIDR_EL0
-#CHECK:  20004: 00 00 40 91     add     x0, x0, #0, lsl #12
-#CHECK:  20008: 00 40 00 91     add     x0, x0, #16
+#CHECK:  210000: 40 d0 3b d5     mrs     x0, TPIDR_EL0
+#CHECK:  210004: 00 00 40 91     add     x0, x0, #0, lsl #12
+#CHECK:  210008: 00 40 00 91     add     x0, x0, #16
+#CHECK:  21000c: 40 d0 3b d5     mrs     x0, TPIDR_EL0
+#CHECK:  210010: 00 fc 7f 91     add     x0, x0, #4095, lsl #12
+#CHECK:  210014: 00 e0 3f 91     add     x0, x0, #4088
+
+.section        .tbss,"awT",@nobits
 
 .type   v1,@object
-.section        .tbss,"awT",@nobits
 .globl  v1
 .p2align 2
 v1:
 .word  0
 .size  v1, 4
 
+# The current offset from the thread pointer is 20. Raise it to just below the
+# 24-bit limit.
+.space (0xfffff8 - 20)
+
+.type   v2,@object
+.globl  v2
+.p2align 2
+v2:
+.word  0
+.size  v2, 4
diff --git a/test/ELF/aarch64-tlsld-ldst.s b/test/ELF/aarch64-tlsld-ldst.s
index 9de3a38..3144ca5 100644
--- a/test/ELF/aarch64-tlsld-ldst.s
+++ b/test/ELF/aarch64-tlsld-ldst.s
@@ -25,22 +25,22 @@
         ldrb w0, [x8, :tprel_lo12_nc:var4]
 
 // CHECK: _start:
-// CHECK-NEXT:    20000:       48 d0 3b d5     mrs     x8, TPIDR_EL0
+// CHECK-NEXT:    210000:       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]
+// CHECK-NEXT:    210004:       08 01 40 91     add     x8, x8, #0, lsl #12
+// CHECK-NEXT:    210008:       14 05 c3 3d     ldr     q20, [x8, #3088]
 // 0x1000 + 0x820 = 0x1820 = tcb + var1
-// CHECK-NEXT:    2000c:       08 05 40 91     add     x8, x8, #1, lsl #12
-// CHECK-NEXT:    20010:       00 11 44 f9     ldr     x0, [x8, #2080]
+// CHECK-NEXT:    21000c:       08 05 40 91     add     x8, x8, #1, lsl #12
+// CHECK-NEXT:    210010:       00 11 44 f9     ldr     x0, [x8, #2080]
 // 0x2000 + 0x428 = 0x2428 = tcb + var2
-// CHECK-NEXT:    20014:       08 09 40 91     add     x8, x8, #2, lsl #12
-// CHECK-NEXT:    20018:       00 29 44 b9     ldr     w0, [x8, #1064]
+// CHECK-NEXT:    210014:       08 09 40 91     add     x8, x8, #2, lsl #12
+// CHECK-NEXT:    210018:       00 29 44 b9     ldr     w0, [x8, #1064]
 // 0x3000 + 0x2c  = 0x302c = tcb + var3
-// CHECK-NEXT:    2001c:       08 0d 40 91     add     x8, x8, #3, lsl #12
-// CHECK-NEXT:    20020:       00 59 40 79     ldrh    w0, [x8, #44]
+// CHECK-NEXT:    21001c:       08 0d 40 91     add     x8, x8, #3, lsl #12
+// CHECK-NEXT:    210020:       00 59 40 79     ldrh    w0, [x8, #44]
 // 0x3000 + 0xc2e = 0x32ce = tcb + var4
-// CHECK-NEXT:    20024:       08 0d 40 91     add     x8, x8, #3, lsl #12
-// CHECK-NEXT:    20028:       00 b9 70 39     ldrb    w0, [x8, #3118]
+// CHECK-NEXT:    210024:       08 0d 40 91     add     x8, x8, #3, lsl #12
+// CHECK-NEXT:    210028:       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
diff --git a/test/ELF/aarch64-tstbr14-reloc.s b/test/ELF/aarch64-tstbr14-reloc.s
index 779ca6b..9e9d969 100644
--- a/test/ELF/aarch64-tstbr14-reloc.s
+++ b/test/ELF/aarch64-tstbr14-reloc.s
@@ -13,19 +13,19 @@
 # 0x11028 - 24 = 0x20010
 # CHECK:      Disassembly of section .text:
 # CHECK-NEXT: _foo:
-# CHECK-NEXT:  20000: {{.*}} nop
-# CHECK-NEXT:  20004: {{.*}} nop
-# CHECK-NEXT:  20008: {{.*}} nop
-# CHECK-NEXT:  2000c: {{.*}} nop
+# CHECK-NEXT:  210000: {{.*}} nop
+# CHECK-NEXT:  210004: {{.*}} nop
+# CHECK-NEXT:  210008: {{.*}} nop
+# CHECK-NEXT:  21000c: {{.*}} nop
 # CHECK:      _bar:
-# CHECK-NEXT:  20010: {{.*}} nop
-# CHECK-NEXT:  20014: {{.*}} nop
-# CHECK-NEXT:  20018: {{.*}} nop
+# CHECK-NEXT:  210010: {{.*}} nop
+# CHECK-NEXT:  210014: {{.*}} nop
+# CHECK-NEXT:  210018: {{.*}} nop
 # CHECK:      _start:
-# CHECK-NEXT:  2001c: {{.*}} tbnz w3, #15, #-28
-# CHECK-NEXT:  20020: {{.*}} tbnz w3, #15, #-16
-# CHECK-NEXT:  20024: {{.*}} tbz x6, #45, #-36
-# CHECK-NEXT:  20028: {{.*}} tbz x6, #45, #-24
+# CHECK-NEXT:  21001c: {{.*}} tbnz w3, #15, #-28
+# CHECK-NEXT:  210020: {{.*}} tbnz w3, #15, #-16
+# CHECK-NEXT:  210024: {{.*}} tbz x6, #45, #-36
+# CHECK-NEXT:  210028: {{.*}} tbz x6, #45, #-24
 
 #DSOREL:      Section {
 #DSOREL:        Index:
@@ -79,10 +79,14 @@
 #DSO-NEXT:  10044: {{.*}} nop
 #DSO-NEXT:  10048: {{.*}} nop
 #DSO-NEXT:  1004c: {{.*}} nop
+#DSO-EMPTY:
+#DSO-NEXT:   _foo@plt:
 #DSO-NEXT:  10050: {{.*}} adrp x16, #65536
 #DSO-NEXT:  10054: {{.*}} ldr x17, [x16, #24]
 #DSO-NEXT:  10058: {{.*}} add x16, x16, #24
 #DSO-NEXT:  1005c: {{.*}} br x17
+#DSO-EMPTY:
+#DSO-NEXT:   _bar@plt:
 #DSO-NEXT:  10060: {{.*}} adrp x16, #65536
 #DSO-NEXT:  10064: {{.*}} ldr x17, [x16, #32]
 #DSO-NEXT:  10068: {{.*}} add x16, x16, #32
diff --git a/test/ELF/aarch64-undefined-weak.s b/test/ELF/aarch64-undefined-weak.s
index e2316ac..893f99a 100644
--- a/test/ELF/aarch64-undefined-weak.s
+++ b/test/ELF/aarch64-undefined-weak.s
@@ -34,16 +34,16 @@
  ldr x8, target
 
 // CHECK: Disassembly of section .text:
-// 131072 = 0x20000
-// CHECK:         20000: {{.*}} b       #4
-// CHECK-NEXT:    20004: {{.*}} bl      #4
-// CHECK-NEXT:    20008: {{.*}} b.eq    #4
-// CHECK-NEXT:    2000c: {{.*}} cbz     x1, #4
-// CHECK-NEXT:    20010: {{.*}} adr     x0, #0
-// CHECK-NEXT:    20014: {{.*}} adrp    x0, #-131072
-// CHECK:         20018: {{.*}} .word   0x00000000
-// CHECK-NEXT:    2001c: {{.*}} .word   0x00000000
-// CHECK-NEXT:    20020: {{.*}} .word   0x00000000
-// CHECK-NEXT:    20024: {{.*}} .short  0x0000
+// 2162688 = 0x210000
+// CHECK:         210000: {{.*}} b       #4
+// CHECK-NEXT:    210004: {{.*}} bl      #4
+// CHECK-NEXT:    210008: {{.*}} b.eq    #4
+// CHECK-NEXT:    21000c: {{.*}} cbz     x1, #4
+// CHECK-NEXT:    210010: {{.*}} adr     x0, #0
+// CHECK-NEXT:    210014: {{.*}} adrp    x0, #-2162688
+// CHECK:         210018: {{.*}} .word   0x00000000
+// CHECK-NEXT:    21001c: {{.*}} .word   0x00000000
+// CHECK-NEXT:    210020: {{.*}} .word   0x00000000
+// CHECK-NEXT:    210024: {{.*}} .short  0x0000
 // CHECK:         $x.2:
-// CHECK-NEXT:    20026: {{.*}} ldr     x8, #0
+// CHECK-NEXT:    210026: {{.*}} ldr     x8, #0
diff --git a/test/ELF/arm-bl-v6-inrange.s b/test/ELF/arm-bl-v6-inrange.s
new file mode 100644
index 0000000..0e186c5
--- /dev/null
+++ b/test/ELF/arm-bl-v6-inrange.s
@@ -0,0 +1,47 @@
+// REQUIRES: arm
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv6-none-linux-gnueabi %s -o %t
+// RUN: echo "SECTIONS { \
+// RUN:          .callee1 0x100004 : { *(.callee_low) } \
+// RUN:          .caller  0x500000 : { *(.text) } \
+// RUN:          .callee2 0x900004 : { *(.callee_high) } } " > %t.script
+// RUN: ld.lld %t --script %t.script -o %t2 2>&1
+// RUN: llvm-objdump -d -triple=thumbv6-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-THUMB %s
+// RUN: llvm-objdump -d -triple=armv6-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-ARM %s
+
+// On older Arm Architectures such as v5 and v6 the Thumb BL and BLX relocation
+// uses a slightly different encoding that has a lower range. These relocations
+// are at the extreme range of what is permitted.
+ .thumb
+ .text
+ .syntax unified
+ .cpu    arm1176jzf-s
+ .globl _start
+ .type   _start,%function
+_start:
+  bl thumbfunc
+  bl armfunc
+  bx lr
+
+  .section .callee_low, "ax", %progbits
+  .globl thumbfunc
+  .type thumbfunc, %function
+thumbfunc:
+  bx lr
+// CHECK-THUMB: Disassembly of section .callee1:
+// CHECK-THUMB-NEXT: thumbfunc:
+// CHECK-THUMB-NEXT:   100004:       70 47   bx      lr
+// CHECK-THUMB-NEXT: Disassembly of section .caller:
+// CHECK-THUMB-NEXT: _start:
+// CHECK-THUMB-NEXT:   500000:       00 f4 00 f8     bl      #-4194304
+// CHECK-THUMB-NEXT:   500004:       ff f3 fe ef     blx     #4194300
+// CHECK-THUMB-NEXT:   500008:       70 47   bx      lr
+
+  .arm
+  .section .callee_high, "ax", %progbits
+  .globl armfunc
+  .type armfunc, %function
+armfunc:
+  bx lr
+// CHECK-ARM: Disassembly of section .callee2:
+// CHECK-ARM-NEXT: armfunc:
+// CHECK-ARM-NEXT:   900004:       1e ff 2f e1     bx      lr
diff --git a/test/ELF/arm-bl-v6.s b/test/ELF/arm-bl-v6.s
index c27a99e..13be769 100644
--- a/test/ELF/arm-bl-v6.s
+++ b/test/ELF/arm-bl-v6.s
@@ -1,22 +1,23 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=arm-none-linux-gnueabi %s -o %t
-// RUN: ld.lld %t -o /dev/null 2>&1 | FileCheck %s
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv6-none-linux-gnueabi %s -o %t
+// RUN: ld.lld %t -o %t2 2>&1
+// RUN: llvm-objdump -d -triple=armv6-none-linux-gnueabi -start-address=69632 -stop-address=69640 %t2 | FileCheck -check-prefix=CHECK-ARM1 %s
+// RUN: llvm-objdump -d -triple=thumbv6-none-linux-gnueabi %t2 -start-address=69640 -stop-address=69644 | FileCheck -check-prefix=CHECK-THUMB1 %s
+// RUN: llvm-objdump -d -triple=armv6-none-linux-gnueabi -start-address=2166796 -stop-address=2166804 %t2 | FileCheck -check-prefix=CHECK-ARM2 %s
+// RUN: llvm-objdump -d -triple=thumbv6-none-linux-gnueabi %t2 -start-address=6365184 -stop-address=6365186 | FileCheck -check-prefix=CHECK-THUMB2 %s
 
 // On Arm v6 the range of a Thumb BL instruction is only 4 megabytes as the
 // extended range encoding is not supported. The following example has a Thumb
 // BL that is out of range on ARM v6 and requires a range extension thunk.
 // As v6 does not support MOVT or MOVW instructions the Thunk must not
-// use these instructions either. At present we don't support v6 so we give a
-// warning for unsupported features.
+// use these instructions either.
 
-// CHECK: warning: lld uses extended branch encoding, no object with architecture supporting feature detected.
-// CHECK-NEXT: warning: lld may use movt/movw, no object with architecture supporting feature detected.
+
 // ARM v6 supports blx so we shouldn't see the blx not supported warning.
 // CHECK-NOT: warning: lld uses blx instruction, no object with architecture supporting feature detected.
  .text
  .syntax unified
  .cpu    arm1176jzf-s
- .eabi_attribute 6, 6    @ Tag_CPU_arch
  .globl _start
  .type   _start,%function
  .balign 0x1000
@@ -24,6 +25,10 @@
   bl thumbfunc
   bx lr
 
+// CHECK-ARM1: Disassembly of section .text:
+// CHECK-ARM1-NEXT: _start:
+// CHECK-ARM1-NEXT:    11000:   00 00 00 fa     blx     #0 <thumbfunc>
+// CHECK-ARM1-NEXT:    11004:   1e ff 2f e1     bx      lr
  .thumb
  .section .text.2, "ax", %progbits
  .globl thumbfunc
@@ -31,11 +36,17 @@
 thumbfunc:
  bl farthumbfunc
 
-// 6 Megabytes, enough to make farthumbfunc out of range of caller on a v6
-// Arm, but not on a v7 Arm.
+// CHECK-THUMB1: thumbfunc:
+// CHECK-THUMB1-NEXT:    11008:	00 f2 00 e8 	blx	#2097152
+// 6 Megabytes, enough to make farthumbfunc out of range of caller
+// on a v6 Arm, but not on a v7 Arm.
+
  .section .text.3, "ax", %progbits
  .space 0x200000
-
+// CHECK-ARM2: __ARMv5ABSLongThunk_farthumbfunc:
+// CHECK-ARM2-NEXT:   21100c:   04 f0 1f e5     ldr     pc, [pc, #-4]
+// CHECK-ARM2: $d:
+// CHECK-ARM2-NEXT:   211010:   01 20 61 00     .word   0x00612001
  .section .text.4, "ax", %progbits
  .space 0x200000
 
@@ -49,3 +60,5 @@
  .type farthumbfunc,%function
 farthumbfunc:
  bx lr
+// CHECK-THUMB2: farthumbfunc:
+// CHECK-THUMB2-NEXT:   612000:        70 47   bx      lr
diff --git a/test/ELF/arm-blx-v4t.s b/test/ELF/arm-blx-v4t.s
index f526b3b..1afc4bf 100644
--- a/test/ELF/arm-blx-v4t.s
+++ b/test/ELF/arm-blx-v4t.s
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=arm-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=arm-none-linux-gnueabi %s -o %t
 // RUN: ld.lld %t -o /dev/null 2>&1 | FileCheck %s
 
 // On Arm v4t there is no blx instruction so all interworking must go via
@@ -7,13 +7,10 @@
 // features.
 
 // CHECK: warning: lld uses blx instruction, no object with architecture supporting feature detected.
-// CHECK-NEXT: warning: lld uses extended branch encoding, no object with architecture supporting feature detected.
-// CHECK-NEXT: warning: lld may use movt/movw, no object with architecture supporting feature detected.
 
  .text
  .syntax unified
  .cpu   arm7tdmi
- .eabi_attribute        6, 2    @ Tag_CPU_arch
  .arm
  .globl _start
  .type   _start,%function
diff --git a/test/ELF/arm-branch-rangethunk.s b/test/ELF/arm-branch-rangethunk.s
index 739a770..7d83c87 100644
--- a/test/ELF/arm-branch-rangethunk.s
+++ b/test/ELF/arm-branch-rangethunk.s
@@ -1,9 +1,9 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-abs.s -o %tfar
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-abs.s -o %tfar
 // RUN: ld.lld  %t %tfar -o %t2 2>&1
 // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck --check-prefix=SHORT %s
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-long-arm-abs.s -o %tfarlong
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-long-arm-abs.s -o %tfarlong
 // RUN: ld.lld  %t %tfarlong -o %t3 2>&1
 // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck --check-prefix=LONG %s
  .syntax unified
diff --git a/test/ELF/arm-branch-undef-weak-plt-thunk.s b/test/ELF/arm-branch-undef-weak-plt-thunk.s
index f47ed61..919d4f5 100644
--- a/test/ELF/arm-branch-undef-weak-plt-thunk.s
+++ b/test/ELF/arm-branch-undef-weak-plt-thunk.s
@@ -1,7 +1,7 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-shared.s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-shared.s -o %t
 // RUN: ld.lld %t --shared -o %t.so
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2
 // RUN: ld.lld %t2 %t.so -o %t3
 // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi -start-address=69632 -stop-address=69664 %t3 | FileCheck %s
 
diff --git a/test/ELF/arm-long-thunk-converge.s b/test/ELF/arm-long-thunk-converge.s
index dadc7e5..f241a58 100644
--- a/test/ELF/arm-long-thunk-converge.s
+++ b/test/ELF/arm-long-thunk-converge.s
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -triple armv7-unknown-gnu -filetype=obj -o %t %s
+// RUN: llvm-mc -triple armv7-unknown-gnu -arm-add-build-attributes -filetype=obj -o %t %s
 // RUN: ld.lld %t %S/Inputs/arm-long-thunk-converge.lds -o %t2
 // RUN: llvm-objdump -d -start-address=0x00000000 -stop-address=0x00000010 -triple=armv7a-linux-gnueabihf %t2 | FileCheck --check-prefix=CHECK1 %s
 // RUN: llvm-objdump -d -start-address=0x02000000 -stop-address=0x02000010 -triple=armv7a-linux-gnueabihf %t2 | FileCheck --check-prefix=CHECK2 %s
diff --git a/test/ELF/arm-thumb-branch-rangethunk.s b/test/ELF/arm-thumb-branch-rangethunk.s
index 4bbd692..31a239d 100644
--- a/test/ELF/arm-thumb-branch-rangethunk.s
+++ b/test/ELF/arm-thumb-branch-rangethunk.s
@@ -1,6 +1,6 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar
 // RUN: ld.lld  %t %tfar -o %t2 2>&1
 // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2
  .syntax unified
diff --git a/test/ELF/arm-thumb-branch.s b/test/ELF/arm-thumb-branch.s
index 89c081a..043db4b 100644
--- a/test/ELF/arm-thumb-branch.s
+++ b/test/ELF/arm-thumb-branch.s
@@ -1,6 +1,6 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar
 // RUN: echo "SECTIONS { \
 // RUN:          . = 0xb4; \
 // RUN:          .callee1 : { *(.callee_low) } \
diff --git a/test/ELF/arm-thumb-condbranch-thunk.s b/test/ELF/arm-thumb-condbranch-thunk.s
index c9365ef..8a5e9c8 100644
--- a/test/ELF/arm-thumb-condbranch-thunk.s
+++ b/test/ELF/arm-thumb-condbranch-thunk.s
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
 // RUN: ld.lld %t -o %t2 2>&1
 // The output file is large, most of it zeroes. We dissassemble only the
 // parts we need to speed up the test and avoid a large output file
diff --git a/test/ELF/arm-thumb-interwork-shared.s b/test/ELF/arm-thumb-interwork-shared.s
index 030ac29..5c84736 100644
--- a/test/ELF/arm-thumb-interwork-shared.s
+++ b/test/ELF/arm-thumb-interwork-shared.s
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
 // RUN: ld.lld %t --shared -o %t.so
 // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t.so | FileCheck %s
 // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t.so | FileCheck %s -check-prefix=PLT
diff --git a/test/ELF/arm-thumb-interwork-thunk-range.s b/test/ELF/arm-thumb-interwork-thunk-range.s
index d59ee11..3c01318 100644
--- a/test/ELF/arm-thumb-interwork-thunk-range.s
+++ b/test/ELF/arm-thumb-interwork-thunk-range.s
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
 // RUN: ld.lld %t.o -o /dev/null -image-base=0x80000000
 
 // Test that when the thunk is at a high address we don't get confused with it
diff --git a/test/ELF/arm-thumb-interwork-thunk-v5.s b/test/ELF/arm-thumb-interwork-thunk-v5.s
new file mode 100644
index 0000000..90aa76e
--- /dev/null
+++ b/test/ELF/arm-thumb-interwork-thunk-v5.s
@@ -0,0 +1,66 @@
+// REQUIRES: arm
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv5-none-linux-gnueabi %s -o %t
+// RUN: ld.lld %t -o %t2
+// RUN: llvm-objdump -d %t2 -triple=armv5-none-linux-gnueabi | FileCheck -check-prefix=CHECK-ARM %s
+// RUN: llvm-objdump -d %t2 -triple=thumbv5-none-linux-gnueabi | FileCheck -check-prefix=CHECK-THUMB %s
+// RUN: ld.lld %t -o %t3 --shared
+// RUN: llvm-objdump -d %t3 -triple=armv5-none-linux-gnueabi | FileCheck -check-prefix=CHECK-ARM-PI %s
+// RUN: llvm-objdump -d %t3 -triple=thumbv5-none-linux-gnueabi | FileCheck -check-prefix=CHECK-THUMB-PI %s
+
+// Test ARM Thumb Interworking on older Arm architectures using Thunks that do
+// not use MOVT/MOVW instructions.
+// For pure interworking (not considering range extension) there is only the
+// case of an Arm B to a Thumb Symbol to consider as in older Arm architectures
+// there is no Thumb B.w that we can intercept with a Thunk and we still assume
+// support for the blx instruction for Thumb BL and BLX to an Arm symbol.
+        .arm
+        .text
+        .syntax unified
+        .cpu    arm10tdmi
+
+        .text
+        .globl _start
+        .type _start, %function
+        .balign 0x1000
+_start:
+        b thumb_func
+        bl thumb_func
+        blx thumb_func
+        bx lr
+
+// CHECK-ARM: _start:
+// CHECK-ARM-NEXT: 11000: 03 00 00 ea     b       #12 <__ARMv5ABSLongThunk_thumb_func>
+// CHECK-ARM-NEXT: 11004: 01 00 00 fa     blx     #4 <thumb_func>
+// CHECK-ARM-NEXT: 11008: 00 00 00 fa     blx     #0 <thumb_func>
+// CHECK-ARM-NEXT: 1100c: 1e ff 2f e1     bx      lr
+
+// CHECK-THUMB: thumb_func:
+// CHECK-THUMB-NEXT: 11010: 70 47   bx      lr
+
+// CHECK-ARM: __ARMv5ABSLongThunk_thumb_func:
+// CHECK-ARM-NEXT: 11014: 04 f0 1f e5     ldr     pc, [pc, #-4]
+// CHECK-ARM: $d:
+// CHECK-ARM-NEXT: 11018: 11 10 01 00     .word   0x00011011
+
+// CHECK-ARM-PI: _start:
+// CHECK-ARM-PI-NEXT: 1000: 03 00 00 ea     b       #12 <__ARMV5PILongThunk_thumb_func>
+// CHECK-ARM-PI-NEXT: 1004: 01 00 00 fa     blx     #4 <thumb_func>
+// CHECK-ARM-PI-NEXT: 1008: 00 00 00 fa     blx     #0 <thumb_func>
+// CHECK-ARM-PI-NEXT: 100c: 1e ff 2f e1     bx      lr
+
+// CHECK-THUMB-PI: thumb_func:
+// CHECK-THUMB-PI-NEXT: 1010: 70 47   bx      lr
+
+// CHECK-ARM-PI: __ARMV5PILongThunk_thumb_func:
+// CHECK-ARM-PI-NEXT: 1014: 04 c0 9f e5     ldr     r12, [pc, #4]
+// CHECK-ARM-PI-NEXT: 1018: 0c c0 8f e0     add     r12, pc, r12
+// CHECK-ARM-PI-NEXT: 101c: 1c ff 2f e1     bx      r12
+// CHECK-ARM-PI: $d:
+// CHECK-ARM-PI-NEXT: 1020: f1 ff ff ff     .word   0xfffffff1
+
+        .section .text.1, "ax", %progbits
+        .thumb
+        .hidden thumb_func
+        .type thumb_func, %function
+thumb_func:
+        bx lr
diff --git a/test/ELF/arm-thumb-interwork-thunk.s b/test/ELF/arm-thumb-interwork-thunk.s
index df5d6c6..4ff08e0 100644
--- a/test/ELF/arm-thumb-interwork-thunk.s
+++ b/test/ELF/arm-thumb-interwork-thunk.s
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
 // RUN: echo "SECTIONS { \
 // RUN:       . = SIZEOF_HEADERS; \
 // RUN:       .R_ARM_JUMP24_callee_1 : { *(.R_ARM_JUMP24_callee_low) } \
diff --git a/test/ELF/arm-thumb-mix-range-thunk-os.s b/test/ELF/arm-thumb-mix-range-thunk-os.s
index b5db256..7be5664 100644
--- a/test/ELF/arm-thumb-mix-range-thunk-os.s
+++ b/test/ELF/arm-thumb-mix-range-thunk-os.s
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
 // RUN: ld.lld %t -o %t2 2>&1
 // The output file is large, most of it zeroes. We dissassemble only the
 // parts we need to speed up the test and avoid a large output file
diff --git a/test/ELF/arm-thumb-nov6thunk.s b/test/ELF/arm-thumb-nov6thunk.s
new file mode 100644
index 0000000..8c1d1f8
--- /dev/null
+++ b/test/ELF/arm-thumb-nov6thunk.s
@@ -0,0 +1,39 @@
+// REQUIRES: arm
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv6m-none-eabi %s -o %t
+// RUN: echo "SECTIONS { \
+// RUN:       . = SIZEOF_HEADERS; \
+// RUN:       .text_low : { *(.text_low) *(.text_low2) } \
+// RUN:       .text_high 0x2000000 : { *(.text_high) *(.text_high2) } \
+// RUN:       } " > %t.script
+// RUN: not ld.lld --script %t.script %t -o %t2 2>&1 | FileCheck %s
+
+// CHECK:  error: thunks not supported for architecture Armv6-m
+
+// Range extension thunks are not currently supported on Armv6-m due to a
+// combination of Armv6-m being aimed at low-end microcontrollers that typically
+// have < 512 Kilobytes of memory, and the restrictions of the instruction set
+// that make thunks inefficient. The main restriction is that the
+// interprocedural scratch register r12 (ip) cannot be accessed from many
+// instructions so we must use the stack to avoid corrupting the program.
+//
+// A v6-m Thunk would look like
+//     push {r0, r1} ; Make 8-bytes of stack for restoring r0, and destination
+//     ldr r0, [pc, #4] ; L1
+//     str r0, [sp, #4] ; store destination address into sp + 4
+//     pop {r0, pc} ; restore r0 and load pc with destination
+// L1: .word destination
+
+ .syntax unified
+ .section .text_low, "ax", %progbits
+ .thumb
+ .type _start, %function
+ .globl _start
+_start:
+ bl far
+
+ .section .text_high, "ax", %progbits
+ .globl far
+ .type far, %function
+far:
+ bx lr
+
diff --git a/test/ELF/arm-thumb-plt-range-thunk-os.s b/test/ELF/arm-thumb-plt-range-thunk-os.s
index 080160b..0890751 100644
--- a/test/ELF/arm-thumb-plt-range-thunk-os.s
+++ b/test/ELF/arm-thumb-plt-range-thunk-os.s
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
 // RUN: ld.lld %t --shared --icf=all -o %t.so
 // The output file is large, most of it zeroes. We dissassemble only the
 // parts we need to speed up the test and avoid a large output file
diff --git a/test/ELF/arm-thumb-range-thunk-os.s b/test/ELF/arm-thumb-range-thunk-os.s
index 182b18d..281e79a 100644
--- a/test/ELF/arm-thumb-range-thunk-os.s
+++ b/test/ELF/arm-thumb-range-thunk-os.s
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc  -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
 // RUN: ld.lld %t -o %t2 2>&1
 // The output file is large, most of it zeroes. We dissassemble only the
 // parts we need to speed up the test and avoid a large output file
diff --git a/test/ELF/arm-thumb-thunk-empty-pass.s b/test/ELF/arm-thumb-thunk-empty-pass.s
index ab9da1b..6e81b50 100644
--- a/test/ELF/arm-thumb-thunk-empty-pass.s
+++ b/test/ELF/arm-thumb-thunk-empty-pass.s
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
 // RUN: ld.lld %t -o %t2 2>&1
 // RUN: llvm-objdump -d %t2 -start-address=69632 -stop-address=69646 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s
 // RUN: llvm-objdump -d %t2 -start-address=16846856 -stop-address=16846874 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s
diff --git a/test/ELF/arm-thumb-thunk-symbols.s b/test/ELF/arm-thumb-thunk-symbols.s
index 457d460..ad6e79d 100644
--- a/test/ELF/arm-thumb-thunk-symbols.s
+++ b/test/ELF/arm-thumb-thunk-symbols.s
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
 // RUN: ld.lld %t -o %t2 2>&1
 // RUN: llvm-readobj --symbols %t2 | FileCheck %s
 // RUN: ld.lld --shared %t -o %t3 2>&1
diff --git a/test/ELF/arm-thunk-edgecase.s b/test/ELF/arm-thunk-edgecase.s
index 81837c7..3566876 100644
--- a/test/ELF/arm-thunk-edgecase.s
+++ b/test/ELF/arm-thunk-edgecase.s
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
 // RUN: echo "SECTIONS { \
 // RUN:           .text_armfunc 0x1000 : { *(.text_armfunc) } \
 // RUN:           .text_thumbfunc 0x11010 : { *(.text_thumbfunc) } \
diff --git a/test/ELF/arm-thunk-largesection.s b/test/ELF/arm-thunk-largesection.s
index d68cd0c..940888f 100644
--- a/test/ELF/arm-thunk-largesection.s
+++ b/test/ELF/arm-thunk-largesection.s
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
 // RUN: ld.lld %t -o %t2 2>&1
 // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=69632 -stop-address=69636 %t2 | FileCheck -check-prefix=CHECK1 %s
 // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=73732 -stop-address=73742 %t2 | FileCheck -check-prefix=CHECK2 %s
@@ -16,9 +16,12 @@
  bx lr
  .space 0x1000
 // CHECK1: Disassembly of section .text:
-// CHECK1-NEXT: _start:
-// CHECK1-NEXT:    11000:       70 47   bx      lr
-// CHECK1-NEXT:    11002:       00 00   movs    r0, r0
+// CHECK1-NEXT:_start:
+// CHECK1-NEXT:   11000:       70 47   bx      lr
+// CHECK1-EMPTY:
+// CHECK-NEXT:$d.1:
+// CHECK-NEXT:  11002:       00 00           .short  0x0000
+
 
 // CHECK2: __Thumbv7ABSLongThunk__start:
 // CHECK2-NEXT:    12004:       fe f7 fc bf     b.w     #-4104 <_start>
diff --git a/test/ELF/arm-thunk-linkerscript-dotexpr.s b/test/ELF/arm-thunk-linkerscript-dotexpr.s
index ea74170..4b68ad8 100644
--- a/test/ELF/arm-thunk-linkerscript-dotexpr.s
+++ b/test/ELF/arm-thunk-linkerscript-dotexpr.s
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
 // RUN: echo "SECTIONS { \
 // RUN:       . = SIZEOF_HEADERS; \
 // RUN:       .text_low : { *(.text_low) *(.text_low2) . = . + 0x2000000 ; *(.text_high) *(.text_high2) } \
diff --git a/test/ELF/arm-thunk-linkerscript-large.s b/test/ELF/arm-thunk-linkerscript-large.s
index 839d771..1b9ec0b 100644
--- a/test/ELF/arm-thunk-linkerscript-large.s
+++ b/test/ELF/arm-thunk-linkerscript-large.s
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
 // RUN: echo "SECTIONS { \
 // RUN:       .text 0x100000 : { *(.text) } \
 // RUN:       .textl : { *(.text_l0*) *(.text_l1*) *(.text_l2*) *(.text_l3*) } \
@@ -21,7 +21,8 @@
 // per OutputSection basis
  .syntax unified
 
-// Define a function that we can match with .text_l* aligned on a megabyte      // boundary
+// Define a function that we can match with .text_l* aligned on a megabyte
+// boundary
  .macro FUNCTIONL suff
  .section .text_l\suff\(), "ax", %progbits
  .thumb
diff --git a/test/ELF/arm-thunk-linkerscript-orphan.s b/test/ELF/arm-thunk-linkerscript-orphan.s
index f05cc0d..556e67b 100644
--- a/test/ELF/arm-thunk-linkerscript-orphan.s
+++ b/test/ELF/arm-thunk-linkerscript-orphan.s
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
 // RUN: echo "SECTIONS { \
 // RUN:       .text_low 0x100000 : { *(.text_low) } \
 // RUN:       .text_high 0x2000000 : { *(.text_high) } \
diff --git a/test/ELF/arm-thunk-linkerscript-sort.s b/test/ELF/arm-thunk-linkerscript-sort.s
index 62ea413..8e2a117 100644
--- a/test/ELF/arm-thunk-linkerscript-sort.s
+++ b/test/ELF/arm-thunk-linkerscript-sort.s
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
 // RUN: echo "SECTIONS { \
 // RUN:       .text 0x100000 : { *(SORT_BY_NAME(.text.*)) } \
 // RUN:       }" > %t.script
diff --git a/test/ELF/arm-thunk-linkerscript.s b/test/ELF/arm-thunk-linkerscript.s
index 7728ddf..6e476a2 100644
--- a/test/ELF/arm-thunk-linkerscript.s
+++ b/test/ELF/arm-thunk-linkerscript.s
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
 // RUN: echo "SECTIONS { \
 // RUN:       . = SIZEOF_HEADERS; \
 // RUN:       .text_low : { *(.text_low) *(.text_low2) } \
diff --git a/test/ELF/arm-thunk-multipass.s b/test/ELF/arm-thunk-multipass.s
index b353bb1..33578b1 100644
--- a/test/ELF/arm-thunk-multipass.s
+++ b/test/ELF/arm-thunk-multipass.s
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
 // RUN: ld.lld %t -o %t2 2>&1
 // The output file is large, most of it zeroes. We dissassemble only the
 // parts we need to speed up the test and avoid a large output file
diff --git a/test/ELF/arm-thunk-re-add.s b/test/ELF/arm-thunk-re-add.s
index 760e18f..9e8feb3 100644
--- a/test/ELF/arm-thunk-re-add.s
+++ b/test/ELF/arm-thunk-re-add.s
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
 // RUN: ld.lld %t --shared -o %t.so
 // The output file is large, most of it zeroes. We dissassemble only the
 // parts we need to speed up the test and avoid a large output file
diff --git a/test/ELF/arm-v5-reloc-error.s b/test/ELF/arm-v5-reloc-error.s
new file mode 100644
index 0000000..90ea36d
--- /dev/null
+++ b/test/ELF/arm-v5-reloc-error.s
@@ -0,0 +1,31 @@
+// REQUIRES: arm
+// RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabi %s -o %t
+// RUN: echo "SECTIONS { \
+// RUN:       . = SIZEOF_HEADERS; \
+// RUN:       .text_low : { *(.text_low) *(.text_low2) } \
+// RUN:       .text_high 0x2000000 : { *(.text_high) *(.text_high2) } \
+// RUN:       } " > %t.script
+// RUN: not ld.lld --script %t.script %t -o %t2 2>&1 | FileCheck %s
+
+// CHECK: error: relocation R_ARM_THM_JUMP24 to far not supported for Armv5 or Armv6 targets
+
+// Lie about our build attributes. Our triple is armv7a-linux-gnueabi but
+// we are claiming to be Armv5. This can also happen with llvm-mc when we
+// don't have any .eabi_attribute directives in the file or the
+// --arm-add-build-attributes command line isn't used to add them from the
+// triple.
+ .eabi_attribute 6, 5           // Tag_cpu_arch 5 = v5TEJ
+ .thumb
+ .syntax unified
+ .section .text_low, "ax", %progbits
+ .thumb
+ .globl _start
+ .type _start, %function
+_start:
+ b.w far // Will produce relocation not supported in Armv5.
+
+ .section .text_high, "ax", %progbits
+ .globl far
+ .type far, %function
+far:
+ bx lr
diff --git a/test/ELF/basic-aarch64.s b/test/ELF/basic-aarch64.s
index efbe008..151bf52 100644
--- a/test/ELF/basic-aarch64.s
+++ b/test/ELF/basic-aarch64.s
@@ -59,7 +59,7 @@
 # CHECK-NEXT:       SHF_ALLOC (0x2)
 # CHECK-NEXT:       SHF_EXECINSTR (0x4)
 # CHECK-NEXT:     ]
-# CHECK-NEXT:     Address: 0x20000
+# CHECK-NEXT:     Address: 0x210000
 # CHECK-NEXT:     Offset: 0x10000
 # CHECK-NEXT:     Size: 12
 # CHECK-NEXT:     Link: 0
@@ -138,7 +138,7 @@
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Name: $x.0
-# CHECK-NEXT:     Value: 0x20000
+# CHECK-NEXT:     Value: 0x210000
 # CHECK-NEXT:     Size: 0
 # CHECK-NEXT:     Binding: Local (0x0)
 # CHECK-NEXT:     Type: None (0x0)
@@ -159,8 +159,8 @@
 # CHECK-NEXT:   ProgramHeader {
 # CHECK-NEXT:     Type: PT_PHDR (0x6)
 # CHECK-NEXT:     Offset: 0x40
-# CHECK-NEXT:     VirtualAddress: 0x10040
-# CHECK-NEXT:     PhysicalAddress: 0x10040
+# CHECK-NEXT:     VirtualAddress: 0x200040
+# CHECK-NEXT:     PhysicalAddress: 0x200040
 # CHECK-NEXT:     FileSize: 224
 # CHECK-NEXT:     MemSize: 224
 # CHECK-NEXT:     Flags [ (0x4)
@@ -171,8 +171,8 @@
 # CHECK-NEXT:   ProgramHeader {
 # CHECK-NEXT:     Type: PT_LOAD (0x1)
 # CHECK-NEXT:     Offset: 0x0
-# CHECK-NEXT:     VirtualAddress: 0x10000
-# CHECK-NEXT:     PhysicalAddress: 0x10000
+# CHECK-NEXT:     VirtualAddress: 0x200000
+# CHECK-NEXT:     PhysicalAddress: 0x200000
 # CHECK-NEXT:     FileSize: 288
 # CHECK-NEXT:     MemSize: 288
 # CHECK-NEXT:     Flags [
@@ -183,8 +183,8 @@
 # CHECK-NEXT:   ProgramHeader {
 # CHECK-NEXT:     Type: PT_LOAD (0x1)
 # CHECK-NEXT:     Offset: 0x1000
-# CHECK-NEXT:     VirtualAddress: 0x20000
-# CHECK-NEXT:     PhysicalAddress: 0x20000
+# CHECK-NEXT:     VirtualAddress: 0x210000
+# CHECK-NEXT:     PhysicalAddress: 0x210000
 # CHECK-NEXT:     FileSize: 4096
 # CHECK-NEXT:     MemSize: 4096
 # CHECK-NEXT:     Flags [ (0x5)
diff --git a/test/ELF/basic32.s b/test/ELF/basic32.s
index 72058dc..38ef779 100644
--- a/test/ELF/basic32.s
+++ b/test/ELF/basic32.s
@@ -23,7 +23,7 @@
 # CHECK-NEXT:   Type: Executable (0x2)
 # CHECK-NEXT:   Machine: EM_386 (0x3)
 # CHECK-NEXT:   Version: 1
-# CHECK-NEXT:   Entry: 0x11000
+# CHECK-NEXT:   Entry: 0x401000
 # CHECK-NEXT:   ProgramHeaderOffset: 0x34
 # CHECK-NEXT:   SectionHeaderOffset: 0x205C
 # CHECK-NEXT:   Flags [ (0x0)
@@ -58,7 +58,7 @@
 # CHECK-NEXT:       SHF_ALLOC (0x2)
 # CHECK-NEXT:       SHF_EXECINSTR (0x4)
 # CHECK-NEXT:     ]
-# CHECK-NEXT:     Address: 0x11000
+# CHECK-NEXT:     Address: 0x401000
 # CHECK-NEXT:     Offset: 0x1000
 # CHECK-NEXT:     Size: 12
 # CHECK-NEXT:     Link: 0
@@ -129,8 +129,8 @@
 # CHECK-NEXT:   ProgramHeader {
 # CHECK-NEXT:     Type: PT_PHDR (0x6)
 # CHECK-NEXT:     Offset: 0x34
-# CHECK-NEXT:     VirtualAddress: 0x10034
-# CHECK-NEXT:     PhysicalAddress: 0x10034
+# CHECK-NEXT:     VirtualAddress: 0x400034
+# CHECK-NEXT:     PhysicalAddress: 0x400034
 # CHECK-NEXT:     FileSize: 128
 # CHECK-NEXT:     MemSize: 128
 # CHECK-NEXT:     Flags [ (0x4)
@@ -141,8 +141,8 @@
 # CHECK-NEXT:   ProgramHeader {
 # CHECK-NEXT:     Type: PT_LOAD (0x1)
 # CHECK-NEXT:     Offset: 0x0
-# CHECK-NEXT:     VirtualAddress: 0x10000
-# CHECK-NEXT:     PhysicalAddress: 0x10000
+# CHECK-NEXT:     VirtualAddress: 0x400000
+# CHECK-NEXT:     PhysicalAddress: 0x400000
 # CHECK-NEXT:     FileSize: 180
 # CHECK-NEXT:     MemSize: 180
 # CHECK-NEXT:     Flags [
@@ -153,8 +153,8 @@
 # CHECK-NEXT:   ProgramHeader {
 # CHECK-NEXT:     Type: PT_LOAD (0x1)
 # CHECK-NEXT:     Offset: 0x1000
-# CHECK-NEXT:     VirtualAddress: 0x11000
-# CHECK-NEXT:     PhysicalAddress: 0x11000
+# CHECK-NEXT:     VirtualAddress: 0x401000
+# CHECK-NEXT:     PhysicalAddress: 0x401000
 # CHECK-NEXT:     FileSize: 4096
 # CHECK-NEXT:     MemSize: 4096
 # CHECK-NEXT:     Flags [ (0x5)
diff --git a/test/ELF/cgprofile-obj-warn.s b/test/ELF/cgprofile-obj-warn.s
new file mode 100644
index 0000000..1882160
--- /dev/null
+++ b/test/ELF/cgprofile-obj-warn.s
@@ -0,0 +1,37 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+# RUN: ld.lld -e A %t -o /dev/null \
+# 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
+
+    .cg_profile A, B, 100
+    .cg_profile A, C, 40
+    .cg_profile B, C, 30
+    .cg_profile adena1, A, 30
+    .cg_profile A, adena2, 30
+    .cg_profile poppy, A, 30
+
+# CHECK: unable to order absolute symbol: B
+# CHECK: unable to order undefined symbol: adena1
+# CHECK: unable to order undefined symbol: adena2
+# CHECK: unable to order undefined symbol: poppy
+
+# RUN: ld.lld %t -o /dev/null \
+# RUN:   -noinhibit-exec -icf=all --no-warn-symbol-ordering 2>&1 \
+# RUN:   | FileCheck %s --check-prefix=NOWARN
+# NOWARN-NOT: unable to order
diff --git a/test/ELF/cgprofile-obj.s b/test/ELF/cgprofile-obj.s
new file mode 100644
index 0000000..90cd0f4
--- /dev/null
+++ b/test/ELF/cgprofile-obj.s
@@ -0,0 +1,41 @@
+# 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
+
+    .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
+
+    .cg_profile A, B, 10
+    .cg_profile A, B, 10
+    .cg_profile Aa, B, 80
+    .cg_profile A, C, 40
+    .cg_profile B, C, 30
+    .cg_profile C, D, 90
+
+# CHECK:          Name: D
+# CHECK-NEXT:     Value: 0x201003
+# CHECK:          Name: A
+# CHECK-NEXT:     Value: 0x201000
+# CHECK:          Name: B
+# CHECK-NEXT:     Value: 0x201001
+# CHECK:          Name: C
+# CHECK-NEXT:     Value: 0x201002
diff --git a/test/ELF/cgprofile-txt2.s b/test/ELF/cgprofile-txt2.s
new file mode 100644
index 0000000..e4f6852
--- /dev/null
+++ b/test/ELF/cgprofile-txt2.s
@@ -0,0 +1,38 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: echo "A B 5" > %t.call_graph
+# RUN: echo "B C 50" >> %t.call_graph
+# RUN: echo "C D 40" >> %t.call_graph
+# RUN: echo "D B 10" >> %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
+
+# CHECK:      Name: A
+# CHECK-NEXT: Value: 0x201003
+# CHECK:      Name: B
+# CHECK-NEXT: Value: 0x201000
+# CHECK:      Name: C
+# CHECK-NEXT: Value: 0x201001
+# CHECK:      Name: D
+# CHECK-NEXT: Value: 0x201002
+
+.section    .text.A,"ax",@progbits
+.globl  A
+A:
+ nop
+
+.section    .text.B,"ax",@progbits
+.globl  B
+B:
+ nop
+
+.section    .text.C,"ax",@progbits
+.globl  C
+C:
+ nop
+
+.section    .text.D,"ax",@progbits
+.globl  D
+D:
+ nop
diff --git a/test/ELF/compressed-debug-input-err.s b/test/ELF/compressed-debug-input-err.s
index e32ba31..191075e 100644
--- a/test/ELF/compressed-debug-input-err.s
+++ b/test/ELF/compressed-debug-input-err.s
@@ -3,8 +3,8 @@
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
 # RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s
 
-## Check we are able to report zlib decompressor errors.
-# CHECK: error: {{.*}}.o:(.zdebug_str): decompress failed: zlib error: Z_DATA_ERROR
+## Check we are able to report zlib uncompress errors.
+# CHECK: error: {{.*}}.o:(.debug_str): uncompress failed: zlib error: Z_DATA_ERROR
 
 .section .zdebug_str,"MS",@progbits,1
  .ascii "ZLIB"
diff --git a/test/ELF/debug-line-str.s b/test/ELF/debug-line-str.s
new file mode 100644
index 0000000..e23b5c8
--- /dev/null
+++ b/test/ELF/debug-line-str.s
@@ -0,0 +1,136 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux -dwarf-version=5 %s -o %t.o
+# RUN: not ld.lld %t.o -o %t1 2>&1 | FileCheck %s
+
+# Check we do not crash and able to report the source location.
+
+# CHECK:      error: undefined symbol: foo()
+# CHECK-NEXT: >>> referenced by test.cpp:3
+# CHECK-NEXT: >>>               {{.*}}.o:(.text+0x1)
+
+# The code below is the reduced version of the output
+# from the following invocation and source:
+#
+# // test.cpp:
+# int foo();
+# int main() {
+#   return foo();
+# }
+#
+# clang -gdwarf-5 test.cpp -o test.s -S
+# clang version 8.0.0 (trunk 343487)
+
+.text
+.file "test.cpp"
+.globl main
+.type main,@function
+main:
+.Lfunc_begin0:
+ .file 0 "/home/path" "test.cpp" md5 0x8ed32099ab837bd13543fd3e8102739f
+ .file 1 "test.cpp" md5 0x8ed32099ab837bd13543fd3e8102739f
+ .loc 1 3 10 prologue_end
+ jmp _Z3foov
+.Lfunc_end0:
+
+.Lstr_offsets_base0:
+.section .debug_str,"MS",@progbits,1
+ .asciz "stub"
+
+.section .debug_str_offsets,"",@progbits
+ .long 0
+
+.section .debug_abbrev,"",@progbits
+ .byte 1                           # Abbreviation Code
+ .byte 17                          # DW_TAG_compile_unit
+ .byte 0                           # DW_CHILDREN_yes
+ .byte 37                          # DW_AT_producer
+ .byte 37                          # DW_FORM_strx1
+ .byte 19                          # DW_AT_language
+ .byte 5                           # DW_FORM_data2
+ .byte 3                           # DW_AT_name
+ .byte 37                          # DW_FORM_strx1
+ .byte 114                         # DW_AT_str_offsets_base
+ .byte 23                          # DW_FORM_sec_offset
+ .byte 16                          # DW_AT_stmt_list
+ .byte 23                          # DW_FORM_sec_offset
+ .byte 27                          # DW_AT_comp_dir
+ .byte 37                          # DW_FORM_strx1
+ .byte 17                          # DW_AT_low_pc
+ .byte 1                           # DW_FORM_addr
+ .byte 18                          # DW_AT_high_pc
+ .byte 6                           # DW_FORM_data4
+ .byte 0                           # EOM(1)
+ .byte 0                           # EOM(2)
+
+ .byte 2                           # Abbreviation Code
+ .byte 46                          # DW_TAG_subprogram
+ .byte 0                           # DW_CHILDREN_no
+ .byte 17                          # DW_AT_low_pc
+ .byte 1                           # DW_FORM_addr
+ .byte 18                          # DW_AT_high_pc
+ .byte 6                           # DW_FORM_data4
+ .byte 64                          # DW_AT_frame_base
+ .byte 24                          # DW_FORM_exprloc
+ .byte 3                           # DW_AT_name
+ .byte 37                          # DW_FORM_strx1
+ .byte 58                          # DW_AT_decl_file
+ .byte 11                          # DW_FORM_data1
+ .byte 59                          # DW_AT_decl_line
+ .byte 11                          # DW_FORM_data1
+ .byte 73                          # DW_AT_type
+ .byte 19                          # DW_FORM_ref4
+ .byte 63                          # DW_AT_external
+ .byte 25                          # DW_FORM_flag_present
+ .byte 0                           # EOM(1)
+ .byte 0                           # EOM(2)
+
+ .byte 3                           # Abbreviation Code
+ .byte 36                          # DW_TAG_base_type
+ .byte 0                           # DW_CHILDREN_no
+ .byte 3                           # DW_AT_name
+ .byte 37                          # DW_FORM_strx1
+ .byte 62                          # DW_AT_encoding
+ .byte 11                          # DW_FORM_data1
+ .byte 11                          # DW_AT_byte_size
+ .byte 11                          # DW_FORM_data1
+ .byte 0                           # EOM(1)
+ .byte 0                           # EOM(2)
+ .byte 0                           # EOM(3)
+
+.section .debug_info,"",@progbits
+.Lcu_begin0:
+ .long 61                         # Length of Unit
+ .short 5                         # DWARF version number
+ .byte  1                         # DWARF Unit Type
+ .byte  8                         # Address Size (in bytes)
+ .long  .debug_abbrev             # Offset Into Abbrev. Section
+
+ .byte  1                         # Abbrev [1] 0xc:0x35 DW_TAG_compile_unit
+ .byte  0                         # DW_AT_producer
+ .short 0                         # DW_AT_language
+ .byte  0                         # DW_AT_name
+ .long  .Lstr_offsets_base0       # DW_AT_str_offsets_base
+ .long  .Lline_table_start0       # DW_AT_stmt_list
+ .byte  0                         # DW_AT_comp_dir
+ .quad  .Lfunc_begin0             # DW_AT_low_pc
+ .long  .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ 
+ .byte  2                         # Abbrev [2] 0x26:0x16 DW_TAG_subprogram
+ .quad  .Lfunc_begin0             # DW_AT_low_pc
+ .long  .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte  1                         # DW_AT_frame_base
+ .byte  87
+ .byte  0                         # DW_AT_name
+ .byte  1                         # DW_AT_decl_file
+ .byte  2                         # DW_AT_decl_line
+ .long  60                        # DW_AT_type
+                                  # DW_AT_external
+
+ .byte  3                         # Abbrev [3] 0x3c:0x4 DW_TAG_base_type
+ .byte  0                         # DW_AT_name
+ .byte  5                         # DW_AT_encoding
+ .byte  4                         # DW_AT_byte_size
+ .byte  0                         # End Of Children Mark
+
+.section .debug_line,"",@progbits
+.Lline_table_start0:
diff --git a/test/ELF/debug-relocation-none.test b/test/ELF/debug-relocation-none.test
new file mode 100644
index 0000000..d22941d
--- /dev/null
+++ b/test/ELF/debug-relocation-none.test
@@ -0,0 +1,58 @@
+# REQUIRES: x86
+# RUN: yaml2obj %s -o %t.o
+# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s
+
+## Previously we would report an error saying the relocation in .debug_info
+## has an unsupported target.
+## Check we do not report debug information parsing errors when relocation
+## used is of type R_*_NONE, what actually means it should be ignored.
+
+# CHECK-NOT: error
+# CHECK: error: undefined symbol: bar
+# CHECK-NOT: error
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    Content:         '0000000000000000'
+  - Name:            .rela.text
+    Type:            SHT_RELA
+    AddressAlign:    8
+    Link:            .symtab
+    Info:            .text
+    Relocations:
+      - Offset:          0x0000000000000000
+        Symbol:          bar
+        Type:            R_X86_64_64
+  - Name:            .debug_line
+    Type:            SHT_PROGBITS
+    Content:         3300000002001C0000000101FB0E0D000101010100000001000001006162632E7300000000000009020000000000000000140208000101
+  - Name:            .rela.debug_line
+    AddressAlign:    8
+    Type:            SHT_RELA
+    Link:            .symtab
+    Info:            .debug_line
+    Relocations:
+      - Offset:          0x0000000000000029
+        Type:            R_X86_64_NONE
+  - Name:            .debug_info
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x0000000000000001
+    Content:         0C000000040000000000080100000000
+  - Name:            .debug_abbrev
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x0000000000000001
+    Content:         '0111001017000000'
+
+Symbols:
+  Global:
+    - Name:            _start
+      Section:         .text
+    - Name:            bar
diff --git a/test/ELF/defsym.s b/test/ELF/defsym.s
index c819cd3..1bf5064 100644
--- a/test/ELF/defsym.s
+++ b/test/ELF/defsym.s
@@ -74,6 +74,12 @@
 # RUN: not ld.lld -o %t %t.o --defsym=xxx=yyy,zzz 2>&1 | FileCheck %s -check-prefix=ERR2
 # ERR2: -defsym:1: EOF expected, but got ,
 
+# RUN: not ld.lld -o %t %t.o --defsym=foo 2>&1 | FileCheck %s -check-prefix=ERR3
+# ERR3: error: -defsym: syntax error: foo
+
+# RUN: not ld.lld -o %t %t.o --defsym= 2>&1 | FileCheck %s -check-prefix=ERR4
+# ERR4: error: -defsym: syntax error:
+
 .globl foo1
  foo1 = 0x123
 
diff --git a/test/ELF/dt_flags.s b/test/ELF/dt_flags.s
index e160e06..8f84dfc 100644
--- a/test/ELF/dt_flags.s
+++ b/test/ELF/dt_flags.s
@@ -3,7 +3,8 @@
 # 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 initfirst -z now -z nodelete -z nodlopen -z origin -Bsymbolic %t %t.so -o %t1
+# RUN: ld.lld -z global -z initfirst -z interpose -z now -z nodelete \
+# RUN:   -z nodlopen -z origin -Bsymbolic %t %t.so -o %t1
 # RUN: llvm-readobj -dynamic-table %t1 | FileCheck -check-prefix=FLAGS %s
 
 # RUN: ld.lld %t %t.so -o %t2
@@ -14,7 +15,7 @@
 
 # FLAGS: DynamicSection [
 # FLAGS:   0x000000000000001E FLAGS ORIGIN SYMBOLIC BIND_NOW
-# FLAGS:   0x000000006FFFFFFB FLAGS_1 NOW NODELETE INITFIRST NOOPEN ORIGIN
+# FLAGS:   0x000000006FFFFFFB FLAGS_1 NOW GLOBAL NODELETE INITFIRST NOOPEN ORIGIN INTERPOSE
 # FLAGS: ]
 
 # CHECK: DynamicSection [
diff --git a/test/ELF/emit-relocs-icf1.s b/test/ELF/emit-relocs-icf1.s
new file mode 100644
index 0000000..2f7e0ca
--- /dev/null
+++ b/test/ELF/emit-relocs-icf1.s
@@ -0,0 +1,32 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld --emit-relocs --icf=all %t.o -o %t
+# RUN: llvm-readobj -r %t | FileCheck %s
+
+# CHECK:      Relocations [
+# CHECK-NEXT:   Section (3) .rela.text {
+# CHECK-NEXT:     0x201000 R_X86_64_64 .text 0x11
+# CHECK-NEXT:     0x201008 R_X86_64_64 .text 0x11
+# CHECK-NEXT:     0x201011 R_X86_64_64 .rodata 0x0
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+.rodata
+quux:
+.quad 0xfe
+
+.section .text.foo,"ax"
+foo:
+.quad quux
+
+.section .text.bar,"ax"
+bar:
+.quad quux
+
+.text
+.quad foo
+.quad bar
+
+.global _start
+_start:
+  nop
diff --git a/test/ELF/emit-relocs-icf2.s b/test/ELF/emit-relocs-icf2.s
new file mode 100644
index 0000000..7c9ac22
--- /dev/null
+++ b/test/ELF/emit-relocs-icf2.s
@@ -0,0 +1,36 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld --gc-sections --emit-relocs --icf=all %t.o -o %t
+# RUN: llvm-readobj -r %t | FileCheck %s
+
+# CHECK:      Relocations [
+# CHECK-NEXT:   Section (3) .rela.text {
+# CHECK-NEXT:     0x201000 R_X86_64_64 .text 0x11
+# CHECK-NEXT:     0x201008 R_X86_64_64 .text 0x11
+# CHECK-NEXT:     0x201011 R_X86_64_64 .rodata 0x0
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+.rodata
+quux:
+.quad 0xfe
+
+.section .text.foo,"ax"
+foo:
+.quad quux
+
+.section .text.bar,"ax"
+bar:
+.quad quux
+
+.section .text.baz,"ax"
+baz:
+.quad quux
+
+.text
+.quad foo
+.quad bar
+
+.global _start
+_start:
+  nop
diff --git a/test/ELF/empty-pack-dyn-relocs.s b/test/ELF/empty-pack-dyn-relocs.s
new file mode 100644
index 0000000..b74a89d
--- /dev/null
+++ b/test/ELF/empty-pack-dyn-relocs.s
@@ -0,0 +1,11 @@
+// REQUIRES: x86
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+// RUN: ld.lld -pie --pack-dyn-relocs=relr %t.o -o %t
+// RUN: llvm-readobj -sections %t | FileCheck %s
+
+.global _start
+_start:
+  nop
+
+# CHECK-NOT: Name: .relr.dyn
diff --git a/test/ELF/gc-sections-implicit-addend.s b/test/ELF/gc-sections-implicit-addend.s
index 1270aff..e3bdeaa 100644
--- a/test/ELF/gc-sections-implicit-addend.s
+++ b/test/ELF/gc-sections-implicit-addend.s
@@ -12,10 +12,10 @@
 # CHECK-NEXT:   SHF_MERGE
 # CHECK-NEXT:   SHF_STRINGS
 # CHECK-NEXT: ]
-# CHECK-NEXT: Address: 0x100B4
+# CHECK-NEXT: Address: 0x4000B4
 
-# 0x100B4 == 65716
-# DISASM: leal    65716, %eax
+# 0x4000B4 == 4194484
+# DISASM: leal    4194484, %eax
 
         .section        .foo,"aMS",@progbits,1
         .byte 0
diff --git a/test/ELF/gnu-ifunc-i386.s b/test/ELF/gnu-ifunc-i386.s
index f379bf1..226e0e5 100644
--- a/test/ELF/gnu-ifunc-i386.s
+++ b/test/ELF/gnu-ifunc-i386.s
@@ -22,8 +22,8 @@
 // CHECK-NEXT: }
 // CHECK:     Relocations [
 // CHECK-NEXT:   Section ({{.*}}) .rel.plt {
-// CHECK-NEXT:     0x12000 R_386_IRELATIVE
-// CHECK-NEXT:     0x12004 R_386_IRELATIVE
+// CHECK-NEXT:     0x402000 R_386_IRELATIVE
+// CHECK-NEXT:     0x402004 R_386_IRELATIVE
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]
 
@@ -39,7 +39,7 @@
 // CHECK-NEXT: }
 // CHECK-NEXT: Symbol {
 // CHECK-NEXT:   Name: __rel_iplt_end
-// CHECK-NEXT:   Value: 0x100E4
+// CHECK-NEXT:   Value: 0x4000E4
 // CHECK-NEXT:   Size: 0
 // CHECK-NEXT:   Binding: Local
 // CHECK-NEXT:   Type: None
@@ -61,7 +61,7 @@
 // CHECK-NEXT: }
 // CHECK-NEXT: Symbol {
 // CHECK-NEXT:   Name: _start
-// CHECK-NEXT:   Value: 0x11002
+// CHECK-NEXT:   Value: 0x401002
 // CHECK-NEXT:   Size: 0
 // CHECK-NEXT:   Binding: Global
 // CHECK-NEXT:   Type: None
@@ -70,7 +70,7 @@
 // CHECK-NEXT: }
 // CHECK-NEXT: Symbol {
 // CHECK-NEXT:   Name: bar
-// CHECK-NEXT:   Value: 0x11001
+// CHECK-NEXT:   Value: 0x401001
 // CHECK-NEXT:   Size: 0
 // CHECK-NEXT:   Binding: Global
 // CHECK-NEXT:   Type: GNU_IFunc
@@ -79,7 +79,7 @@
 // CHECK-NEXT: }
 // CHECK-NEXT: Symbol {
 // CHECK-NEXT:   Name: foo
-// CHECK-NEXT:   Value: 0x11000
+// CHECK-NEXT:   Value: 0x401000
 // CHECK-NEXT:   Size: 0
 // CHECK-NEXT:   Binding: Global
 // CHECK-NEXT:   Type: GNU_IFunc
@@ -90,22 +90,22 @@
 
 // DISASM: Disassembly of section .text:
 // DISASM-NEXT: foo:
-// DISASM-NEXT:    11000: c3 retl
+// DISASM-NEXT:    401000: c3 retl
 // DISASM: bar:
-// DISASM-NEXT:    11001: c3 retl
+// DISASM-NEXT:    401001: c3 retl
 // DISASM:      _start:
-// DISASM-NEXT:    11002: e8 19 00 00 00 calll 25
-// DISASM-NEXT:    11007: e8 24 00 00 00 calll 36
-// DISASM-NEXT:    1100c: ba d4 00 01 00 movl $65748, %edx
-// DISASM-NEXT:    11011: ba e4 00 01 00 movl $65764, %edx
+// DISASM-NEXT:    401002: e8 19 00 00 00 calll 25
+// DISASM-NEXT:    401007: e8 24 00 00 00 calll 36
+// DISASM-NEXT:    40100c: ba d4 00 40 00 movl $4194516, %edx
+// DISASM-NEXT:    401011: ba e4 00 40 00 movl $4194532, %edx
 // DISASM-NEXT: Disassembly of section .plt:
 // DISASM-NEXT: .plt:
-// DISASM-NEXT:    11020: ff 25 00 20 01 00 jmpl *73728
-// DISASM-NEXT:    11026: 68 10 00 00 00 pushl $16
-// DISASM-NEXT:    1102b: e9 e0 ff ff ff jmp -32 <_start+0xe>
-// DISASM-NEXT:    11030: ff 25 04 20 01 00 jmpl *73732
-// DISASM-NEXT:    11036: 68 18 00 00 00 pushl $24
-// DISASM-NEXT:    1103b: e9 d0 ff ff ff jmp -48 <_start+0xe>
+// DISASM-NEXT:    401020: ff 25 00 20 40 00 jmpl *4202496
+// DISASM-NEXT:    401026: 68 10 00 00 00 pushl $16
+// DISASM-NEXT:    40102b: e9 e0 ff ff ff jmp -32 <_start+0xe>
+// DISASM-NEXT:    401030: ff 25 04 20 40 00 jmpl *4202500
+// DISASM-NEXT:    401036: 68 18 00 00 00 pushl $24
+// DISASM-NEXT:    40103b: e9 d0 ff ff ff jmp -48 <_start+0xe>
 
 .text
 .type foo STT_GNU_IFUNC
diff --git a/test/ELF/gnu-ifunc-plt-i386.s b/test/ELF/gnu-ifunc-plt-i386.s
index 14369bf..3ed4e76 100644
--- a/test/ELF/gnu-ifunc-plt-i386.s
+++ b/test/ELF/gnu-ifunc-plt-i386.s
@@ -10,16 +10,16 @@
 // Check that the IRELATIVE relocations are after the JUMP_SLOT in the plt
 // CHECK: Relocations [
 // CHECK-NEXT:   Section (4) .rel.plt {
-// CHECK-NEXT:     0x1200C R_386_JUMP_SLOT bar2
-// CHECK-NEXT:     0x12010 R_386_JUMP_SLOT zed2
-// CHECK-NEXT:     0x12014 R_386_IRELATIVE
-// CHECK-NEXT:     0x12018 R_386_IRELATIVE
+// CHECK-NEXT:     0x40200C R_386_JUMP_SLOT bar2
+// CHECK-NEXT:     0x402010 R_386_JUMP_SLOT zed2
+// CHECK-NEXT:     0x402014 R_386_IRELATIVE
+// CHECK-NEXT:     0x402018 R_386_IRELATIVE
 
 // Check that IRELATIVE .got.plt entries point to ifunc resolver and not
 // back to the plt entry + 6.
 // GOTPLT: Contents of section .got.plt:
-// GOTPLT:       12000 00300100 00000000 00000000 36100100
-// GOTPLT-NEXT:  12010 46100100 00100100 01100100
+// GOTPLT:       402000 00304000 00000000 00000000 36104000
+// GOTPLT-NEXT:  402010 46104000 00104000 01104000
 
 // Check that the PLTRELSZ tag includes the IRELATIVE relocations
 // CHECK: DynamicSection [
@@ -28,34 +28,38 @@
 // Check that a PLT header is written and the ifunc entries appear last
 // DISASM: Disassembly of section .text:
 // DISASM-NEXT: foo:
-// DISASM-NEXT:    11000:       c3      retl
+// DISASM-NEXT:    401000:       c3      retl
 // DISASM:      bar:
-// DISASM-NEXT:    11001:       c3      retl
+// DISASM-NEXT:    401001:       c3      retl
 // DISASM:      _start:
-// DISASM-NEXT:    11002:       e8 49 00 00 00          calll   73
-// DISASM-NEXT:    11007:       e8 54 00 00 00          calll   84
-// DISASM-NEXT:    1100c:       e8 1f 00 00 00          calll   31
-// DISASM-NEXT:    11011:       e8 2a 00 00 00          calll   42
+// DISASM-NEXT:    401002:       e8 49 00 00 00          calll   73
+// DISASM-NEXT:    401007:       e8 54 00 00 00          calll   84
+// DISASM-NEXT:    40100c:       e8 1f 00 00 00          calll   31
+// DISASM-NEXT:    401011:       e8 2a 00 00 00          calll   42
 // DISASM-NEXT: Disassembly of section .plt:
 // DISASM-NEXT: .plt:
-// DISASM-NEXT:    11020:       ff 35 04 20 01 00       pushl   73732
-// DISASM-NEXT:    11026:       ff 25 08 20 01 00       jmpl    *73736
-// DISASM-NEXT:    1102c:       90      nop
-// DISASM-NEXT:    1102d:       90      nop
-// DISASM-NEXT:    1102e:       90      nop
-// DISASM-NEXT:    1102f:       90      nop
-// DISASM-NEXT:    11030:       ff 25 0c 20 01 00       jmpl    *73740
-// DISASM-NEXT:    11036:       68 00 00 00 00          pushl   $0
-// DISASM-NEXT:    1103b:       e9 e0 ff ff ff          jmp     -32 <.plt>
-// DISASM-NEXT:    11040:       ff 25 10 20 01 00       jmpl    *73744
-// DISASM-NEXT:    11046:       68 08 00 00 00          pushl   $8
-// DISASM-NEXT:    1104b:       e9 d0 ff ff ff          jmp     -48 <.plt>
-// DISASM-NEXT:    11050:       ff 25 14 20 01 00       jmpl    *73748
-// DISASM-NEXT:    11056:       68 30 00 00 00          pushl   $48
-// DISASM-NEXT:    1105b:       e9 e0 ff ff ff          jmp     -32 <.plt+0x20>
-// DISASM-NEXT:    11060:       ff 25 18 20 01 00       jmpl    *73752
-// DISASM-NEXT:    11066:       68 38 00 00 00          pushl   $56
-// DISASM-NEXT:    1106b:       e9 d0 ff ff ff          jmp     -48 <.plt+0x20>
+// DISASM-NEXT:    401020:       ff 35 04 20 40 00       pushl   4202500
+// DISASM-NEXT:    401026:       ff 25 08 20 40 00       jmpl    *4202504
+// DISASM-NEXT:    40102c:       90      nop
+// DISASM-NEXT:    40102d:       90      nop
+// DISASM-NEXT:    40102e:       90      nop
+// DISASM-NEXT:    40102f:       90      nop
+// DISASM-EMPTY:
+// DISASM-NEXT:   bar2@plt:
+// DISASM-NEXT:    401030:       ff 25 0c 20 40 00       jmpl    *4202508
+// DISASM-NEXT:    401036:       68 00 00 00 00          pushl   $0
+// DISASM-NEXT:    40103b:       e9 e0 ff ff ff          jmp     -32 <.plt>
+// DISASM-EMPTY:
+// DISASM-NEXT:   zed2@plt:
+// DISASM-NEXT:    401040:       ff 25 10 20 40 00       jmpl    *4202512
+// DISASM-NEXT:    401046:       68 08 00 00 00          pushl   $8
+// DISASM-NEXT:    40104b:       e9 d0 ff ff ff          jmp     -48 <.plt>
+// DISASM-NEXT:    401050:       ff 25 14 20 40 00       jmpl    *4202516
+// DISASM-NEXT:    401056:       68 30 00 00 00          pushl   $48
+// DISASM-NEXT:    40105b:       e9 e0 ff ff ff          jmp     -32 <zed2@plt>
+// DISASM-NEXT:    401060:       ff 25 18 20 40 00       jmpl    *4202520
+// DISASM-NEXT:    401066:       68 38 00 00 00          pushl   $56
+// DISASM-NEXT:    40106b:       e9 d0 ff ff ff          jmp     -48 <zed2@plt>
 
 .text
 .type foo STT_GNU_IFUNC
diff --git a/test/ELF/gnu-ifunc-plt.s b/test/ELF/gnu-ifunc-plt.s
index b88f32c..aa1c3c7 100644
--- a/test/ELF/gnu-ifunc-plt.s
+++ b/test/ELF/gnu-ifunc-plt.s
@@ -42,18 +42,22 @@
 // DISASM-NEXT:   201020:       ff 35 e2 0f 00 00       pushq   4066(%rip)
 // DISASM-NEXT:   201026:       ff 25 e4 0f 00 00       jmpq    *4068(%rip)
 // DISASM-NEXT:   20102c:       0f 1f 40 00     nopl    (%rax)
+// DISASM-EMPTY:
+// DISASM-NEXT:   bar2@plt:
 // DISASM-NEXT:   201030:       ff 25 e2 0f 00 00       jmpq    *4066(%rip)
 // DISASM-NEXT:   201036:       68 00 00 00 00          pushq   $0
 // DISASM-NEXT:   20103b:       e9 e0 ff ff ff          jmp     -32 <.plt>
+// DISASM-EMPTY:
+// DISASM-NEXT:   zed2@plt:
 // DISASM-NEXT:   201040:       ff 25 da 0f 00 00       jmpq    *4058(%rip)
 // DISASM-NEXT:   201046:       68 01 00 00 00          pushq   $1
 // DISASM-NEXT:   20104b:       e9 d0 ff ff ff          jmp     -48 <.plt>
 // DISASM-NEXT:   201050:       ff 25 d2 0f 00 00       jmpq    *4050(%rip)
 // DISASM-NEXT:   201056:       68 00 00 00 00          pushq   $0
-// DISASM-NEXT:   20105b:       e9 e0 ff ff ff          jmp     -32 <.plt+0x20>
+// DISASM-NEXT:   20105b:       e9 e0 ff ff ff          jmp     -32 <zed2@plt>
 // DISASM-NEXT:   201060:       ff 25 ca 0f 00 00       jmpq    *4042(%rip)
 // DISASM-NEXT:   201066:       68 01 00 00 00          pushq   $1
-// DISASM-NEXT:   20106b:       e9 d0 ff ff ff          jmp     -48 <.plt+0x20>
+// DISASM-NEXT:   20106b:       e9 d0 ff ff ff          jmp     -48 <zed2@plt>
 
 .text
 .type foo STT_GNU_IFUNC
diff --git a/test/ELF/gnu-ifunc-shared.s b/test/ELF/gnu-ifunc-shared.s
index bde6807..bc91ff9 100644
--- a/test/ELF/gnu-ifunc-shared.s
+++ b/test/ELF/gnu-ifunc-shared.s
@@ -23,15 +23,19 @@
 // DISASM-NEXT:     1020:       ff 35 e2 0f 00 00       pushq   4066(%rip)
 // DISASM-NEXT:     1026:       ff 25 e4 0f 00 00       jmpq    *4068(%rip)
 // DISASM-NEXT:     102c:       0f 1f 40 00     nopl    (%rax)
+// DISASM-EMPTY:
+// DISASM-NEXT:   fct2@plt:
 // DISASM-NEXT:     1030:       ff 25 e2 0f 00 00       jmpq    *4066(%rip)
 // DISASM-NEXT:     1036:       68 00 00 00 00          pushq   $0
 // DISASM-NEXT:     103b:       e9 e0 ff ff ff          jmp     -32 <.plt>
+// DISASM-EMPTY:
+// DISASM-NEXT:   f2@plt:
 // DISASM-NEXT:     1040:       ff 25 da 0f 00 00       jmpq    *4058(%rip)
 // DISASM-NEXT:     1046:       68 01 00 00 00          pushq   $1
 // DISASM-NEXT:     104b:       e9 d0 ff ff ff          jmp     -48 <.plt>
 // DISASM-NEXT:     1050:       ff 25 d2 0f 00 00       jmpq    *4050(%rip)
 // DISASM-NEXT:     1056:       68 00 00 00 00          pushq   $0
-// DISASM-NEXT:     105b:       e9 e0 ff ff ff          jmp     -32 <.plt+0x20>
+// DISASM-NEXT:     105b:       e9 e0 ff ff ff          jmp     -32 <f2@plt>
 
 // CHECK: Relocations [
 // CHECK-NEXT:   Section (4) .rela.plt {
diff --git a/test/ELF/got-i386.s b/test/ELF/got-i386.s
index 7fb87e0..3b2ef1a 100644
--- a/test/ELF/got-i386.s
+++ b/test/ELF/got-i386.s
@@ -10,7 +10,7 @@
 // CHECK-NEXT:   SHF_ALLOC
 // CHECK-NEXT:   SHF_WRITE
 // CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x12000
+// CHECK-NEXT: Address: 0x402000
 // CHECK-NEXT: Offset:
 // CHECK-NEXT: Size: 0
 // CHECK-NEXT: Link:
@@ -19,7 +19,7 @@
 
 // CHECK:      Symbol {
 // CHECK:       Name: bar
-// CHECK-NEXT:  Value: 0x12000
+// CHECK-NEXT:  Value: 0x402000
 // CHECK-NEXT:  Size: 10
 // CHECK-NEXT:  Binding: Global
 // CHECK-NEXT:  Type: Object
@@ -28,7 +28,7 @@
 // CHECK-NEXT: }
 // CHECK-NEXT: Symbol {
 // CHECK-NEXT:  Name: obj
-// CHECK-NEXT:  Value: 0x1200A
+// CHECK-NEXT:  Value: 0x40200A
 // CHECK-NEXT:  Size: 10
 // CHECK-NEXT:  Binding: Global
 // CHECK-NEXT:  Type: Object
@@ -36,14 +36,14 @@
 // CHECK-NEXT:  Section: .bss
 // CHECK-NEXT: }
 
-// 0x12000 - 0 = addr(.got) = 0x12000
-// 0x1200A - 10 = addr(.got) = 0x12000
-// 0x1200A + 5 - 15 = addr(.got) = 0x12000
+// 0x402000 - 0 = addr(.got) = 0x402000
+// 0x40200A - 10 = addr(.got) = 0x402000
+// 0x40200A + 5 - 15 = addr(.got) = 0x402000
 // DISASM:      Disassembly of section .text:
 // DISASM-NEXT: _start:
-// DISASM-NEXT: 11000: c7 81 00 00 00 00 01 00 00 00 movl $1, (%ecx)
-// DISASM-NEXT: 1100a: c7 81 0a 00 00 00 02 00 00 00 movl $2, 10(%ecx)
-// DISASM-NEXT: 11014: c7 81 0f 00 00 00 03 00 00 00 movl $3, 15(%ecx)
+// DISASM-NEXT: 401000: c7 81 00 00 00 00 01 00 00 00 movl $1, (%ecx)
+// DISASM-NEXT: 40100a: c7 81 0a 00 00 00 02 00 00 00 movl $2, 10(%ecx)
+// DISASM-NEXT: 401014: c7 81 0f 00 00 00 03 00 00 00 movl $3, 15(%ecx)
 
 .global _start
 _start:
diff --git a/test/ELF/got32-i386.s b/test/ELF/got32-i386.s
index dce50d0..ff67a4b 100644
--- a/test/ELF/got32-i386.s
+++ b/test/ELF/got32-i386.s
@@ -14,10 +14,10 @@
 
 ## 73728 == 0x12000 == ADDR(.got)
 # CHECK:       _start:
-# CHECK-NEXT:   11001: 8b 1d {{.*}}  movl 73728, %ebx
+# CHECK-NEXT:   401001: 8b 1d {{.*}}  movl 4202496, %ebx
 # CHECK: Sections:
 # CHECK:  Name Size     Address
-# CHECK:  .got 00000004 0000000000012000
+# CHECK:  .got 00000004 0000000000402000
 
 # RUN: not ld.lld %t.o -o %t -pie 2>&1 | FileCheck %s --check-prefix=ERR
 # ERR: error: can't create dynamic relocation R_386_GOT32 against symbol: foo in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
diff --git a/test/ELF/got32x-i386.s b/test/ELF/got32x-i386.s
index 610051e..88e7e31 100644
--- a/test/ELF/got32x-i386.s
+++ b/test/ELF/got32x-i386.s
@@ -33,13 +33,13 @@
 
 ## 73728 == 0x12000 == ADDR(.got)
 # CHECK:       _start:
-# CHECK-NEXT:   11001: 8b 05 {{.*}} movl 77824, %eax
-# CHECK-NEXT:   11007: 8b 1d {{.*}} movl 77824, %ebx
-# CHECK-NEXT:   1100d: 8b 80 {{.*}} movl -4(%eax), %eax
-# CHECK-NEXT:   11013: 8b 83 {{.*}} movl -4(%ebx), %eax
+# CHECK-NEXT:   401001: 8b 05 {{.*}} movl 4206592, %eax
+# CHECK-NEXT:   401007: 8b 1d {{.*}} movl 4206592, %ebx
+# CHECK-NEXT:   40100d: 8b 80 {{.*}} movl -4(%eax), %eax
+# CHECK-NEXT:   401013: 8b 83 {{.*}} movl -4(%ebx), %eax
 # CHECK: Sections:
 # CHECK:  Name Size     Address
-# CHECK:  .got 00000004 0000000000013000
+# CHECK:  .got 00000004 0000000000403000
 
 # RUN: not ld.lld %S/Inputs/i386-got32x-baseless.elf -o %t1 -pie 2>&1 | \
 # RUN:   FileCheck %s --check-prefix=ERR
diff --git a/test/ELF/hexagon-shared.s b/test/ELF/hexagon-shared.s
new file mode 100644
index 0000000..97f8e84
--- /dev/null
+++ b/test/ELF/hexagon-shared.s
@@ -0,0 +1,46 @@
+# REQUIRES: hexagon
+# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf %s -o %t
+# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf %S/Inputs/hexagon-shared.s -o %t2.o
+# RUN: ld.lld -shared %t2.o -soname %t3.so -o %t3.so
+# RUN: ld.lld -shared %t %t3.so -soname %t4.so -o %t4.so
+# RUN: llvm-objdump -d -j .plt %t4.so | FileCheck --check-prefix=PLT %s
+# RUN: llvm-objdump -d -j .text %t4.so | FileCheck --check-prefix=TEXT %s
+# RUN: llvm-objdump -D -j .got %t4.so | FileCheck --check-prefix=GOT %s
+
+.global foo
+foo:
+
+# _HEX_32_PCREL
+.word _DYNAMIC - .
+call ##bar
+
+# R_HEX_PLT_B22_PCREL
+call bar@PLT
+
+# R_HEX_GOT_11_X and R_HEX_GOT_32_6_X
+r2=add(pc,##_GLOBAL_OFFSET_TABLE_@PCREL)
+r0 = memw (r2+##bar@GOT)
+jumpr r0
+
+# R_HEX_GOT_16_X
+r0 = add(r1,##bar@GOT)
+
+# PLT: { immext(#65472
+# PLT: r28 = add(pc,##65488) }
+# PLT: { r14 -= add(r28,#16)
+# PLT: r15 = memw(r28+#8)
+# PLT: r28 = memw(r28+#4) }
+# PLT: { r14 = asr(r14,#2)
+# PLT: jumpr r28 }
+# PLT: { trap0(#219) }
+# PLT: immext(#65472)
+# PLT: r14 = add(pc,##65472) }
+# PLT: r28 = memw(r14+#0) }
+# PLT: jumpr r28 }
+
+# TEXT:  10000: 00 00 02 00 00020000
+# TEXT: { 	call 0x10050 }
+# TEXT: r0 = add(r1,##65664) }
+
+# GOT: .got:
+# GOT: 30080:	00 00 00 00 00000000 <unknown>
diff --git a/test/ELF/hexagon.s b/test/ELF/hexagon.s
index d3eaa37..c8dd271 100644
--- a/test/ELF/hexagon.s
+++ b/test/ELF/hexagon.s
@@ -4,89 +4,89 @@
 # RUN: ld.lld %t2 %t  -o %t3
 # RUN: llvm-objdump -d  %t3 | FileCheck %s
 
-# Note: 69632 == 0x11000
+# Note: 131072 == 0x20000
 # R_HEX_32_6_X
 # R_HEX_12_X
 if (p0) r0 = ##_start
-# CHECK: immext(#69632)
-# CHECK: if (p0) r0 = ##69632
+# CHECK: immext(#131072)
+# CHECK: if (p0) r0 = ##131072
 
 # R_HEX_B15_PCREL
 if (p0) jump:nt #_start
-# CHECK: if (p0) jump:nt 0x11000
+# CHECK: if (p0) jump:nt 0x20000
 
 # R_HEX_B32_PCREL_X
 # R_HEX_B15_PCREL_X
 if (p0) jump:nt ##_start
-# CHECK: if (p0) jump:nt 0x11000
+# CHECK: if (p0) jump:nt 0x20000
 
 # R_HEX_B22_PCREL
 call #_start
-# CHECK: call 0x11000
+# CHECK: call 0x20000
 
 # R_HEX_B32_PCREL_X
 # R_HEX_B22_PCREL_X
 call ##_start
 # CHECK: immext(#4294967232)
-# CHECK: call 0x11000
+# CHECK: call 0x20000
 
 # R_HEX_6_X tests:
 # One test for each mask in the lookup table.
 
 #0x38000000
 if (!P0) memw(r0+#8)=##_start
-# CHECK: 38c0c100   	if (!p0) memw(r0+#8) = ##69632 }
+# CHECK: 38c0c100   	if (!p0) memw(r0+#8) = ##131072 }
 
 #0x39000000
 { p0 = p1
   if (!P0.new) memw(r0+#0)=##_start }
-# CHECK: 39c0c000   	if (!p0.new) memw(r0+#0) = ##69632 }
+# CHECK: 39c0c000   	if (!p0.new) memw(r0+#0) = ##131072 }
 
 #0x3e000000
 memw(r0+##_start)+=r1
-# CHECK: 3e40c001   	memw(r0+##69632) += r1 }
+# CHECK: 3e40c001   	memw(r0+##131072) += r1 }
 
 #0x3f000000
 memw(r0+##_start)+=#4
-# CHECK: 3f40c004   	memw(r0+##69632) += #4 }
+# CHECK: 3f40c004   	memw(r0+##131072) += #4 }
 
 #0x40000000
 { r0 = r1
   if (p0) memb(r0+##_start)=r0.new }
-# CHECK: 40a0c200   	if (p0) memb(r0+##69632) = r0.new }
+# CHECK: 40a0c200   	if (p0) memb(r0+##131072) = r0.new }
 
 #0x41000000
 if (p0) r0=memb(r1+##_start)
-# CHECK: 4101c000   	if (p0) r0 = memb(r1+##69632) }
+# CHECK: 4101c000   	if (p0) r0 = memb(r1+##131072) }
 
 #0x42000000
 { r0 = r1
   p0 = p1
   if (p0.new) memb(r0+##_start)=r0.new }
-# CHECK: 42a0c200   	if (p0.new) memb(r0+##69632) = r0.new }
+# CHECK: 42a0c200   	if (p0.new) memb(r0+##131072) = r0.new }
 
 #0x43000000
 { p0 = p1
  if (P0.new) r0=memb(r0+##_start) }
-# CHECK: 4300c000   	if (p0.new) r0 = memb(r0+##69632) }
+# CHECK: 4300c000   	if (p0.new) r0 = memb(r0+##131072) }
 
 #0x44000000
 if (!p0) memb(r0+##_start)=r1
-# CHECK: 4400c100   	if (!p0) memb(r0+##69632) = r1 }
+# CHECK: 4400c100   	if (!p0) memb(r0+##131072) = r1 }
 
 #0x45000000
 if (!p0) r0=memb(r1+##_start)
-# CHECK: 4501c000   	if (!p0) r0 = memb(r1+##69632) }
+# CHECK: 4501c000   	if (!p0) r0 = memb(r1+##131072) }
 
 #0x46000000
 { p0 = p1
   if (!p0.new) memb(r0+##_start)=r1 }
-# CHECK: 4600c100   	if (!p0.new) memb(r0+##69632) = r1 }
+# CHECK: 4600c100   	if (!p0.new) memb(r0+##131072) = r1 }
 
 #0x47000000
 { p0 = p1
   if (!p0.new) r0=memb(r1+##_start) }
-# CHECK: 4701c000   	if (!p0.new) r0 = memb(r1+##69632) }
+# CHECK: 4701c000   	if (!p0.new) r0 = memb(r1+##131072) }
 
 #0x6a000000 -- Note 4294967132 == -0xa4 the distance between
 #              here and _start, so this will change if
@@ -96,66 +96,128 @@
 
 #0x7c000000
 r1:0=combine(#8,##_start)
-# CHECK: 7c80c100   	r1:0 = combine(#8,##69632) }
+# CHECK: 7c80c100   	r1:0 = combine(#8,##131072) }
 
 #0x9a000000
 r1:0=memb_fifo(r2=##_start)
-# CHECK: 9a82d000   	r1:0 = memb_fifo(r2=##69632) }
+# CHECK: 9a82d000   	r1:0 = memb_fifo(r2=##131072) }
 
 #0x9b000000
 r0=memb(r1=##_start)
-# CHECK: 9b01d000   	r0 = memb(r1=##69632) }
+# CHECK: 9b01d000   	r0 = memb(r1=##131072) }
 
 #0x9c000000
 r1:0=memb_fifo(r2<<#2+##_start)
-# CHECK: 9c82f000   	r1:0 = memb_fifo(r2<<#2+##69632) }
+# CHECK: 9c82f000   	r1:0 = memb_fifo(r2<<#2+##131072) }
 
 #0x9d000000
 r0=memb(r1<<#2+##_start)
-# CHECK: 9d01f000   	r0 = memb(r1<<#2+##69632) }
+# CHECK: 9d01f000   	r0 = memb(r1<<#2+##131072) }
 
 #0x9f000000
 if (!p0) r0=memb(##_start)
-# CHECK: 9f00e880   	if (!p0) r0 = memb(##69632) }
+# CHECK: 9f00e880   	if (!p0) r0 = memb(##131072) }
 
 #0xab000000
 memb(r0=##_start)=r1
-# CHECK: ab00c180   	memb(r0=##69632) = r1 }
+# CHECK: ab00c180   	memb(r0=##131072) = r1 }
 
 #0xad000000
 memb(r0<<#2+##_start)=r1
-# CHECK: ad00e180   	memb(r0<<#2+##69632) = r1 }
+# CHECK: ad00e180   	memb(r0<<#2+##131072) = r1 }
 
 #0xaf000000
 if (!p0) memb(##_start)=r1
-# CHECK: af00c184   	if (!p0) memb(##69632) = r1 }
+# CHECK: af00c184   	if (!p0) memb(##131072) = r1 }
 
 #0xd7000000
 r0=add(##_start,mpyi(r1,r2))
-# CHECK: d701c200   	r0 = add(##69632,mpyi(r1,r2)) }
+# CHECK: d701c200   	r0 = add(##131072,mpyi(r1,r2)) }
 
 #0xd8000000
 R0=add(##_start,mpyi(r0,#2))
-# CHECK: d800c002   	r0 = add(##69632,mpyi(r0,#2)) }
+# CHECK: d800c002   	r0 = add(##131072,mpyi(r0,#2)) }
 
 #0xdb000000
 r0=add(r1,add(r2,##_start))
-# CHECK: db01c002   	r0 = add(r1,add(r2,##69632)) }
+# CHECK: db01c002   	r0 = add(r1,add(r2,##131072)) }
 
 #0xdf000000
 r0=add(r1,mpyi(r2,##_start))
-# CHECK: df82c001   	r0 = add(r1,mpyi(r2,##69632)) }
+# CHECK: df82c001   	r0 = add(r1,mpyi(r2,##131072)) }
 
 # Duplex form of R_HEX_6_X
 # R_HEX_32_6_X
 # R_HEX_6_X
 { r0 = ##_start; r2 = r16 }
-# CHECK: 28003082   	r0 = ##69632; 	r2 = r16 }
+# CHECK: 28003082   	r0 = ##131072; 	r2 = r16 }
 
 # R_HEX_HI16
 r0.h = #HI(_start)
-# CHECK: r0.h = #1
+# CHECK: r0.h = #2
 
 # R_HEX_LO16
 r0.l = #LO(_start)
-# CHECK: r0.l = #4096
+# CHECK: r0.l = #0
+
+# R_HEX_8_X has 3 relocation mask variations
+#0xde000000
+r0=sub(##_start, asl(r0, #1))
+# CHECK: de00c106      r0 = sub(##131072,asl(r0,#1)) }
+
+#0x3c000000
+memw(r0+#0) = ##_start
+# CHECK: 3c40c000   	memw(r0+#0) = ##131072 }
+
+# The rest:
+r1:0=combine(r2,##_start);
+# CHECK: 7302e000   	r1:0 = combine(r2,##131072) }
+
+# R_HEX_32:
+r_hex_32:
+.word _start
+# CHECK: 00020000
+
+# R_HEX_16_X has 4 relocation mask variations
+# 0x48000000
+memw(##_start) = r0
+# CHECK: 4880c000   memw(##131072) = r0 }
+
+# 0x49000000
+r0 = memw(##_start)
+# CHECK: 4980c000   r0 = memw(##131072)
+
+# 0x78000000
+r0 = ##_start
+# CHECK: 7800c000   r0 = ##131072 }
+
+# 0xb0000000
+r0 = add(r1, ##_start)
+# CHECK: b001c000   r0 = add(r1,##131072) }
+
+# R_HEX_B9_PCREL:
+{r0=#1 ; jump #_start}
+# CHECK: jump 0x20000
+
+# R_HEX_B9_PCREL_X:
+{r0=#1 ; jump ##_start}
+# CHECK: jump 0x20000
+
+# R_HEX_B13_PCREL
+if (r0 == #0) jump:t #_start
+# CHECK: if (r0==#0) jump:t 0x20000
+
+# R_HEX_9_X
+p0 = !cmp.gtu(r0, ##_start)
+# CHECK: p0 = !cmp.gtu(r0,##131072)
+
+# R_HEX_10_X
+p0 = !cmp.gt(r0, ##_start)
+# CHECK: p0 = !cmp.gt(r0,##131072)
+
+# R_HEX_11_X
+r0 = memw(r1+##_start)
+# CHECK: r0 = memw(r1+##131072)
+
+memw(r0+##_start) = r1
+# CHECK: memw(r0+##131072) = r1
diff --git a/test/ELF/i386-linkonce.s b/test/ELF/i386-linkonce.s
new file mode 100644
index 0000000..c06b042
--- /dev/null
+++ b/test/ELF/i386-linkonce.s
@@ -0,0 +1,9 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=i386-linux-gnu %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=i386-linux-gnu %p/Inputs/i386-linkonce.s -o %t2.o
+// RUN: llvm-ar rcs %t2.a %t2.o
+// RUN: ld.lld %t.o %t2.a -o %t
+
+    .globl _start
+_start:
+    call _strchr1
diff --git a/test/ELF/i386-pc8-pc16-addend.s b/test/ELF/i386-pc8-pc16-addend.s
index fc648b0..8dad18f 100644
--- a/test/ELF/i386-pc8-pc16-addend.s
+++ b/test/ELF/i386-pc8-pc16-addend.s
@@ -4,11 +4,11 @@
 # RUN: ld.lld %t1.o -o %t.out
 # RUN: llvm-objdump -s -t %t.out | FileCheck %s
 # CHECK:      Contents of section .text:
-# CHECK-NEXT:  11000 020000
-## 0x11003 - 0x11000 + addend(-1) = 0x02
-## 0x11003 - 0x11001 + addend(-2) = 0x0000
+# CHECK-NEXT:  401000 020000
+## 0x401003 - 0x401000 + addend(-1) = 0x02
+## 0x401003 - 0x401001 + addend(-2) = 0x0000
 # CHECK: SYMBOL TABLE:
-# CHECK: 00011003 .und
+# CHECK: 00401003 .und
 
 .byte  und-.-1
 .short und-.-2
diff --git a/test/ELF/i386-retpoline-nopic.s b/test/ELF/i386-retpoline-nopic.s
index 79dd5a6..6d0a699 100644
--- a/test/ELF/i386-retpoline-nopic.s
+++ b/test/ELF/i386-retpoline-nopic.s
@@ -8,56 +8,56 @@
 
 // CHECK:      Disassembly of section .plt:
 // CHECK-NEXT: .plt:
-// CHECK-NEXT: 11010:       ff 35 04 20 01 00       pushl   73732
-// CHECK-NEXT: 11016:       50      pushl   %eax
-// CHECK-NEXT: 11017:       a1 08 20 01 00  movl    73736, %eax
-// CHECK-NEXT: 1101c:       e8 0f 00 00 00  calll   15 <.plt+0x20>
-// CHECK-NEXT: 11021:       f3 90   pause
-// CHECK-NEXT: 11023:       0f ae e8        lfence
-// CHECK-NEXT: 11026:       eb f9   jmp     -7 <.plt+0x11>
-// CHECK-NEXT: 11028:       cc      int3
-// CHECK-NEXT: 11029:       cc      int3
-// CHECK-NEXT: 1102a:       cc      int3
-// CHECK-NEXT: 1102b:       cc      int3
-// CHECK-NEXT: 1102c:       cc      int3
-// CHECK-NEXT: 1102d:       cc      int3
-// CHECK-NEXT: 1102e:       cc      int3
-// CHECK-NEXT: 1102f:       cc      int3
-// CHECK-NEXT: 11030:       89 0c 24        movl    %ecx, (%esp)
-// CHECK-NEXT: 11033:       8b 4c 24 04     movl    4(%esp), %ecx
-// CHECK-NEXT: 11037:       89 44 24 04     movl    %eax, 4(%esp)
-// CHECK-NEXT: 1103b:       89 c8   movl    %ecx, %eax
-// CHECK-NEXT: 1103d:       59      popl    %ecx
-// CHECK-NEXT: 1103e:       c3      retl
-// CHECK-NEXT: 1103f:       cc      int3
-// CHECK-NEXT: 11040:       50      pushl   %eax
-// CHECK-NEXT: 11041:       a1 0c 20 01 00  movl    73740, %eax
-// CHECK-NEXT: 11046:       e8 e5 ff ff ff  calll   -27 <.plt+0x20>
-// CHECK-NEXT: 1104b:       e9 d1 ff ff ff  jmp     -47 <.plt+0x11>
-// CHECK-NEXT: 11050:       68 00 00 00 00  pushl   $0
-// CHECK-NEXT: 11055:       e9 b6 ff ff ff  jmp     -74 <.plt>
-// CHECK-NEXT: 1105a:       cc      int3
-// CHECK-NEXT: 1105b:       cc      int3
-// CHECK-NEXT: 1105c:       cc      int3
-// CHECK-NEXT: 1105d:       cc      int3
-// CHECK-NEXT: 1105e:       cc      int3
-// CHECK-NEXT: 1105f:       cc      int3
-// CHECK-NEXT: 11060:       50      pushl   %eax
-// CHECK-NEXT: 11061:       a1 10 20 01 00  movl    73744, %eax
-// CHECK-NEXT: 11066:       e8 c5 ff ff ff  calll   -59 <.plt+0x20>
-// CHECK-NEXT: 1106b:       e9 b1 ff ff ff  jmp     -79 <.plt+0x11>
-// CHECK-NEXT: 11070:       68 08 00 00 00  pushl   $8
-// CHECK-NEXT: 11075:       e9 96 ff ff ff  jmp     -106 <.plt>
-// CHECK-NEXT: 1107a:       cc      int3
-// CHECK-NEXT: 1107b:       cc      int3
-// CHECK-NEXT: 1107c:       cc      int3
-// CHECK-NEXT: 1107d:       cc      int3
-// CHECK-NEXT: 1107e:       cc      int3
-// CHECK-NEXT: 1107f:       cc      int3
+// CHECK-NEXT: 401010:       ff 35 04 20 40 00       pushl   4202500
+// CHECK-NEXT: 401016:       50      pushl   %eax
+// CHECK-NEXT: 401017:       a1 08 20 40 00  movl    4202504, %eax
+// CHECK-NEXT: 40101c:       e8 0f 00 00 00  calll   15 <.plt+0x20>
+// CHECK-NEXT: 401021:       f3 90   pause
+// CHECK-NEXT: 401023:       0f ae e8        lfence
+// CHECK-NEXT: 401026:       eb f9   jmp     -7 <.plt+0x11>
+// CHECK-NEXT: 401028:       cc      int3
+// CHECK-NEXT: 401029:       cc      int3
+// CHECK-NEXT: 40102a:       cc      int3
+// CHECK-NEXT: 40102b:       cc      int3
+// CHECK-NEXT: 40102c:       cc      int3
+// CHECK-NEXT: 40102d:       cc      int3
+// CHECK-NEXT: 40102e:       cc      int3
+// CHECK-NEXT: 40102f:       cc      int3
+// CHECK-NEXT: 401030:       89 0c 24        movl    %ecx, (%esp)
+// CHECK-NEXT: 401033:       8b 4c 24 04     movl    4(%esp), %ecx
+// CHECK-NEXT: 401037:       89 44 24 04     movl    %eax, 4(%esp)
+// CHECK-NEXT: 40103b:       89 c8   movl    %ecx, %eax
+// CHECK-NEXT: 40103d:       59      popl    %ecx
+// CHECK-NEXT: 40103e:       c3      retl
+// CHECK-NEXT: 40103f:       cc      int3
+// CHECK-NEXT: 401040:       50      pushl   %eax
+// CHECK-NEXT: 401041:       a1 0c 20 40 00  movl    4202508, %eax
+// CHECK-NEXT: 401046:       e8 e5 ff ff ff  calll   -27 <.plt+0x20>
+// CHECK-NEXT: 40104b:       e9 d1 ff ff ff  jmp     -47 <.plt+0x11>
+// CHECK-NEXT: 401050:       68 00 00 00 00  pushl   $0
+// CHECK-NEXT: 401055:       e9 b6 ff ff ff  jmp     -74 <.plt>
+// CHECK-NEXT: 40105a:       cc      int3
+// CHECK-NEXT: 40105b:       cc      int3
+// CHECK-NEXT: 40105c:       cc      int3
+// CHECK-NEXT: 40105d:       cc      int3
+// CHECK-NEXT: 40105e:       cc      int3
+// CHECK-NEXT: 40105f:       cc      int3
+// CHECK-NEXT: 401060:       50      pushl   %eax
+// CHECK-NEXT: 401061:       a1 10 20 40 00  movl    4202512, %eax
+// CHECK-NEXT: 401066:       e8 c5 ff ff ff  calll   -59 <.plt+0x20>
+// CHECK-NEXT: 40106b:       e9 b1 ff ff ff  jmp     -79 <.plt+0x11>
+// CHECK-NEXT: 401070:       68 08 00 00 00  pushl   $8
+// CHECK-NEXT: 401075:       e9 96 ff ff ff  jmp     -106 <.plt>
+// CHECK-NEXT: 40107a:       cc      int3
+// CHECK-NEXT: 40107b:       cc      int3
+// CHECK-NEXT: 40107c:       cc      int3
+// CHECK-NEXT: 40107d:       cc      int3
+// CHECK-NEXT: 40107e:       cc      int3
+// CHECK-NEXT: 40107f:       cc      int3
 
 // CHECK:      Contents of section .got.plt:
-// CHECK-NEXT: 00300100 00000000 00000000 50100100
-// CHECK-NEXT: 70100100
+// CHECK-NEXT: 00304000 00000000 00000000 50104000
+// CHECK-NEXT: 70104000
 
 .global _start
 _start:
diff --git a/test/ELF/invalid/Inputs/shentsize-zero.elf b/test/ELF/invalid/Inputs/shentsize-zero.elf
deleted file mode 100644
index 5fa7df2..0000000
--- a/test/ELF/invalid/Inputs/shentsize-zero.elf
+++ /dev/null
Binary files differ
diff --git a/test/ELF/invalid/Inputs/sht-group.elf b/test/ELF/invalid/Inputs/sht-group.elf
deleted file mode 100644
index 5cb0336..0000000
--- a/test/ELF/invalid/Inputs/sht-group.elf
+++ /dev/null
Binary files differ
diff --git a/test/ELF/invalid/Inputs/undefined-local-symbol-in-dso.so b/test/ELF/invalid/Inputs/undefined-local-symbol-in-dso.so
new file mode 100755
index 0000000..b884273
--- /dev/null
+++ b/test/ELF/invalid/Inputs/undefined-local-symbol-in-dso.so
Binary files differ
diff --git a/test/ELF/invalid/comdat-broken.test b/test/ELF/invalid/comdat-broken.test
new file mode 100644
index 0000000..9ff8eca
--- /dev/null
+++ b/test/ELF/invalid/comdat-broken.test
@@ -0,0 +1,25 @@
+# REQUIRES: x86
+
+# RUN: yaml2obj %s -o %t.o
+# RUN: not ld.lld %t.o -o %t.exe 2>&1 | FileCheck %s
+# RUN: not ld.lld %t.o %t.o -o %t.exe 2>&1 | FileCheck %s
+
+# CHECK: error: {{.*}}.o: unsupported SHT_GROUP format
+
+--- !ELF
+FileHeader:
+  Class:               ELFCLASS64
+  Data:                ELFDATA2LSB
+  Type:                ET_REL
+  Machine:             EM_X86_64
+Sections:
+  - Name:              .group
+    Type:              SHT_GROUP
+    Link:              .symtab
+    Info:              foo
+    Members:
+      - SectionOrType: 0xFF
+      - SectionOrType: 3
+Symbols:
+  Global:
+    - Name:            foo
diff --git a/test/ELF/invalid/ehframe-broken-relocation.test b/test/ELF/invalid/ehframe-broken-relocation.test
new file mode 100644
index 0000000..1333a6d
--- /dev/null
+++ b/test/ELF/invalid/ehframe-broken-relocation.test
@@ -0,0 +1,31 @@
+# RUN: yaml2obj %s -o %t.o
+# RUN: not ld.lld --icf=all %t.o -o /dev/null 2>&1 | FileCheck %s
+# CHECK: .eh_frame: relocation is not in any piece
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  OSABI:           ELFOSABI_FREEBSD
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .eh_frame
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC]
+    Content:         "1400000000000000017a5200017810011b0c070890010000140000001c00000000000000000000000000000000000000"
+  - Name:            .rela.eh_frame
+    Type:            SHT_RELA
+    Link:            .symtab
+    Info:            .eh_frame
+    Relocations:
+      - Offset:          0x99999999
+        Symbol:          zed
+        Type:            R_X86_64_64
+Symbols:
+  Global:
+    - Name:     zed
+      Type:     STT_FUNC
+      Section:  .eh_frame
+      Value:    0x0
+      Size:     8
diff --git a/test/ELF/invalid/invalid-soname.test b/test/ELF/invalid/invalid-soname.test
new file mode 100644
index 0000000..8641465
--- /dev/null
+++ b/test/ELF/invalid/invalid-soname.test
@@ -0,0 +1,18 @@
+# REQUIRES: x86
+# RUN: yaml2obj %s -o %t.so
+# RUN: not ld.lld %t.so -o %t.exe 2>&1 | FileCheck %s
+
+# CHECK: error: {{.*}}.so: invalid DT_SONAME entry
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_DYN
+  Machine:         EM_X86_64
+Sections:
+  - Name:          .test
+    Type:          SHT_DYNAMIC
+    Flags:         [ SHF_ALLOC ]
+    Content:         "0e000000000000000000000000000001"
+    Link:          .strtab
diff --git a/test/ELF/invalid/linkorder-invalid-sec.test b/test/ELF/invalid/linkorder-invalid-sec.test
new file mode 100644
index 0000000..d4aa376
--- /dev/null
+++ b/test/ELF/invalid/linkorder-invalid-sec.test
@@ -0,0 +1,16 @@
+# REQUIRES: x86
+# RUN: yaml2obj %s -o %t.o
+# RUN: not ld.lld %t.o -o %t.exe 2>&1 | FileCheck %s
+# CHECK: invalid sh_link index: 12345
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:          .linkorder
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR, SHF_LINK_ORDER ]
+    Link:          12345
diff --git a/test/ELF/invalid/linkorder-invalid-sec2.test b/test/ELF/invalid/linkorder-invalid-sec2.test
new file mode 100644
index 0000000..f78df3f
--- /dev/null
+++ b/test/ELF/invalid/linkorder-invalid-sec2.test
@@ -0,0 +1,16 @@
+# REQUIRES: x86
+# RUN: yaml2obj %s -o %t.o
+# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s
+# CHECK: invalid sh_link index: 0
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:          .linkorder
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR, SHF_LINK_ORDER ]
+    Link:          0
diff --git a/test/ELF/invalid/merge-invalid-size.s b/test/ELF/invalid/merge-invalid-size.s
index cc2566d..b16889a 100644
--- a/test/ELF/invalid/merge-invalid-size.s
+++ b/test/ELF/invalid/merge-invalid-size.s
@@ -3,8 +3,5 @@
 // RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s
 // CHECK: SHF_MERGE section size must be a multiple of sh_entsize
 
-// Test that we accept a zero sh_entsize.
-// RUN: ld.lld %p/Inputs/shentsize-zero.elf -o /dev/null
-
 .section .foo,"aM",@progbits,4
 .short 42
diff --git a/test/ELF/invalid/merge-zero-size.test b/test/ELF/invalid/merge-zero-size.test
new file mode 100644
index 0000000..564ed44
--- /dev/null
+++ b/test/ELF/invalid/merge-zero-size.test
@@ -0,0 +1,21 @@
+# REQUIRES: x86
+
+# RUN: yaml2obj %s -o %t.o
+
+# Test that we accept a zero sh_entsize for SHF_MERGE section.
+# RUN: ld.lld %t.o -o %t.exe
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  OSABI:           ELFOSABI_FREEBSD
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Type:            SHT_PROGBITS
+    Name:            .strings
+    Flags:           [ SHF_ALLOC, SHF_MERGE, SHF_STRINGS ]
+    AddressAlign:    0x04
+    Content:         "FFFFFFFFFFFFFFFF"
+    EntSize:         0x0
diff --git a/test/ELF/invalid/sht-group-wrong-section.test b/test/ELF/invalid/sht-group-wrong-section.test
new file mode 100644
index 0000000..d431dcb
--- /dev/null
+++ b/test/ELF/invalid/sht-group-wrong-section.test
@@ -0,0 +1,22 @@
+# REQUIRES: x86
+# RUN: yaml2obj %s -o %t.o
+# RUN: not ld.lld %t.o %t.o -o %t.exe 2>&1 | FileCheck %s
+# CHECK: error: {{.*}}.o: invalid section index in group: 12345
+
+--- !ELF
+FileHeader:
+  Class:               ELFCLASS64
+  Data:                ELFDATA2LSB
+  Type:                ET_REL
+  Machine:             EM_X86_64
+Sections:
+  - Name:              .group
+    Type:              SHT_GROUP
+    Link:              .symtab
+    Info:              foo
+    Members:
+      - SectionOrType: GRP_COMDAT
+      - SectionOrType: 12345
+Symbols:
+  Global:
+    - Name:            foo
diff --git a/test/ELF/invalid/sht-group.s b/test/ELF/invalid/sht-group.s
deleted file mode 100644
index a4b684c..0000000
--- a/test/ELF/invalid/sht-group.s
+++ /dev/null
@@ -1,3 +0,0 @@
-## sht-group.elf contains SHT_GROUP section with invalid sh_info.
-# RUN: not ld.lld %p/Inputs/sht-group.elf -o /dev/null 2>&1 | FileCheck %s
-# CHECK: invalid symbol index
diff --git a/test/ELF/invalid/sht-group.test b/test/ELF/invalid/sht-group.test
new file mode 100644
index 0000000..c91e649
--- /dev/null
+++ b/test/ELF/invalid/sht-group.test
@@ -0,0 +1,18 @@
+# REQUIRES: x86
+# RUN: yaml2obj %s -o %t.o
+# RUN: not ld.lld %t.o -o %t.exe 2>&1 | FileCheck %s
+# CHECK: invalid symbol index
+
+--- !ELF
+FileHeader:
+  Class:               ELFCLASS64
+  Data:                ELFDATA2LSB
+  Type:                ET_REL
+  Machine:             EM_X86_64
+Sections:
+  - Name:              .group
+    Type:              SHT_GROUP
+    Link:              .symtab
+    Info:              12345
+    Members:
+      - SectionOrType: GRP_COMDAT
diff --git a/test/ELF/invalid/undefined-local-symbol-in-dso.test b/test/ELF/invalid/undefined-local-symbol-in-dso.test
new file mode 100644
index 0000000..a9c30f3
--- /dev/null
+++ b/test/ELF/invalid/undefined-local-symbol-in-dso.test
@@ -0,0 +1,66 @@
+# REQUIRES: x86
+
+# LLD used to crash when linking against a DSO with an undefined STB_LOCAL
+# symbol in the global part of the dynamic symbol table (i.e. an STB_LOCAL
+# symbol with an index >= the sh_info of the dynamic symbol table section). Such
+# a DSO is very broken, because local symbols should precede all global symbols
+# in the symbol table, and because having a symbol that's both undefined and
+# STB_LOCAL is a nonsensical combination. Nevertheless, we should warn on such
+# input files instead of crashing.
+
+# We've found actual broken DSOs of this sort in the wild, but for this test, we
+# created a reduced broken input file. There are no tools capable of producing a
+# broken DSO of this nature, so instead we created a valid DSO with an undefined
+# global symbol in the dynamic symbol table and then manually edited the binary
+# to make that symbol local. The valid DSO was created as follows:
+
+```
+% cat undef.s
+.hidden bar
+bar:
+	movq	foo@GOT, %rax
+
+% llvm-mc -triple=x86_64-linux-gnu -filetype=obj -o undef.o undef.s
+% ld.lld --no-rosegment -shared -o undefined-local-symbol-in-dso.so undef.o
+% strip undef.so
+```
+
+# (--no-rosegment and stripping are unnecessary; they just produce a smaller
+# binary)
+
+# This DSO should only have a single dynamic symbol table entry for foo, and
+# then we can use a small C program to modify that symbol table entry to be
+# STB_LOCAL instead of STB_GLOBAL.
+
+```
+#include <elf.h>
+#include <stdio.h>
+
+int main(int argc, char *argv[]) {
+  FILE *F = fopen(argv[1], "rb+");
+
+  Elf64_Ehdr Ehdr;
+  fread(&Ehdr, sizeof(Ehdr), 1, F);
+  fseek(F, Ehdr.e_shoff, SEEK_SET);
+
+  Elf64_Shdr Shdr;
+  do {
+    fread(&Shdr, sizeof(Shdr), 1, F);
+  } while (Shdr.sh_type != SHT_DYNSYM);
+
+  Elf64_Sym Sym;
+  fseek(F, Shdr.sh_offset + sizeof(Elf64_Sym), SEEK_SET);
+  fread(&Sym, sizeof(Sym), 1, F);
+  Sym.st_info = STB_LOCAL << 4 | ELF64_ST_TYPE(Sym.st_info);
+  fseek(F, Shdr.sh_offset + sizeof(Elf64_Sym), SEEK_SET);
+  fwrite(&Sym, sizeof(Sym), 1, F);
+  fclose(F);
+}
+```
+
+# (the C program just takes its input DSO and modifies the binding of the first
+# dynamic symbol table entry to be STB_LOCAL instead of STB_GLOBAL)
+
+# RUN: ld.lld %p/Inputs/undefined-local-symbol-in-dso.so -o %t 2>&1 | \
+# RUN:   FileCheck -check-prefix=WARN %s
+# WARN: found local symbol 'foo' in global part of symbol table in file {{.*}}undefined-local-symbol-in-dso.so
diff --git a/test/ELF/lazy-arch-conflict.s b/test/ELF/lazy-arch-conflict.s
new file mode 100644
index 0000000..e17c301
--- /dev/null
+++ b/test/ELF/lazy-arch-conflict.s
@@ -0,0 +1,7 @@
+# REQUIRES: x86
+
+# RUN: echo '.globl foo; .weak foo; .quad foo;' | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t64.o
+# RUN: echo '.globl foo; foo:' | llvm-mc -filetype=obj -triple=i686-pc-linux - -o %t32.o
+# RUN: not ld.lld %t64.o --start-lib %t32.o --end-lib -o /dev/null 2>&1 | FileCheck %s
+
+# CHECK: error: incompatible file: {{.*}}32.o
diff --git a/test/ELF/linkerscript/icf.s b/test/ELF/linkerscript/icf.s
new file mode 100644
index 0000000..7c74458
--- /dev/null
+++ b/test/ELF/linkerscript/icf.s
@@ -0,0 +1,11 @@
+# REQUIRES: x86
+
+# RUN: echo "foo = 1; bar = 2;" > %t.script
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o %t.script -o %t --icf=all --print-icf-sections | count 0
+
+.section .text.foo,"ax",@progbits
+jmp foo
+
+.section .text.bar,"ax",@progbits
+jmp bar
diff --git a/test/ELF/linkerscript/info-section-type.s b/test/ELF/linkerscript/info-section-type.s
index b718e82..16e663f 100644
--- a/test/ELF/linkerscript/info-section-type.s
+++ b/test/ELF/linkerscript/info-section-type.s
@@ -29,5 +29,14 @@
 # RUN: ld.lld -o %t --script %t.script %t.o
 # RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=NONALLOC
 
+# RUN: echo "SECTIONS { .bar 0x20000 (INFO) : { *(.foo) } };" > %t.script
+# RUN: ld.lld -o %t --script %t.script %t.o
+# RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=NONALLOC
+
+# RUN: echo "SECTIONS { .bar 0x20000 (BAR) : { *(.foo) } };" > %t.script
+# RUN: not ld.lld -o %t --script %t.script %t.o 2>&1 |\
+# RUN:   FileCheck %s --check-prefix=UNKNOWN
+# UNKNOWN: unknown section directive: BAR
+
 .section .foo,"a",@progbits
 .zero 1
diff --git a/test/ELF/local-ver-preemptible.s b/test/ELF/local-ver-preemptible.s
new file mode 100644
index 0000000..b99f700
--- /dev/null
+++ b/test/ELF/local-ver-preemptible.s
@@ -0,0 +1,22 @@
+# REQUIRES: x86
+# RUN: echo '.global foo; .type foo, @function; foo:' | \
+# RUN:   llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.so.o
+# RUN: ld.lld %t.so.o -o %t.so -shared
+
+# RUN: echo "{ global: main; local: *; };" > %t.script
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o %t.so -o %t -version-script %t.script
+# RUN: llvm-readelf -r --symbols %t | FileCheck %s
+
+# CHECK:      Relocation section '.rela.plt' at offset {{.*}} contains 1 entries:
+# CHECK:        R_X86_64_JUMP_SLOT 0000000000201020 foo + 0
+
+# CHECK:      Symbol table '.dynsym' contains 2 entries:
+# CHECK-NEXT:   Num:    Value          Size Type    Bind   Vis      Ndx Name
+# CHECK-NEXT:     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND @
+# CHECK-NEXT:     1: 0000000000201020     0 FUNC    GLOBAL DEFAULT  UND foo@
+
+.globl _start
+_start:
+  movl $foo - ., %eax
diff --git a/test/ELF/lto-plugin-ignore.s b/test/ELF/lto-plugin-ignore.s
index 65230f1..0370d45 100644
--- a/test/ELF/lto-plugin-ignore.s
+++ b/test/ELF/lto-plugin-ignore.s
@@ -6,5 +6,5 @@
 # RUN:   -plugin-opt=-data-sections -plugin-opt=thinlto -o /dev/null
 
 # RUN: not ld.lld %t -plugin-opt=-abc -plugin-opt=-xyz 2>&1 | FileCheck %s
-# CHECK: error: --plugin-opt: ld.lld{{.*}}: Unknown command line argument '-abc'
-# CHECK: error: --plugin-opt: ld.lld{{.*}}: Unknown command line argument '-xyz'
+# CHECK: ld.lld: error: --plugin-opt: ld.lld{{.*}}: Unknown command line argument '-abc'
+# CHECK: ld.lld: error: --plugin-opt: ld.lld{{.*}}: Unknown command line argument '-xyz'
diff --git a/test/ELF/lto/amdgcn.ll b/test/ELF/lto/amdgcn.ll
new file mode 100644
index 0000000..4281e20
--- /dev/null
+++ b/test/ELF/lto/amdgcn.ll
@@ -0,0 +1,12 @@
+; REQUIRES: amdgpu
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld %t.o -o %t
+
+; Make sure the amdgcn triple is handled
+
+target triple = "amdgcn-amd-amdhsa"
+target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
+
+define void @_start() {
+  ret void
+}
diff --git a/test/ELF/lto/cache.ll b/test/ELF/lto/cache.ll
index 5ab74f5..86fcf81 100644
--- a/test/ELF/lto/cache.ll
+++ b/test/ELF/lto/cache.ll
@@ -31,6 +31,20 @@
 ; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy prune_after=0s:cache_size=0%:cache_size_files=1:prune_interval=0s -o %t3 %t2.o %t.o
 ; RUN: ls %t.cache | count 3
 
+; Check that we remove the least recently used file first.
+; RUN: rm -fr %t.cache
+; RUN: mkdir %t.cache
+; RUN: echo xyz > %t.cache/llvmcache-old
+; RUN: touch -t 198002011200 %t.cache/llvmcache-old
+; RUN: echo xyz > %t.cache/llvmcache-newer
+; RUN: touch -t 198002021200 %t.cache/llvmcache-newer
+; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy prune_after=0s:cache_size=0%:cache_size_files=3:prune_interval=0s -o %t3 %t2.o %t.o
+; RUN: ls %t.cache | FileCheck %s
+
+; CHECK-NOT: llvmcache-old
+; CHECK: llvmcache-newer
+; CHECK-NOT: llvmcache-old
+
 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/ppc64le.ll b/test/ELF/lto/ppc64le.ll
new file mode 100644
index 0000000..917b472
--- /dev/null
+++ b/test/ELF/lto/ppc64le.ll
@@ -0,0 +1,12 @@
+; REQUIRES: ppc
+
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld %t.o -o %t
+
+target datalayout = "e-m:e-i64:64-n32:64"
+target triple = "powerpc64le-unknown-linux-gnu"
+
+define void @__start() {
+  entry:
+    ret void
+}
diff --git a/test/ELF/lto/r600.ll b/test/ELF/lto/r600.ll
new file mode 100644
index 0000000..1c95edc
--- /dev/null
+++ b/test/ELF/lto/r600.ll
@@ -0,0 +1,12 @@
+; REQUIRES: amdgpu
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld %t.o -o %t
+
+; Make sure the r600 triple is handled
+
+target triple = "r600-mesa-mesa3d"
+target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
+
+define void @_start() {
+  ret void
+}
diff --git a/test/ELF/lto/thinlto-obj-path.ll b/test/ELF/lto/thinlto-obj-path.ll
index bb69bb8..2806d16 100644
--- a/test/ELF/lto/thinlto-obj-path.ll
+++ b/test/ELF/lto/thinlto-obj-path.ll
@@ -7,7 +7,8 @@
 ; 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
+; RUN: llvm-nm %t4.o 2>&1 | FileCheck %s -check-prefix=NO-SYMBOLS
+; NO-SYMBOLS: no symbols
 
 ; CHECK: Format: ELF64-x86-64
 
diff --git a/test/ELF/lto/thinlto-object-suffix-replace.ll b/test/ELF/lto/thinlto-object-suffix-replace.ll
index 05ce942..c58a1f2 100644
--- a/test/ELF/lto/thinlto-object-suffix-replace.ll
+++ b/test/ELF/lto/thinlto-object-suffix-replace.ll
@@ -29,12 +29,12 @@
 ; 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
+; If filename does not end with old suffix, no suffix change should occur,
+; so ".thinlto.bc" will simply be appended to the input file name.
+; RUN: rm -f %t1.thinlink.bc.thinlto.bc
+; RUN: ld.lld --plugin-opt=thinlto-index-only \
+; RUN: --plugin-opt=thinlto-object-suffix-replace=".abc;.o" -shared %t1.thinlink.bc -o /dev/null
+; RUN: ls %t1.thinlink.bc.thinlto.bc
 
 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/wrap-2.ll b/test/ELF/lto/wrap-2.ll
index 4e82d4a..997725f 100644
--- a/test/ELF/lto/wrap-2.ll
+++ b/test/ELF/lto/wrap-2.ll
@@ -28,11 +28,15 @@
 ; THIN-NEXT: jmp{{.*}}<bar>
 
 ; Check that bar and __wrap_bar retain their original binding.
-; BIND:      Name: __wrap_bar
+; BIND:      Name: bar
 ; BIND-NEXT: Value:
 ; BIND-NEXT: Size:
 ; BIND-NEXT: Binding: Local
-; BIND:      Name: bar
+; BIND:      Name: __real_bar
+; BIND-NEXT: Value:
+; BIND-NEXT: Size:
+; BIND-NEXT: Binding: Local
+; BIND:      Name: __wrap_bar
 ; BIND-NEXT: Value:
 ; BIND-NEXT: Size:
 ; BIND-NEXT: Binding: Local
diff --git a/test/ELF/map-file-i686.s b/test/ELF/map-file-i686.s
index bab2c4b..5c8b154 100644
--- a/test/ELF/map-file-i686.s
+++ b/test/ELF/map-file-i686.s
@@ -7,15 +7,15 @@
 _start:
  nop
 
-// CHECK:        VMA      LMA     Size Align Out     In      Symbol
-// CHECK-NEXT: 11000    11000        1     4 .text
-// CHECK-NEXT: 11000    11000        1     4         {{.*}}{{/|\\}}map-file-i686.s.tmp1.o:(.text)
-// CHECK-NEXT: 11000    11000        0     1                 _start
-// CHECK-NEXT:     0        0        8     1 .comment
-// CHECK-NEXT:     0        0        8     1         <internal>:(.comment)
-// CHECK-NEXT:     0        0       20     4 .symtab
-// CHECK-NEXT:     0        0       20     4         <internal>:(.symtab)
-// CHECK-NEXT:     0        0       2a     1 .shstrtab
-// CHECK-NEXT:     0        0       2a     1         <internal>:(.shstrtab)
-// CHECK-NEXT:     0        0        8     1 .strtab
-// CHECK-NEXT:     0        0        8     1         <internal>:(.strtab)
+// CHECK:         VMA      LMA     Size Align Out     In      Symbol
+// CHECK-NEXT: 401000   401000        1     4 .text
+// CHECK-NEXT: 401000   401000        1     4         {{.*}}{{/|\\}}map-file-i686.s.tmp1.o:(.text)
+// CHECK-NEXT: 401000   401000        0     1                 _start
+// CHECK-NEXT:      0        0        8     1 .comment
+// CHECK-NEXT:      0        0        8     1         <internal>:(.comment)
+// CHECK-NEXT:      0        0       20     4 .symtab
+// CHECK-NEXT:      0        0       20     4         <internal>:(.symtab)
+// CHECK-NEXT:      0        0       2a     1 .shstrtab
+// CHECK-NEXT:      0        0       2a     1         <internal>:(.shstrtab)
+// CHECK-NEXT:      0        0        8     1 .strtab
+// CHECK-NEXT:      0        0        8     1         <internal>:(.strtab)
diff --git a/test/ELF/merge-string-error.s b/test/ELF/merge-string-error.s
index 70a361b..a0ffaaf 100644
--- a/test/ELF/merge-string-error.s
+++ b/test/ELF/merge-string-error.s
@@ -8,4 +8,4 @@
         .data
         .long .rodata.str1.1 + 4
 
-// CHECK: merge-string-error.s.tmp.o:(.rodata.str1.1): entry is past the end of the section
+// CHECK: merge-string-error.s.tmp.o:(.rodata.str1.1): offset is outside the section
diff --git a/test/ELF/pack-dyn-relocs-tls-aarch64.s b/test/ELF/pack-dyn-relocs-tls-aarch64.s
new file mode 100644
index 0000000..978e2e7
--- /dev/null
+++ b/test/ELF/pack-dyn-relocs-tls-aarch64.s
@@ -0,0 +1,34 @@
+// REQUIRES: aarch64
+
+// RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %t.o
+// RUN: ld.lld -shared --pack-dyn-relocs=android %t.o -o %t.so
+// RUN: llvm-readobj -relocations %t.so | FileCheck %s
+
+// Bug 37841: Symbol::getVA must work on TLS symbols during the layout loop in
+// finalizeSections.
+
+    .global foo
+foo:
+    adrp    x0, :tlsdesc:tlsvar1
+    ldr     x1, [x0, :tlsdesc_lo12:tlsvar1]
+    add     x0, x0, :tlsdesc_lo12:tlsvar1
+    .tlsdesccall tlsvar1
+
+// Also test an atypical IE access from a shared object to a local TLS symbol.
+
+    .global bar
+bar:
+    adrp    x0, :gottprel:tlsvar2
+    ldr     x0, [x0, #:gottprel_lo12:tlsvar2]
+
+    .section    .tdata,"awT",@progbits
+    .space  0x1234
+tlsvar1:
+    .word   42
+tlsvar2:
+    .word   17
+
+// CHECK:          Section ({{.+}}) .rela.dyn {
+// CHECK-NEXT:     R_AARCH64_TLSDESC - 0x1234
+// CHECK-NEXT:     R_AARCH64_TLS_TPREL64 - 0x1238
+// CHECK-NEXT:     }
diff --git a/test/ELF/pack-dyn-relocs-tls-x86-64.s b/test/ELF/pack-dyn-relocs-tls-x86-64.s
new file mode 100644
index 0000000..491efa6
--- /dev/null
+++ b/test/ELF/pack-dyn-relocs-tls-x86-64.s
@@ -0,0 +1,23 @@
+// REQUIRES: x86
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld -shared --pack-dyn-relocs=android %t.o -o %t.so
+// RUN: llvm-readobj -relocations %t.so | FileCheck %s
+
+// Bug 37841: Symbol::getVA must work on TLS symbols during the layout loop in
+// finalizeSections. This test uses an atypical IE access in a shared object to
+// access a local TLS symbol, because a more typical access would avoid the
+// bug.
+
+    .globl  foo
+foo:
+    movq    tlsvar@GOTTPOFF(%rip), %rcx
+
+    .section    .tdata,"awT",@progbits
+    .space 0x1234
+tlsvar:
+    .word   42
+
+// CHECK:          Section ({{.+}}) .rela.dyn {
+// CHECK-NEXT:     R_X86_64_TPOFF64 - 0x1234
+// CHECK-NEXT:     }
diff --git a/test/ELF/plt-aarch64.s b/test/ELF/plt-aarch64.s
index 8f637bf..f9c53a4 100644
--- a/test/ELF/plt-aarch64.s
+++ b/test/ELF/plt-aarch64.s
@@ -85,6 +85,8 @@
 
 // foo@plt
 // Page(0x30018) - Page(0x10030) = 0x20000 - 0x10000 = 0x10000 = 65536
+// DISASMDSO-EMPTY:
+// DISASMDSO-NEXT:   foo@plt:
 // DISASMDSO-NEXT:     10030:	90 00 00 90 	adrp	x16, #65536
 // 0x3018 & 0xFFF = 0x18 = 24
 // DISASMDSO-NEXT:     10034:	11 0e 40 f9 	ldr	x17, [x16, #24]
@@ -93,6 +95,8 @@
 
 // bar@plt
 // Page(0x30020) - Page(0x10040) = 0x20000 - 0x10000 = 0x10000 = 65536
+// DISASMDSO-EMPTY:
+// DISASMDSO-NEXT:   bar@plt:
 // DISASMDSO-NEXT:     10040:	90 00 00 90 	adrp	x16, #65536
 // 0x3020 & 0xFFF = 0x20 = 32
 // DISASMDSO-NEXT:     10044:	11 12 40 f9 	ldr	x17, [x16, #32]
@@ -101,6 +105,8 @@
 
 // weak@plt
 // Page(0x30028) - Page(0x10050) = 0x20000 - 0x10000 = 0x10000 = 65536
+// DISASMDSO-EMPTY:
+// DISASMDSO-NEXT:   weak@plt:
 // DISASMDSO-NEXT:     10050:	90 00 00 90 	adrp	x16, #65536
 // 0x3028 & 0xFFF = 0x28 = 40
 // DISASMDSO-NEXT:     10054:	11 16 40 f9 	ldr	x17, [x16, #40]
@@ -113,7 +119,7 @@
 // CHECKEXE-NEXT:       SHF_ALLOC
 // CHECKEXE-NEXT:       SHF_EXECINSTR
 // CHECKEXE-NEXT:     ]
-// CHECKEXE-NEXT:     Address: 0x20010
+// CHECKEXE-NEXT:     Address: 0x210010
 // CHECKEXE-NEXT:     Offset:
 // CHECKEXE-NEXT:     Size: 64
 // CHECKEXE-NEXT:     Link:
@@ -126,7 +132,7 @@
 // CHECKEXE-NEXT:       SHF_ALLOC
 // CHECKEXE-NEXT:       SHF_WRITE
 // CHECKEXE-NEXT:     ]
-// CHECKEXE-NEXT:     Address: 0x30000
+// CHECKEXE-NEXT:     Address: 0x220000
 // CHECKEXE-NEXT:     Offset:
 // CHECKEXE-NEXT:     Size: 40
 // CHECKEXE-NEXT:     Link:
@@ -136,59 +142,63 @@
 // CHECKEXE: Relocations [
 // CHECKEXE-NEXT:   Section ({{.*}}) .rela.plt {
 
-// &(.got.plt[3]) = 0x30000 + 3 * 8 = 0x30018
-// CHECKEXE-NEXT:     0x30018 R_AARCH64_JUMP_SLOT bar 0x0
+// &(.got.plt[3]) = 0x220000 + 3 * 8 = 0x220018
+// CHECKEXE-NEXT:     0x220018 R_AARCH64_JUMP_SLOT bar 0x0
 
-// &(.got.plt[4]) = 0x30000 + 4 * 8 = 0x30020
-// CHECKEXE-NEXT:     0x30020 R_AARCH64_JUMP_SLOT weak 0x0
+// &(.got.plt[4]) = 0x220000 + 4 * 8 = 0x220020
+// CHECKEXE-NEXT:     0x220020 R_AARCH64_JUMP_SLOT weak 0x0
 // CHECKEXE-NEXT:   }
 // CHECKEXE-NEXT: ]
 
 // DUMPEXE: Contents of section .got.plt:
 // .got.plt[0..2] = 0 (reserved)
 // .got.plt[3..4] = .plt = 0x40010
-// DUMPEXE-NEXT:  30000 00000000 00000000 00000000 00000000  ................
-// DUMPEXE-NEXT:  30010 00000000 00000000 10000200 00000000  ................
-// DUMPEXE-NEXT:  30020 10000200 00000000                    ........
+// DUMPEXE-NEXT:  220000 00000000 00000000 00000000 00000000
+// DUMPEXE-NEXT:  220010 00000000 00000000 10002100 00000000
+// DUMPEXE-NEXT:  220020 10002100 00000000
 
 // DISASMEXE: _start:
-// 0x2000c - 0x20000 = 0xc = 12
-// DISASMEXE-NEXT:    20000:	03 00 00 14 	b	#12
-// 0x20030 - 0x20004 = 0x2c = 44
-// DISASMEXE-NEXT:    20004:	0b 00 00 14 	b	#44
-// 0x20040 - 0x20008 = 0x38 = 56
-// DISASMEXE-NEXT:    20008:	0e 00 00 14 	b	#56
+// 0x21000c - 0x210000 = 0xc = 12
+// DISASMEXE-NEXT:    210000:	03 00 00 14 	b	#12
+// 0x210030 - 0x210004 = 0x2c = 44
+// DISASMEXE-NEXT:    210004:	0b 00 00 14 	b	#44
+// 0x210040 - 0x210008 = 0x38 = 56
+// DISASMEXE-NEXT:    210008:	0e 00 00 14 	b	#56
 
 // DISASMEXE: foo:
-// DISASMEXE-NEXT:    2000c:	1f 20 03 d5 	nop
+// DISASMEXE-NEXT:    21000c:	1f 20 03 d5 	nop
 
 // DISASMEXE: Disassembly of section .plt:
 // DISASMEXE-NEXT: .plt:
-// DISASMEXE-NEXT:    20010:	f0 7b bf a9 	stp	x16, x30, [sp, #-16]!
-// &(.got.plt[2]) = 0x300B0 + 2 * 8 = 0x300C0
-// Page(0x30010) - Page(0x20014) = 0x30000 - 0x20000 = 0x10000 = 65536
-// DISASMEXE-NEXT:    20014:	90 00 00 90  	adrp	x16, #65536
+// DISASMEXE-NEXT:    210010:	f0 7b bf a9 	stp	x16, x30, [sp, #-16]!
+// &(.got.plt[2]) = 0x2200B0 + 2 * 8 = 0x2200C0
+// Page(0x220010) - Page(0x210014) = 0x220000 - 0x210000 = 0x10000 = 65536
+// DISASMEXE-NEXT:    210014:	90 00 00 90  	adrp	x16, #65536
 // 0x120c0 & 0xFFF = 0xC0 = 192
-// DISASMEXE-NEXT:    20018:	11 0a 40 f9 	ldr	x17, [x16, #16]
-// DISASMEXE-NEXT:    2001c:	10 42 00 91 	add	x16, x16, #16
-// DISASMEXE-NEXT:    20020:	20 02 1f d6 	br	x17
-// DISASMEXE-NEXT:    20024:	1f 20 03 d5 	nop
-// DISASMEXE-NEXT:    20028:	1f 20 03 d5 	nop
-// DISASMEXE-NEXT:    2002c:	1f 20 03 d5 	nop
+// DISASMEXE-NEXT:    210018:	11 0a 40 f9 	ldr	x17, [x16, #16]
+// DISASMEXE-NEXT:    21001c:	10 42 00 91 	add	x16, x16, #16
+// DISASMEXE-NEXT:    210020:	20 02 1f d6 	br	x17
+// DISASMEXE-NEXT:    210024:	1f 20 03 d5 	nop
+// DISASMEXE-NEXT:    210028:	1f 20 03 d5 	nop
+// DISASMEXE-NEXT:    21002c:	1f 20 03 d5 	nop
 
 // bar@plt
-// Page(0x40018) - Page(0x20030) = 0x30000 - 0x20000 = 0x10000 = 65536
-// DISASMEXE-NEXT:    20030:	90 00 00 90 	adrp	x16, #65536
-// DISASMEXE-NEXT:    20034:	11 0e 40 f9 	ldr	x17, [x16, #24]
-// DISASMEXE-NEXT:    20038:	10 62 00 91 	add	x16, x16, #24
-// DISASMEXE-NEXT:    2003c:	20 02 1f d6 	br	x17
+// Page(0x40018) - Page(0x210030) = 0x220000 - 0x210000 = 0x10000 = 65536
+// DISASMEXE-EMPTY:
+// DISASMEXE-NEXT:   bar@plt:
+// DISASMEXE-NEXT:    210030:	90 00 00 90 	adrp	x16, #65536
+// DISASMEXE-NEXT:    210034:	11 0e 40 f9 	ldr	x17, [x16, #24]
+// DISASMEXE-NEXT:    210038:	10 62 00 91 	add	x16, x16, #24
+// DISASMEXE-NEXT:    21003c:	20 02 1f d6 	br	x17
 
 // weak@plt
-// Page(0x40020) - Page(0x20040) = 0x30000 - 0x20000 = 0x10000 = 65536
-// DISASMEXE-NEXT:    20040:	90 00 00 90 	adrp	x16, #65536
-// DISASMEXE-NEXT:    20044:	11 12 40 f9 	ldr	x17, [x16, #32]
-// DISASMEXE-NEXT:    20048:	10 82 00 91 	add	x16, x16, #32
-// DISASMEXE-NEXT:    2004c:	20 02 1f d6 	br	x17
+// Page(0x40020) - Page(0x210040) = 0x220000 - 0x210000 = 0x10000 = 65536
+// DISASMEXE-EMPTY:
+// DISASMEXE-NEXT:   weak@plt:
+// DISASMEXE-NEXT:    210040:	90 00 00 90 	adrp	x16, #65536
+// DISASMEXE-NEXT:    210044:	11 12 40 f9 	ldr	x17, [x16, #32]
+// DISASMEXE-NEXT:    210048:	10 82 00 91 	add	x16, x16, #32
+// DISASMEXE-NEXT:    21004c:	20 02 1f d6 	br	x17
 
 .global _start,foo,bar
 .weak weak
diff --git a/test/ELF/plt-i686.s b/test/ELF/plt-i686.s
index c24cab2..8a58633 100644
--- a/test/ELF/plt-i686.s
+++ b/test/ELF/plt-i686.s
@@ -17,7 +17,7 @@
 // CHECK-NEXT:   SHF_ALLOC
 // CHECK-NEXT:   SHF_EXECINSTR
 // CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x11020
+// CHECK-NEXT: Address: 0x401020
 // CHECK-NEXT: Offset:
 // CHECK-NEXT: Size: 48
 // CHECK-NEXT: Link: 0
@@ -30,7 +30,7 @@
 // CHECK-NEXT:   SHF_ALLOC
 // CHECK-NEXT:   SHF_WRITE
 // CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x12000
+// CHECK-NEXT: Address: 0x402000
 // CHECK-NEXT: Offset: 0x2000
 // CHECK-NEXT: Size: 20
 // CHECK-NEXT: Link: 0
@@ -42,8 +42,8 @@
 // 0x12000 + got.plt.reserved(12) + 4 = 0x12010
 // CHECK:      Relocations [
 // CHECK-NEXT:   Section ({{.*}}) .rel.plt {
-// CHECK-NEXT:     0x1200C R_386_JUMP_SLOT bar 0x0
-// CHECK-NEXT:     0x12010 R_386_JUMP_SLOT zed 0x0
+// CHECK-NEXT:     0x40200C R_386_JUMP_SLOT bar 0x0
+// CHECK-NEXT:     0x402010 R_386_JUMP_SLOT zed 0x0
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]
 
@@ -51,40 +51,44 @@
 // values:
 
 // 16 is the size of PLT[0]
-// (0x11010 + 16) - (0x11000 + 1) - 4 = 27
-// (0x11010 + 16) - (0x11005 + 1) - 4 = 22
-// (0x11020 + 16) - (0x1100a + 1) - 4 = 33
+// (0x401010 + 16) - (0x401000 + 1) - 4 = 27
+// (0x401010 + 16) - (0x401005 + 1) - 4 = 22
+// (0x401020 + 16) - (0x40100a + 1) - 4 = 33
 
 // DISASM:       local:
-// DISASM-NEXT:  11000: {{.*}}
-// DISASM-NEXT:  11002: {{.*}}
+// DISASM-NEXT:  401000: {{.*}}
+// DISASM-NEXT:  401002: {{.*}}
 // DISASM:       _start:
-// 0x11013 + 5 - 24 = 0x11000
-// DISASM-NEXT: 11004: e9 27 00 00 00 jmp 39
-// DISASM-NEXT: 11009: e9 22 00 00 00 jmp 34
-// DISASM-NEXT: 1100e: e9 2d 00 00 00 jmp 45
-// DISASM-NEXT: 11013: e9 e8 ff ff ff jmp -24
+// 0x401013 + 5 - 24 = 0x401000
+// DISASM-NEXT: 401004: e9 27 00 00 00 jmp 39
+// DISASM-NEXT: 401009: e9 22 00 00 00 jmp 34
+// DISASM-NEXT: 40100e: e9 2d 00 00 00 jmp 45
+// DISASM-NEXT: 401013: e9 e8 ff ff ff jmp -24
 
-// 0x11010 - 0x1102b - 5 = -32
-// 0x11010 - 0x1103b - 5 = -48
-// 77828 = 0x13004 = .got.plt (0x13000) + 4
-// 77832 = 0x13008 = .got.plt (0x13000) + 8
-// 77836 = 0x1300C = .got.plt (0x13000) + got.plt.reserved(12)
-// 77840 = 0x13010 = .got.plt (0x13000) + got.plt.reserved(12) + 4
+// 0x401010 - 0x40102b - 5 = -32
+// 0x401010 - 0x40103b - 5 = -48
+// 4202500 = 0x402004 = .got.plt (0x402000) + 4
+// 4202504 = 0x402008 = .got.plt (0x402000) + 8
+// 4202508 = 0x40200C = .got.plt (0x402000) + got.plt.reserved(12)
+// 4202512 = 0x402010 = .got.plt (0x402000) + got.plt.reserved(12) + 4
 // DISASM:      Disassembly of section .plt:
 // DISASM-NEXT: .plt:
-// DISASM-NEXT:    11020: ff 35 04 20 01 00 pushl 73732
-// DISASM-NEXT:    11026: ff 25 08 20 01 00 jmpl *73736
-// DISASM-NEXT:    1102c: 90 nop
-// DISASM-NEXT:    1102d: 90 nop
-// DISASM-NEXT:    1102e: 90 nop
-// DISASM-NEXT:    1102f: 90 nop
-// DISASM-NEXT:    11030: ff 25 0c 20 01 00 jmpl *73740
-// DISASM-NEXT:    11036: 68 00 00 00 00 pushl $0
-// DISASM-NEXT:    1103b: e9 e0 ff ff ff jmp -32 <.plt>
-// DISASM-NEXT:    11040: ff 25 10 20 01 00 jmpl *73744
-// DISASM-NEXT:    11046: 68 08 00 00 00 pushl $8
-// DISASM-NEXT:    1104b: e9 d0 ff ff ff jmp -48 <.plt>
+// DISASM-NEXT:    401020: ff 35 04 20 40 00 pushl 4202500
+// DISASM-NEXT:    401026: ff 25 08 20 40 00 jmpl *4202504
+// DISASM-NEXT:    40102c: 90 nop
+// DISASM-NEXT:    40102d: 90 nop
+// DISASM-NEXT:    40102e: 90 nop
+// DISASM-NEXT:    40102f: 90 nop
+// DISASM-EMPTY:
+// DISASM-NEXT:   bar@plt:
+// DISASM-NEXT:    401030: ff 25 0c 20 40 00 jmpl *4202508
+// DISASM-NEXT:    401036: 68 00 00 00 00 pushl $0
+// DISASM-NEXT:    40103b: e9 e0 ff ff ff jmp -32 <.plt>
+// DISASM-EMPTY:
+// DISASM-NEXT:   zed@plt:
+// DISASM-NEXT:    401040: ff 25 10 20 40 00 jmpl *4202512
+// DISASM-NEXT:    401046: 68 08 00 00 00 pushl $8
+// DISASM-NEXT:    40104b: e9 d0 ff ff ff jmp -48 <.plt>
 
 // CHECKSHARED:        Name: .plt
 // CHECKSHARED-NEXT:   Type: SHT_PROGBITS
diff --git a/test/ELF/plt.s b/test/ELF/plt.s
index cce60d7..21f0f12 100644
--- a/test/ELF/plt.s
+++ b/test/ELF/plt.s
@@ -73,12 +73,18 @@
 // DISASM-NEXT:   1020:  ff 35 e2 0f 00 00  pushq 4066(%rip)
 // DISASM-NEXT:   1026:  ff 25 e4 0f 00 00  jmpq *4068(%rip)
 // DISASM-NEXT:   102c:  0f 1f 40 00        nopl (%rax)
+// DISASM-EMPTY:
+// DISASM-NEXT:   bar@plt:
 // DISASM-NEXT:   1030:  ff 25 e2 0f 00 00  jmpq *4066(%rip)
 // DISASM-NEXT:   1036:  68 00 00 00 00     pushq $0
 // DISASM-NEXT:   103b:  e9 e0 ff ff ff     jmp -32 <.plt>
+// DISASM-EMPTY:
+// DISASM-NEXT:   zed@plt:
 // DISASM-NEXT:   1040:  ff 25 da 0f 00 00  jmpq *4058(%rip)
 // DISASM-NEXT:   1046:  68 01 00 00 00     pushq $1
 // DISASM-NEXT:   104b:  e9 d0 ff ff ff     jmp -48 <.plt>
+// DISASM-EMPTY:
+// DISASM-NEXT:   _start@plt:
 // DISASM-NEXT:   1050:  ff 25 d2 0f 00 00  jmpq *4050(%rip)
 // DISASM-NEXT:   1056:  68 02 00 00 00     pushq $2
 // DISASM-NEXT:   105b:  e9 c0 ff ff ff     jmp -64 <.plt>
@@ -102,9 +108,13 @@
 // DISASM2-NEXT:  201020:  ff 35 e2 0f 00 00   pushq 4066(%rip)
 // DISASM2-NEXT:  201026:  ff 25 e4 0f 00 00   jmpq *4068(%rip)
 // DISASM2-NEXT:  20102c:  0f 1f 40 00         nopl  (%rax)
+// DISASM2-EMPTY:
+// DISASM2-NEXT:   bar@plt:
 // DISASM2-NEXT:  201030:  ff 25 e2 0f 00 00   jmpq *4066(%rip)
 // DISASM2-NEXT:  201036:  68 00 00 00 00      pushq $0
 // DISASM2-NEXT:  20103b:  e9 e0 ff ff ff      jmp -32 <.plt>
+// DISASM2-EMPTY:
+// DISASM2-NEXT:   zed@plt:
 // DISASM2-NEXT:  201040:  ff 25 da 0f 00 00   jmpq *4058(%rip)
 // DISASM2-NEXT:  201046:  68 01 00 00 00      pushq $1
 // DISASM2-NEXT:  20104b:  e9 d0 ff ff ff      jmp -48 <.plt>
diff --git a/test/ELF/ppc64-bsymbolic-toc-restore.s b/test/ELF/ppc64-bsymbolic-toc-restore.s
new file mode 100644
index 0000000..49d347c
--- /dev/null
+++ b/test/ELF/ppc64-bsymbolic-toc-restore.s
@@ -0,0 +1,68 @@
+# REQUIRES: ppc
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-bsymbolic-local-def.s  -o %t2.o
+# RUN: ld.lld -Bsymbolic -shared %t1.o %t2.o -o %t
+# RUN: llvm-objdump -d -r %t | FileCheck %s
+# RUN: not ld.lld -shared %t1.o %t2.o -o %t 2>&1 | FileCheck --check-prefix=FAIL %s
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-bsymbolic-local-def.s  -o %t2.o
+# RUN: ld.lld -Bsymbolic -shared %t1.o %t2.o -o %t
+# RUN: llvm-objdump -d -r %t | FileCheck %s
+# RUN: not ld.lld -shared %t1.o %t2.o -o %t 2>&1 | FileCheck --check-prefix=FAIL %s
+
+# FAIL: call lacks nop, can't restore toc
+
+# Test to document the toc-restore behavior with -Bsymbolic option. Since
+# -Bsymbolic causes the call to bind to the internal defintion we know the
+# caller and callee share the same TOC base. This means branching to the
+# local entry point of the callee, and no need for a nop to follow the call
+# (since there is no need to restore the TOC-pointer after the call).
+
+        .abiversion 2
+        .section ".text"
+
+        .p2align 2
+        .global caller
+        .type caller, @function
+caller:
+.Lcaller_gep:
+    addis 2, 12, .TOC.-.Lcaller_gep@ha
+    addi  2, 2, .TOC.-.Lcaller_gep@l
+.Lcaller_lep:
+    .localentry caller, .-caller
+    mflr 0
+    std 0, -16(1)
+    stdu 1, -32(1)
+    bl def
+    mr 31, 3
+    bl not_defined
+    nop
+    add 3, 3, 31
+    addi 1, 1, 32
+    ld 0, -16(1)
+    mtlr 0
+    blr
+
+# Note that the bl .+44 is a call to def's local entry, jumping past the first 2
+# instructions. Branching to the global entry would corrupt the TOC pointer
+# since the global entry requires that %r12 hold the address of the function
+# being called.
+
+# CHECK-LABEL: caller
+# CHECK:         bl .+44
+# CHECK-NEXT:    mr 31, 3
+# CHECK-NEXT:    bl .+67108816
+# CHECK-NEXT:    ld 2, 24(1)
+# CHECK-NEXT:    add 3, 3, 31
+# CHECK-NEXT:    addi 1, 1, 32
+# CHECK-NEXT:    ld 0, -16(1)
+# CHECK-NEXT:    mtlr 0
+# CHECK-NEXT:    blr
+# CHECK-EMPTY:
+# CHECK-NEXT:  def:
+# CHECK-NEXT:    addis 2, 12, 2
+# CHECK-NEXT:    addi 2, 2, -32636
+# CHECK-NEXT:    li 3, 55
+# CHECK-NEXT:    blr
diff --git a/test/ELF/ppc64-dq.s b/test/ELF/ppc64-dq.s
new file mode 100644
index 0000000..b29879d
--- /dev/null
+++ b/test/ELF/ppc64-dq.s
@@ -0,0 +1,32 @@
+# REQUIRES: ppc
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t
+# RUN: llvm-objdump -d %t | FileCheck %s
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t
+# RUN: llvm-objdump -d %t | FileCheck %s
+
+        .global test
+        .p2align        4
+        .type   test,@function
+test:
+.Lgep:
+        addis 2, 12, .TOC.-.Lgep@ha
+        addi  2, 2,  .TOC.-.Lgep@l
+.Llep:
+        .localentry test, .Llep-.Lgep
+        addis 3, 2, qword@toc@ha
+        lxv   3, qword@toc@l(3)
+        addis 3, 2, qword@toc@ha
+        stxv  3, qword@toc@l(3)
+        blr
+
+       .comm qword, 16, 16
+
+# Verify that we don't overwrite any of the extended opcode bits on a DQ form
+# instruction.
+# CHECK-LABEL: test
+# CHECK:         lxv 3, -32768(3)
+# CHECK:         stxv 3, -32768(3)
diff --git a/test/ELF/ppc64-dtprel.s b/test/ELF/ppc64-dtprel.s
index 43922fa..e5ac83a 100644
--- a/test/ELF/ppc64-dtprel.s
+++ b/test/ELF/ppc64-dtprel.s
@@ -2,15 +2,15 @@
 
 // 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-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s
 // RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s
 // RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=GotDisLE %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-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s
 // RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s
 // RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=GotDisBE %s
 
diff --git a/test/ELF/ppc64_entry_point.s b/test/ELF/ppc64-entry-point.s
similarity index 77%
rename from test/ELF/ppc64_entry_point.s
rename to test/ELF/ppc64-entry-point.s
index a6f426c..6dbfc53 100644
--- a/test/ELF/ppc64_entry_point.s
+++ b/test/ELF/ppc64-entry-point.s
@@ -3,9 +3,11 @@
 # 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-objdump -D %t2 | FileCheck -check-prefix=CHECK-LE %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
 # RUN: llvm-objdump -D %t2 | FileCheck -check-prefix=CHECK-BE %s
 
 .text
@@ -36,14 +38,11 @@
 // 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-LE: Disassembly of section .got:
+// CHECK-LE-NEXT: .got:
+// CHECK-LE-NEXT: 10020000:       00 80 02 10
+
 // CHECK-BE: Disassembly of section .got:
 // CHECK-BE-NEXT: .got:
 // CHECK-BE-NEXT: 10020000:       00 00 00 00 {{.*}}
diff --git a/test/ELF/ppc64-error-missaligned-dq.s b/test/ELF/ppc64-error-missaligned-dq.s
new file mode 100644
index 0000000..ea30ab8
--- /dev/null
+++ b/test/ELF/ppc64-error-missaligned-dq.s
@@ -0,0 +1,26 @@
+# REQUIRES: ppc
+#
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+# RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+# RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
+
+# CHECK: improper alignment for relocation R_PPC64_ADDR16_LO_DS: 0x8001 is not aligned to 16 bytes
+
+        .global test
+        .p2align        4
+        .type   test,@function
+test:
+.Lgep:
+        addis 2, 12, .TOC.-.Lgep@ha
+        addi  2, 2,  .TOC.-.Lgep@l
+.Llep:
+        .localentry test, .Llep-.Lgep
+        addis 3, 2, qword@toc@ha
+        lxv   3, qword@toc@l(3)
+        blr
+
+       .comm pad, 1, 1
+       .comm qword, 16, 1
+
diff --git a/test/ELF/ppc64-error-missaligned-ds.s b/test/ELF/ppc64-error-missaligned-ds.s
new file mode 100644
index 0000000..99a2c08
--- /dev/null
+++ b/test/ELF/ppc64-error-missaligned-ds.s
@@ -0,0 +1,26 @@
+# REQUIRES: ppc
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+# RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+# RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
+
+# CHECK: improper alignment for relocation R_PPC64_ADDR16_LO_DS: 0x8001 is not aligned to 4 bytes
+
+        .global test
+        .p2align        4
+        .type   test,@function
+test:
+.Lgep:
+        addis 2, 12, .TOC.-.Lgep@ha
+        addi  2, 2,  .TOC.-.Lgep@l
+.Llep:
+        .localentry test, .Llep-.Lgep
+        addis 3, 2, word@toc@ha
+        lwa   3, word@toc@l(3)
+        blr
+
+       .comm pad, 1, 1
+       .comm word, 4, 1
+
diff --git a/test/ELF/ppc64-func-entry-points.s b/test/ELF/ppc64-func-entry-points.s
index 640c94f..1f23e66 100644
--- a/test/ELF/ppc64-func-entry-points.s
+++ b/test/ELF/ppc64-func-entry-points.s
@@ -75,6 +75,6 @@
 // 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-NEXT: 10010088:       {{.*}}     nop
 // CHECK: foo_external_same:
 // CHECK-NEXT: 100100b0:       {{.*}}     add 3, 4, 3
diff --git a/test/ELF/ppc64-gd-to-ie.s b/test/ELF/ppc64-gd-to-ie.s
index 1a6cc5b..121032c 100644
--- a/test/ELF/ppc64-gd-to-ie.s
+++ b/test/ELF/ppc64-gd-to-ie.s
@@ -5,16 +5,16 @@
 # RUN: ld.lld -shared %t2.o -o %t3.so
 # RUN: ld.lld  %t.o %t3.so -o %t
 # RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=CheckGot %s
-# RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
-# RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s
+# RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
+# RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %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 %t3.so
 # RUN: ld.lld  %t.o %t3.so -o %t
 # RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=CheckGot %s
-# RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
-# RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s
+# RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
+# RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
 
         .text
         .abiversion 2
diff --git a/test/ELF/ppc64-general-dynamic-tls.s b/test/ELF/ppc64-general-dynamic-tls.s
index 66dab93..8ae25a9 100644
--- a/test/ELF/ppc64-general-dynamic-tls.s
+++ b/test/ELF/ppc64-general-dynamic-tls.s
@@ -2,17 +2,17 @@
 
 // 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-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -r %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-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-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -r %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-objdump -d %t.so | FileCheck --check-prefix=Dis %s
 
 	.text
 	.abiversion 2
diff --git a/test/ELF/ppc64-got-indirect.s b/test/ELF/ppc64-got-indirect.s
index 2837582..d81700a 100644
--- a/test/ELF/ppc64-got-indirect.s
+++ b/test/ELF/ppc64-got-indirect.s
@@ -83,8 +83,8 @@
 # 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-NEXT: 10010008:  {{.*}}   nop
+# CHECK-NEXT: 1001000c:  {{.*}}   ld 3, -32760(2)
 # CHECK: 1001001c:  {{.*}}   lwa 3, 0(3)
 
 # CHECK-LE: Disassembly of section .data:
diff --git a/test/ELF/ppc64-initial-exec-tls.s b/test/ELF/ppc64-initial-exec-tls.s
index 5218b68..9cdd3e4 100644
--- a/test/ELF/ppc64-initial-exec-tls.s
+++ b/test/ELF/ppc64-initial-exec-tls.s
@@ -4,19 +4,19 @@
 // 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-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -r %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-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-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -r %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-objdump -d %t | FileCheck --check-prefix=Dis %s
 
 	.text
 	.abiversion 2
diff --git a/test/ELF/ppc64-local-dynamic.s b/test/ELF/ppc64-local-dynamic.s
index 57f324e..6ed3b0f 100644
--- a/test/ELF/ppc64-local-dynamic.s
+++ b/test/ELF/ppc64-local-dynamic.s
@@ -2,17 +2,17 @@
 
 // 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-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -r %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-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-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -r %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-objdump -d %t.so | FileCheck --check-prefix=Dis %s
 
         .text
         .abiversion 2
diff --git a/test/ELF/ppc64-local-exec-tls.s b/test/ELF/ppc64-local-exec-tls.s
index ff8c2b9..27e973d 100644
--- a/test/ELF/ppc64-local-exec-tls.s
+++ b/test/ELF/ppc64-local-exec-tls.s
@@ -1,8 +1,8 @@
 // REQUIRES: ppc
 // RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
 // RUN: ld.lld  %t.o -o %t
-// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
-// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
+// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
 
 	.text
 	.abiversion 2
diff --git a/test/ELF/ppc64-rel-so-local-calls.s b/test/ELF/ppc64-rel-so-local-calls.s
index 834dbd5..2bc89d5 100644
--- a/test/ELF/ppc64-rel-so-local-calls.s
+++ b/test/ELF/ppc64-rel-so-local-calls.s
@@ -1,11 +1,11 @@
 // 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: ld.lld -shared %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: ld.lld -shared %t.o -o %t.so
 // RUN: llvm-readelf -dyn-relocations %t.so | FileCheck %s
 
 
diff --git a/test/ELF/ppc64-relocs.s b/test/ELF/ppc64-relocs.s
index 88e3d4b..725f3c6 100644
--- a/test/ELF/ppc64-relocs.s
+++ b/test/ELF/ppc64-relocs.s
@@ -63,7 +63,7 @@
 
 # CHECK: Disassembly of section .R_PPC64_TOC16_HA:
 # CHECK: .FR_PPC64_TOC16_HA:
-# CHECK: 10010018: {{.*}} addis 1, 2, 0
+# CHECK: 10010018: {{.*}} nop
 
 .section .R_PPC64_REL24,"ax",@progbits
 .globl .FR_PPC64_REL24
@@ -160,8 +160,8 @@
 # 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: 1001003c: {{.*}} nop
+# CHECK: 10010040: {{.*}} ld 5, -32736(2)
 # CHECK: 10010044: {{.*}} add 3, 3, 4
 
 .section .R_PPC64_REL64, "ax",@progbits
diff --git a/test/ELF/ppc64-tls-gd-le-small.s b/test/ELF/ppc64-tls-gd-le-small.s
new file mode 100644
index 0000000..1da95dc
--- /dev/null
+++ b/test/ELF/ppc64-tls-gd-le-small.s
@@ -0,0 +1,61 @@
+# REQUIRES: ppc
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+# RUN: llvm-objdump -d -r %t.o | FileCheck --check-prefix=CHECK-INPUT %s
+# RUN: ld.lld  --defsym __tls_get_addr=0x1001000 %t.o -o %t
+# RUN: llvm-objdump -d %t | FileCheck --check-prefix=CHECK-DIS %s
+# RUN: llvm-readelf -relocations %t | FileCheck --check-prefix=DYN-RELOCS %s
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+# RUN: llvm-objdump -d -r %t.o | FileCheck --check-prefix=CHECK-INPUT %s
+# RUN: ld.lld  --defsym __tls_get_addr=0x1001000 %t.o -o %t
+# RUN: llvm-objdump -d %t | FileCheck --check-prefix=CHECK-DIS %s
+# RUN: llvm-readelf -relocations %t | FileCheck --check-prefix=DYN-RELOCS %s
+
+# Test checks the relaxation of a 'small' general-dynamic tls access into a
+# local-exec tls access.
+
+        .text
+        .abiversion 2
+
+        .global test
+        .p2align    4
+        .type test, @function
+
+test:
+.Lgep:
+    addis 2, 12, .TOC.-.Lgep@ha
+    addi  2, 2,  .TOC.-.Lgep@l
+    .localentry test, .-test
+    mflr 0
+    std 0, 16(1)
+    stdu 1, -32(1)
+    addi 3, 2, a@got@tlsgd
+    bl __tls_get_addr(a@tlsgd)
+    nop
+    lwz 3, 0(3)
+    addi 1, 1, 32
+    ld 0, 16(1)
+    mtlr 0
+    blr
+
+        .type a, @object
+        .section .tdata,"awT",@progbits
+        .global a
+        .p2align 2
+a:
+        .long 55
+        .size a, 4
+
+# CHECK-INPUT:       addi 3, 2, 0
+# CHECK-INPUT-NEXT:  R_PPC64_GOT_TLSGD16  a
+# CHECK-INPUT-NEXT:  bl .+0
+# CHECK-INPUT-NEXT:  R_PPC64_TLSGD        a
+# CHECK-INPUT-NEXT:  R_PPC64_REL24        __tls_get_addr
+
+# CHECK-DIS:      addis 3, 13, 0
+# CHECK-DIS-NEXT: nop
+# CHECK-DIS-NEXT: addi  3, 3, -28672
+# CHECK-DIS-NEXT: lwz 3, 0(3)
+
+# DYN-RELOCS: There are no relocations in this file
diff --git a/test/ELF/ppc64-tls-gd-le.s b/test/ELF/ppc64-tls-gd-le.s
index c55ae5f..7907d11 100644
--- a/test/ELF/ppc64-tls-gd-le.s
+++ b/test/ELF/ppc64-tls-gd-le.s
@@ -1,16 +1,16 @@
 // REQUIRES: ppc
 
 // RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
-// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
 // RUN: ld.lld  %t.o -o %t
-// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
-// RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s
+// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
+// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
 
 // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
-// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
 // RUN: ld.lld  %t.o -o %t
-// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
-// RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s
+// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
+// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
 
 	.text
 	.abiversion 2
diff --git a/test/ELF/ppc64-tls-ie-le.s b/test/ELF/ppc64-tls-ie-le.s
new file mode 100644
index 0000000..358d3e8
--- /dev/null
+++ b/test/ELF/ppc64-tls-ie-le.s
@@ -0,0 +1,140 @@
+// 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-ie-le.s -o %t2.o
+// RUN: ld.lld -dynamic-linker /lib64/ld64.so.2 %t.o %t2.o -o %t
+// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %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-ie-le.s -o %t2.o
+// RUN: ld.lld -dynamic-linker /lib64/ld64.so.2 %t.o %t2.o -o %t
+// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
+// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
+
+	.text
+	.abiversion 2
+test1:                                  # @test1
+	addis 3, 2, c@got@tprel@ha
+	ld 3, c@got@tprel@l(3)
+	lbzx 3, 3, c@tls
+	blr
+test2:                                  # @test2
+	addis 3, 2, s@got@tprel@ha
+	ld 3, s@got@tprel@l(3)
+	lhzx 3, 3, s@tls
+	blr
+test3:                                  # @test3
+	addis 3, 2, i@got@tprel@ha
+	ld 3, i@got@tprel@l(3)
+	lwzx 3, 3, i@tls
+	blr
+test4:                                  # @test4
+	addis 3, 2, l@got@tprel@ha
+	ld 3, l@got@tprel@l(3)
+	ldx 3, 3, l@tls
+	blr
+test5:                                  # @test5
+	addis 4, 2, c@got@tprel@ha
+	ld 4, c@got@tprel@l(4)
+	stbx 3, 4, c@tls
+	blr
+test6:                                  # @test6
+	addis 4, 2, s@got@tprel@ha
+	ld 4, s@got@tprel@l(4)
+	sthx 3, 4, s@tls
+	blr
+test7:                                  # @test7
+	addis 4, 2, i@got@tprel@ha
+	ld 4, i@got@tprel@l(4)
+	stwx 3, 4, i@tls
+	blr
+test8:                                  # @test8
+	addis 4, 2, l@got@tprel@ha
+	ld 4, l@got@tprel@l(4)
+	stdx 3, 4, l@tls
+	blr
+test9:                                  # @test9
+	addis 3, 2, i@got@tprel@ha
+	ld 3, i@got@tprel@l(3)
+	add 3, 3, i@tls
+	blr
+test_ds:                                  # @test_ds
+	ld 4, l@got@tprel(2)
+	stdx 3, 4, l@tls
+	blr
+
+
+// Verify that the input has initial-exec tls relocation types.
+// InputRelocs: Relocation section '.rela.text'
+// InputRelocs: R_PPC64_GOT_TPREL16_HA {{0+}} c + 0
+// InputRelocs: R_PPC64_GOT_TPREL16_LO_DS {{0+}} c + 0
+// InputRelocs: R_PPC64_TLS {{0+}} c + 0
+// InputRelocs: R_PPC64_GOT_TPREL16_HA {{0+}} s + 0
+// InputRelocs: R_PPC64_GOT_TPREL16_LO_DS {{0+}} s + 0
+// InputRelocs: R_PPC64_TLS {{0+}} s + 0
+// InputRelocs: R_PPC64_GOT_TPREL16_HA {{0+}} i + 0
+// InputRelocs: R_PPC64_GOT_TPREL16_LO_DS {{0+}} i + 0
+// InputRelocs: R_PPC64_TLS {{0+}} i + 0
+// InputRelocs: R_PPC64_GOT_TPREL16_HA {{0+}} l + 0
+// InputRelocs: R_PPC64_GOT_TPREL16_LO_DS {{0+}} l + 0
+// InputRelocs: R_PPC64_TLS {{0+}} l + 0
+// InputRelocs: R_PPC64_GOT_TPREL16_DS {{0+}} l + 0
+// InputRelocs: R_PPC64_TLS {{0+}} l + 0
+
+// Verify that no initial-exec relocations exist for the dynamic linker.
+// OutputRelocs-NOT: R_PPC64_TPREL64  {{0+}}  c + 0
+// OutputRelocs-NPT: R_PPC64_TPREL64  {{0+}}  s + 0
+// OutputRelocs-NOT: R_PPC64_TPREL64  {{0+}}  i + 0
+// OutputRelocs-NOT: R_PPC64_TPREL64  {{0+}}  l + 0
+
+// Dis: test1:
+// Dis: nop
+// Dis: addis 3, 13, 0
+// Dis: lbz 3, -28672(3)
+
+// Dis: test2:
+// Dis: nop
+// Dis: addis 3, 13, 0
+// Dis: lhz 3, -28670(3)
+
+// Dis: test3:
+// Dis: nop
+// Dis: addis 3, 13, 0
+// Dis: lwz 3, -28668(3)
+
+// Dis: test4:
+// Dis: nop
+// Dis: addis 3, 13, 0
+// Dis: ld 3, -28664(3)
+
+// Dis: test5:
+// Dis: nop
+// Dis: addis 4, 13, 0
+// Dis: stb 3, -28672(4)
+
+// Dis: test6:
+// Dis: nop
+// Dis: addis 4, 13, 0
+// Dis: sth 3, -28670(4)
+
+// Dis: test7:
+// Dis: nop
+// Dis: addis 4, 13, 0
+// Dis: stw 3, -28668(4)
+
+// Dis: test8:
+// Dis: nop
+// Dis: addis 4, 13, 0
+// Dis: std 3, -28664(4)
+
+// Dis: test9:
+// Dis: nop
+// Dis: addis 3, 13, 0
+// Dis: addi 3, 3, -28668
+
+// Dis: test_ds:
+// Dis: addis 4, 13, 0
+// Dis: std 3, -28664(4)
diff --git a/test/ELF/ppc64-tls-ld-le.s b/test/ELF/ppc64-tls-ld-le.s
index d42d7b9..b684515 100644
--- a/test/ELF/ppc64-tls-ld-le.s
+++ b/test/ELF/ppc64-tls-ld-le.s
@@ -1,16 +1,16 @@
 // REQUIRES: ppc
 
 // RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
-// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
 // RUN: ld.lld  %t.o -o %t
-// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
-// RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s
+// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
+// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
 
 // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
-// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
 // RUN: ld.lld  %t.o -o %t
-// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
-// RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s
+// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
+// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
 
 	.text
 	.abiversion 2
diff --git a/test/ELF/ppc64-toc-addis-nop-lqsq.s b/test/ELF/ppc64-toc-addis-nop-lqsq.s
new file mode 100644
index 0000000..da57f38
--- /dev/null
+++ b/test/ELF/ppc64-toc-addis-nop-lqsq.s
@@ -0,0 +1,73 @@
+# REQUIRES: ppc
+
+# RUN: llvm-readelf -relocations --wide  %p/Inputs/ppc64le-quadword-ldst.o | FileCheck --check-prefix=QuadInputRelocs %s
+
+# 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  %t2.so %p/Inputs/ppc64le-quadword-ldst.o -o %t
+# RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
+
+# RUN: ld.lld --no-toc-optimize %t2.so %p/Inputs/ppc64le-quadword-ldst.o -o %t
+# RUN: llvm-objdump -D %t | FileCheck --check-prefix=NoOpt %s
+
+# QuadInputRelocs: Relocation section '.rela.text'
+# QuadInputRelocs:  R_PPC64_TOC16_LO_DS    0000000000000000 quadLd
+# QuadInputRelocs:  R_PPC64_TOC16_LO_DS    0000000000000010 quadSt
+
+# The powerpc backend doesn't support the quadword load/store instructions yet.
+# So they are tested by linking against an object file assembled with
+# `as -mpower9 -o ppc64le-quadword-ldst.o in.s` and checking the encoding of
+# the unknown instructions in the dissasembly. Source used as input:
+#quads:
+#.Lbegin_quads:
+#.Lgep_quads:
+#        addis 2, 12, .TOC.-.Lgep_quads@ha
+#        addi  2, 2, .TOC.-.Lgep_quads@l
+#.Llep_quads:
+#.localentry quads, .Llep_quads-.Lgep_quads
+#        addis 3, 2, quadLd@toc@ha
+#        lq    4,    quadLd@toc@l(3)
+#        addis 3, 2, quadSt@toc@ha
+#        stq   4,    quadSt@toc@l(3)
+#        blr
+#
+#        .p2align 4
+#        .global quadLd
+#        .lcomm  quadLd, 16
+#
+#        .global quadSt
+#        .lcomm  quadSt, 16
+
+
+# e0 82 7f 70 decodes to | 111000 | 00100 | 00010 | 16-bit imm |
+#                        |   56   |   4   |   2   |   32624    |
+# which is `lq r4, 32624(r2)`
+# f8 82 7f 82 decodes to | 111110 | 00100 | 00010 | 14-bit imm | 10 |
+#                        |   62   |   4   |   2   |    8160    | 2  |
+# The immediate represents a word offset so this dissasembles to:
+# `stq r4, 32640(r2)`
+# Dis-LABEL: quads:
+# Dis-NEXT:    addis
+# Dis-NEXT:    addi
+# Dis-NEXT:    nop
+# Dis-NEXT:    70 7f 82 e0  <unknown>
+# Dis-NEXT:    nop
+# Dis-NEXT:    82 7f 82 f8  <unknown>
+# Dis-NEXT:    blr
+
+# e0 83 7f 70 decodes to | 111000 | 00100 | 00011 | 16-bit imm |
+#                        |   56   |   4   |   3   |   32624    |
+# `lq r4, 32624(r3)`
+# f8 83 7f 82 decodes to | 111110 | 00100 | 00010 | 14-bit imm | 10 |
+#                        |   62   |   4   |   2   |    8160    | 2  |
+# `stq r4, 32640(r3)`
+# NoOpt-LABEL: quads:
+# NoOpt-NEXT:    addis
+# NoOpt-NEXT:    addi
+# NoOpt-NEXT:    addis 3, 2, 0
+# NoOpt-NEXT:    70 7f 83 e0  <unknown>
+# NoOpt-NEXT:    addis 3, 2, 0
+# NoOpt-NEXT:    82 7f 83 f8  <unknown>
+# NoOpt-NEXT:    blr
+
diff --git a/test/ELF/ppc64-toc-addis-nop.s b/test/ELF/ppc64-toc-addis-nop.s
new file mode 100644
index 0000000..a8c850c
--- /dev/null
+++ b/test/ELF/ppc64-toc-addis-nop.s
@@ -0,0 +1,272 @@
+# REQUIRES: ppc
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+# RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
+
+# 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  %t2.so %t.o -o %t
+# RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
+#
+# RUN: ld.lld --no-toc-optimize %t2.so %t.o -o %t
+# RUN: llvm-objdump -D %t | FileCheck --check-prefix=NoOpt %s
+
+# InputRelocs:  Relocation section '.rela.text'
+# InputRelocs:   R_PPC64_TOC16_HA
+# InputRelocs:   R_PPC64_TOC16_LO
+# InputRelocs:   R_PPC64_TOC16_LO_DS
+
+
+        .text
+	.abiversion 2
+
+        .global bytes
+        .p2align        4
+        .type   bytes,@function
+bytes:
+.Lbytes_gep:
+        addis 2, 12, .TOC.-.Lbytes_gep@ha
+        addi  2, 2,  .TOC.-.Lbytes_gep@l
+.Lbytes_lep:
+        .localentry     bytes, .Lbytes_lep-.Lbytes_gep
+        addis 3, 2, byteLd@toc@ha
+        lbz   3,    byteLd@toc@l(3)
+        addis 4, 2, byteSt@toc@ha
+        stb   3,    byteSt@toc@l(4)
+        blr
+# Dis-LABEL: bytes
+# Dis-NEXT:   addis
+# Dis-NEXT:   addi
+# Dis-NEXT:   nop
+# Dis-NEXT:   lbz   3, 32624(2)
+# Dis-NEXT:   nop
+# Dis-NEXT:   stb   3, 32625(2)
+# Dis-NEXT:   blr
+
+# NoOpt-LABEL: bytes
+# NoOpt-NEXT:     addis
+# NoOpt-NEXT:     addi
+# NoOpt-NEXT:     addis 3, 2, 0
+# NoOpt-NEXT:     lbz 3, 32624(3)
+# NoOpt-NEXT:     addis 4, 2, 0
+# NoOpt-NEXT:     stb 3, 32625(4)
+# NoOpt-NEXT:     blr
+
+        .global  halfs
+        .p2align        4
+        .type   halfs,@function
+halfs:
+.Lhalfs_gep:
+        addis 2, 12, .TOC.-.Lhalfs_gep@ha
+        addi  2, 2,  .TOC.-.Lhalfs_gep@l
+.Lhalfs_lep:
+        .localentry  halfs, .Lhalfs_lep-.Lhalfs_gep
+        addis 3, 2, halfLd@toc@ha
+        lhz   3,    halfLd@toc@l(3)
+        addis 4, 2, halfLd@toc@ha
+        lha   4,    halfLd@toc@l(4)
+        addis 5, 2, halfSt@toc@ha
+        sth   4,    halfSt@toc@l(5)
+        blr
+# Dis-LABEL: halfs
+# Dis-NEXT:   addis
+# Dis-NEXT:   addi
+# Dis-NEXT:   nop
+# Dis-NEXT:   lhz   3, 32626(2)
+# Dis-NEXT:   nop
+# Dis-NEXT:   lha 4, 32626(2)
+# Dis-NEXT:   nop
+# Dis-NEXT:   sth 4, 32628(2)
+# Dis-NEXT:   blr
+
+# NoOpt-LABEL: halfs
+# NoOpt-NEXT:   addis
+# NoOpt-NEXT:   addi
+# NoOpt-NEXT:   addis 3, 2, 0
+# NoOpt-NEXT:   lhz   3, 32626(3)
+# NoOpt-NEXT:   addis 4, 2, 0
+# NoOpt-NEXT:   lha 4, 32626(4)
+# NoOpt-NEXT:   addis 5, 2, 0
+# NoOpt-NEXT:   sth 4, 32628(5)
+# NoOpt-NEXT:   blr
+
+
+        .global words
+        .p2align        4
+        .type   words,@function
+words:
+.Lwords_gep:
+       addis 2, 12, .TOC.-.Lwords_gep@ha
+       addi  2, 2,  .TOC.-.Lwords_gep@l
+.Lwords_lep:
+       .localentry words, .Lwords_lep-.Lwords_gep
+       addis 3, 2, wordLd@toc@ha
+       lwz   3,    wordLd@toc@l(3)
+       addis 4, 2, wordLd@toc@ha
+       lwa   4,    wordLd@toc@l(4)
+       addis 5, 2, wordSt@toc@ha
+       stw   4,    wordSt@toc@l(5)
+       blr
+# Dis-LABEL: words
+# Dis-NEXT:    addis
+# Dis-NEXT:    addi
+# Dis-NEXT:    nop
+# Dis-NEXT:    lwz 3, 32632(2)
+# Dis-NEXT:    nop
+# Dis-NEXT:    lwa 4, 32632(2)
+# Dis-NEXT:    nop
+# Dis-NEXT:    stw 4, 32636(2)
+# Dis-NEXT:    blr
+
+# NoOpt-LABEL: words
+# NoOpt-NEXT:    addis
+# NoOpt-NEXT:    addi
+# NoOpt-NEXT:    addis 3, 2, 0
+# NoOpt-NEXT:    lwz 3, 32632(3)
+# NoOpt-NEXT:    addis 4, 2, 0
+# NoOpt-NEXT:    lwa 4, 32632(4)
+# NoOpt-NEXT:    addis 5, 2, 0
+# NoOpt-NEXT:    stw 4, 32636(5)
+# NoOpt-NEXT:    blr
+
+        .global doublewords
+        .p2align        4
+        .type   doublewords,@function
+doublewords:
+.Ldoublewords_gep:
+       addis 2, 12, .TOC.-.Ldoublewords_gep@ha
+       addi  2, 2,  .TOC.-.Ldoublewords_gep@l
+.Ldoublewords_lep:
+       .localentry doublewords, .Ldoublewords_lep-.Ldoublewords_gep
+        addis 3, 2, dwordLd@toc@ha
+        ld    3,    dwordLd@toc@l(3)
+        addis 4, 2, dwordSt@toc@ha
+        std   3,    dwordSt@toc@l(4)
+        blr
+
+# Dis-LABEL: doublewords
+# Dis-NEXT:    addis
+# Dis-NEXT:    addi
+# Dis-NEXT:    nop
+# Dis-NEXT:    ld 3, 32640(2)
+# Dis-NEXT:    nop
+# Dis-NEXT:    std 3, 32648(2)
+# Dis-NEXT:    blr
+
+# NoOpt-LABEL: doublewords
+# NoOpt-NEXT:    addis
+# NoOpt-NEXT:    addi
+# NoOpt-NEXT:    addis 3, 2, 0
+# NoOpt-NEXT:    ld 3, 32640(3)
+# NoOpt-NEXT:    addis 4, 2, 0
+# NoOpt-NEXT:    std 3, 32648(4)
+# NoOpt-NEXT:    blr
+
+       .global vec_dq
+       .p2align 4
+        .type vec_dq,@function
+vec_dq:
+.Lvec_dq_gep:
+        addis 2, 12, .TOC.-.Lvec_dq_gep@ha
+        addi  2,  2, .TOC.-.Lvec_dq_gep@l
+.Lvec_dq_lep:
+        .localentry  vec_dq, .Lvec_dq_lep-.Lvec_dq_gep
+        addis 3, 2, vecLd@toc@ha
+        lxv   3,    vecLd@toc@l(3)
+        addis 3, 2, vecSt@toc@ha
+        stxv  3,    vecSt@toc@l(3)
+        blr
+
+# Dis-LABEL: vec_dq
+# Dis-NEXT:    addis
+# Dis-NEXT:    addi
+# Dis-NEXT:    nop
+# Dis-NEXT:    lxv 3, 32656(2)
+# Dis-NEXT:    nop
+# Dis-NEXT:    stxv 3, 32672(2)
+# Dis-NEXT:    blr
+
+# NoOpt-LABEL: vec_dq
+# NoOpt-NEXT:    addis
+# NoOpt-NEXT:    addi
+# NoOpt-NEXT:    addis 3, 2, 0
+# NoOpt-NEXT:    lxv 3, 32656(3)
+# NoOpt-NEXT:    addis 3, 2, 0
+# NoOpt-NEXT:    stxv 3, 32672(3)
+# NoOpt-NEXT:    blr
+
+       .global vec_ds
+       .p2align 4
+        .type vec_ds,@function
+vec_ds:
+.Lvec_ds_gep:
+        addis 2, 12, .TOC.-.Lvec_ds_gep@ha
+        addi  2,  2, .TOC.-.Lvec_ds_gep@l
+.Lvec_ds_lep:
+        .localentry  vec_ds, .Lvec_dq_lep-.Lvec_dq_gep
+        addis  3, 2, vecLd@toc@ha
+        lxsd   3,    vecLd@toc@l(3)
+        addis  3, 2, vecSt@toc@ha
+        stxsd  3,    vecSt@toc@l(3)
+        addis  3, 2, vecLd@toc@ha
+        lxssp  3,    vecLd@toc@l(3)
+        addis  3, 2, vecSt@toc@ha
+        stxssp 3,    vecSt@toc@l(3)
+        blr
+# Dis-LABEL: vec_ds
+# Dis-NEXT:   addis
+# Dis-NEXT:   addi
+# Dis-NEXT:   nop
+# Dis-NEXT:   lxsd 3, 32656(2)
+# Dis-NEXT:   nop
+# Dis-NEXT:   stxsd 3, 32672(2)
+# Dis-NEXT:   nop
+# Dis-NEXT:   lxssp 3, 32656(2)
+# Dis-NEXT:   nop
+# Dis-NEXT:   stxssp 3, 32672(2)
+# Dis-NEXT:   blr
+
+# NoOpt-LABEL: vec_ds
+# NoOpt-NEXT:   addis
+# NoOpt-NEXT:   addi
+# NoOpt-NEXT:   addis 3, 2, 0
+# NoOpt-NEXT:   lxsd 3, 32656(3)
+# NoOpt-NEXT:   addis 3, 2, 0
+# NoOpt-NEXT:   stxsd 3, 32672(3)
+# NoOpt-NEXT:   addis 3, 2, 0
+# NoOpt-NEXT:   lxssp 3, 32656(3)
+# NoOpt-NEXT:   addis 3, 2, 0
+# NoOpt-NEXT:   stxssp 3, 32672(3)
+# NoOpt-NEXT:   blr
+
+
+       .global byteLd
+       .lcomm  byteLd, 1, 1
+
+       .global byteSt
+       .lcomm  byteSt, 1, 1
+
+       .global halfLd
+       .lcomm  halfLd, 2, 2
+
+       .global halfSt
+       .lcomm  halfSt, 2, 2
+
+       .global wordLd
+       .lcomm  wordLd, 4, 4
+
+       .global wordSt
+       .lcomm  wordSt, 4, 4
+
+       .global dwordLd
+       .lcomm  dwordLd, 8, 8
+
+       .global dwordSt
+       .lcomm  dwordSt, 8, 8
+
+       .global vecLd
+       .lcomm  vecLd, 16, 16
+
+       .global vecSt
+       .lcomm  vecSt, 16, 16
diff --git a/test/ELF/ppc64-toc-rel.s b/test/ELF/ppc64-toc-rel.s
index ac156c7..5769e43 100644
--- a/test/ELF/ppc64-toc-rel.s
+++ b/test/ELF/ppc64-toc-rel.s
@@ -1,13 +1,15 @@
 # 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: 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
+# RUN: llvm-objdump -D %t2 | FileCheck -check-prefix=CHECK-LE %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
 # 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
@@ -45,15 +47,15 @@
 
 # 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-LE:      Relocations [
+# RELOCS-LE-NEXT:   .rela.text {
+# RELOCS-LE:          0x8 R_PPC64_TOC16_HA global_a 0x0
+# RELOCS-LE:          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
+# RELOCS-BE:          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
@@ -70,19 +72,9 @@
 # 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-LE:      Disassembly of section .got:
+# CHECK-LE-NEXT: .got:
+# CHECK-LE-NEXT: 10030000:       00 80 03 10
 
 # CHECK-BE:      Disassembly of section .got:
 # CHECK-BE-NEXT: .got:
diff --git a/test/ELF/ppc64-toc-restore-recursive-call.s b/test/ELF/ppc64-toc-restore-recursive-call.s
new file mode 100644
index 0000000..4bedcfe
--- /dev/null
+++ b/test/ELF/ppc64-toc-restore-recursive-call.s
@@ -0,0 +1,52 @@
+# REQUIRES: ppc
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t1.o
+# RUN: ld.lld -shared %t1.o -o %t
+# RUN: llvm-objdump -d -r %t | FileCheck %s
+
+# For a recursive call that is interposable the linker calls the plt-stub rather
+# then calling the function directly. Since the call is through a plt stub and
+# might be interposed with a different definition at runtime, a toc-restore is
+# required to follow the call.
+
+# The decision to use a plt-stub for the recursive call is not one I feel
+# strongly about either way. It was done because it matches what bfd and gold do
+# for recursive calls as well as keeps the logic for recursive calls consistent
+# with non-recursive calls.
+
+# CHECK-LABEL: __plt_recursive_func:
+# CHECK-NEXT: 10000:
+# CHECK-LABEL: recursive_func
+# CHECK-NEXT:  10014:
+# CHECK:       1003c: {{[0-9a-fA-F ]+}} bl .+67108804
+# CHECK-NEXT:  ld 2, 24(1)
+
+        .abiversion 2
+        .section ".text"
+        .p2align 2
+        .global recursive_func
+        .type recursive_func, @function
+recursive_func:
+.Lrf_gep:
+    addis 2, 12, .TOC.-.Lrf_gep@ha
+    addi  2, 2, .TOC.-.Lrf_gep@l
+    .localentry recursive_func, .-recursive_func
+    cmpldi 3, 2
+    blt   0, .Lend
+
+    mflr 0
+    std 0, 16(1)
+    stdu 1, -32(1)
+    addi 5, 3, -1
+    mulld 4, 4, 3
+    mr 3, 5
+    bl recursive_func
+    nop
+    mr 4, 3
+    addi 1, 1, 32
+    ld 0, 16(1)
+    mtlr 0
+
+.Lend:
+    extsw 3, 4
+    blr
diff --git a/test/ELF/ppc64-toc-restore.s b/test/ELF/ppc64-toc-restore.s
index 9efe0e8..d9e06ca 100644
--- a/test/ELF/ppc64-toc-restore.s
+++ b/test/ELF/ppc64-toc-restore.s
@@ -22,7 +22,7 @@
   blr
 
 # Calling external function foo in a shared object needs a nop.
-# Calling local function bar_local doe snot need a nop.
+# Calling local function bar_local doe not need a nop.
 .global _start
 _start:
   bl foo
diff --git a/test/ELF/ppc64-tocopt-option.s b/test/ELF/ppc64-tocopt-option.s
new file mode 100644
index 0000000..82130aa
--- /dev/null
+++ b/test/ELF/ppc64-tocopt-option.s
@@ -0,0 +1,14 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: not ld.lld %t --toc-optimize -o /dev/null 2>&1 | FileCheck %s
+
+# CHECK: error: --toc-optimize is only supported on the PowerPC64 target.
+
+         .global __start
+         .type __start,@function
+
+         .text
+        .quad 0
+ __start:
+
diff --git a/test/ELF/relocatable-bss.s b/test/ELF/relocatable-bss.s
index becfbae..716eb4a 100644
--- a/test/ELF/relocatable-bss.s
+++ b/test/ELF/relocatable-bss.s
@@ -20,7 +20,7 @@
 # CHECK-NEXT:  Version:
 # CHECK-NEXT:  Entry:
 # CHECK-NEXT:   ProgramHeaderOffset:
-# CHECK-NEXT:   SectionHeaderOffset: 0xD8
+# CHECK-NEXT:   SectionHeaderOffset: 0xE8
 # CHECK-NEXT:  Flags [
 # CHECK-NEXT:  ]
 # CHECK-NEXT:  HeaderSize:
diff --git a/test/ELF/relocatable-comdat-multiple.s b/test/ELF/relocatable-comdat-multiple.s
index bb7a784..6a8d833 100644
--- a/test/ELF/relocatable-comdat-multiple.s
+++ b/test/ELF/relocatable-comdat-multiple.s
@@ -8,7 +8,7 @@
 # CHECK-NEXT:   Group {
 # CHECK-NEXT:     Name: .group
 # CHECK-NEXT:     Index: 2
-# CHECK-NEXT:     Link: 8
+# CHECK-NEXT:     Link: 9
 # CHECK-NEXT:     Info: 1
 # CHECK-NEXT:     Type: COMDAT
 # CHECK-NEXT:     Signature: aaa
@@ -20,7 +20,7 @@
 # CHECK-NEXT:   Group {
 # CHECK-NEXT:     Name: .group
 # CHECK-NEXT:     Index: 5
-# CHECK-NEXT:     Link: 8
+# CHECK-NEXT:     Link: 9
 # CHECK-NEXT:     Info: 6
 # CHECK-NEXT:     Type: COMDAT
 # CHECK-NEXT:     Signature: bbb
diff --git a/test/ELF/relocatable-comdat.s b/test/ELF/relocatable-comdat.s
index 11aa30c..98ef993 100644
--- a/test/ELF/relocatable-comdat.s
+++ b/test/ELF/relocatable-comdat.s
@@ -30,7 +30,7 @@
 # CHECK-NEXT:    Group {
 # CHECK-NEXT:      Name: .group
 # CHECK-NEXT:      Index: 2
-# CHECK-NEXT:      Link: 5
+# CHECK-NEXT:      Link: 6
 # CHECK-NEXT:      Info: 1 
 # CHECK-NEXT:      Type: COMDAT
 # CHECK-NEXT:      Signature: abc
diff --git a/test/ELF/relocatable-comdat2.s b/test/ELF/relocatable-comdat2.s
index 27844fe..3318fb6 100644
--- a/test/ELF/relocatable-comdat2.s
+++ b/test/ELF/relocatable-comdat2.s
@@ -13,7 +13,7 @@
 # CHECK-NEXT:   Group {
 # CHECK-NEXT:     Name: .group
 # CHECK-NEXT:     Index: 2
-# CHECK-NEXT:     Link: 7
+# CHECK-NEXT:     Link: 8
 # CHECK-NEXT:     Info: 1
 # CHECK-NEXT:     Type: COMDAT
 # CHECK-NEXT:     Signature: bar
@@ -24,7 +24,7 @@
 # CHECK-NEXT:   Group {
 # CHECK-NEXT:     Name: .group
 # CHECK-NEXT:     Index: 4
-# CHECK-NEXT:     Link: 7
+# CHECK-NEXT:     Link: 8
 # CHECK-NEXT:     Info: 2
 # CHECK-NEXT:     Type: COMDAT
 # CHECK-NEXT:     Signature: zed
diff --git a/test/ELF/relocatable-compressed-input.s b/test/ELF/relocatable-compressed-input.s
index 47d8c11..7ef0cf0 100644
--- a/test/ELF/relocatable-compressed-input.s
+++ b/test/ELF/relocatable-compressed-input.s
@@ -7,7 +7,7 @@
 # RUN: ld.lld %t1 -o %t2 -r
 # RUN: llvm-readobj -sections -section-data %t2 | FileCheck %s
 
-## Check we decompress section and remove ".z" prefix specific for zlib-gnu compression.
+## Check we uncompress section and remove ".z" prefix specific for zlib-gnu compression.
 # CHECK:      Section {
 # CHECK:        Index:
 # CHECK:        Name: .debug_str
diff --git a/test/ELF/relocatable-many-sections.s b/test/ELF/relocatable-many-sections.s
index 347f3f7..0d84c6b 100644
--- a/test/ELF/relocatable-many-sections.s
+++ b/test/ELF/relocatable-many-sections.s
@@ -9,8 +9,8 @@
 ## sections amount is greater than SHN_LORESERVE.
 # RUN: llvm-readobj -file-headers %t | FileCheck %s --check-prefix=HDR
 # HDR:      ElfHeader {
-# HDR:        SectionHeaderCount: 0 (65543)
-# HDR-NEXT:   StringTableSectionIndex: 65535 (65541)
+# HDR:        SectionHeaderCount: 0 (65544)
+# HDR-NEXT:   StringTableSectionIndex: 65535 (65542)
 
 ## Check that:
 ## 1) 65541 is the index of .shstrtab section.
@@ -18,13 +18,15 @@
 ## 3) .symtab_shndxr entry size and alignment == 4.
 ## 4) .symtab_shndxr has size equal to
 ##    (sizeof(.symtab) / entsize(.symtab)) * entsize(.symtab_shndxr) = 0x4 * 0x180048 / 0x18 == 0x04000c
+
 # RUN: llvm-readelf -sections -symbols %t | FileCheck %s
-##              [Nr]    Name           Type                   Address          Off    Size   ES Flg  Lk    Inf    Al
-# CHECK:        [65538] .bar
-# CHECK-NEXT:   [65539] .symtab        SYMTAB                 0000000000000000 000040 180078 18      65542 65539  8
-# CHECK-NEXT:   [65540] .symtab_shndxr SYMTAB SECTION INDICES 0000000000000000 1800b8 040014 04      65539 0      4
-# CHECK-NEXT:   [65541] .shstrtab      STRTAB                 0000000000000000 1c00cc 0f0035 00      0     0      1
-# CHECK-NEXT:   [65542] .strtab        STRTAB                 0000000000000000 2b0101 00000c 00
+#        [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
+# CHECK: [65539] .note.GNU-stack PROGBITS       0000000000000000 000040 000000 00      0   0  1
+# CHECK: [65540] .symtab        SYMTAB          0000000000000000 000040 180078 18     65543 65539  8
+# CHECK: [65541] .symtab_shndxr SYMTAB SECTION INDICES 0000000000000000 1800b8 040014 04     65540   0  4
+# CHECK: [65542] .shstrtab      STRTAB          0000000000000000 1c00cc 0f0045 00      0   0  1
+# CHECK: [65543] .strtab        STRTAB          0000000000000000 2b0111 00000c 00      0   0  1
+
 # 5) Check we are able to represent symbol foo with section (.bar) index  > 0xFF00 (SHN_LORESERVE).
 # CHECK: GLOBAL DEFAULT  65538 foo
 
diff --git a/test/ELF/relocatable.s b/test/ELF/relocatable.s
index 7cb2a08..7235ea0 100644
--- a/test/ELF/relocatable.s
+++ b/test/ELF/relocatable.s
@@ -4,6 +4,7 @@
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/relocatable2.s -o %t3.o
 # RUN: ld.lld -r %t1.o %t2.o %t3.o -o %t
 # RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s
+# RUN: llvm-objdump -section-headers %t | FileCheck -check-prefix=SECTION %s
 # RUN: llvm-objdump -s -d %t | FileCheck -check-prefix=CHECKTEXT %s
 
 ## Test --relocatable alias
@@ -37,8 +38,8 @@
 # CHECK-NEXT:  ProgramHeaderEntrySize: 0
 # CHECK-NEXT:  ProgramHeaderCount: 0
 # CHECK-NEXT:  SectionHeaderEntrySize: 64
-# CHECK-NEXT:  SectionHeaderCount: 7
-# CHECK-NEXT:  StringTableSectionIndex: 5
+# CHECK-NEXT:  SectionHeaderCount: 8
+# CHECK-NEXT:  StringTableSectionIndex: 6
 # CHECK-NEXT:  }
 
 # CHECK:       Relocations [
@@ -51,6 +52,17 @@
 # CHECK-NEXT:    0x4E R_X86_64_32S yyy 0x0
 # CHECK-NEXT:  }
 
+# SECTION: Sections:
+# SECTION: Idx Name          Size      Address          Type
+# SECTION:   0               00000000 0000000000000000
+# SECTION:   1 .text         00000056 0000000000000000 TEXT
+# SECTION:   2 .rela.text    00000090 0000000000000000
+# SECTION:   3 .bss          00000018 0000000000000000 BSS
+# SECTION:   4 .note.GNU-stack 00000000 0000000000000000
+# SECTION:   5 .symtab       00000168 0000000000000000
+# SECTION:   6 .shstrtab     00000041 0000000000000000
+# SECTION:   7 .strtab       0000002d 0000000000000000
+
 # CHECKTEXT:      Disassembly of section .text:
 # CHECKTEXT-NEXT: main:
 # CHECKTEXT-NEXT: 0: c7 04 25 00 00 00 00 05 00 00 00 movl $5, 0
diff --git a/test/ELF/relocation-b-aarch64.test b/test/ELF/relocation-b-aarch64.test
index 24bf4b7..152cc39 100644
--- a/test/ELF/relocation-b-aarch64.test
+++ b/test/ELF/relocation-b-aarch64.test
@@ -9,9 +9,9 @@
 
 # CHECK: Disassembly of section .text:
 # CHECK-NEXT: foo:
-# CHECK-NEXT:    20000:        01 00 00 14     b       #4
+# CHECK-NEXT:    210000:        01 00 00 14     b       #4
 # CHECK: bar:
-# CHECK-NEXT:    20004:        ff ff ff 17     b       #-4
+# CHECK-NEXT:    210004:        ff ff ff 17     b       #-4
 
 !ELF
 FileHeader:
diff --git a/test/ELF/relocation-before-merge-start.s b/test/ELF/relocation-before-merge-start.s
new file mode 100644
index 0000000..3550fd2
--- /dev/null
+++ b/test/ELF/relocation-before-merge-start.s
@@ -0,0 +1,9 @@
+// REQUIRES: x86
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: not ld.lld %t.o -o /dev/null -shared 2>&1 | FileCheck %s
+// CHECK: relocation-before-merge-start.s.tmp.o:(.foo): offset is outside the section
+
+.data
+.long .foo - 1
+.section	.foo,"aM",@progbits,4
+.quad 0
diff --git a/test/ELF/relocation-copy-i686.s b/test/ELF/relocation-copy-i686.s
index f9ee32e..8b14f9a 100644
--- a/test/ELF/relocation-copy-i686.s
+++ b/test/ELF/relocation-copy-i686.s
@@ -21,7 +21,7 @@
 // CHECK-NEXT:   SHF_ALLOC
 // CHECK-NEXT:   SHF_WRITE
 // CHECK-NEXT:  ]
-// CHECK-NEXT:  Address: 0x13000
+// CHECK-NEXT:  Address:  0x403000
 // CHECK-NEXT:  Offset:
 // CHECK-NEXT:  Size: 24
 // CHECK-NEXT:  Link: 0
@@ -52,12 +52,12 @@
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]
 
-// 77824 = 0x13000
+// 4206592 =  0x403000
 // 16 is alignment here
-// 77840 = 0x13000 + 16
-// 77844 = 0x13000 + 16 + 4
+// 4206608 =  0x403000 + 16
+// 4206612 =  0x403000 + 16 + 4
 // CODE: Disassembly of section .text:
 // CODE-NEXT: main:
-// CODE-NEXT: 11000: c7 05 00 30 01 00 05 00 00 00 movl $5, 77824
-// CODE-NEXT: 1100a: c7 05 10 30 01 00 07 00 00 00 movl $7, 77840
-// CODE-NEXT: 11014: c7 05 14 30 01 00 09 00 00 00 movl $9, 77844
+// CODE-NEXT: 401000: c7 05 00 30 40 00 05 00 00 00 movl $5, 4206592
+// CODE-NEXT: 40100a: c7 05 10 30 40 00 07 00 00 00 movl $7, 4206608
+// CODE-NEXT: 401014: c7 05 14 30 40 00 09 00 00 00 movl $9, 4206612
diff --git a/test/ELF/relocation-i686.s b/test/ELF/relocation-i686.s
index fdec7ca..6ca487c 100644
--- a/test/ELF/relocation-i686.s
+++ b/test/ELF/relocation-i686.s
@@ -27,14 +27,14 @@
 
 // CHECK: Disassembly of section .R_386_32:
 // CHECK-NEXT: R_386_32:
-// CHECK-NEXT:  11000: {{.*}} movl $69633, %edx
+// CHECK-NEXT:  401000: {{.*}} movl $4198401, %edx
 
 // CHECK: Disassembly of section .R_386_PC32:
 // CHECK-NEXT: R_386_PC32:
-// CHECK-NEXT:   11005:  e8 04 00 00 00  calll 4
+// CHECK-NEXT:   401005:  e8 04 00 00 00  calll 4
 
 // CHECK:      R_386_PC32_2:
-// CHECK-NEXT:   1100e:  90  nop
+// CHECK-NEXT:   40100e:  90  nop
 
 // Create a .got
 movl bar@GOT, %eax
@@ -45,7 +45,7 @@
 // ADDR-NEXT:   SHF_ALLOC
 // ADDR-NEXT:   SHF_EXECINSTR
 // ADDR-NEXT: ]
-// ADDR-NEXT: Address: 0x11040
+// ADDR-NEXT: Address: 0x401040
 // ADDR-NEXT: Offset: 0x1040
 // ADDR-NEXT: Size: 32
 
@@ -55,7 +55,7 @@
 // ADDR-NEXT:   SHF_ALLOC
 // ADDR-NEXT:   SHF_WRITE
 // ADDR-NEXT: ]
-// ADDR-NEXT: Address: 0x13078
+// ADDR-NEXT: Address: 0x403078
 // ADDR-NEXT: Offset:
 // ADDR-NEXT: Size: 8
 
@@ -63,18 +63,18 @@
 R_386_GOTPC:
  movl $_GLOBAL_OFFSET_TABLE_, %eax
 
-// 0x12078 + 8 - 0x11014 = 4204
+// 0x402078 + 8 - 0x401014 = 4204
 
 // CHECK:      Disassembly of section .R_386_GOTPC:
 // CHECK-NEXT: R_386_GOTPC:
-// CHECK-NEXT:   11014:  {{.*}} movl  $8300, %eax
+// CHECK-NEXT:   401014:  {{.*}} movl  $8300, %eax
 
 .section .dynamic_reloc, "ax",@progbits
  call bar
-// addr(.plt) + 16 - (0x11019 + 5) = 50
+// addr(.plt) + 16 - (0x401019 + 5) = 50
 // CHECK:      Disassembly of section .dynamic_reloc:
 // CHECK-NEXT: .dynamic_reloc:
-// CHECK-NEXT:   11019:  e8 32 00 00 00 calll 50
+// CHECK-NEXT:   401019:  e8 32 00 00 00 calll 50
 
 .section .R_386_GOT32,"ax",@progbits
 .global R_386_GOT32
@@ -84,13 +84,13 @@
  movl bar+8@GOT, %eax
  movl zed+4@GOT, %eax
 
-// 4294967288 = 0xFFFFFFF8 = got[0](0x12070) - .got(0x12070) - sizeof(.got)(8)
-// 4294967292 = 0xFFFFFFFC = got[1](0x12074) - .got(0x12070) - sizeof(.got)(8)
+// 4294967288 = 0xFFFFFFF8 = got[0](0x402070) - .got(0x402070) - sizeof(.got)(8)
+// 4294967292 = 0xFFFFFFFC = got[1](0x402074) - .got(0x402070) - sizeof(.got)(8)
 // 0xFFFFFFF8 + 8 = 0
 // 0xFFFFFFFC + 4 = 0
 // CHECK:      Disassembly of section .R_386_GOT32:
 // CHECK-NEXT: R_386_GOT32:
-// CHECK-NEXT: 1101e: a1 f8 ff ff ff movl 4294967288, %eax
-// CHECK-NEXT: 11023: a1 fc ff ff ff movl 4294967292, %eax
-// CHECK-NEXT: 11028: a1 00 00 00 00 movl 0, %eax
-// CHECK-NEXT: 1102d: a1 00 00 00 00 movl 0, %eax
+// CHECK-NEXT: 40101e: a1 f8 ff ff ff movl 4294967288, %eax
+// CHECK-NEXT: 401023: a1 fc ff ff ff movl 4294967292, %eax
+// CHECK-NEXT: 401028: a1 00 00 00 00 movl 0, %eax
+// CHECK-NEXT: 40102d: a1 00 00 00 00 movl 0, %eax
diff --git a/test/ELF/relocation-past-merge-end.s b/test/ELF/relocation-past-merge-end.s
index a3e7b59..53015bc 100644
--- a/test/ELF/relocation-past-merge-end.s
+++ b/test/ELF/relocation-past-merge-end.s
@@ -1,7 +1,7 @@
 // REQUIRES: x86
 // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
 // RUN: not ld.lld %t.o -o /dev/null -shared 2>&1 | FileCheck %s
-// CHECK: relocation-past-merge-end.s.tmp.o:(.foo): entry is past the end of the section
+// CHECK: relocation-past-merge-end.s.tmp.o:(.foo): offset is outside the section
 
 .data
 .long .foo + 10
diff --git a/test/ELF/shared.s b/test/ELF/shared.s
index 3a8fede..1b93fef 100644
--- a/test/ELF/shared.s
+++ b/test/ELF/shared.s
@@ -141,7 +141,7 @@
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Symbol {
 // CHECK-NEXT:     Name: _DYNAMIC
-// CHECK-NEXT:     Value: 0x12000
+// CHECK-NEXT:     Value: 0x402000
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Local
 // CHECK-NEXT:     Type: None
@@ -152,7 +152,7 @@
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Symbol {
 // CHECK-NEXT:     Name: _start
-// CHECK-NEXT:     Value: 0x11000
+// CHECK-NEXT:     Value: 0x401000
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Global
 // CHECK-NEXT:     Type: None
@@ -191,7 +191,7 @@
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Symbol {
 // CHECK-NEXT:     Name: _start@
-// CHECK-NEXT:     Value: 0x11000
+// CHECK-NEXT:     Value: 0x401000
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Global
 // CHECK-NEXT:     Type: Non
diff --git a/test/ELF/static-with-export-dynamic.s b/test/ELF/static-with-export-dynamic.s
index f0c67df..a718bab 100644
--- a/test/ELF/static-with-export-dynamic.s
+++ b/test/ELF/static-with-export-dynamic.s
@@ -18,7 +18,7 @@
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Symbol {
 // CHECK-NEXT:     Name: _start
-// CHECK-NEXT:     Value: 0x11000
+// CHECK-NEXT:     Value: 0x401000
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Global
 // CHECK-NEXT:     Type: None
diff --git a/test/ELF/strip-debug.s b/test/ELF/strip-debug.s
index 8005cfa..e5295f1 100644
--- a/test/ELF/strip-debug.s
+++ b/test/ELF/strip-debug.s
@@ -1,4 +1,4 @@
-# REQUIRES: x86
+# REQUIRES: x86, zlib
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
 # RUN: ld.lld %t -o %t2 --strip-debug
 # RUN: llvm-readobj -sections %t2 | FileCheck %s
@@ -12,3 +12,5 @@
 
 .section .debug_Foo,"",@progbits
 .section .zdebug_Bar,"",@progbits
+.ascii "ZLIB"
+.quad 0
diff --git a/test/ELF/textrel.s b/test/ELF/textrel.s
new file mode 100644
index 0000000..fac67d5
--- /dev/null
+++ b/test/ELF/textrel.s
@@ -0,0 +1,40 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux-gnu %s -o %t.o
+
+# Without --warn-text-ifunc, lld should run fine:
+# RUN: ld.lld -z notext %t.o -o %t2
+
+# With --warn-text-ifunc, lld should run with warnings:
+# RUN: ld.lld --warn-ifunc-textrel -z notext %t.o -o /dev/null 2>&1 | FileCheck %s
+# CHECK: using ifunc symbols when text relocations are allowed may produce
+# CHECK-SAME: a binary that will segfault, if the object file is linked with
+# CHECK-SAME: old version of glibc (glibc 2.28 and earlier). If this applies to
+# CHECK-SAME: you, consider recompiling the object files without -fPIC and
+# CHECK-SAME: without -Wl,-z,notext option. Use -no-warn-ifunc-textrel to
+# CHECK-SAME: turn off this warning.
+# CHECK: >>> defined in {{.*}}
+# CHECK: >>> referenced by {{.*}}:(.text+0x8)
+
+# Without text relocations, lld should run fine:
+# RUN: ld.lld --fatal-warnings %t.o -o /dev/null
+
+.text
+.globl a_func_impl
+a_func_impl:
+  nop
+
+.globl selector
+.type selector,@function
+selector:
+  movl $a_func_impl, %eax
+  retq
+
+.globl a_func
+.type a_func,@gnu_indirect_function
+.set a_func, selector
+
+.globl _start
+.type _start,@function
+main:
+  callq a_func
+  retq
diff --git a/test/ELF/tls-i686.s b/test/ELF/tls-i686.s
index c411fc7..31c9494 100644
--- a/test/ELF/tls-i686.s
+++ b/test/ELF/tls-i686.s
@@ -32,16 +32,16 @@
 
 // DIS:      Disassembly of section test:
 // DIS-NEXT: _start:
-// DIS-NEXT: 11000: ba 08 00 00 00       movl $8, %edx
-// DIS-NEXT: 11005: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
-// DIS-NEXT: 1100c: 29 d0                subl %edx, %eax
-// DIS-NEXT: 1100e: ba 04 00 00 00       movl $4, %edx
-// DIS-NEXT: 11013: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
-// DIS-NEXT: 1101a: 29 d0                subl %edx, %eax
-// DIS-NEXT: 1101c: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
-// DIS-NEXT: 11023: 8d 81 f8 ff ff ff    leal -8(%ecx), %eax
-// DIS-NEXT: 11029: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
-// DIS-NEXT: 11030: 8d 81 77 00 00 00    leal 119(%ecx), %eax
+// DIS-NEXT: 401000: ba 08 00 00 00       movl $8, %edx
+// DIS-NEXT: 401005: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
+// DIS-NEXT: 40100c: 29 d0                subl %edx, %eax
+// DIS-NEXT: 40100e: ba 04 00 00 00       movl $4, %edx
+// DIS-NEXT: 401013: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
+// DIS-NEXT: 40101a: 29 d0                subl %edx, %eax
+// DIS-NEXT: 40101c: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
+// DIS-NEXT: 401023: 8d 81 f8 ff ff ff    leal -8(%ecx), %eax
+// DIS-NEXT: 401029: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
+// DIS-NEXT: 401030: 8d 81 77 00 00 00    leal 119(%ecx), %eax
 
 // RELOC: Relocations [
 // RELOC-NEXT: ]
diff --git a/test/ELF/tls-opt-gdiele-i686.s b/test/ELF/tls-opt-gdiele-i686.s
index b39f933..1baaf11 100644
--- a/test/ELF/tls-opt-gdiele-i686.s
+++ b/test/ELF/tls-opt-gdiele-i686.s
@@ -8,21 +8,21 @@
 
 // NORELOC:      Relocations [
 // NORELOC-NEXT: Section ({{.*}}) .rel.dyn {
-// NORELOC-NEXT:   0x12058 R_386_TLS_TPOFF tlsshared0 0x0
-// NORELOC-NEXT:   0x1205C R_386_TLS_TPOFF tlsshared1 0x0
+// NORELOC-NEXT:   0x402058 R_386_TLS_TPOFF tlsshared0 0x0
+// NORELOC-NEXT:   0x40205C R_386_TLS_TPOFF tlsshared1 0x0
 // NORELOC-NEXT:   }
 // NORELOC-NEXT: ]
 
 // DISASM:      Disassembly of section .text:
 // DISASM-NEXT: _start:
-// DISASM-NEXT: 11000: 65 a1 00 00 00 00 movl %gs:0, %eax
-// DISASM-NEXT: 11006: 03 83 f8 ff ff ff addl -8(%ebx), %eax
-// DISASM-NEXT: 1100c: 65 a1 00 00 00 00 movl %gs:0, %eax
-// DISASM-NEXT: 11012: 03 83 fc ff ff ff addl -4(%ebx), %eax
-// DISASM-NEXT: 11018: 65 a1 00 00 00 00 movl %gs:0, %eax
-// DISASM-NEXT: 1101e: 81 e8 08 00 00 00 subl $8, %eax
-// DISASM-NEXT: 11024: 65 a1 00 00 00 00 movl %gs:0, %eax
-// DISASM-NEXT: 1102a: 81 e8 04 00 00 00 subl $4, %eax
+// DISASM-NEXT: 401000: 65 a1 00 00 00 00 movl %gs:0, %eax
+// DISASM-NEXT: 401006: 03 83 f8 ff ff ff addl -8(%ebx), %eax
+// DISASM-NEXT: 40100c: 65 a1 00 00 00 00 movl %gs:0, %eax
+// DISASM-NEXT: 401012: 03 83 fc ff ff ff addl -4(%ebx), %eax
+// DISASM-NEXT: 401018: 65 a1 00 00 00 00 movl %gs:0, %eax
+// DISASM-NEXT: 40101e: 81 e8 08 00 00 00 subl $8, %eax
+// DISASM-NEXT: 401024: 65 a1 00 00 00 00 movl %gs:0, %eax
+// DISASM-NEXT: 40102a: 81 e8 04 00 00 00 subl $4, %eax
 
 .type tlsexe1,@object
 .section .tbss,"awT",@nobits
diff --git a/test/ELF/tls-opt-i686.s b/test/ELF/tls-opt-i686.s
index d8b1d0e..0f9d4d6 100644
--- a/test/ELF/tls-opt-i686.s
+++ b/test/ELF/tls-opt-i686.s
@@ -10,25 +10,25 @@
 // DISASM:      Disassembly of section .text:
 // DISASM-NEXT: _start:
 // LD -> LE:
-// DISASM-NEXT: 11000: 65 a1 00 00 00 00 movl %gs:0, %eax
-// DISASM-NEXT: 11006: 90                nop
-// DISASM-NEXT: 11007: 8d 74 26 00       leal (%esi,%eiz), %esi
-// DISASM-NEXT: 1100b: 8d 90 f8 ff ff ff leal -8(%eax), %edx
-// DISASM-NEXT: 11011: 65 a1 00 00 00 00 movl %gs:0, %eax
-// DISASM-NEXT: 11017: 90                nop
-// DISASM-NEXT: 11018: 8d 74 26 00       leal (%esi,%eiz), %esi
-// DISASM-NEXT: 1101c: 8d 90 fc ff ff ff leal -4(%eax), %edx
+// DISASM-NEXT: 401000: 65 a1 00 00 00 00 movl %gs:0, %eax
+// DISASM-NEXT: 401006: 90                nop
+// DISASM-NEXT: 401007: 8d 74 26 00       leal (%esi,%eiz), %esi
+// DISASM-NEXT: 40100b: 8d 90 f8 ff ff ff leal -8(%eax), %edx
+// DISASM-NEXT: 401011: 65 a1 00 00 00 00 movl %gs:0, %eax
+// DISASM-NEXT: 401017: 90                nop
+// DISASM-NEXT: 401018: 8d 74 26 00       leal (%esi,%eiz), %esi
+// DISASM-NEXT: 40101c: 8d 90 fc ff ff ff leal -4(%eax), %edx
 // IE -> LE:
 // 4294967288 == 0xFFFFFFF8
 // 4294967292 == 0xFFFFFFFC
-// DISASM-NEXT: 11022: 65 a1 00 00 00 00  movl %gs:0, %eax
-// DISASM-NEXT: 11028: c7 c0 f8 ff ff ff  movl $4294967288, %eax
-// DISASM-NEXT: 1102e: 65 a1 00 00 00 00  movl %gs:0, %eax
-// DISASM-NEXT: 11034: c7 c0 fc ff ff ff  movl $4294967292, %eax
-// DISASM-NEXT: 1103a: 65 a1 00 00 00 00  movl %gs:0, %eax
-// DISASM-NEXT: 11040: 8d 80 f8 ff ff ff  leal -8(%eax), %eax
-// DISASM-NEXT: 11046: 65 a1 00 00 00 00  movl %gs:0, %eax
-// DISASM-NEXT: 1104c: 8d 80 fc ff ff ff  leal -4(%eax), %eax
+// DISASM-NEXT: 401022: 65 a1 00 00 00 00  movl %gs:0, %eax
+// DISASM-NEXT: 401028: c7 c0 f8 ff ff ff  movl $4294967288, %eax
+// DISASM-NEXT: 40102e: 65 a1 00 00 00 00  movl %gs:0, %eax
+// DISASM-NEXT: 401034: c7 c0 fc ff ff ff  movl $4294967292, %eax
+// DISASM-NEXT: 40103a: 65 a1 00 00 00 00  movl %gs:0, %eax
+// DISASM-NEXT: 401040: 8d 80 f8 ff ff ff  leal -8(%eax), %eax
+// DISASM-NEXT: 401046: 65 a1 00 00 00 00  movl %gs:0, %eax
+// DISASM-NEXT: 40104c: 8d 80 fc ff ff ff  leal -4(%eax), %eax
 .type tls0,@object
 .section .tbss,"awT",@nobits
 .globl tls0
diff --git a/test/ELF/tls-opt-iele-i686-nopic.s b/test/ELF/tls-opt-iele-i686-nopic.s
index 50655e3..704928b 100644
--- a/test/ELF/tls-opt-iele-i686-nopic.s
+++ b/test/ELF/tls-opt-iele-i686-nopic.s
@@ -14,7 +14,7 @@
 // GOTREL-NEXT:     SHF_ALLOC
 // GOTREL-NEXT:     SHF_WRITE
 // GOTREL-NEXT:   ]
-// GOTREL-NEXT:   Address: 0x12058
+// GOTREL-NEXT:   Address: 0x402058
 // GOTREL-NEXT:   Offset: 0x2058
 // GOTREL-NEXT:   Size: 8
 // GOTREL-NEXT:   Link: 0
@@ -24,8 +24,8 @@
 // GOTREL-NEXT: }
 // GOTREL:      Relocations [
 // GOTREL-NEXT: Section ({{.*}}) .rel.dyn {
-// GOTREL-NEXT:   0x12058 R_386_TLS_TPOFF tlsshared0 0x0
-// GOTREL-NEXT:   0x1205C R_386_TLS_TPOFF tlsshared1 0x0
+// GOTREL-NEXT:   0x402058 R_386_TLS_TPOFF tlsshared0 0x0
+// GOTREL-NEXT:   0x40205C R_386_TLS_TPOFF tlsshared1 0x0
 // GOTREL-NEXT:  }
 // GOTREL-NEXT: ]
 
@@ -33,24 +33,24 @@
 // DISASM-NEXT: _start:
 // 4294967288 = 0xFFFFFFF8
 // 4294967292 = 0xFFFFFFFC
-// 73808 = (.got)[0] = 0x12058
-// 73812 = (.got)[1] = 0x1205C
-// DISASM-NEXT: 11000: c7 c1 f8 ff ff ff movl $4294967288, %ecx
-// DISASM-NEXT: 11006: 65 8b 01          movl %gs:(%ecx), %eax
-// DISASM-NEXT: 11009: b8 f8 ff ff ff    movl $4294967288, %eax
-// DISASM-NEXT: 1100e: 65 8b 00          movl %gs:(%eax), %eax
-// DISASM-NEXT: 11011: 81 c1 f8 ff ff ff addl $4294967288, %ecx
-// DISASM-NEXT: 11017: 65 8b 01          movl %gs:(%ecx), %eax
-// DISASM-NEXT: 1101a: c7 c1 fc ff ff ff movl $4294967292, %ecx
-// DISASM-NEXT: 11020: 65 8b 01          movl %gs:(%ecx), %eax
-// DISASM-NEXT: 11023: b8 fc ff ff ff    movl $4294967292, %eax
-// DISASM-NEXT: 11028: 65 8b 00          movl %gs:(%eax), %eax
-// DISASM-NEXT: 1102b: 81 c1 fc ff ff ff addl $4294967292, %ecx
-// DISASM-NEXT: 11031: 65 8b 01          movl %gs:(%ecx), %eax
-// DISASM-NEXT: 11034: 8b 0d 58 20 01 00 movl 73816, %ecx
-// DISASM-NEXT: 1103a: 65 8b 01          movl %gs:(%ecx), %eax
-// DISASM-NEXT: 1103d: 03 0d 5c 20 01 00 addl 73820, %ecx
-// DISASM-NEXT: 11043: 65 8b 01          movl %gs:(%ecx), %eax
+// 4202584 = (.got)[0] = 0x402058
+// 4202588 = (.got)[1] = 0x40205C
+// DISASM-NEXT: 401000: c7 c1 f8 ff ff ff movl $4294967288, %ecx
+// DISASM-NEXT: 401006: 65 8b 01          movl %gs:(%ecx), %eax
+// DISASM-NEXT: 401009: b8 f8 ff ff ff    movl $4294967288, %eax
+// DISASM-NEXT: 40100e: 65 8b 00          movl %gs:(%eax), %eax
+// DISASM-NEXT: 401011: 81 c1 f8 ff ff ff addl $4294967288, %ecx
+// DISASM-NEXT: 401017: 65 8b 01          movl %gs:(%ecx), %eax
+// DISASM-NEXT: 40101a: c7 c1 fc ff ff ff movl $4294967292, %ecx
+// DISASM-NEXT: 401020: 65 8b 01          movl %gs:(%ecx), %eax
+// DISASM-NEXT: 401023: b8 fc ff ff ff    movl $4294967292, %eax
+// DISASM-NEXT: 401028: 65 8b 00          movl %gs:(%eax), %eax
+// DISASM-NEXT: 40102b: 81 c1 fc ff ff ff addl $4294967292, %ecx
+// DISASM-NEXT: 401031: 65 8b 01          movl %gs:(%ecx), %eax
+// DISASM-NEXT: 401034: 8b 0d 58 20 40 00 movl 4202584, %ecx
+// DISASM-NEXT: 40103a: 65 8b 01          movl %gs:(%ecx), %eax
+// DISASM-NEXT: 40103d: 03 0d 5c 20 40 00 addl 4202588, %ecx
+// DISASM-NEXT: 401043: 65 8b 01          movl %gs:(%ecx), %eax
 
 .type tlslocal0,@object
 .section .tbss,"awT",@nobits
diff --git a/test/ELF/undef-broken-debug.test b/test/ELF/undef-broken-debug.test
index b93d399..c3405ad 100644
--- a/test/ELF/undef-broken-debug.test
+++ b/test/ELF/undef-broken-debug.test
@@ -5,7 +5,7 @@
 # The debug info has a broken relocation. Check that we don't crash
 # and still report the undefined symbol.
 
-# CHECK: error: unsupported relocation target while parsing debug info
+# CHECK: error: {{.*}}.o: relocation R_X86_64_64 at 0x29 has unsupported target
 # CHECK: error: undefined symbol: bar
 
 --- !ELF
diff --git a/test/ELF/undef-with-plt-addr-i686.s b/test/ELF/undef-with-plt-addr-i686.s
index 755f0da..cd1b3fd 100644
--- a/test/ELF/undef-with-plt-addr-i686.s
+++ b/test/ELF/undef-with-plt-addr-i686.s
@@ -17,7 +17,7 @@
 // CHECK-NEXT:   SHF_ALLOC
 // CHECK-NEXT:   SHF_EXECINSTR
 // CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x11010
+// CHECK-NEXT: Address: 0x401010
 
 // CHECK:      Name:    set_data
-// CHECK-NEXT: Value:   0x11020
+// CHECK-NEXT: Value:   0x401020
diff --git a/test/ELF/wrap-entry.s b/test/ELF/wrap-entry.s
new file mode 100644
index 0000000..c746b8e
--- /dev/null
+++ b/test/ELF/wrap-entry.s
@@ -0,0 +1,13 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+
+// RUN: ld.lld -o %t.exe %t.o -wrap=_start
+// RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
+
+// CHECK: Entry: 0x201001
+
+.global _start, __wrap__start
+_start:
+  nop
+__wrap__start:
+  nop
diff --git a/test/ELF/wrap-no-real.s b/test/ELF/wrap-no-real.s
index 100efa6..d6bda77 100644
--- a/test/ELF/wrap-no-real.s
+++ b/test/ELF/wrap-no-real.s
@@ -15,60 +15,15 @@
 // CHECK-NEXT: movl $0x11010, %edx
 // CHECK-NEXT: movl $0x11000, %edx
 
-// RUN: llvm-readobj -t %t | FileCheck -check-prefix=SYM %s
+// RUN: llvm-objdump -t %t | FileCheck -check-prefix=SYM %s
 
-// Test the full symbol table. It is verbose, but lld at times
-// produced duplicated symbols which are hard to test otherwise.
 
-// SYM:       Symbols [
-// SYM-NEXT:    Symbol {
-// SYM-NEXT:     Name:  (0)
-// SYM-NEXT:     Value:
-// SYM-NEXT:     Size:
-// SYM-NEXT:     Binding:
-// SYM-NEXT:     Type
-// SYM-NEXT:     Other:
-// SYM-NEXT:     Section:
-// SYM-NEXT:   }
-// SYM-NEXT:   Symbol {
-// SYM-NEXT:     Name: _DYNAMIC
-// SYM-NEXT:     Value:
-// SYM-NEXT:     Size:
-// SYM-NEXT:     Binding:
-// SYM-NEXT:     Type:
-// SYM-NEXT:     Other [
-// SYM-NEXT:       STV_HIDDEN
-// SYM-NEXT:     ]
-// SYM-NEXT:     Section: .dynamic
-// SYM-NEXT:   }
-// SYM-NEXT:   Symbol {
-// SYM-NEXT:     Name: foo
-// SYM-NEXT:     Value: 0x11000
-// SYM-NEXT:     Size:
-// SYM-NEXT:     Binding:
-// SYM-NEXT:     Type:
-// SYM-NEXT:     Other:
-// SYM-NEXT:     Section:
-// SYM-NEXT:   }
-// SYM-NEXT:   Symbol {
-// SYM-NEXT:     Name: _start
-// SYM-NEXT:     Value:
-// SYM-NEXT:     Size:
-// SYM-NEXT:     Binding:
-// SYM-NEXT:     Type
-// SYM-NEXT:     Other:
-// SYM-NEXT:     Section:
-// SYM-NEXT:   }
-// SYM-NEXT:   Symbol {
-// SYM-NEXT:     Name: __wrap_foo
-// SYM-NEXT:     Value: 0x11010
-// SYM-NEXT:     Size:
-// SYM-NEXT:     Binding:
-// SYM-NEXT:     Type:
-// SYM-NEXT:     Other:
-// SYM-NEXT:     Section:
-// SYM-NEXT:   }
-// SYM-NEXT: ]
+// SYM:      0000000000000000  *UND*     00000000
+// SYM-NEXT: 0000000000202000  .dynamic  00000000 .hidden _DYNAMIC
+// SYM-NEXT: 0000000000011000  *ABS*     00000000 __real_foo
+// SYM-NEXT: 0000000000011010  *ABS*     00000000 __wrap_foo
+// SYM-NEXT: 0000000000201000  .text     00000000 _start
+// SYM-NEXT: 0000000000011000  *ABS*     00000000 foo
 
 .global _start
 _start:
diff --git a/test/ELF/wrap-plt.s b/test/ELF/wrap-plt.s
new file mode 100644
index 0000000..71f533d
--- /dev/null
+++ b/test/ELF/wrap-plt.s
@@ -0,0 +1,45 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
+
+// RUN: ld.lld -o %t2 %t -wrap foo -shared
+// RUN: llvm-readobj -s -r %t2 | FileCheck %s
+// RUN: llvm-objdump -d %t2 | FileCheck --check-prefix=DISASM %s
+
+// CHECK:      Name: .plt
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT:   SHF_ALLOC
+// CHECK-NEXT:   SHF_EXECINSTR
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x1020
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 48
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 16
+
+// CHECK:      Relocations [
+// CHECK-NEXT:   Section ({{.*}}) .rela.plt {
+// CHECK-NEXT:     0x2018 R_X86_64_JUMP_SLOT __wrap_foo 0x0
+// CHECK-NEXT:     0x2020 R_X86_64_JUMP_SLOT _start 0x0
+// CHECK-NEXT:   }
+// CHECK-NEXT: ]
+
+// DISASM:      _start:
+// DISASM-NEXT: jmp    41
+// DISASM-NEXT: jmp    36
+// DISASM-NEXT: jmp    47
+
+.global foo
+foo:
+  nop
+
+.global __wrap_foo
+__wrap_foo:
+  nop
+
+.global _start
+_start:
+  jmp foo@plt
+  jmp __wrap_foo@plt
+  jmp _start@plt
diff --git a/test/ELF/wrap.s b/test/ELF/wrap.s
index a02592e..1a97268 100644
--- a/test/ELF/wrap.s
+++ b/test/ELF/wrap.s
@@ -34,7 +34,7 @@
 // SYM2-NEXT:   STV_PROTECTED
 // SYM2-NEXT: ]
 // SYM3:      Name: __real_foo
-// SYM3-NEXT: Value: 0x11020
+// SYM3-NEXT: Value: 0x11000
 // SYM3-NEXT: Size:
 // SYM3-NEXT: Binding: Global
 // SYM3-NEXT: Type:    None
diff --git a/test/ELF/x86-64-reloc-error2.s b/test/ELF/x86-64-reloc-error2.s
index d49b675..81f033f 100644
--- a/test/ELF/x86-64-reloc-error2.s
+++ b/test/ELF/x86-64-reloc-error2.s
@@ -1,14 +1,18 @@
 # REQUIRES: x86
 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
-# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s
+# RUN: not ld.lld --entry=func --gc-sections %t.o -o /dev/null 2>&1 | FileCheck %s
 
 ## Check we are able to find a function symbol that encloses
 ## a given location when reporting error messages.
 # CHECK: {{.*}}.o:(function func): relocation R_X86_64_32S out of range: -281474974609408 is not in [-2147483648, 2147483647]
 
+# This mergeable section will be garbage collected. We had a crash issue in that case. Test it.
+.section .rodata.str1,"aMS",@progbits,1
+.asciz "a"
+
 .section .text.func, "ax", %progbits
 .globl func
 .type func,@function
-.size func, 0x10
 func:
- movq func - 0x1000000000000, %rdx
+  movq $func - 0x1000000000000, %rdx
+.size func, .-func
diff --git a/test/ELF/x86-64-split-stack-prologue-adjust-fail.s b/test/ELF/x86-64-split-stack-prologue-adjust-fail.s
index f3d0924..b2d21e1 100644
--- a/test/ELF/x86-64-split-stack-prologue-adjust-fail.s
+++ b/test/ELF/x86-64-split-stack-prologue-adjust-fail.s
@@ -9,7 +9,7 @@
 # CHECK: error: {{.*}}.o:(.text): unknown_prologue (with -fsplit-stack) calls non_split (without -fsplit-stack), but couldn't adjust its prologue
 
 # RUN: not ld.lld -r --defsym __morestack=0x100 %t1.o %t2.o -o %t 2>&1 | FileCheck %s -check-prefix=RELOCATABLE
-# RELOCATABLE: Cannot mix split-stack and non-split-stack in a relocatable link
+# RELOCATABLE: cannot mix split-stack and non-split-stack in a relocatable link
 
 # RUN: not ld.lld --defsym __morestack=0x100 --defsym _start=0x300 %t1.o %t2.o %t3.o -o %t 2>&1 | FileCheck %s -check-prefix=ERROR
 # ERROR: Mixing split-stack objects requires a definition of __morestack_non_split
diff --git a/test/ELF/x86-64-split-stack-prologue-adjust-shared.s b/test/ELF/x86-64-split-stack-prologue-adjust-shared.s
new file mode 100644
index 0000000..9da2dde
--- /dev/null
+++ b/test/ELF/x86-64-split-stack-prologue-adjust-shared.s
@@ -0,0 +1,31 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/x86-64-split-stack-extra.s -o %t2.o
+# RUN: ld.lld --defsym __morestack=0x100 --defsym __morestack_non_split=0x200 %t2.o -o %t4.so  -shared
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+# RUN: ld.lld --defsym __morestack=0x100 --defsym __morestack_non_split=0x200 %t1.o %t4.so -o %t
+# RUN: llvm-objdump -d %t | FileCheck %s
+
+# For a cross .so call, make sure lld produced the conservative call to __morestack_non_split.
+# CHECK: prologue1_cross_so_call:
+# CHECK-NEXT: stc{{.*$}}
+# CHECK-NEXT: nopl{{.*$}}
+# CHECK: jae{{.*$}}
+# CHECK-NEXT: callq{{.*}}<__morestack_non_split>
+
+	.text
+
+	.global	prologue1_cross_so_call
+	.type	prologue1_cross_so_call,@function
+prologue1_cross_so_call:
+	cmp %fs:0x70,%rsp
+	jae 1f
+	callq __morestack
+	retq
+1:
+	callq split
+	retq
+	.size	prologue1_cross_so_call,. - prologue1_cross_so_call
+
+	.section	.note.GNU-stack,"",@progbits
+	.section	.note.GNU-split-stack,"",@progbits
diff --git a/test/ELF/znotext-plt-relocations-protected.s b/test/ELF/znotext-plt-relocations-protected.s
index 4fd8065..37724e7 100644
--- a/test/ELF/znotext-plt-relocations-protected.s
+++ b/test/ELF/znotext-plt-relocations-protected.s
@@ -4,7 +4,12 @@
 # RUN: ld.lld %t2.o -o %t2.so -shared
 # RUN: not ld.lld -z notext %t.o %t2.so -o /dev/null 2>&1 | FileCheck %s
 
-# CHECK: error: cannot preempt symbol: foo
+# CHECK:      error: cannot preempt symbol: foo
+# CHECK-NEXT: >>> defined in {{.*}}2.so
+# CHECK-NEXT: >>> referenced by test.cpp
+# CHECK-NEXT: >>>               {{.*}}.o:(.text+0x0)
+
+.file "test.cpp"
 
 .global _start
 _start:
diff --git a/test/ELF/zstack-size.s b/test/ELF/zstack-size.s
index 23eed0a..bec2b20 100644
--- a/test/ELF/zstack-size.s
+++ b/test/ELF/zstack-size.s
@@ -6,6 +6,9 @@
 # RUN: ld.lld -z stack-size=0 %t -o %t2
 # RUN: llvm-readobj -program-headers %t2 | FileCheck %s -check-prefix=CHECK2
 
+# RUN: ld.lld -z stack-size=0x2000 -z stack-size=0x1000 %t -o %t3
+# RUN: llvm-readobj -program-headers %t3 | FileCheck %s -check-prefix=CHECK1
+
 .global _start
 _start:
   nop
diff --git a/test/MinGW/driver.test b/test/MinGW/driver.test
index 35d3ccf..3222bb1 100644
--- a/test/MinGW/driver.test
+++ b/test/MinGW/driver.test
@@ -145,3 +145,9 @@
 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
+
+RUN: ld.lld -### foo.o -m i386pe -require-defined _foo --require-defined _bar -require-defined=_baz --require-defined=_foo2 | FileCheck -check-prefix=REQUIRE-DEFINED %s
+REQUIRE-DEFINED: -include:_foo -include:_bar -include:_baz -include:_foo2
+
+RUN: ld.lld -### -m i386pep foo.o -Llibpath | FileCheck -check-prefix LIBPATH %s
+LIBPATH: -libpath:libpath
diff --git a/test/lit.site.cfg.py.in b/test/lit.site.cfg.py.in
index 764ab83..7475ac7 100644
--- a/test/lit.site.cfg.py.in
+++ b/test/lit.site.cfg.py.in
@@ -25,7 +25,8 @@
     key, = e.args
     lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))
 
-@LIT_SITE_CFG_IN_FOOTER@
+import lit.llvm
+lit.llvm.initialize(lit_config, config)
 
 # Let the main config do the real work.
 lit_config.load_config(config, "@LLD_SOURCE_DIR@/test/lit.cfg.py")
diff --git a/test/wasm/alias.ll b/test/wasm/alias.ll
index f88452e..d91f4b1 100644
--- a/test/wasm/alias.ll
+++ b/test/wasm/alias.ll
@@ -1,5 +1,5 @@
 ; RUN: llc -filetype=obj -o %t.o %s
-; RUN: wasm-ld %t.o -o %t.wasm
+; RUN: wasm-ld --export=start_alias %t.o -o %t.wasm
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
 target triple = "wasm32-unknown-unknown"
diff --git a/test/wasm/archive-export.ll b/test/wasm/archive-export.ll
index fc70ec7..37256ce 100644
--- a/test/wasm/archive-export.ll
+++ b/test/wasm/archive-export.ll
@@ -5,9 +5,9 @@
 RUN: llc -filetype=obj %S/Inputs/archive2.ll -o %t.a2.o
 RUN: rm -f %t.a
 RUN: llvm-ar rcs %t.a %t.a1.o %t.a2.o
-RUN: wasm-ld --export=archive2_symbol -o %t.wasm %t.a %t.o
+RUN: wasm-ld --export-dynamic --export=archive2_symbol -o %t.wasm %t.a %t.o
 RUN: obj2yaml %t.wasm | FileCheck %s
-RUN: wasm-ld -o %t.wasm %t.a %t.o
+RUN: wasm-ld --export-dynamic -o %t.wasm %t.a %t.o
 RUN: obj2yaml %t.wasm | FileCheck %s -check-prefix=NOEXPORT
 
 CHECK:         Exports:
diff --git a/test/wasm/call-indirect.ll b/test/wasm/call-indirect.ll
index f5dc220..1b9e172 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 -o %t.wasm %t2.o %t.o
+; RUN: wasm-ld --export-dynamic -o %t.wasm %t2.o %t.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
 ; bitcode generated from the following C code:
diff --git a/test/wasm/comdats.ll b/test/wasm/comdats.ll
index d0bec4c..9baea22 100644
--- a/test/wasm/comdats.ll
+++ b/test/wasm/comdats.ll
@@ -1,7 +1,7 @@
 ; 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 -o %t.wasm %t.o %t1.o %t2.o
+; RUN: wasm-ld --export-dynamic -o %t.wasm %t.o %t1.o %t2.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
 target triple = "wasm32-unknown-unknown"
diff --git a/test/wasm/compress-relocs.ll b/test/wasm/compress-relocs.ll
index b137d5a..d14ea26 100644
--- a/test/wasm/compress-relocs.ll
+++ b/test/wasm/compress-relocs.ll
@@ -1,9 +1,11 @@
 ; 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: wasm-ld --export-dynamic -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: wasm-ld --export-dynamic -O2 -o %t-opt.wasm %t2.o %t.o
+; RUN: obj2yaml %t-opt.wasm | FileCheck %s
+; RUN: not wasm-ld --compress-relocations -o %t-compressed.wasm %t2.o %t.o 2>&1 | FileCheck %s -check-prefix=ERROR
+; RUN: wasm-ld --export-dynamic --strip-debug --compress-relocations -o %t-compressed.wasm %t2.o %t.o
 ; RUN: obj2yaml %t-compressed.wasm | FileCheck %s -check-prefix=COMPRESS
 
 target triple = "wasm32-unknown-unknown-wasm"
@@ -18,5 +20,7 @@
   ret void
 }
 
+; ERROR: wasm-ld: error: --compress-relocations is incompatible with output debug information. Please pass --strip-debug or --strip-all
+
 ; CHECK:    Body:            4100280284888080002100410028028088808000118080808000001A2000118180808000001A0B
 ; COMPRESS: Body:            41002802840821004100280280081100001A20001101001A0B
diff --git a/test/wasm/cxx-mangling.ll b/test/wasm/cxx-mangling.ll
index c7f15af..0ab4874 100644
--- a/test/wasm/cxx-mangling.ll
+++ b/test/wasm/cxx-mangling.ll
@@ -1,7 +1,7 @@
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: wasm-ld --demangle -o %t_demangle.wasm %t.o
+; RUN: wasm-ld --export=_Z3fooi --demangle -o %t_demangle.wasm %t.o
 ; RUN: obj2yaml %t_demangle.wasm | FileCheck %s
-; RUN: wasm-ld --no-demangle -o %t_nodemangle.wasm %t.o
+; RUN: wasm-ld --export=_Z3fooi --no-demangle -o %t_nodemangle.wasm %t.o
 ; RUN: obj2yaml %t_nodemangle.wasm | FileCheck %s
 
 target triple = "wasm32-unknown-unknown"
diff --git a/test/wasm/debug-removed-fn.ll b/test/wasm/debug-removed-fn.ll
new file mode 100644
index 0000000..8f5f650
--- /dev/null
+++ b/test/wasm/debug-removed-fn.ll
@@ -0,0 +1,44 @@
+; RUN: llc -filetype=obj < %s -o %t.o
+; RUN: wasm-ld %t.o --no-entry --export=foo -o %t.wasm
+; RUN: llvm-dwarfdump -debug-line %t.wasm | FileCheck %s
+
+; CHECK: Address
+; CHECK: 0x0000000000000005
+; CHECK: 0x0000000000000000
+
+; ModuleID = 't.bc'
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown-wasm"
+
+; Function Attrs: noinline nounwind optnone
+define hidden i32 @foo() #0 !dbg !7 {
+entry:
+  ret i32 42, !dbg !11
+}
+
+; Function Attrs: noinline nounwind optnone
+define hidden i32 @bar() #0 !dbg !12 {
+entry:
+  ret i32 6, !dbg !13
+}
+
+attributes #0 = { noinline nounwind optnone "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" }
+
+!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 337293)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+!1 = !DIFile(filename: "t.c", directory: "/d/y")
+!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 337293)"}
+!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, retainedNodes: !2)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !DILocation(line: 2, column: 3, scope: !7)
+!12 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 5, type: !8, isLocal: false, isDefinition: true, scopeLine: 5, isOptimized: false, unit: !0, retainedNodes: !2)
+!13 = !DILocation(line: 6, column: 3, scope: !12)
diff --git a/test/wasm/local-symbols.ll b/test/wasm/local-symbols.ll
index 5471466..6d1a324 100644
--- a/test/wasm/local-symbols.ll
+++ b/test/wasm/local-symbols.ll
@@ -1,5 +1,6 @@
+; Test that internal symbols can still be GC'd when with --export-dynamic.
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: wasm-ld -o %t.wasm %t.o
+; RUN: wasm-ld --export-dynamic -o %t.wasm %t.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
 target triple = "wasm32-unknown-unknown"
diff --git a/test/wasm/locals-duplicate.test b/test/wasm/locals-duplicate.test
index 3c67cdd..8da0b22 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 --no-entry -o %t.wasm %t1.o %t2.o
+; RUN: wasm-ld --export-dynamic --no-entry -o %t.wasm %t1.o %t2.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
 ; CHECK:      --- !WASM
diff --git a/test/wasm/lto/archive.ll b/test/wasm/lto/archive.ll
index 89fa840..ab067d8 100644
--- a/test/wasm/lto/archive.ll
+++ b/test/wasm/lto/archive.ll
@@ -2,7 +2,7 @@
 ; RUN: rm -f %t.a
 ; RUN: llvm-ar rcs %t.a %t1.o
 ; RUN: llvm-as %s -o %t2.o
-; RUN: wasm-ld %t2.o %t.a -o %t3
+; RUN: wasm-ld --export-dynamic %t2.o %t.a -o %t3
 ; RUN: obj2yaml %t3 | FileCheck %s
 
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
diff --git a/test/wasm/lto/signature-mismatch.ll b/test/wasm/lto/signature-mismatch.ll
new file mode 100644
index 0000000..4b6b3b8
--- /dev/null
+++ b/test/wasm/lto/signature-mismatch.ll
@@ -0,0 +1,19 @@
+; RUN: llc -filetype=obj -o %t.o %s
+; RUN: llvm-as %S/Inputs/archive.ll -o %t1.o
+; RUN: not wasm-ld --fatal-warnings %t.o %t1.o -o %t.wasm 2>&1 | FileCheck %s
+
+; Test that functions defined in bitcode correctly report signature
+; mistmaches with existing undefined sybmols in normal objects.
+
+target triple = "wasm32-unknown-unknown"
+
+; f is defined to take no argument in archive.ll which is compiled to bitcode
+declare void @f(i32);
+
+define void @_start() {
+  call void @f(i32 0)
+  ret void
+}
+
+; CHECK: >>> defined as (I32) -> void in {{.*}}signature-mismatch.ll.tmp1.o
+; CHECK: >>> defined as () -> void in lto.tmp
diff --git a/test/wasm/undefined-weak-call.ll b/test/wasm/undefined-weak-call.ll
index c13f5c1..920379e 100644
--- a/test/wasm/undefined-weak-call.ll
+++ b/test/wasm/undefined-weak-call.ll
@@ -1,5 +1,5 @@
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: wasm-ld --no-entry --print-gc-sections %t.o \
+; RUN: wasm-ld --entry=callWeakFuncs --print-gc-sections %t.o \
 ; RUN:     -o %t.wasm 2>&1 | FileCheck -check-prefix=CHECK-GC %s
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
diff --git a/test/wasm/visibility-hidden.ll b/test/wasm/visibility-hidden.ll
index f553c08..b4fe0b5 100644
--- a/test/wasm/visibility-hidden.ll
+++ b/test/wasm/visibility-hidden.ll
@@ -2,11 +2,17 @@
 ; RUN: llc -filetype=obj %S/Inputs/hidden.ll -o %t2.o
 ; RUN: rm -f %t2.a
 ; RUN: llvm-ar rcs %t2.a %t2.o
-; RUN: wasm-ld %t.o %t2.a -o %t.wasm
+
+; Test that symbols with hidden visitiblity are not export, even with
+; --export-dynamic
+; RUN: wasm-ld --export-dynamic %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.
+; Test that symbols with default visitiblity are not exported without
+; --export-dynamic
+; RUN: wasm-ld %t.o %t2.a -o %t.nodef.wasm
+; RUN: obj2yaml %t.nodef.wasm | FileCheck %s -check-prefix=NO-DEFAULT
+
 
 target triple = "wasm32-unknown-unknown"
 
@@ -53,3 +59,20 @@
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           5
 ; CHECK-NEXT:   - Type:
+
+
+; NO-DEFAULT:        - Type:            EXPORT
+; NO-DEFAULT-NEXT:     Exports:
+; NO-DEFAULT-NEXT:       - Name:            memory
+; NO-DEFAULT-NEXT:         Kind:            MEMORY
+; NO-DEFAULT-NEXT:         Index:           0
+; NO-DEFAULT-NEXT:       - Name:            __heap_base
+; NO-DEFAULT-NEXT:         Kind:            GLOBAL
+; NO-DEFAULT-NEXT:         Index:           1
+; NO-DEFAULT-NEXT:       - Name:            __data_end
+; NO-DEFAULT-NEXT:         Kind:            GLOBAL
+; NO-DEFAULT-NEXT:         Index:           2
+; NO-DEFAULT-NEXT:       - Name:            _start
+; NO-DEFAULT-NEXT:         Kind:            FUNCTION
+; NO-DEFAULT-NEXT:         Index:           3
+; NO-DEFAULT-NEXT:   - Type:
diff --git a/test/wasm/weak-alias-overide.ll b/test/wasm/weak-alias-overide.ll
index a6a37f2..496900b 100644
--- a/test/wasm/weak-alias-overide.ll
+++ b/test/wasm/weak-alias-overide.ll
@@ -1,6 +1,6 @@
 ; RUN: llc -filetype=obj -o %t.o %s
 ; RUN: llc -filetype=obj %S/Inputs/weak-alias.ll -o %t2.o
-; RUN: wasm-ld %t.o %t2.o -o %t.wasm
+; RUN: wasm-ld --export-dynamic %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
diff --git a/test/wasm/weak-alias.ll b/test/wasm/weak-alias.ll
index 227906a..49f2885 100644
--- a/test/wasm/weak-alias.ll
+++ b/test/wasm/weak-alias.ll
@@ -1,6 +1,6 @@
 ; RUN: llc -filetype=obj -o %t.o %s
 ; RUN: llc -filetype=obj %S/Inputs/weak-alias.ll -o %t2.o
-; RUN: wasm-ld %t.o %t2.o -o %t.wasm
+; RUN: wasm-ld --export-dynamic %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
diff --git a/test/wasm/weak-symbols.ll b/test/wasm/weak-symbols.ll
index bd45de3..7af4323 100644
--- a/test/wasm/weak-symbols.ll
+++ b/test/wasm/weak-symbols.ll
@@ -1,7 +1,7 @@
 ; 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 -o %t.wasm %t.o %t1.o %t2.o
+; RUN: wasm-ld --export-dynamic -o %t.wasm %t.o %t1.o %t2.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
 target triple = "wasm32-unknown-unknown"
@@ -29,7 +29,7 @@
 ; CHECK-NEXT:         ReturnType:      I32
 ; CHECK-NEXT:         ParamTypes:
 ; CHECK-NEXT:   - Type:            FUNCTION
-; CHECK-NEXT:     FunctionTypes:   [ 0, 0, 1, 1, 1, 1 ]
+; CHECK-NEXT:     FunctionTypes:   [ 0, 0, 1, 1, 1 ]
 ; CHECK-NEXT:   - Type:            TABLE
 ; CHECK-NEXT:     Tables:
 ; CHECK-NEXT:       - ElemType:        ANYFUNC
@@ -59,7 +59,7 @@
 ; CHECK-NEXT:         Mutable:         false
 ; CHECK-NEXT:         InitExpr:
 ; CHECK-NEXT:           Opcode:          I32_CONST
-; CHECK-NEXT:           Value:           1032
+; CHECK-NEXT:           Value:           1028
 ; CHECK-NEXT:       - Index:           3
 ; CHECK-NEXT:         Type:            I32
 ; CHECK-NEXT:         Mutable:         false
@@ -91,7 +91,7 @@
 ; CHECK-NEXT:         Index:           3
 ; CHECK-NEXT:       - Name:            exportWeak2
 ; CHECK-NEXT:         Kind:            FUNCTION
-; CHECK-NEXT:         Index:           5
+; CHECK-NEXT:         Index:           4
 ; CHECK-NEXT:   - Type:            ELEM
 ; CHECK-NEXT:     Segments:
 ; CHECK-NEXT:       - Offset:
@@ -114,9 +114,6 @@
 ; CHECK-NEXT:         Body:            4181808080000B
 ; CHECK-NEXT:       - Index:           4
 ; CHECK-NEXT:         Locals:
-; CHECK-NEXT:         Body:            41020B
-; CHECK-NEXT:       - Index:           5
-; CHECK-NEXT:         Locals:
 ; CHECK-NEXT:         Body:            4181808080000B
 ; CHECK-NEXT:   - Type:            DATA
 ; CHECK-NEXT:     Segments:
@@ -125,7 +122,7 @@
 ; CHECK-NEXT:         Offset:
 ; CHECK-NEXT:           Opcode:          I32_CONST
 ; CHECK-NEXT:           Value:           1024
-; CHECK-NEXT:         Content:         '0100000002000000'
+; CHECK-NEXT:         Content:         '01000000'
 ; CHECK-NEXT:   - Type:            CUSTOM
 ; CHECK-NEXT:     Name:            name
 ; CHECK-NEXT:     FunctionNames:
@@ -138,7 +135,5 @@
 ; CHECK-NEXT:       - Index:           3
 ; CHECK-NEXT:         Name:            exportWeak1
 ; CHECK-NEXT:       - Index:           4
-; CHECK-NEXT:         Name:            weakFn
-; CHECK-NEXT:       - Index:           5
 ; CHECK-NEXT:         Name:            exportWeak2
 ; CHECK-NEXT: ...
diff --git a/test/wasm/weak-undefined.ll b/test/wasm/weak-undefined.ll
index 048b91b..2f2451a 100644
--- a/test/wasm/weak-undefined.ll
+++ b/test/wasm/weak-undefined.ll
@@ -22,7 +22,8 @@
 
 define void @_start() #0 {
 entry:
-    %call = call i32* @get_address_of_global_var()
+    %call1 = call i32* @get_address_of_global_var()
+    %call2 = call i8* @get_address_of_foo()
     ret void
 }
 
@@ -81,12 +82,6 @@
 ; CHECK-NEXT:       - Name:            __data_end
 ; CHECK-NEXT:         Kind:            GLOBAL
 ; CHECK-NEXT:         Index:           2
-; CHECK-NEXT:       - Name:            get_address_of_foo
-; CHECK-NEXT:         Kind:            FUNCTION
-; CHECK-NEXT:         Index:           1
-; CHECK-NEXT:       - Name:            get_address_of_global_var
-; CHECK-NEXT:         Kind:            FUNCTION
-; CHECK-NEXT:         Index:           2
 ; CHECK-NEXT:       - Name:            _start
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           3
@@ -103,5 +98,5 @@
 ; CHECK-NEXT:         Body:            4180808080000B
 ; CHECK-NEXT:       - Index:           3
 ; CHECK-NEXT:         Locals:
-; CHECK-NEXT:         Body:            1082808080001A0B
+; CHECK-NEXT:         Body:            1082808080001A1081808080001A0B
 ; CHECK-NEXT: ...
diff --git a/tools/lld/lld.cpp b/tools/lld/lld.cpp
index 4a8e3f7..c749d45 100644
--- a/tools/lld/lld.cpp
+++ b/tools/lld/lld.cpp
@@ -138,7 +138,7 @@
     return !wasm::link(Args, canExitEarly());
   default:
     die("lld is a generic driver.\n"
-        "Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-lld"
+        "Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-ld"
         " (WebAssembly) instead");
   }
 }
diff --git a/wasm/Config.h b/wasm/Config.h
index 76a7805..233ac9f 100644
--- a/wasm/Config.h
+++ b/wasm/Config.h
@@ -20,10 +20,11 @@
 
 struct Configuration {
   bool AllowUndefined;
-  bool CompressRelocTargets;
+  bool CompressRelocations;
   bool Demangle;
   bool DisableVerify;
   bool ExportAll;
+  bool ExportDynamic;
   bool ExportTable;
   bool GcSections;
   bool ImportMemory;
diff --git a/wasm/Driver.cpp b/wasm/Driver.cpp
index 3c542ed..bbf9bcd 100644
--- a/wasm/Driver.cpp
+++ b/wasm/Driver.cpp
@@ -24,6 +24,7 @@
 #include "llvm/Object/Wasm.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Process.h"
 #include "llvm/Support/TargetSelect.h"
@@ -78,7 +79,7 @@
 
 bool lld::wasm::link(ArrayRef<const char *> Args, bool CanExitEarly,
                      raw_ostream &Error) {
-  errorHandler().LogName = sys::path::filename(Args[0]);
+  errorHandler().LogName = args::getFilenameWithoutExe(Args[0]);
   errorHandler().ErrorOS = &Error;
   errorHandler().ColorDiagnostics = Error.has_colors();
   errorHandler().ErrorLimitExceededMsg =
@@ -186,8 +187,7 @@
 
 // Returns slices of MB by parsing MB as an archive file.
 // Each slice consists of a member file in the archive.
-std::vector<MemoryBufferRef> static getArchiveMembers(
-    MemoryBufferRef MB) {
+std::vector<MemoryBufferRef> static getArchiveMembers(MemoryBufferRef MB) {
   std::unique_ptr<Archive> File =
       CHECK(Archive::create(MB),
             MB.getBufferIdentifier() + ": failed to parse archive");
@@ -205,8 +205,8 @@
     V.push_back(MBRef);
   }
   if (Err)
-    fatal(MB.getBufferIdentifier() + ": Archive::children failed: " +
-          toString(std::move(Err)));
+    fatal(MB.getBufferIdentifier() +
+          ": Archive::children failed: " + toString(std::move(Err)));
 
   // Take ownership of memory buffers created for members of thin archives.
   for (std::unique_ptr<MemoryBuffer> &MB : File->takeThinBuffers())
@@ -350,7 +350,8 @@
 
   // Handle --help
   if (Args.hasArg(OPT_help)) {
-    Parser.PrintHelp(outs(), ArgsArr[0], "LLVM Linker", false);
+    std::string Usage = formatv("{0} [options] file...", ArgsArr[0]).str();
+    Parser.PrintHelp(outs(), Usage.c_str(), "LLVM Linker", false);
     return;
   }
 
@@ -374,6 +375,8 @@
   Config->DisableVerify = Args.hasArg(OPT_disable_verify);
   Config->Entry = getEntry(Args, Args.hasArg(OPT_relocatable) ? "" : "_start");
   Config->ExportAll = Args.hasArg(OPT_export_all);
+  Config->ExportDynamic = Args.hasFlag(OPT_export_dynamic,
+      OPT_no_export_dynamic, false);
   Config->ExportTable = Args.hasArg(OPT_export_table);
   errorHandler().FatalWarnings =
       Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false);
@@ -395,6 +398,7 @@
   Config->SearchPaths = args::getStrings(Args, OPT_L);
   Config->StripAll = Args.hasArg(OPT_strip_all);
   Config->StripDebug = Args.hasArg(OPT_strip_debug);
+  Config->CompressRelocations = Args.hasArg(OPT_compress_relocations);
   Config->StackFirst = Args.hasArg(OPT_stack_first);
   Config->ThinLTOCacheDir = Args.getLastArgValue(OPT_thinlto_cache_dir);
   Config->ThinLTOCachePolicy = CHECK(
@@ -410,7 +414,9 @@
   Config->ZStackSize =
       args::getZOptionValue(Args, OPT_z, "stack-size", WasmPageSize);
 
-  Config->CompressRelocTargets = Config->Optimize > 0 && !Config->Relocatable;
+  if (!Config->StripDebug && !Config->StripAll && Config->CompressRelocations)
+    error("--compress-relocations is incompatible with output debug"
+          " information. Please pass --strip-debug or --strip-all");
 
   if (Config->LTOO > 3)
     error("invalid optimization level for LTO: " + Twine(Config->LTOO));
@@ -438,6 +444,8 @@
       error("entry point specified for relocatable output file");
     if (Config->GcSections)
       error("-r and --gc-sections may not be used together");
+    if (Config->CompressRelocations)
+      error("-r -and --compress-relocations may not be used together");
     if (Args.hasArg(OPT_undefined))
       error("-r -and --undefined may not be used together");
   }
@@ -452,7 +460,7 @@
     InputGlobal *StackPointer = make<InputGlobal>(Global, nullptr);
     StackPointer->Live = true;
 
-    static WasmSignature NullSignature = {{}, WASM_TYPE_NORESULT};
+    static WasmSignature NullSignature = {{}, {}};
 
     // Add synthetic symbols before any others
     WasmSym::CallCtors = Symtab->addSyntheticFunction(
@@ -467,6 +475,11 @@
     WasmSym::DsoHandle = Symtab->addSyntheticDataSymbol(
         "__dso_handle", WASM_SYMBOL_VISIBILITY_HIDDEN);
     WasmSym::DataEnd = Symtab->addSyntheticDataSymbol("__data_end", 0);
+
+    // These two synthetic symbols exist purely for the embedder so we always
+    // want to export them.
+    WasmSym::HeapBase->ForceExport = true;
+    WasmSym::DataEnd->ForceExport = true;
   }
 
   createFiles(Args);
@@ -501,7 +514,9 @@
 
     if (!Config->Entry.empty()) {
       EntrySym = handleUndefined(Config->Entry);
-      if (!EntrySym)
+      if (EntrySym && EntrySym->isDefined())
+        EntrySym->ForceExport = true;
+      else
         error("entry symbol not defined (pass --no-entry to supress): " +
               Config->Entry);
     }
diff --git a/wasm/InputChunks.cpp b/wasm/InputChunks.cpp
index fcefac7..87aac5a 100644
--- a/wasm/InputChunks.cpp
+++ b/wasm/InputChunks.cpp
@@ -25,7 +25,9 @@
 
 static StringRef ReloctTypeToString(uint8_t RelocType) {
   switch (RelocType) {
-#define WASM_RELOC(NAME, REL) case REL: return #NAME;
+#define WASM_RELOC(NAME, REL)                                                  \
+  case REL:                                                                    \
+    return #NAME;
 #include "llvm/BinaryFormat/WasmRelocs.def"
 #undef WASM_RELOC
   }
@@ -43,16 +45,6 @@
   return File->getWasmObj()->linkingData().Comdats[Index];
 }
 
-void InputChunk::copyRelocations(const WasmSection &Section) {
-  if (Section.Relocations.empty())
-    return;
-  size_t Start = getInputSectionOffset();
-  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;
@@ -228,7 +220,7 @@
 // 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)
+  if (!File || !Config->CompressRelocations)
     return;
 
   LLVM_DEBUG(dbgs() << "calculateSize: " << getName() << "\n");
@@ -242,7 +234,7 @@
   uint32_t End = Start + Function->Size;
 
   uint32_t LastRelocEnd = Start + FunctionSizeLength;
-  for (WasmRelocation &Rel : Relocations) {
+  for (const WasmRelocation &Rel : Relocations) {
     LLVM_DEBUG(dbgs() << "  region: " << (Rel.Offset - LastRelocEnd) << "\n");
     CompressedFuncSize += Rel.Offset - LastRelocEnd;
     CompressedFuncSize += getRelocWidth(Rel, File->calcNewValue(Rel));
@@ -263,11 +255,12 @@
 // 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)
+  if (!File || !Config->CompressRelocations)
     return InputChunk::writeTo(Buf);
 
   Buf += OutputOffset;
-  uint8_t *Orig = Buf; (void)Orig;
+  uint8_t *Orig = Buf;
+  (void)Orig;
 
   const uint8_t *SecStart = File->CodeSection->Content.data();
   const uint8_t *FuncStart = SecStart + getInputSectionOffset();
diff --git a/wasm/InputChunks.h b/wasm/InputChunks.h
index 526e298..f899d69 100644
--- a/wasm/InputChunks.h
+++ b/wasm/InputChunks.h
@@ -49,17 +49,18 @@
   Kind kind() const { return SectionKind; }
 
   virtual uint32_t getSize() const { return data().size(); }
-
-  void copyRelocations(const WasmSection &Section);
+  virtual uint32_t getInputSize() const { return getSize(); };
 
   virtual void writeTo(uint8_t *SectionStart) const;
 
   ArrayRef<WasmRelocation> getRelocations() const { return Relocations; }
+  void setRelocations(ArrayRef<WasmRelocation> Rs) { Relocations = Rs; }
 
   virtual StringRef getName() const = 0;
   virtual StringRef getDebugName() const = 0;
   virtual uint32_t getComdat() const = 0;
   StringRef getComdatName() const;
+  virtual uint32_t getInputSectionOffset() const = 0;
 
   size_t NumRelocations() const { return Relocations.size(); }
   void writeRelocations(llvm::raw_ostream &OS) const;
@@ -77,14 +78,12 @@
       : File(F), Live(!Config->GcSections), SectionKind(K) {}
   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;
+  ArrayRef<WasmRelocation> Relocations;
   Kind SectionKind;
 };
 
@@ -107,15 +106,15 @@
   StringRef getName() const override { return Segment.Data.Name; }
   StringRef getDebugName() const override { return StringRef(); }
   uint32_t getComdat() const override { return Segment.Data.Comdat; }
+  uint32_t getInputSectionOffset() const override {
+    return Segment.SectionOffset;
+  }
 
   const OutputSegment *OutputSeg = nullptr;
   int32_t OutputSegmentOffset = 0;
 
 protected:
   ArrayRef<uint8_t> data() const override { return Segment.Data.Content; }
-  uint32_t getInputSectionOffset() const override {
-    return Segment.SectionOffset;
-  }
 
   const WasmSegment &Segment;
 };
@@ -139,15 +138,19 @@
   uint32_t getFunctionInputOffset() const { return getInputSectionOffset(); }
   uint32_t getFunctionCodeOffset() const { return Function->CodeOffset; }
   uint32_t getSize() const override {
-    if (Config->CompressRelocTargets && File) {
+    if (Config->CompressRelocations && File) {
       assert(CompressedSize);
       return CompressedSize;
     }
     return data().size();
   }
+  uint32_t getInputSize() const override { return Function->Size; }
   uint32_t getFunctionIndex() const { return FunctionIndex.getValue(); }
   bool hasFunctionIndex() const { return FunctionIndex.hasValue(); }
   void setFunctionIndex(uint32_t Index);
+  uint32_t getInputSectionOffset() const override {
+    return Function->CodeSectionOffset;
+  }
   uint32_t getTableIndex() const { return TableIndex.getValue(); }
   bool hasTableIndex() const { return TableIndex.hasValue(); }
   void setTableIndex(uint32_t Index);
@@ -162,17 +165,11 @@
 
 protected:
   ArrayRef<uint8_t> data() const override {
-    assert(!Config->CompressRelocTargets);
+    assert(!Config->CompressRelocations);
     return File->CodeSection->Content.slice(getInputSectionOffset(),
                                             Function->Size);
   }
 
-  uint32_t getInputSize() const override { return Function->Size; }
-
-  uint32_t getInputSectionOffset() const override {
-    return Function->CodeSectionOffset;
-  }
-
   const WasmFunction *Function;
   llvm::Optional<uint32_t> FunctionIndex;
   llvm::Optional<uint32_t> TableIndex;
diff --git a/wasm/InputFiles.cpp b/wasm/InputFiles.cpp
index 53a24c3..cda72c1 100644
--- a/wasm/InputFiles.cpp
+++ b/wasm/InputFiles.cpp
@@ -94,16 +94,17 @@
   switch (Reloc.Type) {
   case R_WEBASSEMBLY_TABLE_INDEX_I32:
   case R_WEBASSEMBLY_TABLE_INDEX_SLEB: {
-    const WasmSymbol& Sym = WasmObj->syms()[Reloc.Index];
+    const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index];
     return TableEntries[Sym.Info.ElementIndex];
   }
   case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
   case R_WEBASSEMBLY_MEMORY_ADDR_I32:
   case R_WEBASSEMBLY_MEMORY_ADDR_LEB: {
-    const WasmSymbol& Sym = WasmObj->syms()[Reloc.Index];
+    const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index];
     if (Sym.isUndefined())
       return 0;
-    const WasmSegment& Segment = WasmObj->dataSegments()[Sym.Info.DataRef.Segment];
+    const WasmSegment &Segment =
+        WasmObj->dataSegments()[Sym.Info.DataRef.Segment];
     return Segment.Data.Offset.Value.Int32 + Sym.Info.DataRef.Offset +
            Reloc.Addend;
   }
@@ -119,7 +120,7 @@
     return Reloc.Index;
   case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
   case R_WEBASSEMBLY_GLOBAL_INDEX_LEB: {
-    const WasmSymbol& Sym = WasmObj->syms()[Reloc.Index];
+    const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index];
     return Sym.Info.ElementIndex;
   }
   default:
@@ -148,8 +149,9 @@
     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;
+      if (Sym->isLive())
+        return Sym->Function->OutputOffset +
+               Sym->Function->getFunctionCodeOffset() + Reloc.Addend;
     }
     return 0;
   case R_WEBASSEMBLY_SECTION_OFFSET_I32:
@@ -159,6 +161,37 @@
   }
 }
 
+template <class T>
+static void setRelocs(const std::vector<T *> &Chunks,
+                      const WasmSection *Section) {
+  if (!Section)
+    return;
+
+  ArrayRef<WasmRelocation> Relocs = Section->Relocations;
+  assert(std::is_sorted(Relocs.begin(), Relocs.end(),
+                        [](const WasmRelocation &R1, const WasmRelocation &R2) {
+                          return R1.Offset < R2.Offset;
+                        }));
+  assert(std::is_sorted(
+      Chunks.begin(), Chunks.end(), [](InputChunk *C1, InputChunk *C2) {
+        return C1->getInputSectionOffset() < C2->getInputSectionOffset();
+      }));
+
+  auto RelocsNext = Relocs.begin();
+  auto RelocsEnd = Relocs.end();
+  auto RelocLess = [](const WasmRelocation &R, uint32_t Val) {
+    return R.Offset < Val;
+  };
+  for (InputChunk *C : Chunks) {
+    auto RelocsStart = std::lower_bound(RelocsNext, RelocsEnd,
+                                        C->getInputSectionOffset(), RelocLess);
+    RelocsNext = std::lower_bound(
+        RelocsStart, RelocsEnd, C->getInputSectionOffset() + C->getInputSize(),
+        RelocLess);
+    C->setRelocations(ArrayRef<WasmRelocation>(RelocsStart, RelocsNext));
+  }
+}
+
 void ObjFile::parse() {
   // Parse a memory buffer as a wasm file.
   LLVM_DEBUG(dbgs() << "Parsing object: " << toString(this) << "\n");
@@ -200,7 +233,7 @@
       DataSection = &Section;
     } else if (Section.Type == WASM_SEC_CUSTOM) {
       CustomSections.emplace_back(make<InputSection>(Section, this));
-      CustomSections.back()->copyRelocations(Section);
+      CustomSections.back()->setRelocations(Section.Relocations);
       CustomSectionsByIndex[SectionIndex] = CustomSections.back();
     }
     SectionIndex++;
@@ -215,11 +248,9 @@
     UsedComdats[I] = Symtab->addComdat(Comdats[I]);
 
   // Populate `Segments`.
-  for (const WasmSegment &S : WasmObj->dataSegments()) {
-    InputSegment *Seg = make<InputSegment>(S, this);
-    Seg->copyRelocations(*DataSection);
-    Segments.emplace_back(Seg);
-  }
+  for (const WasmSegment &S : WasmObj->dataSegments())
+    Segments.emplace_back(make<InputSegment>(S, this));
+  setRelocs(Segments, DataSection);
 
   // Populate `Functions`.
   ArrayRef<WasmFunction> Funcs = WasmObj->functions();
@@ -227,12 +258,10 @@
   ArrayRef<WasmSignature> Types = WasmObj->types();
   Functions.reserve(Funcs.size());
 
-  for (size_t I = 0, E = Funcs.size(); I != E; ++I) {
-    InputFunction *F =
-        make<InputFunction>(Types[FuncTypes[I]], &Funcs[I], this);
-    F->copyRelocations(*CodeSection);
-    Functions.emplace_back(F);
-  }
+  for (size_t I = 0, E = Funcs.size(); I != E; ++I)
+    Functions.emplace_back(
+        make<InputFunction>(Types[FuncTypes[I]], &Funcs[I], this));
+  setRelocs(Functions, CodeSection);
 
   // Populate `Globals`.
   for (const WasmGlobal &G : WasmObj->globals())
diff --git a/wasm/LTO.cpp b/wasm/LTO.cpp
index f15551d..933607a 100644
--- a/wasm/LTO.cpp
+++ b/wasm/LTO.cpp
@@ -72,10 +72,11 @@
 BitcodeCompiler::~BitcodeCompiler() = default;
 
 static void undefine(Symbol *S) {
-  if (isa<DefinedFunction>(S))
-    replaceSymbol<UndefinedFunction>(S, S->getName(), 0);
+  if (auto F = dyn_cast<DefinedFunction>(S))
+    replaceSymbol<UndefinedFunction>(F, F->getName(), 0, F->getFile(),
+                                     F->FunctionType);
   else if (isa<DefinedData>(S))
-    replaceSymbol<UndefinedData>(S, S->getName(), 0);
+    replaceSymbol<UndefinedData>(S, S->getName(), 0, S->getFile());
   else
     llvm_unreachable("unexpected symbol kind");
 }
diff --git a/wasm/Options.td b/wasm/Options.td
index 43588a8..c9636ca 100644
--- a/wasm/Options.td
+++ b/wasm/Options.td
@@ -23,10 +23,17 @@
 def color_diagnostics_eq: J<"color-diagnostics=">,
   HelpText<"Use colors in diagnostics; one of 'always', 'never', 'auto'">;
 
+def compress_relocations: F<"compress-relocations">,
+  HelpText<"Compress the relocation targets in the code section.">;
+
 defm demangle: B<"demangle",
     "Demangle symbol names",
     "Do not demangle symbol names">;
 
+defm export_dynamic: B<"export-dynamic",
+    "Put symbols in the dynamic symbol table",
+    "Do not put symbols in the dynamic symbol table (default)">;
+
 def entry: S<"entry">, MetaVarName<"<entry>">,
   HelpText<"Name of entry point symbol">;
 
@@ -137,12 +144,13 @@
     "Do not force load of all members in a static library (default)">;
 
 // Aliases
-def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>;
-def alias_entry_entry: J<"entry=">, Alias<entry>;
-def alias_initial_memory_i: Flag<["-"], "i">, Alias<initial_memory>;
-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>;
+def: JoinedOrSeparate<["-"], "e">, Alias<entry>;
+def: J<"entry=">, Alias<entry>;
+def: Flag<["-"], "E">, Alias<export_dynamic>, HelpText<"Alias for --export-dynamic">;
+def: Flag<["-"], "i">, Alias<initial_memory>;
+def: Flag<["-"], "m">, Alias<max_memory>;
+def: Flag<["-"], "r">, Alias<relocatable>;
+def: JoinedOrSeparate<["-"], "u">, Alias<undefined>;
 
 // LTO-related options.
 def lto_O: J<"lto-O">, MetaVarName<"<opt-level>">,
diff --git a/wasm/OutputSections.h b/wasm/OutputSections.h
index 189d650..46916f3 100644
--- a/wasm/OutputSections.h
+++ b/wasm/OutputSections.h
@@ -113,7 +113,7 @@
   size_t BodySize = 0;
 };
 
-// Represents a custom section in the output file.  Wasm custom sections are 
+// 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
diff --git a/wasm/SymbolTable.cpp b/wasm/SymbolTable.cpp
index 2a4249e..d1e9c05 100644
--- a/wasm/SymbolTable.cpp
+++ b/wasm/SymbolTable.cpp
@@ -201,7 +201,9 @@
 Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags,
                                         InputFile *File,
                                         InputFunction *Function) {
-  LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << "\n");
+  LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << " ["
+                    << (Function ? toString(Function->Signature) : "none")
+                    << "]\n");
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name, File);
@@ -214,8 +216,16 @@
   if (Function)
     checkFunctionType(S, File, &Function->Signature);
 
-  if (shouldReplace(S, File, Flags))
-    replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function);
+  if (shouldReplace(S, File, Flags)) {
+    // If the new defined function doesn't have signture (i.e. bitcode
+    // functions) but the old symbols does then preserve the old signature
+    const WasmSignature *OldSig = nullptr;
+    if (auto* F = dyn_cast<FunctionSymbol>(S))
+      OldSig = F->FunctionType;
+    auto NewSym = replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function);
+    if (!NewSym->FunctionType)
+      NewSym->FunctionType = OldSig;
+  }
   return S;
 }
 
@@ -263,7 +273,8 @@
 Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags,
                                           InputFile *File,
                                           const WasmSignature *Sig) {
-  LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << "\n");
+  LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name <<
+             " [" << (Sig ? toString(*Sig) : "none") << "]\n");
 
   Symbol *S;
   bool WasInserted;
diff --git a/wasm/Symbols.cpp b/wasm/Symbols.cpp
index a11081c..035c7f2 100644
--- a/wasm/Symbols.cpp
+++ b/wasm/Symbols.cpp
@@ -105,7 +105,10 @@
   if (ForceExport || Config->ExportAll)
     return true;
 
-  return !isHidden();
+  if (Config->ExportDynamic && !isHidden())
+    return true;
+
+  return false;
 }
 
 uint32_t FunctionSymbol::getFunctionIndex() const {
diff --git a/wasm/Writer.cpp b/wasm/Writer.cpp
index 23a7b5d..3d44bce 100644
--- a/wasm/Writer.cpp
+++ b/wasm/Writer.cpp
@@ -586,9 +586,9 @@
 //  - 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.
+// 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() {
   createOutputSegments();
 
@@ -991,7 +991,7 @@
     const WasmLinkingData &L = File->getWasmObj()->linkingData();
     for (const WasmInitFunc &F : L.InitFunctions) {
       FunctionSymbol *Sym = File->getFunctionSymbol(F.Symbol);
-      if (*Sym->FunctionType != WasmSignature{{}, WASM_TYPE_NORESULT})
+      if (*Sym->FunctionType != WasmSignature{{}, {}})
         error("invalid signature for init func: " + toString(*Sym));
       InitFunctions.emplace_back(WasmInitEntry{Sym, F.Priority});
     }
diff --git a/wasm/WriterUtils.cpp b/wasm/WriterUtils.cpp
index 201529e..a92da74 100644
--- a/wasm/WriterUtils.cpp
+++ b/wasm/WriterUtils.cpp
@@ -19,15 +19,15 @@
 using namespace llvm::wasm;
 using namespace lld::wasm;
 
-static const char *valueTypeToString(uint8_t Type) {
+static const char *valueTypeToString(ValType Type) {
   switch (Type) {
-  case WASM_TYPE_I32:
+  case wasm::ValType::I32:
     return "i32";
-  case WASM_TYPE_I64:
+  case wasm::ValType::I64:
     return "i64";
-  case WASM_TYPE_F32:
+  case wasm::ValType::F32:
     return "f32";
-  case WASM_TYPE_F64:
+  case wasm::ValType::F64:
     return "f64";
   default:
     llvm_unreachable("invalid value type");
@@ -73,21 +73,20 @@
   support::endian::write(OS, Number, support::little);
 }
 
-void wasm::writeValueType(raw_ostream &OS, uint8_t Type, const Twine &Msg) {
-  writeU8(OS, Type, Msg + "[type: " + valueTypeToString(Type) + "]");
+void wasm::writeValueType(raw_ostream &OS, ValType Type, const Twine &Msg) {
+  writeU8(OS, static_cast<uint8_t>(Type),
+          Msg + "[type: " + valueTypeToString(Type) + "]");
 }
 
 void wasm::writeSig(raw_ostream &OS, const WasmSignature &Sig) {
   writeU8(OS, WASM_TYPE_FUNC, "signature type");
-  writeUleb128(OS, Sig.ParamTypes.size(), "param Count");
-  for (uint8_t ParamType : Sig.ParamTypes) {
+  writeUleb128(OS, Sig.Params.size(), "param Count");
+  for (ValType ParamType : Sig.Params) {
     writeValueType(OS, ParamType, "param type");
   }
-  if (Sig.ReturnType == WASM_TYPE_NORESULT) {
-    writeUleb128(OS, 0, "result Count");
-  } else {
-    writeUleb128(OS, 1, "result Count");
-    writeValueType(OS, Sig.ReturnType, "result type");
+  writeUleb128(OS, Sig.Returns.size(), "result Count");
+  if (Sig.Returns.size()) {
+    writeValueType(OS, Sig.Returns[0], "result type");
   }
 }
 
@@ -117,7 +116,8 @@
 }
 
 void wasm::writeGlobalType(raw_ostream &OS, const WasmGlobalType &Type) {
-  writeValueType(OS, Type.Type, "global type");
+  // TODO: Update WasmGlobalType to use ValType and remove this cast.
+  writeValueType(OS, ValType(Type.Type), "global type");
   writeU8(OS, Type.Mutable, "global mutable");
 }
 
@@ -185,6 +185,8 @@
     return "F32";
   case ValType::F64:
     return "F64";
+  case ValType::V128:
+    return "V128";
   case ValType::EXCEPT_REF:
     return "except_ref";
   }
@@ -193,16 +195,16 @@
 
 std::string lld::toString(const WasmSignature &Sig) {
   SmallString<128> S("(");
-  for (uint32_t Type : Sig.ParamTypes) {
+  for (ValType Type : Sig.Params) {
     if (S.size() != 1)
       S += ", ";
-    S += toString(static_cast<ValType>(Type));
+    S += toString(Type);
   }
   S += ") -> ";
-  if (Sig.ReturnType == WASM_TYPE_NORESULT)
+  if (Sig.Returns.size() == 0)
     S += "void";
   else
-    S += toString(static_cast<ValType>(Sig.ReturnType));
+    S += toString(Sig.Returns[0]);
   return S.str();
 }
 
diff --git a/wasm/WriterUtils.h b/wasm/WriterUtils.h
index 74d727b..6f11cca 100644
--- a/wasm/WriterUtils.h
+++ b/wasm/WriterUtils.h
@@ -35,7 +35,8 @@
 
 void writeU32(raw_ostream &OS, uint32_t Number, const Twine &Msg);
 
-void writeValueType(raw_ostream &OS, uint8_t Type, const Twine &Msg);
+void writeValueType(raw_ostream &OS, llvm::wasm::ValType Type,
+                    const Twine &Msg);
 
 void writeSig(raw_ostream &OS, const llvm::wasm::WasmSignature &Sig);