//===- Driver.cpp ---------------------------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// The driver drives the entire linking process. It is responsible for
// parsing command line options and doing whatever it is instructed to do.
//
// One notable thing in the LLD's driver when compared to other linkers is
// that the LLD's driver is agnostic on the host operating system.
// Other linkers usually have implicit default values (such as a dynamic
// linker path or library paths) for each host OS.
//
// I don't think implicit default values are useful because they are
// usually explicitly specified by the compiler driver. They can even
// be harmful when you are doing cross-linking. Therefore, in LLD, we
// simply trust the compiler driver to pass all required options and
// don't try to make effort on our side.
//
//===----------------------------------------------------------------------===//

#include "Driver.h"
#include "Config.h"
#include "Filesystem.h"
#include "ICF.h"
#include "InputFiles.h"
#include "InputSection.h"
#include "LinkerScript.h"
#include "MarkLive.h"
#include "OutputSections.h"
#include "ScriptParser.h"
#include "SymbolTable.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
#include "Writer.h"
#include "lld/Common/Args.h"
#include "lld/Common/Driver.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Memory.h"
#include "lld/Common/Strings.h"
#include "lld/Common/TargetOptionsCommandFlags.h"
#include "lld/Common/Threads.h"
#include "lld/Common/Version.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/TarWriter.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdlib>
#include <utility>

using namespace llvm;
using namespace llvm::ELF;
using namespace llvm::object;
using namespace llvm::sys;
using namespace llvm::support;

using namespace lld;
using namespace lld::elf;

Configuration *elf::Config;
LinkerDriver *elf::Driver;

static void setConfigs(opt::InputArgList &Args);

bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,
               raw_ostream &Error) {
  errorHandler().LogName = args::getFilenameWithoutExe(Args[0]);
  errorHandler().ErrorLimitExceededMsg =
      "too many errors emitted, stopping now (use "
      "-error-limit=0 to see all errors)";
  errorHandler().ErrorOS = &Error;
  errorHandler().ExitEarly = CanExitEarly;
  errorHandler().ColorDiagnostics = Error.has_colors();

  InputSections.clear();
  OutputSections.clear();
  BinaryFiles.clear();
  BitcodeFiles.clear();
  ObjectFiles.clear();
  SharedFiles.clear();

  Config = make<Configuration>();
  Driver = make<LinkerDriver>();
  Script = make<LinkerScript>();
  Symtab = make<SymbolTable>();

  Tar = nullptr;
  memset(&In, 0, sizeof(In));

  Config->ProgName = Args[0];

  Driver->main(Args);

  // Exit immediately if we don't need to return to the caller.
  // This saves time because the overhead of calling destructors
  // for all globally-allocated objects is not negligible.
  if (CanExitEarly)
    exitLld(errorCount() ? 1 : 0);

  freeArena();
  return !errorCount();
}

// Parses a linker -m option.
static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef Emul) {
  uint8_t OSABI = 0;
  StringRef S = Emul;
  if (S.endswith("_fbsd")) {
    S = S.drop_back(5);
    OSABI = ELFOSABI_FREEBSD;
  }

  std::pair<ELFKind, uint16_t> Ret =
      StringSwitch<std::pair<ELFKind, uint16_t>>(S)
          .Cases("aarch64elf", "aarch64linux", "aarch64_elf64_le_vec",
                 {ELF64LEKind, EM_AARCH64})
          .Cases("armelf", "armelf_linux_eabi", {ELF32LEKind, EM_ARM})
          .Case("elf32_x86_64", {ELF32LEKind, EM_X86_64})
          .Cases("elf32btsmip", "elf32btsmipn32", {ELF32BEKind, EM_MIPS})
          .Cases("elf32ltsmip", "elf32ltsmipn32", {ELF32LEKind, EM_MIPS})
          .Case("elf32lriscv", {ELF32LEKind, EM_RISCV})
          .Case("elf32ppc", {ELF32BEKind, EM_PPC})
          .Case("elf64btsmip", {ELF64BEKind, EM_MIPS})
          .Case("elf64ltsmip", {ELF64LEKind, EM_MIPS})
          .Case("elf64lriscv", {ELF64LEKind, EM_RISCV})
          .Case("elf64ppc", {ELF64BEKind, EM_PPC64})
          .Case("elf64lppc", {ELF64LEKind, EM_PPC64})
          .Cases("elf_amd64", "elf_x86_64", {ELF64LEKind, EM_X86_64})
          .Case("elf_i386", {ELF32LEKind, EM_386})
          .Case("elf_iamcu", {ELF32LEKind, EM_IAMCU})
          .Default({ELFNoneKind, EM_NONE});

  if (Ret.first == ELFNoneKind)
    error("unknown emulation: " + Emul);
  return std::make_tuple(Ret.first, Ret.second, OSABI);
}

// Returns slices of MB by parsing MB as an archive file.
// Each slice consists of a member file in the archive.
std::vector<std::pair<MemoryBufferRef, uint64_t>> static getArchiveMembers(
    MemoryBufferRef MB) {
  std::unique_ptr<Archive> File =
      CHECK(Archive::create(MB),
            MB.getBufferIdentifier() + ": failed to parse archive");

  std::vector<std::pair<MemoryBufferRef, uint64_t>> V;
  Error Err = Error::success();
  bool AddToTar = File->isThin() && Tar;
  for (const ErrorOr<Archive::Child> &COrErr : File->children(Err)) {
    Archive::Child C =
        CHECK(COrErr, MB.getBufferIdentifier() +
                          ": could not get the child of the archive");
    MemoryBufferRef MBRef =
        CHECK(C.getMemoryBufferRef(),
              MB.getBufferIdentifier() +
                  ": could not get the buffer for a child of the archive");
    if (AddToTar)
      Tar->append(relativeToRoot(check(C.getFullName())), MBRef.getBuffer());
    V.push_back(std::make_pair(MBRef, C.getChildOffset()));
  }
  if (Err)
    fatal(MB.getBufferIdentifier() + ": Archive::children failed: " +
          toString(std::move(Err)));

  // Take ownership of memory buffers created for members of thin archives.
  for (std::unique_ptr<MemoryBuffer> &MB : File->takeThinBuffers())
    make<std::unique_ptr<MemoryBuffer>>(std::move(MB));

  return V;
}

// Opens a file and create a file object. Path has to be resolved already.
void LinkerDriver::addFile(StringRef Path, bool WithLOption) {
  using namespace sys::fs;

  Optional<MemoryBufferRef> Buffer = readFile(Path);
  if (!Buffer.hasValue())
    return;
  MemoryBufferRef MBRef = *Buffer;

  if (Config->FormatBinary) {
    Files.push_back(make<BinaryFile>(MBRef));
    return;
  }

  switch (identify_magic(MBRef.getBuffer())) {
  case file_magic::unknown:
    readLinkerScript(MBRef);
    return;
  case file_magic::archive: {
    // Handle -whole-archive.
    if (InWholeArchive) {
      for (const auto &P : getArchiveMembers(MBRef))
        Files.push_back(createObjectFile(P.first, Path, P.second));
      return;
    }

    std::unique_ptr<Archive> File =
        CHECK(Archive::create(MBRef), Path + ": failed to parse archive");

    // If an archive file has no symbol table, it is likely that a user
    // is attempting LTO and using a default ar command that doesn't
    // understand the LLVM bitcode file. It is a pretty common error, so
    // we'll handle it as if it had a symbol table.
    if (!File->isEmpty() && !File->hasSymbolTable()) {
      for (const auto &P : getArchiveMembers(MBRef))
        Files.push_back(make<LazyObjFile>(P.first, Path, P.second));
      return;
    }

    // Handle the regular case.
    Files.push_back(make<ArchiveFile>(std::move(File)));
    return;
  }
  case file_magic::elf_shared_object:
    if (Config->Relocatable) {
      error("attempted static link of dynamic object " + Path);
      return;
    }

    // DSOs usually have DT_SONAME tags in their ELF headers, and the
    // sonames are used to identify DSOs. But if they are missing,
    // they are identified by filenames. We don't know whether the new
    // file has a DT_SONAME or not because we haven't parsed it yet.
    // Here, we set the default soname for the file because we might
    // need it later.
    //
    // If a file was specified by -lfoo, the directory part is not
    // significant, as a user did not specify it. This behavior is
    // compatible with GNU.
    Files.push_back(
        createSharedFile(MBRef, WithLOption ? path::filename(Path) : Path));
    return;
  case file_magic::bitcode:
  case file_magic::elf_relocatable:
    if (InLib)
      Files.push_back(make<LazyObjFile>(MBRef, "", 0));
    else
      Files.push_back(createObjectFile(MBRef));
    break;
  default:
    error(Path + ": unknown file type");
  }
}

