//===-- FuzzerCLI.cpp -----------------------------------------------------===//
//
// 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 "llvm/FuzzMutate/FuzzerCLI.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Verifier.h"

using namespace llvm;

void llvm::parseFuzzerCLOpts(int ArgC, char *ArgV[]) {
  std::vector<const char *> CLArgs;
  CLArgs.push_back(ArgV[0]);

  int I = 1;
  while (I < ArgC)
    if (StringRef(ArgV[I++]).equals("-ignore_remaining_args=1"))
      break;
  while (I < ArgC)
    CLArgs.push_back(ArgV[I++]);

  cl::ParseCommandLineOptions(CLArgs.size(), CLArgs.data());
}

void llvm::handleExecNameEncodedBEOpts(StringRef ExecName) {
  std::vector<std::string> Args{std::string(ExecName)};

  auto NameAndArgs = ExecName.split("--");
  if (NameAndArgs.second.empty())
    return;

  SmallVector<StringRef, 4> Opts;
  NameAndArgs.second.split(Opts, '-');
  for (StringRef Opt : Opts) {
    if (Opt.equals("gisel")) {
      Args.push_back("-global-isel");
      // For now we default GlobalISel to -O0
      Args.push_back("-O0");
    } else if (Opt.startswith("O")) {
      Args.push_back("-" + Opt.str());
    } else if (Triple(Opt).getArch()) {
      Args.push_back("-mtriple=" + Opt.str());
    } else {
      errs() << ExecName << ": Unknown option: " << Opt << ".\n";
      exit(1);
    }
  }
  errs() << NameAndArgs.first << ": Injected args:";
  for (int I = 1, E = Args.size(); I < E; ++I)
    errs() << " " << Args[I];
  errs() << "\n";

  std::vector<const char *> CLArgs;
  CLArgs.reserve(Args.size());
  for (std::string &S : Args)
    CLArgs.push_back(S.c_str());

  cl::ParseCommandLineOptions(CLArgs.size(), CLArgs.data());
}

void llvm::handleExecNameEncodedOptimizerOpts(StringRef ExecName) {
  // TODO: Refactor parts common with the 'handleExecNameEncodedBEOpts'
  std::vector<std::string> Args{std::string(ExecName)};

  auto NameAndArgs = ExecName.split("--");
  if (NameAndArgs.second.empty())
    return;

  SmallVector<StringRef, 4> Opts;
  NameAndArgs.second.split(Opts, '-');
  for (StringRef Opt : Opts) {
    if (Opt == "instcombine") {
      Args.push_back("-passes=instcombine");
    } else if (Opt == "earlycse") {
      Args.push_back("-passes=early-cse");
    } else if (Opt == "simplifycfg") {
      Args.push_back("-passes=simplifycfg");
    } else if (Opt == "gvn") {
      Args.push_back("-passes=gvn");
    } else if (Opt == "sccp") {
      Args.push_back("-passes=sccp");

    } else if (Opt == "loop_predication") {
      Args.push_back("-passes=loop-predication");
    } else if (Opt == "guard_widening") {
      Args.push_back("-passes=guard-widening");
    } else if (Opt == "loop_rotate") {
      Args.push_back("-passes=loop(rotate)");
    } else if (Opt == "loop_unswitch") {
      Args.push_back("-passes=loop(simple-loop-unswitch)");
    } else if (Opt == "loop_unroll") {
      Args.push_back("-passes=unroll");
    } else if (Opt == "loop_vectorize") {
      Args.push_back("-passes=loop-vectorize");
    } else if (Opt == "licm") {
      Args.push_back("-passes=licm");
    } else if (Opt == "indvars") {
      Args.push_back("-passes=indvars");
    } else if (Opt == "strength_reduce") {
      Args.push_back("-passes=loop-reduce");
    } else if (Opt == "irce") {
      Args.push_back("-passes=irce");

    } else if (Triple(Opt).getArch()) {
      Args.push_back("-mtriple=" + Opt.str());
    } else {
      errs() << ExecName << ": Unknown option: " << Opt << ".\n";
      exit(1);
    }
  }

  errs() << NameAndArgs.first << ": Injected args:";
  for (int I = 1, E = Args.size(); I < E; ++I)
    errs() << " " << Args[I];
  errs() << "\n";

  std::vector<const char *> CLArgs;
  CLArgs.reserve(Args.size());
  for (std::string &S : Args)
    CLArgs.push_back(S.c_str());

  cl::ParseCommandLineOptions(CLArgs.size(), CLArgs.data());
}

int llvm::runFuzzerOnInputs(int ArgC, char *ArgV[], FuzzerTestFun TestOne,
                            FuzzerInitFun Init) {
  errs() << "*** This tool was not linked to libFuzzer.\n"
         << "*** No fuzzing will be performed.\n";
  if (int RC = Init(&ArgC, &ArgV)) {
    errs() << "Initialization failed\n";
    return RC;
  }

  for (int I = 1; I < ArgC; ++I) {
    StringRef Arg(ArgV[I]);
    if (Arg.startswith("-")) {
      if (Arg.equals("-ignore_remaining_args=1"))
        break;
      continue;
    }

    auto BufOrErr = MemoryBuffer::getFile(Arg, /*IsText=*/false,
                                          /*RequiresNullTerminator=*/false);
    if (std::error_code EC = BufOrErr.getError()) {
      errs() << "Error reading file: " << Arg << ": " << EC.message() << "\n";
      return 1;
    }
    std::unique_ptr<MemoryBuffer> Buf = std::move(BufOrErr.get());
    errs() << "Running: " << Arg << " (" << Buf->getBufferSize() << " bytes)\n";
    TestOne(reinterpret_cast<const uint8_t *>(Buf->getBufferStart()),
            Buf->getBufferSize());
  }
  return 0;
}

std::unique_ptr<Module> llvm::parseModule(
    const uint8_t *Data, size_t Size, LLVMContext &Context) {

  if (Size <= 1)
    // We get bogus data given an empty corpus - just create a new module.
    return std::make_unique<Module>("M", Context);

  auto Buffer = MemoryBuffer::getMemBuffer(
      StringRef(reinterpret_cast<const char *>(Data), Size), "Fuzzer input",
      /*RequiresNullTerminator=*/false);

  SMDiagnostic Err;
  auto M = parseBitcodeFile(Buffer->getMemBufferRef(), Context);
  if (Error E = M.takeError()) {
    errs() << toString(std::move(E)) << "\n";
    return nullptr;
  }
  return std::move(M.get());
}

size_t llvm::writeModule(const Module &M, uint8_t *Dest, size_t MaxSize) {
  std::string Buf;
  {
    raw_string_ostream OS(Buf);
    WriteBitcodeToFile(M, OS);
  }
  if (Buf.size() > MaxSize)
      return 0;
  memcpy(Dest, Buf.data(), Buf.size());
  return Buf.size();
}

std::unique_ptr<Module> llvm::parseAndVerify(const uint8_t *Data, size_t Size,
                                             LLVMContext &Context) {
  auto M = parseModule(Data, Size, Context);
  if (!M || verifyModule(*M, &errs()))
    return nullptr;

  return M;
}
