//===- dsymutil.cpp - Debug info dumping utility for llvm -----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This program is a utility that aims to be a dropin replacement for Darwin's
// dsymutil.
//===----------------------------------------------------------------------===//

#include "dsymutil.h"
#include "BinaryHolder.h"
#include "CFBundle.h"
#include "DebugMap.h"
#include "LinkUtils.h"
#include "MachOUtils.h"
#include "Reproducer.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/MachO.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileCollector.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ThreadPool.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/thread.h"
#include <algorithm>
#include <cstdint>
#include <cstdlib>
#include <string>
#include <system_error>

using namespace llvm;
using namespace llvm::dsymutil;
using namespace object;

namespace {
enum ID {
  OPT_INVALID = 0, // This is not an option ID.
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
               HELPTEXT, METAVAR, VALUES)                                      \
  OPT_##ID,
#include "Options.inc"
#undef OPTION
};

#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
#include "Options.inc"
#undef PREFIX

const opt::OptTable::Info InfoTable[] = {
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
               HELPTEXT, METAVAR, VALUES)                                      \
  {                                                                            \
      PREFIX,      NAME,      HELPTEXT,                                        \
      METAVAR,     OPT_##ID,  opt::Option::KIND##Class,                        \
      PARAM,       FLAGS,     OPT_##GROUP,                                     \
      OPT_##ALIAS, ALIASARGS, VALUES},
#include "Options.inc"
#undef OPTION
};

class DsymutilOptTable : public opt::OptTable {
public:
  DsymutilOptTable() : OptTable(InfoTable) {}
};
} // namespace

struct DsymutilOptions {
  bool DumpDebugMap = false;
  bool DumpStab = false;
  bool Flat = false;
  bool InputIsYAMLDebugMap = false;
  bool PaperTrailWarnings = false;
  bool Verify = false;
  bool ForceKeepFunctionForStatic = false;
  std::string SymbolMap;
  std::string OutputFile;
  std::string Toolchain;
  std::string ReproducerPath;
  std::vector<std::string> Archs;
  std::vector<std::string> InputFiles;
  unsigned NumThreads;
  ReproducerMode ReproMode = ReproducerMode::Off;
  dsymutil::LinkOptions LinkOpts;
};

/// Return a list of input files. This function has logic for dealing with the
/// special case where we might have dSYM bundles as input. The function
/// returns an error when the directory structure doesn't match that of a dSYM
/// bundle.
static Expected<std::vector<std::string>> getInputs(opt::InputArgList &Args,
                                                    bool DsymAsInput) {
  std::vector<std::string> InputFiles;
  for (auto *File : Args.filtered(OPT_INPUT))
    InputFiles.push_back(File->getValue());

  if (!DsymAsInput)
    return InputFiles;

  // If we are updating, we might get dSYM bundles as input.
  std::vector<std::string> Inputs;
  for (const auto &Input : InputFiles) {
    if (!sys::fs::is_directory(Input)) {
      Inputs.push_back(Input);
      continue;
    }

    // Make sure that we're dealing with a dSYM bundle.
    SmallString<256> BundlePath(Input);
    sys::path::append(BundlePath, "Contents", "Resources", "DWARF");
    if (!sys::fs::is_directory(BundlePath))
      return make_error<StringError>(
          Input + " is a directory, but doesn't look like a dSYM bundle.",
          inconvertibleErrorCode());

    // Create a directory iterator to iterate over all the entries in the
    // bundle.
    std::error_code EC;
    sys::fs::directory_iterator DirIt(BundlePath, EC);
    sys::fs::directory_iterator DirEnd;
    if (EC)
      return errorCodeToError(EC);

    // Add each entry to the list of inputs.
    while (DirIt != DirEnd) {
      Inputs.push_back(DirIt->path());
      DirIt.increment(EC);
      if (EC)
        return errorCodeToError(EC);
    }
  }
  return Inputs;
}