// Add a given library by searching it from input search paths.
void LinkerDriver::addLibrary(StringRef Name) {
  if (Optional<std::string> Path = searchLibrary(Name))
    addFile(*Path, /*WithLOption=*/true);
  else
    error("unable to find library -l" + Name);
}

// This function is called on startup. We need this for LTO since
// LTO calls LLVM functions to compile bitcode files to native code.
// Technically this can be delayed until we read bitcode files, but
// we don't bother to do lazily because the initialization is fast.
static void initLLVM() {
  InitializeAllTargets();
  InitializeAllTargetMCs();
  InitializeAllAsmPrinters();
  InitializeAllAsmParsers();
}

// Some command line options or some combinations of them are not allowed.
// This function checks for such errors.
static void checkOptions() {
  // 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->FixCortexA53Errata843419 && Config->EMachine != EM_AARCH64)
    error("--fix-cortex-a53-843419 is only supported on AArch64 targets");

  if (Config->TocOptimize && Config->EMachine != EM_PPC64)
    error("--toc-optimize is only supported on the PowerPC64 target");

  if (Config->Pie && Config->Shared)
    error("-shared and -pie may not be used together");

  if (!Config->Shared && !Config->FilterList.empty())
    error("-F may not be used without -shared");

  if (!Config->Shared && !Config->AuxiliaryList.empty())
    error("-f may not be used without -shared");

  if (!Config->Relocatable && !Config->DefineCommon)
    error("-no-define-common not supported in non relocatable output");

  if (Config->Relocatable) {
    if (Config->Shared)
      error("-r and -shared may not be used together");
    if (Config->GcSections)
      error("-r and --gc-sections may not be used together");
    if (Config->GdbIndex)
      error("-r and --gdb-index may not be used together");
    if (Config->ICF != ICFLevel::None)
      error("-r and --icf may not be used together");
    if (Config->Pie)
      error("-r and -pie may not be used together");
  }

  if (Config->ExecuteOnly) {
    if (Config->EMachine != EM_AARCH64)
      error("-execute-only is only supported on AArch64 targets");

    if (Config->SingleRoRx && !Script->HasSectionsCommand)
      error("-execute-only and -no-rosegment cannot be used together");
  }
}

static const char *getReproduceOption(opt::InputArgList &Args) {
  if (auto *Arg = Args.getLastArg(OPT_reproduce))
    return Arg->getValue();
  return getenv("LLD_REPRODUCE");
}

static bool hasZOption(opt::InputArgList &Args, StringRef Key) {
  for (auto *Arg : Args.filtered(OPT_z))
    if (Key == Arg->getValue())
      return true;
  return false;
}

static bool getZFlag(opt::InputArgList &Args, StringRef K1, StringRef K2,
                     bool Default) {
  for (auto *Arg : Args.filtered_reverse(OPT_z)) {
    if (K1 == Arg->getValue())
      return true;
    if (K2 == Arg->getValue())
      return false;
  }
  return Default;
}

static bool isKnownZFlag(StringRef S) {
  return S == "combreloc" || S == "copyreloc" || S == "defs" ||
         S == "execstack" || S == "global" || S == "hazardplt" ||
         S == "initfirst" || S == "interpose" ||
         S == "keep-text-section-prefix" || S == "lazy" || S == "muldefs" ||
         S == "nocombreloc" || S == "nocopyreloc" || S == "nodefaultlib" ||
         S == "nodelete" || S == "nodlopen" || S == "noexecstack" ||
         S == "nokeep-text-section-prefix" || S == "norelro" || S == "notext" ||
         S == "now" || S == "origin" || S == "relro" || S == "retpolineplt" ||
         S == "rodynamic" || S == "text" || S == "wxneeded" ||
         S.startswith("max-page-size=") || S.startswith("stack-size=");
}

// Report an error for an unknown -z option.
static void checkZOptions(opt::InputArgList &Args) {
  for (auto *Arg : Args.filtered(OPT_z))
    if (!isKnownZFlag(Arg->getValue()))
      error("unknown -z value: " + StringRef(Arg->getValue()));
}

void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
  ELFOptTable Parser;
  opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));

  // Interpret this flag early because error() depends on them.
  errorHandler().ErrorLimit = args::getInteger(Args, OPT_error_limit, 20);

  // Handle -help
  if (Args.hasArg(OPT_help)) {
    printHelp();
    return;
  }

  // Handle -v or -version.
  //
  // A note about "compatible with GNU linkers" message: this is a hack for
  // scripts generated by GNU Libtool 2.4.6 (released in February 2014 and
  // still the newest version in March 2017) or earlier to recognize LLD as
  // a GNU compatible linker. As long as an output for the -v option
  // contains "GNU" or "with BFD", they recognize us as GNU-compatible.
  //
  // This is somewhat ugly hack, but in reality, we had no choice other
  // than doing this. Considering the very long release cycle of Libtool,
  // it is not easy to improve it to recognize LLD as a GNU compatible
  // linker in a timely manner. Even if we can make it, there are still a
  // lot of "configure" scripts out there that are generated by old version
  // of Libtool. We cannot convince every software developer to migrate to
  // the latest version and re-generate scripts. So we have this hack.
  if (Args.hasArg(OPT_v) || Args.hasArg(OPT_version))
    message(getLLDVersion() + " (compatible with GNU linkers)");

  if (const char *Path = getReproduceOption(Args)) {
    // Note that --reproduce is a debug option so you can ignore it
    // if you are trying to understand the whole picture of the code.
    Expected<std::unique_ptr<TarWriter>> ErrOrWriter =
        TarWriter::create(Path, path::stem(Path));
    if (ErrOrWriter) {
      Tar = ErrOrWriter->get();
      Tar->append("response.txt", createResponseFile(Args));
      Tar->append("version.txt", getLLDVersion() + "\n");
      make<std::unique_ptr<TarWriter>>(std::move(*ErrOrWriter));
    } else {
      error(Twine("--reproduce: failed to open ") + Path + ": " +
            toString(ErrOrWriter.takeError()));
    }
  }

  readConfigs(Args);
  checkZOptions(Args);

  // The behavior of -v or --version is a bit strange, but this is
  // needed for compatibility with GNU linkers.
  if (Args.hasArg(OPT_v) && !Args.hasArg(OPT_INPUT))
    return;
  if (Args.hasArg(OPT_version))
    return;

  initLLVM();
  createFiles(Args);
  if (errorCount())
    return;

  inferMachineType();
  setConfigs(Args);
  checkOptions();
  if (errorCount())
    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:
    llvm_unreachable("unknown Config->EKind");
  }
}

static std::string getRpath(opt::InputArgList &Args) {
  std::vector<StringRef> V = args::getStrings(Args, OPT_rpath);
  return llvm::join(V.begin(), V.end(), ":");
}

