[PATCH] D14382: [ELF2] - Basic implementation of -r/--relocatable

Rafael EspĂ­ndola via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 23 14:13:16 PST 2016


On 23 February 2016 at 16:38, Rui Ueyama <ruiu at google.com> wrote:
> ruiu added inline comments.
>
> ================
> Comment at: ELF/InputSection.h:39
> @@ -38,3 +38,3 @@
>  public:
> -  enum Kind { Regular, EHFrame, Merge, MipsReginfo };
> +  enum Kind { Regular, RelInputSection, EHFrame, Merge, MipsReginfo };
>    Kind SectionKind;
> ----------------
> So you just added RelInputSection kind? Adding a new kind and does not add a new class does not make sense. What I suggested was to actually define a new class for a relocation section. See http://reviews.llvm.org/D17551. I applied your patch and updated yours to separate the class from InputSection.

I went the other way and deleted the enum :-)

There is not that much specific to relocation sections. At least with
what is currently implemented it feels natural to use InputSection and
OutputSection for them.

Let me know what you think of the attached patch.

Cheers,
Rafael
-------------- next part --------------
diff --git a/ELF/Config.h b/ELF/Config.h
index f767dc3..8fed3eb 100644
--- a/ELF/Config.h
+++ b/ELF/Config.h
@@ -1,92 +1,93 @@
 //===- Config.h -------------------------------------------------*- C++ -*-===//
 //
 //                             The LLVM Linker
 //
 // This file is distributed under the University of Illinois Open Source
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLD_ELF_CONFIG_H
 #define LLD_ELF_CONFIG_H
 
 #include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/ELF.h"
 
 #include <vector>
 
 namespace lld {
 namespace elf2 {
 
 class InputFile;
 class SymbolBody;
 
 enum ELFKind {
   ELFNoneKind,
   ELF32LEKind,
   ELF32BEKind,
   ELF64LEKind,
   ELF64BEKind
 };
 
 // This struct contains the global configuration for the linker.
 // Most fields are direct mapping from the command line options
 // and such fields have the same name as the corresponding options.
 // Most fields are initialized by the driver.
 struct Configuration {
   SymbolBody *EntrySym = nullptr;
   SymbolBody *MipsGpDisp = nullptr;
   SymbolBody *MipsLocalGp = nullptr;
   InputFile *FirstElf = nullptr;
   llvm::StringRef DynamicLinker;
   llvm::StringRef Entry;
   llvm::StringRef Emulation;
   llvm::StringRef Fini;
   llvm::StringRef Init;
   llvm::StringRef OutputFile;
   llvm::StringRef SoName;
   llvm::StringRef Sysroot;
   std::string RPath;
   std::vector<llvm::StringRef> SearchPaths;
   std::vector<llvm::StringRef> Undefined;
   bool AllowMultipleDefinition;
   bool AsNeeded = false;
   bool Bsymbolic;
   bool BsymbolicFunctions;
   bool Demangle = true;
   bool DiscardAll;
   bool DiscardLocals;
   bool DiscardNone;
   bool EhFrameHdr;
   bool EnableNewDtags;
   bool ExportDynamic;
   bool GcSections;
   bool GnuHash = false;
   bool Mips64EL = false;
   bool NoInhibitExec;
   bool NoUndefined;
   bool PrintGcSections;
+  bool Relocatable;
   bool Shared;
   bool Static = false;
   bool StripAll;
   bool SysvHash = true;
   bool Verbose;
   bool ZExecStack;
   bool ZNodelete;
   bool ZNow;
   bool ZOrigin;
   bool ZRelro;
   ELFKind EKind = ELFNoneKind;
   uint16_t EMachine = llvm::ELF::EM_NONE;
   uint64_t EntryAddr = -1;
   unsigned Optimize = 0;
 };
 
 // The only instance of Configuration struct.
 extern Configuration *Config;
 
 } // namespace elf2
 } // namespace lld
 
 #endif
diff --git a/ELF/Driver.cpp b/ELF/Driver.cpp
index 5d08237..f8141de 100644
--- a/ELF/Driver.cpp
+++ b/ELF/Driver.cpp
@@ -1,374 +1,379 @@
 //===- Driver.cpp ---------------------------------------------------------===//
 //
 //                             The LLVM Linker
 //
 // This file is distributed under the University of Illinois Open Source
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 
 #include "Driver.h"
 #include "Config.h"
 #include "Error.h"
 #include "InputFiles.h"
 #include "LinkerScript.h"
 #include "SymbolTable.h"
 #include "Target.h"
 #include "Writer.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/raw_ostream.h"
 #include <utility>
 
 using namespace llvm;
 using namespace llvm::ELF;
 using namespace llvm::object;
 
 using namespace lld;
 using namespace lld::elf2;
 
 Configuration *elf2::Config;
 LinkerDriver *elf2::Driver;
 
 bool elf2::link(ArrayRef<const char *> Args, raw_ostream &Error) {
   HasError = false;
   ErrorOS = &Error;
   Configuration C;
   LinkerDriver D;
   LinkerScript LS;
   Config = &C;
   Driver = &D;
   Script = &LS;
   Driver->main(Args.slice(1));
   return !HasError;
 }
 
 static std::pair<ELFKind, uint16_t> parseEmulation(StringRef S) {
   if (S == "elf32btsmip")
     return {ELF32BEKind, EM_MIPS};
   if (S == "elf32ltsmip")
     return {ELF32LEKind, EM_MIPS};
   if (S == "elf32ppc" || S == "elf32ppc_fbsd")
     return {ELF32BEKind, EM_PPC};
   if (S == "elf64ppc" || S == "elf64ppc_fbsd")
     return {ELF64BEKind, EM_PPC64};
   if (S == "elf_i386")
     return {ELF32LEKind, EM_386};
   if (S == "elf_x86_64")
     return {ELF64LEKind, EM_X86_64};
   if (S == "aarch64linux")
     return {ELF64LEKind, EM_AARCH64};
   if (S == "i386pe" || S == "i386pep" || S == "thumb2pe")
     error("Windows targets are not supported on the ELF frontend: " + S);
   else
     error("Unknown emulation: " + S);
   return {ELFNoneKind, 0};
 }
 
 // Returns slices of MB by parsing MB as an archive file.
 // Each slice consists of a member file in the archive.
 static std::vector<MemoryBufferRef> getArchiveMembers(MemoryBufferRef MB) {
   ErrorOr<std::unique_ptr<Archive>> FileOrErr = Archive::create(MB);
   fatal(FileOrErr, "Failed to parse archive");
   std::unique_ptr<Archive> File = std::move(*FileOrErr);
 
   std::vector<MemoryBufferRef> V;
   for (const ErrorOr<Archive::Child> &C : File->children()) {
     fatal(C, "Could not get the child of the archive " + File->getFileName());
     ErrorOr<MemoryBufferRef> MbOrErr = C->getMemoryBufferRef();
     fatal(MbOrErr, "Could not get the buffer for a child of the archive " +
                        File->getFileName());
     V.push_back(*MbOrErr);
   }
   return V;
 }
 
 // Opens and parses a file. Path has to be resolved already.
 // Newly created memory buffers are owned by this driver.
 void LinkerDriver::addFile(StringRef Path) {
   using namespace llvm::sys::fs;
   if (Config->Verbose)
     llvm::outs() << Path << "\n";
   auto MBOrErr = MemoryBuffer::getFile(Path);
   if (error(MBOrErr, "cannot open " + Path))
     return;
   std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
   MemoryBufferRef MBRef = MB->getMemBufferRef();
   OwningMBs.push_back(std::move(MB)); // take MB ownership
 
   switch (identify_magic(MBRef.getBuffer())) {
   case file_magic::unknown:
     Script->read(MBRef);
     return;
   case file_magic::archive:
     if (WholeArchive) {
       StringRef S = MBRef.getBufferIdentifier();
       for (MemoryBufferRef MB : getArchiveMembers(MBRef))
         Files.push_back(createObjectFile(MB, S));
       return;
     }
     Files.push_back(make_unique<ArchiveFile>(MBRef));
     return;
   case file_magic::elf_shared_object:
+    if (Config->Relocatable) {
+      error("Attempted static link of dynamic object " + Path);
+      return;
+    }
     Files.push_back(createSharedFile(MBRef));
     return;
   default:
     Files.push_back(createObjectFile(MBRef));
   }
 }
 
 // Add a given library by searching it from input search paths.
 void LinkerDriver::addLibrary(StringRef Name) {
   std::string Path = searchLibrary(Name);
   if (Path.empty())
     error("Unable to find library -l" + Name);
   else
     addFile(Path);
 }
 
 // Some command line options or some combinations of them are not allowed.
 // This function checks for such errors.
 static void checkOptions(opt::InputArgList &Args) {
-  // Traditional linkers can generate re-linkable object files instead
-  // of executables or DSOs. We don't support that since the feature
-  // does not seem to provide more value than the static archiver.
-  if (Args.hasArg(OPT_relocatable))
-    error("-r option is not supported. Use 'ar' command instead.");
-
   // The MIPS ABI as of 2016 does not support the GNU-style symbol lookup
   // table which is a relatively new feature.
   if (Config->EMachine == EM_MIPS && Config->GnuHash)
     error("The .gnu.hash section is not compatible with the MIPS target.");
 
   if (Config->EMachine == EM_AMDGPU && !Config->Entry.empty())
     error("-e option is not valid for AMDGPU.");
+
+  if (Config->Relocatable && Config->Shared)
+    error("-r and -shared may not be used together");
 }
 
 static StringRef
 getString(opt::InputArgList &Args, unsigned Key, StringRef Default = "") {
   if (auto *Arg = Args.getLastArg(Key))
     return Arg->getValue();
   return Default;
 }
 
 static bool hasZOption(opt::InputArgList &Args, StringRef Key) {
   for (auto *Arg : Args.filtered(OPT_z))
     if (Key == Arg->getValue())
       return true;
   return false;
 }
 
 void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
   initSymbols();
 
   opt::InputArgList Args = parseArgs(&Alloc, ArgsArr);
   readConfigs(Args);
   createFiles(Args);
   checkOptions(Args);
   if (HasError)
     return;
 
   switch (Config->EKind) {
   case ELF32LEKind:
     link<ELF32LE>(Args);
     return;
   case ELF32BEKind:
     link<ELF32BE>(Args);
     return;
   case ELF64LEKind:
     link<ELF64LE>(Args);
     return;
   case ELF64BEKind:
     link<ELF64BE>(Args);
     return;
   default:
     error("-m or at least a .o file required");
   }
 }
 
 // Initializes Config members by the command line options.
 void LinkerDriver::readConfigs(opt::InputArgList &Args) {
   for (auto *Arg : Args.filtered(OPT_L))
     Config->SearchPaths.push_back(Arg->getValue());
 
   std::vector<StringRef> RPaths;
   for (auto *Arg : Args.filtered(OPT_rpath))
     RPaths.push_back(Arg->getValue());
   if (!RPaths.empty())
     Config->RPath = llvm::join(RPaths.begin(), RPaths.end(), ":");
 
   if (auto *Arg = Args.getLastArg(OPT_m)) {
     // Parse ELF{32,64}{LE,BE} and CPU type.
     StringRef S = Arg->getValue();
     std::tie(Config->EKind, Config->EMachine) = parseEmulation(S);
     Config->Emulation = S;
   }
 
   Config->AllowMultipleDefinition = Args.hasArg(OPT_allow_multiple_definition);
   Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic);
   Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions);
   Config->Demangle = !Args.hasArg(OPT_no_demangle);
   Config->DiscardAll = Args.hasArg(OPT_discard_all);
   Config->DiscardLocals = Args.hasArg(OPT_discard_locals);
   Config->DiscardNone = Args.hasArg(OPT_discard_none);
   Config->EhFrameHdr = Args.hasArg(OPT_eh_frame_hdr);
   Config->EnableNewDtags = !Args.hasArg(OPT_disable_new_dtags);
   Config->ExportDynamic = Args.hasArg(OPT_export_dynamic);
   Config->GcSections = Args.hasArg(OPT_gc_sections);
   Config->NoInhibitExec = Args.hasArg(OPT_noinhibit_exec);
   Config->NoUndefined = Args.hasArg(OPT_no_undefined);
   Config->PrintGcSections = Args.hasArg(OPT_print_gc_sections);
+  Config->Relocatable = Args.hasArg(OPT_relocatable);
   Config->Shared = Args.hasArg(OPT_shared);
   Config->StripAll = Args.hasArg(OPT_strip_all);
   Config->Verbose = Args.hasArg(OPT_verbose);
 
   Config->DynamicLinker = getString(Args, OPT_dynamic_linker);
   Config->Entry = getString(Args, OPT_entry);
   Config->Fini = getString(Args, OPT_fini, "_fini");
   Config->Init = getString(Args, OPT_init, "_init");
   Config->OutputFile = getString(Args, OPT_o);
   Config->SoName = getString(Args, OPT_soname);
   Config->Sysroot = getString(Args, OPT_sysroot);
 
   Config->ZExecStack = hasZOption(Args, "execstack");
   Config->ZNodelete = hasZOption(Args, "nodelete");
   Config->ZNow = hasZOption(Args, "now");
   Config->ZOrigin = hasZOption(Args, "origin");
   Config->ZRelro = !hasZOption(Args, "norelro");
 
+  if (Config->Relocatable)
+    Config->StripAll = false;
+
   if (auto *Arg = Args.getLastArg(OPT_O)) {
     StringRef Val = Arg->getValue();
     if (Val.getAsInteger(10, Config->Optimize))
       error("Invalid optimization level");
   }
 
   if (auto *Arg = Args.getLastArg(OPT_hash_style)) {
     StringRef S = Arg->getValue();
     if (S == "gnu") {
       Config->GnuHash = true;
       Config->SysvHash = false;
     } else if (S == "both") {
       Config->GnuHash = true;
     } else if (S != "sysv")
       error("Unknown hash style: " + S);
   }
 
   for (auto *Arg : Args.filtered(OPT_undefined))
     Config->Undefined.push_back(Arg->getValue());
 }
 
 void LinkerDriver::createFiles(opt::InputArgList &Args) {
   for (auto *Arg : Args) {
     switch (Arg->getOption().getID()) {
     case OPT_l:
       addLibrary(Arg->getValue());
       break;
     case OPT_INPUT:
     case OPT_script:
       addFile(Arg->getValue());
       break;
     case OPT_as_needed:
       Config->AsNeeded = true;
       break;
     case OPT_no_as_needed:
       Config->AsNeeded = false;
       break;
     case OPT_Bstatic:
       Config->Static = true;
       break;
     case OPT_Bdynamic:
       Config->Static = false;
       break;
     case OPT_whole_archive:
       WholeArchive = true;
       break;
     case OPT_no_whole_archive:
       WholeArchive = false;
       break;
     }
   }
 
   if (Files.empty() && !HasError)
     error("no input files.");
 }
 
 template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
   // For LTO
   InitializeAllTargets();
   InitializeAllTargetMCs();
   InitializeAllAsmPrinters();
 
   SymbolTable<ELFT> Symtab;
   std::unique_ptr<TargetInfo> TI(createTarget());
   Target = TI.get();
 
-  if (!Config->Shared) {
+  if (!Config->Shared && !Config->Relocatable) {
     // Add entry symbol.
     //
     // There is no entry symbol for AMDGPU binaries, so skip adding one to avoid
     // having and undefined symbol.
     if (Config->Entry.empty() && Config->EMachine != EM_AMDGPU)
       Config->Entry = (Config->EMachine == EM_MIPS) ? "__start" : "_start";
 
     // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol
     // is magical and is used to produce a R_386_GOTPC relocation.
     // The R_386_GOTPC relocation value doesn't actually depend on the
     // symbol value, so it could use an index of STN_UNDEF which, according
     // to the spec, means the symbol value is 0.
     // Unfortunately both gas and MC keep the _GLOBAL_OFFSET_TABLE_ symbol in
     // the object file.
     // The situation is even stranger on x86_64 where the assembly doesn't
     // need the magical symbol, but gas still puts _GLOBAL_OFFSET_TABLE_ as
     // an undefined symbol in the .o files.
     // Given that the symbol is effectively unused, we just create a dummy
     // hidden one to avoid the undefined symbol error.
     Symtab.addIgnored("_GLOBAL_OFFSET_TABLE_");
   }
 
   if (!Config->Entry.empty()) {
     // Set either EntryAddr (if S is a number) or EntrySym (otherwise).
     StringRef S = Config->Entry;
     if (S.getAsInteger(0, Config->EntryAddr))
       Config->EntrySym = Symtab.addUndefined(S);
   }
 
   if (Config->EMachine == EM_MIPS) {
     // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between
     // start of function and 'gp' pointer into GOT.
     Config->MipsGpDisp = Symtab.addIgnored("_gp_disp");
     // The __gnu_local_gp is a magic symbol equal to the current value of 'gp'
     // pointer. This symbol is used in the code generated by .cpload pseudo-op
     // in case of using -mno-shared option.
     // https://sourceware.org/ml/binutils/2004-12/msg00094.html
     Config->MipsLocalGp = Symtab.addIgnored("__gnu_local_gp");
 
     // Define _gp for MIPS. st_value of _gp symbol will be updated by Writer
     // so that it points to an absolute address which is relative to GOT.
     // See "Global Data Symbols" in Chapter 6 in the following document:
     // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
     Symtab.addAbsolute("_gp", ElfSym<ELFT>::MipsGp);
   }
 
   for (std::unique_ptr<InputFile> &F : Files)
     Symtab.addFile(std::move(F));
   if (HasError)
     return; // There were duplicate symbols or incompatible files
 
   for (StringRef S : Config->Undefined)
     Symtab.addUndefinedOpt(S);
 
   Symtab.addCombinedLtoObject();
 
   for (auto *Arg : Args.filtered(OPT_wrap))
     Symtab.wrap(Arg->getValue());
 
   if (Config->OutputFile.empty())
     Config->OutputFile = "a.out";
 
   // Write the result to the file.
   Symtab.scanShlibUndefined();
   if (Config->GcSections)
     markLive<ELFT>(&Symtab);
   writeResult<ELFT>(&Symtab);
 }
diff --git a/ELF/InputFiles.cpp b/ELF/InputFiles.cpp
index 2ba02fc..b76b185 100644
--- a/ELF/InputFiles.cpp
+++ b/ELF/InputFiles.cpp
@@ -1,521 +1,525 @@
 //===- InputFiles.cpp -----------------------------------------------------===//
 //
 //                             The LLVM Linker
 //
 // This file is distributed under the University of Illinois Open Source
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 
 #include "InputFiles.h"
 #include "Error.h"
 #include "InputSection.h"
 #include "Symbols.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/Object/IRObjectFile.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
 using namespace llvm::ELF;
 using namespace llvm::object;
 using namespace llvm::sys::fs;
 
 using namespace lld;
 using namespace lld::elf2;
 
 namespace {
 class ECRAII {
   std::error_code EC;
 
 public:
   std::error_code &getEC() { return EC; }
   ~ECRAII() { fatal(EC); }
 };
 }
 
 template <class ELFT>
 ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef M)
     : InputFile(K, M), ELFObj(MB.getBuffer(), ECRAII().getEC()) {}
 
 template <class ELFT>
 ELFKind ELFFileBase<ELFT>::getELFKind() {
   if (ELFT::TargetEndianness == support::little)
     return ELFT::Is64Bits ? ELF64LEKind : ELF32LEKind;
   return ELFT::Is64Bits ? ELF64BEKind : ELF32BEKind;
 }
 
 template <class ELFT>
 typename ELFFileBase<ELFT>::Elf_Sym_Range
 ELFFileBase<ELFT>::getSymbolsHelper(bool Local) {
   if (!Symtab)
     return Elf_Sym_Range(nullptr, nullptr);
   Elf_Sym_Range Syms = ELFObj.symbols(Symtab);
   uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
   uint32_t FirstNonLocal = Symtab->sh_info;
   if (FirstNonLocal > NumSymbols)
     fatal("Invalid sh_info in symbol table");
   if (!Local)
     return make_range(Syms.begin() + FirstNonLocal, Syms.end());
   // +1 to skip over dummy symbol.
   return make_range(Syms.begin() + 1, Syms.begin() + FirstNonLocal);
 }
 
 template <class ELFT>
 uint32_t ELFFileBase<ELFT>::getSectionIndex(const Elf_Sym &Sym) const {
   uint32_t I = Sym.st_shndx;
   if (I == ELF::SHN_XINDEX)
     return ELFObj.getExtendedSymbolTableIndex(&Sym, Symtab, SymtabSHNDX);
   if (I >= ELF::SHN_LORESERVE || I == ELF::SHN_ABS)
     return 0;
   return I;
 }
 
 template <class ELFT> void ELFFileBase<ELFT>::initStringTable() {
   if (!Symtab)
     return;
   ErrorOr<StringRef> StringTableOrErr = ELFObj.getStringTableForSymtab(*Symtab);
   fatal(StringTableOrErr);
   StringTable = *StringTableOrErr;
 }
 
 template <class ELFT>
 typename ELFFileBase<ELFT>::Elf_Sym_Range
 ELFFileBase<ELFT>::getNonLocalSymbols() {
   return getSymbolsHelper(false);
 }
 
 template <class ELFT>
 elf2::ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M)
     : ELFFileBase<ELFT>(Base::ObjectKind, M) {}
 
 template <class ELFT>
 typename elf2::ObjectFile<ELFT>::Elf_Sym_Range
 elf2::ObjectFile<ELFT>::getLocalSymbols() {
   return this->getSymbolsHelper(true);
 }
 
 template <class ELFT> uint32_t elf2::ObjectFile<ELFT>::getMipsGp0() const {
   if (MipsReginfo)
     return MipsReginfo->Reginfo->ri_gp_value;
   return 0;
 }
 
 template <class ELFT>
 const typename elf2::ObjectFile<ELFT>::Elf_Sym *
 elf2::ObjectFile<ELFT>::getLocalSymbol(uintX_t SymIndex) {
   uint32_t FirstNonLocal = this->Symtab->sh_info;
   if (SymIndex >= FirstNonLocal)
     return nullptr;
   Elf_Sym_Range Syms = this->ELFObj.symbols(this->Symtab);
   return Syms.begin() + SymIndex;
 }
 
 template <class ELFT>
 void elf2::ObjectFile<ELFT>::parse(DenseSet<StringRef> &ComdatGroups) {
   // Read section and symbol tables.
   initializeSections(ComdatGroups);
   initializeSymbols();
 }
 
 // Sections with SHT_GROUP and comdat bits define comdat section groups.
 // They are identified and deduplicated by group name. This function
 // returns a group name.
 template <class ELFT>
 StringRef elf2::ObjectFile<ELFT>::getShtGroupSignature(const Elf_Shdr &Sec) {
   const ELFFile<ELFT> &Obj = this->ELFObj;
   uint32_t SymtabdSectionIndex = Sec.sh_link;
   ErrorOr<const Elf_Shdr *> SecOrErr = Obj.getSection(SymtabdSectionIndex);
   fatal(SecOrErr);
   const Elf_Shdr *SymtabSec = *SecOrErr;
   uint32_t SymIndex = Sec.sh_info;
   const Elf_Sym *Sym = Obj.getSymbol(SymtabSec, SymIndex);
   ErrorOr<StringRef> StringTableOrErr = Obj.getStringTableForSymtab(*SymtabSec);
   fatal(StringTableOrErr);
   ErrorOr<StringRef> SignatureOrErr = Sym->getName(*StringTableOrErr);
   fatal(SignatureOrErr);
   return *SignatureOrErr;
 }
 
 template <class ELFT>
 ArrayRef<typename elf2::ObjectFile<ELFT>::uint32_X>
 elf2::ObjectFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) {
   const ELFFile<ELFT> &Obj = this->ELFObj;
   ErrorOr<ArrayRef<uint32_X>> EntriesOrErr =
       Obj.template getSectionContentsAsArray<uint32_X>(&Sec);
   fatal(EntriesOrErr);
   ArrayRef<uint32_X> Entries = *EntriesOrErr;
   if (Entries.empty() || Entries[0] != GRP_COMDAT)
     fatal("Unsupported SHT_GROUP format");
   return Entries.slice(1);
 }
 
 template <class ELFT>
 static bool shouldMerge(const typename ELFFile<ELFT>::Elf_Shdr &Sec) {
   typedef typename ELFFile<ELFT>::uintX_t uintX_t;
   uintX_t Flags = Sec.sh_flags;
   if (!(Flags & SHF_MERGE))
     return false;
   if (Flags & SHF_WRITE)
     fatal("Writable SHF_MERGE sections are not supported");
   uintX_t EntSize = Sec.sh_entsize;
   if (!EntSize || Sec.sh_size % EntSize)
     fatal("SHF_MERGE section size must be a multiple of sh_entsize");
 
   // Don't try to merge if the aligment is larger than the sh_entsize and this
   // is not SHF_STRINGS.
   //
   // Since this is not a SHF_STRINGS, we would need to pad after every entity.
   // It would be equivalent for the producer of the .o to just set a larger
   // sh_entsize.
   if (Flags & SHF_STRINGS)
     return true;
 
   if (Sec.sh_addralign > EntSize)
     return false;
 
   return true;
 }
 
 template <class ELFT>
 void elf2::ObjectFile<ELFT>::initializeSections(
     DenseSet<StringRef> &ComdatGroups) {
   uint64_t Size = this->ELFObj.getNumSections();
   Sections.resize(Size);
   unsigned I = -1;
   const ELFFile<ELFT> &Obj = this->ELFObj;
   for (const Elf_Shdr &Sec : Obj.sections()) {
     ++I;
     if (Sections[I] == &InputSection<ELFT>::Discarded)
       continue;
 
     switch (Sec.sh_type) {
     case SHT_GROUP:
       Sections[I] = &InputSection<ELFT>::Discarded;
       if (ComdatGroups.insert(getShtGroupSignature(Sec)).second)
         continue;
       for (uint32_t SecIndex : getShtGroupEntries(Sec)) {
         if (SecIndex >= Size)
           fatal("Invalid section index in group");
         Sections[SecIndex] = &InputSection<ELFT>::Discarded;
       }
       break;
     case SHT_SYMTAB:
       this->Symtab = &Sec;
       break;
     case SHT_SYMTAB_SHNDX: {
       ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable = Obj.getSHNDXTable(Sec);
       fatal(ErrorOrTable);
       this->SymtabSHNDX = *ErrorOrTable;
       break;
     }
     case SHT_STRTAB:
     case SHT_NULL:
       break;
     case SHT_RELA:
     case SHT_REL: {
       uint32_t RelocatedSectionIndex = Sec.sh_info;
       if (RelocatedSectionIndex >= Size)
         fatal("Invalid relocated section index");
       InputSectionBase<ELFT> *RelocatedSection =
           Sections[RelocatedSectionIndex];
       // Strictly speaking, a relocation section must be included in the
       // group of the section it relocates. However, LLVM 3.3 and earlier
       // would fail to do so, so we gracefully handle that case.
       if (RelocatedSection == &InputSection<ELFT>::Discarded)
         continue;
       if (!RelocatedSection)
         fatal("Unsupported relocation reference");
-      if (auto *S = dyn_cast<InputSection<ELFT>>(RelocatedSection)) {
+      if (Config->Relocatable) {
+        // For -r, relocation sections are handled as regular input sections.
+        InputSection<ELFT> *S = new (Alloc) InputSection<ELFT>(this, &Sec);
+        Sections[I] = S;
+      } else if (auto *S = dyn_cast<InputSection<ELFT>>(RelocatedSection)) {
         S->RelocSections.push_back(&Sec);
       } else if (auto *S = dyn_cast<EHInputSection<ELFT>>(RelocatedSection)) {
         if (S->RelocSection)
           fatal("Multiple relocation sections to .eh_frame are not supported");
         S->RelocSection = &Sec;
       } else {
         fatal("Relocations pointing to SHF_MERGE are not supported");
       }
       break;
     }
     default:
       Sections[I] = createInputSection(Sec);
     }
   }
 }
 
 template <class ELFT>
 InputSectionBase<ELFT> *
 elf2::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
   ErrorOr<StringRef> NameOrErr = this->ELFObj.getSectionName(&Sec);
   fatal(NameOrErr);
   StringRef Name = *NameOrErr;
 
   // .note.GNU-stack is a marker section to control the presence of
   // PT_GNU_STACK segment in outputs. Since the presence of the segment
   // is controlled only by the command line option (-z execstack) in LLD,
   // .note.GNU-stack is ignored.
   if (Name == ".note.GNU-stack")
     return &InputSection<ELFT>::Discarded;
 
   // A MIPS object file has a special section that contains register
   // usage info, which needs to be handled by the linker specially.
   if (Config->EMachine == EM_MIPS && Name == ".reginfo") {
     MipsReginfo = new (Alloc) MipsReginfoInputSection<ELFT>(this, &Sec);
     return MipsReginfo;
   }
 
   if (Name == ".eh_frame")
     return new (EHAlloc.Allocate()) EHInputSection<ELFT>(this, &Sec);
   if (shouldMerge<ELFT>(Sec))
     return new (MAlloc.Allocate()) MergeInputSection<ELFT>(this, &Sec);
   return new (Alloc) InputSection<ELFT>(this, &Sec);
 }
 
 template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() {
   this->initStringTable();
   Elf_Sym_Range Syms = this->getNonLocalSymbols();
   uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
   SymbolBodies.reserve(NumSymbols);
   for (const Elf_Sym &Sym : Syms)
     SymbolBodies.push_back(createSymbolBody(&Sym));
 }
 
 template <class ELFT>
 InputSectionBase<ELFT> *
 elf2::ObjectFile<ELFT>::getSection(const Elf_Sym &Sym) const {
   uint32_t Index = this->getSectionIndex(Sym);
   if (Index == 0)
     return nullptr;
   if (Index >= Sections.size() || !Sections[Index])
     fatal("Invalid section index");
   return Sections[Index];
 }
 
 template <class ELFT>
 SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) {
   ErrorOr<StringRef> NameOrErr = Sym->getName(this->StringTable);
   fatal(NameOrErr);
   StringRef Name = *NameOrErr;
 
   switch (Sym->st_shndx) {
   case SHN_UNDEF:
     return new (Alloc) UndefinedElf<ELFT>(Name, *Sym);
   case SHN_COMMON:
     return new (Alloc) DefinedCommon(Name, Sym->st_size, Sym->st_value,
                                      Sym->getBinding() == llvm::ELF::STB_WEAK,
                                      Sym->getVisibility());
   }
 
   switch (Sym->getBinding()) {
   default:
     fatal("unexpected binding");
   case STB_GLOBAL:
   case STB_WEAK:
   case STB_GNU_UNIQUE: {
     InputSectionBase<ELFT> *Sec = getSection(*Sym);
     if (Sec == &InputSection<ELFT>::Discarded)
       return new (Alloc) UndefinedElf<ELFT>(Name, *Sym);
     return new (Alloc) DefinedRegular<ELFT>(Name, *Sym, Sec);
   }
   }
 }
 
 void ArchiveFile::parse() {
   ErrorOr<std::unique_ptr<Archive>> FileOrErr = Archive::create(MB);
   fatal(FileOrErr, "Failed to parse archive");
   File = std::move(*FileOrErr);
 
   // Allocate a buffer for Lazy objects.
   size_t NumSyms = File->getNumberOfSymbols();
   LazySymbols.reserve(NumSyms);
 
   // Read the symbol table to construct Lazy objects.
   for (const Archive::Symbol &Sym : File->symbols())
     LazySymbols.emplace_back(this, Sym);
 }
 
 // Returns a buffer pointing to a member file containing a given symbol.
 MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) {
   ErrorOr<Archive::Child> COrErr = Sym->getMember();
   fatal(COrErr, "Could not get the member for symbol " + Sym->getName());
   const Archive::Child &C = *COrErr;
 
   if (!Seen.insert(C.getChildOffset()).second)
     return MemoryBufferRef();
 
   ErrorOr<MemoryBufferRef> RefOrErr = C.getMemoryBufferRef();
   if (!RefOrErr)
     fatal(RefOrErr, "Could not get the buffer for the member defining symbol " +
                         Sym->getName());
   return *RefOrErr;
 }
 
 template <class ELFT>
 SharedFile<ELFT>::SharedFile(MemoryBufferRef M)
     : ELFFileBase<ELFT>(Base::SharedKind, M), AsNeeded(Config->AsNeeded) {}
 
 template <class ELFT>
 const typename ELFFile<ELFT>::Elf_Shdr *
 SharedFile<ELFT>::getSection(const Elf_Sym &Sym) const {
   uint32_t Index = this->getSectionIndex(Sym);
   if (Index == 0)
     return nullptr;
   ErrorOr<const Elf_Shdr *> Ret = this->ELFObj.getSection(Index);
   fatal(Ret);
   return *Ret;
 }
 
 // Partially parse the shared object file so that we can call
 // getSoName on this object.
 template <class ELFT> void SharedFile<ELFT>::parseSoName() {
   typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn;
   typedef typename ELFFile<ELFT>::uintX_t uintX_t;
   const Elf_Shdr *DynamicSec = nullptr;
 
   const ELFFile<ELFT> Obj = this->ELFObj;
   for (const Elf_Shdr &Sec : Obj.sections()) {
     switch (Sec.sh_type) {
     default:
       continue;
     case SHT_DYNSYM:
       this->Symtab = &Sec;
       break;
     case SHT_DYNAMIC:
       DynamicSec = &Sec;
       break;
     case SHT_SYMTAB_SHNDX: {
       ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable = Obj.getSHNDXTable(Sec);
       fatal(ErrorOrTable);
       this->SymtabSHNDX = *ErrorOrTable;
       break;
     }
     }
   }
 
   this->initStringTable();
   SoName = this->getName();
 
   if (!DynamicSec)
     return;
   auto *Begin =
       reinterpret_cast<const Elf_Dyn *>(Obj.base() + DynamicSec->sh_offset);
   const Elf_Dyn *End = Begin + DynamicSec->sh_size / sizeof(Elf_Dyn);
 
   for (const Elf_Dyn &Dyn : make_range(Begin, End)) {
     if (Dyn.d_tag == DT_SONAME) {
       uintX_t Val = Dyn.getVal();
       if (Val >= this->StringTable.size())
         fatal("Invalid DT_SONAME entry");
       SoName = StringRef(this->StringTable.data() + Val);
       return;
     }
   }
 }
 
 // Fully parse the shared object file. This must be called after parseSoName().
 template <class ELFT> void SharedFile<ELFT>::parseRest() {
   Elf_Sym_Range Syms = this->getNonLocalSymbols();
   uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
   SymbolBodies.reserve(NumSymbols);
   for (const Elf_Sym &Sym : Syms) {
     ErrorOr<StringRef> NameOrErr = Sym.getName(this->StringTable);
     fatal(NameOrErr.getError());
     StringRef Name = *NameOrErr;
 
     if (Sym.isUndefined())
       Undefs.push_back(Name);
     else
       SymbolBodies.emplace_back(this, Name, Sym);
   }
 }
 
 BitcodeFile::BitcodeFile(MemoryBufferRef M) : InputFile(BitcodeKind, M) {}
 
 bool BitcodeFile::classof(const InputFile *F) {
   return F->kind() == BitcodeKind;
 }
 
 void BitcodeFile::parse() {
   LLVMContext Context;
   ErrorOr<std::unique_ptr<IRObjectFile>> ObjOrErr =
       IRObjectFile::create(MB, Context);
   fatal(ObjOrErr);
   IRObjectFile &Obj = **ObjOrErr;
   for (const BasicSymbolRef &Sym : Obj.symbols()) {
     SmallString<64> Name;
     raw_svector_ostream OS(Name);
     Sym.printName(OS);
     StringRef NameRef = Saver.save(StringRef(Name));
     SymbolBody *Body;
     if (Sym.getFlags() & object::BasicSymbolRef::SF_Undefined)
       Body = new (Alloc) Undefined(NameRef, false, STV_DEFAULT, false);
     else
       Body = new (Alloc) DefinedBitcode(NameRef);
     SymbolBodies.push_back(Body);
   }
 }
 
 template <typename T>
 static std::unique_ptr<InputFile> createELFFileAux(MemoryBufferRef MB) {
   std::unique_ptr<T> Ret = llvm::make_unique<T>(MB);
 
   if (!Config->FirstElf)
     Config->FirstElf = Ret.get();
 
   if (Config->EKind == ELFNoneKind) {
     Config->EKind = Ret->getELFKind();
     Config->EMachine = Ret->getEMachine();
   }
 
   return std::move(Ret);
 }
 
 template <template <class> class T>
 static std::unique_ptr<InputFile> createELFFile(MemoryBufferRef MB) {
   std::pair<unsigned char, unsigned char> Type = getElfArchType(MB.getBuffer());
   if (Type.second != ELF::ELFDATA2LSB && Type.second != ELF::ELFDATA2MSB)
     fatal("Invalid data encoding: " + MB.getBufferIdentifier());
 
   if (Type.first == ELF::ELFCLASS32) {
     if (Type.second == ELF::ELFDATA2LSB)
       return createELFFileAux<T<ELF32LE>>(MB);
     return createELFFileAux<T<ELF32BE>>(MB);
   }
   if (Type.first == ELF::ELFCLASS64) {
     if (Type.second == ELF::ELFDATA2LSB)
       return createELFFileAux<T<ELF64LE>>(MB);
     return createELFFileAux<T<ELF64BE>>(MB);
   }
   fatal("Invalid file class: " + MB.getBufferIdentifier());
 }
 
 std::unique_ptr<InputFile> elf2::createObjectFile(MemoryBufferRef MB,
                                                   StringRef ArchiveName) {
   using namespace sys::fs;
   std::unique_ptr<InputFile> F;
   if (identify_magic(MB.getBuffer()) == file_magic::bitcode)
     F.reset(new BitcodeFile(MB));
   else
     F = createELFFile<ObjectFile>(MB);
   F->ArchiveName = ArchiveName;
   return F;
 }
 
 std::unique_ptr<InputFile> elf2::createSharedFile(MemoryBufferRef MB) {
   return createELFFile<SharedFile>(MB);
 }
 
 template class elf2::ELFFileBase<ELF32LE>;
 template class elf2::ELFFileBase<ELF32BE>;
 template class elf2::ELFFileBase<ELF64LE>;
 template class elf2::ELFFileBase<ELF64BE>;
 
 template class elf2::ObjectFile<ELF32LE>;
 template class elf2::ObjectFile<ELF32BE>;
 template class elf2::ObjectFile<ELF64LE>;
 template class elf2::ObjectFile<ELF64BE>;
 
 template class elf2::SharedFile<ELF32LE>;
 template class elf2::SharedFile<ELF32BE>;
 template class elf2::SharedFile<ELF64LE>;
 template class elf2::SharedFile<ELF64BE>;
