//===- Linker.cpp ---------------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <mcld/Linker.h>
#include <mcld/LinkerConfig.h>
#include <mcld/Module.h>
#include <mcld/IRBuilder.h>

#include <mcld/Support/MsgHandling.h>
#include <mcld/Support/TargetRegistry.h>
#include <mcld/Support/FileHandle.h>
#include <mcld/Support/MemoryArea.h>
#include <mcld/Support/raw_ostream.h>

#include <mcld/Object/ObjectLinker.h>
#include <mcld/MC/InputBuilder.h>
#include <mcld/Target/TargetLDBackend.h>
#include <mcld/LD/LDSection.h>
#include <mcld/LD/LDSymbol.h>
#include <mcld/LD/SectionData.h>
#include <mcld/LD/RelocData.h>
#include <mcld/Fragment/Relocation.h>
#include <mcld/Fragment/FragmentRef.h>

#include <cassert>

using namespace mcld;

Linker::Linker()
  : m_pConfig(NULL), m_pModule(NULL), m_pIRBuilder(NULL),
    m_pTarget(NULL), m_pBackend(NULL), m_pObjLinker(NULL) {
}

Linker::~Linker()
{
  reset();
}

bool Linker::config(LinkerConfig& pConfig)
{
  m_pConfig = &pConfig;

  if (!initTarget())
    return false;

  if (!initBackend())
    return false;

  if (!initEmulator())
    return false;

  if (!initOStream())
    return false;

  return true;
}

bool Linker::link(Module& pModule, IRBuilder& pBuilder)
{
  assert(NULL != m_pConfig);

  m_pIRBuilder = &pBuilder;
  m_pObjLinker = new ObjectLinker(*m_pConfig,
                                  pModule,
                                  *m_pIRBuilder,
                                  *m_pBackend);

  // 2. - initialize FragmentLinker
  if (!m_pObjLinker->initFragmentLinker())
    return false;

  // 3. - initialize output's standard sections
  if (!m_pObjLinker->initStdSections())
    return false;

  // 4. - normalize the input tree
  m_pObjLinker->normalize();

  if (m_pConfig->options().trace()) {
    static int counter = 0;
    mcld::outs() << "** name\ttype\tpath\tsize (" << pModule.getInputTree().size() << ")\n";
    InputTree::const_dfs_iterator input, inEnd = pModule.getInputTree().dfs_end();
    for (input=pModule.getInputTree().dfs_begin(); input!=inEnd; ++input) {
      mcld::outs() << counter++ << " *  " << (*input)->name();
      switch((*input)->type()) {
      case Input::Archive:
        mcld::outs() << "\tarchive\t(";
        break;
      case Input::Object:
        mcld::outs() << "\tobject\t(";
        break;
      case Input::DynObj:
        mcld::outs() << "\tshared\t(";
        break;
      case Input::Script:
        mcld::outs() << "\tscript\t(";
        break;
      case Input::External:
        mcld::outs() << "\textern\t(";
        break;
      default:
        unreachable(diag::err_cannot_trace_file) << (*input)->type()
                                                 << (*input)->name()
                                                 << (*input)->path();
      }
      mcld::outs() << (*input)->path() << ")\n";
    }
  }

  // 5. - check if we can do static linking and if we use split-stack.
  if (!m_pObjLinker->linkable())
    return Diagnose();

  // 6. - read all relocation entries from input files
  m_pObjLinker->readRelocations();

  // 7. - merge all sections
  if (!m_pObjLinker->mergeSections())
    return false;

  // 8. - add standard symbols and target-dependent symbols
  // m_pObjLinker->addUndefSymbols();
  if (!m_pObjLinker->addStandardSymbols() ||
      !m_pObjLinker->addTargetSymbols())
    return false;

  // 9. - scan all relocation entries by output symbols.
  m_pObjLinker->scanRelocations();

  // 10.a - pre-layout
  m_pObjLinker->prelayout();

  // 10.b - linear layout
  m_pObjLinker->layout();

  // 10.c - post-layout (create segment, instruction relaxing)
  m_pObjLinker->postlayout();

  // 11. - finalize symbol value
  m_pObjLinker->finalizeSymbolValue();

  // 12. - apply relocations
  m_pObjLinker->relocation();

  if (!Diagnose())
    return false;
  return true;
}

bool Linker::emit(MemoryArea& pOutput)
{
  // 13. - write out output
  m_pObjLinker->emitOutput(pOutput);

  // 14. - post processing
  m_pObjLinker->postProcessing(pOutput);

  if (!Diagnose())
    return false;

  return true;
}

bool Linker::emit(const std::string& pPath)
{
  FileHandle file;
  FileHandle::Permission perm = 0755;
  if (!file.open(pPath,
            FileHandle::ReadWrite | FileHandle::Truncate | FileHandle::Create,
            perm)) {
    error(diag::err_cannot_open_output_file) << "Linker::emit()" << pPath;
    return false;
  }

  MemoryArea* output = new MemoryArea(file);

  bool result = emit(*output);

  delete output;
  file.close();
  return result;
}

bool Linker::emit(int pFileDescriptor)
{
  FileHandle file;
  file.delegate(pFileDescriptor);
  MemoryArea* output = new MemoryArea(file);

  bool result = emit(*output);

  delete output;
  file.close();
  return result;
}

bool Linker::reset()
{
  m_pConfig = NULL;
  m_pModule = NULL;
  m_pIRBuilder = NULL;
  m_pTarget = NULL;

  // Because llvm::iplist will touch the removed node, we must clear
  // RelocData before deleting target backend.
  RelocData::Clear();
  SectionData::Clear();

  delete m_pBackend;
  m_pBackend = NULL;

  delete m_pObjLinker;
  m_pObjLinker = NULL;

  LDSection::Clear();
  LDSymbol::Clear();
  FragmentRef::Clear();
  Relocation::Clear();
  return true;
}

bool Linker::initTarget()
{
  assert(NULL != m_pConfig);

  std::string error;
  m_pTarget = mcld::TargetRegistry::lookupTarget(m_pConfig->targets().triple().str(), error);
  if (NULL == m_pTarget) {
    fatal(diag::fatal_cannot_init_target) << m_pConfig->targets().triple().str() << error;
    return false;
  }
  return true;
}

bool Linker::initBackend()
{
  assert(NULL != m_pTarget);
  m_pBackend = m_pTarget->createLDBackend(*m_pConfig);
  if (NULL == m_pBackend) {
    fatal(diag::fatal_cannot_init_backend) << m_pConfig->targets().triple().str();
    return false;
  }
  return true;
}

bool Linker::initEmulator()
{
  assert(NULL != m_pTarget && NULL != m_pConfig);
  bool result = m_pTarget->emulate(m_pConfig->targets().triple().str(),
                                   *m_pConfig);

  // Relocation should be set up after emulation.
  Relocation::SetUp(*m_pConfig);
  return result;
}

bool Linker::initOStream()
{
  assert(NULL != m_pConfig);

  mcld::outs().setColor(m_pConfig->options().color());
  mcld::errs().setColor(m_pConfig->options().color());

  return true;
}