// Determines what we should do if there are remaining unresolved
// symbols after the name resolution.
static UnresolvedPolicy getUnresolvedSymbolPolicy(opt::InputArgList &Args) {
  UnresolvedPolicy ErrorOrWarn = Args.hasFlag(OPT_error_unresolved_symbols,
                                              OPT_warn_unresolved_symbols, true)
                                     ? UnresolvedPolicy::ReportError
                                     : UnresolvedPolicy::Warn;

  // Process the last of -unresolved-symbols, -no-undefined or -z defs.
  for (auto *Arg : llvm::reverse(Args)) {
    switch (Arg->getOption().getID()) {
    case OPT_unresolved_symbols: {
      StringRef S = Arg->getValue();
      if (S == "ignore-all" || S == "ignore-in-object-files")
        return UnresolvedPolicy::Ignore;
      if (S == "ignore-in-shared-libs" || S == "report-all")
        return ErrorOrWarn;
      error("unknown --unresolved-symbols value: " + S);
      continue;
    }
    case OPT_no_undefined:
      return ErrorOrWarn;
    case OPT_z:
      if (StringRef(Arg->getValue()) == "defs")
        return ErrorOrWarn;
      continue;
    }
  }

  // -shared implies -unresolved-symbols=ignore-all because missing
  // symbols are likely to be resolved at runtime using other DSOs.
  if (Config->Shared)
    return UnresolvedPolicy::Ignore;
  return ErrorOrWarn;
}

static Target2Policy getTarget2(opt::InputArgList &Args) {
  StringRef S = Args.getLastArgValue(OPT_target2, "got-rel");
  if (S == "rel")
    return Target2Policy::Rel;
  if (S == "abs")
    return Target2Policy::Abs;
  if (S == "got-rel")
    return Target2Policy::GotRel;
  error("unknown --target2 option: " + S);
  return Target2Policy::GotRel;
}

static bool isOutputFormatBinary(opt::InputArgList &Args) {
  StringRef S = Args.getLastArgValue(OPT_oformat, "elf");
  if (S == "binary")
    return true;
  if (!S.startswith("elf"))
    error("unknown --oformat value: " + S);
  return false;
}

static DiscardPolicy getDiscard(opt::InputArgList &Args) {
  if (Args.hasArg(OPT_relocatable))
    return DiscardPolicy::None;

  auto *Arg =
      Args.getLastArg(OPT_discard_all, OPT_discard_locals, OPT_discard_none);
  if (!Arg)
    return DiscardPolicy::Default;
  if (Arg->getOption().getID() == OPT_discard_all)
    return DiscardPolicy::All;
  if (Arg->getOption().getID() == OPT_discard_locals)
    return DiscardPolicy::Locals;
  return DiscardPolicy::None;
}

static StringRef getDynamicLinker(opt::InputArgList &Args) {
  auto *Arg = Args.getLastArg(OPT_dynamic_linker, OPT_no_dynamic_linker);
  if (!Arg || Arg->getOption().getID() == OPT_no_dynamic_linker)
    return "";
  return Arg->getValue();
}

static ICFLevel getICF(opt::InputArgList &Args) {
  auto *Arg = Args.getLastArg(OPT_icf_none, OPT_icf_safe, OPT_icf_all);
  if (!Arg || Arg->getOption().getID() == OPT_icf_none)
    return ICFLevel::None;
  if (Arg->getOption().getID() == OPT_icf_safe)
    return ICFLevel::Safe;
  return ICFLevel::All;
}

static StripPolicy getStrip(opt::InputArgList &Args) {
  if (Args.hasArg(OPT_relocatable))
    return StripPolicy::None;

  auto *Arg = Args.getLastArg(OPT_strip_all, OPT_strip_debug);
  if (!Arg)
    return StripPolicy::None;
  if (Arg->getOption().getID() == OPT_strip_all)
    return StripPolicy::All;
  return StripPolicy::Debug;
}

static uint64_t parseSectionAddress(StringRef S, const opt::Arg &Arg) {
  uint64_t VA = 0;
  if (S.startswith("0x"))
    S = S.drop_front(2);
  if (!to_integer(S, VA, 16))
    error("invalid argument: " + toString(Arg));
  return VA;
}

static StringMap<uint64_t> getSectionStartMap(opt::InputArgList &Args) {
  StringMap<uint64_t> Ret;
  for (auto *Arg : Args.filtered(OPT_section_start)) {
    StringRef Name;
    StringRef Addr;
    std::tie(Name, Addr) = StringRef(Arg->getValue()).split('=');
    Ret[Name] = parseSectionAddress(Addr, *Arg);
  }

  if (auto *Arg = Args.getLastArg(OPT_Ttext))
    Ret[".text"] = parseSectionAddress(Arg->getValue(), *Arg);
  if (auto *Arg = Args.getLastArg(OPT_Tdata))
    Ret[".data"] = parseSectionAddress(Arg->getValue(), *Arg);
  if (auto *Arg = Args.getLastArg(OPT_Tbss))
    Ret[".bss"] = parseSectionAddress(Arg->getValue(), *Arg);
  return Ret;
}

static SortSectionPolicy getSortSection(opt::InputArgList &Args) {
  StringRef S = Args.getLastArgValue(OPT_sort_section);
  if (S == "alignment")
    return SortSectionPolicy::Alignment;
  if (S == "name")
    return SortSectionPolicy::Name;
  if (!S.empty())
    error("unknown --sort-section rule: " + S);
  return SortSectionPolicy::Default;
}

static OrphanHandlingPolicy getOrphanHandling(opt::InputArgList &Args) {
  StringRef S = Args.getLastArgValue(OPT_orphan_handling, "place");
  if (S == "warn")
    return OrphanHandlingPolicy::Warn;
  if (S == "error")
    return OrphanHandlingPolicy::Error;
  if (S != "place")
    error("unknown --orphan-handling mode: " + S);
  return OrphanHandlingPolicy::Place;
}

// Parse --build-id or --build-id=<style>. We handle "tree" as a
// synonym for "sha1" because all our hash functions including
// -build-id=sha1 are actually tree hashes for performance reasons.
static std::pair<BuildIdKind, std::vector<uint8_t>>
getBuildId(opt::InputArgList &Args) {
  auto *Arg = Args.getLastArg(OPT_build_id, OPT_build_id_eq);
  if (!Arg)
    return {BuildIdKind::None, {}};

  if (Arg->getOption().getID() == OPT_build_id)
    return {BuildIdKind::Fast, {}};

  StringRef S = Arg->getValue();
  if (S == "fast")
    return {BuildIdKind::Fast, {}};
  if (S == "md5")
    return {BuildIdKind::Md5, {}};
  if (S == "sha1" || S == "tree")
    return {BuildIdKind::Sha1, {}};
  if (S == "uuid")
    return {BuildIdKind::Uuid, {}};
  if (S.startswith("0x"))
    return {BuildIdKind::Hexstring, parseHex(S.substr(2))};

  if (S != "none")
    error("unknown --build-id style: " + S);
  return {BuildIdKind::None, {}};
}

static std::pair<bool, bool> getPackDynRelocs(opt::InputArgList &Args) {
  StringRef S = Args.getLastArgValue(OPT_pack_dyn_relocs, "none");
  if (S == "android")
    return {true, false};
  if (S == "relr")
    return {false, true};
  if (S == "android+relr")
    return {true, true};

  if (S != "none")
    error("unknown -pack-dyn-relocs format: " + S);
  return {false, false};
}

static void readCallGraph(MemoryBufferRef MB) {
  // Build a map from symbol name to section
  DenseMap<StringRef, Symbol *> Map;
  for (InputFile *File : ObjectFiles)
    for (Symbol *Sym : File->getSymbols())
      Map[Sym->getName()] = Sym;

  auto FindSection = [&](StringRef Name) -> InputSectionBase * {
    Symbol *Sym = Map.lookup(Name);
    if (!Sym) {
      if (Config->WarnSymbolOrdering)
        warn(MB.getBufferIdentifier() + ": no such symbol: " + Name);
      return nullptr;
    }
    maybeWarnUnorderableSymbol(Sym);

    if (Defined *DR = dyn_cast_or_null<Defined>(Sym))
      return dyn_cast_or_null<InputSectionBase>(DR->Section);
    return nullptr;
  };

  for (StringRef Line : args::getLines(MB)) {
    SmallVector<StringRef, 3> Fields;
    Line.split(Fields, ' ');
    uint64_t Count;

    if (Fields.size() != 3 || !to_integer(Fields[2], Count)) {
      error(MB.getBufferIdentifier() + ": parse error");
      return;
    }

    if (InputSectionBase *From = FindSection(Fields[0]))
      if (InputSectionBase *To = FindSection(Fields[1]))
        Config->CallGraphProfile[std::make_pair(From, To)] += Count;
  }
}