diff --git a/ELF/InputSection.cpp b/ELF/InputSection.cpp
index ad81780..eb8ec93 100644
--- a/ELF/InputSection.cpp
+++ b/ELF/InputSection.cpp
@@ -1,397 +1,446 @@
 //===- InputSection.cpp ---------------------------------------------------===//
 //
 //                             The LLVM Linker
 //
 // This file is distributed under the University of Illinois Open Source
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 
 #include "InputSection.h"
 #include "Config.h"
 #include "Error.h"
 #include "InputFiles.h"
 #include "OutputSections.h"
 #include "Target.h"
 
 using namespace llvm;
 using namespace llvm::ELF;
 using namespace llvm::object;
 
 using namespace lld;
 using namespace lld::elf2;
 
 template <class ELFT>
 InputSectionBase<ELFT>::InputSectionBase(ObjectFile<ELFT> *File,
                                          const Elf_Shdr *Header,
                                          Kind SectionKind)
     : Header(Header), File(File), SectionKind(SectionKind) {}
 
 template <class ELFT> StringRef InputSectionBase<ELFT>::getSectionName() const {
   ErrorOr<StringRef> Name = File->getObj().getSectionName(this->Header);
   fatal(Name);
   return *Name;
 }
 
 template <class ELFT>
 ArrayRef<uint8_t> InputSectionBase<ELFT>::getSectionData() const {
   ErrorOr<ArrayRef<uint8_t>> Ret =
       this->File->getObj().getSectionContents(this->Header);
   fatal(Ret);
   return *Ret;
 }
 
 template <class ELFT>
 typename ELFFile<ELFT>::uintX_t
 InputSectionBase<ELFT>::getOffset(uintX_t Offset) {
   switch (SectionKind) {
   case Regular:
     return cast<InputSection<ELFT>>(this)->OutSecOff + Offset;
   case EHFrame:
     return cast<EHInputSection<ELFT>>(this)->getOffset(Offset);
   case Merge:
     return cast<MergeInputSection<ELFT>>(this)->getOffset(Offset);
   case MipsReginfo:
     // MIPS .reginfo sections are consumed by the linker,
     // so it should never be copied to output.
     llvm_unreachable("MIPS .reginfo reached writeTo().");
   }
   llvm_unreachable("Invalid section kind");
 }
 
 template <class ELFT>
 typename ELFFile<ELFT>::uintX_t
 InputSectionBase<ELFT>::getOffset(const Elf_Sym &Sym) {
   return getOffset(Sym.st_value);
 }
 
 // Returns a section that Rel relocation is pointing to.
 template <class ELFT>
 InputSectionBase<ELFT> *
 InputSectionBase<ELFT>::getRelocTarget(const Elf_Rel &Rel) {
   // Global symbol
   uint32_t SymIndex = Rel.getSymbol(Config->Mips64EL);
   if (SymbolBody *B = File->getSymbolBody(SymIndex))
     if (auto *D = dyn_cast<DefinedRegular<ELFT>>(B->repl()))
       return D->Section;
   // Local symbol
   if (const Elf_Sym *Sym = File->getLocalSymbol(SymIndex))
     if (InputSectionBase<ELFT> *Sec = File->getSection(*Sym))
       return Sec;
   return nullptr;
 }
 
 template <class ELFT>
 InputSectionBase<ELFT> *
 InputSectionBase<ELFT>::getRelocTarget(const Elf_Rela &Rel) {
   return getRelocTarget(reinterpret_cast<const Elf_Rel &>(Rel));
 }
 
 template <class ELFT>
 InputSection<ELFT>::InputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header)
     : InputSectionBase<ELFT>(F, Header, Base::Regular) {}
 
 template <class ELFT>
 bool InputSection<ELFT>::classof(const InputSectionBase<ELFT> *S) {
   return S->SectionKind == Base::Regular;
 }
 
 template <class ELFT>
+InputSectionBase<ELFT> *InputSectionBase<ELFT>::getRelocatedSection() {
+  assert(Header->sh_type == SHT_RELA || Header->sh_type == SHT_REL);
+  ArrayRef<InputSectionBase<ELFT> *> Sections = File->getSections();
+  return Sections[Header->sh_info];
+}
+
+// This is used for -r. We can't use memcpy to copy relocations because we need
+// to update symbol table offset and section index for each relocation. So we
+// copy relocations one by one.
+template <class ELFT>
+template <bool isRela>
+void InputSectionBase<ELFT>::copyRelocations(uint8_t *Buf,
+                                             RelIteratorRange<isRela> Rels) {
+  typedef Elf_Rel_Impl<ELFT, isRela> RelType;
+  InputSectionBase<ELFT> *RelocatedSection = getRelocatedSection();
+
+  for (const RelType &Rel : Rels) {
+    uint32_t SymIndex = Rel.getSymbol(Config->Mips64EL);
+    uint32_t Type = Rel.getType(Config->Mips64EL);
+    const Elf_Shdr *SymTab = File->getSymbolTable();
+
+    RelType *P = reinterpret_cast<RelType *>(Buf);
+    Buf += sizeof(RelType);
+
+    // Relocation for local symbol here means that it is probably
+    // rel[a].eh_frame section which has references to
+    // sections in r_info field. Also needs fix for addend.
+    if (SymIndex < SymTab->sh_info)
+      fatal("Relocation against local symbols is not supported yet");
+
+    SymbolBody *Body = File->getSymbolBody(SymIndex)->repl();
+    P->r_offset = RelocatedSection->getOffset(Rel.r_offset);
+    P->setSymbolAndType(Body->DynsymIndex, Type, Config->Mips64EL);
+  }
+}
+
+template <class ELFT>
 template <bool isRela>
 uint8_t *
 InputSectionBase<ELFT>::findMipsPairedReloc(uint8_t *Buf, uint32_t SymIndex,
                                             uint32_t Type,
                                             RelIteratorRange<isRela> Rels) {
   // Some MIPS relocations use addend calculated from addend of the relocation
   // itself and addend of paired relocation. ABI requires to compute such
   // combined addend in case of REL relocation record format only.
   // See p. 4-17 at ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
   if (isRela || Config->EMachine != EM_MIPS)
     return nullptr;
   if (Type == R_MIPS_HI16)
     Type = R_MIPS_LO16;
   else if (Type == R_MIPS_PCHI16)
     Type = R_MIPS_PCLO16;
   else if (Type == R_MICROMIPS_HI16)
     Type = R_MICROMIPS_LO16;
   else
     return nullptr;
   for (const auto &RI : Rels) {
     if (RI.getType(Config->Mips64EL) != Type)
       continue;
     if (RI.getSymbol(Config->Mips64EL) != SymIndex)
       continue;
     uintX_t Offset = getOffset(RI.r_offset);
     if (Offset == (uintX_t)-1)
       return nullptr;
     return Buf + Offset;
   }
   return nullptr;
 }
 
 template <class ELFT>
 template <bool isRela>
 void InputSectionBase<ELFT>::relocate(uint8_t *Buf, uint8_t *BufEnd,
                                       RelIteratorRange<isRela> Rels) {
   typedef Elf_Rel_Impl<ELFT, isRela> RelType;
   size_t Num = Rels.end() - Rels.begin();
   for (size_t I = 0; I < Num; ++I) {
     const RelType &RI = *(Rels.begin() + I);
     uint32_t SymIndex = RI.getSymbol(Config->Mips64EL);
     uint32_t Type = RI.getType(Config->Mips64EL);
     uintX_t Offset = getOffset(RI.r_offset);
     if (Offset == (uintX_t)-1)
       continue;
 
     uint8_t *BufLoc = Buf + Offset;
     uintX_t AddrLoc = OutSec->getVA() + Offset;
     auto NextRelocs = llvm::make_range(&RI, Rels.end());
 
     if (Target->isTlsLocalDynamicRel(Type) &&
         !Target->canRelaxTls(Type, nullptr)) {
       Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc,
                           Out<ELFT>::Got->getTlsIndexVA() +
                               getAddend<ELFT>(RI));
       continue;
     }
 
     const Elf_Shdr *SymTab = File->getSymbolTable();
     SymbolBody *Body = nullptr;
     if (SymIndex >= SymTab->sh_info)
       Body = File->getSymbolBody(SymIndex)->repl();
 
     if (Target->canRelaxTls(Type, Body)) {
       uintX_t SymVA;
       if (!Body)
         SymVA = getLocalRelTarget(*File, RI, 0);
       else if (Target->needsGot(Type, *Body))
         SymVA = Body->getGotVA<ELFT>();
       else
         SymVA = Body->getVA<ELFT>();
       // By optimizing TLS relocations, it is sometimes needed to skip
       // relocations that immediately follow TLS relocations. This function
       // knows how many slots we need to skip.
       I += Target->relaxTls(BufLoc, BufEnd, Type, AddrLoc, SymVA, Body);
       continue;
     }
 
     // Handle relocations for local symbols -- they never get
     // resolved so we don't allocate a SymbolBody.
     uintX_t A = getAddend<ELFT>(RI);
     if (!Body) {
       uintX_t SymVA = getLocalRelTarget(*File, RI, A);
       if (Config->EMachine == EM_MIPS) {
         if (Type == R_MIPS_GPREL16 || Type == R_MIPS_GPREL32)
           // We need to adjust SymVA value in case of R_MIPS_GPREL16/32
           // relocations because they use the following expression to calculate
           // the relocation's result for local symbol: S + A + GP0 - G.
           SymVA += File->getMipsGp0();
         else if (Type == R_MIPS_GOT16)
           // R_MIPS_GOT16 relocation against local symbol requires index of
           // a local GOT entry which contains page address corresponds
           // to the symbol address.
           SymVA = Out<ELFT>::Got->getMipsLocalPageAddr(SymVA);
       }
       Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA, 0,
                           findMipsPairedReloc(Buf, SymIndex, Type, NextRelocs));
       continue;
     }
 
     if (Target->isTlsGlobalDynamicRel(Type) &&
         !Target->canRelaxTls(Type, Body)) {
       Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc,
                           Out<ELFT>::Got->getGlobalDynAddr(*Body) +
                               getAddend<ELFT>(RI));
       continue;
     }
 
     uintX_t SymVA = Body->getVA<ELFT>();
     if (Target->needsPlt(Type, *Body)) {
       SymVA = Body->getPltVA<ELFT>();
     } else if (Target->needsGot(Type, *Body)) {
       if (Config->EMachine == EM_MIPS && !canBePreempted(Body, true))
         // Under some conditions relocations against non-local symbols require
         // entries in the local part of MIPS GOT. In that case we need an entry
         // initialized by full address of the symbol.
         SymVA = Out<ELFT>::Got->getMipsLocalFullAddr(*Body);
       else
         SymVA = Body->getGotVA<ELFT>();
       if (Body->IsTls)
         Type = Target->getTlsGotRel(Type);
     } else if (!Target->needsCopyRel<ELFT>(Type, *Body) &&
                isa<SharedSymbol<ELFT>>(*Body)) {
       continue;
     } else if (Target->isTlsDynRel(Type, *Body)) {
       continue;
     } else if (Target->isSizeRel(Type) && canBePreempted(Body, false)) {
       // A SIZE relocation is supposed to set a symbol size, but if a symbol
       // can be preempted, the size at runtime may be different than link time.
       // If that's the case, we leave the field alone rather than filling it
       // with a possibly incorrect value.
       continue;
     } else if (Config->EMachine == EM_MIPS) {
       if (Type == R_MIPS_HI16 && Body == Config->MipsGpDisp)
         SymVA = getMipsGpAddr<ELFT>() - AddrLoc;
       else if (Type == R_MIPS_LO16 && Body == Config->MipsGpDisp)
         SymVA = getMipsGpAddr<ELFT>() - AddrLoc + 4;
       else if (Body == Config->MipsLocalGp)
         SymVA = getMipsGpAddr<ELFT>();
     }
     uintX_t Size = Body->getSize<ELFT>();
     Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA + A, Size + A,
                         findMipsPairedReloc(Buf, SymIndex, Type, NextRelocs));
   }
 }
 
 template <class ELFT> void InputSection<ELFT>::writeTo(uint8_t *Buf) {
   if (this->Header->sh_type == SHT_NOBITS)
     return;
   // Copy section contents from source object file to output file.
   ArrayRef<uint8_t> Data = this->getSectionData();
+  ELFFile<ELFT> &EObj = this->File->getObj();
+
+  // That happens with -r. In that case we need fix the relocation position and
+  // target. No relocations are applied.
+  if (this->Header->sh_type == SHT_RELA) {
+    this->copyRelocations(Buf + OutSecOff, EObj.relas(this->Header));
+    return;
+  }
+  if (this->Header->sh_type == SHT_REL) {
+    this->copyRelocations(Buf + OutSecOff, EObj.rels(this->Header));
+    return;
+  }
+
   memcpy(Buf + OutSecOff, Data.data(), Data.size());
 
-  ELFFile<ELFT> &EObj = this->File->getObj();
   uint8_t *BufEnd = Buf + OutSecOff + Data.size();
   // Iterate over all relocation sections that apply to this section.
   for (const Elf_Shdr *RelSec : this->RelocSections) {
     if (RelSec->sh_type == SHT_RELA)
       this->relocate(Buf, BufEnd, EObj.relas(RelSec));
     else
       this->relocate(Buf, BufEnd, EObj.rels(RelSec));
   }
 }
 
 template <class ELFT>
 SplitInputSection<ELFT>::SplitInputSection(
     ObjectFile<ELFT> *File, const Elf_Shdr *Header,
     typename InputSectionBase<ELFT>::Kind SectionKind)
     : InputSectionBase<ELFT>(File, Header, SectionKind) {}
 
 template <class ELFT>
 EHInputSection<ELFT>::EHInputSection(ObjectFile<ELFT> *F,
                                      const Elf_Shdr *Header)
     : SplitInputSection<ELFT>(F, Header, InputSectionBase<ELFT>::EHFrame) {
   // Mark .eh_frame sections as live by default because there are
   // usually no relocations that point to .eh_frames. Otherwise,
   // the garbage collector would drop all .eh_frame sections.
   this->Live = true;
 }
 
 template <class ELFT>
 bool EHInputSection<ELFT>::classof(const InputSectionBase<ELFT> *S) {
   return S->SectionKind == InputSectionBase<ELFT>::EHFrame;
 }
 
 template <class ELFT>
 typename EHInputSection<ELFT>::uintX_t
 EHInputSection<ELFT>::getOffset(uintX_t Offset) {
   // The file crtbeginT.o has relocations pointing to the start of an empty
   // .eh_frame that is known to be the first in the link. It does that to
   // identify the start of the output .eh_frame. Handle this special case.
   if (this->getSectionHdr()->sh_size == 0)
     return Offset;
   std::pair<uintX_t, uintX_t> *I = this->getRangeAndSize(Offset).first;
   uintX_t Base = I->second;
   if (Base == uintX_t(-1))
     return -1; // Not in the output
 
   uintX_t Addend = Offset - I->first;
   return Base + Addend;
 }
 
 template <class ELFT>
 MergeInputSection<ELFT>::MergeInputSection(ObjectFile<ELFT> *F,
                                            const Elf_Shdr *Header)
     : SplitInputSection<ELFT>(F, Header, InputSectionBase<ELFT>::Merge) {}
 
 template <class ELFT>
 bool MergeInputSection<ELFT>::classof(const InputSectionBase<ELFT> *S) {
   return S->SectionKind == InputSectionBase<ELFT>::Merge;
 }
 
 template <class ELFT>
 std::pair<std::pair<typename ELFFile<ELFT>::uintX_t,
                     typename ELFFile<ELFT>::uintX_t> *,
           typename ELFFile<ELFT>::uintX_t>
 SplitInputSection<ELFT>::getRangeAndSize(uintX_t Offset) {
   ArrayRef<uint8_t> D = this->getSectionData();
   StringRef Data((const char *)D.data(), D.size());
   uintX_t Size = Data.size();
   if (Offset >= Size)
     fatal("Entry is past the end of the section");
 
   // Find the element this offset points to.
   auto I = std::upper_bound(
       Offsets.begin(), Offsets.end(), Offset,
       [](const uintX_t &A, const std::pair<uintX_t, uintX_t> &B) {
         return A < B.first;
       });
   uintX_t End = I == Offsets.end() ? Data.size() : I->first;
   --I;
   return std::make_pair(&*I, End);
 }
 
 template <class ELFT>
 typename MergeInputSection<ELFT>::uintX_t
 MergeInputSection<ELFT>::getOffset(uintX_t Offset) {
   std::pair<std::pair<uintX_t, uintX_t> *, uintX_t> T =
       this->getRangeAndSize(Offset);
   std::pair<uintX_t, uintX_t> *I = T.first;
   uintX_t End = T.second;
   uintX_t Start = I->first;
 
   // Compute the Addend and if the Base is cached, return.
   uintX_t Addend = Offset - Start;
   uintX_t &Base = I->second;
   if (Base != uintX_t(-1))
     return Base + Addend;
 
   // Map the base to the offset in the output section and cache it.
   ArrayRef<uint8_t> D = this->getSectionData();
   StringRef Data((const char *)D.data(), D.size());
   StringRef Entry = Data.substr(Start, End - Start);
   Base =
       static_cast<MergeOutputSection<ELFT> *>(this->OutSec)->getOffset(Entry);
   return Base + Addend;
 }
 
 template <class ELFT>
 MipsReginfoInputSection<ELFT>::MipsReginfoInputSection(ObjectFile<ELFT> *F,
                                                        const Elf_Shdr *Hdr)
     : InputSectionBase<ELFT>(F, Hdr, InputSectionBase<ELFT>::MipsReginfo) {
   // Initialize this->Reginfo.
   ArrayRef<uint8_t> D = this->getSectionData();
   if (D.size() != sizeof(Elf_Mips_RegInfo<ELFT>))
     fatal("Invalid size of .reginfo section");
   Reginfo = reinterpret_cast<const Elf_Mips_RegInfo<ELFT> *>(D.data());
 }
 
 template <class ELFT>
 bool MipsReginfoInputSection<ELFT>::classof(const InputSectionBase<ELFT> *S) {
   return S->SectionKind == InputSectionBase<ELFT>::MipsReginfo;
 }
 
 template class elf2::InputSectionBase<ELF32LE>;
 template class elf2::InputSectionBase<ELF32BE>;
 template class elf2::InputSectionBase<ELF64LE>;
 template class elf2::InputSectionBase<ELF64BE>;
 
 template class elf2::InputSection<ELF32LE>;
 template class elf2::InputSection<ELF32BE>;
 template class elf2::InputSection<ELF64LE>;
 template class elf2::InputSection<ELF64BE>;
 
 template class elf2::EHInputSection<ELF32LE>;
 template class elf2::EHInputSection<ELF32BE>;
 template class elf2::EHInputSection<ELF64LE>;
 template class elf2::EHInputSection<ELF64BE>;
 
 template class elf2::MergeInputSection<ELF32LE>;
 template class elf2::MergeInputSection<ELF32BE>;
 template class elf2::MergeInputSection<ELF64LE>;
 template class elf2::MergeInputSection<ELF64BE>;
 
 template class elf2::MipsReginfoInputSection<ELF32LE>;
 template class elf2::MipsReginfoInputSection<ELF32BE>;
 template class elf2::MipsReginfoInputSection<ELF64LE>;
 template class elf2::MipsReginfoInputSection<ELF64BE>;