// Verify that the given combination of options makes sense.
static Error verifyOptions(const DsymutilOptions &Options) {
  if (Options.InputFiles.empty()) {
    return make_error<StringError>("no input files specified",
                                   errc::invalid_argument);
  }

  if (Options.LinkOpts.Update && llvm::is_contained(Options.InputFiles, "-")) {
    // FIXME: We cannot use stdin for an update because stdin will be
    // consumed by the BinaryHolder during the debugmap parsing, and
    // then we will want to consume it again in DwarfLinker. If we
    // used a unique BinaryHolder object that could cache multiple
    // binaries this restriction would go away.
    return make_error<StringError>(
        "standard input cannot be used as input for a dSYM update.",
        errc::invalid_argument);
  }

  if (!Options.Flat && Options.OutputFile == "-")
    return make_error<StringError>(
        "cannot emit to standard output without --flat.",
        errc::invalid_argument);

  if (Options.InputFiles.size() > 1 && Options.Flat &&
      !Options.OutputFile.empty())
    return make_error<StringError>(
        "cannot use -o with multiple inputs in flat mode.",
        errc::invalid_argument);

  if (Options.PaperTrailWarnings && Options.InputIsYAMLDebugMap)
    return make_error<StringError>(
        "paper trail warnings are not supported for YAML input.",
        errc::invalid_argument);

  if (!Options.ReproducerPath.empty() &&
      Options.ReproMode != ReproducerMode::Use)
    return make_error<StringError>(
        "cannot combine --gen-reproducer and --use-reproducer.",
        errc::invalid_argument);

  return Error::success();
}

static Expected<AccelTableKind> getAccelTableKind(opt::InputArgList &Args) {
  if (opt::Arg *Accelerator = Args.getLastArg(OPT_accelerator)) {
    StringRef S = Accelerator->getValue();
    if (S == "Apple")
      return AccelTableKind::Apple;
    if (S == "Dwarf")
      return AccelTableKind::Dwarf;
    if (S == "Pub")
      return AccelTableKind::Pub;
    if (S == "Default")
      return AccelTableKind::Default;
    return make_error<StringError>(
        "invalid accelerator type specified: '" + S +
            "'. Support values are 'Apple', 'Dwarf', 'Pub' and 'Default'.",
        inconvertibleErrorCode());
  }
  return AccelTableKind::Default;
}

/// Parses the command line options into the LinkOptions struct and performs
/// some sanity checking. Returns an error in case the latter fails.
static Expected<DsymutilOptions> getOptions(opt::InputArgList &Args) {
  DsymutilOptions Options;

  Options.DumpDebugMap = Args.hasArg(OPT_dump_debug_map);
  Options.DumpStab = Args.hasArg(OPT_symtab);
  Options.Flat = Args.hasArg(OPT_flat);
  Options.InputIsYAMLDebugMap = Args.hasArg(OPT_yaml_input);
  Options.PaperTrailWarnings = Args.hasArg(OPT_papertrail);
  Options.Verify = Args.hasArg(OPT_verify);

  Options.LinkOpts.NoODR = Args.hasArg(OPT_no_odr);
  Options.LinkOpts.NoOutput = Args.hasArg(OPT_no_output);
  Options.LinkOpts.NoTimestamp = Args.hasArg(OPT_no_swiftmodule_timestamp);
  Options.LinkOpts.Update = Args.hasArg(OPT_update);
  Options.LinkOpts.Verbose = Args.hasArg(OPT_verbose);
  Options.LinkOpts.Statistics = Args.hasArg(OPT_statistics);
  Options.LinkOpts.KeepFunctionForStatic =
      Args.hasArg(OPT_keep_func_for_static);

  if (opt::Arg *ReproducerPath = Args.getLastArg(OPT_use_reproducer)) {
    Options.ReproMode = ReproducerMode::Use;
    Options.ReproducerPath = ReproducerPath->getValue();
  }

  if (Args.hasArg(OPT_gen_reproducer))
    Options.ReproMode = ReproducerMode::Generate;

  if (Expected<AccelTableKind> AccelKind = getAccelTableKind(Args)) {
    Options.LinkOpts.TheAccelTableKind = *AccelKind;
  } else {
    return AccelKind.takeError();
  }

  if (opt::Arg *SymbolMap = Args.getLastArg(OPT_symbolmap))
    Options.SymbolMap = SymbolMap->getValue();

  if (Args.hasArg(OPT_symbolmap))
    Options.LinkOpts.Update = true;

  if (Expected<std::vector<std::string>> InputFiles =
          getInputs(Args, Options.LinkOpts.Update)) {
    Options.InputFiles = std::move(*InputFiles);
  } else {
    return InputFiles.takeError();
  }

  for (auto *Arch : Args.filtered(OPT_arch))
    Options.Archs.push_back(Arch->getValue());

  if (opt::Arg *OsoPrependPath = Args.getLastArg(OPT_oso_prepend_path))
    Options.LinkOpts.PrependPath = OsoPrependPath->getValue();

  for (const auto &Arg : Args.getAllArgValues(OPT_object_prefix_map)) {
    auto Split = StringRef(Arg).split('=');
    Options.LinkOpts.ObjectPrefixMap.insert(
        {std::string(Split.first), std::string(Split.second)});
  }

  if (opt::Arg *OutputFile = Args.getLastArg(OPT_output))
    Options.OutputFile = OutputFile->getValue();

  if (opt::Arg *Toolchain = Args.getLastArg(OPT_toolchain))
    Options.Toolchain = Toolchain->getValue();

  if (Args.hasArg(OPT_assembly))
    Options.LinkOpts.FileType = OutputFileType::Assembly;

  if (opt::Arg *NumThreads = Args.getLastArg(OPT_threads))
    Options.LinkOpts.Threads = atoi(NumThreads->getValue());
  else
    Options.LinkOpts.Threads = 0; // Use all available hardware threads

  if (Options.DumpDebugMap || Options.LinkOpts.Verbose)
    Options.LinkOpts.Threads = 1;

  if (getenv("RC_DEBUG_OPTIONS"))
    Options.PaperTrailWarnings = true;

  if (opt::Arg *RemarksPrependPath = Args.getLastArg(OPT_remarks_prepend_path))
    Options.LinkOpts.RemarksPrependPath = RemarksPrependPath->getValue();

  if (opt::Arg *RemarksOutputFormat =
          Args.getLastArg(OPT_remarks_output_format)) {
    if (Expected<remarks::Format> FormatOrErr =
            remarks::parseFormat(RemarksOutputFormat->getValue()))
      Options.LinkOpts.RemarksFormat = *FormatOrErr;
    else
      return FormatOrErr.takeError();
  }

  if (Error E = verifyOptions(Options))
    return std::move(E);
  return Options;
}

