//===- DriverDispatcher.cpp - Support using LLD as a library --------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "lld/Common/CommonLinkerContext.h"
#include "lld/Common/Driver.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Memory.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/TargetParser/Host.h"
#include "llvm/TargetParser/Triple.h"
#include <cstdlib>

using namespace lld;
using namespace llvm;
using namespace llvm::sys;

static void err(const Twine &s) { llvm::errs() << s << "\n"; }

static Flavor getFlavor(StringRef s) {
  return StringSwitch<Flavor>(s)
      .CasesLower("ld", "ld.lld", "gnu", Gnu)
      .CasesLower("wasm", "ld-wasm", Wasm)
      .CaseLower("link", WinLink)
      .CasesLower("ld64", "ld64.lld", "darwin", Darwin)
      .Default(Invalid);
}

static cl::TokenizerCallback getDefaultQuotingStyle() {
  if (Triple(sys::getProcessTriple()).getOS() == Triple::Win32)
    return cl::TokenizeWindowsCommandLine;
  return cl::TokenizeGNUCommandLine;
}

static bool isPETargetName(StringRef s) {
  return s == "i386pe" || s == "i386pep" || s == "thumb2pe" || s == "arm64pe" ||
         s == "arm64ecpe";
}

static std::optional<bool> isPETarget(llvm::ArrayRef<const char *> args) {
  for (auto it = args.begin(); it + 1 != args.end(); ++it) {
    if (StringRef(*it) != "-m")
      continue;
    return isPETargetName(*(it + 1));
  }

  // Expand response files (arguments in the form of @<filename>)
  // to allow detecting the -m argument from arguments in them.
  SmallVector<const char *, 256> expandedArgs(args.data(),
                                              args.data() + args.size());
  BumpPtrAllocator a;
  StringSaver saver(a);
  cl::ExpansionContext ectx(saver.getAllocator(), getDefaultQuotingStyle());
  if (Error e = ectx.expandResponseFiles(expandedArgs)) {
    err(toString(std::move(e)));
    return std::nullopt;
  }

  for (auto it = expandedArgs.begin(); it + 1 != expandedArgs.end(); ++it) {
    if (StringRef(*it) != "-m")
      continue;
    return isPETargetName(*(it + 1));
  }

#ifdef LLD_DEFAULT_LD_LLD_IS_MINGW
  return true;
#else
  return false;
#endif
}

static Flavor parseProgname(StringRef progname) {
  // Use GNU driver for "ld" by default.
  if (progname == "ld")
    return Gnu;

  // Progname may be something like "lld-gnu". Parse it.
  SmallVector<StringRef, 3> v;
  progname.split(v, "-");
  for (StringRef s : v)
    if (Flavor f = getFlavor(s))
      return f;
  return Invalid;
}

static Flavor
parseFlavorWithoutMinGW(llvm::SmallVectorImpl<const char *> &argsV) {
  // Parse -flavor option.
  if (argsV.size() > 1 && argsV[1] == StringRef("-flavor")) {
    if (argsV.size() <= 2) {
      err("missing arg value for '-flavor'");
      return Invalid;
    }
    Flavor f = getFlavor(argsV[2]);
    if (f == Invalid) {
      err("Unknown flavor: " + StringRef(argsV[2]));
      return Invalid;
    }
    argsV.erase(argsV.begin() + 1, argsV.begin() + 3);
    return f;
  }

  // Deduct the flavor from argv[0].
  StringRef arg0 = path::filename(argsV[0]);
  arg0.consume_back_insensitive(".exe");
  Flavor f = parseProgname(arg0);
  if (f == Invalid) {
    err("lld is a generic driver.\n"
        "Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-ld"
        " (WebAssembly) instead");
    return Invalid;
  }
  return f;
}

static Flavor parseFlavor(llvm::SmallVectorImpl<const char *> &argsV) {
  Flavor f = parseFlavorWithoutMinGW(argsV);
  if (f == Gnu) {
    auto isPE = isPETarget(argsV);
    if (!isPE)
      return Invalid;
    if (*isPE)
      return MinGW;
  }
  return f;
}

static Driver whichDriver(llvm::SmallVectorImpl<const char *> &argsV,
                          llvm::ArrayRef<DriverDef> drivers) {
  Flavor f = parseFlavor(argsV);
  auto it =
      llvm::find_if(drivers, [=](auto &driverdef) { return driverdef.f == f; });
  if (it == drivers.end()) {
    // Driver is invalid or not available in this build.
    return [](llvm::ArrayRef<const char *>, llvm::raw_ostream &,
              llvm::raw_ostream &, bool, bool) { return false; };
  }
  return it->d;
}

namespace lld {
bool inTestOutputDisabled = false;

/// Universal linker main(). This linker emulates the gnu, darwin, or
/// windows linker based on the argv[0] or -flavor option.
int unsafeLldMain(llvm::ArrayRef<const char *> args,
                  llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS,
                  llvm::ArrayRef<DriverDef> drivers, bool exitEarly) {
  SmallVector<const char *, 256> argsV(args);
  Driver d = whichDriver(argsV, drivers);
  // Run the driver. If an error occurs, false will be returned.
  int r = !d(argsV, stdoutOS, stderrOS, exitEarly, inTestOutputDisabled);
  // At this point 'r' is either 1 for error, and 0 for no error.

  // Call exit() if we can to avoid calling destructors.
  if (exitEarly)
    exitLld(r);

  // Delete the global context and clear the global context pointer, so that it
  // cannot be accessed anymore.
  CommonLinkerContext::destroy();

  return r;
}
} // namespace lld

Result lld::lldMain(llvm::ArrayRef<const char *> args,
                    llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS,
                    llvm::ArrayRef<DriverDef> drivers) {
  int r = 0;
  {
    // The crash recovery is here only to be able to recover from arbitrary
    // control flow when fatal() is called (through setjmp/longjmp or
    // __try/__except).
    llvm::CrashRecoveryContext crc;
    if (!crc.RunSafely([&]() {
          r = unsafeLldMain(args, stdoutOS, stderrOS, drivers,
                            /*exitEarly=*/false);
        }))
      return {crc.RetCode, /*canRunAgain=*/false};
  }

  // Cleanup memory and reset everything back in pristine condition. This path
  // is only taken when LLD is in test, or when it is used as a library.
  llvm::CrashRecoveryContext crc;
  if (!crc.RunSafely([&]() { CommonLinkerContext::destroy(); })) {
    // The memory is corrupted beyond any possible recovery.
    return {r, /*canRunAgain=*/false};
  }
  return {r, /*canRunAgain=*/true};
}