diff --git a/ELF/InputSection.h b/ELF/InputSection.h
index f0d4972..04eaf14 100644
--- a/ELF/InputSection.h
+++ b/ELF/InputSection.h
@@ -1,193 +1,197 @@
 //===- InputSection.h -------------------------------------------*- C++ -*-===//
 //
 //                             The LLVM Linker
 //
 // This file is distributed under the University of Illinois Open Source
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLD_ELF_INPUT_SECTION_H
 #define LLD_ELF_INPUT_SECTION_H
 
 #include "Config.h"
 #include "lld/Core/LLVM.h"
 #include "llvm/ADT/TinyPtrVector.h"
 #include "llvm/Object/ELF.h"
 
 namespace lld {
 namespace elf2 {
 
 template <class ELFT> class ObjectFile;
 template <class ELFT> class OutputSection;
 template <class ELFT> class OutputSectionBase;
 
 // This corresponds to a section of an input file.
 template <class ELFT> class InputSectionBase {
 protected:
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Rel Elf_Rel;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Rela Elf_Rela;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
   const Elf_Shdr *Header;
 
   // The file this section is from.
   ObjectFile<ELFT> *File;
 
 public:
   enum Kind { Regular, EHFrame, Merge, MipsReginfo };
   Kind SectionKind;
 
   InputSectionBase(ObjectFile<ELFT> *File, const Elf_Shdr *Header,
                    Kind SectionKind);
   OutputSectionBase<ELFT> *OutSec = nullptr;
 
   // Used for garbage collection.
   // Live bit makes sense only when Config->GcSections is true.
   bool isLive() const { return !Config->GcSections || Live; }
   bool Live = false;
 
   // Returns the size of this section (even if this is a common or BSS.)
   size_t getSize() const { return Header->sh_size; }
 
   static InputSectionBase<ELFT> Discarded;
 
   StringRef getSectionName() const;
   const Elf_Shdr *getSectionHdr() const { return Header; }
   ObjectFile<ELFT> *getFile() const { return File; }
 
   // The writer sets and uses the addresses.
   uintX_t getAlign() {
     // The ELF spec states that a value of 0 means the section has no alignment
     // constraits.
     return std::max<uintX_t>(Header->sh_addralign, 1);
   }
 
   uintX_t getOffset(const Elf_Sym &Sym);
 
   // Translate an offset in the input section to an offset in the output
   // section.
   uintX_t getOffset(uintX_t Offset);
 
   ArrayRef<uint8_t> getSectionData() const;
 
   // Returns a section that Rel is pointing to. Used by the garbage collector.
   InputSectionBase<ELFT> *getRelocTarget(const Elf_Rel &Rel);
   InputSectionBase<ELFT> *getRelocTarget(const Elf_Rela &Rel);
 
   template <bool isRela>
   using RelIteratorRange =
       llvm::iterator_range<const llvm::object::Elf_Rel_Impl<ELFT, isRela> *>;
 
   template <bool isRela>
   void relocate(uint8_t *Buf, uint8_t *BufEnd, RelIteratorRange<isRela> Rels);
 
+  InputSectionBase<ELFT> *getRelocatedSection();
+  template <bool isRela>
+  void copyRelocations(uint8_t *Buf, RelIteratorRange<isRela> Rels);
+
 private:
   template <bool isRela>
   uint8_t *findMipsPairedReloc(uint8_t *Buf, uint32_t SymIndex, uint32_t Type,
                                RelIteratorRange<isRela> Rels);
 };
 
 template <class ELFT>
 InputSectionBase<ELFT>
     InputSectionBase<ELFT>::Discarded(nullptr, nullptr,
                                       InputSectionBase<ELFT>::Regular);
 
 // Usually sections are copied to the output as atomic chunks of data,
 // but some special types of sections are split into small pieces of data
 // and each piece is copied to a different place in the output.
 // This class represents such special sections.
 template <class ELFT> class SplitInputSection : public InputSectionBase<ELFT> {
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
 
 public:
   SplitInputSection(ObjectFile<ELFT> *File, const Elf_Shdr *Header,
                     typename InputSectionBase<ELFT>::Kind SectionKind);
 
   // For each piece of data, we maintain the offsets in the input section and
   // in the output section. The latter may be -1 if it is not assigned yet.
   std::vector<std::pair<uintX_t, uintX_t>> Offsets;
 
   std::pair<std::pair<uintX_t, uintX_t> *, uintX_t>
   getRangeAndSize(uintX_t Offset);
 };
 
 // This corresponds to a SHF_MERGE section of an input file.
 template <class ELFT> class MergeInputSection : public SplitInputSection<ELFT> {
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
 
 public:
   MergeInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header);
   static bool classof(const InputSectionBase<ELFT> *S);
   // Translate an offset in the input section to an offset in the output
   // section.
   uintX_t getOffset(uintX_t Offset);
 };
 
 // This corresponds to a .eh_frame section of an input file.
 template <class ELFT> class EHInputSection : public SplitInputSection<ELFT> {
 public:
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
   EHInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header);
   static bool classof(const InputSectionBase<ELFT> *S);
 
   // Translate an offset in the input section to an offset in the output
   // section.
   uintX_t getOffset(uintX_t Offset);
 
   // Relocation section that refer to this one.
   const Elf_Shdr *RelocSection = nullptr;
 };
 
 // This corresponds to a non SHF_MERGE section of an input file.
 template <class ELFT> class InputSection : public InputSectionBase<ELFT> {
   typedef InputSectionBase<ELFT> Base;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Rela Elf_Rela;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Rel Elf_Rel;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
 
 public:
   InputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header);
 
   // Write this section to a mmap'ed file, assuming Buf is pointing to
   // beginning of the output section.
   void writeTo(uint8_t *Buf);
 
   // Relocation sections that refer to this one.
   llvm::TinyPtrVector<const Elf_Shdr *> RelocSections;
 
   // The offset from beginning of the output sections this section was assigned
   // to. The writer sets a value.
   uint64_t OutSecOff = 0;
 
   static bool classof(const InputSectionBase<ELFT> *S);
 };
 
 // MIPS .reginfo section provides information on the registers used by the code
 // in the object file. Linker should collect this information and write a single
 // .reginfo section in the output file. The output section contains a union of
 // used registers masks taken from input .reginfo sections and final value
 // of the `_gp` symbol.  For details: Chapter 4 / "Register Information" at
 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
 template <class ELFT>
 class MipsReginfoInputSection : public InputSectionBase<ELFT> {
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
 
 public:
   MipsReginfoInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Hdr);
   static bool classof(const InputSectionBase<ELFT> *S);
 
   const llvm::object::Elf_Mips_RegInfo<ELFT> *Reginfo;
 };
 
 } // namespace elf2
 } // namespace lld
 
 #endif
diff --git a/ELF/Options.td b/ELF/Options.td
index 40bab6a..f0f2fac 100644
--- a/ELF/Options.td
+++ b/ELF/Options.td
@@ -1,173 +1,174 @@
 include "llvm/Option/OptParser.td"
 
 def Bsymbolic: Flag<["-"], "Bsymbolic">,
   HelpText<"Bind defined symbols locally">;
 
 def Bsymbolic_functions: Flag<["-"], "Bsymbolic-functions">,
   HelpText<"Bind defined function symbols locally">;
 
 def Bdynamic: Flag<["-"], "Bdynamic">,
   HelpText<"Link against shared libraries">;
 
 def Bstatic: Flag<["-"], "Bstatic">,
   HelpText<"Do not link against shared libraries">;
 
 def L : JoinedOrSeparate<["-"], "L">, MetaVarName<"<dir>">,
   HelpText<"Directory to search for libraries">;
 
 def O : Joined<["-"], "O">, HelpText<"Optimize">;
 
 def allow_multiple_definition: Flag<["--"], "allow-multiple-definition">,
   HelpText<"Allow multiple definitions">;
 
 def allow_shlib_undefined : Flag<["--", "-"], "allow-shlib-undefined">;
 
 def as_needed : Flag<["--"], "as-needed">;
 
 def disable_new_dtags : Flag<["--"], "disable-new-dtags">,
   HelpText<"Disable new dynamic tags">;
 
 def discard_all : Flag<["-"], "discard-all">,
   HelpText<"Delete all local symbols">;
 
 def discard_locals : Flag<["-"], "discard-locals">,
   HelpText<"Delete temporary local symbols">;
 
 def discard_none : Flag<["-"], "discard-none">,
   HelpText<"Keep all symbols in the symbol table">;
 
 def dynamic_linker : Separate<["--", "-"], "dynamic-linker">,
   HelpText<"Which dynamic linker to use">;
 
 def eh_frame_hdr : Flag<["--"], "eh-frame-hdr">,
   HelpText<"Request creation of .eh_frame_hdr section and PT_GNU_EH_FRAME segment header">;
 
 def enable_new_dtags : Flag<["--"], "enable-new-dtags">,
   HelpText<"Enable new dynamic tags">;
 
 def entry : Separate<["--", "-"], "entry">, MetaVarName<"<entry>">,
   HelpText<"Name of entry point symbol">;
 
 def export_dynamic : Flag<["--", "-"], "export-dynamic">,
   HelpText<"Put symbols in the dynamic symbol table">;
 
 def fini : Separate<["-"], "fini">, MetaVarName<"<symbol>">,
   HelpText<"Specify a finalizer function">;
 
 def hash_style : Separate<["--", "-"], "hash-style">,
   HelpText<"Specify hash style (sysv, gnu or both)">;
 
 def gc_sections : Flag<["--"], "gc-sections">,
   HelpText<"Enable garbage collection of unused sections">;
 
 def init : Separate<["-"], "init">, MetaVarName<"<symbol>">,
   HelpText<"Specify an initializer function">;
 
 def l : JoinedOrSeparate<["-"], "l">, MetaVarName<"<libName>">,
   HelpText<"Root name of library to use">;
 
 def m : JoinedOrSeparate<["-"], "m">,
   HelpText<"Set target emulation">;
 
 def no_allow_shlib_undefined : Flag<["--"], "no-allow-shlib-undefined">;
 
 def no_as_needed : Flag<["--"], "no-as-needed">;
 
 def no_demangle: Flag<["--"], "no-demangle">,
   HelpText<"Demangle symbol names">;
 
 def no_whole_archive : Flag<["--", "-"], "no-whole-archive">,
   HelpText<"Restores the default behavior of loading archive members">;
 
 def noinhibit_exec : Flag<["--"], "noinhibit-exec">,
   HelpText<"Retain the executable output file whenever it is still usable">;
 
 def no_undefined : Flag<["--"], "no-undefined">,
   HelpText<"Report unresolved symbols even if the linker is creating a shared library">;
 
 def o : Separate<["-"], "o">, MetaVarName<"<path>">,
   HelpText<"Path to file to write output">;
 
 def print_gc_sections: Flag<["--"], "print-gc-sections">,
   HelpText<"List removed unused sections">;
 
 def rpath : Separate<["-"], "rpath">,
   HelpText<"Add a DT_RUNPATH to the output">;
 
-def relocatable : Flag<["--"], "relocatable">;
+def relocatable : Flag<["--"], "relocatable">,
+  HelpText<"Create relocatable object file">;
 
 def script : Separate<["--"], "script">, HelpText<"Read linker script">;
 
 def shared : Flag<["-"], "shared">,
   HelpText<"Build a shared object">;
 
 def soname : Joined<["-"], "soname=">,
   HelpText<"Set DT_SONAME">;
 
 def strip_all : Flag<["--"], "strip-all">,
   HelpText<"Strip all symbols">;
 
 def sysroot : Joined<["--"], "sysroot=">,
   HelpText<"Set the system root">;
 
 def undefined : Joined<["--"], "undefined=">,
   HelpText<"Force undefined symbol during linking">;
 
 def verbose : Flag<["--"], "verbose">;
 
 def whole_archive : Flag<["--", "-"], "whole-archive">,
   HelpText<"Force load of all members in a static library">;
 
 def wrap : Separate<["--", "-"], "wrap">, MetaVarName<"<symbol>">,
   HelpText<"Use wrapper functions for symbol">;
 
 def z : JoinedOrSeparate<["-"], "z">, MetaVarName<"<option>">,
   HelpText<"Linker option extensions">;
 
 // Aliases
 def alias_Bdynamic_call_shared: Flag<["-"], "call_shared">, Alias<Bdynamic>;
 def alias_Bdynamic_dy: Flag<["-"], "dy">, Alias<Bdynamic>;
 def alias_Bstatic_dn: Flag<["-"], "dn">, Alias<Bstatic>;
 def alias_Bstatic_non_shared: Flag<["-"], "non_shared">, Alias<Bstatic>;
 def alias_Bstatic_static: Flag<["-"], "static">, Alias<Bstatic>;
 def alias_L__library_path : Joined<["--"], "library-path=">, Alias<L>;
 def alias_discard_all_x: Flag<["-"], "x">, Alias<discard_all>;
 def alias_discard_locals_X: Flag<["-"], "X">, Alias<discard_locals>;
 def alias_entry_e : Separate<["-"], "e">, Alias<entry>;
 def alias_export_dynamic_E: Flag<["-"], "E">, Alias<export_dynamic>;
 def alias_fini_fini : Joined<["-"], "fini=">, Alias<fini>;
 def alias_hash_style_hash_style : Joined<["--", "-"], "hash-style=">, Alias<hash_style>;
 def alias_init_init : Joined<["-"], "init=">, Alias<init>;
 def alias_l__library : Joined<["--"], "library=">, Alias<l>;
 def alias_o_output : Joined<["--"], "output=">, Alias<o>;
 def alias_rpath_rpath : Joined<["-"], "rpath=">, Alias<rpath>;
 def alias_relocatable_r : Flag<["-"], "r">, Alias<relocatable>;
 def alias_shared_Bshareable : Flag<["-"], "Bshareable">, Alias<shared>;
 def alias_soname_h : Separate<["-"], "h">, Alias<soname>;
 def alias_soname_soname : Separate<["-"], "soname">, Alias<soname>;
 def alias_script_T : Separate<["-"], "T">, Alias<script>;
 def alias_strip_all: Flag<["-"], "s">, Alias<strip_all>;
 def alias_undefined_u : Separate<["-"], "u">, Alias<undefined>;
 def alias_wrap_wrap : Joined<["--", "-"], "wrap=">, Alias<wrap>;
 
 // Our symbol resolution algorithm handles symbols in archive files differently
 // than traditional linkers, so we don't need --start-group and --end-group.
 // These options are recongized for compatibility but ignored.
 def end_group : Flag<["--"], "end-group">;
 def end_group_paren: Flag<["-"], ")">;
 def start_group : Flag<["--"], "start-group">;
 def start_group_paren: Flag<["-"], "(">;
 
 // Options listed below are silently ignored for now for compatibility.
 def build_id : Flag<["--"], "build-id">;
 def fatal_warnings : Flag<["--"], "fatal-warnings">;
 def no_add_needed : Flag<["--"], "no-add-needed">;
 def no_fatal_warnings : Flag<["--"], "no-fatal-warnings">;
 def no_warn_mismatch : Flag<["--"], "no-warn-mismatch">;
 def version_script : Separate<["--"], "version-script">;
 def warn_common : Flag<["--"], "warn-common">;
 def warn_shared_textrel : Flag<["--"], "warn-shared-textrel">;
 def G : Separate<["-"], "G">;
 
 // Aliases for ignored options
 def alias_version_script_version_script : Joined<["--"], "version-script=">, Alias<version_script>;
diff --git a/ELF/OutputSections.cpp b/ELF/OutputSections.cpp
index c7fd991..2e5a18f 100644
--- a/ELF/OutputSections.cpp
+++ b/ELF/OutputSections.cpp
@@ -1,1651 +1,1673 @@
 //===- OutputSections.cpp -------------------------------------------------===//
 //
 //                             The LLVM Linker
 //
 // This file is distributed under the University of Illinois Open Source
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 
 #include "OutputSections.h"
 #include "Config.h"
 #include "SymbolTable.h"
 #include "Target.h"
 #include "llvm/Support/Dwarf.h"
 #include "llvm/Support/MathExtras.h"
 #include <map>
 
 using namespace llvm;
 using namespace llvm::dwarf;
 using namespace llvm::object;
 using namespace llvm::support::endian;
 using namespace llvm::ELF;
 
 using namespace lld;
 using namespace lld::elf2;
 
 template <class ELFT>
 OutputSectionBase<ELFT>::OutputSectionBase(StringRef Name, uint32_t Type,
                                            uintX_t Flags)
     : Name(Name) {
   memset(&Header, 0, sizeof(Elf_Shdr));
   Header.sh_type = Type;
   Header.sh_flags = Flags;
 }
 
 template <class ELFT>
 GotPltSection<ELFT>::GotPltSection()
     : OutputSectionBase<ELFT>(".got.plt", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) {
   this->Header.sh_addralign = sizeof(uintX_t);
 }
 
 template <class ELFT> void GotPltSection<ELFT>::addEntry(SymbolBody *Sym) {
   Sym->GotPltIndex = Target->GotPltHeaderEntriesNum + Entries.size();
   Entries.push_back(Sym);
 }
 
 template <class ELFT> bool GotPltSection<ELFT>::empty() const {
   return Entries.empty();
 }
 
 template <class ELFT> void GotPltSection<ELFT>::finalize() {
   this->Header.sh_size =
       (Target->GotPltHeaderEntriesNum + Entries.size()) * sizeof(uintX_t);
 }
 
 template <class ELFT> void GotPltSection<ELFT>::writeTo(uint8_t *Buf) {
   Target->writeGotPltHeader(Buf);
   Buf += Target->GotPltHeaderEntriesNum * sizeof(uintX_t);
   for (const SymbolBody *B : Entries) {
     Target->writeGotPlt(Buf, B->getPltVA<ELFT>());
     Buf += sizeof(uintX_t);
   }
 }
 
 template <class ELFT>
 GotSection<ELFT>::GotSection()
     : OutputSectionBase<ELFT>(".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) {
   if (Config->EMachine == EM_MIPS)
     this->Header.sh_flags |= SHF_MIPS_GPREL;
   this->Header.sh_addralign = sizeof(uintX_t);
 }
 
 template <class ELFT> void GotSection<ELFT>::addEntry(SymbolBody *Sym) {
   Sym->GotIndex = Entries.size();
   Entries.push_back(Sym);
 }
 
 template <class ELFT> void GotSection<ELFT>::addMipsLocalEntry() {
   ++MipsLocalEntries;
 }
 
 template <class ELFT> bool GotSection<ELFT>::addDynTlsEntry(SymbolBody *Sym) {
   if (Sym->hasGlobalDynIndex())
     return false;
   Sym->GlobalDynIndex = Target->GotHeaderEntriesNum + Entries.size();
   // Global Dynamic TLS entries take two GOT slots.
   Entries.push_back(Sym);
   Entries.push_back(nullptr);
   return true;
 }
 
 // Reserves TLS entries for a TLS module ID and a TLS block offset.
 // In total it takes two GOT slots.
 template <class ELFT> bool GotSection<ELFT>::addTlsIndex() {
   if (TlsIndexOff != uint32_t(-1))
     return false;
   TlsIndexOff = Entries.size() * sizeof(uintX_t);
   Entries.push_back(nullptr);
   Entries.push_back(nullptr);
   return true;
 }
 
 template <class ELFT>
 typename GotSection<ELFT>::uintX_t
 GotSection<ELFT>::getMipsLocalFullAddr(const SymbolBody &B) {
   return getMipsLocalEntryAddr(B.getVA<ELFT>());
 }
 
 template <class ELFT>
 typename GotSection<ELFT>::uintX_t
 GotSection<ELFT>::getMipsLocalPageAddr(uintX_t EntryValue) {
   // Initialize the entry by the %hi(EntryValue) expression
   // but without right-shifting.
   return getMipsLocalEntryAddr((EntryValue + 0x8000) & ~0xffff);
 }
 
 template <class ELFT>
 typename GotSection<ELFT>::uintX_t
 GotSection<ELFT>::getMipsLocalEntryAddr(uintX_t EntryValue) {
   size_t NewIndex = Target->GotHeaderEntriesNum + MipsLocalGotPos.size();
   auto P = MipsLocalGotPos.insert(std::make_pair(EntryValue, NewIndex));
   assert(!P.second || MipsLocalGotPos.size() <= MipsLocalEntries);
   return this->getVA() + P.first->second * sizeof(uintX_t);
 }
 
 template <class ELFT>
 typename GotSection<ELFT>::uintX_t
 GotSection<ELFT>::getGlobalDynAddr(const SymbolBody &B) const {
   return this->getVA() + B.GlobalDynIndex * sizeof(uintX_t);
 }
 
 template <class ELFT>
 const SymbolBody *GotSection<ELFT>::getMipsFirstGlobalEntry() const {
   return Entries.empty() ? nullptr : Entries.front();
 }
 
 template <class ELFT>
 unsigned GotSection<ELFT>::getMipsLocalEntriesNum() const {
   return Target->GotHeaderEntriesNum + MipsLocalEntries;
 }
 
 template <class ELFT> void GotSection<ELFT>::finalize() {
   this->Header.sh_size =
       (Target->GotHeaderEntriesNum + MipsLocalEntries + Entries.size()) *
       sizeof(uintX_t);
 }
 
 template <class ELFT> void GotSection<ELFT>::writeTo(uint8_t *Buf) {
   Target->writeGotHeader(Buf);
   for (std::pair<uintX_t, size_t> &L : MipsLocalGotPos) {
     uint8_t *Entry = Buf + L.second * sizeof(uintX_t);
     write<uintX_t, ELFT::TargetEndianness, sizeof(uintX_t)>(Entry, L.first);
   }
   Buf += Target->GotHeaderEntriesNum * sizeof(uintX_t);
   Buf += MipsLocalEntries * sizeof(uintX_t);
   for (const SymbolBody *B : Entries) {
     uint8_t *Entry = Buf;
     Buf += sizeof(uintX_t);
     if (!B)
       continue;
     // MIPS has special rules to fill up GOT entries.
     // See "Global Offset Table" in Chapter 5 in the following document
     // for detailed description:
     // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
     // As the first approach, we can just store addresses for all symbols.
     if (Config->EMachine != EM_MIPS && canBePreempted(B, false))
       continue; // The dynamic linker will take care of it.
     uintX_t VA = B->getVA<ELFT>();
     write<uintX_t, ELFT::TargetEndianness, sizeof(uintX_t)>(Entry, VA);
   }
 }
 
 template <class ELFT>
 PltSection<ELFT>::PltSection()
     : OutputSectionBase<ELFT>(".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR) {
   this->Header.sh_addralign = 16;
 }
 
 template <class ELFT> void PltSection<ELFT>::writeTo(uint8_t *Buf) {
   size_t Off = 0;
   if (Target->UseLazyBinding) {
     // At beginning of PLT, we have code to call the dynamic linker
     // to resolve dynsyms at runtime. Write such code.
     Target->writePltZero(Buf);
     Off += Target->PltZeroSize;
   }
   for (auto &I : Entries) {
     const SymbolBody *B = I.first;
     unsigned RelOff = I.second;
     uint64_t Got =
         Target->UseLazyBinding ? B->getGotPltVA<ELFT>() : B->getGotVA<ELFT>();
     uint64_t Plt = this->getVA() + Off;
     Target->writePlt(Buf + Off, Got, Plt, B->PltIndex, RelOff);
     Off += Target->PltEntrySize;
   }
 }
 
 template <class ELFT> void PltSection<ELFT>::addEntry(SymbolBody *Sym) {
   Sym->PltIndex = Entries.size();
   unsigned RelOff = Target->UseLazyBinding
                         ? Out<ELFT>::RelaPlt->getRelocOffset()
                         : Out<ELFT>::RelaDyn->getRelocOffset();
   Entries.push_back(std::make_pair(Sym, RelOff));
 }
 
 template <class ELFT> void PltSection<ELFT>::finalize() {
   this->Header.sh_size =
       Target->PltZeroSize + Entries.size() * Target->PltEntrySize;
 }
 
 template <class ELFT>
 RelocationSection<ELFT>::RelocationSection(StringRef Name, bool IsRela)
     : OutputSectionBase<ELFT>(Name, IsRela ? SHT_RELA : SHT_REL, SHF_ALLOC),
       IsRela(IsRela) {
   this->Header.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
   this->Header.sh_addralign = sizeof(uintX_t);
 }
 
 template <class ELFT>
 void RelocationSection<ELFT>::addReloc(const DynamicReloc<ELFT> &Reloc) {
   SymbolBody *Sym = Reloc.Sym;
   if (!Reloc.UseSymVA && Sym)
     Sym->MustBeInDynSym = true;
   Relocs.push_back(Reloc);
 }
 
 template <class ELFT>
 typename ELFFile<ELFT>::uintX_t DynamicReloc<ELFT>::getOffset() const {
   switch (OKind) {
   case Off_GTlsIndex:
     return Out<ELFT>::Got->getGlobalDynAddr(*Sym);
   case Off_GTlsOffset:
     return Out<ELFT>::Got->getGlobalDynAddr(*Sym) + sizeof(uintX_t);
   case Off_LTlsIndex:
     return Out<ELFT>::Got->getTlsIndexVA();
   case Off_Sec:
     return OffsetSec->getOffset(OffsetInSec) + OffsetSec->OutSec->getVA();
   case Off_Bss:
     return cast<SharedSymbol<ELFT>>(Sym)->OffsetInBss + Out<ELFT>::Bss->getVA();
   case Off_Got:
     return Sym->getGotVA<ELFT>();
   case Off_GotPlt:
     return Sym->getGotPltVA<ELFT>();
   }
   llvm_unreachable("Invalid offset kind");
 }
 
 template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
   for (const DynamicReloc<ELFT> &Rel : Relocs) {
     auto *P = reinterpret_cast<Elf_Rel *>(Buf);
     Buf += IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
     SymbolBody *Sym = Rel.Sym;
 
     if (IsRela) {
       uintX_t VA = 0;
       if (Rel.UseSymVA)
         VA = Sym->getVA<ELFT>();
       else if (Rel.TargetSec)
         VA = Rel.TargetSec->getOffset(Rel.OffsetInTargetSec) +
              Rel.TargetSec->OutSec->getVA();
       reinterpret_cast<Elf_Rela *>(P)->r_addend = Rel.Addend + VA;
     }
 
     P->r_offset = Rel.getOffset();
     uint32_t SymIdx = (!Rel.UseSymVA && Sym) ? Sym->DynsymIndex : 0;
     P->setSymbolAndType(SymIdx, Rel.Type, Config->Mips64EL);
   }
 }
 
 template <class ELFT> unsigned RelocationSection<ELFT>::getRelocOffset() {
   return this->Header.sh_entsize * Relocs.size();
 }
 
 template <class ELFT> void RelocationSection<ELFT>::finalize() {
   this->Header.sh_link = Static ? Out<ELFT>::SymTab->SectionIndex
                                 : Out<ELFT>::DynSymTab->SectionIndex;
   this->Header.sh_size = Relocs.size() * this->Header.sh_entsize;
 }
 
 template <class ELFT>
 InterpSection<ELFT>::InterpSection()
     : OutputSectionBase<ELFT>(".interp", SHT_PROGBITS, SHF_ALLOC) {
   this->Header.sh_size = Config->DynamicLinker.size() + 1;
   this->Header.sh_addralign = 1;
 }
 
 template <class ELFT>
 void OutputSectionBase<ELFT>::writeHeaderTo(Elf_Shdr *SHdr) {
   *SHdr = Header;
 }
 
 template <class ELFT> void InterpSection<ELFT>::writeTo(uint8_t *Buf) {
   memcpy(Buf, Config->DynamicLinker.data(), Config->DynamicLinker.size());
 }
 
 template <class ELFT>
 HashTableSection<ELFT>::HashTableSection()
     : OutputSectionBase<ELFT>(".hash", SHT_HASH, SHF_ALLOC) {
   this->Header.sh_entsize = sizeof(Elf_Word);
   this->Header.sh_addralign = sizeof(Elf_Word);
 }
 
 static uint32_t hashSysv(StringRef Name) {
   uint32_t H = 0;
   for (char C : Name) {
     H = (H << 4) + C;
     uint32_t G = H & 0xf0000000;
     if (G)
       H ^= G >> 24;
     H &= ~G;
   }
   return H;
 }
 
 template <class ELFT> void HashTableSection<ELFT>::finalize() {
   this->Header.sh_link = Out<ELFT>::DynSymTab->SectionIndex;
 
   unsigned NumEntries = 2;                             // nbucket and nchain.
   NumEntries += Out<ELFT>::DynSymTab->getNumSymbols(); // The chain entries.
 
   // Create as many buckets as there are symbols.
   // FIXME: This is simplistic. We can try to optimize it, but implementing
   // support for SHT_GNU_HASH is probably even more profitable.
   NumEntries += Out<ELFT>::DynSymTab->getNumSymbols();
   this->Header.sh_size = NumEntries * sizeof(Elf_Word);
 }
 
 template <class ELFT> void HashTableSection<ELFT>::writeTo(uint8_t *Buf) {
   unsigned NumSymbols = Out<ELFT>::DynSymTab->getNumSymbols();
   auto *P = reinterpret_cast<Elf_Word *>(Buf);
   *P++ = NumSymbols; // nbucket
   *P++ = NumSymbols; // nchain
 
   Elf_Word *Buckets = P;
   Elf_Word *Chains = P + NumSymbols;
 
   for (const std::pair<SymbolBody *, unsigned> &P :
        Out<ELFT>::DynSymTab->getSymbols()) {
     SymbolBody *Body = P.first;
     StringRef Name = Body->getName();
     unsigned I = Body->DynsymIndex;
     uint32_t Hash = hashSysv(Name) % NumSymbols;
     Chains[I] = Buckets[Hash];
     Buckets[Hash] = I;
   }
 }
 
 static uint32_t hashGnu(StringRef Name) {
   uint32_t H = 5381;
   for (uint8_t C : Name)
     H = (H << 5) + H + C;
   return H;
 }
 
 template <class ELFT>
 GnuHashTableSection<ELFT>::GnuHashTableSection()
     : OutputSectionBase<ELFT>(".gnu.hash", SHT_GNU_HASH, SHF_ALLOC) {
   this->Header.sh_entsize = ELFT::Is64Bits ? 0 : 4;
   this->Header.sh_addralign = sizeof(uintX_t);
 }
 
 template <class ELFT>
 unsigned GnuHashTableSection<ELFT>::calcNBuckets(unsigned NumHashed) {
   if (!NumHashed)
     return 0;
 
   // These values are prime numbers which are not greater than 2^(N-1) + 1.
   // In result, for any particular NumHashed we return a prime number
   // which is not greater than NumHashed.
   static const unsigned Primes[] = {
       1,   1,    3,    3,    7,    13,    31,    61,    127,   251,
       509, 1021, 2039, 4093, 8191, 16381, 32749, 65521, 131071};
 
   return Primes[std::min<unsigned>(Log2_32_Ceil(NumHashed),
                                    array_lengthof(Primes) - 1)];
 }
 
 // Bloom filter estimation: at least 8 bits for each hashed symbol.
 // GNU Hash table requirement: it should be a power of 2,
 //   the minimum value is 1, even for an empty table.
 // Expected results for a 32-bit target:
 //   calcMaskWords(0..4)   = 1
 //   calcMaskWords(5..8)   = 2
 //   calcMaskWords(9..16)  = 4
 // For a 64-bit target:
 //   calcMaskWords(0..8)   = 1
 //   calcMaskWords(9..16)  = 2
 //   calcMaskWords(17..32) = 4
 template <class ELFT>
 unsigned GnuHashTableSection<ELFT>::calcMaskWords(unsigned NumHashed) {
   if (!NumHashed)
     return 1;
   return NextPowerOf2((NumHashed - 1) / sizeof(Elf_Off));
 }
 
 template <class ELFT> void GnuHashTableSection<ELFT>::finalize() {
   unsigned NumHashed = Symbols.size();
   NBuckets = calcNBuckets(NumHashed);
   MaskWords = calcMaskWords(NumHashed);
   // Second hash shift estimation: just predefined values.
   Shift2 = ELFT::Is64Bits ? 6 : 5;
 
   this->Header.sh_link = Out<ELFT>::DynSymTab->SectionIndex;
   this->Header.sh_size = sizeof(Elf_Word) * 4            // Header
                          + sizeof(Elf_Off) * MaskWords   // Bloom Filter
                          + sizeof(Elf_Word) * NBuckets   // Hash Buckets
                          + sizeof(Elf_Word) * NumHashed; // Hash Values
 }
 
 template <class ELFT> void GnuHashTableSection<ELFT>::writeTo(uint8_t *Buf) {
   writeHeader(Buf);
   if (Symbols.empty())
     return;
   writeBloomFilter(Buf);
   writeHashTable(Buf);
 }
 
 template <class ELFT>
 void GnuHashTableSection<ELFT>::writeHeader(uint8_t *&Buf) {
   auto *P = reinterpret_cast<Elf_Word *>(Buf);
   *P++ = NBuckets;
   *P++ = Out<ELFT>::DynSymTab->getNumSymbols() - Symbols.size();
   *P++ = MaskWords;
   *P++ = Shift2;
   Buf = reinterpret_cast<uint8_t *>(P);
 }
 
 template <class ELFT>
 void GnuHashTableSection<ELFT>::writeBloomFilter(uint8_t *&Buf) {
   unsigned C = sizeof(Elf_Off) * 8;
 
   auto *Masks = reinterpret_cast<Elf_Off *>(Buf);
   for (const SymbolData &Sym : Symbols) {
     size_t Pos = (Sym.Hash / C) & (MaskWords - 1);
     uintX_t V = (uintX_t(1) << (Sym.Hash % C)) |
                 (uintX_t(1) << ((Sym.Hash >> Shift2) % C));
     Masks[Pos] |= V;
   }
   Buf += sizeof(Elf_Off) * MaskWords;
 }
 
 template <class ELFT>
 void GnuHashTableSection<ELFT>::writeHashTable(uint8_t *Buf) {
   Elf_Word *Buckets = reinterpret_cast<Elf_Word *>(Buf);
   Elf_Word *Values = Buckets + NBuckets;
 
   int PrevBucket = -1;
   int I = 0;
   for (const SymbolData &Sym : Symbols) {
     int Bucket = Sym.Hash % NBuckets;
     assert(PrevBucket <= Bucket);
     if (Bucket != PrevBucket) {
       Buckets[Bucket] = Sym.Body->DynsymIndex;
       PrevBucket = Bucket;
       if (I > 0)
         Values[I - 1] |= 1;
     }
     Values[I] = Sym.Hash & ~1;
     ++I;
   }
   if (I > 0)
     Values[I - 1] |= 1;
 }
 
 static bool includeInGnuHashTable(SymbolBody *B) {
   // Assume that includeInDynsym() is already checked.
   return !B->isUndefined();
 }
 
 // Add symbols to this symbol hash table. Note that this function
 // destructively sort a given vector -- which is needed because
 // GNU-style hash table places some sorting requirements.
 template <class ELFT>
 void GnuHashTableSection<ELFT>::addSymbols(
     std::vector<std::pair<SymbolBody *, size_t>> &V) {
   auto Mid = std::stable_partition(V.begin(), V.end(),
                                    [](std::pair<SymbolBody *, size_t> &P) {
                                      return !includeInGnuHashTable(P.first);
                                    });
   if (Mid == V.end())
     return;
   for (auto I = Mid, E = V.end(); I != E; ++I) {
     SymbolBody *B = I->first;
     size_t StrOff = I->second;
     Symbols.push_back({B, StrOff, hashGnu(B->getName())});
   }
 
   unsigned NBuckets = calcNBuckets(Symbols.size());
   std::stable_sort(Symbols.begin(), Symbols.end(),
                    [&](const SymbolData &L, const SymbolData &R) {
                      return L.Hash % NBuckets < R.Hash % NBuckets;
                    });
 
   V.erase(Mid, V.end());
   for (const SymbolData &Sym : Symbols)
     V.push_back({Sym.Body, Sym.STName});
 }
 
 template <class ELFT>
 DynamicSection<ELFT>::DynamicSection(SymbolTable<ELFT> &SymTab)
     : OutputSectionBase<ELFT>(".dynamic", SHT_DYNAMIC, SHF_ALLOC | SHF_WRITE),
       SymTab(SymTab) {
   Elf_Shdr &Header = this->Header;
   Header.sh_addralign = sizeof(uintX_t);
   Header.sh_entsize = ELFT::Is64Bits ? 16 : 8;
 
   // .dynamic section is not writable on MIPS.
   // See "Special Section" in Chapter 4 in the following document:
   // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
   if (Config->EMachine == EM_MIPS)
     Header.sh_flags = SHF_ALLOC;
 }
 
 template <class ELFT> void DynamicSection<ELFT>::finalize() {
   if (this->Header.sh_size)
     return; // Already finalized.
 
   Elf_Shdr &Header = this->Header;
   Header.sh_link = Out<ELFT>::DynStrTab->SectionIndex;
 
   auto Add = [=](Entry E) { Entries.push_back(E); };
 
   // Add strings. We know that these are the last strings to be added to
   // DynStrTab and doing this here allows this function to set DT_STRSZ.
   if (!Config->RPath.empty())
     Add({Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
          Out<ELFT>::DynStrTab->addString(Config->RPath)});
   for (const std::unique_ptr<SharedFile<ELFT>> &F : SymTab.getSharedFiles())
     if (F->isNeeded())
       Add({DT_NEEDED, Out<ELFT>::DynStrTab->addString(F->getSoName())});
   if (!Config->SoName.empty())
     Add({DT_SONAME, Out<ELFT>::DynStrTab->addString(Config->SoName)});
 
   Out<ELFT>::DynStrTab->finalize();
 
   if (Out<ELFT>::RelaDyn->hasRelocs()) {
     bool IsRela = Out<ELFT>::RelaDyn->isRela();
     Add({IsRela ? DT_RELA : DT_REL, Out<ELFT>::RelaDyn});
     Add({IsRela ? DT_RELASZ : DT_RELSZ, Out<ELFT>::RelaDyn->getSize()});
     Add({IsRela ? DT_RELAENT : DT_RELENT,
          uintX_t(IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel))});
   }
   if (Out<ELFT>::RelaPlt && Out<ELFT>::RelaPlt->hasRelocs()) {
     Add({DT_JMPREL, Out<ELFT>::RelaPlt});
     Add({DT_PLTRELSZ, Out<ELFT>::RelaPlt->getSize()});
     Add({Config->EMachine == EM_MIPS ? DT_MIPS_PLTGOT : DT_PLTGOT,
          Out<ELFT>::GotPlt});
     Add({DT_PLTREL, uint64_t(Out<ELFT>::RelaPlt->isRela() ? DT_RELA : DT_REL)});
   }
 
   Add({DT_SYMTAB, Out<ELFT>::DynSymTab});
   Add({DT_SYMENT, sizeof(Elf_Sym)});
   Add({DT_STRTAB, Out<ELFT>::DynStrTab});
   Add({DT_STRSZ, Out<ELFT>::DynStrTab->getSize()});
   if (Out<ELFT>::GnuHashTab)
     Add({DT_GNU_HASH, Out<ELFT>::GnuHashTab});
   if (Out<ELFT>::HashTab)
     Add({DT_HASH, Out<ELFT>::HashTab});
 
   if (PreInitArraySec) {
     Add({DT_PREINIT_ARRAY, PreInitArraySec});
     Add({DT_PREINIT_ARRAYSZ, PreInitArraySec->getSize()});
   }
   if (InitArraySec) {
     Add({DT_INIT_ARRAY, InitArraySec});
     Add({DT_INIT_ARRAYSZ, (uintX_t)InitArraySec->getSize()});
   }
   if (FiniArraySec) {
     Add({DT_FINI_ARRAY, FiniArraySec});
     Add({DT_FINI_ARRAYSZ, (uintX_t)FiniArraySec->getSize()});
   }
 
   if (SymbolBody *B = SymTab.find(Config->Init))
     Add({DT_INIT, B});
   if (SymbolBody *B = SymTab.find(Config->Fini))
     Add({DT_FINI, B});
 
   uint32_t DtFlags = 0;
   uint32_t DtFlags1 = 0;
   if (Config->Bsymbolic)
     DtFlags |= DF_SYMBOLIC;
   if (Config->ZNodelete)
     DtFlags1 |= DF_1_NODELETE;
   if (Config->ZNow) {
     DtFlags |= DF_BIND_NOW;
     DtFlags1 |= DF_1_NOW;
   }
   if (Config->ZOrigin) {
     DtFlags |= DF_ORIGIN;
     DtFlags1 |= DF_1_ORIGIN;
   }
 
   if (DtFlags)
     Add({DT_FLAGS, DtFlags});
   if (DtFlags1)
     Add({DT_FLAGS_1, DtFlags1});
 
   if (!Config->Entry.empty())
     Add({DT_DEBUG, (uint64_t)0});
 
   if (Config->EMachine == EM_MIPS) {
     Add({DT_MIPS_RLD_VERSION, 1});
     Add({DT_MIPS_FLAGS, RHF_NOTPOT});
     Add({DT_MIPS_BASE_ADDRESS, (uintX_t)Target->getVAStart()});
     Add({DT_MIPS_SYMTABNO, Out<ELFT>::DynSymTab->getNumSymbols()});
     Add({DT_MIPS_LOCAL_GOTNO, Out<ELFT>::Got->getMipsLocalEntriesNum()});
     if (const SymbolBody *B = Out<ELFT>::Got->getMipsFirstGlobalEntry())
       Add({DT_MIPS_GOTSYM, B->DynsymIndex});
     else
       Add({DT_MIPS_GOTSYM, Out<ELFT>::DynSymTab->getNumSymbols()});
     Add({DT_PLTGOT, Out<ELFT>::Got});
     if (Out<ELFT>::MipsRldMap)
       Add({DT_MIPS_RLD_MAP, Out<ELFT>::MipsRldMap});
   }
 
   // +1 for DT_NULL
   Header.sh_size = (Entries.size() + 1) * Header.sh_entsize;
 }
 
 template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
   auto *P = reinterpret_cast<Elf_Dyn *>(Buf);
 
   for (const Entry &E : Entries) {
     P->d_tag = E.Tag;
     switch (E.Kind) {
     case Entry::SecAddr:
       P->d_un.d_ptr = E.OutSec->getVA();
       break;
     case Entry::SymAddr:
       P->d_un.d_ptr = E.Sym->template getVA<ELFT>();
       break;
     case Entry::PlainInt:
       P->d_un.d_val = E.Val;
       break;
     }
     ++P;
   }
 }
 
 template <class ELFT>
 EhFrameHeader<ELFT>::EhFrameHeader()
     : OutputSectionBase<ELFT>(".eh_frame_hdr", llvm::ELF::SHT_PROGBITS,
                               SHF_ALLOC) {
   // It's a 4 bytes of header + pointer to the contents of the .eh_frame section
   // + the number of FDE pointers in the table.
   this->Header.sh_size = 12;
 }
 
 // We have to get PC values of FDEs. They depend on relocations
 // which are target specific, so we run this code after performing
 // all relocations. We read the values from ouput buffer according to the
 // encoding given for FDEs. Return value is an offset to the initial PC value
 // for the FDE.
 template <class ELFT>
 typename EhFrameHeader<ELFT>::uintX_t
 EhFrameHeader<ELFT>::getFdePc(uintX_t EhVA, const FdeData &F) {
   const endianness E = ELFT::TargetEndianness;
   assert((F.Enc & 0xF0) != DW_EH_PE_datarel);
 
   uintX_t FdeOff = EhVA + F.Off + 8;
   switch (F.Enc & 0xF) {
   case DW_EH_PE_udata2:
   case DW_EH_PE_sdata2:
     return FdeOff + read16<E>(F.PCRel);
   case DW_EH_PE_udata4:
   case DW_EH_PE_sdata4:
     return FdeOff + read32<E>(F.PCRel);
   case DW_EH_PE_udata8:
   case DW_EH_PE_sdata8:
     return FdeOff + read64<E>(F.PCRel);
   case DW_EH_PE_absptr:
     if (sizeof(uintX_t) == 8)
       return FdeOff + read64<E>(F.PCRel);
     return FdeOff + read32<E>(F.PCRel);
   }
   fatal("unknown FDE size encoding");
 }
 
 template <class ELFT> void EhFrameHeader<ELFT>::writeTo(uint8_t *Buf) {
   const endianness E = ELFT::TargetEndianness;
 
   const uint8_t Header[] = {1, DW_EH_PE_pcrel | DW_EH_PE_sdata4,
                             DW_EH_PE_udata4,
                             DW_EH_PE_datarel | DW_EH_PE_sdata4};
   memcpy(Buf, Header, sizeof(Header));
 
   uintX_t EhVA = Sec->getVA();
   uintX_t VA = this->getVA();
   uintX_t EhOff = EhVA - VA - 4;
   write32<E>(Buf + 4, EhOff);
   write32<E>(Buf + 8, this->FdeList.size());
   Buf += 12;
 
   // InitialPC -> Offset in .eh_frame, sorted by InitialPC.
   std::map<uintX_t, size_t> PcToOffset;
   for (const FdeData &F : FdeList)
     PcToOffset[getFdePc(EhVA, F)] = F.Off;
 
   for (auto &I : PcToOffset) {
     // The first four bytes are an offset to the initial PC value for the FDE.
     write32<E>(Buf, I.first - VA);
     // The last four bytes are an offset to the FDE data itself.
     write32<E>(Buf + 4, EhVA + I.second - VA);
     Buf += 8;
   }
 }
 
 template <class ELFT>
 void EhFrameHeader<ELFT>::assignEhFrame(EHOutputSection<ELFT> *Sec) {
   assert((!this->Sec || this->Sec == Sec) &&
          "multiple .eh_frame sections not supported for .eh_frame_hdr");
   Live = Config->EhFrameHdr;
   this->Sec = Sec;
 }
 
 template <class ELFT>
 void EhFrameHeader<ELFT>::addFde(uint8_t Enc, size_t Off, uint8_t *PCRel) {
   if (Live && (Enc & 0xF0) == DW_EH_PE_datarel)
     fatal("DW_EH_PE_datarel encoding unsupported for FDEs by .eh_frame_hdr");
   FdeList.push_back(FdeData{Enc, Off, PCRel});
 }
 
 template <class ELFT> void EhFrameHeader<ELFT>::reserveFde() {
   // Each FDE entry is 8 bytes long:
   // The first four bytes are an offset to the initial PC value for the FDE. The
   // last four byte are an offset to the FDE data itself.
   this->Header.sh_size += 8;
 }
 
 template <class ELFT>
