Commit 38aed5af8b

Andrew Kelley <superjoe30@gmail.com>
2018-02-07 23:38:02
update embedded LLD to 6.0.0rc2
1 parent aa043a6
deps/lld/ELF/Arch/X86.cpp
@@ -21,7 +21,7 @@ using namespace lld;
 using namespace lld::elf;
 
 namespace {
-class X86 final : public TargetInfo {
+class X86 : public TargetInfo {
 public:
   X86();
   RelExpr getRelExpr(RelType Type, const Symbol &S,
@@ -399,7 +399,145 @@ void X86::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
   memcpy(Loc - 2, Inst, sizeof(Inst));
 }
 
+namespace {
+class RetpolinePic : public X86 {
+public:
+  RetpolinePic();
+  void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
+  void writePltHeader(uint8_t *Buf) const override;
+  void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
+                int32_t Index, unsigned RelOff) const override;
+};
+
+class RetpolineNoPic : public X86 {
+public:
+  RetpolineNoPic();
+  void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
+  void writePltHeader(uint8_t *Buf) const override;
+  void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
+                int32_t Index, unsigned RelOff) const override;
+};
+} // namespace
+
+RetpolinePic::RetpolinePic() {
+  PltHeaderSize = 48;
+  PltEntrySize = 32;
+}
+
+void RetpolinePic::writeGotPlt(uint8_t *Buf, const Symbol &S) const {
+  write32le(Buf, S.getPltVA() + 17);
+}
+
+void RetpolinePic::writePltHeader(uint8_t *Buf) const {
+  const uint8_t Insn[] = {
+      0xff, 0xb3, 0,    0,    0,    0,          // 0:    pushl GOTPLT+4(%ebx)
+      0x50,                                     // 6:    pushl %eax
+      0x8b, 0x83, 0,    0,    0,    0,          // 7:    mov GOTPLT+8(%ebx), %eax
+      0xe8, 0x0e, 0x00, 0x00, 0x00,             // d:    call next
+      0xf3, 0x90,                               // 12: loop: pause
+      0x0f, 0xae, 0xe8,                         // 14:   lfence
+      0xeb, 0xf9,                               // 17:   jmp loop
+      0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 19:   int3; .align 16
+      0x89, 0x0c, 0x24,                         // 20: next: mov %ecx, (%esp)
+      0x8b, 0x4c, 0x24, 0x04,                   // 23:   mov 0x4(%esp), %ecx
+      0x89, 0x44, 0x24, 0x04,                   // 27:   mov %eax ,0x4(%esp)
+      0x89, 0xc8,                               // 2b:   mov %ecx, %eax
+      0x59,                                     // 2d:   pop %ecx
+      0xc3,                                     // 2e:   ret
+  };
+  memcpy(Buf, Insn, sizeof(Insn));
+
+  uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize();
+  uint32_t GotPlt = InX::GotPlt->getVA() - Ebx;
+  write32le(Buf + 2, GotPlt + 4);
+  write32le(Buf + 9, GotPlt + 8);
+}
+
+void RetpolinePic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
+                            uint64_t PltEntryAddr, int32_t Index,
+                            unsigned RelOff) const {
+  const uint8_t Insn[] = {
+      0x50,                   // pushl %eax
+      0x8b, 0x83, 0, 0, 0, 0, // mov foo@GOT(%ebx), %eax
+      0xe8, 0,    0, 0, 0,    // call plt+0x20
+      0xe9, 0,    0, 0, 0,    // jmp plt+0x12
+      0x68, 0,    0, 0, 0,    // pushl $reloc_offset
+      0xe9, 0,    0, 0, 0,    // jmp plt+0
+  };
+  memcpy(Buf, Insn, sizeof(Insn));
+
+  uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize();
+  write32le(Buf + 3, GotPltEntryAddr - Ebx);
+  write32le(Buf + 8, -Index * PltEntrySize - PltHeaderSize - 12 + 32);
+  write32le(Buf + 13, -Index * PltEntrySize - PltHeaderSize - 17 + 18);
+  write32le(Buf + 18, RelOff);
+  write32le(Buf + 23, -Index * PltEntrySize - PltHeaderSize - 27);
+}
+
+RetpolineNoPic::RetpolineNoPic() {
+  PltHeaderSize = 48;
+  PltEntrySize = 32;
+}
+
+void RetpolineNoPic::writeGotPlt(uint8_t *Buf, const Symbol &S) const {
+  write32le(Buf, S.getPltVA() + 16);
+}
+
+void RetpolineNoPic::writePltHeader(uint8_t *Buf) const {
+  const uint8_t PltData[] = {
+      0xff, 0x35, 0,    0,    0,    0, // 0:    pushl GOTPLT+4
+      0x50,                            // 6:    pushl %eax
+      0xa1, 0,    0,    0,    0,       // 7:    mov GOTPLT+8, %eax
+      0xe8, 0x0f, 0x00, 0x00, 0x00,    // c:    call next
+      0xf3, 0x90,                      // 11: loop: pause
+      0x0f, 0xae, 0xe8,                // 13:   lfence
+      0xeb, 0xf9,                      // 16:   jmp loop
+      0xcc, 0xcc, 0xcc, 0xcc, 0xcc,    // 18:   int3
+      0xcc, 0xcc, 0xcc,                // 1f:   int3; .align 16
+      0x89, 0x0c, 0x24,                // 20: next: mov %ecx, (%esp)
+      0x8b, 0x4c, 0x24, 0x04,          // 23:   mov 0x4(%esp), %ecx
+      0x89, 0x44, 0x24, 0x04,          // 27:   mov %eax ,0x4(%esp)
+      0x89, 0xc8,                      // 2b:   mov %ecx, %eax
+      0x59,                            // 2d:   pop %ecx
+      0xc3,                            // 2e:   ret
+  };
+  memcpy(Buf, PltData, sizeof(PltData));
+
+  uint32_t GotPlt = InX::GotPlt->getVA();
+  write32le(Buf + 2, GotPlt + 4);
+  write32le(Buf + 8, GotPlt + 8);
+}
+
+void RetpolineNoPic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
+                              uint64_t PltEntryAddr, int32_t Index,
+                              unsigned RelOff) const {
+  const uint8_t Insn[] = {
+      0x50,             // 0:  pushl %eax
+      0xa1, 0, 0, 0, 0, // 1:  mov foo_in_GOT, %eax
+      0xe8, 0, 0, 0, 0, // 6:  call plt+0x20
+      0xe9, 0, 0, 0, 0, // b:  jmp plt+0x11
+      0x68, 0, 0, 0, 0, // 10: pushl $reloc_offset
+      0xe9, 0, 0, 0, 0, // 15: jmp plt+0
+  };
+  memcpy(Buf, Insn, sizeof(Insn));
+
+  write32le(Buf + 2, GotPltEntryAddr);
+  write32le(Buf + 7, -Index * PltEntrySize - PltHeaderSize - 11 + 32);
+  write32le(Buf + 12, -Index * PltEntrySize - PltHeaderSize - 16 + 17);
+  write32le(Buf + 17, RelOff);
+  write32le(Buf + 22, -Index * PltEntrySize - PltHeaderSize - 26);
+}
+
 TargetInfo *elf::getX86TargetInfo() {
-  static X86 Target;
-  return &Target;
+  if (Config->ZRetpolineplt) {
+    if (Config->Pic) {
+      static RetpolinePic T;
+      return &T;
+    }
+    static RetpolineNoPic T;
+    return &T;
+  }
+
+  static X86 T;
+  return &T;
 }