template <class ELFT> static void readCallGraphsFromObjectFiles() {
  for (auto File : ObjectFiles) {
    auto *Obj = cast<ObjFile<ELFT>>(File);

    for (const Elf_CGProfile_Impl<ELFT> &CGPE : Obj->CGProfile) {
      auto *FromSym = dyn_cast<Defined>(&Obj->getSymbol(CGPE.cgp_from));
      auto *ToSym = dyn_cast<Defined>(&Obj->getSymbol(CGPE.cgp_to));
      if (!FromSym || !ToSym)
        continue;

      auto *From = dyn_cast_or_null<InputSectionBase>(FromSym->Section);
      auto *To = dyn_cast_or_null<InputSectionBase>(ToSym->Section);
      if (From && To)
        Config->CallGraphProfile[{From, To}] += CGPE.cgp_weight;
    }
  }
}

static bool getCompressDebugSections(opt::InputArgList &Args) {
  StringRef S = Args.getLastArgValue(OPT_compress_debug_sections, "none");
  if (S == "none")
    return false;
  if (S != "zlib")
    error("unknown --compress-debug-sections value: " + S);
  if (!zlib::isAvailable())
    error("--compress-debug-sections: zlib is not available");
  return true;
}

static std::pair<StringRef, StringRef> getOldNewOptions(opt::InputArgList &Args,
                                                        unsigned Id) {
  auto *Arg = Args.getLastArg(Id);
  if (!Arg)
    return {"", ""};

  StringRef S = Arg->getValue();
  std::pair<StringRef, StringRef> Ret = S.split(';');
  if (Ret.second.empty())
    error(Arg->getSpelling() + " expects 'old;new' format, but got " + S);
  return Ret;
}

// Parse the symbol ordering file and warn for any duplicate entries.
static std::vector<StringRef> getSymbolOrderingFile(MemoryBufferRef MB) {
  SetVector<StringRef> Names;
  for (StringRef S : args::getLines(MB))
    if (!Names.insert(S) && Config->WarnSymbolOrdering)
      warn(MB.getBufferIdentifier() + ": duplicate ordered symbol: " + S);

  return Names.takeVector();
}

static void parseClangOption(StringRef Opt, const Twine &Msg) {
  std::string Err;
  raw_string_ostream OS(Err);

  const char *Argv[] = {Config->ProgName.data(), Opt.data()};
  if (cl::ParseCommandLineOptions(2, Argv, "", &OS))
    return;
  OS.flush();
  error(Msg + ": " + StringRef(Err).trim());
}