-OutputSection<ELFT>::OutputSection(StringRef Name, uint32_t Type,
-                                   uintX_t Flags)
-    : OutputSectionBase<ELFT>(Name, Type, Flags) {}
+OutputSection<ELFT>::OutputSection(StringRef Name, uint32_t Type, uintX_t Flags)
+    : OutputSectionBase<ELFT>(Name, Type, Flags) {
+  if (Type == SHT_RELA)
+    this->Header.sh_entsize = sizeof(Elf_Rela);
+  else if (Type == SHT_REL)
+    this->Header.sh_entsize = sizeof(Elf_Rel);
+}
+
+template <class ELFT> void OutputSection<ELFT>::finalize() {
+  uint32_t Type = this->Header.sh_type;
+  if (Type != SHT_RELA && Type != SHT_REL)
+    return;
+  this->Header.sh_link = Out<ELFT>::SymTab->SectionIndex;
+  // sh_info for SHT_REL[A] sections should contain the section header index of
+  // the section to which the relocation applies.
+  InputSectionBase<ELFT> *RelocatedSection = Sections[0]->getRelocatedSection();
+  this->Header.sh_info = RelocatedSection->OutSec->SectionIndex;
+}
 
 template <class ELFT>
 void OutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
   auto *S = cast<InputSection<ELFT>>(C);
   Sections.push_back(S);
   S->OutSec = this;
   uint32_t Align = S->getAlign();
   this->updateAlign(Align);
 
   uintX_t Off = this->Header.sh_size;
   Off = alignTo(Off, Align);
   S->OutSecOff = Off;
   Off += S->getSize();
   this->Header.sh_size = Off;
 }
 
 // If an input string is in the form of "foo.N" where N is a number,
 // return N. Otherwise, returns 65536, which is one greater than the
 // lowest priority.
 static int getPriority(StringRef S) {
   size_t Pos = S.rfind('.');
   if (Pos == StringRef::npos)
     return 65536;
   int V;
   if (S.substr(Pos + 1).getAsInteger(10, V))
     return 65536;
   return V;
 }
 
 // This function is called after we sort input sections
 // to update their offsets.
 template <class ELFT> void OutputSection<ELFT>::reassignOffsets() {
   uintX_t Off = 0;
   for (InputSection<ELFT> *S : Sections) {
     Off = alignTo(Off, S->getAlign());
     S->OutSecOff = Off;
     Off += S->getSize();
   }
   this->Header.sh_size = Off;
 }
 
 // Sorts input sections by section name suffixes, so that .foo.N comes
 // before .foo.M if N < M. Used to sort .{init,fini}_array.N sections.
 // We want to keep the original order if the priorities are the same
 // because the compiler keeps the original initialization order in a
 // translation unit and we need to respect that.
 // For more detail, read the section of the GCC's manual about init_priority.
 template <class ELFT> void OutputSection<ELFT>::sortInitFini() {
   // Sort sections by priority.
   typedef std::pair<int, InputSection<ELFT> *> Pair;
   auto Comp = [](const Pair &A, const Pair &B) { return A.first < B.first; };
 
   std::vector<Pair> V;
   for (InputSection<ELFT> *S : Sections)
     V.push_back({getPriority(S->getSectionName()), S});
   std::stable_sort(V.begin(), V.end(), Comp);
   Sections.clear();
   for (Pair &P : V)
     Sections.push_back(P.second);
   reassignOffsets();
 }
 
 // Returns true if S matches /Filename.?\.o$/.
 static bool isCrtBeginEnd(StringRef S, StringRef Filename) {
   if (!S.endswith(".o"))
     return false;
   S = S.drop_back(2);
   if (S.endswith(Filename))
     return true;
   return !S.empty() && S.drop_back().endswith(Filename);
 }
 
 static bool isCrtbegin(StringRef S) { return isCrtBeginEnd(S, "crtbegin"); }
 static bool isCrtend(StringRef S) { return isCrtBeginEnd(S, "crtend"); }
 
 // .ctors and .dtors are sorted by this priority from highest to lowest.
 //
 //  1. The section was contained in crtbegin (crtbegin contains
 //     some sentinel value in its .ctors and .dtors so that the runtime
 //     can find the beginning of the sections.)
 //
 //  2. The section has an optional priority value in the form of ".ctors.N"
 //     or ".dtors.N" where N is a number. Unlike .{init,fini}_array,
 //     they are compared as string rather than number.
 //
 //  3. The section is just ".ctors" or ".dtors".
 //
 //  4. The section was contained in crtend, which contains an end marker.
 //
 // In an ideal world, we don't need this function because .init_array and
 // .ctors are duplicate features (and .init_array is newer.) However, there
 // are too many real-world use cases of .ctors, so we had no choice to
 // support that with this rather ad-hoc semantics.
 template <class ELFT>
 static bool compCtors(const InputSection<ELFT> *A,
                       const InputSection<ELFT> *B) {
   bool BeginA = isCrtbegin(A->getFile()->getName());
   bool BeginB = isCrtbegin(B->getFile()->getName());
   if (BeginA != BeginB)
     return BeginA;
   bool EndA = isCrtend(A->getFile()->getName());
   bool EndB = isCrtend(B->getFile()->getName());
   if (EndA != EndB)
     return EndB;
   StringRef X = A->getSectionName();
   StringRef Y = B->getSectionName();
   assert(X.startswith(".ctors") || X.startswith(".dtors"));
   assert(Y.startswith(".ctors") || Y.startswith(".dtors"));
   X = X.substr(6);
   Y = Y.substr(6);
   if (X.empty() && Y.empty())
     return false;
   return X < Y;
 }
 
 // Sorts input sections by the special rules for .ctors and .dtors.
 // Unfortunately, the rules are different from the one for .{init,fini}_array.
 // Read the comment above.
 template <class ELFT> void OutputSection<ELFT>::sortCtorsDtors() {
   std::stable_sort(Sections.begin(), Sections.end(), compCtors<ELFT>);
   reassignOffsets();
 }
 
 // Returns a VA which a relocatin RI refers to. Used only for local symbols.
 // For non-local symbols, use SymbolBody::getVA instead.
 template <class ELFT, bool IsRela>
 typename ELFFile<ELFT>::uintX_t
 elf2::getLocalRelTarget(const ObjectFile<ELFT> &File,
                         const Elf_Rel_Impl<ELFT, IsRela> &RI,
                         typename ELFFile<ELFT>::uintX_t Addend) {
   typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
   typedef typename ELFFile<ELFT>::uintX_t uintX_t;
 
   // PPC64 has a special relocation representing the TOC base pointer
   // that does not have a corresponding symbol.
   if (Config->EMachine == EM_PPC64 && RI.getType(false) == R_PPC64_TOC)
     return getPPC64TocBase() + Addend;
 
   const Elf_Sym *Sym =
       File.getObj().getRelocationSymbol(&RI, File.getSymbolTable());
 
   if (!Sym)
     fatal("Unsupported relocation without symbol");
 
   InputSectionBase<ELFT> *Section = File.getSection(*Sym);
 
   if (Sym->getType() == STT_TLS)
     return (Section->OutSec->getVA() + Section->getOffset(*Sym) + Addend) -
            Out<ELFT>::TlsPhdr->p_vaddr;
 
   // According to the ELF spec reference to a local symbol from outside
   // the group are not allowed. Unfortunately .eh_frame breaks that rule
   // and must be treated specially. For now we just replace the symbol with
   // 0.
   if (Section == &InputSection<ELFT>::Discarded || !Section->isLive())
     return Addend;
 
   uintX_t Offset = Sym->st_value;
   if (Sym->getType() == STT_SECTION) {
     Offset += Addend;
     Addend = 0;
   }
   return Section->OutSec->getVA() + Section->getOffset(Offset) + Addend;
 }
 
 // Returns true if a symbol can be replaced at load-time by a symbol
 // with the same name defined in other ELF executable or DSO.
 bool elf2::canBePreempted(const SymbolBody *Body, bool NeedsGot) {
   if (!Body)
     return false;  // Body is a local symbol.
   if (Body->isShared())
     return true;
 
   if (Body->isUndefined()) {
     if (!Body->isWeak())
       return true;
 
     // This is an horrible corner case. Ideally we would like to say that any
     // undefined symbol can be preempted so that the dynamic linker has a
     // chance of finding it at runtime.
     //
     // The problem is that the code sequence used to test for weak undef
     // functions looks like
     // if (func) func()
     // If the code is -fPIC the first reference is a load from the got and
     // everything works.
     // If the code is not -fPIC there is no reasonable way to solve it:
     // * A relocation writing to the text segment will fail (it is ro).
     // * A copy relocation doesn't work for functions.
     // * The trick of using a plt entry as the address would fail here since
     //   the plt entry would have a non zero address.
     // Since we cannot do anything better, we just resolve the symbol to 0 and
     // don't produce a dynamic relocation.
     //
     // As an extra hack, assume that if we are producing a shared library the
     // user knows what he or she is doing and can handle a dynamic relocation.
     return Config->Shared || NeedsGot;
   }
   if (!Config->Shared)
     return false;
   if (Body->getVisibility() != STV_DEFAULT)
     return false;
   if (Config->Bsymbolic || (Config->BsymbolicFunctions && Body->isFunc()))
     return false;
   return true;
 }
 
 template <class ELFT> void OutputSection<ELFT>::writeTo(uint8_t *Buf) {
   for (InputSection<ELFT> *C : Sections)
     C->writeTo(Buf);
 }
 
 template <class ELFT>
 EHOutputSection<ELFT>::EHOutputSection(StringRef Name, uint32_t Type,
                                        uintX_t Flags)
     : OutputSectionBase<ELFT>(Name, Type, Flags) {
   Out<ELFT>::EhFrameHdr->assignEhFrame(this);
 }
 
 template <class ELFT>
 EHRegion<ELFT>::EHRegion(EHInputSection<ELFT> *S, unsigned Index)
     : S(S), Index(Index) {}
 
 template <class ELFT> StringRef EHRegion<ELFT>::data() const {
   ArrayRef<uint8_t> SecData = S->getSectionData();
   ArrayRef<std::pair<uintX_t, uintX_t>> Offsets = S->Offsets;
   size_t Start = Offsets[Index].first;
   size_t End =
       Index == Offsets.size() - 1 ? SecData.size() : Offsets[Index + 1].first;
   return StringRef((const char *)SecData.data() + Start, End - Start);
 }
 
 template <class ELFT>
 Cie<ELFT>::Cie(EHInputSection<ELFT> *S, unsigned Index)
     : EHRegion<ELFT>(S, Index) {}
 
 // Read a byte and advance D by one byte.
 static uint8_t readByte(ArrayRef<uint8_t> &D) {
   if (D.empty())
     fatal("corrupted or unsupported CIE information");
   uint8_t B = D.front();
   D = D.slice(1);
   return B;
 }
 
 static void skipLeb128(ArrayRef<uint8_t> &D) {
   while (!D.empty()) {
     uint8_t Val = D.front();
     D = D.slice(1);
     if ((Val & 0x80) == 0)
       return;
   }
   fatal("corrupted or unsupported CIE information");
 }
 
 template <class ELFT> static size_t getAugPSize(unsigned Enc) {
   switch (Enc & 0x0f) {
   case DW_EH_PE_absptr:
   case DW_EH_PE_signed:
     return ELFT::Is64Bits ? 8 : 4;
   case DW_EH_PE_udata2:
   case DW_EH_PE_sdata2:
     return 2;
   case DW_EH_PE_udata4:
   case DW_EH_PE_sdata4:
     return 4;
   case DW_EH_PE_udata8:
   case DW_EH_PE_sdata8:
     return 8;
   }
   fatal("unknown FDE encoding");
 }
 
 template <class ELFT> static void skipAugP(ArrayRef<uint8_t> &D) {
   uint8_t Enc = readByte(D);
   if ((Enc & 0xf0) == DW_EH_PE_aligned)
     fatal("DW_EH_PE_aligned encoding is not supported");
   size_t Size = getAugPSize<ELFT>(Enc);
   if (Size >= D.size())
     fatal("corrupted CIE");
   D = D.slice(Size);
 }
 
 template <class ELFT>
 uint8_t EHOutputSection<ELFT>::getFdeEncoding(ArrayRef<uint8_t> D) {
   if (D.size() < 8)
     fatal("CIE too small");
   D = D.slice(8);
 
   uint8_t Version = readByte(D);
   if (Version != 1 && Version != 3)
     fatal("FDE version 1 or 3 expected, but got " + Twine((unsigned)Version));
 
   const unsigned char *AugEnd = std::find(D.begin() + 1, D.end(), '\0');
   if (AugEnd == D.end())
     fatal("corrupted CIE");
   StringRef Aug(reinterpret_cast<const char *>(D.begin()), AugEnd - D.begin());
   D = D.slice(Aug.size() + 1);
 
   // Code alignment factor should always be 1 for .eh_frame.
   if (readByte(D) != 1)
     fatal("CIE code alignment must be 1");
 
   // Skip data alignment factor.
   skipLeb128(D);
 
   // Skip the return address register. In CIE version 1 this is a single
   // byte. In CIE version 3 this is an unsigned LEB128.
   if (Version == 1)
     readByte(D);
   else
     skipLeb128(D);
 
   // We only care about an 'R' value, but other records may precede an 'R'
   // record. Records are not in TLV (type-length-value) format, so we need
   // to teach the linker how to skip records for each type.
   for (char C : Aug) {
     if (C == 'R')
       return readByte(D);
     if (C == 'z') {
       skipLeb128(D);
       continue;
     }
     if (C == 'P') {
       skipAugP<ELFT>(D);
       continue;
     }
     if (C == 'L')
       continue;
     fatal("unknown .eh_frame augmentation string: " + Aug);
   }
   return DW_EH_PE_absptr;
 }
 
 template <class ELFT>
 static typename ELFFile<ELFT>::uintX_t readEntryLength(ArrayRef<uint8_t> D) {
   const endianness E = ELFT::TargetEndianness;
   if (D.size() < 4)
     fatal("CIE/FDE too small");
 
   // First 4 bytes of CIE/FDE is the size of the record.
   // If it is 0xFFFFFFFF, the next 8 bytes contain the size instead.
   uint64_t V = read32<E>(D.data());
   if (V < UINT32_MAX) {
     uint64_t Len = V + 4;
     if (Len > D.size())
       fatal("CIE/FIE ends past the end of the section");
     return Len;
   }
 
   if (D.size() < 12)
     fatal("CIE/FDE too small");
   V = read64<E>(D.data() + 4);
   uint64_t Len = V + 12;
   if (Len < V || D.size() < Len)
     fatal("CIE/FIE ends past the end of the section");
   return Len;
 }
 
 template <class ELFT>
 template <bool IsRela>
 void EHOutputSection<ELFT>::addSectionAux(
     EHInputSection<ELFT> *S,
     iterator_range<const Elf_Rel_Impl<ELFT, IsRela> *> Rels) {
   const endianness E = ELFT::TargetEndianness;
 
   S->OutSec = this;
   this->updateAlign(S->getAlign());
   Sections.push_back(S);
 
   ArrayRef<uint8_t> SecData = S->getSectionData();
   ArrayRef<uint8_t> D = SecData;
   uintX_t Offset = 0;
   auto RelI = Rels.begin();
   auto RelE = Rels.end();
 
   DenseMap<unsigned, unsigned> OffsetToIndex;
   while (!D.empty()) {
     unsigned Index = S->Offsets.size();
     S->Offsets.push_back(std::make_pair(Offset, -1));
 
     uintX_t Length = readEntryLength<ELFT>(D);
     // If CIE/FDE data length is zero then Length is 4, this
     // shall be considered a terminator and processing shall end.
     if (Length == 4)
       break;
     StringRef Entry((const char *)D.data(), Length);
 
     while (RelI != RelE && RelI->r_offset < Offset)
       ++RelI;
     uintX_t NextOffset = Offset + Length;
     bool HasReloc = RelI != RelE && RelI->r_offset < NextOffset;
 
     uint32_t ID = read32<E>(D.data() + 4);
     if (ID == 0) {
       // CIE
       Cie<ELFT> C(S, Index);
       if (Config->EhFrameHdr)
         C.FdeEncoding = getFdeEncoding(D);
 
       SymbolBody *Personality = nullptr;
       if (HasReloc) {
         uint32_t SymIndex = RelI->getSymbol(Config->Mips64EL);
         Personality = S->getFile()->getSymbolBody(SymIndex)->repl();
       }
 
       std::pair<StringRef, SymbolBody *> CieInfo(Entry, Personality);
       auto P = CieMap.insert(std::make_pair(CieInfo, Cies.size()));
       if (P.second) {
         Cies.push_back(C);
         this->Header.sh_size += alignTo(Length, sizeof(uintX_t));
       }
       OffsetToIndex[Offset] = P.first->second;
     } else {
       if (!HasReloc)
         fatal("FDE doesn't reference another section");
       InputSectionBase<ELFT> *Target = S->getRelocTarget(*RelI);
       if (Target != &InputSection<ELFT>::Discarded && Target->isLive()) {
         uint32_t CieOffset = Offset + 4 - ID;
         auto I = OffsetToIndex.find(CieOffset);
         if (I == OffsetToIndex.end())
           fatal("Invalid CIE reference");
         Cies[I->second].Fdes.push_back(EHRegion<ELFT>(S, Index));
         Out<ELFT>::EhFrameHdr->reserveFde();
         this->Header.sh_size += alignTo(Length, sizeof(uintX_t));
       }
     }
 
     Offset = NextOffset;
     D = D.slice(Length);
   }
 }
 
 template <class ELFT>
 void EHOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
   auto *S = cast<EHInputSection<ELFT>>(C);
   const Elf_Shdr *RelSec = S->RelocSection;
   if (!RelSec) {
     addSectionAux(S, make_range<const Elf_Rela *>(nullptr, nullptr));
     return;
   }
   ELFFile<ELFT> &Obj = S->getFile()->getObj();
   if (RelSec->sh_type == SHT_RELA)
     addSectionAux(S, Obj.relas(RelSec));
   else
     addSectionAux(S, Obj.rels(RelSec));
 }
 
 template <class ELFT>
 static typename ELFFile<ELFT>::uintX_t writeAlignedCieOrFde(StringRef Data,
                                                             uint8_t *Buf) {
   typedef typename ELFFile<ELFT>::uintX_t uintX_t;
   const endianness E = ELFT::TargetEndianness;
   uint64_t Len = alignTo(Data.size(), sizeof(uintX_t));
   write32<E>(Buf, Len - 4);
   memcpy(Buf + 4, Data.data() + 4, Data.size() - 4);
   return Len;
 }
 
 template <class ELFT> void EHOutputSection<ELFT>::writeTo(uint8_t *Buf) {
   const endianness E = ELFT::TargetEndianness;
   size_t Offset = 0;
   for (const Cie<ELFT> &C : Cies) {
     size_t CieOffset = Offset;
 
     uintX_t CIELen = writeAlignedCieOrFde<ELFT>(C.data(), Buf + Offset);
     C.S->Offsets[C.Index].second = Offset;
     Offset += CIELen;
 
     for (const EHRegion<ELFT> &F : C.Fdes) {
       uintX_t Len = writeAlignedCieOrFde<ELFT>(F.data(), Buf + Offset);
       write32<E>(Buf + Offset + 4, Offset + 4 - CieOffset); // Pointer
       F.S->Offsets[F.Index].second = Offset;
       Out<ELFT>::EhFrameHdr->addFde(C.FdeEncoding, Offset, Buf + Offset + 8);
       Offset += Len;
     }
   }
 
   for (EHInputSection<ELFT> *S : Sections) {
     const Elf_Shdr *RelSec = S->RelocSection;
     if (!RelSec)
       continue;
     ELFFile<ELFT> &EObj = S->getFile()->getObj();
     if (RelSec->sh_type == SHT_RELA)
       S->relocate(Buf, nullptr, EObj.relas(RelSec));
     else
       S->relocate(Buf, nullptr, EObj.rels(RelSec));
   }
 }
 
 template <class ELFT>
 MergeOutputSection<ELFT>::MergeOutputSection(StringRef Name, uint32_t Type,
                                              uintX_t Flags, uintX_t Alignment)
     : OutputSectionBase<ELFT>(Name, Type, Flags),
       Builder(llvm::StringTableBuilder::RAW, Alignment) {}
 
 template <class ELFT> void MergeOutputSection<ELFT>::writeTo(uint8_t *Buf) {
   if (shouldTailMerge()) {
     StringRef Data = Builder.data();
     memcpy(Buf, Data.data(), Data.size());
     return;
   }
   for (const std::pair<StringRef, size_t> &P : Builder.getMap()) {
     StringRef Data = P.first;
     memcpy(Buf + P.second, Data.data(), Data.size());
   }
 }
 
 static size_t findNull(StringRef S, size_t EntSize) {
   // Optimize the common case.
   if (EntSize == 1)
     return S.find(0);
 
   for (unsigned I = 0, N = S.size(); I != N; I += EntSize) {
     const char *B = S.begin() + I;
     if (std::all_of(B, B + EntSize, [](char C) { return C == 0; }))
       return I;
   }
   return StringRef::npos;
 }
 
 template <class ELFT>
 void MergeOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
   auto *S = cast<MergeInputSection<ELFT>>(C);
   S->OutSec = this;
   this->updateAlign(S->getAlign());
 
   ArrayRef<uint8_t> D = S->getSectionData();
   StringRef Data((const char *)D.data(), D.size());
   uintX_t EntSize = S->getSectionHdr()->sh_entsize;
 
   // If this is of type string, the contents are null-terminated strings.
   if (this->Header.sh_flags & SHF_STRINGS) {
     uintX_t Offset = 0;
     while (!Data.empty()) {
       size_t End = findNull(Data, EntSize);
       if (End == StringRef::npos)
         fatal("String is not null terminated");
       StringRef Entry = Data.substr(0, End + EntSize);
       uintX_t OutputOffset = Builder.add(Entry);
       if (shouldTailMerge())
         OutputOffset = -1;
       S->Offsets.push_back(std::make_pair(Offset, OutputOffset));
       uintX_t Size = End + EntSize;
       Data = Data.substr(Size);
       Offset += Size;
     }
     return;
   }
 
   // If this is not of type string, every entry has the same size.
   for (unsigned I = 0, N = Data.size(); I != N; I += EntSize) {
     StringRef Entry = Data.substr(I, EntSize);
     size_t OutputOffset = Builder.add(Entry);
     S->Offsets.push_back(std::make_pair(I, OutputOffset));
   }
 }
 
 template <class ELFT>
 unsigned MergeOutputSection<ELFT>::getOffset(StringRef Val) {
   return Builder.getOffset(Val);
 }
 
 template <class ELFT> bool MergeOutputSection<ELFT>::shouldTailMerge() const {
   return Config->Optimize >= 2 && this->Header.sh_flags & SHF_STRINGS;
 }
 
 template <class ELFT> void MergeOutputSection<ELFT>::finalize() {
   if (shouldTailMerge())
     Builder.finalize();
   this->Header.sh_size = Builder.getSize();
 }
 
 template <class ELFT>
 StringTableSection<ELFT>::StringTableSection(StringRef Name, bool Dynamic)
     : OutputSectionBase<ELFT>(Name, SHT_STRTAB,
                               Dynamic ? (uintX_t)SHF_ALLOC : 0),
       Dynamic(Dynamic) {
   this->Header.sh_addralign = 1;
 }
 
 // Adds a string to the string table. If HashIt is true we hash and check for
 // duplicates. It is optional because the name of global symbols are already
 // uniqued and hashing them again has a big cost for a small value: uniquing
 // them with some other string that happens to be the same.
 template <class ELFT>
 unsigned StringTableSection<ELFT>::addString(StringRef S, bool HashIt) {
   if (HashIt) {
     auto R = StringMap.insert(std::make_pair(S, Size));
     if (!R.second)
       return R.first->second;
   }
   unsigned Ret = Size;
   Size += S.size() + 1;
   Strings.push_back(S);
   return Ret;
 }
 
 template <class ELFT> void StringTableSection<ELFT>::writeTo(uint8_t *Buf) {
   // ELF string tables start with NUL byte, so advance the pointer by one.
   ++Buf;
   for (StringRef S : Strings) {
     memcpy(Buf, S.data(), S.size());
     Buf += S.size() + 1;
   }
 }
 
 template <class ELFT>
 SymbolTableSection<ELFT>::SymbolTableSection(
     SymbolTable<ELFT> &Table, StringTableSection<ELFT> &StrTabSec)
     : OutputSectionBase<ELFT>(StrTabSec.isDynamic() ? ".dynsym" : ".symtab",
                               StrTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB,
                               StrTabSec.isDynamic() ? (uintX_t)SHF_ALLOC : 0),
       StrTabSec(StrTabSec), Table(Table) {
   this->Header.sh_entsize = sizeof(Elf_Sym);
   this->Header.sh_addralign = sizeof(uintX_t);
 }
 
 // Orders symbols according to their positions in the GOT,
 // in compliance with MIPS ABI rules.
 // 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
 static bool sortMipsSymbols(const std::pair<SymbolBody *, unsigned> &L,
                             const std::pair<SymbolBody *, unsigned> &R) {
   if (!L.first->isInGot() || !R.first->isInGot())
     return R.first->isInGot();
   return L.first->GotIndex < R.first->GotIndex;
 }
 
 template <class ELFT> void SymbolTableSection<ELFT>::finalize() {
   if (this->Header.sh_size)
     return; // Already finalized.
 
   this->Header.sh_size = getNumSymbols() * sizeof(Elf_Sym);
   this->Header.sh_link = StrTabSec.SectionIndex;
   this->Header.sh_info = NumLocals + 1;
 
+  if (Config->Relocatable) {
+    size_t I = NumLocals;
+    for (const std::pair<SymbolBody *, size_t> &P : Symbols)
+      P.first->DynsymIndex = ++I;
+    return;
+  }
+
   if (!StrTabSec.isDynamic()) {
     std::stable_sort(Symbols.begin(), Symbols.end(),
                      [](const std::pair<SymbolBody *, unsigned> &L,
                         const std::pair<SymbolBody *, unsigned> &R) {
                        return getSymbolBinding(L.first) == STB_LOCAL &&
                               getSymbolBinding(R.first) != STB_LOCAL;
                      });
     return;
   }
   if (Out<ELFT>::GnuHashTab)
     // NB: It also sorts Symbols to meet the GNU hash table requirements.
     Out<ELFT>::GnuHashTab->addSymbols(Symbols);
   else if (Config->EMachine == EM_MIPS)
     std::stable_sort(Symbols.begin(), Symbols.end(), sortMipsSymbols);
   size_t I = 0;
   for (const std::pair<SymbolBody *, size_t> &P : Symbols)
     P.first->DynsymIndex = ++I;
 }
 
 template <class ELFT>
 void SymbolTableSection<ELFT>::addSymbol(SymbolBody *B) {
   Symbols.push_back({B, StrTabSec.addString(B->getName(), false)});
 }
 
 template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
   Buf += sizeof(Elf_Sym);
 
   // All symbols with STB_LOCAL binding precede the weak and global symbols.
   // .dynsym only contains global symbols.
   if (!Config->DiscardAll && !StrTabSec.isDynamic())
     writeLocalSymbols(Buf);
 
   writeGlobalSymbols(Buf);
 }
 
 template <class ELFT>
 void SymbolTableSection<ELFT>::writeLocalSymbols(uint8_t *&Buf) {
   // Iterate over all input object files to copy their local symbols
   // to the output symbol table pointed by Buf.
   for (const std::unique_ptr<ObjectFile<ELFT>> &File : Table.getObjectFiles()) {
     for (const std::pair<const Elf_Sym *, size_t> &P : File->KeptLocalSyms) {
       const Elf_Sym *Sym = P.first;
 
       auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
       uintX_t VA = 0;
       if (Sym->st_shndx == SHN_ABS) {
         ESym->st_shndx = SHN_ABS;
         VA = Sym->st_value;
       } else {
         InputSectionBase<ELFT> *Section = File->getSection(*Sym);
         const OutputSectionBase<ELFT> *OutSec = Section->OutSec;
         ESym->st_shndx = OutSec->SectionIndex;
         VA = Section->getOffset(*Sym);
         // Symbol offsets for AMDGPU need to be the offset in bytes of the
         // symbol from the beginning of the section.
         if (Config->EMachine != EM_AMDGPU)
           VA += OutSec->getVA();
       }
       ESym->st_name = P.second;
       ESym->st_size = Sym->st_size;
       ESym->setBindingAndType(Sym->getBinding(), Sym->getType());
       ESym->st_value = VA;
       Buf += sizeof(*ESym);
     }
   }
 }
 
 template <class ELFT>
 static const typename llvm::object::ELFFile<ELFT>::Elf_Sym *
 getElfSym(SymbolBody &Body) {
   if (auto *EBody = dyn_cast<DefinedElf<ELFT>>(&Body))
     return &EBody->Sym;
   if (auto *EBody = dyn_cast<UndefinedElf<ELFT>>(&Body))
     return &EBody->Sym;
   return nullptr;
 }
 
 template <class ELFT>
 void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) {
   // Write the internal symbol table contents to the output symbol table
   // pointed by Buf.
   auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
   for (const std::pair<SymbolBody *, size_t> &P : Symbols) {
     SymbolBody *Body = P.first;
     size_t StrOff = P.second;
 
     unsigned char Type = STT_NOTYPE;
     uintX_t Size = 0;
     if (const Elf_Sym *InputSym = getElfSym<ELFT>(*Body)) {
       Type = InputSym->getType();
       Size = InputSym->st_size;
     } else if (auto *C = dyn_cast<DefinedCommon>(Body)) {
       Type = STT_OBJECT;
       Size = C->Size;
     }
 
     ESym->setBindingAndType(getSymbolBinding(Body), Type);
     ESym->st_size = Size;
     ESym->st_name = StrOff;
     ESym->setVisibility(Body->getVisibility());
     ESym->st_value = Body->getVA<ELFT>();
 
     if (const OutputSectionBase<ELFT> *OutSec = getOutputSection(Body))
       ESym->st_shndx = OutSec->SectionIndex;
     else if (isa<DefinedRegular<ELFT>>(Body))
       ESym->st_shndx = SHN_ABS;
     ++ESym;
   }
 }
 
 template <class ELFT>
 const OutputSectionBase<ELFT> *
 SymbolTableSection<ELFT>::getOutputSection(SymbolBody *Sym) {
   switch (Sym->kind()) {
   case SymbolBody::DefinedSyntheticKind:
     return &cast<DefinedSynthetic<ELFT>>(Sym)->Section;
   case SymbolBody::DefinedRegularKind: {
     auto *D = cast<DefinedRegular<ELFT>>(Sym->repl());
     if (D->Section)
       return D->Section->OutSec;
     break;
   }
   case SymbolBody::DefinedCommonKind:
     return Out<ELFT>::Bss;
   case SymbolBody::SharedKind:
     if (cast<SharedSymbol<ELFT>>(Sym)->needsCopy())
       return Out<ELFT>::Bss;
     break;
   case SymbolBody::UndefinedElfKind:
   case SymbolBody::UndefinedKind:
   case SymbolBody::LazyKind:
     break;
   case SymbolBody::DefinedBitcodeKind:
     llvm_unreachable("Should have been replaced");
   }
   return nullptr;
 }
 
 template <class ELFT>
 uint8_t SymbolTableSection<ELFT>::getSymbolBinding(SymbolBody *Body) {
   uint8_t Visibility = Body->getVisibility();
   if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
     return STB_LOCAL;
   if (const Elf_Sym *ESym = getElfSym<ELFT>(*Body))
     return ESym->getBinding();
   if (isa<DefinedSynthetic<ELFT>>(Body))
     return STB_LOCAL;
   return Body->isWeak() ? STB_WEAK : STB_GLOBAL;
 }
 
 template <class ELFT>
 MipsReginfoOutputSection<ELFT>::MipsReginfoOutputSection()
     : OutputSectionBase<ELFT>(".reginfo", SHT_MIPS_REGINFO, SHF_ALLOC) {
   this->Header.sh_addralign = 4;
   this->Header.sh_entsize = sizeof(Elf_Mips_RegInfo);
   this->Header.sh_size = sizeof(Elf_Mips_RegInfo);
 }
 
 template <class ELFT>
 void MipsReginfoOutputSection<ELFT>::writeTo(uint8_t *Buf) {
   auto *R = reinterpret_cast<Elf_Mips_RegInfo *>(Buf);
   R->ri_gp_value = getMipsGpAddr<ELFT>();
   R->ri_gprmask = GprMask;
 }
 
 template <class ELFT>
 void MipsReginfoOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
   // Copy input object file's .reginfo gprmask to output.
   auto *S = cast<MipsReginfoInputSection<ELFT>>(C);
   GprMask |= S->Reginfo->ri_gprmask;
 }
 
 namespace lld {
 namespace elf2 {
 template class OutputSectionBase<ELF32LE>;
 template class OutputSectionBase<ELF32BE>;
 template class OutputSectionBase<ELF64LE>;
 template class OutputSectionBase<ELF64BE>;
 
 template class EhFrameHeader<ELF32LE>;
 template class EhFrameHeader<ELF32BE>;
 template class EhFrameHeader<ELF64LE>;
 template class EhFrameHeader<ELF64BE>;
 
 template class GotPltSection<ELF32LE>;
 template class GotPltSection<ELF32BE>;
 template class GotPltSection<ELF64LE>;
 template class GotPltSection<ELF64BE>;
 
 template class GotSection<ELF32LE>;
 template class GotSection<ELF32BE>;
 template class GotSection<ELF64LE>;
 template class GotSection<ELF64BE>;
 
 template class PltSection<ELF32LE>;
 template class PltSection<ELF32BE>;
 template class PltSection<ELF64LE>;
 template class PltSection<ELF64BE>;
 
 template class RelocationSection<ELF32LE>;
 template class RelocationSection<ELF32BE>;
 template class RelocationSection<ELF64LE>;
 template class RelocationSection<ELF64BE>;
 
 template class InterpSection<ELF32LE>;
 template class InterpSection<ELF32BE>;
 template class InterpSection<ELF64LE>;
 template class InterpSection<ELF64BE>;
 
 template class GnuHashTableSection<ELF32LE>;
 template class GnuHashTableSection<ELF32BE>;
 template class GnuHashTableSection<ELF64LE>;
 template class GnuHashTableSection<ELF64BE>;
 
 template class HashTableSection<ELF32LE>;
 template class HashTableSection<ELF32BE>;
 template class HashTableSection<ELF64LE>;
 template class HashTableSection<ELF64BE>;
 
 template class DynamicSection<ELF32LE>;
 template class DynamicSection<ELF32BE>;
 template class DynamicSection<ELF64LE>;
 template class DynamicSection<ELF64BE>;
 
 template class OutputSection<ELF32LE>;
 template class OutputSection<ELF32BE>;
 template class OutputSection<ELF64LE>;
 template class OutputSection<ELF64BE>;
 
 template class EHOutputSection<ELF32LE>;
 template class EHOutputSection<ELF32BE>;
 template class EHOutputSection<ELF64LE>;
 template class EHOutputSection<ELF64BE>;
 
 template class MipsReginfoOutputSection<ELF32LE>;
 template class MipsReginfoOutputSection<ELF32BE>;
 template class MipsReginfoOutputSection<ELF64LE>;
 template class MipsReginfoOutputSection<ELF64BE>;
 
 template class MergeOutputSection<ELF32LE>;
 template class MergeOutputSection<ELF32BE>;
 template class MergeOutputSection<ELF64LE>;
 template class MergeOutputSection<ELF64BE>;
 
 template class StringTableSection<ELF32LE>;
 template class StringTableSection<ELF32BE>;
 template class StringTableSection<ELF64LE>;
 template class StringTableSection<ELF64BE>;
 
 template class SymbolTableSection<ELF32LE>;
 template class SymbolTableSection<ELF32BE>;
 template class SymbolTableSection<ELF64LE>;
 template class SymbolTableSection<ELF64BE>;
 
 template uint32_t getLocalRelTarget(const ObjectFile<ELF32LE> &,
                                     const ELFFile<ELF32LE>::Elf_Rel &,
                                     uint32_t);
 template uint32_t getLocalRelTarget(const ObjectFile<ELF32BE> &,
                                     const ELFFile<ELF32BE>::Elf_Rel &,
                                     uint32_t);
 template uint64_t getLocalRelTarget(const ObjectFile<ELF64LE> &,
                                     const ELFFile<ELF64LE>::Elf_Rel &,
                                     uint64_t);
 template uint64_t getLocalRelTarget(const ObjectFile<ELF64BE> &,
                                     const ELFFile<ELF64BE>::Elf_Rel &,
                                     uint64_t);
 template uint32_t getLocalRelTarget(const ObjectFile<ELF32LE> &,
                                     const ELFFile<ELF32LE>::Elf_Rela &,
                                     uint32_t);
 template uint32_t getLocalRelTarget(const ObjectFile<ELF32BE> &,
                                     const ELFFile<ELF32BE>::Elf_Rela &,
                                     uint32_t);
 template uint64_t getLocalRelTarget(const ObjectFile<ELF64LE> &,
                                     const ELFFile<ELF64LE>::Elf_Rela &,
                                     uint64_t);
 template uint64_t getLocalRelTarget(const ObjectFile<ELF64BE> &,
                                     const ELFFile<ELF64BE>::Elf_Rela &,
                                     uint64_t);
 }
 }
