//===- ObjectLinker.h -----------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// ObjectLinker plays the same role as GNU collect2 to prepare all implicit
// parameters for FragmentLinker.
//
//===----------------------------------------------------------------------===//
#ifndef MCLD_OBJECT_OBJECT_LINKER_H
#define MCLD_OBJECT_OBJECT_LINKER_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
#include <stddef.h>

namespace mcld {

class Module;
class LinkerConfig;
class InputBuilder;
class FragmentLinker;
class TargetLDBackend;
class MemoryArea;
class MemoryAreaFactory;
class ObjectReader;
class DynObjReader;
class ArchiveReader;
class GroupReader;
class ObjectWriter;
class DynObjWriter;
class ExecWriter;

/** \class ObjectLinker
 *  \brief ObjectLinker prepares parameters for FragmentLinker.
 */
class ObjectLinker
{
public:
  ObjectLinker(const LinkerConfig& pConfig,
               Module& pModule,
               InputBuilder& pInputBuilder,
               TargetLDBackend& pLDBackend);

  ~ObjectLinker();

  /// initFragmentLinker - initialize FragmentLinker
  ///  Connect all components in FragmentLinker
  bool initFragmentLinker();

  /// initStdSections - initialize standard sections of the output file.
  bool initStdSections();

  /// normalize - normalize the input files
  void normalize();

  /// linkable - check the linkability of current LinkerConfig
  ///  Check list:
  ///  - check the Attributes are not violate the constaint
  ///  - check every Input has a correct Attribute
  bool linkable() const;

  /// readRelocations - read all relocation entries
  bool readRelocations();

  /// mergeSections - put allinput sections into output sections
  bool mergeSections();

  /// addStandardSymbols - shared object and executable files need some
  /// standard symbols
  ///   @return if there are some input symbols with the same name to the
  ///   standard symbols, return false
  bool addStandardSymbols();

  /// addTargetSymbols - some targets, such as MIPS and ARM, need some
  /// target-dependent symbols
  ///   @return if there are some input symbols with the same name to the
  ///   target symbols, return false
  bool addTargetSymbols();

  /// scanRelocations - scan all relocation entries by output symbols.
  bool scanRelocations();

  /// prelayout - help backend to do some modification before layout
  bool prelayout();

  /// layout - linearly layout all output sections and reserve some space
  /// for GOT/PLT
  ///   Because we do not support instruction relaxing in this early version,
  ///   if there is a branch can not jump to its target, we return false
  ///   directly
  bool layout();

  /// postlayout - help backend to do some modification after layout
  bool postlayout();

  /// relocate - applying relocation entries and create relocation
  /// section in the output files
  /// Create relocation section, asking TargetLDBackend to
  /// read the relocation information into RelocationEntry
  /// and push_back into the relocation section
  bool relocation();

  /// finalizeSymbolValue - finalize the symbol value
  bool finalizeSymbolValue();

  /// emitOutput - emit the output file.
  bool emitOutput(MemoryArea& pOutput);

  /// postProcessing - do modificatiion after all processes
  bool postProcessing(MemoryArea& pOutput);

  /// getLinker - get internal FragmentLinker object
  const FragmentLinker* getLinker() const { return m_pLinker; }
  FragmentLinker*       getLinker()       { return m_pLinker; }

  /// hasInitLinker - has Linker been initialized?
  bool hasInitLinker() const
  { return (NULL != m_pLinker); }

  // -----  readers and writers  ----- //
  const ObjectReader*  getObjectReader () const { return m_pObjectReader;  }
  ObjectReader*        getObjectReader ()       { return m_pObjectReader;  }

  const DynObjReader*  getDynObjReader () const { return m_pDynObjReader;  }
  DynObjReader*        getDynObjReader ()       { return m_pDynObjReader;  }

  const ArchiveReader* getArchiveReader() const { return m_pArchiveReader; }
  ArchiveReader*       getArchiveReader()       { return m_pArchiveReader; }

  const GroupReader* getGroupReader() const { return m_pGroupReader; }
  GroupReader*       getGroupReader()       { return m_pGroupReader; }

  const ObjectWriter*  getObjectWriter () const { return m_pObjectWriter;  }
  ObjectWriter*        getObjectWriter ()       { return m_pObjectWriter;  }

  const DynObjWriter*  getDynObjWriter () const { return m_pDynObjWriter;  }
  DynObjWriter*        getDynObjWriter ()       { return m_pDynObjWriter;  }

  const ExecWriter*    getExecWriter   () const { return m_pExecWriter;    }
  ExecWriter*          getExecWriter   ()       { return m_pExecWriter;    }

private:
  const LinkerConfig& m_Config;
  Module& m_Module;

  // we pass in InputBuilder for Archive and GroupReader.
  InputBuilder& m_InputBuilder; 

  FragmentLinker* m_pLinker;
  TargetLDBackend &m_LDBackend;

  // -----  readers and writers  ----- //
  ObjectReader* m_pObjectReader;
  DynObjReader* m_pDynObjReader;
  ArchiveReader* m_pArchiveReader;
  ObjectWriter* m_pObjectWriter;
  DynObjWriter* m_pDynObjWriter;
  ExecWriter* m_pExecWriter;
  GroupReader* m_pGroupReader;
};

} // end namespace mcld
#endif
