diff --git a/lib/Object/ObjectLinker.cpp b/lib/Object/ObjectLinker.cpp
new file mode 100644
index 0000000..93fdb20
--- /dev/null
+++ b/lib/Object/ObjectLinker.cpp
@@ -0,0 +1,442 @@
+//===- ObjectLinker.cpp ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <mcld/Object/ObjectLinker.h>
+
+#include <mcld/LinkerConfig.h>
+#include <mcld/Module.h>
+#include <mcld/InputTree.h>
+#include <mcld/MC/InputBuilder.h>
+#include <mcld/LD/LDSection.h>
+#include <mcld/LD/LDContext.h>
+#include <mcld/LD/Archive.h>
+#include <mcld/LD/ArchiveReader.h>
+#include <mcld/LD/ObjectReader.h>
+#include <mcld/LD/DynObjReader.h>
+#include <mcld/LD/GroupReader.h>
+#include <mcld/LD/ObjectWriter.h>
+#include <mcld/LD/DynObjWriter.h>
+#include <mcld/LD/ExecWriter.h>
+#include <mcld/LD/ResolveInfo.h>
+#include <mcld/LD/Layout.h>
+#include <mcld/LD/RelocData.h>
+#include <mcld/Support/RealPath.h>
+#include <mcld/Support/MemoryArea.h>
+#include <mcld/Support/MsgHandling.h>
+#include <mcld/Target/TargetLDBackend.h>
+#include <mcld/Fragment/FragmentLinker.h>
+#include <mcld/Object/ObjectBuilder.h>
+
+#include <llvm/Support/Casting.h>
+
+using namespace llvm;
+using namespace mcld;
+
+ObjectLinker::ObjectLinker(const LinkerConfig& pConfig,
+                           Module& pModule,
+                           InputBuilder& pInputBuilder,
+                           TargetLDBackend& pLDBackend)
+  : m_Config(pConfig),
+    m_Module(pModule),
+    m_InputBuilder(pInputBuilder),
+    m_pLinker(NULL),
+    m_LDBackend(pLDBackend),
+    m_pObjectReader(NULL),
+    m_pDynObjReader(NULL),
+    m_pArchiveReader(NULL),
+    m_pObjectWriter(NULL),
+    m_pDynObjWriter(NULL),
+    m_pExecWriter(NULL),
+    m_pGroupReader(NULL)
+{
+  // set up soname
+  if (!m_Config.options().soname().empty()) {
+    m_Module.setName(m_Config.options().soname());
+  }
+}
+
+ObjectLinker::~ObjectLinker()
+{
+  delete m_pLinker;
+  delete m_pObjectReader;
+  delete m_pDynObjReader;
+  delete m_pArchiveReader;
+  delete m_pObjectWriter;
+  delete m_pDynObjWriter;
+  delete m_pExecWriter;
+  delete m_pGroupReader;
+}
+
+/// initFragmentLinker - initialize FragmentLinker
+///  Connect all components with FragmentLinker
+bool ObjectLinker::initFragmentLinker()
+{
+  if (NULL == m_pLinker) {
+    m_pLinker = new FragmentLinker(m_Config,
+                                   m_Module,
+                                   m_LDBackend);
+  }
+
+  // initialize the readers and writers
+  // Because constructor can not be failed, we initalize all readers and
+  // writers outside the FragmentLinker constructors.
+  m_pObjectReader  = m_LDBackend.createObjectReader(*m_pLinker);
+  m_pArchiveReader = m_LDBackend.createArchiveReader(m_Module);
+  m_pDynObjReader  = m_LDBackend.createDynObjReader(*m_pLinker);
+  m_pObjectWriter  = m_LDBackend.createObjectWriter(*m_pLinker);
+  m_pDynObjWriter  = m_LDBackend.createDynObjWriter(*m_pLinker);
+  m_pExecWriter    = m_LDBackend.createExecWriter(*m_pLinker);
+  m_pGroupReader   = new GroupReader(m_Module, *m_pObjectReader,
+                                     *m_pDynObjReader, *m_pArchiveReader);
+
+  // initialize RelocationFactory
+  m_LDBackend.initRelocFactory(*m_pLinker);
+
+  // initialize BranchIslandFactory
+  m_LDBackend.initBRIslandFactory();
+
+  // initialize StubFactory
+  m_LDBackend.initStubFactory();
+
+  // initialize target stubs
+  m_LDBackend.initTargetStubs(*m_pLinker);
+  return true;
+}
+
+/// initStdSections - initialize standard sections
+bool ObjectLinker::initStdSections()
+{
+  ObjectBuilder builder(m_Config, m_Module);
+
+  // initialize standard sections
+  if (!m_LDBackend.initStdSections(builder))
+    return false;
+
+  // initialize target-dependent sections
+  m_LDBackend.initTargetSections(m_Module, builder);
+
+  return true;
+}
+
+void ObjectLinker::normalize()
+{
+  // -----  set up inputs  ----- //
+  Module::input_iterator input, inEnd = m_Module.input_end();
+  for (input = m_Module.input_begin(); input!=inEnd; ++input) {
+    // is a group node
+    if (isGroup(input)) {
+      getGroupReader()->readGroup(input, m_InputBuilder, m_Config);
+      continue;
+    }
+
+    // already got type - for example, bitcode or external OIR (object
+    // intermediate representation)
+    if ((*input)->type() == Input::Script ||
+        (*input)->type() == Input::Archive ||
+        (*input)->type() == Input::External)
+      continue;
+
+    if (Input::Object == (*input)->type()) {
+      m_Module.getObjectList().push_back(*input);
+      continue;
+    }
+
+    if (Input::DynObj == (*input)->type()) {
+      m_Module.getLibraryList().push_back(*input);
+      continue;
+    }
+
+    // is a relocatable object file
+    if (getObjectReader()->isMyFormat(**input)) {
+      (*input)->setType(Input::Object);
+      getObjectReader()->readHeader(**input);
+      getObjectReader()->readSections(**input);
+      getObjectReader()->readSymbols(**input);
+      m_Module.getObjectList().push_back(*input);
+    }
+    // is a shared object file
+    else if (getDynObjReader()->isMyFormat(**input)) {
+      (*input)->setType(Input::DynObj);
+      getDynObjReader()->readHeader(**input);
+      getDynObjReader()->readSymbols(**input);
+      m_Module.getLibraryList().push_back(*input);
+    }
+    // is an archive
+    else if (getArchiveReader()->isMyFormat(**input)) {
+      (*input)->setType(Input::Archive);
+      Archive archive(**input, m_InputBuilder);
+      getArchiveReader()->readArchive(archive);
+      if(archive.numOfObjectMember() > 0) {
+        m_Module.getInputTree().merge<InputTree::Inclusive>(input,
+                                                            archive.inputs());
+      }
+    }
+    else {
+      fatal(diag::err_unrecognized_input_file) << (*input)->path()
+                                               << m_Config.triple().str();
+    }
+  } // end of for
+}
+
+bool ObjectLinker::linkable() const
+{
+  // check we have input and output files
+  if (m_Module.getInputTree().empty()) {
+    error(diag::err_no_inputs);
+    return false;
+  }
+
+  // can not mix -static with shared objects
+  Module::const_lib_iterator lib, libEnd = m_Module.lib_end();
+  for (lib = m_Module.lib_begin(); lib != libEnd; ++lib) {
+    if((*lib)->attribute()->isStatic()) {
+      error(diag::err_mixed_shared_static_objects)
+                                      << (*lib)->name() << (*lib)->path();
+      return false;
+    }
+  }
+
+  // can not mix -r with shared objects
+  return true;
+}
+
+/// readRelocations - read all relocation entries
+///
+/// All symbols should be read and resolved before this function.
+bool ObjectLinker::readRelocations()
+{
+  // Bitcode is read by the other path. This function reads relocation sections
+  // in object files.
+  mcld::InputTree::bfs_iterator input, inEnd = m_Module.getInputTree().bfs_end();
+  for (input=m_Module.getInputTree().bfs_begin(); input!=inEnd; ++input) {
+    if ((*input)->type() == Input::Object && (*input)->hasMemArea()) {
+      if (!getObjectReader()->readRelocations(**input))
+        return false;
+    }
+    // ignore the other kinds of files.
+  }
+  return true;
+}
+
+/// mergeSections - put allinput sections into output sections
+bool ObjectLinker::mergeSections()
+{
+  ObjectBuilder builder(m_Config, m_Module);
+  Module::obj_iterator obj, objEnd = m_Module.obj_end();
+  for (obj = m_Module.obj_begin(); obj != objEnd; ++obj) {
+    LDContext::sect_iterator sect, sectEnd = (*obj)->context()->sectEnd();
+    for (sect = (*obj)->context()->sectBegin(); sect != sectEnd; ++sect) {
+      switch ((*sect)->kind()) {
+        // Some *INPUT sections should not be merged.
+        case LDFileFormat::Ignore:
+        case LDFileFormat::Null:
+        case LDFileFormat::Relocation:
+        case LDFileFormat::NamePool:
+        case LDFileFormat::Group:
+        case LDFileFormat::StackNote:
+          // skip
+          continue;
+        case LDFileFormat::Target:
+          if (!m_LDBackend.mergeSection(m_Module, **sect)) {
+            error(diag::err_cannot_merge_section) << (*sect)->name()
+                                                  << (*obj)->name();
+            return false;
+          }
+          break;
+        case LDFileFormat::EhFrame: {
+          if (!(*sect)->hasEhFrame())
+            continue; // skip
+
+          if (!builder.MergeSection(**sect)) {
+            error(diag::err_cannot_merge_section) << (*sect)->name()
+                                                  << (*obj)->name();
+            return false;
+          }
+          break;
+        }
+        default: {
+          if (!(*sect)->hasSectionData())
+            continue; // skip
+
+          if (!builder.MergeSection(**sect)) {
+            error(diag::err_cannot_merge_section) << (*sect)->name()
+                                                  << (*obj)->name();
+            return false;
+          }
+          break;
+        }
+      } // end of switch
+    } // for each section
+  } // for each obj
+  return true;
+}
+
+/// 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 ObjectLinker::addStandardSymbols()
+{
+  // create and add section symbols for each output section
+  Module::iterator iter, iterEnd = m_Module.end();
+  for (iter = m_Module.begin(); iter != iterEnd; ++iter) {
+    m_Module.getSectionSymbolSet().add(**iter, m_Module.getNamePool());
+  }
+
+  return m_LDBackend.initStandardSymbols(*m_pLinker, m_Module);
+}
+
+/// 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 ObjectLinker::addTargetSymbols()
+{
+  m_LDBackend.initTargetSymbols(*m_pLinker);
+  return true;
+}
+
+bool ObjectLinker::scanRelocations()
+{
+  // apply all relocations of all inputs
+  Module::obj_iterator input, inEnd = m_Module.obj_end();
+  for (input = m_Module.obj_begin(); input != inEnd; ++input) {
+    LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
+    for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
+      // bypass the reloc section if
+      // 1. its section kind is changed to Ignore. (The target section is a
+      // discarded group section.)
+      // 2. it has no reloc data. (All symbols in the input relocs are in the
+      // discarded group sections)
+      if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData())
+        continue;
+      RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end();
+      for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) {
+        Relocation* relocation = llvm::cast<Relocation>(reloc);
+        // scan relocation
+        if (LinkerConfig::Object != m_Config.codeGenType()) {
+          m_LDBackend.scanRelocation(*relocation,
+                                     *m_pLinker,
+                                     m_Module,
+                                     *(*rs)->getLink());
+        }
+        else {
+          m_LDBackend.partialScanRelocation(*relocation,
+                                     *m_pLinker,
+                                     m_Module,
+                                     *(*rs)->getLink());
+        }
+      } // for all relocations
+    } // for all relocation section
+  } // for all inputs
+  return true;
+}
+
+/// prelayout - help backend to do some modification before layout
+bool ObjectLinker::prelayout()
+{
+  // finalize the section symbols, set their fragment reference and push them
+  // into output symbol table
+  Module::iterator iter, iterEnd = m_Module.end();
+  for (iter = m_Module.begin(); iter != iterEnd; ++iter) {
+    LDSection* section = *iter;
+    if (0x0 == section->size() || LDFileFormat::Relocation == section->kind())
+      continue;
+    m_Module.getSectionSymbolSet().finalize(
+                                           *section, m_Module.getSymbolTable());
+  }
+
+  m_LDBackend.preLayout(m_Module, *m_pLinker);
+
+  m_LDBackend.allocateCommonSymbols(m_Module);
+
+  /// check program interpreter - computer the name size of the runtime dyld
+  if (!m_pLinker->isStaticLink() &&
+      (LinkerConfig::Exec == m_Config.codeGenType() ||
+       m_Config.options().isPIE() ||
+       m_Config.options().hasDyld()))
+    m_LDBackend.sizeInterp();
+
+  /// measure NamePools - compute the size of name pool sections
+  /// In ELF, will compute  the size of.symtab, .strtab, .dynsym, .dynstr,
+  /// .hash and .shstrtab sections.
+  ///
+  /// dump all symbols and strings from FragmentLinker and build the format-dependent
+  /// hash table.
+  m_LDBackend.sizeNamePools(m_Module, m_pLinker->isStaticLink());
+
+  return true;
+}
+
+/// 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 ObjectLinker::layout()
+{
+  Layout layout;
+  return layout.layout(m_Module, m_LDBackend, m_Config);
+}
+
+/// prelayout - help backend to do some modification after layout
+bool ObjectLinker::postlayout()
+{
+  m_LDBackend.postLayout(m_Module, *m_pLinker);
+  return true;
+}
+
+/// finalizeSymbolValue - finalize the resolved symbol value.
+///   Before relocate(), after layout(), FragmentLinker should correct value of all
+///   symbol.
+bool ObjectLinker::finalizeSymbolValue()
+{
+  return m_pLinker->finalizeSymbols();
+}
+
+/// 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 ObjectLinker::relocation()
+{
+  return m_pLinker->applyRelocations();
+}
+
+/// emitOutput - emit the output file.
+bool ObjectLinker::emitOutput(MemoryArea& pOutput)
+{
+  switch(m_Config.codeGenType()) {
+    case LinkerConfig::Object:
+      getObjectWriter()->writeObject(m_Module, pOutput);
+      return true;
+    case LinkerConfig::DynObj:
+      getDynObjWriter()->writeDynObj(m_Module, pOutput);
+      return true;
+    case LinkerConfig::Exec:
+      getExecWriter()->writeExecutable(m_Module, pOutput);
+      return true;
+    default:
+      fatal(diag::unrecognized_output_file) << m_Config.codeGenType();
+  }
+  return false;
+}
+
+/// postProcessing - do modification after all processes
+bool ObjectLinker::postProcessing(MemoryArea& pOutput)
+{
+  m_pLinker->syncRelocationResult(pOutput);
+
+  // emit .eh_frame_hdr
+  // eh_frame_hdr should be emitted after syncRelocation, because eh_frame_hdr
+  // needs FDE PC value, which will be corrected at syncRelocation
+  m_LDBackend.postProcessing(*m_pLinker, pOutput);
+  return true;
+}
+