diff --git a/ELF/OutputSections.h b/ELF/OutputSections.h
index a3a80db..e6538e8 100644
--- a/ELF/OutputSections.h
+++ b/ELF/OutputSections.h
@@ -1,582 +1,583 @@
 //===- OutputSections.h -----------------------------------------*- C++ -*-===//
 //
 //                             The LLVM Linker
 //
 // This file is distributed under the University of Illinois Open Source
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLD_ELF_OUTPUT_SECTIONS_H
 #define LLD_ELF_OUTPUT_SECTIONS_H
 
 #include "lld/Core/LLVM.h"
 
 #include "llvm/MC/StringTableBuilder.h"
 #include "llvm/Object/ELF.h"
 
 #include "Config.h"
 
 #include <type_traits>
 
 namespace lld {
 namespace elf2 {
 
 class SymbolBody;
 template <class ELFT> class SymbolTable;
 template <class ELFT> class SymbolTableSection;
 template <class ELFT> class StringTableSection;
 template <class ELFT> class EHInputSection;
 template <class ELFT> class InputSection;
 template <class ELFT> class InputSectionBase;
 template <class ELFT> class MergeInputSection;
 template <class ELFT> class MipsReginfoInputSection;
 template <class ELFT> class OutputSection;
 template <class ELFT> class ObjectFile;
 template <class ELFT> class DefinedRegular;
 
 template <class ELFT>
 static inline typename llvm::object::ELFFile<ELFT>::uintX_t
 getAddend(const typename llvm::object::ELFFile<ELFT>::Elf_Rel &Rel) {
   return 0;
 }
 
 template <class ELFT>
 static inline typename llvm::object::ELFFile<ELFT>::uintX_t
 getAddend(const typename llvm::object::ELFFile<ELFT>::Elf_Rela &Rel) {
   return Rel.r_addend;
 }
 
 template <class ELFT, bool IsRela>
 typename llvm::object::ELFFile<ELFT>::uintX_t
 getLocalRelTarget(const ObjectFile<ELFT> &File,
                   const llvm::object::Elf_Rel_Impl<ELFT, IsRela> &Rel,
                   typename llvm::object::ELFFile<ELFT>::uintX_t Addend);
 
 bool canBePreempted(const SymbolBody *Body, bool NeedsGot);
 
 // This represents a section in an output file.
 // Different sub classes represent different types of sections. Some contain
 // input sections, others are created by the linker.
 // The writer creates multiple OutputSections and assign them unique,
 // non-overlapping file offsets and VAs.
 template <class ELFT> class OutputSectionBase {
 public:
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
 
   OutputSectionBase(StringRef Name, uint32_t Type, uintX_t Flags);
   void setVA(uintX_t VA) { Header.sh_addr = VA; }
   uintX_t getVA() const { return Header.sh_addr; }
   void setFileOffset(uintX_t Off) { Header.sh_offset = Off; }
   void setSHName(unsigned Val) { Header.sh_name = Val; }
   void writeHeaderTo(Elf_Shdr *SHdr);
   StringRef getName() { return Name; }
 
   virtual void addSection(InputSectionBase<ELFT> *C) {}
 
   unsigned SectionIndex;
 
   // Returns the size of the section in the output file.
   uintX_t getSize() const { return Header.sh_size; }
   void setSize(uintX_t Val) { Header.sh_size = Val; }
   uintX_t getFlags() { return Header.sh_flags; }
   uintX_t getFileOff() { return Header.sh_offset; }
   uintX_t getAlign() {
     // The ELF spec states that a value of 0 means the section has no alignment
     // constraits.
     return std::max<uintX_t>(Header.sh_addralign, 1);
   }
   uint32_t getType() { return Header.sh_type; }
   void updateAlign(uintX_t Align) {
     if (Align > Header.sh_addralign)
       Header.sh_addralign = Align;
   }
 
   virtual void finalize() {}
   virtual void writeTo(uint8_t *Buf) {}
   virtual ~OutputSectionBase() = default;
 
 protected:
   StringRef Name;
   Elf_Shdr Header;
 };
 
 template <class ELFT> class GotSection final : public OutputSectionBase<ELFT> {
   typedef OutputSectionBase<ELFT> Base;
   typedef typename Base::uintX_t uintX_t;
 
 public:
   GotSection();
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
   void addEntry(SymbolBody *Sym);
   void addMipsLocalEntry();
   bool addDynTlsEntry(SymbolBody *Sym);
   bool addTlsIndex();
   bool empty() const { return MipsLocalEntries == 0 && Entries.empty(); }
   uintX_t getMipsLocalFullAddr(const SymbolBody &B);
   uintX_t getMipsLocalPageAddr(uintX_t Addr);
   uintX_t getGlobalDynAddr(const SymbolBody &B) const;
   uintX_t getNumEntries() const { return Entries.size(); }
 
   // Returns the symbol which corresponds to the first entry of the global part
   // of GOT on MIPS platform. It is required to fill up MIPS-specific dynamic
   // table properties.
   // Returns nullptr if the global part is empty.
   const SymbolBody *getMipsFirstGlobalEntry() const;
 
   // Returns the number of entries in the local part of GOT including
   // the number of reserved entries. This method is MIPS-specific.
   unsigned getMipsLocalEntriesNum() const;
 
   uintX_t getTlsIndexVA() { return Base::getVA() + TlsIndexOff; }
 
 private:
   std::vector<const SymbolBody *> Entries;
   uint32_t TlsIndexOff = -1;
   uint32_t MipsLocalEntries = 0;
   llvm::DenseMap<uintX_t, size_t> MipsLocalGotPos;
 
   uintX_t getMipsLocalEntryAddr(uintX_t EntryValue);
 };
 
 template <class ELFT>
 class GotPltSection final : public OutputSectionBase<ELFT> {
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
 
 public:
   GotPltSection();
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
   void addEntry(SymbolBody *Sym);
   bool empty() const;
 
 private:
   std::vector<const SymbolBody *> Entries;
 };
 
 template <class ELFT> class PltSection final : public OutputSectionBase<ELFT> {
   typedef OutputSectionBase<ELFT> Base;
   typedef typename Base::uintX_t uintX_t;
 
 public:
   PltSection();
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
   void addEntry(SymbolBody *Sym);
   bool empty() const { return Entries.empty(); }
 
 private:
   std::vector<std::pair<const SymbolBody *, unsigned>> Entries;
 };
 
 template <class ELFT> struct DynamicReloc {
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
   uint32_t Type;
 
   // Where the relocation is.
   enum OffsetKind {
     Off_Got,       // The got entry of Sym.
     Off_GotPlt,    // The got.plt entry of Sym.
     Off_Bss,       // The bss entry of Sym (copy reloc).
     Off_Sec,       // The final position of the given input section and offset.
     Off_LTlsIndex, // The local tls index.
     Off_GTlsIndex, // The global tls index of Sym.
     Off_GTlsOffset // The global tls offset of Sym.
   } OKind;
 
   SymbolBody *Sym = nullptr;
   InputSectionBase<ELFT> *OffsetSec = nullptr;
   uintX_t OffsetInSec = 0;
   bool UseSymVA = false;
   InputSectionBase<ELFT> *TargetSec = nullptr;
   uintX_t OffsetInTargetSec = 0;
   uintX_t Addend = 0;
 
   DynamicReloc(uint32_t Type, OffsetKind OKind, SymbolBody *Sym)
       : Type(Type), OKind(OKind), Sym(Sym) {}
 
   DynamicReloc(uint32_t Type, OffsetKind OKind, bool UseSymVA, SymbolBody *Sym)
       : Type(Type), OKind(OKind), Sym(Sym), UseSymVA(UseSymVA) {}
 
   DynamicReloc(uint32_t Type, InputSectionBase<ELFT> *OffsetSec,
                uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym,
                uintX_t Addend)
       : Type(Type), OKind(Off_Sec), Sym(Sym), OffsetSec(OffsetSec),
         OffsetInSec(OffsetInSec), UseSymVA(UseSymVA), Addend(Addend) {}
 
   DynamicReloc(uint32_t Type, InputSectionBase<ELFT> *OffsetSec,
                uintX_t OffsetInSec, InputSectionBase<ELFT> *TargetSec,
                uintX_t OffsetInTargetSec, uintX_t Addend)
       : Type(Type), OKind(Off_Sec), OffsetSec(OffsetSec),
         OffsetInSec(OffsetInSec), TargetSec(TargetSec),
         OffsetInTargetSec(OffsetInTargetSec), Addend(Addend) {}
 
   uintX_t getOffset() const;
 };
 
 template <class ELFT>
 class SymbolTableSection final : public OutputSectionBase<ELFT> {
 public:
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range;
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
   SymbolTableSection(SymbolTable<ELFT> &Table,
                      StringTableSection<ELFT> &StrTabSec);
 
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
   void addSymbol(SymbolBody *Body);
   StringTableSection<ELFT> &getStrTabSec() const { return StrTabSec; }
   unsigned getNumSymbols() const { return NumLocals + Symbols.size() + 1; }
 
   ArrayRef<std::pair<SymbolBody *, size_t>> getSymbols() const {
     return Symbols;
   }
 
   unsigned NumLocals = 0;
   StringTableSection<ELFT> &StrTabSec;
 
 private:
   void writeLocalSymbols(uint8_t *&Buf);
   void writeGlobalSymbols(uint8_t *Buf);
 
   const OutputSectionBase<ELFT> *getOutputSection(SymbolBody *Sym);
   static uint8_t getSymbolBinding(SymbolBody *Body);
 
   SymbolTable<ELFT> &Table;
 
   // A vector of symbols and their string table offsets.
   std::vector<std::pair<SymbolBody *, size_t>> Symbols;
 };
 
 template <class ELFT>
 class RelocationSection final : public OutputSectionBase<ELFT> {
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Rel Elf_Rel;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Rela Elf_Rela;
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
 
 public:
   RelocationSection(StringRef Name, bool IsRela);
   void addReloc(const DynamicReloc<ELFT> &Reloc);
   unsigned getRelocOffset();
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
   bool hasRelocs() const { return !Relocs.empty(); }
   bool isRela() const { return IsRela; }
 
   bool Static = false;
 
 private:
   std::vector<DynamicReloc<ELFT>> Relocs;
   const bool IsRela;
 };
 
 template <class ELFT>
 class OutputSection final : public OutputSectionBase<ELFT> {
 public:
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Rel Elf_Rel;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Rela Elf_Rela;
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
   OutputSection(StringRef Name, uint32_t Type, uintX_t Flags);
   void addSection(InputSectionBase<ELFT> *C) override;
   void sortInitFini();
   void sortCtorsDtors();
   void writeTo(uint8_t *Buf) override;
+  void finalize() override;
 
 private:
   void reassignOffsets();
   std::vector<InputSection<ELFT> *> Sections;
 };
 
 template <class ELFT>
 class MergeOutputSection final : public OutputSectionBase<ELFT> {
   typedef typename OutputSectionBase<ELFT>::uintX_t uintX_t;
 
   bool shouldTailMerge() const;
 
 public:
   MergeOutputSection(StringRef Name, uint32_t Type, uintX_t Flags,
                      uintX_t Alignment);
   void addSection(InputSectionBase<ELFT> *S) override;
   void writeTo(uint8_t *Buf) override;
   unsigned getOffset(StringRef Val);
   void finalize() override;
 
 private:
   llvm::StringTableBuilder Builder;
 };
 
 // FDE or CIE
 template <class ELFT> struct EHRegion {
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
   EHRegion(EHInputSection<ELFT> *S, unsigned Index);
   StringRef data() const;
   EHInputSection<ELFT> *S;
   unsigned Index;
 };
 
 template <class ELFT> struct Cie : public EHRegion<ELFT> {
   Cie(EHInputSection<ELFT> *S, unsigned Index);
   std::vector<EHRegion<ELFT>> Fdes;
   uint8_t FdeEncoding;
 };
 
 template <class ELFT>
 class EHOutputSection final : public OutputSectionBase<ELFT> {
 public:
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Rel Elf_Rel;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Rela Elf_Rela;
   EHOutputSection(StringRef Name, uint32_t Type, uintX_t Flags);
   void writeTo(uint8_t *Buf) override;
 
   template <bool IsRela>
   void addSectionAux(
       EHInputSection<ELFT> *S,
       llvm::iterator_range<const llvm::object::Elf_Rel_Impl<ELFT, IsRela> *>
           Rels);
 
   void addSection(InputSectionBase<ELFT> *S) override;
 
 private:
   uint8_t getFdeEncoding(ArrayRef<uint8_t> D);
 
   std::vector<EHInputSection<ELFT> *> Sections;
   std::vector<Cie<ELFT>> Cies;
 
   // Maps CIE content + personality to a index in Cies.
   llvm::DenseMap<std::pair<StringRef, SymbolBody *>, unsigned> CieMap;
 };
 
 template <class ELFT>
 class InterpSection final : public OutputSectionBase<ELFT> {
 public:
   InterpSection();
   void writeTo(uint8_t *Buf) override;
 };
 
 template <class ELFT>
 class StringTableSection final : public OutputSectionBase<ELFT> {
 public:
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
   StringTableSection(StringRef Name, bool Dynamic);
   unsigned addString(StringRef S, bool HashIt = true);
   void writeTo(uint8_t *Buf) override;
   unsigned getSize() const { return Size; }
   void finalize() override { this->Header.sh_size = getSize(); }
   bool isDynamic() const { return Dynamic; }
 
 private:
   const bool Dynamic;
   llvm::DenseMap<StringRef, unsigned> StringMap;
   std::vector<StringRef> Strings;
   unsigned Size = 1; // ELF string tables start with a NUL byte, so 1.
 };
 
 template <class ELFT>
 class HashTableSection final : public OutputSectionBase<ELFT> {
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Word Elf_Word;
 
 public:
   HashTableSection();
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
 };
 
 // Outputs GNU Hash section. For detailed explanation see:
 // https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections
 template <class ELFT>
 class GnuHashTableSection final : public OutputSectionBase<ELFT> {
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Off Elf_Off;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Word Elf_Word;
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
 
 public:
   GnuHashTableSection();
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
 
   // Adds symbols to the hash table.
   // Sorts the input to satisfy GNU hash section requirements.
   void addSymbols(std::vector<std::pair<SymbolBody *, size_t>> &Symbols);
 
 private:
   static unsigned calcNBuckets(unsigned NumHashed);
   static unsigned calcMaskWords(unsigned NumHashed);
 
   void writeHeader(uint8_t *&Buf);
   void writeBloomFilter(uint8_t *&Buf);
   void writeHashTable(uint8_t *Buf);
 
   struct SymbolData {
     SymbolBody *Body;
     size_t STName;
     uint32_t Hash;
   };
 
   std::vector<SymbolData> Symbols;
 
   unsigned MaskWords;
   unsigned NBuckets;
   unsigned Shift2;
 };
 
 template <class ELFT>
 class DynamicSection final : public OutputSectionBase<ELFT> {
   typedef OutputSectionBase<ELFT> Base;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Dyn Elf_Dyn;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Rel Elf_Rel;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Rela Elf_Rela;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
 
   // The .dynamic section contains information for the dynamic linker.
   // The section consists of fixed size entries, which consist of
   // type and value fields. Value are one of plain integers, symbol
   // addresses, or section addresses. This struct represents the entry.
   struct Entry {
     int32_t Tag;
     union {
       OutputSectionBase<ELFT> *OutSec;
       uint64_t Val;
       const SymbolBody *Sym;
     };
     enum KindT { SecAddr, SymAddr, PlainInt } Kind;
     Entry(int32_t Tag, OutputSectionBase<ELFT> *OutSec)
         : Tag(Tag), OutSec(OutSec), Kind(SecAddr) {}
     Entry(int32_t Tag, uint64_t Val) : Tag(Tag), Val(Val), Kind(PlainInt) {}
     Entry(int32_t Tag, const SymbolBody *Sym)
         : Tag(Tag), Sym(Sym), Kind(SymAddr) {}
   };
 
   // finalize() fills this vector with the section contents. finalize()
   // cannot directly create final section contents because when the
   // function is called, symbol or section addresses are not fixed yet.
   std::vector<Entry> Entries;
 
 public:
   DynamicSection(SymbolTable<ELFT> &SymTab);
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
 
   OutputSectionBase<ELFT> *PreInitArraySec = nullptr;
   OutputSectionBase<ELFT> *InitArraySec = nullptr;
   OutputSectionBase<ELFT> *FiniArraySec = nullptr;
 
 private:
   SymbolTable<ELFT> &SymTab;
 };
 
 template <class ELFT>
 class MipsReginfoOutputSection final : public OutputSectionBase<ELFT> {
   typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
 
 public:
   MipsReginfoOutputSection();
   void writeTo(uint8_t *Buf) override;
   void addSection(InputSectionBase<ELFT> *S) override;
 
 private:
   uint32_t GprMask = 0;
 };
 
 // --eh-frame-hdr option tells linker to construct a header for all the
 // .eh_frame sections. This header is placed to a section named .eh_frame_hdr
 // and also to a PT_GNU_EH_FRAME segment.
 // At runtime the unwinder then can find all the PT_GNU_EH_FRAME segments by
 // calling dl_iterate_phdr.
 // This section contains a lookup table for quick binary search of FDEs.
 // Detailed info about internals can be found in Ian Lance Taylor's blog:
 // http://www.airs.com/blog/archives/460 (".eh_frame")
 // http://www.airs.com/blog/archives/462 (".eh_frame_hdr")
 template <class ELFT>
 class EhFrameHeader final : public OutputSectionBase<ELFT> {
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
 
 public:
   EhFrameHeader();
   void writeTo(uint8_t *Buf) override;
 
   void addFde(uint8_t Enc, size_t Off, uint8_t *PCRel);
   void assignEhFrame(EHOutputSection<ELFT> *Sec);
   void reserveFde();
 
   bool Live = false;
 
 private:
   struct FdeData {
     uint8_t Enc;
     size_t Off;
     uint8_t *PCRel;
   };
 
   uintX_t getFdePc(uintX_t EhVA, const FdeData &F);
 
   EHOutputSection<ELFT> *Sec = nullptr;
   std::vector<FdeData> FdeList;
 };
 
 // All output sections that are hadnled by the linker specially are
 // globally accessible. Writer initializes them, so don't use them
 // until Writer is initialized.
 template <class ELFT> struct Out {
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Phdr Elf_Phdr;
   static DynamicSection<ELFT> *Dynamic;
   static EhFrameHeader<ELFT> *EhFrameHdr;
   static GnuHashTableSection<ELFT> *GnuHashTab;
   static GotPltSection<ELFT> *GotPlt;
   static GotSection<ELFT> *Got;
   static HashTableSection<ELFT> *HashTab;
   static InterpSection<ELFT> *Interp;
   static OutputSection<ELFT> *Bss;
   static OutputSection<ELFT> *MipsRldMap;
   static OutputSectionBase<ELFT> *Opd;
   static uint8_t *OpdBuf;
   static PltSection<ELFT> *Plt;
   static RelocationSection<ELFT> *RelaDyn;
   static RelocationSection<ELFT> *RelaPlt;
   static StringTableSection<ELFT> *DynStrTab;
   static StringTableSection<ELFT> *ShStrTab;
   static StringTableSection<ELFT> *StrTab;
   static SymbolTableSection<ELFT> *DynSymTab;
   static SymbolTableSection<ELFT> *SymTab;
   static Elf_Phdr *TlsPhdr;
   static OutputSectionBase<ELFT> *ElfHeader;
   static OutputSectionBase<ELFT> *ProgramHeaders;
 };
 
 template <class ELFT> DynamicSection<ELFT> *Out<ELFT>::Dynamic;
 template <class ELFT> EhFrameHeader<ELFT> *Out<ELFT>::EhFrameHdr;
 template <class ELFT> GnuHashTableSection<ELFT> *Out<ELFT>::GnuHashTab;
 template <class ELFT> GotPltSection<ELFT> *Out<ELFT>::GotPlt;
 template <class ELFT> GotSection<ELFT> *Out<ELFT>::Got;
 template <class ELFT> HashTableSection<ELFT> *Out<ELFT>::HashTab;
 template <class ELFT> InterpSection<ELFT> *Out<ELFT>::Interp;
 template <class ELFT> OutputSection<ELFT> *Out<ELFT>::Bss;
 template <class ELFT> OutputSection<ELFT> *Out<ELFT>::MipsRldMap;
 template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::Opd;
 template <class ELFT> uint8_t *Out<ELFT>::OpdBuf;
 template <class ELFT> PltSection<ELFT> *Out<ELFT>::Plt;
 template <class ELFT> RelocationSection<ELFT> *Out<ELFT>::RelaDyn;
 template <class ELFT> RelocationSection<ELFT> *Out<ELFT>::RelaPlt;
 template <class ELFT> StringTableSection<ELFT> *Out<ELFT>::DynStrTab;
 template <class ELFT> StringTableSection<ELFT> *Out<ELFT>::ShStrTab;
 template <class ELFT> StringTableSection<ELFT> *Out<ELFT>::StrTab;
 template <class ELFT> SymbolTableSection<ELFT> *Out<ELFT>::DynSymTab;
 template <class ELFT> SymbolTableSection<ELFT> *Out<ELFT>::SymTab;
 template <class ELFT> typename Out<ELFT>::Elf_Phdr *Out<ELFT>::TlsPhdr;
 template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::ElfHeader;
 template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::ProgramHeaders;
 
 } // namespace elf2
 } // namespace lld
 
 #endif // LLD_ELF_OUTPUT_SECTIONS_H
diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp
index 0f7edf8..1392f23 100644
--- a/ELF/Writer.cpp
+++ b/ELF/Writer.cpp
@@ -1,1502 +1,1534 @@
 //===- Writer.cpp ---------------------------------------------------------===//
 //
 //                             The LLVM Linker
 //
 // This file is distributed under the University of Illinois Open Source
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 
 #include "Writer.h"
 #include "Config.h"
 #include "LinkerScript.h"
 #include "OutputSections.h"
 #include "SymbolTable.h"
 #include "Target.h"
 
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/FileOutputBuffer.h"
 #include "llvm/Support/StringSaver.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
 using namespace llvm::ELF;
 using namespace llvm::object;
 
 using namespace lld;
 using namespace lld::elf2;
 
 namespace {
 // The writer writes a SymbolTable result to a file.
 template <class ELFT> class Writer {
 public:
   typedef typename ELFFile<ELFT>::uintX_t uintX_t;
   typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
   typedef typename ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
   typedef typename ELFFile<ELFT>::Elf_Phdr Elf_Phdr;
   typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
   typedef typename ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range;
   typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela;
   Writer(SymbolTable<ELFT> &S) : Symtab(S) {}
   void run();
 
 private:
   // This describes a program header entry.
   // Each contains type, access flags and range of output sections that will be
   // placed in it.
   struct Phdr {
     Phdr(unsigned Type, unsigned Flags) {
       H.p_type = Type;
       H.p_flags = Flags;
     }
     Elf_Phdr H = {};
     OutputSectionBase<ELFT> *First = nullptr;
     OutputSectionBase<ELFT> *Last = nullptr;
   };
 
   void copyLocalSymbols();
   void addReservedSymbols();
   bool createSections();
   void addPredefinedSections();
 
   template <bool isRela>
   void scanRelocs(InputSectionBase<ELFT> &C,
                   iterator_range<const Elf_Rel_Impl<ELFT, isRela> *> Rels);
 
   void scanRelocs(InputSection<ELFT> &C);
   void scanRelocs(InputSectionBase<ELFT> &S, const Elf_Shdr &RelSec);
   void createPhdrs();
   void assignAddresses();
+  void assignAddressesRelocatable();
   void fixAbsoluteSymbols();
   bool openFile();
   void writeHeader();
   void writeSections();
   bool isDiscarded(InputSectionBase<ELFT> *IS) const;
   StringRef getOutputSectionName(InputSectionBase<ELFT> *S) const;
   bool needsInterpSection() const {
     return !Symtab.getSharedFiles().empty() && !Config->DynamicLinker.empty();
   }
   bool isOutputDynamic() const {
     return !Symtab.getSharedFiles().empty() || Config->Shared;
   }
 
   OutputSection<ELFT> *getBss();
   void addCommonSymbols(std::vector<DefinedCommon *> &Syms);
   void addCopyRelSymbols(std::vector<SharedSymbol<ELFT> *> &Syms);
 
   std::unique_ptr<llvm::FileOutputBuffer> Buffer;
 
   BumpPtrAllocator Alloc;
   std::vector<OutputSectionBase<ELFT> *> OutputSections;
   std::vector<std::unique_ptr<OutputSectionBase<ELFT>>> OwningSections;
 
   // We create a section for the ELF header and one for the program headers.
-  const unsigned NumDummySections = 2;
   ArrayRef<OutputSectionBase<ELFT> *> getSections() const {
-    return makeArrayRef(OutputSections).slice(NumDummySections);
+    return makeArrayRef(OutputSections).slice(dummySectionsNum());
   }
   unsigned getNumSections() const {
-    return OutputSections.size() + 1 - NumDummySections;
+    return OutputSections.size() + 1 - dummySectionsNum();
   }
+  // Usually there are 2 dummies sections: ELF header and program header.
+  // Relocatable output does not require program headers to be created.
+  unsigned dummySectionsNum() const { return Config->Relocatable ? 1 : 2; }
 
   void addRelIpltSymbols();
   void addStartEndSymbols();
   void addStartStopSymbols(OutputSectionBase<ELFT> *Sec);
 
   SymbolTable<ELFT> &Symtab;
   std::vector<Phdr> Phdrs;
 
   uintX_t FileSize;
   uintX_t SectionHeaderOff;
 
   // Flag to force GOT to be in output if we have relocations
   // that relies on its address.
   bool HasGotOffRel = false;
 };
 } // anonymous namespace
 
 template <class ELFT> static bool shouldUseRela() { return ELFT::Is64Bits; }
 
 template <class ELFT> void elf2::writeResult(SymbolTable<ELFT> *Symtab) {
   typedef typename ELFFile<ELFT>::uintX_t uintX_t;
 
   // Create singleton output sections.
   bool IsRela = shouldUseRela<ELFT>();
   DynamicSection<ELFT> Dynamic(*Symtab);
   EhFrameHeader<ELFT> EhFrameHdr;
   GotSection<ELFT> Got;
   InterpSection<ELFT> Interp;
   PltSection<ELFT> Plt;
   RelocationSection<ELFT> RelaDyn(IsRela ? ".rela.dyn" : ".rel.dyn", IsRela);
   StringTableSection<ELFT> DynStrTab(".dynstr", true);
   StringTableSection<ELFT> ShStrTab(".shstrtab", false);
   SymbolTableSection<ELFT> DynSymTab(*Symtab, DynStrTab);
 
   OutputSectionBase<ELFT> ElfHeader("", 0, SHF_ALLOC);
   OutputSectionBase<ELFT> ProgramHeaders("", 0, SHF_ALLOC);
   ProgramHeaders.updateAlign(sizeof(uintX_t));
 
   // Instantiate optional output sections if they are needed.
   std::unique_ptr<GnuHashTableSection<ELFT>> GnuHashTab;
   std::unique_ptr<GotPltSection<ELFT>> GotPlt;
   std::unique_ptr<HashTableSection<ELFT>> HashTab;
   std::unique_ptr<RelocationSection<ELFT>> RelaPlt;
   std::unique_ptr<StringTableSection<ELFT>> StrTab;
   std::unique_ptr<SymbolTableSection<ELFT>> SymTabSec;
 
   if (Config->GnuHash)
     GnuHashTab.reset(new GnuHashTableSection<ELFT>);
   if (Config->SysvHash)
     HashTab.reset(new HashTableSection<ELFT>);
   if (Target->UseLazyBinding) {
     StringRef S = IsRela ? ".rela.plt" : ".rel.plt";
     GotPlt.reset(new GotPltSection<ELFT>);
     RelaPlt.reset(new RelocationSection<ELFT>(S, IsRela));
   }
   if (!Config->StripAll) {
     StrTab.reset(new StringTableSection<ELFT>(".strtab", false));
     SymTabSec.reset(new SymbolTableSection<ELFT>(*Symtab, *StrTab));
   }
 
   Out<ELFT>::DynStrTab = &DynStrTab;
   Out<ELFT>::DynSymTab = &DynSymTab;
   Out<ELFT>::Dynamic = &Dynamic;
   Out<ELFT>::EhFrameHdr = &EhFrameHdr;
   Out<ELFT>::GnuHashTab = GnuHashTab.get();
   Out<ELFT>::Got = &Got;
   Out<ELFT>::GotPlt = GotPlt.get();
   Out<ELFT>::HashTab = HashTab.get();
   Out<ELFT>::Interp = &Interp;
   Out<ELFT>::Plt = &Plt;
   Out<ELFT>::RelaDyn = &RelaDyn;
   Out<ELFT>::RelaPlt = RelaPlt.get();
   Out<ELFT>::ShStrTab = &ShStrTab;
   Out<ELFT>::StrTab = StrTab.get();
   Out<ELFT>::SymTab = SymTabSec.get();
   Out<ELFT>::Bss = nullptr;
   Out<ELFT>::MipsRldMap = nullptr;
   Out<ELFT>::Opd = nullptr;
   Out<ELFT>::OpdBuf = nullptr;
   Out<ELFT>::TlsPhdr = nullptr;
   Out<ELFT>::ElfHeader = &ElfHeader;
   Out<ELFT>::ProgramHeaders = &ProgramHeaders;
 
   Writer<ELFT>(*Symtab).run();
 }
 
 // The main function of the writer.
 template <class ELFT> void Writer<ELFT>::run() {
   if (!Config->DiscardAll)
     copyLocalSymbols();
   addReservedSymbols();
   if (!createSections())
     return;
-  createPhdrs();
-  assignAddresses();
+  if (!Config->Relocatable) {
+    createPhdrs();
+    assignAddresses();
+  } else {
+    assignAddressesRelocatable();
+  }
   fixAbsoluteSymbols();
   if (!openFile())
     return;
   writeHeader();
   writeSections();
   if (HasError)
     return;
   fatal(Buffer->commit());
 }
 
 namespace {
 template <bool Is64Bits> struct SectionKey {
   typedef typename std::conditional<Is64Bits, uint64_t, uint32_t>::type uintX_t;
   StringRef Name;
   uint32_t Type;
   uintX_t Flags;
   uintX_t Alignment;
 };
 }
 namespace llvm {
 template <bool Is64Bits> struct DenseMapInfo<SectionKey<Is64Bits>> {
   static SectionKey<Is64Bits> getEmptyKey() {
     return SectionKey<Is64Bits>{DenseMapInfo<StringRef>::getEmptyKey(), 0, 0,
                                 0};
   }
   static SectionKey<Is64Bits> getTombstoneKey() {
     return SectionKey<Is64Bits>{DenseMapInfo<StringRef>::getTombstoneKey(), 0,
                                 0, 0};
   }
   static unsigned getHashValue(const SectionKey<Is64Bits> &Val) {
     return hash_combine(Val.Name, Val.Type, Val.Flags, Val.Alignment);
   }
   static bool isEqual(const SectionKey<Is64Bits> &LHS,
                       const SectionKey<Is64Bits> &RHS) {
     return DenseMapInfo<StringRef>::isEqual(LHS.Name, RHS.Name) &&
            LHS.Type == RHS.Type && LHS.Flags == RHS.Flags &&
            LHS.Alignment == RHS.Alignment;
   }
 };
 }
 
 template <class ELFT, class RelT>
 static bool handleTlsRelocation(unsigned Type, SymbolBody *Body,
                                 InputSectionBase<ELFT> &C, RelT &RI) {
   if (Target->isTlsLocalDynamicRel(Type)) {
     if (Target->canRelaxTls(Type, nullptr))
       return true;
     if (Out<ELFT>::Got->addTlsIndex())
       Out<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel,
                                     DynamicReloc<ELFT>::Off_LTlsIndex,
                                     nullptr});
     return true;
   }
 
   if (!Body || !Body->IsTls)
     return false;
 
   if (Target->isTlsGlobalDynamicRel(Type)) {
     if (!Target->canRelaxTls(Type, Body)) {
       if (Out<ELFT>::Got->addDynTlsEntry(Body)) {
         Out<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel,
                                       DynamicReloc<ELFT>::Off_GTlsIndex, Body});
         Out<ELFT>::RelaDyn->addReloc(
             {Target->TlsOffsetRel, DynamicReloc<ELFT>::Off_GTlsOffset, Body});
       }
       return true;
     }
     if (!canBePreempted(Body, true))
       return true;
   }
   return !Target->isTlsDynRel(Type, *Body);
 }
 
 // The reason we have to do this early scan is as follows
 // * To mmap the output file, we need to know the size
 // * For that, we need to know how many dynamic relocs we will have.
 // It might be possible to avoid this by outputting the file with write:
 // * Write the allocated output sections, computing addresses.
 // * Apply relocations, recording which ones require a dynamic reloc.
 // * Write the dynamic relocations.
 // * Write the rest of the file.
 // This would have some drawbacks. For example, we would only know if .rela.dyn
 // is needed after applying relocations. If it is, it will go after rw and rx
 // sections. Given that it is ro, we will need an extra PT_LOAD. This
 // complicates things for the dynamic linker and means we would have to reserve
 // space for the extra PT_LOAD even if we end up not using it.
 template <class ELFT>
 template <bool isRela>
 void Writer<ELFT>::scanRelocs(
     InputSectionBase<ELFT> &C,
     iterator_range<const Elf_Rel_Impl<ELFT, isRela> *> Rels) {
   typedef Elf_Rel_Impl<ELFT, isRela> RelType;
   const ObjectFile<ELFT> &File = *C.getFile();
   for (const RelType &RI : Rels) {
     uint32_t SymIndex = RI.getSymbol(Config->Mips64EL);
     SymbolBody *Body = File.getSymbolBody(SymIndex);
     uint32_t Type = RI.getType(Config->Mips64EL);
 
     // Ignore "hint" relocation because it is for optional code optimization.
     if (Target->isHintRel(Type))
       continue;
 
     if (Target->isGotRelative(Type))
       HasGotOffRel = true;
 
     // Set "used" bit for --as-needed.
     if (Body && Body->isUndefined() && !Body->isWeak())
       if (auto *S = dyn_cast<SharedSymbol<ELFT>>(Body->repl()))
         S->File->IsUsed = true;
 
     if (Body)
       Body = Body->repl();
 
     if (handleTlsRelocation<ELFT>(Type, Body, C, RI))
       continue;
 
     if (Target->needsDynRelative(Type))
       Out<ELFT>::RelaDyn->addReloc({Target->RelativeRel, &C, RI.r_offset, true,
                                     Body, getAddend<ELFT>(RI)});
 
     // MIPS has a special rule to create GOTs for local symbols.
     if (Config->EMachine == EM_MIPS && !canBePreempted(Body, true) &&
         (Type == R_MIPS_GOT16 || Type == R_MIPS_CALL16)) {
       // FIXME (simon): Do not add so many redundant entries.
       Out<ELFT>::Got->addMipsLocalEntry();
       continue;
     }
 
     // If a symbol in a DSO is referenced directly instead of through GOT,
     // we need to create a copy relocation for the symbol.
     if (auto *B = dyn_cast_or_null<SharedSymbol<ELFT>>(Body)) {
       if (B->needsCopy())
         continue;
       if (Target->needsCopyRel<ELFT>(Type, *B)) {
         B->NeedsCopyOrPltAddr = true;
         Out<ELFT>::RelaDyn->addReloc(
             {Target->CopyRel, DynamicReloc<ELFT>::Off_Bss, B});
         continue;
       }
     }
 
     // An STT_GNU_IFUNC symbol always uses a PLT entry, and all references
     // to the symbol go through the PLT. This is true even for a local
     // symbol, although local symbols normally do not require PLT entries.
     if (Body && isGnuIFunc<ELFT>(*Body)) {
       if (Body->isInPlt())
         continue;
       Out<ELFT>::Plt->addEntry(Body);
       bool CBP = canBePreempted(Body, /*NeedsGot=*/true);
       if (Target->UseLazyBinding) {
         Out<ELFT>::GotPlt->addEntry(Body);
         Out<ELFT>::RelaPlt->addReloc(
             {CBP ? Target->PltRel : Target->IRelativeRel,
              DynamicReloc<ELFT>::Off_GotPlt, !CBP, Body});
       } else {
         Out<ELFT>::Got->addEntry(Body);
         Out<ELFT>::RelaDyn->addReloc(
             {CBP ? Target->PltRel : Target->IRelativeRel,
              DynamicReloc<ELFT>::Off_Got, !CBP, Body});
       }
       continue;
     }
 
     // If a relocation needs PLT, we create a PLT and a GOT slot
     // for the symbol.
     TargetInfo::PltNeed NeedPlt = TargetInfo::Plt_No;
     if (Body)
       NeedPlt = Target->needsPlt(Type, *Body);
     if (NeedPlt) {
       if (NeedPlt == TargetInfo::Plt_Implicit)
         Body->NeedsCopyOrPltAddr = true;
       if (Body->isInPlt())
         continue;
       Out<ELFT>::Plt->addEntry(Body);
 
       if (Target->UseLazyBinding) {
         Out<ELFT>::GotPlt->addEntry(Body);
         Out<ELFT>::RelaPlt->addReloc(
             {Target->PltRel, DynamicReloc<ELFT>::Off_GotPlt, Body});
       } else {
         if (Body->isInGot())
           continue;
         Out<ELFT>::Got->addEntry(Body);
         Out<ELFT>::RelaDyn->addReloc(
             {Target->GotRel, DynamicReloc<ELFT>::Off_Got, Body});
       }
       continue;
     }
 
     // If a relocation needs GOT, we create a GOT slot for the symbol.
     if (Body && Target->needsGot(Type, *Body)) {
       if (Body->isInGot())
         continue;
       Out<ELFT>::Got->addEntry(Body);
 
       if (Config->EMachine == EM_MIPS) {
         // MIPS ABI has special rules to process GOT entries
         // and doesn't require relocation entries for them.
         // 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
         Body->MustBeInDynSym = true;
         continue;
       }
 
       bool CBP = canBePreempted(Body, /*NeedsGot=*/true);
       bool Dynrel = Config->Shared && !Target->isRelRelative(Type) &&
                     !Target->isSizeRel(Type);
       if (CBP || Dynrel) {
         uint32_t DynType;
         if (CBP)
           DynType = Body->IsTls ? Target->TlsGotRel : Target->GotRel;
         else
           DynType = Target->RelativeRel;
         Out<ELFT>::RelaDyn->addReloc(
             {DynType, DynamicReloc<ELFT>::Off_Got, !CBP, Body});
       }
       continue;
     }
 
     if (Config->EMachine == EM_MIPS) {
       if (Type == R_MIPS_LO16)
         // Ignore R_MIPS_LO16 relocation. If it is a pair for R_MIPS_GOT16 we
         // already completed all required action (GOT entry allocation) when
         // handle R_MIPS_GOT16a. If it is a pair for R_MIPS_HI16 against
         // _gp_disp it does not require dynamic relocation. If its a pair for
         // R_MIPS_HI16 against a regular symbol it does not require dynamic
         // relocation too because that case is possible for executable file
         // linking only.
         continue;
       if (Body == Config->MipsGpDisp || Body == Config->MipsLocalGp)
         // MIPS _gp_disp designates offset between start of function and 'gp'
         // pointer into GOT. __gnu_local_gp is equal to the current value of
         // the 'gp'. Therefore any relocations against them do not require
         // dynamic relocation.
         continue;
     }
 
     if (canBePreempted(Body, /*NeedsGot=*/false)) {
       // We don't know anything about the finaly symbol. Just ask the dynamic
       // linker to handle the relocation for us.
       Out<ELFT>::RelaDyn->addReloc({Target->getDynRel(Type), &C, RI.r_offset,
                                     false, Body, getAddend<ELFT>(RI)});
       continue;
     }
 
     // We know that this is the final symbol. If the program being produced
     // is position independent, the final value is still not known.
     // If the relocation depends on the symbol value (not the size or distances
     // in the output), we still need some help from the dynamic linker.
     // We can however do better than just copying the incoming relocation. We
     // can process some of it and and just ask the dynamic linker to add the
     // load address.
     if (!Config->Shared || Target->isRelRelative(Type) ||
         Target->isSizeRel(Type))
       continue;
 
     uintX_t Addend = getAddend<ELFT>(RI);
     if (Config->EMachine == EM_PPC64 && RI.getType(false) == R_PPC64_TOC) {
       Out<ELFT>::RelaDyn->addReloc({R_PPC64_RELATIVE, &C, RI.r_offset, false,
                                     nullptr,
                                     (uintX_t)getPPC64TocBase() + Addend});
       continue;
     }
     if (Body) {
       Out<ELFT>::RelaDyn->addReloc(
           {Target->RelativeRel, &C, RI.r_offset, true, Body, Addend});
       continue;
     }
     const Elf_Sym *Sym =
         File.getObj().getRelocationSymbol(&RI, File.getSymbolTable());
     InputSectionBase<ELFT> *Section = File.getSection(*Sym);
     uintX_t Offset = Sym->st_value;
     if (Sym->getType() == STT_SECTION) {
       Offset += Addend;
       Addend = 0;
     }
     Out<ELFT>::RelaDyn->addReloc(
         {Target->RelativeRel, &C, RI.r_offset, Section, Offset, Addend});
   }
 }
 
 template <class ELFT> void Writer<ELFT>::scanRelocs(InputSection<ELFT> &C) {
   if (C.getSectionHdr()->sh_flags & SHF_ALLOC)
     for (const Elf_Shdr *RelSec : C.RelocSections)
       scanRelocs(C, *RelSec);
 }
 
 template <class ELFT>
 void Writer<ELFT>::scanRelocs(InputSectionBase<ELFT> &S,
                               const Elf_Shdr &RelSec) {
   ELFFile<ELFT> &EObj = S.getFile()->getObj();
   if (RelSec.sh_type == SHT_RELA)
     scanRelocs(S, EObj.relas(&RelSec));
   else
     scanRelocs(S, EObj.rels(&RelSec));
 }
 
 template <class ELFT>
 static void reportUndefined(SymbolTable<ELFT> &Symtab, SymbolBody *Sym) {
-  if (Config->Shared && !Config->NoUndefined)
+  if ((Config->Relocatable || Config->Shared) && !Config->NoUndefined)
     return;
 
   std::string Msg = "undefined symbol: " + Sym->getName().str();
   if (ELFFileBase<ELFT> *File = Symtab.findFile(Sym))
     Msg += " in " + File->getName().str();
   if (Config->NoInhibitExec)
     warning(Msg);
   else
     error(Msg);
 }
 
 template <class ELFT>
 static bool shouldKeepInSymtab(const ObjectFile<ELFT> &File, StringRef SymName,
                                const typename ELFFile<ELFT>::Elf_Sym &Sym) {
   if (Sym.getType() == STT_SECTION || Sym.getType() == STT_FILE)
     return false;
 
   InputSectionBase<ELFT> *Sec = File.getSection(Sym);
   // If sym references a section in a discarded group, don't keep it.
   if (Sec == &InputSection<ELFT>::Discarded)
     return false;
 
   if (Config->DiscardNone)
     return true;
 
   // In ELF assembly .L symbols are normally discarded by the assembler.
   // If the assembler fails to do so, the linker discards them if
   // * --discard-locals is used.
   // * The symbol is in a SHF_MERGE section, which is normally the reason for
   //   the assembler keeping the .L symbol.
   if (!SymName.startswith(".L") && !SymName.empty())
     return true;
 
   if (Config->DiscardLocals)
     return false;
 
   return !(Sec->getSectionHdr()->sh_flags & SHF_MERGE);
 }
 
 // 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 (!Out<ELFT>::SymTab)
     return;
   for (const std::unique_ptr<ObjectFile<ELFT>> &F : Symtab.getObjectFiles()) {
     for (const Elf_Sym &Sym : F->getLocalSymbols()) {
       ErrorOr<StringRef> SymNameOrErr = Sym.getName(F->getStringTable());
       fatal(SymNameOrErr);
       StringRef SymName = *SymNameOrErr;
       if (!shouldKeepInSymtab<ELFT>(*F, SymName, Sym))
         continue;
       if (Sym.st_shndx != SHN_ABS) {
         InputSectionBase<ELFT> *Section = F->getSection(Sym);
         if (!Section->isLive())
           continue;
       }
       ++Out<ELFT>::SymTab->NumLocals;
       F->KeptLocalSyms.push_back(std::make_pair(
           &Sym, Out<ELFT>::SymTab->StrTabSec.addString(SymName)));
     }
   }
 }
 
 // PPC64 has a number of special SHT_PROGBITS+SHF_ALLOC+SHF_WRITE sections that
 // we would like to make sure appear is a specific order to maximize their
 // coverage by a single signed 16-bit offset from the TOC base pointer.
 // Conversely, the special .tocbss section should be first among all SHT_NOBITS
 // sections. This will put it next to the loaded special PPC64 sections (and,
 // thus, within reach of the TOC base pointer).
 static int getPPC64SectionRank(StringRef SectionName) {
   return StringSwitch<int>(SectionName)
            .Case(".tocbss", 0)
            .Case(".branch_lt", 2)
            .Case(".toc", 3)
            .Case(".toc1", 4)
            .Case(".opd", 5)
            .Default(1);
 }
 
 template <class ELFT> static bool isRelroSection(OutputSectionBase<ELFT> *Sec) {
   if (!Config->ZRelro)
     return false;
   typename OutputSectionBase<ELFT>::uintX_t Flags = Sec->getFlags();
   if (!(Flags & SHF_ALLOC) || !(Flags & SHF_WRITE))
     return false;
   if (Flags & SHF_TLS)
     return true;
   uint32_t Type = Sec->getType();
   if (Type == SHT_INIT_ARRAY || Type == SHT_FINI_ARRAY ||
       Type == SHT_PREINIT_ARRAY)
     return true;
   if (Sec == Out<ELFT>::GotPlt)
     return Config->ZNow;
   if (Sec == Out<ELFT>::Dynamic || Sec == Out<ELFT>::Got)
     return true;
   StringRef S = Sec->getName();
   return S == ".data.rel.ro" || S == ".ctors" || S == ".dtors" || S == ".jcr" ||
          S == ".eh_frame";
 }
 
 // Output section ordering is determined by this function.
 template <class ELFT>
 static bool compareSections(OutputSectionBase<ELFT> *A,
                             OutputSectionBase<ELFT> *B) {
   typedef typename ELFFile<ELFT>::uintX_t uintX_t;
 
   int Comp = Script->compareSections(A->getName(), B->getName());
   if (Comp != 0)
     return Comp < 0;
 
   uintX_t AFlags = A->getFlags();
   uintX_t BFlags = B->getFlags();
 
   // Allocatable sections go first to reduce the total PT_LOAD size and
   // so debug info doesn't change addresses in actual code.
   bool AIsAlloc = AFlags & SHF_ALLOC;
   bool BIsAlloc = BFlags & SHF_ALLOC;
   if (AIsAlloc != BIsAlloc)
     return AIsAlloc;
 
   // We don't have any special requirements for the relative order of
   // two non allocatable sections.
   if (!AIsAlloc)
     return false;
 
   // We want the read only sections first so that they go in the PT_LOAD
   // covering the program headers at the start of the file.
   bool AIsWritable = AFlags & SHF_WRITE;
   bool BIsWritable = BFlags & SHF_WRITE;
   if (AIsWritable != BIsWritable)
     return BIsWritable;
 
   // For a corresponding reason, put non exec sections first (the program
   // header PT_LOAD is not executable).
   bool AIsExec = AFlags & SHF_EXECINSTR;
   bool BIsExec = BFlags & SHF_EXECINSTR;
   if (AIsExec != BIsExec)
     return BIsExec;
 
   // If we got here we know that both A and B are in the same PT_LOAD.
 
   // The TLS initialization block needs to be a single contiguous block in a R/W
   // PT_LOAD, so stick TLS sections directly before R/W sections. The TLS NOBITS
   // sections are placed here as they don't take up virtual address space in the
   // PT_LOAD.
   bool AIsTls = AFlags & SHF_TLS;
   bool BIsTls = BFlags & SHF_TLS;
   if (AIsTls != BIsTls)
     return AIsTls;
 
   // The next requirement we have is to put nobits sections last. The
   // reason is that the only thing the dynamic linker will see about
   // them is a p_memsz that is larger than p_filesz. Seeing that it
   // zeros the end of the PT_LOAD, so that has to correspond to the
   // nobits sections.
   bool AIsNoBits = A->getType() == SHT_NOBITS;
   bool BIsNoBits = B->getType() == SHT_NOBITS;
   if (AIsNoBits != BIsNoBits)
     return BIsNoBits;
 
   // We place RelRo section before plain r/w ones.
   bool AIsRelRo = isRelroSection(A);
   bool BIsRelRo = isRelroSection(B);
   if (AIsRelRo != BIsRelRo)
     return AIsRelRo;
 
   // Some architectures have additional ordering restrictions for sections
   // within the same PT_LOAD.
   if (Config->EMachine == EM_PPC64)
     return getPPC64SectionRank(A->getName()) <
            getPPC64SectionRank(B->getName());
 
   return false;
 }
 
 template <class ELFT> OutputSection<ELFT> *Writer<ELFT>::getBss() {
   if (!Out<ELFT>::Bss) {
     Out<ELFT>::Bss =
         new OutputSection<ELFT>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
     OwningSections.emplace_back(Out<ELFT>::Bss);
     OutputSections.push_back(Out<ELFT>::Bss);
   }
   return Out<ELFT>::Bss;
 }
 
 // Until this function is called, common symbols do not belong to any section.
 // This function adds them to end of BSS section.
 template <class ELFT>
 void Writer<ELFT>::addCommonSymbols(std::vector<DefinedCommon *> &Syms) {
   if (Syms.empty())
     return;
 
   // Sort the common symbols by alignment as an heuristic to pack them better.
   std::stable_sort(Syms.begin(), Syms.end(),
                    [](const DefinedCommon *A, const DefinedCommon *B) {
                      return A->MaxAlignment > B->MaxAlignment;
                    });
 
   uintX_t Off = getBss()->getSize();
   for (DefinedCommon *C : Syms) {
     Off = alignTo(Off, C->MaxAlignment);
     C->OffsetInBss = Off;
     Off += C->Size;
   }
 
   Out<ELFT>::Bss->setSize(Off);
 }
 
 // Reserve space in .bss for copy relocations.
 template <class ELFT>
 void Writer<ELFT>::addCopyRelSymbols(std::vector<SharedSymbol<ELFT> *> &Syms) {
   if (Syms.empty())
     return;
   uintX_t Off = getBss()->getSize();
   for (SharedSymbol<ELFT> *C : Syms) {
     const Elf_Sym &Sym = C->Sym;
     const Elf_Shdr *Sec = C->File->getSection(Sym);
     uintX_t SecAlign = Sec->sh_addralign;
     unsigned TrailingZeros =
         std::min(countTrailingZeros(SecAlign),
                  countTrailingZeros((uintX_t)Sym.st_value));
     uintX_t Align = 1 << TrailingZeros;
     Out<ELFT>::Bss->updateAlign(Align);
     Off = alignTo(Off, Align);
     C->OffsetInBss = Off;
     Off += Sym.st_size;
   }
   Out<ELFT>::Bss->setSize(Off);
 }
 
 template <class ELFT>
 StringRef Writer<ELFT>::getOutputSectionName(InputSectionBase<ELFT> *S) const {
   StringRef Dest = Script->getOutputSection<ELFT>(S);
   if (!Dest.empty())
     return Dest;
 
   StringRef Name = S->getSectionName();
   for (StringRef V : {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.",
                       ".init_array.", ".fini_array.", ".ctors.", ".dtors.",
                       ".tbss.", ".gcc_except_table.", ".tdata."})
     if (Name.startswith(V))
       return V.drop_back();
   return Name;
 }
 
 template <class ELFT>
 void reportDiscarded(InputSectionBase<ELFT> *IS,
                      const std::unique_ptr<ObjectFile<ELFT>> &File) {
   if (!Config->PrintGcSections || !IS || IS->isLive())
     return;
   llvm::errs() << "removing unused section from '" << IS->getSectionName()
                << "' in file '" << File->getName() << "'\n";
 }
 
 template <class ELFT>
 bool Writer<ELFT>::isDiscarded(InputSectionBase<ELFT> *S) const {
   return !S || !S->isLive() || S == &InputSection<ELFT>::Discarded ||
          Script->isDiscarded(S);
 }
 
 // The beginning and the ending of .rel[a].plt section are marked
 // with __rel[a]_iplt_{start,end} symbols if it is a statically linked
 // executable. The runtime needs these symbols in order to resolve
 // all IRELATIVE relocs on startup. For dynamic executables, we don't
 // need these symbols, since IRELATIVE relocs are resolved through GOT
 // and PLT. For details, see http://www.airs.com/blog/archives/403.
 template <class ELFT>
 void Writer<ELFT>::addRelIpltSymbols() {
   if (isOutputDynamic() || !Out<ELFT>::RelaPlt)
     return;
   bool IsRela = shouldUseRela<ELFT>();
 
   StringRef S = IsRela ? "__rela_iplt_start" : "__rel_iplt_start";
   if (Symtab.find(S))
     Symtab.addAbsolute(S, ElfSym<ELFT>::RelaIpltStart);
 
   S = IsRela ? "__rela_iplt_end" : "__rel_iplt_end";
   if (Symtab.find(S))
     Symtab.addAbsolute(S, ElfSym<ELFT>::RelaIpltEnd);
 }
 
 template <class ELFT> static bool includeInSymtab(const SymbolBody &B) {
   if (!B.isUsedInRegularObj())
     return false;
 
   if (auto *D = dyn_cast<DefinedRegular<ELFT>>(&B)) {
     // Don't include synthetic symbols like __init_array_start in every output.
     if (&D->Sym == &ElfSym<ELFT>::Ignored)
       return false;
     // Exclude symbols pointing to garbage-collected sections.
     if (D->Section && !D->Section->isLive())
       return false;
   }
   return true;
 }
 
 static bool includeInDynsym(const SymbolBody &B) {
   uint8_t V = B.getVisibility();
   if (V != STV_DEFAULT && V != STV_PROTECTED)
     return false;
   if (Config->ExportDynamic || Config->Shared)
     return true;
   return B.MustBeInDynSym;
 }
 
 // This class knows how to create an output section for a given
 // input section. Output section type is determined by various
 // factors, including input section's sh_flags, sh_type and
 // linker scripts.
 namespace {
 template <class ELFT> class OutputSectionFactory {
   typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
   typedef typename ELFFile<ELFT>::uintX_t uintX_t;
 
 public:
   std::pair<OutputSectionBase<ELFT> *, bool> create(InputSectionBase<ELFT> *C,
                                                     StringRef OutsecName);
 
   OutputSectionBase<ELFT> *lookup(StringRef Name, uint32_t Type, uintX_t Flags);
 
 private:
   SectionKey<ELFT::Is64Bits> createKey(InputSectionBase<ELFT> *C,
                                        StringRef OutsecName);
 
   SmallDenseMap<SectionKey<ELFT::Is64Bits>, OutputSectionBase<ELFT> *> Map;
 };
 }
 
 template <class ELFT>
 std::pair<OutputSectionBase<ELFT> *, bool>
 OutputSectionFactory<ELFT>::create(InputSectionBase<ELFT> *C,
                                    StringRef OutsecName) {
   SectionKey<ELFT::Is64Bits> Key = createKey(C, OutsecName);
   OutputSectionBase<ELFT> *&Sec = Map[Key];
   if (Sec)
     return {Sec, false};
 
   switch (C->SectionKind) {
   case InputSectionBase<ELFT>::Regular:
     Sec = new OutputSection<ELFT>(Key.Name, Key.Type, Key.Flags);
     break;
   case InputSectionBase<ELFT>::EHFrame:
     Sec = new EHOutputSection<ELFT>(Key.Name, Key.Type, Key.Flags);
     break;
   case InputSectionBase<ELFT>::Merge:
     Sec = new MergeOutputSection<ELFT>(Key.Name, Key.Type, Key.Flags,
                                        Key.Alignment);
     break;
   case InputSectionBase<ELFT>::MipsReginfo:
     Sec = new MipsReginfoOutputSection<ELFT>();
     break;
   }
   return {Sec, true};
 }
 
 template <class ELFT>
 OutputSectionBase<ELFT> *OutputSectionFactory<ELFT>::lookup(StringRef Name,
                                                             uint32_t Type,
                                                             uintX_t Flags) {
   return Map.lookup({Name, Type, Flags, 0});
 }
 
 template <class ELFT>
 SectionKey<ELFT::Is64Bits>
 OutputSectionFactory<ELFT>::createKey(InputSectionBase<ELFT> *C,
                                       StringRef OutsecName) {
   const Elf_Shdr *H = C->getSectionHdr();
   uintX_t Flags = H->sh_flags & ~SHF_GROUP;
 
   // For SHF_MERGE we create different output sections for each alignment.
   // This makes each output section simple and keeps a single level mapping from
   // input to output.
   uintX_t Alignment = 0;
   if (isa<MergeInputSection<ELFT>>(C)) {
     Alignment = H->sh_addralign;
     if (H->sh_entsize > Alignment)
       Alignment = H->sh_entsize;
   }
 
   // GNU as can give .eh_frame secion type SHT_PROGBITS or SHT_X86_64_UNWIND
   // depending on the construct. We want to canonicalize it so that
   // there is only one .eh_frame in the end.
   uint32_t Type = H->sh_type;
   if (Type == SHT_PROGBITS && Config->EMachine == EM_X86_64 &&
       isa<EHInputSection<ELFT>>(C))
     Type = SHT_X86_64_UNWIND;
 
   return SectionKey<ELFT::Is64Bits>{OutsecName, Type, Flags, Alignment};
 }
 
 // The linker is expected to define some symbols depending on
 // the linking result. This function defines such symbols.
 template <class ELFT> void Writer<ELFT>::addReservedSymbols() {
   // __tls_get_addr is defined by the dynamic linker for dynamic ELFs. For
   // static linking the linker is required to optimize away any references to
   // __tls_get_addr, so it's not defined anywhere. Create a hidden definition
   // to avoid the undefined symbol error.
   if (!isOutputDynamic())
     Symtab.addIgnored("__tls_get_addr");
 
   // If the "_end" symbol is referenced, it is expected to point to the address
   // right after the data segment. Usually, this symbol points to the end
   // of .bss section or to the end of .data section if .bss section is absent.
   // We don't know the final address of _end yet, so just add a symbol here,
   // and fix ElfSym<ELFT>::End.st_value later.
   if (Symtab.find("_end"))
     Symtab.addAbsolute("_end", ElfSym<ELFT>::End);
 
   // Define "end" as an alias to "_end" if it is used but not defined.
   // We don't want to define that unconditionally because we don't want to
   // break programs that uses "end" as a regular symbol.
   if (SymbolBody *B = Symtab.find("end"))
     if (B->isUndefined())
       Symtab.addAbsolute("end", ElfSym<ELFT>::End);
 }
 
 // Sort input sections by section name suffixes for
 // __attribute__((init_priority(N))).
 template <class ELFT> static void sortInitFini(OutputSectionBase<ELFT> *S) {
   if (S)
     reinterpret_cast<OutputSection<ELFT> *>(S)->sortInitFini();
 }
 
 // Sort input sections by the special rule for .ctors and .dtors.
 template <class ELFT> static void sortCtorsDtors(OutputSectionBase<ELFT> *S) {
   if (S)
     reinterpret_cast<OutputSection<ELFT> *>(S)->sortCtorsDtors();
 }
 
 // Create output section objects and add them to OutputSections.
 template <class ELFT> bool Writer<ELFT>::createSections() {
   OutputSections.push_back(Out<ELFT>::ElfHeader);
-  OutputSections.push_back(Out<ELFT>::ProgramHeaders);
+  if (!Config->Relocatable)
+    OutputSections.push_back(Out<ELFT>::ProgramHeaders);
 
   // Add .interp first because some loaders want to see that section
   // on the first page of the executable file when loaded into memory.
   if (needsInterpSection())
     OutputSections.push_back(Out<ELFT>::Interp);
 
   // Create output sections for input object file sections.
   std::vector<OutputSectionBase<ELFT> *> RegularSections;
   OutputSectionFactory<ELFT> Factory;
   for (const std::unique_ptr<ObjectFile<ELFT>> &F : Symtab.getObjectFiles()) {
     for (InputSectionBase<ELFT> *C : F->getSections()) {
       if (isDiscarded(C)) {
         reportDiscarded(C, F);
         continue;
       }
       OutputSectionBase<ELFT> *Sec;
       bool IsNew;
       std::tie(Sec, IsNew) = Factory.create(C, getOutputSectionName(C));
       if (IsNew) {
         OwningSections.emplace_back(Sec);
         OutputSections.push_back(Sec);
         RegularSections.push_back(Sec);
       }
       Sec->addSection(C);
     }
   }
 
   Out<ELFT>::Bss = static_cast<OutputSection<ELFT> *>(
       Factory.lookup(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE));
 
   // If we have a .opd section (used under PPC64 for function descriptors),
   // store a pointer to it here so that we can use it later when processing
   // relocations.
   Out<ELFT>::Opd = Factory.lookup(".opd", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC);
 
   Out<ELFT>::Dynamic->PreInitArraySec = Factory.lookup(
       ".preinit_array", SHT_PREINIT_ARRAY, SHF_WRITE | SHF_ALLOC);
   Out<ELFT>::Dynamic->InitArraySec =
       Factory.lookup(".init_array", SHT_INIT_ARRAY, SHF_WRITE | SHF_ALLOC);
   Out<ELFT>::Dynamic->FiniArraySec =
       Factory.lookup(".fini_array", SHT_FINI_ARRAY, SHF_WRITE | SHF_ALLOC);
 
   // Sort section contents for __attribute__((init_priority(N)).
   sortInitFini(Out<ELFT>::Dynamic->InitArraySec);
   sortInitFini(Out<ELFT>::Dynamic->FiniArraySec);
   sortCtorsDtors(Factory.lookup(".ctors", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC));
   sortCtorsDtors(Factory.lookup(".dtors", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC));
 
   // The linker needs to define SECNAME_start, SECNAME_end and SECNAME_stop
   // symbols for sections, so that the runtime can get the start and end
   // addresses of each section by section name. Add such symbols.
   addStartEndSymbols();
   for (OutputSectionBase<ELFT> *Sec : RegularSections)
     addStartStopSymbols(Sec);
 
   // Define __rel[a]_iplt_{start,end} symbols if needed.
   addRelIpltSymbols();
 
   // Scan relocations. This must be done after every symbol is declared so that
   // we can correctly decide if a dynamic relocation is needed.
   for (const std::unique_ptr<ObjectFile<ELFT>> &F : Symtab.getObjectFiles()) {
     for (InputSectionBase<ELFT> *C : F->getSections()) {
       if (isDiscarded(C))
         continue;
       if (auto *S = dyn_cast<InputSection<ELFT>>(C))
         scanRelocs(*S);
       else if (auto *S = dyn_cast<EHInputSection<ELFT>>(C))
         if (S->RelocSection)
           scanRelocs(*S, *S->RelocSection);
     }
   }
 
   // Now that we have defined all possible symbols including linker-
   // synthesized ones. Visit all symbols to give the finishing touches.
   std::vector<DefinedCommon *> CommonSymbols;
   std::vector<SharedSymbol<ELFT> *> CopyRelSymbols;
   for (auto &P : Symtab.getSymbols()) {
     SymbolBody *Body = P.second->Body;
     if (auto *U = dyn_cast<Undefined>(Body))
       if (!U->isWeak() && !U->canKeepUndefined())
         reportUndefined<ELFT>(Symtab, Body);
 
     if (auto *C = dyn_cast<DefinedCommon>(Body))
       CommonSymbols.push_back(C);
     if (auto *SC = dyn_cast<SharedSymbol<ELFT>>(Body))
       if (SC->needsCopy())
         CopyRelSymbols.push_back(SC);
 
     if (!includeInSymtab<ELFT>(*Body))
       continue;
     if (Out<ELFT>::SymTab)
       Out<ELFT>::SymTab->addSymbol(Body);
 
     if (isOutputDynamic() && includeInDynsym(*Body))
       Out<ELFT>::DynSymTab->addSymbol(Body);
   }
 
   // Do not proceed if there was an undefined symbol.
   if (HasError)
     return false;
 
   addCommonSymbols(CommonSymbols);
   addCopyRelSymbols(CopyRelSymbols);
 
   // So far we have added sections from input object files.
   // This function adds linker-created Out<ELFT>::* sections.
   addPredefinedSections();
 
   std::stable_sort(OutputSections.begin(), OutputSections.end(),
                    compareSections<ELFT>);
 
-  for (unsigned I = NumDummySections, N = OutputSections.size(); I < N; ++I)
-    OutputSections[I]->SectionIndex = I + 1 - NumDummySections;
+  for (unsigned I = dummySectionsNum(), N = OutputSections.size(); I < N; ++I)
+    OutputSections[I]->SectionIndex = I + 1 - dummySectionsNum();
 
   for (OutputSectionBase<ELFT> *Sec : getSections())
     Sec->setSHName(Out<ELFT>::ShStrTab->addString(Sec->getName()));
 
   // Finalizers fix each section's size.
   // .dynsym is finalized early since that may fill up .gnu.hash.
   if (isOutputDynamic())
     Out<ELFT>::DynSymTab->finalize();
 
   // Fill other section headers. The dynamic table is finalized
   // at the end because some tags like RELSZ depend on result
   // of finalizing other sections. The dynamic string table is
   // finalized once the .dynamic finalizer has added a few last
   // strings. See DynamicSection::finalize()
   for (OutputSectionBase<ELFT> *Sec : OutputSections)
     if (Sec != Out<ELFT>::DynStrTab && Sec != Out<ELFT>::Dynamic)
       Sec->finalize();
 
   if (isOutputDynamic())
     Out<ELFT>::Dynamic->finalize();
   return true;
 }
 
 // This function add Out<ELFT>::* sections to OutputSections.
 template <class ELFT> void Writer<ELFT>::addPredefinedSections() {
   auto Add = [&](OutputSectionBase<ELFT> *C) {
     if (C)
       OutputSections.push_back(C);
   };
 
   // This order is not the same as the final output order
   // because we sort the sections using their attributes below.
   Add(Out<ELFT>::SymTab);
   Add(Out<ELFT>::ShStrTab);
   Add(Out<ELFT>::StrTab);
   if (isOutputDynamic()) {
     Add(Out<ELFT>::DynSymTab);
     Add(Out<ELFT>::GnuHashTab);
     Add(Out<ELFT>::HashTab);
     Add(Out<ELFT>::Dynamic);
     Add(Out<ELFT>::DynStrTab);
     if (Out<ELFT>::RelaDyn->hasRelocs())
       Add(Out<ELFT>::RelaDyn);
 
     // This is a MIPS specific section to hold a space within the data segment
     // of executable file which is pointed to by the DT_MIPS_RLD_MAP entry.
     // See "Dynamic section" in Chapter 5 in the following document:
     // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
     if (Config->EMachine == EM_MIPS && !Config->Shared) {
       Out<ELFT>::MipsRldMap = new OutputSection<ELFT>(".rld_map", SHT_PROGBITS,
                                                       SHF_ALLOC | SHF_WRITE);
       Out<ELFT>::MipsRldMap->setSize(sizeof(uintX_t));
       Out<ELFT>::MipsRldMap->updateAlign(sizeof(uintX_t));
       OwningSections.emplace_back(Out<ELFT>::MipsRldMap);
       Add(Out<ELFT>::MipsRldMap);
     }
   }
 
   // We always need to add rel[a].plt to output if it has entries.
   // Even during static linking it can contain R_[*]_IRELATIVE relocations.
   if (Out<ELFT>::RelaPlt && Out<ELFT>::RelaPlt->hasRelocs()) {
     Add(Out<ELFT>::RelaPlt);
     Out<ELFT>::RelaPlt->Static = !isOutputDynamic();
   }
 
   bool needsGot = !Out<ELFT>::Got->empty();
   // We add the .got section to the result for dynamic MIPS target because
   // its address and properties are mentioned in the .dynamic section.
   if (Config->EMachine == EM_MIPS)
     needsGot |= isOutputDynamic();
   // If we have a relocation that is relative to GOT (such as GOTOFFREL),
   // we need to emit a GOT even if it's empty.
   if (HasGotOffRel)
     needsGot = true;
 
   if (needsGot)
     Add(Out<ELFT>::Got);
   if (Out<ELFT>::GotPlt && !Out<ELFT>::GotPlt->empty())
     Add(Out<ELFT>::GotPlt);
   if (!Out<ELFT>::Plt->empty())
     Add(Out<ELFT>::Plt);
 
   if (Out<ELFT>::EhFrameHdr->Live)
     Add(Out<ELFT>::EhFrameHdr);
 }
 
 // The linker is expected to define SECNAME_start and SECNAME_end
 // symbols for a few sections. This function defines them.
 template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
   auto Define = [&](StringRef Start, StringRef End,
                     OutputSectionBase<ELFT> *OS) {
     if (OS) {
       Symtab.addSynthetic(Start, *OS, 0);
       Symtab.addSynthetic(End, *OS, OS->getSize());
     } else {
       Symtab.addIgnored(Start);
       Symtab.addIgnored(End);
     }
   };
 
   Define("__preinit_array_start", "__preinit_array_end",
          Out<ELFT>::Dynamic->PreInitArraySec);
   Define("__init_array_start", "__init_array_end",
          Out<ELFT>::Dynamic->InitArraySec);
   Define("__fini_array_start", "__fini_array_end",
          Out<ELFT>::Dynamic->FiniArraySec);
 }
 
 static bool isAlpha(char C) {
   return ('a' <= C && C <= 'z') || ('A' <= C && C <= 'Z') || C == '_';
 }
 
 static bool isAlnum(char C) { return isAlpha(C) || ('0' <= C && C <= '9'); }
 
 // Returns true if S is valid as a C language identifier.
 static bool isValidCIdentifier(StringRef S) {
   if (S.empty() || !isAlpha(S[0]))
     return false;
   return std::all_of(S.begin() + 1, S.end(), isAlnum);
 }
 
 // If a section name is valid as a C identifier (which is rare because of
 // the leading '.'), linkers are expected to define __start_<secname> and
 // __stop_<secname> symbols. They are at beginning and end of the section,
 // respectively. This is not requested by the ELF standard, but GNU ld and
 // gold provide the feature, and used by many programs.
 template <class ELFT>
 void Writer<ELFT>::addStartStopSymbols(OutputSectionBase<ELFT> *Sec) {
   StringRef S = Sec->getName();
   if (!isValidCIdentifier(S))
     return;
   StringSaver Saver(Alloc);
   StringRef Start = Saver.save("__start_" + S);
   StringRef Stop = Saver.save("__stop_" + S);
   if (SymbolBody *B = Symtab.find(Start))
     if (B->isUndefined())
       Symtab.addSynthetic(Start, *Sec, 0);
   if (SymbolBody *B = Symtab.find(Stop))
     if (B->isUndefined())
       Symtab.addSynthetic(Stop, *Sec, Sec->getSize());
 }
 
 template <class ELFT> static bool needsPtLoad(OutputSectionBase<ELFT> *Sec) {
   if (!(Sec->getFlags() & SHF_ALLOC))
     return false;
 
   // Don't allocate VA space for TLS NOBITS sections. The PT_TLS PHDR is
   // responsible for allocating space for them, not the PT_LOAD that
   // contains the TLS initialization image.
   if (Sec->getFlags() & SHF_TLS && Sec->getType() == SHT_NOBITS)
     return false;
   return true;
 }
 
 static uint32_t toPhdrFlags(uint64_t Flags) {
   uint32_t Ret = PF_R;
   if (Flags & SHF_WRITE)
     Ret |= PF_W;
   if (Flags & SHF_EXECINSTR)
     Ret |= PF_X;
   return Ret;
 }
 
 /// For AMDGPU we need to use custom segment kinds in order to specify which
 /// address space data should be loaded into.
 template <class ELFT>
 static uint32_t getAmdgpuPhdr(OutputSectionBase<ELFT> *Sec) {
   uint32_t Flags = Sec->getFlags();
   if (Flags & SHF_AMDGPU_HSA_CODE)
     return PT_AMDGPU_HSA_LOAD_CODE_AGENT;
   if ((Flags & SHF_AMDGPU_HSA_GLOBAL) && !(Flags & SHF_AMDGPU_HSA_AGENT))
     return PT_AMDGPU_HSA_LOAD_GLOBAL_PROGRAM;
   return PT_LOAD;
 }
 
 // Decide which program headers to create and which sections to include in each
 // one.
 template <class ELFT> void Writer<ELFT>::createPhdrs() {
   auto AddHdr = [this](unsigned Type, unsigned Flags) {
     return &*Phdrs.emplace(Phdrs.end(), Type, Flags);
   };
 
   auto AddSec = [](Phdr &Hdr, OutputSectionBase<ELFT> *Sec) {
     Hdr.Last = Sec;
     if (!Hdr.First)
       Hdr.First = Sec;
     Hdr.H.p_align = std::max<uintX_t>(Hdr.H.p_align, Sec->getAlign());
   };
 
   // The first phdr entry is PT_PHDR which describes the program header itself.
   Phdr &Hdr = *AddHdr(PT_PHDR, PF_R);
   AddSec(Hdr, Out<ELFT>::ProgramHeaders);
 
   // PT_INTERP must be the second entry if exists.
   if (needsInterpSection()) {
     Phdr &Hdr = *AddHdr(PT_INTERP, toPhdrFlags(Out<ELFT>::Interp->getFlags()));
     AddSec(Hdr, Out<ELFT>::Interp);
   }
 
   // Add the first PT_LOAD segment for regular output sections.
   uintX_t Flags = PF_R;
   Phdr *Load = AddHdr(PT_LOAD, Flags);
   AddSec(*Load, Out<ELFT>::ElfHeader);
 
   Phdr TlsHdr(PT_TLS, PF_R);
   Phdr RelRo(PT_GNU_RELRO, PF_R);
   for (OutputSectionBase<ELFT> *Sec : OutputSections) {
     if (!(Sec->getFlags() & SHF_ALLOC))
       break;
 
     // If we meet TLS section then we create TLS header
     // and put all TLS sections inside for futher use when
     // assign addresses.
     if (Sec->getFlags() & SHF_TLS)
       AddSec(TlsHdr, Sec);
 
     if (!needsPtLoad<ELFT>(Sec))
       continue;
 
     // If flags changed then we want new load segment.
     uintX_t NewFlags = toPhdrFlags(Sec->getFlags());
     if (Flags != NewFlags) {
       uint32_t LoadType = (Config->EMachine == EM_AMDGPU) ? getAmdgpuPhdr(Sec)
                                                           : (uint32_t)PT_LOAD;
       Load = AddHdr(LoadType, NewFlags);
       Flags = NewFlags;
     }
 
     AddSec(*Load, Sec);
 
     if (isRelroSection(Sec))
       AddSec(RelRo, Sec);
   }
 
   // Add the TLS segment unless it's empty.
   if (TlsHdr.First)
     Phdrs.push_back(std::move(TlsHdr));
 
   // Add an entry for .dynamic.
   if (isOutputDynamic()) {
     Phdr &H = *AddHdr(PT_DYNAMIC, toPhdrFlags(Out<ELFT>::Dynamic->getFlags()));
     AddSec(H, Out<ELFT>::Dynamic);
   }
 
   // PT_GNU_RELRO includes all sections that should be marked as
   // read-only by dynamic linker after proccessing relocations.
   if (RelRo.First)
     Phdrs.push_back(std::move(RelRo));
 
   // PT_GNU_EH_FRAME is a special section pointing on .eh_frame_hdr.
   if (Out<ELFT>::EhFrameHdr->Live) {
     Phdr &Hdr = *AddHdr(PT_GNU_EH_FRAME,
                         toPhdrFlags(Out<ELFT>::EhFrameHdr->getFlags()));
     AddSec(Hdr, Out<ELFT>::EhFrameHdr);
   }
 
   // PT_GNU_STACK is a special section to tell the loader to make the
   // pages for the stack non-executable.
   if (!Config->ZExecStack)
     AddHdr(PT_GNU_STACK, PF_R | PF_W);
 }
 
