//===-- IntegAssembler.cpp ------------------------------------------------===//
//
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
//===----------------------------------------------------------------------===//
//
// Gollvm driver helper class "IntegAssembler" methods.
//
//===----------------------------------------------------------------------===//

#include "IntegAssembler.h"

#include "go-llvm-linemap.h"
#include "go-llvm-diagnostics.h"
#include "go-llvm.h"
#include "go-c.h"
#include "mpfr.h"
#include "GollvmOptions.h"
#include "GollvmConfig.h"
#include "GollvmPasses.h"

#include "Action.h"
#include "Artifact.h"
#include "Driver.h"
#include "ToolChain.h"

#include "llvm/ADT/Triple.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"

#include <sstream>

using namespace llvm;

namespace gollvm {
namespace driver {

class IntegAssemblerImpl {
 public:
  IntegAssemblerImpl(IntegAssembler &ia, ToolChain &tc, const std::string &executablePath);

  // Perform compilation.
  bool performAction(Compilation &compilation,
                     const Action &jobAction,
                     const ArtifactList &inputArtifacts,
                     const Artifact &output);

 private:
  IntegAssembler &ia_;
  Triple triple_;
  const ToolChain &toolchain_;
  Driver &driver_;
  LLVMContext context_;
  const char *progname_;
  std::string executablePath_;
  opt::InputArgList &args_;
  std::string inputFileName_;
  std::string objOutFileName_;
  std::unique_ptr<raw_fd_ostream> objout_;

  bool resolveInputOutput(const Action &jobAction,
                          const ArtifactList &inputArtifacts,
                          const Artifact &output);
  bool invokeAssembler();
};

IntegAssemblerImpl::IntegAssemblerImpl(IntegAssembler &ia, ToolChain &tc, const std::string &executablePath)
    : ia_(ia),
      triple_(tc.driver().triple()),
      toolchain_(tc),
      driver_(tc.driver()),
      progname_(tc.driver().progname()),
      executablePath_(executablePath),
      args_(tc.driver().args())
{
  InitializeAllTargets();
  InitializeAllTargetMCs();
  InitializeAllAsmPrinters();
  InitializeAllAsmParsers();
}

bool IntegAssemblerImpl::resolveInputOutput(const Action &jobAction,
                                            const ArtifactList &inputArtifacts,
                                            const Artifact &output)
{
  // Collect input file. Should be only one.
  if (inputArtifacts.size() != 1) {
    errs() << progname_ << ": expected exactly one input file, "
           << inputArtifacts.size() << " provided.\n";
    return false;
  }
  inputFileName_ = inputArtifacts[0]->file();
  objOutFileName_ = output.file();

  // Remove output on signal.
  if (objOutFileName_ != "-")
    sys::RemoveFileOnSignal(objOutFileName_);

  // Open output file.
  std::error_code EC;
  sys::fs::OpenFlags OpenFlags = sys::fs::OF_None;
  objout_ = std::make_unique<raw_fd_ostream>(
      objOutFileName_, EC, OpenFlags);
  if (EC) {
    errs() << progname_ << ": error opening " << objOutFileName_ << ": "
           << EC.message() << '\n';
    return false;
  }
  return true;
}

bool IntegAssemblerImpl::invokeAssembler()
{
  // Get the target specific parser.
  std::string Error;
  const Target *TheTarget = TargetRegistry::lookupTarget("", triple_, Error);
  if (!TheTarget) {
    errs() << progname_ << ": unknown/unsupported target "
           << triple_.str() << "\n";
    return false;
  }

  ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer =
      MemoryBuffer::getFileOrSTDIN(inputFileName_);
  if (std::error_code EC = Buffer.getError()) {
    Error = EC.message();
    errs() << progname_ << ": opening/reading " << inputFileName_ << ": "
           << EC.message() << "\n";
    return false;
  }

  auto Trip = triple_.str();
  SourceMgr SrcMgr;

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(std::move(*Buffer), SMLoc());

  // Record the location of the include directories so that the lexer can find
  // it later.
  SrcMgr.setIncludeDirs(driver_.args().getAllArgValues(gollvm::options::OPT_I));

  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Trip));
  assert(MRI && "Unable to create target register info!");

  MCTargetOptions MCOptions;
  std::unique_ptr<MCAsmInfo> MAI(
      TheTarget->createMCAsmInfo(*MRI, Trip, MCOptions));
  assert(MAI && "Unable to create target asm info!");

  // Note: -Xassembler and -Wa, options should already have been
  // examined at this point.

  // FIXME: no support yet for -march (bring over from CompileGo.cpp)
  opt::Arg *cpuarg = args_.getLastArg(gollvm::options::OPT_march_EQ);
  if (cpuarg != nullptr) {
    errs() << progname_ << ": internal error: option '"
           <<  cpuarg->getAsString(args_)
           << "' not yet implemented in integrated assembler\n";
    assert(false);
    return false;
  }