static Error createPlistFile(StringRef Bin, StringRef BundleRoot,
                             StringRef Toolchain) {
  // Create plist file to write to.
  SmallString<128> InfoPlist(BundleRoot);
  sys::path::append(InfoPlist, "Contents/Info.plist");
  std::error_code EC;
  raw_fd_ostream PL(InfoPlist, EC, sys::fs::OF_TextWithCRLF);
  if (EC)
    return make_error<StringError>(
        "cannot create Plist: " + toString(errorCodeToError(EC)), EC);

  CFBundleInfo BI = getBundleInfo(Bin);

  if (BI.IDStr.empty()) {
    StringRef BundleID = *sys::path::rbegin(BundleRoot);
    if (sys::path::extension(BundleRoot) == ".dSYM")
      BI.IDStr = std::string(sys::path::stem(BundleID));
    else
      BI.IDStr = std::string(BundleID);
  }

  // Print out information to the plist file.
  PL << "<?xml version=\"1.0\" encoding=\"UTF-8\"\?>\n"
     << "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
     << "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
     << "<plist version=\"1.0\">\n"
     << "\t<dict>\n"
     << "\t\t<key>CFBundleDevelopmentRegion</key>\n"
     << "\t\t<string>English</string>\n"
     << "\t\t<key>CFBundleIdentifier</key>\n"
     << "\t\t<string>com.apple.xcode.dsym.";
  printHTMLEscaped(BI.IDStr, PL);
  PL << "</string>\n"
     << "\t\t<key>CFBundleInfoDictionaryVersion</key>\n"
     << "\t\t<string>6.0</string>\n"
     << "\t\t<key>CFBundlePackageType</key>\n"
     << "\t\t<string>dSYM</string>\n"
     << "\t\t<key>CFBundleSignature</key>\n"
     << "\t\t<string>\?\?\?\?</string>\n";

  if (!BI.OmitShortVersion()) {
    PL << "\t\t<key>CFBundleShortVersionString</key>\n";
    PL << "\t\t<string>";
    printHTMLEscaped(BI.ShortVersionStr, PL);
    PL << "</string>\n";
  }

  PL << "\t\t<key>CFBundleVersion</key>\n";
  PL << "\t\t<string>";
  printHTMLEscaped(BI.VersionStr, PL);
  PL << "</string>\n";

  if (!Toolchain.empty()) {
    PL << "\t\t<key>Toolchain</key>\n";
    PL << "\t\t<string>";
    printHTMLEscaped(Toolchain, PL);
    PL << "</string>\n";
  }

  PL << "\t</dict>\n"
     << "</plist>\n";

  PL.close();
  return Error::success();
}