// Initializes Config members by the command line options.
void LinkerDriver::readConfigs(opt::InputArgList &Args) {
  errorHandler().Verbose = Args.hasArg(OPT_verbose);
  errorHandler().FatalWarnings =
      Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false);
  ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true);

  Config->AllowMultipleDefinition =
      Args.hasFlag(OPT_allow_multiple_definition,
                   OPT_no_allow_multiple_definition, false) ||
      hasZOption(Args, "muldefs");
  Config->AuxiliaryList = args::getStrings(Args, OPT_auxiliary);
  Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic);
  Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions);
  Config->CheckSections =
      Args.hasFlag(OPT_check_sections, OPT_no_check_sections, true);
  Config->Chroot = Args.getLastArgValue(OPT_chroot);
  Config->CompressDebugSections = getCompressDebugSections(Args);
  Config->Cref = Args.hasFlag(OPT_cref, OPT_no_cref, false);
  Config->DefineCommon = Args.hasFlag(OPT_define_common, OPT_no_define_common,
                                      !Args.hasArg(OPT_relocatable));
  Config->Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, true);
  Config->DisableVerify = Args.hasArg(OPT_disable_verify);
  Config->Discard = getDiscard(Args);
  Config->DwoDir = Args.getLastArgValue(OPT_plugin_opt_dwo_dir_eq);
  Config->DynamicLinker = getDynamicLinker(Args);
  Config->EhFrameHdr =
      Args.hasFlag(OPT_eh_frame_hdr, OPT_no_eh_frame_hdr, false);
  Config->EmitRelocs = Args.hasArg(OPT_emit_relocs);
  Config->CallGraphProfileSort = Args.hasFlag(
      OPT_call_graph_profile_sort, OPT_no_call_graph_profile_sort, true);
  Config->EnableNewDtags =
      Args.hasFlag(OPT_enable_new_dtags, OPT_disable_new_dtags, true);
  Config->Entry = Args.getLastArgValue(OPT_entry);
  Config->ExecuteOnly =
      Args.hasFlag(OPT_execute_only, OPT_no_execute_only, false);
  Config->ExportDynamic =
      Args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false);
  Config->FilterList = args::getStrings(Args, OPT_filter);
  Config->Fini = Args.getLastArgValue(OPT_fini, "_fini");
  Config->FixCortexA53Errata843419 = Args.hasArg(OPT_fix_cortex_a53_843419);
  Config->GcSections = Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false);
  Config->GnuUnique = Args.hasFlag(OPT_gnu_unique, OPT_no_gnu_unique, true);
  Config->GdbIndex = Args.hasFlag(OPT_gdb_index, OPT_no_gdb_index, false);
  Config->ICF = getICF(Args);
  Config->IgnoreDataAddressEquality =
      Args.hasArg(OPT_ignore_data_address_equality);
  Config->IgnoreFunctionAddressEquality =
      Args.hasArg(OPT_ignore_function_address_equality);
  Config->Init = Args.getLastArgValue(OPT_init, "_init");
  Config->LTOAAPipeline = Args.getLastArgValue(OPT_lto_aa_pipeline);
  Config->LTODebugPassManager = Args.hasArg(OPT_lto_debug_pass_manager);
  Config->LTONewPassManager = Args.hasArg(OPT_lto_new_pass_manager);
  Config->LTONewPmPasses = Args.getLastArgValue(OPT_lto_newpm_passes);
  Config->LTOO = args::getInteger(Args, OPT_lto_O, 2);
  Config->LTOObjPath = Args.getLastArgValue(OPT_plugin_opt_obj_path_eq);
  Config->LTOPartitions = args::getInteger(Args, OPT_lto_partitions, 1);
  Config->LTOSampleProfile = Args.getLastArgValue(OPT_lto_sample_profile);
  Config->MapFile = Args.getLastArgValue(OPT_Map);
  Config->MipsGotSize = args::getInteger(Args, OPT_mips_got_size, 0xfff0);
  Config->MergeArmExidx =
      Args.hasFlag(OPT_merge_exidx_entries, OPT_no_merge_exidx_entries, true);
  Config->NoinhibitExec = Args.hasArg(OPT_noinhibit_exec);
  Config->Nostdlib = Args.hasArg(OPT_nostdlib);
  Config->OFormatBinary = isOutputFormatBinary(Args);
  Config->Omagic = Args.hasFlag(OPT_omagic, OPT_no_omagic, false);
  Config->OptRemarksFilename = Args.getLastArgValue(OPT_opt_remarks_filename);
  Config->OptRemarksWithHotness = Args.hasArg(OPT_opt_remarks_with_hotness);
  Config->Optimize = args::getInteger(Args, OPT_O, 1);
  Config->OrphanHandling = getOrphanHandling(Args);
  Config->OutputFile = Args.getLastArgValue(OPT_o);
  Config->Pie = Args.hasFlag(OPT_pie, OPT_no_pie, false);
  Config->PrintIcfSections =
      Args.hasFlag(OPT_print_icf_sections, OPT_no_print_icf_sections, false);
  Config->PrintGcSections =
      Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
  Config->Rpath = getRpath(Args);
  Config->Relocatable = Args.hasArg(OPT_relocatable);
  Config->SaveTemps = Args.hasArg(OPT_save_temps);
  Config->SearchPaths = args::getStrings(Args, OPT_library_path);
  Config->SectionStartMap = getSectionStartMap(Args);
  Config->Shared = Args.hasArg(OPT_shared);
  Config->SingleRoRx = Args.hasArg(OPT_no_rosegment);
  Config->SoName = Args.getLastArgValue(OPT_soname);
  Config->SortSection = getSortSection(Args);
  Config->SplitStackAdjustSize = args::getInteger(Args, OPT_split_stack_adjust_size, 16384);
  Config->Strip = getStrip(Args);
  Config->Sysroot = Args.getLastArgValue(OPT_sysroot);
  Config->Target1Rel = Args.hasFlag(OPT_target1_rel, OPT_target1_abs, false);
  Config->Target2 = getTarget2(Args);
  Config->ThinLTOCacheDir = Args.getLastArgValue(OPT_thinlto_cache_dir);
  Config->ThinLTOCachePolicy = CHECK(
      parseCachePruningPolicy(Args.getLastArgValue(OPT_thinlto_cache_policy)),
      "--thinlto-cache-policy: invalid cache policy");
  Config->ThinLTOEmitImportsFiles =
      Args.hasArg(OPT_plugin_opt_thinlto_emit_imports_files);
  Config->ThinLTOIndexOnly = Args.hasArg(OPT_plugin_opt_thinlto_index_only) ||
                             Args.hasArg(OPT_plugin_opt_thinlto_index_only_eq);
  Config->ThinLTOIndexOnlyArg =
      Args.getLastArgValue(OPT_plugin_opt_thinlto_index_only_eq);
  Config->ThinLTOJobs = args::getInteger(Args, OPT_thinlto_jobs, -1u);
  Config->ThinLTOObjectSuffixReplace =
      getOldNewOptions(Args, OPT_plugin_opt_thinlto_object_suffix_replace_eq);
  Config->ThinLTOPrefixReplace =
      getOldNewOptions(Args, OPT_plugin_opt_thinlto_prefix_replace_eq);
  Config->Trace = Args.hasArg(OPT_trace);
  Config->Undefined = args::getStrings(Args, OPT_undefined);
  Config->UndefinedVersion =
      Args.hasFlag(OPT_undefined_version, OPT_no_undefined_version, true);
  Config->UseAndroidRelrTags = Args.hasFlag(
      OPT_use_android_relr_tags, OPT_no_use_android_relr_tags, false);
  Config->UnresolvedSymbols = getUnresolvedSymbolPolicy(Args);
  Config->WarnBackrefs =
      Args.hasFlag(OPT_warn_backrefs, OPT_no_warn_backrefs, false);
  Config->WarnCommon = Args.hasFlag(OPT_warn_common, OPT_no_warn_common, false);
  Config->WarnIfuncTextrel =
      Args.hasFlag(OPT_warn_ifunc_textrel, OPT_no_warn_ifunc_textrel, false);
  Config->WarnSymbolOrdering =
      Args.hasFlag(OPT_warn_symbol_ordering, OPT_no_warn_symbol_ordering, true);
  Config->ZCombreloc = getZFlag(Args, "combreloc", "nocombreloc", true);
  Config->ZCopyreloc = getZFlag(Args, "copyreloc", "nocopyreloc", true);
  Config->ZExecstack = getZFlag(Args, "execstack", "noexecstack", false);
  Config->ZGlobal = hasZOption(Args, "global");
  Config->ZHazardplt = hasZOption(Args, "hazardplt");
  Config->ZInitfirst = hasZOption(Args, "initfirst");
  Config->ZInterpose = hasZOption(Args, "interpose");
  Config->ZKeepTextSectionPrefix = getZFlag(
      Args, "keep-text-section-prefix", "nokeep-text-section-prefix", false);
  Config->ZNodefaultlib = hasZOption(Args, "nodefaultlib");
  Config->ZNodelete = hasZOption(Args, "nodelete");
  Config->ZNodlopen = hasZOption(Args, "nodlopen");
  Config->ZNow = getZFlag(Args, "now", "lazy", false);
  Config->ZOrigin = hasZOption(Args, "origin");
  Config->ZRelro = getZFlag(Args, "relro", "norelro", true);
  Config->ZRetpolineplt = hasZOption(Args, "retpolineplt");
  Config->ZRodynamic = hasZOption(Args, "rodynamic");
  Config->ZStackSize = args::getZOptionValue(Args, OPT_z, "stack-size", 0);
  Config->ZText = getZFlag(Args, "text", "notext", true);
  Config->ZWxneeded = hasZOption(Args, "wxneeded");

  // Parse LTO options.
  if (auto *Arg = Args.getLastArg(OPT_plugin_opt_mcpu_eq))
    parseClangOption(Saver.save("-mcpu=" + StringRef(Arg->getValue())),
                     Arg->getSpelling());

  for (auto *Arg : Args.filtered(OPT_plugin_opt))
    parseClangOption(Arg->getValue(), Arg->getSpelling());

  // Parse -mllvm options.
  for (auto *Arg : Args.filtered(OPT_mllvm))
    parseClangOption(Arg->getValue(), Arg->getSpelling());

  if (Config->LTOO > 3)
    error("invalid optimization level for LTO: " + Twine(Config->LTOO));
  if (Config->LTOPartitions == 0)
    error("--lto-partitions: number of threads must be > 0");
  if (Config->ThinLTOJobs == 0)
    error("--thinlto-jobs: number of threads must be > 0");

  if (Config->SplitStackAdjustSize < 0)
    error("--split-stack-adjust-size: size must be >= 0");

  // Parse ELF{32,64}{LE,BE} and CPU type.
  if (auto *Arg = Args.getLastArg(OPT_m)) {
    StringRef S = Arg->getValue();
    std::tie(Config->EKind, Config->EMachine, Config->OSABI) =
        parseEmulation(S);
    Config->MipsN32Abi = (S == "elf32btsmipn32" || S == "elf32ltsmipn32");
    Config->Emulation = S;
  }

  // Parse -hash-style={sysv,gnu,both}.
  if (auto *Arg = Args.getLastArg(OPT_hash_style)) {
    StringRef S = Arg->getValue();
    if (S == "sysv")
      Config->SysvHash = true;
    else if (S == "gnu")
      Config->GnuHash = true;
    else if (S == "both")
      Config->SysvHash = Config->GnuHash = true;
    else
      error("unknown -hash-style: " + S);
  }

  if (Args.hasArg(OPT_print_map))
    Config->MapFile = "-";

  // --omagic is an option to create old-fashioned executables in which
  // .text segments are writable. Today, the option is still in use to
  // create special-purpose programs such as boot loaders. It doesn't
  // make sense to create PT_GNU_RELRO for such executables.
  if (Config->Omagic)
    Config->ZRelro = false;

  std::tie(Config->BuildId, Config->BuildIdVector) = getBuildId(Args);

  std::tie(Config->AndroidPackDynRelocs, Config->RelrPackDynRelocs) =
      getPackDynRelocs(Args);

  if (auto *Arg = Args.getLastArg(OPT_symbol_ordering_file))
    if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
      Config->SymbolOrderingFile = getSymbolOrderingFile(*Buffer);

  // If --retain-symbol-file is used, we'll keep only the symbols listed in
  // the file and discard all others.
  if (auto *Arg = Args.getLastArg(OPT_retain_symbols_file)) {
    Config->DefaultSymbolVersion = VER_NDX_LOCAL;
    if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
      for (StringRef S : args::getLines(*Buffer))
        Config->VersionScriptGlobals.push_back(
            {S, /*IsExternCpp*/ false, /*HasWildcard*/ false});
  }

  bool HasExportDynamic =
      Args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false);

  // Parses -dynamic-list and -export-dynamic-symbol. They make some
  // symbols private. Note that -export-dynamic takes precedence over them
  // as it says all symbols should be exported.
  if (!HasExportDynamic) {
    for (auto *Arg : Args.filtered(OPT_dynamic_list))
      if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
        readDynamicList(*Buffer);

    for (auto *Arg : Args.filtered(OPT_export_dynamic_symbol))
      Config->DynamicList.push_back(
          {Arg->getValue(), /*IsExternCpp*/ false, /*HasWildcard*/ false});
  }

  // If --export-dynamic-symbol=foo is given and symbol foo is defined in
  // an object file in an archive file, that object file should be pulled
  // out and linked. (It doesn't have to behave like that from technical
  // point of view, but this is needed for compatibility with GNU.)
  for (auto *Arg : Args.filtered(OPT_export_dynamic_symbol))
    Config->Undefined.push_back(Arg->getValue());

  for (auto *Arg : Args.filtered(OPT_version_script))
    if (Optional<std::string> Path = searchScript(Arg->getValue())) {
      if (Optional<MemoryBufferRef> Buffer = readFile(*Path))
        readVersionScript(*Buffer);
    } else {
      error(Twine("cannot find version script ") + Arg->getValue());
    }
}