deps/lld/ELF/Arch/X86_64.cpp
@@ -23,7 +23,7 @@ using namespace lld;
 using namespace lld::elf;
 
 namespace {
-template <class ELFT> class X86_64 final : public TargetInfo {
+template <class ELFT> class X86_64 : public TargetInfo {
 public:
   X86_64();
   RelExpr getRelExpr(RelType Type, const Symbol &S,
@@ -460,12 +460,125 @@ void X86_64<ELFT>::relaxGot(uint8_t *Loc, uint64_t Val) const {
   write32le(Loc - 1, Val + 1);
 }
 
-TargetInfo *elf::getX32TargetInfo() {
-  static X86_64<ELF32LE> Target;
-  return &Target;
+namespace {
+template <class ELFT> class Retpoline : public X86_64<ELFT> {
+public:
+  Retpoline();
+  void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
+  void writePltHeader(uint8_t *Buf) const override;
+  void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
+                int32_t Index, unsigned RelOff) const override;
+};
+
+template <class ELFT> class RetpolineZNow : public X86_64<ELFT> {
+public:
+  RetpolineZNow();
+  void writeGotPlt(uint8_t *Buf, const Symbol &S) const override {}
+  void writePltHeader(uint8_t *Buf) const override;
+  void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
+                int32_t Index, unsigned RelOff) const override;
+};
+} // namespace
+
+template <class ELFT> Retpoline<ELFT>::Retpoline() {
+  TargetInfo::PltHeaderSize = 48;
+  TargetInfo::PltEntrySize = 32;
+}
+
+template <class ELFT>
+void Retpoline<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &S) const {
+  write32le(Buf, S.getPltVA() + 17);
+}
+
+template <class ELFT> void Retpoline<ELFT>::writePltHeader(uint8_t *Buf) const {
+  const uint8_t Insn[] = {
+      0xff, 0x35, 0,    0,    0,    0,          // 0:    pushq GOTPLT+8(%rip)
+      0x4c, 0x8b, 0x1d, 0,    0,    0,    0,    // 6:    mov GOTPLT+16(%rip), %r11
+      0xe8, 0x0e, 0x00, 0x00, 0x00,             // d:    callq next
+      0xf3, 0x90,                               // 12: loop: pause
+      0x0f, 0xae, 0xe8,                         // 14:   lfence
+      0xeb, 0xf9,                               // 17:   jmp loop
+      0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 19:   int3; .align 16
+      0x4c, 0x89, 0x1c, 0x24,                   // 20: next: mov %r11, (%rsp)
+      0xc3,                                     // 24:   ret
+  };
+  memcpy(Buf, Insn, sizeof(Insn));
+
+  uint64_t GotPlt = InX::GotPlt->getVA();
+  uint64_t Plt = InX::Plt->getVA();
+  write32le(Buf + 2, GotPlt - Plt - 6 + 8);
+  write32le(Buf + 9, GotPlt - Plt - 13 + 16);
+}
+
+template <class ELFT>
+void Retpoline<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
+                               uint64_t PltEntryAddr, int32_t Index,
+                               unsigned RelOff) const {
+  const uint8_t Insn[] = {
+      0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // 0:  mov foo@GOTPLT(%rip), %r11
+      0xe8, 0,    0,    0, 0,       // 7:  callq plt+0x20
+      0xe9, 0,    0,    0, 0,       // c:  jmp plt+0x12
+      0x68, 0,    0,    0, 0,       // 11: pushq <relocation index>
+      0xe9, 0,    0,    0, 0,       // 16: jmp plt+0
+  };
+  memcpy(Buf, Insn, sizeof(Insn));
+
+  uint64_t Off = TargetInfo::PltHeaderSize + TargetInfo::PltEntrySize * Index;
+
+  write32le(Buf + 3, GotPltEntryAddr - PltEntryAddr - 7);
+  write32le(Buf + 8, -Off - 12 + 32);
+  write32le(Buf + 13, -Off - 17 + 18);
+  write32le(Buf + 18, Index);
+  write32le(Buf + 23, -Off - 27);
+}
+
+template <class ELFT> RetpolineZNow<ELFT>::RetpolineZNow() {
+  TargetInfo::PltHeaderSize = 32;
+  TargetInfo::PltEntrySize = 16;
+}
+
+template <class ELFT>
+void RetpolineZNow<ELFT>::writePltHeader(uint8_t *Buf) const {
+  const uint8_t Insn[] = {
+      0xe8, 0x0b, 0x00, 0x00, 0x00, // 0:    call next
+      0xf3, 0x90,                   // 5:  loop: pause
+      0x0f, 0xae, 0xe8,             // 7:    lfence
+      0xeb, 0xf9,                   // a:    jmp loop
+      0xcc, 0xcc, 0xcc, 0xcc,       // c:    int3; .align 16
+      0x4c, 0x89, 0x1c, 0x24,       // 10: next: mov %r11, (%rsp)
+      0xc3,                         // 14:   ret
+  };
+  memcpy(Buf, Insn, sizeof(Insn));
 }
 
-TargetInfo *elf::getX86_64TargetInfo() {
-  static X86_64<ELF64LE> Target;
-  return &Target;
+template <class ELFT>
+void RetpolineZNow<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
+                                   uint64_t PltEntryAddr, int32_t Index,
+                                   unsigned RelOff) const {
+  const uint8_t Insn[] = {
+      0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // mov foo@GOTPLT(%rip), %r11
+      0xe9, 0,    0,    0, 0,       // jmp plt+0
+  };
+  memcpy(Buf, Insn, sizeof(Insn));
+
+  write32le(Buf + 3, GotPltEntryAddr - PltEntryAddr - 7);
+  write32le(Buf + 8,
+            -Index * TargetInfo::PltEntrySize - TargetInfo::PltHeaderSize - 12);
 }
+
+template <class ELFT> TargetInfo *getTargetInfo() {
+  if (Config->ZRetpolineplt) {
+    if (Config->ZNow) {
+      static RetpolineZNow<ELFT> T;
+      return &T;
+    }
+    static Retpoline<ELFT> T;
+    return &T;
+  }
+
+  static X86_64<ELFT> T;
+  return &T;
+}
+
+TargetInfo *elf::getX32TargetInfo() { return getTargetInfo<ELF32LE>(); }
+TargetInfo *elf::getX86_64TargetInfo() { return getTargetInfo<ELF64LE>(); }
deps/lld/ELF/AArch64ErrataFix.cpp
@@ -47,6 +47,7 @@
 using namespace llvm;
 using namespace llvm::ELF;
 using namespace llvm::object;
+using namespace llvm::support;
 using namespace llvm::support::endian;
 
 using namespace lld;
@@ -357,7 +358,7 @@ static uint64_t scanCortexA53Errata843419(InputSection *IS, uint64_t &Off,
 
   uint64_t PatchOff = 0;
   const uint8_t *Buf = IS->Data.begin();
-  const uint32_t *InstBuf = reinterpret_cast<const uint32_t *>(Buf + Off);
+  const ulittle32_t *InstBuf = reinterpret_cast<const ulittle32_t *>(Buf + Off);
   uint32_t Instr1 = *InstBuf++;
   uint32_t Instr2 = *InstBuf++;
   uint32_t Instr3 = *InstBuf++;
deps/lld/ELF/Config.h
@@ -159,6 +159,7 @@ struct Configuration {
   bool ZRelro;
   bool ZRodynamic;
   bool ZText;
+  bool ZRetpolineplt;
   bool ExitEarly;
   bool ZWxneeded;
   DiscardPolicy Discard;
deps/lld/ELF/Driver.cpp
@@ -638,7 +638,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
   Config->Optimize = args::getInteger(Args, OPT_O, 1);
   Config->OrphanHandling = getOrphanHandling(Args);
   Config->OutputFile = Args.getLastArgValue(OPT_o);
-  Config->Pie = Args.hasFlag(OPT_pie, OPT_nopie, false);
+  Config->Pie = Args.hasFlag(OPT_pie, OPT_no_pie, false);
   Config->PrintGcSections =
       Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
   Config->Rpath = getRpath(Args);
@@ -674,6 +674,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
   Config->ZNow = hasZOption(Args, "now");
   Config->ZOrigin = hasZOption(Args, "origin");
   Config->ZRelro = !hasZOption(Args, "norelro");
+  Config->ZRetpolineplt = hasZOption(Args, "retpolineplt");
   Config->ZRodynamic = hasZOption(Args, "rodynamic");
   Config->ZStackSize = args::getZOptionValue(Args, OPT_z, "stack-size", 0);
   Config->ZText = !hasZOption(Args, "notext");
deps/lld/ELF/InputFiles.cpp
@@ -856,6 +856,14 @@ template <class ELFT> void SharedFile<ELFT>::parseRest() {
       continue;
     }
 
+    if (Config->EMachine == EM_MIPS) {
+      // FIXME: 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.
+      if (Versym && VersymIndex == VER_NDX_LOCAL && Name == "_gp_disp")
+        continue;
+    }
+
     const Elf_Verdef *Ver = nullptr;
     if (VersymIndex != VER_NDX_GLOBAL) {
       if (VersymIndex >= Verdefs.size() || VersymIndex == VER_NDX_LOCAL) {
deps/lld/ELF/LinkerScript.cpp
@@ -589,8 +589,12 @@ void LinkerScript::output(InputSection *S) {
 
   // If there is a memory region associated with this input section, then
   // place the section in that region and update the region index.
+  if (Ctx->LMARegion)
+    Ctx->LMARegion->CurPos += Pos - Before;
+  // FIXME: should we also produce overflow errors for LMARegion?
+
   if (Ctx->MemRegion) {
-    uint64_t &CurOffset = Ctx->MemRegionOffset[Ctx->MemRegion];
+    uint64_t &CurOffset = Ctx->MemRegion->CurPos;
     CurOffset += Pos - Before;
     uint64_t CurSize = CurOffset - Ctx->MemRegion->Origin;
     if (CurSize > Ctx->MemRegion->Length) {
@@ -608,13 +612,6 @@ void LinkerScript::switchTo(OutputSection *Sec) {
 
   Ctx->OutSec = Sec;
   Ctx->OutSec->Addr = advance(0, Ctx->OutSec->Alignment);
-
-  // If neither AT nor AT> is specified for an allocatable section, the linker
-  // will set the LMA such that the difference between VMA and LMA for the
-  // section is the same as the preceding output section in the same region
-  // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html
-  if (Ctx->LMAOffset)
-    Ctx->OutSec->LMAOffset = Ctx->LMAOffset();
 }
 
 // This function searches for a memory region to place the given output
@@ -624,9 +621,8 @@ MemoryRegion *LinkerScript::findMemoryRegion(OutputSection *Sec) {
   // If a memory region name was specified in the output section command,
   // then try to find that region first.
   if (!Sec->MemoryRegionName.empty()) {
-    auto It = MemoryRegions.find(Sec->MemoryRegionName);
-    if (It != MemoryRegions.end())
-      return It->second;
+    if (MemoryRegion *M = MemoryRegions.lookup(Sec->MemoryRegionName))
+      return M;
     error("memory region '" + Sec->MemoryRegionName + "' not declared");
     return nullptr;
   }
@@ -659,16 +655,25 @@ void LinkerScript::assignOffsets(OutputSection *Sec) {
     setDot(Sec->AddrExpr, Sec->Location, false);
 
   Ctx->MemRegion = Sec->MemRegion;
+  Ctx->LMARegion = Sec->LMARegion;
   if (Ctx->MemRegion)
-    Dot = Ctx->MemRegionOffset[Ctx->MemRegion];
-
-  if (Sec->LMAExpr) {
-    uint64_t D = Dot;
-    Ctx->LMAOffset = [=] { return Sec->LMAExpr().getValue() - D; };
-  }
+    Dot = Ctx->MemRegion->CurPos;
 
   switchTo(Sec);
 
+  if (Sec->LMAExpr)
+    Ctx->LMAOffset = Sec->LMAExpr().getValue() - Dot;
+
+  if (MemoryRegion *MR = Sec->LMARegion)
+    Ctx->LMAOffset = MR->CurPos - Dot;
+
+  // If neither AT nor AT> is specified for an allocatable section, the linker
+  // will set the LMA such that the difference between VMA and LMA for the
+  // section is the same as the preceding output section in the same region
+  // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html
+  if (PhdrEntry *L = Ctx->OutSec->PtLoad)
+    L->LMAOffset = Ctx->LMAOffset;
+
   // The Size previously denoted how many InputSections had been added to this
   // section, and was used for sorting SHF_LINK_ORDER sections. Reset it to
   // compute the actual size value.
@@ -689,7 +694,9 @@ void LinkerScript::assignOffsets(OutputSection *Sec) {
       Cmd->Offset = Dot - Ctx->OutSec->Addr;
       Dot += Cmd->Size;
       if (Ctx->MemRegion)
-        Ctx->MemRegionOffset[Ctx->MemRegion] += Cmd->Size;
+        Ctx->MemRegion->CurPos += Cmd->Size;
+      if (Ctx->LMARegion)
+        Ctx->LMARegion->CurPos += Cmd->Size;
       Ctx->OutSec->Size = Dot - Ctx->OutSec->Addr;
       continue;
     }
@@ -788,6 +795,12 @@ void LinkerScript::adjustSectionsAfterSorting() {
     if (auto *Sec = dyn_cast<OutputSection>(Base)) {
       if (!Sec->Live)
         continue;
+      if (!Sec->LMARegionName.empty()) {
+        if (MemoryRegion *M = MemoryRegions.lookup(Sec->LMARegionName))
+          Sec->LMARegion = M;
+        else
+          error("memory region '" + Sec->LMARegionName + "' not declared");
+      }
       Sec->MemRegion = findMemoryRegion(Sec);
       // Handle align (e.g. ".foo : ALIGN(16) { ... }").
       if (Sec->AlignExpr)
@@ -878,8 +891,8 @@ void LinkerScript::allocateHeaders(std::vector<PhdrEntry *> &Phdrs) {
 
 LinkerScript::AddressState::AddressState() {
   for (auto &MRI : Script->MemoryRegions) {
-    const MemoryRegion *MR = MRI.second;
-    MemRegionOffset[MR] = MR->Origin;
+    MemoryRegion *MR = MRI.second;
+    MR->CurPos = MR->Origin;
   }
 }
 
deps/lld/ELF/LinkerScript.h
@@ -118,11 +118,17 @@ enum class ConstraintKind { NoConstraint, ReadOnly, ReadWrite };
 // target memory. Instances of the struct are created by parsing the
 // MEMORY command.
 struct MemoryRegion {
+  MemoryRegion(StringRef Name, uint64_t Origin, uint64_t Length, uint32_t Flags,
+               uint32_t NegFlags)
+      : Name(Name), Origin(Origin), Length(Length), Flags(Flags),
+        NegFlags(NegFlags) {}
+
   std::string Name;
   uint64_t Origin;
   uint64_t Length;
   uint32_t Flags;
   uint32_t NegFlags;
+  uint64_t CurPos = 0;
 };
 
 // This struct represents one section match pattern in SECTIONS() command.
@@ -200,8 +206,8 @@ class LinkerScript final {
     uint64_t ThreadBssOffset = 0;
     OutputSection *OutSec = nullptr;
     MemoryRegion *MemRegion = nullptr;
-    llvm::DenseMap<const MemoryRegion *, uint64_t> MemRegionOffset;
-    std::function<uint64_t()> LMAOffset;
+    MemoryRegion *LMARegion = nullptr;
+    uint64_t LMAOffset = 0;
   };
 
   llvm::DenseMap<StringRef, OutputSection *> NameToOutputSection;
deps/lld/ELF/Options.td
@@ -202,6 +202,8 @@ def no_gnu_unique: F<"no-gnu-unique">,
 def no_merge_exidx_entries: F<"no-merge-exidx-entries">,
   HelpText<"Disable merging .ARM.exidx entries">;
 
+def no_pie: F<"no-pie">, HelpText<"Do not create a position independent executable">;
+
 def no_threads: F<"no-threads">,
   HelpText<"Do not run the linker multi-threaded">;
 
@@ -211,8 +213,6 @@ def no_whole_archive: F<"no-whole-archive">,
 def noinhibit_exec: F<"noinhibit-exec">,
   HelpText<"Retain the executable output file whenever it is still usable">;
 
-def nopie: F<"nopie">, HelpText<"Do not create a position independent executable">;
-
 def no_omagic: Flag<["--"], "no-omagic">, MetaVarName<"<magic>">,
   HelpText<"Do not set the text data sections to be writable">;
 
deps/lld/ELF/OutputSections.h
@@ -49,7 +49,7 @@ public:
 
   static bool classof(const BaseCommand *C);
 
-  uint64_t getLMA() const { return Addr + LMAOffset; }
+  uint64_t getLMA() const { return PtLoad ? Addr + PtLoad->LMAOffset : Addr; }
   template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr);
 
   unsigned SectionIndex;
@@ -78,7 +78,6 @@ public:
 
   // The following fields correspond to Elf_Shdr members.
   uint64_t Offset = 0;
-  uint64_t LMAOffset = 0;
   uint64_t Addr = 0;
   uint32_t ShName = 0;
 
@@ -89,6 +88,7 @@ public:
 
   // The following members are normally only used in linker scripts.
   MemoryRegion *MemRegion = nullptr;
+  MemoryRegion *LMARegion = nullptr;
   Expr AddrExpr;
   Expr AlignExpr;
   Expr LMAExpr;
@@ -99,6 +99,7 @@ public:
   ConstraintKind Constraint = ConstraintKind::NoConstraint;
   std::string Location;
   std::string MemoryRegionName;
+  std::string LMARegionName;
   bool Noload = false;
 
   template <class ELFT> void finalize();
deps/lld/ELF/ScriptParser.cpp
@@ -709,6 +709,14 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) {
   if (consume(">"))
     Cmd->MemoryRegionName = next();
 
+  if (consume("AT")) {
+    expect(">");
+    Cmd->LMARegionName = next();
+  }
+
+  if (Cmd->LMAExpr && !Cmd->LMARegionName.empty())
+    error("section can't have both LMA and a load region");
+
   Cmd->Phdrs = readOutputSectionPhdrs();
 
   if (consume("="))
@@ -922,7 +930,10 @@ ByteCommand *ScriptParser::readByteCommand(StringRef Tok) {
 
 StringRef ScriptParser::readParenLiteral() {
   expect("(");
+  bool Orig = InExpr;
+  InExpr = false;
   StringRef Tok = next();
+  InExpr = Orig;
   expect(")");
   return Tok;
 }
@@ -1282,8 +1293,8 @@ void ScriptParser::readMemory() {
     // Add the memory region to the region map.
     if (Script->MemoryRegions.count(Name))
       setError("region '" + Name + "' already defined");
-    MemoryRegion *MR = make<MemoryRegion>();
-    *MR = {Name, Origin, Length, Flags, NegFlags};
+    MemoryRegion *MR =
+        make<MemoryRegion>(Name, Origin, Length, Flags, NegFlags);
     Script->MemoryRegions[Name] = MR;
   }
 }
deps/lld/ELF/SymbolTable.cpp
@@ -491,12 +491,13 @@ void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> &File,
   if (WasInserted || ((S->isUndefined() || S->isLazy()) &&
                       S->getVisibility() == STV_DEFAULT)) {
     uint8_t Binding = S->Binding;
+    bool WasUndefined = S->isUndefined();
     replaceSymbol<SharedSymbol>(S, File, Name, Sym.getBinding(), Sym.st_other,
                                 Sym.getType(), Sym.st_value, Sym.st_size,
                                 Alignment, VerdefIndex);
     if (!WasInserted) {
       S->Binding = Binding;
-      if (!S->isWeak() && !Config->GcSections)
+      if (!S->isWeak() && !Config->GcSections && WasUndefined)
         File.IsNeeded = true;
     }
   }
deps/lld/ELF/Writer.cpp
@@ -822,6 +822,8 @@ void PhdrEntry::add(OutputSection *Sec) {
   p_align = std::max(p_align, Sec->Alignment);
   if (p_type == PT_LOAD)
     Sec->PtLoad = this;
+  if (Sec->LMAExpr)
+    ASectionHasLMA = true;
 }
 
 // The beginning and the ending of .rel[a].plt section are marked
@@ -1626,7 +1628,9 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() {
     // different flags or is loaded at a discontiguous address using AT linker
     // script command.
     uint64_t NewFlags = computeFlags(Sec->getPhdrFlags());
-    if (Sec->LMAExpr || Flags != NewFlags) {
+    if ((Sec->LMAExpr && Load->ASectionHasLMA) ||
+        Sec->MemRegion != Load->FirstSec->MemRegion || Flags != NewFlags) {
+
       Load = AddHdr(PT_LOAD, NewFlags);
       Flags = NewFlags;
     }
deps/lld/ELF/Writer.h
@@ -44,6 +44,13 @@ struct PhdrEntry {
   OutputSection *FirstSec = nullptr;
   OutputSection *LastSec = nullptr;
   bool HasLMA = false;
+
+  // True if one of the sections in this program header has a LMA specified via
+  // linker script: AT(addr). We never allow 2 or more sections with LMA in the
+  // same program header.
+  bool ASectionHasLMA = false;
+
+  uint64_t LMAOffset = 0;
 };
 
 void addReservedSymbols();
deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
@@ -621,6 +621,7 @@ void ArchHandler_x86_64::applyFixupFinal(
     // Fall into llvm_unreachable().
     break;
   }
+  llvm_unreachable("invalid x86_64 Reference Kind");
 }
 
 void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref,
deps/lld/test/ELF/Inputs/as-needed-lazy.s
@@ -0,0 +1,3 @@
+.global foo
+foo:
+  nop
deps/lld/test/ELF/Inputs/mips-gp-dips-corrupt-ver.s
@@ -0,0 +1,14 @@
+# Source file for mips-gp-dips-corrupt-ver.so
+#
+# % cat gpdisp.ver
+# LLD_1.0.0 { global: foo; };
+#
+# % as mips-gp-dips-corrupt-ver.s -o mips-gp-dips-corrupt-ver.o
+# % ld -shared -o mips-gp-dips-corrupt-ver.so \
+#      --version-script gpdisp.ver mips-gp-dips-corrupt-ver.o
+
+  .global foo
+  .text
+foo:
+  lui    $t0, %hi(_gp_disp)
+  addi   $t0, $t0, %lo(_gp_disp)
deps/lld/test/ELF/Inputs/mips-gp-dips-corrupt-ver.so
Binary file
deps/lld/test/ELF/linkerscript/at-self-reference.s
@@ -0,0 +1,63 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: echo "SECTIONS { \
+# RUN:  . = 0x1000; \
+# RUN:  .aaa : AT(ADDR(.aaa)) { *(.aaa) } \
+# RUN:  .bbb : AT(ADDR(.bbb)) { *(.bbb) } \
+# RUN: }" > %t.script
+# RUN: ld.lld %t --script %t.script -o %t2
+# RUN: llvm-readobj -program-headers %t2 | FileCheck %s
+
+# CHECK:      ProgramHeaders [
+# CHECK-NEXT:  ProgramHeader {
+# CHECK-NEXT:    Type: PT_LOAD (0x1)
+# CHECK-NEXT:    Offset: 0x1000
+# CHECK-NEXT:    VirtualAddress: 0x1000
+# CHECK-NEXT:    PhysicalAddress: 0x1000
+# CHECK-NEXT:    FileSize: 3
+# CHECK-NEXT:    MemSize: 3
+# CHECK-NEXT:    Flags [ (0x5)
+# CHECK-NEXT:      PF_R (0x4)
+# CHECK-NEXT:      PF_X (0x1)
+# CHECK-NEXT:    ]
+# CHECK-NEXT:    Alignment: 4096
+# CHECK-NEXT:  }
+# CHECK-NEXT:  ProgramHeader {
+# CHECK-NEXT:    Type: PT_LOAD (0x1)
+# CHECK-NEXT:    Offset: 0x1008
+# CHECK-NEXT:    VirtualAddress: 0x1008
+# CHECK-NEXT:    PhysicalAddress: 0x1008
+# CHECK-NEXT:    FileSize: 9
+# CHECK-NEXT:    MemSize: 9
+# CHECK-NEXT:    Flags [ (0x5)
+# CHECK-NEXT:      PF_R (0x4)
+# CHECK-NEXT:      PF_X (0x1)
+# CHECK-NEXT:    ]
+# CHECK-NEXT:    Alignment: 4096
+# CHECK-NEXT:  }
+# CHECK-NEXT:  ProgramHeader {
+# CHECK-NEXT:    Type: PT_GNU_STACK (0x6474E551)
+# CHECK-NEXT:    Offset: 0x0
+# CHECK-NEXT:    VirtualAddress: 0x0
+# CHECK-NEXT:    PhysicalAddress: 0x0
+# CHECK-NEXT:    FileSize: 0
+# CHECK-NEXT:    MemSize: 0
+# CHECK-NEXT:    Flags [ (0x6)
+# CHECK-NEXT:      PF_R (0x4)
+# CHECK-NEXT:      PF_W (0x2)
+# CHECK-NEXT:    ]
+# CHECK-NEXT:    Alignment: 0
+# CHECK-NEXT:  }
+# CHECK-NEXT:]
+
+.global _start
+_start:
+ nop
+
+
+.section .aaa, "a"
+.asciz "aa"
+
+.section .bbb, "a"
+.align 8
+.quad 0
deps/lld/test/ELF/linkerscript/at2.s
@@ -0,0 +1,81 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: echo "MEMORY {                                   \
+# RUN:   AX (ax)   : ORIGIN = 0x2000, LENGTH = 0x100   \
+# RUN:   AW (aw)   : ORIGIN = 0x3000, LENGTH = 0x100   \
+# RUN:   FLASH (ax) : ORIGIN = 0x6000, LENGTH = 0x100   \
+# RUN:   RAM (aw)   : ORIGIN = 0x7000, LENGTH = 0x100 } \
+# RUN: SECTIONS {                                       \
+# RUN:  .foo1 : { *(.foo1) } > AX AT>FLASH             \
+# RUN:  .foo2 : { *(.foo2) } > AX                      \
+# RUN:  .bar1 : { *(.bar1) } > AW AT> RAM              \
+# RUN:  .bar2 : { *(.bar2) } > AW AT > RAM             \
+# RUN:  .bar3 : { *(.bar3) } > AW AT >RAM              \
+# RUN: }" > %t.script
+# RUN: ld.lld %t --script %t.script -o %t2
+# RUN: llvm-readobj -program-headers %t2 | FileCheck %s
+# RUN: llvm-objdump -section-headers %t2 | FileCheck %s --check-prefix=SECTIONS
+
+# CHECK:      ProgramHeaders [
+# CHECK-NEXT:   ProgramHeader {
+# CHECK-NEXT:     Type: PT_LOAD
+# CHECK-NEXT:     Offset: 0x1000
+# CHECK-NEXT:     VirtualAddress: 0x2000
+# CHECK-NEXT:     PhysicalAddress: 0x6000
+# CHECK-NEXT:     FileSize: 16
+# CHECK-NEXT:     MemSize: 16
+# CHECK-NEXT:     Flags [
+# CHECK-NEXT:       PF_R
+# CHECK-NEXT:       PF_X
+# CHECK-NEXT:     ]
+# CHECK-NEXT:     Alignment:
+# CHECK-NEXT:   }
+# CHECK-NEXT:   ProgramHeader {
+# CHECK-NEXT:     Type: PT_LOAD
+# CHECK-NEXT:     Offset: 0x2000
+# CHECK-NEXT:     VirtualAddress: 0x3000
+# CHECK-NEXT:     PhysicalAddress: 0x7000
+# CHECK-NEXT:     FileSize: 24
+# CHECK-NEXT:     MemSize: 24
+# CHECK-NEXT:     Flags [
+# CHECK-NEXT:       PF_R
+# CHECK-NEXT:       PF_W
+# CHECK-NEXT:     ]
+# CHECK-NEXT:     Alignment: 4096
+# CHECK-NEXT:   }
+
+# SECTIONS:      Sections:
+# SECTIONS-NEXT: Idx Name          Size      Address
+# SECTIONS-NEXT:   0               00000000 0000000000000000
+# SECTIONS-NEXT:   1 .foo1         00000008 0000000000002000
+# SECTIONS-NEXT:   2 .foo2         00000008 0000000000002008
+# SECTIONS-NEXT:   3 .text         00000000 0000000000002010
+# SECTIONS-NEXT:   4 .bar1         00000008 0000000000003000
+# SECTIONS-NEXT:   5 .bar2         00000008 0000000000003008
+# SECTIONS-NEXT:   6 .bar3         00000008 0000000000003010
+  
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: echo "MEMORY {                                            \
+# RUN:   FLASH (ax) : ORIGIN = 0x2000, LENGTH = 0x100            \
+# RUN:   RAM (aw)   : ORIGIN = 0x5000, LENGTH = 0x100 }          \
+# RUN: SECTIONS {                                                \
+# RUN:  .foo1 : AT(0x500) { *(.foo1) } > FLASH AT>FLASH          \
+# RUN: }" > %t2.script
+# RUN: not ld.lld %t --script %t2.script -o %t2 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=ERR
+# ERR: error: section can't have both LMA and a load region
+
+.section .foo1, "ax"
+.quad 0
+
+.section .foo2, "ax"
+.quad 0
+
+.section .bar1, "aw"
+.quad 0
+
+.section .bar2, "aw"
+.quad 0
+
+.section .bar3, "aw"
+.quad 0
deps/lld/test/ELF/linkerscript/at3.s
@@ -0,0 +1,38 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: echo "MEMORY {                                  \
+# RUN:   FOO   (ax) : ORIGIN = 0x1000, LENGTH = 0x100  \
+# RUN:   BAR   (ax) : ORIGIN = 0x2000, LENGTH = 0x100  \
+# RUN:   ZED   (ax) : ORIGIN = 0x3000, LENGTH = 0x100  \
+# RUN:   FLASH (ax) : ORIGIN = 0x6000, LENGTH = 0x200  \
+# RUN: }                                               \
+# RUN: SECTIONS {                                      \
+# RUN:  .foo1 : { *(.foo1) }            > FOO AT>FLASH \
+# RUN:  .foo2 : { *(.foo2) BYTE(0x42) } > BAR AT>FLASH \
+# RUN:  .foo3 : { *(.foo3) }            > ZED AT>FLASH \
+# RUN: }" > %t.script
+# RUN: ld.lld %t.o --script %t.script -o %t
+# RUN: llvm-readelf -sections -program-headers %t | FileCheck %s
+
+# CHECK: .foo1             PROGBITS        0000000000001000 001000
+# CHECK: .foo2             PROGBITS        0000000000002000 002000
+# CHECK: .foo3             PROGBITS        0000000000003000 003000
+
+# CHECK: Program Headers:
+# CHECK-NOT: LOAD
+
+# CHECK:      Type  Offset   VirtAddr           PhysAddr
+# CHECK-NEXT: LOAD  0x001000 0x0000000000001000 0x0000000000006000
+# CHECK-NEXT: LOAD  0x002000 0x0000000000002000 0x0000000000006008
+# CHECK-NEXT: LOAD  0x003000 0x0000000000003000 0x0000000000006011
+
+# CHECK-NOT: LOAD
+
+.section .foo1, "a"
+.quad 0
+
+.section .foo2, "ax"
+.quad 0
+
+.section .foo3, "ax"
+.quad 0
deps/lld/test/ELF/linkerscript/merge-header-load.s
@@ -0,0 +1,21 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: echo "SECTIONS {                  \
+# RUN:  . = 0xffffffff80000200;          \
+# RUN:  .text : AT (0x4200) { *(.text) } \
+# RUN: }" > %t.script
+# RUN: ld.lld %t.o --script %t.script -o %t
+# RUN: llvm-readelf -program-headers %t | FileCheck %s
+
+# Test that we put the header in the first PT_LOAD. We used to create a PT_LOAD
+# just for it and it would have a different virtual to physical address delta.
+
+# CHECK: Program Headers:
+# CHECK:      Type  Offset   VirtAddr           PhysAddr
+# CHECK-NEXT: PHDR  0x000040 0xffffffff80000040 0x0000000000004040
+# CHECK-NEXT: LOAD  0x000000 0xffffffff80000000 0x0000000000004000
+# CHECK-NOT:  LOAD
+
+.global _start
+_start:
+nop
deps/lld/test/ELF/linkerscript/parse-section-in-addr.s
@@ -0,0 +1,10 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+
+# RUN: echo "SECTIONS {                                   \
+# RUN:         .foo-bar : AT(ADDR(.foo-bar)) { *(.text) } \
+# RUN:       }" > %t.script
+# RUN: ld.lld -o %t.so --script %t.script %t.o -shared
+# RUN: llvm-readelf -S %t.so | FileCheck %s
+
+# CHECK: .foo-bar
deps/lld/test/ELF/as-needed-lazy.s
@@ -0,0 +1,14 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/as-needed-lazy.s -o %t2.o
+# RUN: ld.lld %t2.o -o %t2.so -shared
+# RUN: rm -f %t2.a
+# RUN: llvm-ar rc %t2.a %t2.o
+# RUN: ld.lld %t1.o %t2.a --as-needed %t2.so -o %t
+# RUN: llvm-readobj -d %t | FileCheck %s
+
+# CHECK-NOT: NEEDED
+
+.global _start
+_start:
+  nop
deps/lld/test/ELF/i386-retpoline-nopic.s
@@ -0,0 +1,65 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %s -o %t1.o
+// RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %p/Inputs/shared.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+
+// RUN: ld.lld %t1.o %t2.so -o %t.exe -z retpolineplt
+// RUN: llvm-objdump -d -s %t.exe | FileCheck %s
+
+// 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:      Contents of section .got.plt:
+// CHECK-NEXT: 00300100 00000000 00000000 50100100
+// CHECK-NEXT: 70100100
+
+.global _start
+_start:
+  jmp bar@PLT
+  jmp zed@PLT
deps/lld/test/ELF/i386-retpoline-pic.s
@@ -0,0 +1,62 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux -position-independent %s -o %t1.o
+// RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux -position-independent %p/Inputs/shared.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+
+// RUN: ld.lld %t1.o %t2.so -o %t.exe -z retpolineplt -pie
+// RUN: llvm-objdump -d -s %t.exe | FileCheck %s
+
+// CHECK:      Disassembly of section .plt:
+// CHECK-NEXT: .plt:
+// CHECK-NEXT: 1010:       ff b3 04 20 00 00       pushl   8196(%ebx)
+// CHECK-NEXT: 1016:       50      pushl   %eax
+// CHECK-NEXT: 1017:       8b 83 08 20 00 00       movl    8200(%ebx), %eax
+// CHECK-NEXT: 101d:       e8 0e 00 00 00  calll   14 <.plt+0x20>
+// CHECK-NEXT: 1022:       f3 90   pause
+// CHECK-NEXT: 1024:       0f ae e8        lfence
+// CHECK-NEXT: 1027:       eb f9   jmp     -7 <.plt+0x12>
+// CHECK-NEXT: 1029:       cc      int3
+// CHECK-NEXT: 102a:       cc      int3
+// CHECK-NEXT: 102b:       cc      int3
+// CHECK-NEXT: 102c:       cc      int3
+// CHECK-NEXT: 102d:       cc      int3
+// CHECK-NEXT: 102e:       cc      int3
+// CHECK-NEXT: 102f:       cc      int3
+// CHECK-NEXT: 1030:       89 0c 24        movl    %ecx, (%esp)
+// CHECK-NEXT: 1033:       8b 4c 24 04     movl    4(%esp), %ecx
+// CHECK-NEXT: 1037:       89 44 24 04     movl    %eax, 4(%esp)
+// CHECK-NEXT: 103b:       89 c8   movl    %ecx, %eax
+// CHECK-NEXT: 103d:       59      popl    %ecx
+// CHECK-NEXT: 103e:       c3      retl
+// CHECK-NEXT: 103f:       cc      int3
+// CHECK-NEXT: 1040:       50      pushl   %eax
+// CHECK-NEXT: 1041:       8b 83 0c 20 00 00       movl    8204(%ebx), %eax
+// CHECK-NEXT: 1047:       e8 e4 ff ff ff  calll   -28 <.plt+0x20>
+// CHECK-NEXT: 104c:       e9 d1 ff ff ff  jmp     -47 <.plt+0x12>
+// CHECK-NEXT: 1051:       68 00 00 00 00  pushl   $0
+// CHECK-NEXT: 1056:       e9 b5 ff ff ff  jmp     -75 <.plt>
+// CHECK-NEXT: 105b:       cc      int3
+// CHECK-NEXT: 105c:       cc      int3
+// CHECK-NEXT: 105d:       cc      int3
+// CHECK-NEXT: 105e:       cc      int3
+// CHECK-NEXT: 105f:       cc      int3
+// CHECK-NEXT: 1060:       50      pushl   %eax
+// CHECK-NEXT: 1061:       8b 83 10 20 00 00       movl    8208(%ebx), %eax
+// CHECK-NEXT: 1067:       e8 c4 ff ff ff  calll   -60 <.plt+0x20>
+// CHECK-NEXT: 106c:       e9 b1 ff ff ff  jmp     -79 <.plt+0x12>
+// CHECK-NEXT: 1071:       68 08 00 00 00  pushl   $8
+// CHECK-NEXT: 1076:       e9 95 ff ff ff  jmp     -107 <.plt>
+// CHECK-NEXT: 107b:       cc      int3
+// CHECK-NEXT: 107c:       cc      int3
+// CHECK-NEXT: 107d:       cc      int3
+// CHECK-NEXT: 107e:       cc      int3
+// CHECK-NEXT: 107f:       cc      int3
+
+// CHECK:      Contents of section .got.plt:
+// CHECK-NEXT: 2000 00300000 00000000 00000000 51100000
+// CHECK-NEXT: 2010 71100000
+
+.global _start
+_start:
+  jmp bar@PLT
+  jmp zed@PLT
deps/lld/test/ELF/mips-gp-disp-ver.s
@@ -0,0 +1,15 @@
+# MIPS BFD linker puts _gp_disp symbol into DSO files and assigns zero
+# version definition index to it. This value means 'unversioned local symbol'
+# while _gp_disp is a section global symbol. We have to handle this bug
+# in the LLD because BFD linker is used for building MIPS toolchain
+# libraries. This test checks such handling.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o %S/Inputs/mips-gp-dips-corrupt-ver.so
+
+# REQUIRES: mips
+
+  .global __start
+  .text
+__start:
+  lw     $t0, %got(foo)($gp)
deps/lld/test/ELF/pie.s
@@ -48,7 +48,7 @@
 # CHECK:         Type: PT_DYNAMIC
 
 ## Check -nopie
-# RUN: ld.lld -nopie %t1.o -o %t2
+# RUN: ld.lld -no-pie %t1.o -o %t2
 # RUN: llvm-readobj -file-headers -r %t2 | FileCheck %s --check-prefix=NOPIE
 # NOPIE-NOT: Type: SharedObject
 
deps/lld/test/ELF/x86-64-retpoline-znow.s
@@ -0,0 +1,53 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+
+// RUN: ld.lld -shared %t1.o %t2.so -o %t.exe -z retpolineplt -z now
+// RUN: llvm-objdump -d -s %t.exe | FileCheck %s
+
+// CHECK:      Disassembly of section .plt:
+// CHECK-NEXT: .plt:
+// CHECK-NEXT: 1010:	e8 0b 00 00 00 	callq	11 <.plt+0x10>
+// CHECK-NEXT: 1015:	f3 90 	pause
+// CHECK-NEXT: 1017:	0f ae e8 	lfence
+// CHECK-NEXT: 101a:	eb f9 	jmp	-7 <.plt+0x5>
+// CHECK-NEXT: 101c:	cc 	int3
+// CHECK-NEXT: 101d:	cc 	int3
+// CHECK-NEXT: 101e:	cc 	int3
+// CHECK-NEXT: 101f:	cc 	int3
+// CHECK-NEXT: 1020:	4c 89 1c 24 	movq	%r11, (%rsp)
+// CHECK-NEXT: 1024:	c3 	retq
+// CHECK-NEXT: 1025:	cc 	int3
+// CHECK-NEXT: 1026:	cc 	int3
+// CHECK-NEXT: 1027:	cc 	int3
+// CHECK-NEXT: 1028:	cc 	int3
+// CHECK-NEXT: 1029:	cc 	int3
+// CHECK-NEXT: 102a:	cc 	int3
+// CHECK-NEXT: 102b:	cc 	int3
+// CHECK-NEXT: 102c:	cc 	int3
+// CHECK-NEXT: 102d:	cc 	int3
+// CHECK-NEXT: 102e:	cc 	int3
+// CHECK-NEXT: 102f:	cc 	int3
+// CHECK-NEXT: 1030:	4c 8b 1d c1 10 00 00 	movq	4289(%rip), %r11
+// CHECK-NEXT: 1037:	e9 d4 ff ff ff 	jmp	-44 <.plt>
+// CHECK-NEXT: 103c:	cc 	int3
+// CHECK-NEXT: 103d:	cc 	int3
+// CHECK-NEXT: 103e:	cc 	int3
+// CHECK-NEXT: 103f:	cc 	int3
+// CHECK-NEXT: 1040:	4c 8b 1d b9 10 00 00 	movq	4281(%rip), %r11
+// CHECK-NEXT: 1047:	e9 c4 ff ff ff 	jmp	-60 <.plt>
+// CHECK-NEXT: 104c:	cc 	int3
+// CHECK-NEXT: 104d:	cc 	int3
+// CHECK-NEXT: 104e:	cc 	int3
+// CHECK-NEXT: 104f:	cc 	int3
+
+// CHECK:      Contents of section .got.plt:
+// CHECK-NEXT: 20e0 00200000 00000000 00000000 00000000
+// CHECK-NEXT: 20f0 00000000 00000000 00000000 00000000
+// CHECK-NEXT: 2100 00000000 00000000
+
+.global _start
+_start:
+  jmp bar@PLT
+  jmp zed@PLT
deps/lld/test/ELF/x86-64-retpoline.s
@@ -0,0 +1,66 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+
+// RUN: ld.lld -shared %t1.o %t2.so -o %t.exe -z retpolineplt
+// RUN: llvm-objdump -d -s %t.exe | FileCheck %s
+
+// CHECK:      Disassembly of section .plt:
+// CHECK-NEXT: .plt:
+// CHECK-NEXT: 1010:       ff 35 f2 0f 00 00       pushq   4082(%rip)
+// CHECK-NEXT: 1016:       4c 8b 1d f3 0f 00 00    movq    4083(%rip), %r11
+// CHECK-NEXT: 101d:       e8 0e 00 00 00  callq   14 <.plt+0x20>
+// CHECK-NEXT: 1022:       f3 90   pause
+// CHECK-NEXT: 1024:       0f ae e8        lfence
+// CHECK-NEXT: 1027:       eb f9   jmp     -7 <.plt+0x12>
+// CHECK-NEXT: 1029:       cc      int3
+// CHECK-NEXT: 102a:       cc      int3
+// CHECK-NEXT: 102b:       cc      int3
+// CHECK-NEXT: 102c:       cc      int3
+// CHECK-NEXT: 102d:       cc      int3
+// CHECK-NEXT: 102e:       cc      int3
+// CHECK-NEXT: 102f:       cc      int3
+// CHECK-NEXT: 1030:       4c 89 1c 24     movq    %r11, (%rsp)
+// CHECK-NEXT: 1034:       c3      retq
+// CHECK-NEXT: 1035:       cc      int3
+// CHECK-NEXT: 1036:       cc      int3
+// CHECK-NEXT: 1037:       cc      int3
+// CHECK-NEXT: 1038:       cc      int3
+// CHECK-NEXT: 1039:       cc      int3
+// CHECK-NEXT: 103a:       cc      int3
+// CHECK-NEXT: 103b:       cc      int3
+// CHECK-NEXT: 103c:       cc      int3
+// CHECK-NEXT: 103d:       cc      int3
+// CHECK-NEXT: 103e:       cc      int3
+// CHECK-NEXT: 103f:       cc      int3
+// CHECK-NEXT: 1040:       4c 8b 1d d1 0f 00 00    movq    4049(%rip), %r11
+// CHECK-NEXT: 1047:       e8 e4 ff ff ff  callq   -28 <.plt+0x20>
+// CHECK-NEXT: 104c:       e9 d1 ff ff ff  jmp     -47 <.plt+0x12>
+// CHECK-NEXT: 1051:       68 00 00 00 00  pushq   $0
+// CHECK-NEXT: 1056:       e9 b5 ff ff ff  jmp     -75 <.plt>
+// CHECK-NEXT: 105b:       cc      int3
+// CHECK-NEXT: 105c:       cc      int3
+// CHECK-NEXT: 105d:       cc      int3
+// CHECK-NEXT: 105e:       cc      int3
+// CHECK-NEXT: 105f:       cc      int3
+// CHECK-NEXT: 1060:       4c 8b 1d b9 0f 00 00    movq    4025(%rip), %r11
+// CHECK-NEXT: 1067:       e8 c4 ff ff ff  callq   -60 <.plt+0x20>
+// CHECK-NEXT: 106c:       e9 b1 ff ff ff  jmp     -79 <.plt+0x12>
+// CHECK-NEXT: 1071:       68 01 00 00 00  pushq   $1
+// CHECK-NEXT: 1076:       e9 95 ff ff ff  jmp     -107 <.plt>
+// CHECK-NEXT: 107b:       cc      int3
+// CHECK-NEXT: 107c:       cc      int3
+// CHECK-NEXT: 107d:       cc      int3
+// CHECK-NEXT: 107e:       cc      int3
+// CHECK-NEXT: 107f:       cc      int3
+
+// CHECK:      Contents of section .got.plt:
+// CHECK-NEXT: 2000 00300000 00000000 00000000 00000000
+// CHECK-NEXT: 2010 00000000 00000000 51100000 00000000
+// CHECK-NEXT: 2020 71100000 00000000
+
+.global _start
+_start:
+  jmp bar@PLT
+  jmp zed@PLT
deps/lld-prebuilt/ELF/Options.inc
@@ -230,6 +230,8 @@ OPTION(prefix_2, "no-merge-exidx-entries", no_merge_exidx_entries, Flag, INVALID
 OPTION(prefix_2, "no-mmap-output-file", no_mmap_output_file, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
 OPTION(prefix_3, "no-omagic", no_omagic, Flag, INVALID, INVALID, nullptr, 0, 0,
        "Do not set the text data sections to be writable", "<magic>", nullptr)
+OPTION(prefix_2, "no-pie", no_pie, Flag, INVALID, INVALID, nullptr, 0, 0,
+       "Do not create a position independent executable", nullptr, nullptr)
 OPTION(prefix_2, "no-print-gc-sections", no_print_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0,
        "Do not list removed unused sections", nullptr, nullptr)
 OPTION(prefix_2, "no-rosegment", no_rosegment, Flag, INVALID, INVALID, nullptr, 0, 0,
@@ -247,8 +249,6 @@ OPTION(prefix_2, "no-whole-archive", no_whole_archive, Flag, INVALID, INVALID, n
 OPTION(prefix_2, "noinhibit-exec", noinhibit_exec, Flag, INVALID, INVALID, nullptr, 0, 0,
        "Retain the executable output file whenever it is still usable", nullptr, nullptr)
 OPTION(prefix_2, "non_shared", alias_Bstatic_non_shared, Flag, INVALID, Bstatic, nullptr, 0, 0, nullptr, nullptr, nullptr)
-OPTION(prefix_2, "nopie", nopie, Flag, INVALID, INVALID, nullptr, 0, 0,
-       "Do not create a position independent executable", nullptr, nullptr)
 OPTION(prefix_2, "nostdlib", nostdlib, Flag, INVALID, INVALID, nullptr, 0, 0,
        "Only search directories specified on the command line", nullptr, nullptr)
 OPTION(prefix_1, "N", alias_omagic, Flag, INVALID, omagic, nullptr, 0, 0, nullptr, nullptr, nullptr)