+// Used for relocatable output (-r). In this case we create only ELF file
+// header, do not create program headers. Also assign of section addresses
+// is very straightforward: we just put all sections sequentually to the file.
+template <class ELFT> void Writer<ELFT>::assignAddressesRelocatable() {
+  Out<ELFT>::ElfHeader->setSize(sizeof(Elf_Ehdr));
+  uintX_t FileOff = 0;
+  for (OutputSectionBase<ELFT> *Sec : OutputSections) {
+    FileOff = alignTo(FileOff, Sec->getAlign());
+    Sec->setFileOffset(FileOff);
+    FileOff += Sec->getSize();
+  }
+  SectionHeaderOff = alignTo(FileOff, sizeof(uintX_t));
+  FileSize = SectionHeaderOff + getNumSections() * sizeof(Elf_Shdr);
+}
+
 // Visits all headers in PhdrTable and assigns the adresses to
 // the output sections. Also creates common and special headers.
 template <class ELFT> void Writer<ELFT>::assignAddresses() {
   Out<ELFT>::ElfHeader->setSize(sizeof(Elf_Ehdr));
   size_t PhdrSize = sizeof(Elf_Phdr) * Phdrs.size();
   Out<ELFT>::ProgramHeaders->setSize(PhdrSize);
 
   // The first section of each PT_LOAD and the first section after PT_GNU_RELRO
   // have to be page aligned so that the dynamic linker can set the permissions.
   SmallPtrSet<OutputSectionBase<ELFT> *, 4> PageAlign;
   for (const Phdr &P : Phdrs) {
     if (P.H.p_type == PT_GNU_RELRO) {
       // Find the first section after PT_GNU_RELRO. If it is in a PT_LOAD we
       // have to align it to a page.
       auto I = std::find(OutputSections.begin(), OutputSections.end(), P.Last);
       ++I;
       if (I != OutputSections.end() && needsPtLoad(*I))
         PageAlign.insert(*I);
     }
 
     if (P.H.p_type == PT_LOAD)
       PageAlign.insert(P.First);
   }
 
   uintX_t ThreadBssOffset = 0;
   uintX_t VA = Target->getVAStart();
   uintX_t FileOff = 0;
 
   for (OutputSectionBase<ELFT> *Sec : OutputSections) {
     uintX_t Align = Sec->getAlign();
     if (PageAlign.count(Sec))
       Align = std::max<uintX_t>(Align, Target->PageSize);
 
     if (Sec->getType() != SHT_NOBITS)
       FileOff = alignTo(FileOff, Align);
     Sec->setFileOffset(FileOff);
     if (Sec->getType() != SHT_NOBITS)
       FileOff += Sec->getSize();
 
     // We only assign VAs to allocated sections.
     if (needsPtLoad<ELFT>(Sec)) {
       VA = alignTo(VA, Align);
       Sec->setVA(VA);
       VA += Sec->getSize();
     } else if (Sec->getFlags() & SHF_TLS && Sec->getType() == SHT_NOBITS) {
       uintX_t TVA = VA + ThreadBssOffset;
       TVA = alignTo(TVA, Align);
       Sec->setVA(TVA);
       ThreadBssOffset = TVA - VA + Sec->getSize();
     }
   }
 
   // Add space for section headers.
   SectionHeaderOff = alignTo(FileOff, sizeof(uintX_t));
   FileSize = SectionHeaderOff + getNumSections() * sizeof(Elf_Shdr);
 
   // Update "_end" and "end" symbols so that they
   // point to the end of the data segment.
   ElfSym<ELFT>::End.st_value = VA;
 
   for (Phdr &PHdr : Phdrs) {
     Elf_Phdr &H = PHdr.H;
     if (PHdr.First) {
       OutputSectionBase<ELFT> *Last = PHdr.Last;
       H.p_filesz = Last->getFileOff() - PHdr.First->getFileOff();
       if (Last->getType() != SHT_NOBITS)
         H.p_filesz += Last->getSize();
       H.p_memsz = Last->getVA() + Last->getSize() - PHdr.First->getVA();
       H.p_offset = PHdr.First->getFileOff();
       H.p_vaddr = PHdr.First->getVA();
     }
     if (PHdr.H.p_type == PT_LOAD)
       H.p_align = Target->PageSize;
     else if (PHdr.H.p_type == PT_GNU_RELRO)
       H.p_align = 1;
     H.p_paddr = H.p_vaddr;
 
     // 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 (PHdr.H.p_type == PT_TLS) {
       Out<ELFT>::TlsPhdr = &H;
       H.p_memsz = alignTo(H.p_memsz, H.p_align);
     }
   }
 }
 
 static uint32_t getELFFlags() {
   if (Config->EMachine != EM_MIPS)
     return 0;
   // FIXME: In fact ELF flags depends on ELF flags of input object files
   // and selected emulation. For now just use hard coded values.
   uint32_t V = EF_MIPS_ABI_O32 | EF_MIPS_CPIC | EF_MIPS_ARCH_32R2;
   if (Config->Shared)
     V |= EF_MIPS_PIC;
   return V;
 }
 
 template <class ELFT>
 static typename ELFFile<ELFT>::uintX_t getEntryAddr() {
   if (Config->EntrySym) {
     if (SymbolBody *B = Config->EntrySym->repl())
       return B->getVA<ELFT>();
     return 0;
   }
   if (Config->EntryAddr != uint64_t(-1))
     return Config->EntryAddr;
   return 0;
 }
 
 // This function is called after we have assigned address and size
 // to each section. This function fixes some predefined absolute
 // symbol values that depend on section address and size.
 template <class ELFT> void Writer<ELFT>::fixAbsoluteSymbols() {
   // Update __rel[a]_iplt_{start,end} symbols so that they point
   // to beginning or ending of .rela.plt section, respectively.
   if (Out<ELFT>::RelaPlt) {
     uintX_t Start = Out<ELFT>::RelaPlt->getVA();
     ElfSym<ELFT>::RelaIpltStart.st_value = Start;
     ElfSym<ELFT>::RelaIpltEnd.st_value = Start + Out<ELFT>::RelaPlt->getSize();
   }
 
   // Update MIPS _gp absolute symbol so that it points to the static data.
   if (Config->EMachine == EM_MIPS)
     ElfSym<ELFT>::MipsGp.st_value = getMipsGpAddr<ELFT>();
 }
 
 template <class ELFT> void Writer<ELFT>::writeHeader() {
   uint8_t *Buf = Buffer->getBufferStart();
   memcpy(Buf, "\177ELF", 4);
 
   // Write the ELF header.
   auto *EHdr = reinterpret_cast<Elf_Ehdr *>(Buf);
   EHdr->e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32;
   EHdr->e_ident[EI_DATA] = ELFT::TargetEndianness == llvm::support::little
                                ? ELFDATA2LSB
                                : ELFDATA2MSB;
   EHdr->e_ident[EI_VERSION] = EV_CURRENT;
 
   auto &FirstObj = cast<ELFFileBase<ELFT>>(*Config->FirstElf);
   EHdr->e_ident[EI_OSABI] = FirstObj.getOSABI();
 
-  EHdr->e_type = Config->Shared ? ET_DYN : ET_EXEC;
+  if (Config->Shared)
+    EHdr->e_type = ET_DYN;
+  else if (Config->Relocatable)
+    EHdr->e_type = ET_REL;
+  else
+    EHdr->e_type = ET_EXEC;
+
   EHdr->e_machine = FirstObj.getEMachine();
   EHdr->e_version = EV_CURRENT;
   EHdr->e_entry = getEntryAddr<ELFT>();
-  EHdr->e_phoff = sizeof(Elf_Ehdr);
   EHdr->e_shoff = SectionHeaderOff;
   EHdr->e_flags = getELFFlags();
   EHdr->e_ehsize = sizeof(Elf_Ehdr);
-  EHdr->e_phentsize = sizeof(Elf_Phdr);
   EHdr->e_phnum = Phdrs.size();
   EHdr->e_shentsize = sizeof(Elf_Shdr);
   EHdr->e_shnum = getNumSections();
   EHdr->e_shstrndx = Out<ELFT>::ShStrTab->SectionIndex;
 
+  if (!Config->Relocatable) {
+    EHdr->e_phoff = sizeof(Elf_Ehdr);
+    EHdr->e_phentsize = sizeof(Elf_Phdr);
+  }
+
   // Write the program header table.
   auto *HBuf = reinterpret_cast<Elf_Phdr *>(Buf + EHdr->e_phoff);
   for (Phdr &P : Phdrs)
     *HBuf++ = P.H;
 
   // Write the section header table. Note that the first table entry is null.
   auto SHdrs = reinterpret_cast<Elf_Shdr *>(Buf + EHdr->e_shoff);
   for (OutputSectionBase<ELFT> *Sec : getSections())
     Sec->writeHeaderTo(++SHdrs);
 }
 
 template <class ELFT> bool Writer<ELFT>::openFile() {
   ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
       FileOutputBuffer::create(Config->OutputFile, FileSize,
                                FileOutputBuffer::F_executable);
   if (error(BufferOrErr, "failed to open " + Config->OutputFile))
     return false;
   Buffer = std::move(*BufferOrErr);
   return true;
 }
 
 // Write section contents to a mmap'ed file.
 template <class ELFT> void Writer<ELFT>::writeSections() {
   uint8_t *Buf = Buffer->getBufferStart();
 
   // PPC64 needs to process relocations in the .opd section before processing
   // relocations in code-containing sections.
   if (OutputSectionBase<ELFT> *Sec = Out<ELFT>::Opd) {
     Out<ELFT>::OpdBuf = Buf + Sec->getFileOff();
     Sec->writeTo(Buf + Sec->getFileOff());
   }
 
   for (OutputSectionBase<ELFT> *Sec : OutputSections)
     if (Sec != Out<ELFT>::Opd)
       Sec->writeTo(Buf + Sec->getFileOff());
 }
 
 template void elf2::writeResult<ELF32LE>(SymbolTable<ELF32LE> *Symtab);
 template void elf2::writeResult<ELF32BE>(SymbolTable<ELF32BE> *Symtab);
 template void elf2::writeResult<ELF64LE>(SymbolTable<ELF64LE> *Symtab);
 template void elf2::writeResult<ELF64BE>(SymbolTable<ELF64BE> *Symtab);