// Some Config members do not directly correspond to any particular
// command line options, but computed based on other Config values.
// This function initialize such members. See Config.h for the details
// of these values.
static void setConfigs(opt::InputArgList &Args) {
  ELFKind K = Config->EKind;
  uint16_t M = Config->EMachine;

  Config->CopyRelocs = (Config->Relocatable || Config->EmitRelocs);
  Config->Is64 = (K == ELF64LEKind || K == ELF64BEKind);
  Config->IsLE = (K == ELF32LEKind || K == ELF64LEKind);
  Config->Endianness = Config->IsLE ? endianness::little : endianness::big;
  Config->IsMips64EL = (K == ELF64LEKind && M == EM_MIPS);
  Config->Pic = Config->Pie || Config->Shared;
  Config->Wordsize = Config->Is64 ? 8 : 4;

  // ELF defines two different ways to store relocation addends as shown below:
  //
  //  Rel:  Addends are stored to the location where relocations are applied.
  //  Rela: Addends are stored as part of relocation entry.
  //
  // In other words, Rela makes it easy to read addends at the price of extra
  // 4 or 8 byte for each relocation entry. We don't know why ELF defined two
  // different mechanisms in the first place, but this is how the spec is
  // defined.
  //
  // You cannot choose which one, Rel or Rela, you want to use. Instead each
  // ABI defines which one you need to use. The following expression expresses
  // that.
  Config->IsRela = M == EM_AARCH64 || M == EM_AMDGPU || M == EM_HEXAGON ||
                   M == EM_PPC || M == EM_PPC64 || M == EM_RISCV ||
                   M == EM_X86_64;

  // If the output uses REL relocations we must store the dynamic relocation
  // addends to the output sections. We also store addends for RELA relocations
  // if --apply-dynamic-relocs is used.
  // We default to not writing the addends when using RELA relocations since
  // any standard conforming tool can find it in r_addend.
  Config->WriteAddends = Args.hasFlag(OPT_apply_dynamic_relocs,
                                      OPT_no_apply_dynamic_relocs, false) ||
                         !Config->IsRela;

  Config->TocOptimize =
      Args.hasFlag(OPT_toc_optimize, OPT_no_toc_optimize, M == EM_PPC64);
}

// Returns a value of "-format" option.
static bool isFormatBinary(StringRef S) {
  if (S == "binary")
    return true;
  if (S == "elf" || S == "default")
    return false;
  error("unknown -format value: " + S +
        " (supported formats: elf, default, binary)");
  return false;
}

void LinkerDriver::createFiles(opt::InputArgList &Args) {
  // For --{push,pop}-state.
  std::vector<std::tuple<bool, bool, bool>> Stack;

  // Iterate over argv to process input files and positional arguments.
  for (auto *Arg : Args) {
    switch (Arg->getOption().getUnaliasedOption().getID()) {
    case OPT_library:
      addLibrary(Arg->getValue());
      break;
    case OPT_INPUT:
      addFile(Arg->getValue(), /*WithLOption=*/false);
      break;
    case OPT_defsym: {
      StringRef From;
      StringRef To;
      std::tie(From, To) = StringRef(Arg->getValue()).split('=');
      if (From.empty() || To.empty())
        error("-defsym: syntax error: " + StringRef(Arg->getValue()));
      else
        readDefsym(From, MemoryBufferRef(To, "-defsym"));
      break;
    }
    case OPT_script:
      if (Optional<std::string> Path = searchScript(Arg->getValue())) {
        if (Optional<MemoryBufferRef> MB = readFile(*Path))
          readLinkerScript(*MB);
        break;
      }
      error(Twine("cannot find linker script ") + Arg->getValue());
      break;
    case OPT_as_needed:
      Config->AsNeeded = true;
      break;
    case OPT_format:
      Config->FormatBinary = isFormatBinary(Arg->getValue());
      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:
      InWholeArchive = true;
      break;
    case OPT_no_whole_archive:
      InWholeArchive = false;
      break;
    case OPT_just_symbols:
      if (Optional<MemoryBufferRef> MB = readFile(Arg->getValue())) {
        Files.push_back(createObjectFile(*MB));
        Files.back()->JustSymbols = true;
      }
      break;
    case OPT_start_group:
      if (InputFile::IsInGroup)
        error("nested --start-group");
      InputFile::IsInGroup = true;
      break;
    case OPT_end_group:
      if (!InputFile::IsInGroup)
        error("stray --end-group");
      InputFile::IsInGroup = false;
      ++InputFile::NextGroupId;
      break;
    case OPT_start_lib:
      if (InLib)
        error("nested --start-lib");
      if (InputFile::IsInGroup)
        error("may not nest --start-lib in --start-group");
      InLib = true;
      InputFile::IsInGroup = true;
      break;
    case OPT_end_lib:
      if (!InLib)
        error("stray --end-lib");
      InLib = false;
      InputFile::IsInGroup = false;
      ++InputFile::NextGroupId;
      break;
    case OPT_push_state:
      Stack.emplace_back(Config->AsNeeded, Config->Static, InWholeArchive);
      break;
    case OPT_pop_state:
      if (Stack.empty()) {
        error("unbalanced --push-state/--pop-state");
        break;
      }
      std::tie(Config->AsNeeded, Config->Static, InWholeArchive) = Stack.back();
      Stack.pop_back();
      break;
    }
  }

  if (Files.empty() && errorCount() == 0)
    error("no input files");
}

// If -m <machine_type> was not given, infer it from object files.
void LinkerDriver::inferMachineType() {
  if (Config->EKind != ELFNoneKind)
    return;

  for (InputFile *F : Files) {
    if (F->EKind == ELFNoneKind)
      continue;
    Config->EKind = F->EKind;
    Config->EMachine = F->EMachine;
    Config->OSABI = F->OSABI;
    Config->MipsN32Abi = Config->EMachine == EM_MIPS && isMipsN32Abi(F);
    return;
  }
  error("target emulation unknown: -m or at least one .o file required");
}

// Parse -z max-page-size=<value>. The default value is defined by
// each target.
static uint64_t getMaxPageSize(opt::InputArgList &Args) {
  uint64_t Val = args::getZOptionValue(Args, OPT_z, "max-page-size",
                                       Target->DefaultMaxPageSize);
  if (!isPowerOf2_64(Val))
    error("max-page-size: value isn't a power of 2");
  return Val;
}

// Parses -image-base option.
static Optional<uint64_t> getImageBase(opt::InputArgList &Args) {
  // Because we are using "Config->MaxPageSize" here, this function has to be
  // called after the variable is initialized.
  auto *Arg = Args.getLastArg(OPT_image_base);
  if (!Arg)
    return None;

  StringRef S = Arg->getValue();
  uint64_t V;
  if (!to_integer(S, V)) {
    error("-image-base: number expected, but got " + S);
    return 0;
  }
  if ((V % Config->MaxPageSize) != 0)
    warn("-image-base: address isn't multiple of page size: " + S);
  return V;
}

// Parses `--exclude-libs=lib,lib,...`.
// The library names may be delimited by commas or colons.
static DenseSet<StringRef> getExcludeLibs(opt::InputArgList &Args) {
  DenseSet<StringRef> Ret;
  for (auto *Arg : Args.filtered(OPT_exclude_libs)) {
    StringRef S = Arg->getValue();
    for (;;) {
      size_t Pos = S.find_first_of(",:");
      if (Pos == StringRef::npos)
        break;
      Ret.insert(S.substr(0, Pos));
      S = S.substr(Pos + 1);
    }
    Ret.insert(S);
  }
  return Ret;
}