  // Support for compressed debug.
  llvm::DebugCompressionType CompressDebugSections =
      llvm::DebugCompressionType::None;
  if (!driver_.determineDebugCompressionType(&CompressDebugSections))
    return false;

  // Ensure MCAsmInfo initialization occurs before any use, otherwise sections
  // may be created with a combination of default and explicit settings.
  MAI->setCompressDebugSections(CompressDebugSections);

  // Build up the feature string from the target feature list.
  std::string FS;
  std::string CPU;
  std::unique_ptr<MCStreamer> Str;
  std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
  std::unique_ptr<MCSubtargetInfo> STI(
      TheTarget->createMCSubtargetInfo(Trip, CPU, FS));

  MCContext Ctx(triple_, MAI.get(), MRI.get(), STI.get(), &SrcMgr, &MCOptions);

  bool PIC = (driver_.getPicLevel() != PICLevel::NotPIC);
  Ctx.setGenDwarfForAssembly(true);

  // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
  // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
  std::unique_ptr<MCObjectFileInfo> MOFI(
      TheTarget->createMCObjectFileInfo(Ctx, PIC));
  Ctx.setObjectFileInfo(MOFI.get());

  // Use current dir (llvm-goc does not yet support -fdebug-compilation-dir)
  SmallString<128> CWD;
  if (!sys::fs::current_path(CWD))
    Ctx.setCompilationDir(CWD);

  // Honor -fdebug-prefix=... option.
  for (const auto &arg : driver_.args().getAllArgValues(gollvm::options::OPT_fdebug_prefix_map_EQ)) {
    std::pair<StringRef, StringRef> p = StringRef(arg).split('=');
    Ctx.addDebugPrefixMapEntry(std::string(p.first), std::string(p.second));
  }


  StringRef BaseName = llvm::sys::path::filename(inputFileName_);
  Ctx.setMainFileName(BaseName);
  // FIXME: incorporate version here?
  Ctx.setDwarfDebugProducer("llvm-goc");

  raw_pwrite_stream *Out = objout_.get();
  std::unique_ptr<buffer_ostream> BOS;

  if (!objout_->supportsSeeking()) {
    BOS = std::make_unique<buffer_ostream>(*objout_);
    Out = BOS.get();
  }

  std::unique_ptr<MCCodeEmitter> CE(
      TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx));
  std::unique_ptr<MCAsmBackend> MAB(
      TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions));
  std::unique_ptr<MCObjectWriter> OW = MAB->createObjectWriter(*Out);

  Triple T(driver_.triple());
  unsigned RelaxAll = 0;
  unsigned IncrementalLinkerCompatible = 0;
  Str.reset(TheTarget->createMCObjectStreamer(
      T, Ctx, std::move(MAB), std::move(OW), std::move(CE), *STI,
      RelaxAll, IncrementalLinkerCompatible,
        /*DWARFMustBeAtTheEnd*/ true));

  bool NoExecStack = true;
  Str.get()->InitSections(NoExecStack);

  // Assembly to object compilation should leverage assembly info.
  Str->setUseAssemblerInfoForParsing(true);

  std::unique_ptr<MCAsmParser> Parser(
      createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI));

  std::unique_ptr<MCTargetAsmParser> TAP(
      TheTarget->createMCAsmParser(*STI, *Parser, *MCII, MCOptions));
  if (!TAP) {
    errs() << progname_ << ": error: unknown triple"
           << triple_.str() << "\n";
    return false;
  }

  // FIXME: add support for -Wa,-defsym here?

  Parser->setTargetParser(*TAP.get());
  bool NoInitialTextSection = false;
  auto Failed = Parser->Run(NoInitialTextSection);

  // Close Streamer first.
  // It might have a reference to the output stream.
  Str.reset();
  // Close the output stream early.
  BOS.reset();
  objout_.reset();

  // Delete output file if there were errors.
  if (Failed) {
    if (objOutFileName_ != "-")
      sys::fs::remove(objOutFileName_);
  }

  return !Failed;
}

bool IntegAssemblerImpl::performAction(Compilation &compilation,
                                  const Action &jobAction,
                                  const ArtifactList &inputArtifacts,
                                  const Artifact &output)
{
  if (ia_.emitMinusVOrHashHashHash(triple_, output, jobAction))
    return true;

  // Resolve input/output files.
  if (!resolveInputOutput(jobAction, inputArtifacts, output))
    return false;

  // Invoke back end
  if (!invokeAssembler())
    return false;

  return true;
}

//........................................................................

IntegAssembler::IntegAssembler(ToolChain &tc, const std::string &executablePath)
    : InternalTool("integassembler", tc, executablePath),
      impl_(new IntegAssemblerImpl(*this, tc, executablePath))
{
}

IntegAssembler::~IntegAssembler()
{
}

bool IntegAssembler::performAction(Compilation &compilation,
                              const Action &jobAction,
                              const ArtifactList &inputArtifacts,
                              const Artifact &output)
{
  return impl_->performAction(compilation, jobAction, inputArtifacts, output);
}


} // end namespace driver
} // end namespace gollvm