diff --git a/test/ELF/Inputs/relocatable.s b/test/ELF/Inputs/relocatable.s
new file mode 100644
index 0000000..de34a6b
--- /dev/null
+++ b/test/ELF/Inputs/relocatable.s
@@ -0,0 +1,22 @@
+.text
+.type xx, at object
+.bss
+.globl xx
+.align 4
+xx:
+.long 0
+.size xx, 4
+.type yy, at object
+.globl yy
+.align 4
+yy:
+.long 0
+.size yy, 4
+
+.text
+.globl foo
+.align 16, 0x90
+.type foo, at function
+foo:
+movl $1, xx
+movl $2, yy
diff --git a/test/ELF/Inputs/relocatable2.s b/test/ELF/Inputs/relocatable2.s
new file mode 100644
index 0000000..93e23bc
--- /dev/null
+++ b/test/ELF/Inputs/relocatable2.s
@@ -0,0 +1,22 @@
+.text
+.type xxx, at object
+.bss
+.globl xxx
+.align 4
+xxx:
+.long 0
+.size xxx, 4
+.type yyy, at object
+.globl yyy
+.align 4
+yyy:
+.long 0
+.size yyy, 4
+
+.text
+.globl bar
+.align 16, 0x90
+.type bar, at function
+bar:
+movl $8, xxx
+movl $9, yyy
diff --git a/test/ELF/relocatable.s b/test/ELF/relocatable.s
index 9fb171d..50ac3a8 100644
--- a/test/ELF/relocatable.s
+++ b/test/ELF/relocatable.s
@@ -1,9 +1,129 @@
 # 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/relocatable.s -o %t2.o
+# 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 -s -d %t | FileCheck -check-prefix=CHECKTEXT %s
 
-# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
-# RUN: not ld.lld -r %t -o %t2 2>&1 | FileCheck %s
+## Test --relocatable alias
+# RUN: ld.lld --relocatable %t1.o %t2.o %t3.o -o %t
+# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s
+# RUN: llvm-objdump -s -d %t | FileCheck -check-prefix=CHECKTEXT %s
 
-# CHECK: -r option is not supported. Use 'ar' command instead.
+## Verify that we can use our relocation output as input to produce executable
+# RUN: ld.lld -e main %t -o %texec
+# RUN: llvm-readobj -file-headers %texec | FileCheck -check-prefix=CHECKEXE %s
 
-.globl _start;
-_start:
+## Attempt to link DSO with -r
+# RUN: ld.lld -shared %t1.o -o %t.so
+# RUN: not ld.lld -r %t.so %t2.o -o %tfail 2>&1 | FileCheck -check-prefix=ERR %s
+# ERR: Attempted static link of dynamic object
+
+## Attempt to use -r and shared together
+# RUN: not ld.lld -r -shared %t2.o -o %tfail 2>&1 | FileCheck -check-prefix=ERR2 %s
+# ERR2: -r and -shared may not be used together
+
+# CHECK:       ElfHeader {
+# CHECK-NEXT:  Ident {
+# CHECK-NEXT:    Magic: (7F 45 4C 46)
+# CHECK-NEXT:    Class: 64-bit
+# CHECK-NEXT:    DataEncoding: LittleEndian
+# CHECK-NEXT:    FileVersion: 1
+# CHECK-NEXT:    OS/ABI: SystemV
+# CHECK-NEXT:    ABIVersion: 0
+# CHECK-NEXT:    Unused: (00 00 00 00 00 00 00)
+# CHECK-NEXT:  }
+# CHECK-NEXT:  Type: Relocatable
+# CHECK-NEXT:  Machine: EM_X86_64
+# CHECK-NEXT:  Version: 1
+# CHECK-NEXT:  Entry: 0x0
+# CHECK-NEXT:  ProgramHeaderOffset: 0x0
+# CHECK-NEXT:  SectionHeaderOffset: 0x2D8
+# CHECK-NEXT:  Flags [
+# CHECK-NEXT:  ]
+# CHECK-NEXT:  HeaderSize: 64
+# CHECK-NEXT:  ProgramHeaderEntrySize: 0
+# CHECK-NEXT:  ProgramHeaderCount: 0
+# CHECK-NEXT:  SectionHeaderEntrySize: 64
+# CHECK-NEXT:  SectionHeaderCount: 7
+# CHECK-NEXT:  StringTableSectionIndex: 5
+# CHECK-NEXT:  }
+
+# CHECK:       Relocations [
+# CHECK-NEXT:  Section (3) .rela.text {
+# CHECK-NEXT:    0x3 R_X86_64_32S x 0x0
+# CHECK-NEXT:    0xE R_X86_64_32S y 0x0
+# CHECK-NEXT:    0x23 R_X86_64_32S xx 0x0
+# CHECK-NEXT:    0x2E R_X86_64_32S yy 0x0
+# CHECK-NEXT:    0x43 R_X86_64_32S xxx 0x0
+# CHECK-NEXT:    0x4E R_X86_64_32S yyy 0x0
+# CHECK-NEXT:  }
+
+# 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
+# CHECKTEXT-NEXT: b: c7 04 25 00 00 00 00 07 00 00 00 movl $7, 0
+# CHECKTEXT:      foo:
+# CHECKTEXT-NEXT: 20: c7 04 25 00 00 00 00 01 00 00 00 movl $1, 0
+# CHECKTEXT-NEXT: 2b: c7 04 25 00 00 00 00 02 00 00 00 movl $2, 0
+# CHECKTEXT:      bar:
+# CHECKTEXT-NEXT: 40: c7 04 25 00 00 00 00 08 00 00 00 movl $8, 0
+# CHECKTEXT-NEXT: 4b: c7 04 25 00 00 00 00 09 00 00 00 movl $9, 0
+
+# CHECKEXE:       Format: ELF64-x86-64
+# CHECKEXE-NEXT:  Arch: x86_64
+# CHECKEXE-NEXT:  AddressSize: 64bit
+# CHECKEXE-NEXT:  LoadName:
+# CHECKEXE-NEXT:  ElfHeader {
+# CHECKEXE-NEXT:    Ident {
+# CHECKEXE-NEXT:      Magic: (7F 45 4C 46)
+# CHECKEXE-NEXT:      Class: 64-bit
+# CHECKEXE-NEXT:      DataEncoding: LittleEndian
+# CHECKEXE-NEXT:      FileVersion: 1
+# CHECKEXE-NEXT:      OS/ABI: SystemV (0x0)
+# CHECKEXE-NEXT:      ABIVersion: 0
+# CHECKEXE-NEXT:      Unused: (00 00 00 00 00 00 00)
+# CHECKEXE-NEXT:    }
+# CHECKEXE-NEXT:    Type: Executable
+# CHECKEXE-NEXT:    Machine: EM_X86_64
+# CHECKEXE-NEXT:    Version: 1
+# CHECKEXE-NEXT:    Entry: 0x11000
+# CHECKEXE-NEXT:    ProgramHeaderOffset: 0x40
+# CHECKEXE-NEXT:    SectionHeaderOffset: 0x11E8
+# CHECKEXE-NEXT:    Flags [
+# CHECKEXE-NEXT:    ]
+# CHECKEXE-NEXT:    HeaderSize: 64
+# CHECKEXE-NEXT:    ProgramHeaderEntrySize: 56
+# CHECKEXE-NEXT:    ProgramHeaderCount: 5
+# CHECKEXE-NEXT:    SectionHeaderEntrySize: 64
+# CHECKEXE-NEXT:    SectionHeaderCount: 6
+# CHECKEXE-NEXT:    StringTableSectionIndex: 4
+# CHECKEXE-NEXT:  }
+
+.text
+.type x, at object
+.bss
+.globl x
+.align 4
+x:
+.long 0
+.size x, 4
+.type y, at object
+.globl y
+.align 4
+y:
+.long 0
+.size y, 4
+
+.text
+.globl main
+.align 16, 0x90
+.type main, at function
+main:
+movl $5, x
+movl $7, y
+
+blah:
+goo:
+abs = 42
diff --git a/test/ELF/strip-all.s b/test/ELF/strip-all.s
index 6d18431..91b1306 100644
--- a/test/ELF/strip-all.s
+++ b/test/ELF/strip-all.s
@@ -1,25 +1,29 @@
 # REQUIRES: x86
 
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
 # RUN: ld.lld %t.o -o %t1
 #RUN: llvm-objdump -section-headers %t1 | FileCheck %s -check-prefix BEFORE
 #BEFORE:       .symtab
 #BEFORE-NEXT:  .shstrtab
 #BEFORE-NEXT:  .strtab
 
 #RUN: ld.lld %t.o --strip-all -o %t1
 #RUN: llvm-objdump -section-headers %t1 | FileCheck %s -check-prefix AFTER
 #AFTER-NOT: .symtab
 #AFTER:     .shstrtab
 #AFTER-NOT: .strtab
 
+# Ignore --strip-all if -r is specified
+#RUN: ld.lld %t.o --strip-all -r -o %t1
+#RUN: llvm-objdump -section-headers %t1 | FileCheck %s -check-prefix BEFORE
+
 # Test alias -s
 #RUN: ld.lld %t.o -s -o %t1
 #RUN: llvm-objdump -section-headers %t1 | FileCheck %s -check-prefix AFTER
 
 # exits with return code 42 on linux
 .globl _start;
 _start:
   mov $60, %rax
   mov $42, %rdi
   syscall


More information about the llvm-commits mailing list