static Error createBundleDir(StringRef BundleBase) {
  SmallString<128> Bundle(BundleBase);
  sys::path::append(Bundle, "Contents", "Resources", "DWARF");
  if (std::error_code EC =
          create_directories(Bundle.str(), true, sys::fs::perms::all_all))
    return make_error<StringError>(
        "cannot create bundle: " + toString(errorCodeToError(EC)), EC);

  return Error::success();
}

static bool verify(StringRef OutputFile, StringRef Arch, bool Verbose) {
  if (OutputFile == "-") {
    WithColor::warning() << "verification skipped for " << Arch
                         << "because writing to stdout.\n";
    return true;
  }

  Expected<OwningBinary<Binary>> BinOrErr = createBinary(OutputFile);
  if (!BinOrErr) {
    WithColor::error() << OutputFile << ": " << toString(BinOrErr.takeError());
    return false;
  }

  Binary &Binary = *BinOrErr.get().getBinary();
  if (auto *Obj = dyn_cast<MachOObjectFile>(&Binary)) {
    raw_ostream &os = Verbose ? errs() : nulls();
    os << "Verifying DWARF for architecture: " << Arch << "\n";
    std::unique_ptr<DWARFContext> DICtx = DWARFContext::create(*Obj);
    DIDumpOptions DumpOpts;
    bool success = DICtx->verify(os, DumpOpts.noImplicitRecursion());
    if (!success)
      WithColor::error() << "verification failed for " << Arch << '\n';
    return success;
  }

  return false;
}

namespace {
struct OutputLocation {
  OutputLocation(std::string DWARFFile, Optional<std::string> ResourceDir = {})
      : DWARFFile(DWARFFile), ResourceDir(ResourceDir) {}
  /// This method is a workaround for older compilers.
  Optional<std::string> getResourceDir() const { return ResourceDir; }
  std::string DWARFFile;
  Optional<std::string> ResourceDir;
};
} // namespace

static Expected<OutputLocation>
getOutputFileName(StringRef InputFile, const DsymutilOptions &Options) {
  if (Options.OutputFile == "-")
    return OutputLocation(Options.OutputFile);

  // When updating, do in place replacement.
  if (Options.OutputFile.empty() &&
      (Options.LinkOpts.Update || !Options.SymbolMap.empty()))
    return OutputLocation(std::string(InputFile));

  // When dumping the debug map, just return an empty output location. This
  // allows us to compute the output location once.
  if (Options.DumpDebugMap)
    return OutputLocation("");

  // If a flat dSYM has been requested, things are pretty simple.
  if (Options.Flat) {
    if (Options.OutputFile.empty()) {
      if (InputFile == "-")
        return OutputLocation{"a.out.dwarf", {}};
      return OutputLocation((InputFile + ".dwarf").str());
    }

    return OutputLocation(Options.OutputFile);
  }

  // We need to create/update a dSYM bundle.
  // A bundle hierarchy looks like this:
  //   <bundle name>.dSYM/
  //       Contents/
  //          Info.plist
  //          Resources/
  //             DWARF/
  //                <DWARF file(s)>
  std::string DwarfFile =
      std::string(InputFile == "-" ? StringRef("a.out") : InputFile);
  SmallString<128> Path(Options.OutputFile);
  if (Path.empty())
    Path = DwarfFile + ".dSYM";
  if (!Options.LinkOpts.NoOutput) {
    if (auto E = createBundleDir(Path))
      return std::move(E);
    if (auto E = createPlistFile(DwarfFile, Path, Options.Toolchain))
      return std::move(E);
  }

  sys::path::append(Path, "Contents", "Resources");
  std::string ResourceDir = std::string(Path.str());
  sys::path::append(Path, "DWARF", sys::path::filename(DwarfFile));
  return OutputLocation(std::string(Path.str()), ResourceDir);
}