// Handles the -exclude-libs option. If a static library file is specified
// by the -exclude-libs option, all public symbols from the archive become
// private unless otherwise specified by version scripts or something.
// A special library name "ALL" means all archive files.
//
// This is not a popular option, but some programs such as bionic libc use it.
template <class ELFT>
static void excludeLibs(opt::InputArgList &Args) {
  DenseSet<StringRef> Libs = getExcludeLibs(Args);
  bool All = Libs.count("ALL");

  auto Visit = [&](InputFile *File) {
    if (!File->ArchiveName.empty())
      if (All || Libs.count(path::filename(File->ArchiveName)))
        for (Symbol *Sym : File->getSymbols())
          if (!Sym->isLocal() && Sym->File == File)
            Sym->VersionId = VER_NDX_LOCAL;
  };

  for (InputFile *File : ObjectFiles)
    Visit(File);

  for (BitcodeFile *File : BitcodeFiles)
    Visit(File);
}

// Force Sym to be entered in the output. Used for -u or equivalent.
template <class ELFT> static void handleUndefined(StringRef Name) {
  Symbol *Sym = Symtab->find(Name);
  if (!Sym)
    return;

  // Since symbol S may not be used inside the program, LTO may
  // eliminate it. Mark the symbol as "used" to prevent it.
  Sym->IsUsedInRegularObj = true;

  if (Sym->isLazy())
    Symtab->fetchLazy<ELFT>(Sym);
}

template <class ELFT> static void handleLibcall(StringRef Name) {
  Symbol *Sym = Symtab->find(Name);
  if (!Sym || !Sym->isLazy())
    return;

  MemoryBufferRef MB;
  if (auto *LO = dyn_cast<LazyObject>(Sym))
    MB = LO->File->MB;
  else
    MB = cast<LazyArchive>(Sym)->getMemberBuffer();

  if (isBitcode(MB))
    Symtab->fetchLazy<ELFT>(Sym);
}

// If all references to a DSO happen to be weak, the DSO is not added
// to DT_NEEDED. If that happens, we need to eliminate shared symbols
// created from the DSO. Otherwise, they become dangling references
// that point to a non-existent DSO.
template <class ELFT> static void demoteSharedSymbols() {
  for (Symbol *Sym : Symtab->getSymbols()) {
    if (auto *S = dyn_cast<SharedSymbol>(Sym)) {
      if (!S->getFile<ELFT>().IsNeeded) {
        bool Used = S->Used;
        replaceSymbol<Undefined>(S, nullptr, S->getName(), STB_WEAK, S->StOther,
                                 S->Type);
        S->Used = Used;
      }
    }
  }
}

// The section referred to by S is considered address-significant. Set the
// KeepUnique flag on the section if appropriate.
static void markAddrsig(Symbol *S) {
  if (auto *D = dyn_cast_or_null<Defined>(S))
    if (D->Section)
      // We don't need to keep text sections unique under --icf=all even if they
      // are address-significant.
      if (Config->ICF == ICFLevel::Safe || !(D->Section->Flags & SHF_EXECINSTR))
        D->Section->KeepUnique = true;
}

// Record sections that define symbols mentioned in --keep-unique <symbol>
// and symbols referred to by address-significance tables. These sections are
// ineligible for ICF.
template <class ELFT>
static void findKeepUniqueSections(opt::InputArgList &Args) {
  for (auto *Arg : Args.filtered(OPT_keep_unique)) {
    StringRef Name = Arg->getValue();
    auto *D = dyn_cast_or_null<Defined>(Symtab->find(Name));
    if (!D || !D->Section) {
      warn("could not find symbol " + Name + " to keep unique");
      continue;
    }
    D->Section->KeepUnique = true;
  }

  // --icf=all --ignore-data-address-equality means that we can ignore
  // the dynsym and address-significance tables entirely.
  if (Config->ICF == ICFLevel::All && Config->IgnoreDataAddressEquality)
    return;

  // Symbols in the dynsym could be address-significant in other executables
  // or DSOs, so we conservatively mark them as address-significant.
  for (Symbol *S : Symtab->getSymbols())
    if (S->includeInDynsym())
      markAddrsig(S);

  // Visit the address-significance table in each object file and mark each
  // referenced symbol as address-significant.
  for (InputFile *F : ObjectFiles) {
    auto *Obj = cast<ObjFile<ELFT>>(F);
    ArrayRef<Symbol *> Syms = Obj->getSymbols();
    if (Obj->AddrsigSec) {
      ArrayRef<uint8_t> Contents =
          check(Obj->getObj().getSectionContents(Obj->AddrsigSec));
      const uint8_t *Cur = Contents.begin();
      while (Cur != Contents.end()) {
        unsigned Size;
        const char *Err;
        uint64_t SymIndex = decodeULEB128(Cur, &Size, Contents.end(), &Err);
        if (Err)
          fatal(toString(F) + ": could not decode addrsig section: " + Err);
        markAddrsig(Syms[SymIndex]);
        Cur += Size;
      }
    } else {
      // If an object file does not have an address-significance table,
      // conservatively mark all of its symbols as address-significant.
      for (Symbol *S : Syms)
        markAddrsig(S);
    }
  }
}

template <class ELFT> static Symbol *addUndefined(StringRef Name) {
  return Symtab->addUndefined<ELFT>(Name, STB_GLOBAL, STV_DEFAULT, 0, false,
                                    nullptr);
}

// The --wrap option is a feature to rename symbols so that you can write
// wrappers for existing functions. If you pass `-wrap=foo`, all
// occurrences of symbol `foo` are resolved to `wrap_foo` (so, you are
// expected to write `wrap_foo` function as a wrapper). The original
// symbol becomes accessible as `real_foo`, so you can call that from your
// wrapper.
//
// This data structure is instantiated for each -wrap option.
struct WrappedSymbol {
  Symbol *Sym;
  Symbol *Real;
  Symbol *Wrap;
};

// Handles -wrap option.
//
// This function instantiates wrapper symbols. At this point, they seem
// like they are not being used at all, so we explicitly set some flags so
// that LTO won't eliminate them.
template <class ELFT>
static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &Args) {
  std::vector<WrappedSymbol> V;
  DenseSet<StringRef> Seen;

  for (auto *Arg : Args.filtered(OPT_wrap)) {
    StringRef Name = Arg->getValue();
    if (!Seen.insert(Name).second)
      continue;

    Symbol *Sym = Symtab->find(Name);
    if (!Sym)
      continue;

    Symbol *Real = addUndefined<ELFT>(Saver.save("__real_" + Name));
    Symbol *Wrap = addUndefined<ELFT>(Saver.save("__wrap_" + Name));
    V.push_back({Sym, Real, Wrap});

    // We want to tell LTO not to inline symbols to be overwritten
    // because LTO doesn't know the final symbol contents after renaming.
    Real->CanInline = false;
    Sym->CanInline = false;

    // Tell LTO not to eliminate these symbols.
    Sym->IsUsedInRegularObj = true;
    Wrap->IsUsedInRegularObj = true;
  }
  return V;
}

// Do renaming for -wrap by updating pointers to symbols.
//
// When this function is executed, only InputFiles and symbol table
// contain pointers to symbol objects. We visit them to replace pointers,
// so that wrapped symbols are swapped as instructed by the command line.
template <class ELFT> static void wrapSymbols(ArrayRef<WrappedSymbol> Wrapped) {
  DenseMap<Symbol *, Symbol *> Map;
  for (const WrappedSymbol &W : Wrapped) {
    Map[W.Sym] = W.Wrap;
    Map[W.Real] = W.Sym;
  }

  // Update pointers in input files.
  parallelForEach(ObjectFiles, [&](InputFile *File) {
    std::vector<Symbol *> &Syms = File->getMutableSymbols();
    for (size_t I = 0, E = Syms.size(); I != E; ++I)
      if (Symbol *S = Map.lookup(Syms[I]))
        Syms[I] = S;
  });

  // Update pointers in the symbol table.
  for (const WrappedSymbol &W : Wrapped)
    Symtab->wrap(W.Sym, W.Real, W.Wrap);
}

static const char *LibcallRoutineNames[] = {
#define HANDLE_LIBCALL(code, name) name,
#include "llvm/IR/RuntimeLibcalls.def"
#undef HANDLE_LIBCALL
};

// Do actual linking. Note that when this function is called,
// all linker scripts have already been parsed.
template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
  Target = getTarget();
  InX<ELFT>::VerSym = nullptr;
  InX<ELFT>::VerNeed = nullptr;

  Config->MaxPageSize = getMaxPageSize(Args);
  Config->ImageBase = getImageBase(Args);

  // If a -hash-style option was not given, set to a default value,
  // which varies depending on the target.
  if (!Args.hasArg(OPT_hash_style)) {
    if (Config->EMachine == EM_MIPS)
      Config->SysvHash = true;
    else
      Config->SysvHash = Config->GnuHash = true;
  }

  // Default output filename is "a.out" by the Unix tradition.
  if (Config->OutputFile.empty())
    Config->OutputFile = "a.out";

  // Fail early if the output file or map file is not writable. If a user has a
  // long link, e.g. due to a large LTO link, they do not wish to run it and
  // find that it failed because there was a mistake in their command-line.
  if (auto E = tryCreateFile(Config->OutputFile))
    error("cannot open output file " + Config->OutputFile + ": " + E.message());
  if (auto E = tryCreateFile(Config->MapFile))
    error("cannot open map file " + Config->MapFile + ": " + E.message());
  if (errorCount())
    return;

  // Use default entry point name if no name was given via the command
  // line nor linker scripts. For some reason, MIPS entry point name is
  // different from others.
  Config->WarnMissingEntry =
      (!Config->Entry.empty() || (!Config->Shared && !Config->Relocatable));
  if (Config->Entry.empty() && !Config->Relocatable)
    Config->Entry = (Config->EMachine == EM_MIPS) ? "__start" : "_start";

  // Handle --trace-symbol.
  for (auto *Arg : Args.filtered(OPT_trace_symbol))
    Symtab->trace(Arg->getValue());

  // Add all files to the symbol table. This will add almost all
  // symbols that we need to the symbol table.
  for (InputFile *F : Files)
    Symtab->addFile<ELFT>(F);

  // Now that we have every file, we can decide if we will need a
  // dynamic symbol table.
  // We need one if we were asked to export dynamic symbols or if we are
  // producing a shared library.
  // We also need one if any shared libraries are used and for pie executables
  // (probably because the dynamic linker needs it).
  Config->HasDynSymTab =
      !SharedFiles.empty() || Config->Pic || Config->ExportDynamic;

  // Some symbols (such as __ehdr_start) are defined lazily only when there
  // are undefined symbols for them, so we add these to trigger that logic.
  for (StringRef Name : Script->ReferencedSymbols)
    addUndefined<ELFT>(Name);

  // Handle the `--undefined <sym>` options.
  for (StringRef S : Config->Undefined)
    handleUndefined<ELFT>(S);

  // If an entry symbol is in a static archive, pull out that file now.
  handleUndefined<ELFT>(Config->Entry);

  // If any of our inputs are bitcode files, the LTO code generator may create
  // references to certain library functions that might not be explicit in the
  // bitcode file's symbol table. If any of those library functions are defined
  // in a bitcode file in an archive member, we need to arrange to use LTO to
  // compile those archive members by adding them to the link beforehand.
  //
  // However, adding all libcall symbols to the link can have undesired
  // consequences. For example, the libgcc implementation of
  // __sync_val_compare_and_swap_8 on 32-bit ARM pulls in an .init_array entry
  // that aborts the program if the Linux kernel does not support 64-bit
  // atomics, which would prevent the program from running even if it does not
  // use 64-bit atomics.
  //
  // Therefore, we only add libcall symbols to the link before LTO if we have
  // to, i.e. if the symbol's definition is in bitcode. Any other required
  // libcall symbols will be added to the link after LTO when we add the LTO
  // object file to the link.
  if (!BitcodeFiles.empty())
    for (const char *S : LibcallRoutineNames)
      handleLibcall<ELFT>(S);

  // Return if there were name resolution errors.
  if (errorCount())
    return;

  // Now when we read all script files, we want to finalize order of linker
  // script commands, which can be not yet final because of INSERT commands.
  Script->processInsertCommands();

  // We want to declare linker script's symbols early,
  // so that we can version them.
  // They also might be exported if referenced by DSOs.
  Script->declareSymbols();

  // Handle the -exclude-libs option.
  if (Args.hasArg(OPT_exclude_libs))
    excludeLibs<ELFT>(Args);

  // Create ElfHeader early. We need a dummy section in
  // addReservedSymbols to mark the created symbols as not absolute.
  Out::ElfHeader = make<OutputSection>("", 0, SHF_ALLOC);
  Out::ElfHeader->Size = sizeof(typename ELFT::Ehdr);

  // We need to create some reserved symbols such as _end. Create them.
  if (!Config->Relocatable)
    addReservedSymbols();

  // Apply version scripts.
  //
  // For a relocatable output, version scripts don't make sense, and
  // parsing a symbol version string (e.g. dropping "@ver1" from a symbol
  // name "foo@ver1") rather do harm, so we don't call this if -r is given.
  if (!Config->Relocatable)
    Symtab->scanVersionScript();

  // Create wrapped symbols for -wrap option.
  std::vector<WrappedSymbol> Wrapped = addWrappedSymbols<ELFT>(Args);

  // Do link-time optimization if given files are LLVM bitcode files.
  // This compiles bitcode files into real object files.
  //
  // With this the symbol table should be complete. After this, no new names
  // except a few linker-synthesized ones will be added to the symbol table.
  Symtab->addCombinedLTOObject<ELFT>();
  if (errorCount())
    return;

  // If -thinlto-index-only is given, we should create only "index
  // files" and not object files. Index file creation is already done
  // in addCombinedLTOObject, so we are done if that's the case.
  if (Config->ThinLTOIndexOnly)
    return;

  // Apply symbol renames for -wrap.
  if (!Wrapped.empty())
    wrapSymbols<ELFT>(Wrapped);

  // Now that we have a complete list of input files.
  // Beyond this point, no new files are added.
  // Aggregate all input sections into one place.
  for (InputFile *F : ObjectFiles)
    for (InputSectionBase *S : F->getSections())
      if (S && S != &InputSection::Discarded)
        InputSections.push_back(S);
  for (BinaryFile *F : BinaryFiles)
    for (InputSectionBase *S : F->getSections())
      InputSections.push_back(cast<InputSection>(S));

  // We do not want to emit debug sections if --strip-all
  // or -strip-debug are given.
  if (Config->Strip != StripPolicy::None)
    llvm::erase_if(InputSections, [](InputSectionBase *S) {
      return S->Name.startswith(".debug") || S->Name.startswith(".zdebug");
    });

  Config->EFlags = Target->calcEFlags();

  if (Config->EMachine == EM_ARM) {
    // FIXME: These warnings can be removed when lld only uses these features
    // when the input objects have been compiled with an architecture that
    // supports them.
    if (Config->ARMHasBlx == false)
      warn("lld uses blx instruction, no object with architecture supporting "
           "feature detected");
  }

  // This adds a .comment section containing a version string. We have to add it
  // before mergeSections because the .comment section is a mergeable section.
  if (!Config->Relocatable)
    InputSections.push_back(createCommentSection());

  // Do size optimizations: garbage collection, merging of SHF_MERGE sections
  // and identical code folding.
  splitSections<ELFT>();
  markLive<ELFT>();
  demoteSharedSymbols<ELFT>();
  mergeSections();
  if (Config->ICF != ICFLevel::None) {
    findKeepUniqueSections<ELFT>(Args);
    doIcf<ELFT>();
  }

  // Read the callgraph now that we know what was gced or icfed
  if (Config->CallGraphProfileSort) {
    if (auto *Arg = Args.getLastArg(OPT_call_graph_ordering_file))
      if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
        readCallGraph(*Buffer);
    readCallGraphsFromObjectFiles<ELFT>();
  }

  // Write the result to the file.
  writeResult<ELFT>();
}