int main(int argc, char **argv) {
  InitLLVM X(argc, argv);

  // Parse arguments.
  DsymutilOptTable T;
  unsigned MAI;
  unsigned MAC;
  ArrayRef<const char *> ArgsArr = makeArrayRef(argv + 1, argc - 1);
  opt::InputArgList Args = T.ParseArgs(ArgsArr, MAI, MAC);

  void *P = (void *)(intptr_t)getOutputFileName;
  std::string SDKPath = sys::fs::getMainExecutable(argv[0], P);
  SDKPath = std::string(sys::path::parent_path(SDKPath));

  for (auto *Arg : Args.filtered(OPT_UNKNOWN)) {
    WithColor::warning() << "ignoring unknown option: " << Arg->getSpelling()
                         << '\n';
  }

  if (Args.hasArg(OPT_help)) {
    T.printHelp(
        outs(), (std::string(argv[0]) + " [options] <input files>").c_str(),
        "manipulate archived DWARF debug symbol files.\n\n"
        "dsymutil links the DWARF debug information found in the object files\n"
        "for the executable <input file> by using debug symbols information\n"
        "contained in its symbol table.\n",
        false);
    return EXIT_SUCCESS;
  }

  if (Args.hasArg(OPT_version)) {
    cl::PrintVersionMessage();
    return EXIT_SUCCESS;
  }

  auto OptionsOrErr = getOptions(Args);
  if (!OptionsOrErr) {
    WithColor::error() << toString(OptionsOrErr.takeError());
    return EXIT_FAILURE;
  }

  auto &Options = *OptionsOrErr;

  InitializeAllTargetInfos();
  InitializeAllTargetMCs();
  InitializeAllTargets();
  InitializeAllAsmPrinters();

  auto Repro =
      Reproducer::createReproducer(Options.ReproMode, Options.ReproducerPath);
  if (!Repro) {
    WithColor::error() << toString(Repro.takeError());
    return EXIT_FAILURE;
  }

  Options.LinkOpts.VFS = (*Repro)->getVFS();

  for (const auto &Arch : Options.Archs)
    if (Arch != "*" && Arch != "all" &&
        !object::MachOObjectFile::isValidArch(Arch)) {
      WithColor::error() << "unsupported cpu architecture: '" << Arch << "'\n";
      return EXIT_FAILURE;
    }

  SymbolMapLoader SymMapLoader(Options.SymbolMap);

  for (auto &InputFile : Options.InputFiles) {
    // Dump the symbol table for each input file and requested arch
    if (Options.DumpStab) {
      if (!dumpStab(Options.LinkOpts.VFS, InputFile, Options.Archs,
                    Options.LinkOpts.PrependPath))
        return EXIT_FAILURE;
      continue;
    }

    auto DebugMapPtrsOrErr =
        parseDebugMap(Options.LinkOpts.VFS, InputFile, Options.Archs,
                      Options.LinkOpts.PrependPath, Options.PaperTrailWarnings,
                      Options.LinkOpts.Verbose, Options.InputIsYAMLDebugMap);

    if (auto EC = DebugMapPtrsOrErr.getError()) {
      WithColor::error() << "cannot parse the debug map for '" << InputFile
                         << "': " << EC.message() << '\n';
      return EXIT_FAILURE;
    }

    // Remember the number of debug maps that are being processed to decide how
    // to name the remark files.
    Options.LinkOpts.NumDebugMaps = DebugMapPtrsOrErr->size();

    if (Options.LinkOpts.Update) {
      // The debug map should be empty. Add one object file corresponding to
      // the input file.
      for (auto &Map : *DebugMapPtrsOrErr)
        Map->addDebugMapObject(InputFile,
                               sys::TimePoint<std::chrono::seconds>());
    }

    // Ensure that the debug map is not empty (anymore).
    if (DebugMapPtrsOrErr->empty()) {
      WithColor::error() << "no architecture to link\n";
      return EXIT_FAILURE;
    }

    // Shared a single binary holder for all the link steps.
    BinaryHolder BinHolder(Options.LinkOpts.VFS);

    // Compute the output location and update the resource directory.
    Expected<OutputLocation> OutputLocationOrErr =
        getOutputFileName(InputFile, Options);
    if (!OutputLocationOrErr) {
      WithColor::error() << toString(OutputLocationOrErr.takeError());
      return EXIT_FAILURE;
    }
    Options.LinkOpts.ResourceDir = OutputLocationOrErr->getResourceDir();

    // Statistics only require different architectures to be processed
    // sequentially, the link itself can still happen in parallel. Change the
    // thread pool strategy here instead of modifying LinkOpts.Threads.
    ThreadPoolStrategy S = hardware_concurrency(
        Options.LinkOpts.Statistics ? 1 : Options.LinkOpts.Threads);
    if (Options.LinkOpts.Threads == 0) {
      // If NumThreads is not specified, create one thread for each input, up to
      // the number of hardware threads.
      S.ThreadsRequested = DebugMapPtrsOrErr->size();
      S.Limit = true;
    }
    ThreadPool Threads(S);

    // If there is more than one link to execute, we need to generate
    // temporary files.
    const bool NeedsTempFiles =
        !Options.DumpDebugMap && (Options.OutputFile != "-") &&
        (DebugMapPtrsOrErr->size() != 1 || Options.LinkOpts.Update);
    const bool Verify = Options.Verify && !Options.LinkOpts.NoOutput;

    SmallVector<MachOUtils::ArchAndFile, 4> TempFiles;
    std::atomic_char AllOK(1);
    for (auto &Map : *DebugMapPtrsOrErr) {
      if (Options.LinkOpts.Verbose || Options.DumpDebugMap)
        Map->print(outs());

      if (Options.DumpDebugMap)
        continue;

      if (!Options.SymbolMap.empty())
        Options.LinkOpts.Translator = SymMapLoader.Load(InputFile, *Map);

      if (Map->begin() == Map->end())
        WithColor::warning()
            << "no debug symbols in executable (-arch "
            << MachOUtils::getArchName(Map->getTriple().getArchName()) << ")\n";

      // Using a std::shared_ptr rather than std::unique_ptr because move-only
      // types don't work with std::bind in the ThreadPool implementation.
      std::shared_ptr<raw_fd_ostream> OS;

      std::string OutputFile = OutputLocationOrErr->DWARFFile;
      if (NeedsTempFiles) {
        TempFiles.emplace_back(Map->getTriple().getArchName().str());

        auto E = TempFiles.back().createTempFile();
        if (E) {
          WithColor::error() << toString(std::move(E));
          return EXIT_FAILURE;
        }

        auto &TempFile = *(TempFiles.back().File);
        OS = std::make_shared<raw_fd_ostream>(TempFile.FD,
                                              /*shouldClose*/ false);
        OutputFile = TempFile.TmpName;
      } else {
        std::error_code EC;
        OS = std::make_shared<raw_fd_ostream>(
            Options.LinkOpts.NoOutput ? "-" : OutputFile, EC, sys::fs::OF_None);
        if (EC) {
          WithColor::error() << OutputFile << ": " << EC.message();
          return EXIT_FAILURE;
        }
      }

      auto LinkLambda = [&, OutputFile](std::shared_ptr<raw_fd_ostream> Stream,
                                        LinkOptions Options) {
        AllOK.fetch_and(
            linkDwarf(*Stream, BinHolder, *Map, std::move(Options)));
        Stream->flush();
        if (Verify)
          AllOK.fetch_and(verify(OutputFile, Map->getTriple().getArchName(),
                                 Options.Verbose));
      };

      // FIXME: The DwarfLinker can have some very deep recursion that can max
      // out the (significantly smaller) stack when using threads. We don't
      // want this limitation when we only have a single thread.
      if (S.ThreadsRequested == 1)
        LinkLambda(OS, Options.LinkOpts);
      else
        Threads.async(LinkLambda, OS, Options.LinkOpts);
    }

    Threads.wait();

    if (!AllOK)
      return EXIT_FAILURE;

    if (NeedsTempFiles) {
      if (!MachOUtils::generateUniversalBinary(TempFiles,
                                               OutputLocationOrErr->DWARFFile,
                                               Options.LinkOpts, SDKPath))
        return EXIT_FAILURE;
    }

    // The Mach-O object file format is limited to 4GB. Make sure that we print
    // an error when we emit an invalid Mach-O companion file. Leave the
    // invalid object file around on disk for inspection.
    ErrorOr<vfs::Status> stat =
        Options.LinkOpts.VFS->status(OutputLocationOrErr->DWARFFile);
    if (stat) {
      if (stat->getSize() > std::numeric_limits<uint32_t>::max()) {
        WithColor::error() << "the linked debug info exceeds the 4GB Mach-O "
                              "object file format.";
        return EXIT_FAILURE;
      }
    }
  }

  return EXIT_SUCCESS;
}
