Linkloader improvement: mclinker.

Change-Id: I8805e39ccbc2ee204234fb3e71c70c906f3990bb
diff --git a/include/mcld/ADT/BinTree.h b/include/mcld/ADT/BinTree.h
new file mode 100644
index 0000000..0a7fe28
--- /dev/null
+++ b/include/mcld/ADT/BinTree.h
@@ -0,0 +1,481 @@
+//===- BinTree.h ----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_BINARY_TREE_H
+#define MCLD_BINARY_TREE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/ADT/Uncopyable.h"
+#include "mcld/ADT/TreeAllocator.h"
+
+#include <iterator>
+#include <memory>
+#include <queue>
+#include <stack>
+
+namespace mcld
+{
+
+template<class DataType>
+class BinaryTree;
+
+class DFSIterator : public TreeIteratorBase
+{
+public:
+  DFSIterator()
+  : TreeIteratorBase()
+  { }
+
+  DFSIterator(NodeBase *X)
+    : TreeIteratorBase(X) {
+    if (hasRightChild())
+      m_Stack.push(m_pNode->right);
+    if (hasLeftChild())
+      m_Stack.push(m_pNode->left);
+  }
+
+  virtual ~DFSIterator()
+  { }
+
+  void advance() {
+    if (m_Stack.empty()) { // reach the end
+      m_pNode = m_pNode->right; // should be root
+      return;
+    }
+    m_pNode = m_Stack.top();
+    m_Stack.pop();
+    if (hasRightChild())
+      m_Stack.push(m_pNode->right);
+    if (hasLeftChild())
+      m_Stack.push(m_pNode->left);
+  }
+
+private:
+    std::stack<NodeBase *> m_Stack;
+};
+
+class BFSIterator : public TreeIteratorBase
+{
+public:
+  BFSIterator()
+  : TreeIteratorBase()
+  { }
+
+  BFSIterator(NodeBase *X)
+    : TreeIteratorBase(X) {
+    if (hasRightChild())
+      m_Queue.push(m_pNode->right);
+    if (hasLeftChild())
+      m_Queue.push(m_pNode->left);
+  }
+
+  virtual ~BFSIterator()
+  { }
+
+  void advance() { 
+    if (m_Queue.empty()) { // reach the end
+      m_pNode = m_pNode->right; // should be root
+      return;
+    }
+    m_pNode = m_Queue.front();
+    m_Queue.pop();
+    if (hasRightChild())
+      m_Queue.push(m_pNode->right);
+    if (hasLeftChild())
+      m_Queue.push(m_pNode->left);
+  }
+
+private:
+    std::queue<NodeBase *> m_Queue;
+};
+
+template<class DataType, class Traits, class IteratorType>
+class PolicyIteratorBase : public IteratorType
+{
+public:
+  typedef DataType                       value_type;
+  typedef Traits                         traits;
+  typedef typename traits::pointer       pointer;
+  typedef typename traits::reference     reference;
+  
+  typedef PolicyIteratorBase<value_type, Traits, IteratorType>          Self;
+  typedef Node<value_type>                                              node_type;
+  typedef typename traits::nonconst_traits                              nonconst_traits;
+  typedef PolicyIteratorBase<value_type, nonconst_traits, IteratorType> iterator;
+  typedef typename traits::const_traits                                 const_traits;
+  typedef PolicyIteratorBase<value_type, const_traits, IteratorType>    const_iterator;
+  typedef std::forward_iterator_tag                                     iterator_category;
+  typedef size_t                                                        size_type;
+  typedef ptrdiff_t                                                     difference_type;
+
+public:
+  PolicyIteratorBase()
+    : IteratorType() {}
+
+  PolicyIteratorBase(const iterator &X)
+    : IteratorType(X.m_pNode) {}
+
+  explicit PolicyIteratorBase(NodeBase* X)
+    : IteratorType(X) {}
+
+  virtual ~PolicyIteratorBase() {}
+
+  // -----  operators  ----- //
+  pointer operator*() const 
+  { return static_cast<node_type*>(IteratorType::m_pNode)->data; }
+
+  reference operator->() const
+  { return *static_cast<node_type*>(IteratorType::m_pNode)->data; }
+
+  bool isRoot() const
+  { return (IteratorType::m_pNode->right == IteratorType::m_pNode); }
+
+  bool hasData() const 
+  { return (!isRoot() && (0 != static_cast<node_type*>(IteratorType::m_pNode)->data)); }
+
+};
+
+template<class DataType, class Traits, class IteratorType>
+class PolicyIterator : public PolicyIteratorBase<DataType, Traits, IteratorType>
+{
+public:
+  typedef PolicyIterator<DataType, Traits, IteratorType> Self;
+  typedef PolicyIteratorBase<DataType, Traits, IteratorType> Base;
+  typedef PolicyIterator<DataType, typename Traits::nonconst_traits, IteratorType> iterator;
+  typedef PolicyIterator<DataType, typename Traits::const_traits, IteratorType>    const_iterator;
+
+public:
+  PolicyIterator()
+    : Base() {}
+
+  PolicyIterator(const iterator &X)
+    : Base(X.m_pNode) {}
+
+  explicit PolicyIterator(NodeBase* X)
+    : Base(X) {}
+
+  virtual ~PolicyIterator() {}
+
+  Self& operator++() {
+    IteratorType::advance();
+    return *this;
+  }
+
+  Self operator++(int) {
+    Self tmp = *this;
+    IteratorType::advance();
+    return tmp;
+  }
+};
+
+template<class DataType>
+class BinaryTree;
+
+/** \class TreeIterator
+ *  \brief TreeIterator provides full functions of binary tree's iterator.
+ *
+ *  TreeIterator is designed to compatible with STL iterators.
+ *  TreeIterator is bi-directional. Incremental direction means to move
+ *  rightward, and decremental direction is leftward.
+ *
+ *  @see TreeIteratorBase
+ */
+template<class DataType, class Traits>
+struct TreeIterator : public TreeIteratorBase
+{
+public:
+  typedef DataType                       value_type;
+  typedef Traits                         traits;
+  typedef typename traits::pointer       pointer;
+  typedef typename traits::reference     reference;
+
+  typedef TreeIterator<value_type, Traits>          Self;
+  typedef Node<value_type>                          node_type;
+
+  typedef typename traits::nonconst_traits          nonconst_traits;
+  typedef TreeIterator<value_type, nonconst_traits> iterator;
+  typedef typename traits::const_traits             const_traits;
+  typedef TreeIterator<value_type, const_traits>    const_iterator;
+  typedef std::bidirectional_iterator_tag           iterator_category;
+  typedef size_t                                    size_type;
+  typedef ptrdiff_t                                 difference_type;
+
+public:
+  TreeIterator()
+  : TreeIteratorBase() {}
+
+  TreeIterator(const iterator &X)
+    : TreeIteratorBase(X.m_pNode) {}
+
+  ~TreeIterator() {}
+
+  // -----  operators  ----- //
+  pointer operator*() const 
+  { return static_cast<node_type*>(m_pNode)->data; }
+
+  reference operator->() const
+  { return *static_cast<node_type*>(m_pNode)->data; }
+
+  bool isRoot() const
+  { return (m_pNode->right == m_pNode); }
+
+  bool hasData() const 
+  { return (!isRoot() && (0 != static_cast<node_type*>(m_pNode)->data)); }
+
+  Self& operator++() {
+    this->move<TreeIteratorBase::Rightward>();
+    return *this;
+  }
+
+  Self operator++(int) {
+    Self tmp = *this;
+    this->move<TreeIteratorBase::Rightward>();
+    return tmp;
+  }
+
+  Self& operator--() {
+    this->move<TreeIteratorBase::Leftward>();
+    return *this;
+  }
+
+  Self operator--(int) {
+    Self tmp = *this;
+    this->move<TreeIteratorBase::Leftward>();
+    return tmp;
+  }
+
+  explicit TreeIterator(NodeBase* X)
+    : TreeIteratorBase(X) {}
+};
+
+/** \class BinaryTreeBase
+ *  \brief BinaryTreeBase gives root node and memory management.
+ *
+ *  The memory management of nodes in is hidden by BinaryTreeBase.
+ *  BinaryTreeBase also provides the basic functions for merging a tree and 
+ *  inserton of a node.
+ * 
+ *  @see BinaryTree
+ */
+template<class DataType>
+class BinaryTreeBase : private Uncopyable
+{
+public:
+  typedef Node<DataType> NodeType;
+protected:
+  /// TreeImpl - TreeImpl records the root node and the number of nodes
+  //
+  //    +---> Root(end) <---+
+  //    |        |left      |
+  //    |      begin        |
+  //    |     /     \       |
+  //    |  Left     Right   |
+  //    +---/         \-----+
+  //     
+  class TreeImpl : public NodeFactory<DataType>
+  {
+    typedef typename NodeFactory<DataType>::iterator       iterator;
+    typedef typename NodeFactory<DataType>::const_iterator const_iterator;
+
+  public:
+    NodeBase node;
+
+  public:
+    TreeImpl()
+      : NodeFactory<DataType>() {
+      node.left = node.right = &node;
+    }
+
+    ~TreeImpl()
+    { }
+
+    /// summon - change the final edges of pClient to our root
+    void summon(TreeImpl& pClient) {
+      if (this == &pClient)
+        return;
+
+      iterator data;
+      iterator dEnd = pClient.end();
+      for (data = pClient.begin(); data!=dEnd; ++data ) {
+        if ((*data).left == &pClient.node)
+          (*data).left = &node;
+        if ((*data).right == &pClient.node)
+          (*data).right = &node;
+      }
+    }
+  }; // TreeImpl
+
+protected:
+  /// m_Root is a special object who responses:
+  //  - the pointer of root
+  //  - the simple factory of nodes.
+  TreeImpl m_Root;
+
+protected:
+  NodeType *createNode() {
+    NodeType *result = m_Root.produce();
+    result->left = result->right = &m_Root.node;
+    return result;
+  }
+
+  void destroyNode(NodeType *pNode) {
+    pNode->left = pNode->right = 0;
+    pNode->data = 0;
+    m_Root.deallocate(pNode);
+  }
+
+public:
+  BinaryTreeBase()
+  : m_Root()
+  { }
+
+  virtual ~BinaryTreeBase()
+  { }
+
+  size_t size() const {
+    return m_Root.size();
+  }
+
+  bool empty() const {
+    return m_Root.empty();
+  }
+
+protected:
+  void clear() {
+    m_Root.clear();
+  }
+};
+
+/** \class BinaryTree
+ *  \brief An abstract data type of binary tree.
+ *
+ *  @see mcld::InputTree
+ */
+template<class DataType>
+class BinaryTree : public BinaryTreeBase<DataType>
+{
+public:
+  typedef size_t             size_type;
+  typedef ptrdiff_t          difference_type;
+  typedef DataType           value_type;
+  typedef value_type*        pointer;
+  typedef value_type&        reference;
+  typedef const value_type*  const_pointer;
+  typedef const value_type&  const_reference;
+
+  typedef BinaryTree<DataType>  Self;
+  typedef TreeIterator<value_type, NonConstTraits<value_type> > iterator;
+  typedef TreeIterator<value_type, ConstTraits<value_type> >    const_iterator;
+
+  typedef PolicyIterator<value_type, NonConstTraits<value_type>, DFSIterator> dfs_iterator;
+  typedef PolicyIterator<value_type, ConstTraits<value_type>, DFSIterator>    const_dfs_iterator;
+  typedef PolicyIterator<value_type, NonConstTraits<value_type>, BFSIterator> bfs_iterator;
+  typedef PolicyIterator<value_type, ConstTraits<value_type>, BFSIterator>    const_bfs_iterator;
+
+protected:
+  typedef Node<value_type> node_type;
+
+public:
+  // -----  constructors and destructor  ----- //
+  BinaryTree()
+  : BinaryTreeBase<DataType>()
+  { }
+
+  ~BinaryTree() {
+  }
+
+  // -----  iterators  ----- //
+  bfs_iterator bfs_begin()
+  { return bfs_iterator(BinaryTreeBase<DataType>::m_Root.node.left); }
+
+  bfs_iterator bfs_end()
+  { return bfs_iterator(BinaryTreeBase<DataType>::m_Root.node.right); }
+
+  const_bfs_iterator bfs_begin() const
+  { return const_bfs_iterator(BinaryTreeBase<DataType>::m_Root.node.left); }
+
+  const_bfs_iterator bfs_end() const
+  { return const_bfs_iterator(BinaryTreeBase<DataType>::m_Root.node.right); }
+
+  dfs_iterator dfs_begin()
+  { return dfs_iterator(BinaryTreeBase<DataType>::m_Root.node.left); }
+
+  dfs_iterator dfs_end()
+  { return dfs_iterator(BinaryTreeBase<DataType>::m_Root.node.right); }
+
+  const_dfs_iterator dfs_begin() const
+  { return const_dfs_iterator(BinaryTreeBase<DataType>::m_Root.node.left); }
+
+  const_dfs_iterator dfs_end() const
+  { return const_dfs_iterator(BinaryTreeBase<DataType>::m_Root.node.right); }
+
+  iterator root()
+  { return iterator(&(BinaryTreeBase<DataType>::m_Root.node)); }
+
+  const_iterator root() const
+  { return const_iterator(&(BinaryTreeBase<DataType>::m_Root.node)); }
+
+  iterator begin()
+  { return iterator(BinaryTreeBase<DataType>::m_Root.node.left); }
+
+  iterator end()
+  { return iterator(BinaryTreeBase<DataType>::m_Root.node.right); }
+
+  const_iterator begin() const
+  { return const_iterator(BinaryTreeBase<DataType>::m_Root.node.left); }
+
+  const_iterator end() const
+  { return const_iterator(BinaryTreeBase<DataType>::m_Root.node.right); }
+
+  // ----- modifiers  ----- //
+  /// join - create a leaf node and merge it in the tree.
+  //  This version of join determines the direction on compilation time.
+  //  @param DIRECT the direction of the connecting edge of the parent node.
+  //  @param position the parent node
+  //  @param value the value being pushed.
+  template<size_t DIRECT, class Pos>
+  BinaryTree& join(Pos position, const DataType& value) {
+    node_type *node = BinaryTreeBase<DataType>::createNode();
+    node->data = const_cast<DataType*>(&value);
+    if (position.isRoot())
+      proxy::hook<TreeIteratorBase::Leftward>(position.m_pNode,
+                          const_cast<const node_type*>(node));
+    else
+      proxy::hook<DIRECT>(position.m_pNode,
+                          const_cast<const node_type*>(node));
+    return *this;
+  }
+
+  /// merge - merge the tree
+  //  @param DIRECT the direction of the connecting edge of the parent node.
+  //  @param position the parent node
+  //  @param the tree being joined.
+  //  @return the joined tree
+  template<size_t DIRECT, class Pos>
+  BinaryTree& merge(Pos position, BinaryTree& pTree) {
+    if (this == &pTree)
+      return *this;
+
+    if (!pTree.empty()) {
+      proxy::hook<DIRECT>(position.m_pNode,
+                        const_cast<const NodeBase*>(pTree.m_Root.node.left));
+      BinaryTreeBase<DataType>::m_Root.summon(
+                                   pTree.BinaryTreeBase<DataType>::m_Root);
+      BinaryTreeBase<DataType>::m_Root.delegate(pTree.m_Root);
+      pTree.m_Root.node.left = pTree.m_Root.node.right = &pTree.m_Root.node;
+    }
+    return *this;
+  }
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/HashBase.h b/include/mcld/ADT/HashBase.h
new file mode 100644
index 0000000..76410ab
--- /dev/null
+++ b/include/mcld/ADT/HashBase.h
@@ -0,0 +1,139 @@
+//===- HashBase.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_HASH_BASE_H
+#define MCLD_HASH_BASE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/ADT/StringRef.h>
+#include <cstdlib>
+
+namespace mcld {
+
+/** forward declaration **/
+template<typename HashTableImplTy>
+class ChainIteratorBase;
+
+template<typename HashTableImplTy>
+class EntryIteratorBase;
+
+/** \class HashBucket
+ *  \brief HashBucket is an entry in the hash table.
+ */
+template<typename HashEntryTy>
+class HashBucket
+{
+public:
+  typedef HashEntryTy entry_type;
+
+public:
+  unsigned int FullHashValue;
+  entry_type *Entry;
+
+public:
+  static entry_type* getEmptyBucket();
+  static entry_type* getTombstone();
+
+};
+
+/** \class HashTableImpl
+ *  \brief HashTableImpl is the base class of HashTable.
+ *
+ *  HashTableImpl uses open-addressing, linear probing hash table.
+ *  linear probing hash table obviously has high performance when the
+ *  load factor is less than 0.7.
+ *  The drawback is that the number of the stored items can notbe more
+ *  than the size of the hash table.
+ *
+ *  MCLinker tries to merge every things in the same HashEntry. It can
+ *  keep every thing in the same cache line and improve the locality
+ *  efficiently. HashTableImpl provides a template argument to change the
+ *  definition of HashEntries.
+ *
+ *  HashEntryTy must provide getKey() and getKenLength() functions.
+ *
+ *  Different environments have different demands of HashFunctions. For
+ *  example, on-device linkers needs a more light-weight hash function
+ *  than static linkers. HashTableImpl also provides a template argument to
+ *  change the hash functions.
+ */
+template<typename HashEntryTy,
+         typename HashFunctionTy>
+class HashTableImpl
+{
+private:
+  static const unsigned int NumOfInitBuckets = 16;
+
+public:
+  typedef size_t size_type;
+  typedef HashFunctionTy hasher;
+  typedef HashEntryTy entry_type;
+  typedef typename HashEntryTy::key_type key_type;
+  typedef HashBucket<HashEntryTy> bucket_type;
+  typedef HashTableImpl<HashEntryTy, HashFunctionTy> Self;
+
+
+public:
+  HashTableImpl();
+  explicit HashTableImpl(unsigned int pInitSize);
+  virtual ~HashTableImpl();
+
+  // -----  observers  ----- //
+  bool empty() const;
+
+  size_t numOfBuckets() const
+  { return m_NumOfBuckets; }
+
+  size_t numOfEntries() const
+  { return m_NumOfEntries; }
+
+  hasher& hash()
+  { return m_Hasher; }
+
+  const hasher& hash() const
+  { return m_Hasher; }
+
+protected:
+  /// initialize the hash table.
+  void init(unsigned int pInitSize);
+
+  /// lookUpBucketFor - search the index of bucket whose key is p>ey
+  //  @return the index of the found bucket
+  unsigned int lookUpBucketFor(const key_type& pKey);
+
+  /// findKey - finds an element with key pKey
+  //  return the index of the element, or -1 when the element does not exist.
+  int findKey(const key_type& pKey) const;
+
+  /// mayRehash - check the load_factor, compute the new size, and then doRehash
+  void mayRehash();
+
+  /// doRehash - re-new the hash table, and rehash all elements into the new buckets
+  void doRehash(unsigned int pNewSize);
+
+friend class ChainIteratorBase<Self>;
+friend class ChainIteratorBase<const Self>;
+friend class EntryIteratorBase<Self>;
+friend class EntryIteratorBase<const Self>;
+protected:
+  // Array of Buckets
+  bucket_type* m_Buckets;
+  unsigned int m_NumOfBuckets;
+  unsigned int m_NumOfEntries;
+  unsigned int m_NumOfTombstones;
+  hasher m_Hasher;
+
+};
+
+#include "HashBase.tcc"
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/HashBase.tcc b/include/mcld/ADT/HashBase.tcc
new file mode 100644
index 0000000..62d92b1
--- /dev/null
+++ b/include/mcld/ADT/HashBase.tcc
@@ -0,0 +1,250 @@
+//===- HashBase.tcc -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//===--------------------------------------------------------------------===//
+// internal non-member functions
+inline static unsigned int compute_bucket_count(unsigned int pNumOfBuckets)
+{
+  static const unsigned int bucket_size[] =
+  {
+    1, 3, 17, 37, 67, 97, 197, 419, 977, 2593, 4099, 8209, 12289,
+    16411, 20483, 32771, 49157, 65537, 98317, 131101, 196613
+  };
+
+  const unsigned int buckets_count =
+      sizeof(bucket_size) / sizeof(bucket_size[0]);
+  unsigned int idx = 0;
+  do {
+    if (pNumOfBuckets < bucket_size[idx]) {
+      return bucket_size[idx];
+    }
+    ++idx;
+  } while(idx < buckets_count);
+
+  return (pNumOfBuckets+131101); // rare case. increase constantly
+}
+
+//===--------------------------------------------------------------------===//
+// template implementation of HashBucket
+template<typename DataType>
+typename HashBucket<DataType>::entry_type*
+HashBucket<DataType>::getEmptyBucket()
+{
+  static entry_type* empty_bucket = reinterpret_cast<entry_type*>(0x0);
+  return empty_bucket;
+}
+
+template<typename DataType>
+typename HashBucket<DataType>::entry_type*
+HashBucket<DataType>::getTombstone()
+{
+  static entry_type* tombstone = reinterpret_cast<entry_type*>(0x1);
+  return tombstone;
+}
+
+//===--------------------------------------------------------------------===//
+// template implementation of HashTableImpl
+template<typename HashEntryTy,
+         typename HashFunctionTy>
+HashTableImpl<HashEntryTy, HashFunctionTy>::HashTableImpl()
+  : m_Buckets(0),
+    m_NumOfBuckets(0),
+    m_NumOfEntries(0),
+    m_NumOfTombstones(0),
+    m_Hasher() {
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy>
+HashTableImpl<HashEntryTy, HashFunctionTy>::HashTableImpl(
+  unsigned int pInitSize)
+  : m_Hasher() {
+  if (pInitSize) {
+    init(pInitSize);
+    return;
+  }
+
+  m_Buckets = 0;
+  m_NumOfBuckets = 0;
+  m_NumOfEntries = 0;
+  m_NumOfTombstones = 0;
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy>
+HashTableImpl<HashEntryTy, HashFunctionTy>::~HashTableImpl()
+{
+  free(m_Buckets);
+}
+
+/// empty - check if the hash table is empty
+template<typename HashEntryTy,
+         typename HashFunctionTy>
+bool HashTableImpl<HashEntryTy, HashFunctionTy>::empty() const
+{
+  return (0 == m_NumOfEntries);
+}
+
+/// init - initialize the hash table.
+template<typename HashEntryTy,
+         typename HashFunctionTy>
+void HashTableImpl<HashEntryTy, HashFunctionTy>::init(unsigned int pInitSize)
+{
+  m_NumOfBuckets = pInitSize? compute_bucket_count(pInitSize): NumOfInitBuckets;
+
+  m_NumOfEntries = 0;
+  m_NumOfTombstones = 0;
+
+  /** calloc also set bucket.Item = bucket_type::getEmptyStone() **/
+  m_Buckets = (bucket_type*)calloc(m_NumOfBuckets, sizeof(bucket_type));
+}
+
+/// lookUpBucketFor - look up the bucket whose key is pKey
+template<typename HashEntryTy,
+         typename HashFunctionTy>
+unsigned int
+HashTableImpl<HashEntryTy, HashFunctionTy>::lookUpBucketFor(
+  const typename HashTableImpl<HashEntryTy, HashFunctionTy>::key_type& pKey)
+{
+  if (0 == m_NumOfBuckets) {
+    // NumOfBuckets is changed after init(pInitSize)
+    init(NumOfInitBuckets);
+  }
+
+  unsigned int full_hash = m_Hasher(pKey);
+  unsigned int index = full_hash % m_NumOfBuckets;
+
+  const unsigned int probe = 1;
+  int firstTombstone = -1;
+
+  // linear probing
+  while(true) {
+    bucket_type& bucket = m_Buckets[index];
+    // If we found an empty bucket, this key isn't in the table yet, return it.
+    if (bucket_type::getEmptyBucket() == bucket.Entry) {
+      if (-1 != firstTombstone) {
+        m_Buckets[firstTombstone].FullHashValue = full_hash;
+        return firstTombstone;
+      }
+
+      bucket.FullHashValue = full_hash;
+      return index;
+    }
+
+    if (bucket_type::getTombstone() == bucket.Entry) {
+      if (-1 == firstTombstone) {
+        firstTombstone = index;
+      }
+    }
+    else if (bucket.FullHashValue == full_hash) {
+      if (bucket.Entry->compare(pKey)) {
+        return index;
+      }
+    }
+
+    index += probe;
+    if (index == m_NumOfBuckets)
+      index = 0;
+  }
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy>
+int
+HashTableImpl<HashEntryTy, HashFunctionTy>::findKey(
+  const typename HashTableImpl<HashEntryTy, HashFunctionTy>::key_type& pKey) const
+{
+  if (0 == m_NumOfBuckets)
+    return -1;
+
+  unsigned int full_hash = m_Hasher(pKey);
+  unsigned int index = full_hash % m_NumOfBuckets;
+
+  const unsigned int probe = 1;
+  // linear probing
+  while (true) {
+    bucket_type &bucket = m_Buckets[index];
+
+    if (bucket_type::getEmptyBucket() == bucket.Entry)
+      return -1;
+
+    if (bucket_type::getTombstone() == bucket.Entry) {
+      // Ignore tombstones.
+    }
+    else if (full_hash == bucket.FullHashValue) {
+      // get string, compare, if match, return index
+      if (bucket.Entry->compare(pKey))
+        return index;
+    }
+    index += probe;
+    if (index == m_NumOfBuckets)
+      index = 0;
+  }
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy>
+void HashTableImpl<HashEntryTy, HashFunctionTy>::mayRehash()
+{
+
+  unsigned int new_size;
+  // If the hash table is now more than 3/4 full, or if fewer than 1/8 of
+  // the buckets are empty (meaning that many are filled with tombstones),
+  // grow/rehash the table.
+  if ((m_NumOfEntries<<2) > m_NumOfBuckets*3)
+    new_size = compute_bucket_count(m_NumOfBuckets);
+  else if (((m_NumOfBuckets-(m_NumOfEntries+m_NumOfTombstones))<<3) < m_NumOfBuckets)
+    new_size = m_NumOfBuckets;
+  else
+    return;
+
+  doRehash(new_size);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy>
+void HashTableImpl<HashEntryTy, HashFunctionTy>::doRehash(unsigned int pNewSize)
+{
+  bucket_type* new_table = (bucket_type*)calloc(pNewSize, sizeof(bucket_type));
+
+  // Rehash all the items into their new buckets.  Luckily :) we already have
+  // the hash values available, so we don't have to recall hash function again.
+  for (bucket_type *IB = m_Buckets, *E = m_Buckets+m_NumOfBuckets; IB != E; ++IB) {
+    if (IB->Entry != bucket_type::getEmptyBucket() &&
+        IB->Entry != bucket_type::getTombstone()) {
+      // Fast case, bucket available.
+      unsigned full_hash = IB->FullHashValue;
+      unsigned new_bucket = full_hash % pNewSize;
+      if (bucket_type::getEmptyBucket() == new_table[new_bucket].Entry) {
+        new_table[new_bucket].Entry = IB->Entry;
+        new_table[new_bucket].FullHashValue = full_hash;
+        continue;
+      }
+
+      // Otherwise probe for a spot.
+      const unsigned int probe = 1;
+      do {
+        new_bucket += probe;
+        if (new_bucket == pNewSize)
+          new_bucket = 0;
+      } while (new_table[new_bucket].Entry != bucket_type::getEmptyBucket());
+
+      // Finally found a slot.  Fill it in.
+      new_table[new_bucket].Entry = IB->Entry;
+      new_table[new_bucket].FullHashValue = full_hash;
+    }
+  }
+
+  free(m_Buckets);
+
+  m_Buckets = new_table;
+  m_NumOfBuckets = pNewSize;
+  m_NumOfTombstones = 0;
+}
+
diff --git a/include/mcld/ADT/HashEntry.h b/include/mcld/ADT/HashEntry.h
new file mode 100644
index 0000000..c034783
--- /dev/null
+++ b/include/mcld/ADT/HashEntry.h
@@ -0,0 +1,95 @@
+//===- HashEntry.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_HASH_ENTRY_H
+#define MCLD_HASH_ENTRY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+namespace mcld {
+
+/** forward declaration **/
+template<typename HashEntryTy>
+class EntryFactory;
+
+/** \class HashEntry
+ *  \brief HashEntry is the item in the bucket of hash table.
+ *
+ *  mcld::HashEntry illustrates the demand from mcld::HashTable.
+ *  Since HashTable can change the definition of the HashEntry by changing
+ *  the template argument. class mcld::HashEntry here is used to show the
+ *  basic interfaces that HashTable requests. You can define your own entry
+ *  of the hash table which has no relation to mcld::HashEntry
+ *
+ *  Since mcld::HashEntry here is a special class whose size is changing,
+ *  derive a new class from it is risky. Make sure you understand what you
+ *  are doing when you let a new class inherit from mcld::HashEntry.
+ */
+template <typename KeyType, typename ValueType, typename KeyCompare>
+class HashEntry
+{
+public:
+  typedef KeyType key_type;
+  typedef ValueType value_type;
+  typedef KeyCompare key_compare;
+
+private:
+  typedef HashEntry<KeyType, ValueType, KeyCompare> Self;
+  friend class EntryFactory<Self>;
+
+private:
+  HashEntry(const KeyType& pKey);
+  ~HashEntry();
+
+public:
+  KeyType& key()
+  { return m_Key; }
+
+  const KeyType& key() const
+  { return m_Key; }
+
+  ValueType& value()
+  { return m_Value; }
+
+  const ValueType& value() const
+  { return m_Value; }
+
+  void setValue(const ValueType& pValue)
+  { m_Value = pValue; }
+
+  bool compare(const key_type& pKey);
+
+public:
+  KeyType m_Key;
+  ValueType m_Value;
+};
+
+template <typename HashEntryTy>
+class EntryFactory
+{
+public:
+  typedef HashEntryTy                      entry_type;
+  typedef typename HashEntryTy::key_type   key_type;
+  typedef typename HashEntryTy::value_type value_type;
+
+public:
+  EntryFactory();
+  ~EntryFactory();
+
+  HashEntryTy* produce(const key_type& pKey);
+  void destroy(HashEntryTy* pEntry);
+};
+
+#include "HashEntry.tcc"
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/HashEntry.tcc b/include/mcld/ADT/HashEntry.tcc
new file mode 100644
index 0000000..fdd886b
--- /dev/null
+++ b/include/mcld/ADT/HashEntry.tcc
@@ -0,0 +1,53 @@
+//===- HashEntry.tcc ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//===--------------------------------------------------------------------===//
+// template implementation of HashEntry
+template <typename KeyType, typename ValueType, typename KeyCompare>
+HashEntry<KeyType, ValueType, KeyCompare>::HashEntry(const KeyType& pKey)
+  : m_Key(pKey) {
+}
+
+template <typename KeyType, typename ValueType, typename KeyCompare>
+HashEntry<KeyType, ValueType, KeyCompare>::~HashEntry()
+{
+}
+
+template <typename KeyType, typename ValueType, typename KeyCompare>
+bool HashEntry<KeyType, ValueType, KeyCompare>::compare(const KeyType& pKey)
+{
+  static KeyCompare comparator;
+  return comparator(m_Key, pKey);
+}
+
+//===--------------------------------------------------------------------===//
+// template implementation of EntryFactory
+template <typename HashEntryTy>
+EntryFactory<HashEntryTy>::EntryFactory()
+{
+}
+
+template <typename HashEntryTy>
+EntryFactory<HashEntryTy>::~EntryFactory()
+{
+}
+
+template <typename HashEntryTy>
+void EntryFactory<HashEntryTy>::destroy(HashEntryTy* pEntry)
+{
+  delete pEntry;
+}
+
+template <typename HashEntryTy>
+HashEntryTy*
+EntryFactory<HashEntryTy>::produce(const typename EntryFactory<HashEntryTy>::key_type& pKey)
+{
+  return new HashEntryTy(pKey);
+}
+
diff --git a/include/mcld/ADT/HashIterator.h b/include/mcld/ADT/HashIterator.h
new file mode 100644
index 0000000..92ccdc5
--- /dev/null
+++ b/include/mcld/ADT/HashIterator.h
@@ -0,0 +1,323 @@
+//===- HashIterator.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_HASH_ITERATOR_H
+#define MCLD_HASH_ITERATOR_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+namespace mcld {
+
+/** \class ChainIteratorBase
+ *  \brief ChaintIteratorBase follows the HashEntryTy with the same hash value.
+ */
+template<typename HashTableImplTy>
+class ChainIteratorBase
+{
+public:
+  typedef HashTableImplTy hash_table;
+  typedef typename HashTableImplTy::key_type key_type;
+  typedef typename HashTableImplTy::entry_type entry_type;
+  typedef typename HashTableImplTy::bucket_type bucket_type;
+
+public:
+  ChainIteratorBase()
+  : m_pHashTable(0), m_HashValue(0), m_Index(0), m_EndIndex(0)
+  { }
+
+  ChainIteratorBase(HashTableImplTy* pTable, const key_type& pKey)
+  : m_pHashTable(pTable)
+  {
+    m_HashValue = pTable->hash()(pKey);
+    m_EndIndex = m_Index = m_HashValue % m_pHashTable->m_NumOfBuckets;
+    const unsigned int probe = 1;
+    while(true) {
+      bucket_type &bucket = m_pHashTable->m_Buckets[m_Index];
+      if (bucket_type::getTombstone() == bucket.Entry) {
+        // Ignore tombstones.
+      }
+      else if (m_HashValue == bucket.FullHashValue) {
+        if (bucket.Entry->compare(pKey)) {
+          m_EndIndex = m_Index;
+          break;
+        }
+      }
+      m_Index += probe;
+      if (m_Index == m_pHashTable->m_NumOfBuckets)
+        m_Index = 0;
+      // doesn't exist
+      if (m_EndIndex == m_Index) {
+        reset();
+        break;
+      }
+    }
+  }
+
+  ChainIteratorBase(const ChainIteratorBase& pCopy)
+  : m_pHashTable(pCopy.m_pHashTable),
+    m_Index(pCopy.m_Index),
+    m_EndIndex(pCopy.m_EndIndex),
+    m_HashValue(pCopy.m_HashValue)
+  { }
+
+  ChainIteratorBase& assign(const ChainIteratorBase& pCopy) {
+    m_pHashTable = pCopy.m_pHashTable;
+    m_Index = pCopy.m_Index;
+    m_EndIndex = pCopy.m_EndIndex;
+    m_HashValue = pCopy.m_HashValue;
+    return *this;
+  }
+
+  inline bucket_type* getBucket() {
+    if (0 == m_pHashTable)
+      return 0;
+    return &(m_pHashTable->m_Buckets[m_Index]);
+  }
+
+  inline const bucket_type* getBucket() const {
+    if (0 == m_pHashTable)
+      return 0;
+    return &(m_pHashTable->m_Buckets[m_Index]);
+  }
+
+  inline entry_type* getEntry() {
+    if (0 == m_pHashTable)
+      return 0;
+    return m_pHashTable->m_Buckets[m_Index].Entry;
+  }
+
+  inline const entry_type* getEntry() const {
+    if (0 == m_pHashTable)
+      return 0;
+    return m_pHashTable->m_Buckets[m_Index].Entry;
+  }
+
+  inline void reset() {
+    m_pHashTable = 0;
+    m_Index = 0;
+    m_EndIndex = 0;
+    m_HashValue = 0;
+  }
+
+  inline void advance() {
+    if (0 == m_pHashTable)
+      return;
+    const unsigned int probe = 1;
+    while(true) {
+      m_Index += probe;
+      if (m_Index == m_pHashTable->m_NumOfBuckets)
+        m_Index = 0;
+      // reach end()
+      if (m_Index == m_EndIndex) {
+        reset();
+        return;
+      }
+
+      bucket_type &bucket = m_pHashTable->m_Buckets[m_Index];
+
+      if (bucket_type::getTombstone() == bucket.Entry ||
+          bucket_type::getEmptyBucket() == bucket.Entry) {
+        // Ignore tombstones.
+      }
+      else if (m_HashValue == bucket.FullHashValue) {
+        return;
+      }
+    }
+  }
+
+  bool operator==(const ChainIteratorBase& pCopy) const {
+    if (m_pHashTable == pCopy.m_pHashTable) {
+      if (0 == m_pHashTable)
+        return true;
+      return ((m_HashValue == pCopy.m_HashValue) &&
+              (m_EndIndex == pCopy.m_EndIndex) &&
+              (m_Index == pCopy.m_Index));
+    }
+    return false;
+  }
+
+  bool operator!=(const ChainIteratorBase& pCopy) const
+  { return !(*this == pCopy); }
+
+private:
+  HashTableImplTy* m_pHashTable;
+  unsigned int m_Index;
+  unsigned int m_HashValue;
+  unsigned int m_EndIndex;
+};
+ 
+/** \class EntryIteratorBase
+ *  \brief EntryIteratorBase walks over hash table by the natural layout of the
+ *  buckets
+ */
+template<typename HashTableImplTy>
+class EntryIteratorBase
+{
+public:
+  typedef HashTableImplTy hash_table;
+  typedef typename HashTableImplTy::key_type key_type;
+  typedef typename HashTableImplTy::entry_type entry_type;
+  typedef typename HashTableImplTy::bucket_type bucket_type;
+
+public:
+  EntryIteratorBase()
+  : m_pHashTable(0), m_Index(0)
+  { }
+
+  EntryIteratorBase(HashTableImplTy* pTable,
+                   unsigned int pIndex)
+  : m_pHashTable(pTable), m_Index(pIndex)
+  { }
+
+  EntryIteratorBase(const EntryIteratorBase& pCopy)
+  : m_pHashTable(pCopy.m_pHashTable), m_Index(pCopy.m_Index)
+  { }
+
+  EntryIteratorBase& assign(const EntryIteratorBase& pCopy) {
+    m_pHashTable = pCopy.m_pHashTable;
+    m_Index = pCopy.m_Index;
+    return *this;
+  }
+
+  inline bucket_type* getBucket() {
+    if (0 == m_pHashTable)
+      return 0;
+    return &(m_pHashTable->m_Buckets[m_Index]);
+  }
+
+  inline const bucket_type* getBucket() const {
+    if (0 == m_pHashTable)
+      return 0;
+    return &(m_pHashTable->m_Buckets[m_Index]);
+  }
+
+  inline entry_type* getEntry() {
+    if (0 == m_pHashTable)
+      return 0;
+    return m_pHashTable->m_Buckets[m_Index].Entry;
+  }
+
+  inline const entry_type* getEntry() const {
+    if (0 == m_pHashTable)
+      return 0;
+    return m_pHashTable->m_Buckets[m_Index].Entry;
+  }
+
+  inline void reset() {
+    m_pHashTable = 0;
+    m_Index = 0;
+  }
+
+  inline void advance() {
+    if (0 == m_pHashTable)
+      return;
+    do {
+      ++m_Index;
+      if (m_pHashTable->m_NumOfBuckets == m_Index) { // to the end
+        reset();
+        return;
+      }
+    } while(bucket_type::getEmptyBucket() == m_pHashTable->m_Buckets[m_Index].Entry || 
+            bucket_type::getTombstone() == m_pHashTable->m_Buckets[m_Index].Entry);
+  }
+
+  bool operator==(const EntryIteratorBase& pCopy) const
+  { return ((m_pHashTable == pCopy.m_pHashTable) &&
+            (m_Index == pCopy.m_Index)); }
+
+  bool operator!=(const EntryIteratorBase& pCopy) const
+  { return !(*this == pCopy); }
+
+private:
+  HashTableImplTy* m_pHashTable;
+  unsigned int m_Index;
+
+};
+
+/** \class HashIterator
+ *  \brief HashIterator provides a policy-based iterator.
+ *
+ *  HashTable has two kinds of iterators. One is used to traverse buckets
+ *  with the same hash value; the other is used to traverse all entries of the
+ *  hash table.
+ *
+ *  HashIterator is a template policy-based iterator, which can change its
+ *  behavior by change the template argument IteratorBase. HashTable defines
+ *  above two iterators by defining HashIterators with different IteratorBase.
+ */
+template<typename IteratorBase,
+         typename Traits>
+class HashIterator : public IteratorBase
+{
+public:
+  typedef Traits                     traits;
+  typedef typename traits::pointer   pointer;
+  typedef typename traits::reference reference;
+  typedef size_t                     size_type;
+  typedef ptrdiff_t                  difference_type;
+  typedef IteratorBase               Base;
+
+  typedef HashIterator<IteratorBase,
+                       Traits>             Self;
+
+  typedef typename traits::nonconst_traits nonconst_traits;
+  typedef HashIterator<IteratorBase,
+                       nonconst_traits>    iterator;
+
+  typedef typename traits::const_traits    const_traits;
+  typedef HashIterator<IteratorBase,
+                       const_traits>       const_iterator;
+  typedef std::forward_iterator_tag        iterator_category;
+
+public:
+  HashIterator()
+  : IteratorBase()
+  { }
+
+  /// HashIterator - constructor for EntryIterator
+  HashIterator(typename IteratorBase::hash_table* pTable, unsigned int pIndex)
+  : IteratorBase(pTable, pIndex)
+  { }
+
+  /// HashIterator - constructor for ChainIterator
+  explicit HashIterator(typename IteratorBase::hash_table* pTable,
+                        const typename IteratorBase::key_type& pKey,
+                        int)
+  : IteratorBase(pTable, pKey)
+  { }
+
+  HashIterator(const HashIterator& pCopy)
+  : IteratorBase(pCopy)
+  { }
+
+  ~HashIterator()
+  { }
+
+  HashIterator& operator=(const HashIterator& pCopy) {
+    IteratorBase::assign(pCopy);
+    return *this;
+  }
+
+  // -----  operators  ----- //
+  Self& operator++() {
+    this->Base::advance();
+    return *this;
+  }
+
+  Self operator++(int) {
+    Self tmp = *this;
+    this->Base::advance();
+    return tmp;
+  }
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/HashTable.h b/include/mcld/ADT/HashTable.h
new file mode 100644
index 0000000..dfc2f5a
--- /dev/null
+++ b/include/mcld/ADT/HashTable.h
@@ -0,0 +1,126 @@
+//===- HashTable.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_HASH_TABLE_H
+#define MCLD_HASH_TABLE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/ADT/HashBase.h"
+#include "mcld/ADT/HashIterator.h"
+#include "mcld/ADT/Uncopyable.h"
+#include "mcld/ADT/TypeTraits.h"
+#include "mcld/Support/Allocators.h"
+#include <utility>
+
+namespace mcld
+{
+
+/** \class HashTable
+ *  \brief HashTable is a hash table which follows boost::unordered_map, but it
+ *  is open addressing and can linear probing.
+ *
+ *  mcld::HashTable is a linear probing hash table. It does not allocate
+ *  the memory space of the entries by itself. Instead, entries are allocated
+ *  outside and then emplaced into the hash table.
+ */
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+class HashTable : public HashTableImpl<HashEntryTy, HashFunctionTy>,
+                  private Uncopyable
+{
+private:
+  typedef HashTableImpl<HashEntryTy, HashFunctionTy> BaseTy;
+
+public:
+  typedef size_t size_type;
+  typedef HashFunctionTy hasher;
+  typedef HashEntryTy entry_type;
+  typedef typename BaseTy::bucket_type bucket_type;
+  typedef typename HashEntryTy::key_type key_type;
+
+  typedef HashIterator<ChainIteratorBase<BaseTy>,
+                       NonConstTraits<HashEntryTy> > chain_iterator;
+  typedef HashIterator<ChainIteratorBase<const BaseTy>,
+                       ConstTraits<HashEntryTy> >    const_chain_iterator;
+
+  typedef HashIterator<EntryIteratorBase<BaseTy>,
+                       NonConstTraits<HashEntryTy> > entry_iterator;
+  typedef HashIterator<EntryIteratorBase<const BaseTy>,
+                       ConstTraits<HashEntryTy> >    const_entry_iterator;
+
+  typedef entry_iterator                             iterator;
+  typedef const_entry_iterator                       const_iterator;
+
+public:
+  // -----  constructor  ----- //
+  explicit HashTable(size_type pSize=3);
+  ~HashTable();
+  
+  EntryFactoryTy& getEntryFactory()
+  { return m_EntryFactory; }
+
+  // -----  modifiers  ----- //
+  void clear();
+
+  /// insert - insert a new element to the container. The element is
+  //  constructed in-place, i.e. no copy or move operations are performed.
+  //  If the element already exists, return the element, and set pExist true.
+  entry_type* insert(const key_type& pKey, bool& pExist);
+
+  /// erase - remove the element with the same key
+  size_type erase(const key_type& pKey);
+
+  // -----  lookups  ----- //
+  /// find - finds an element with key pKey
+  //  If the element does not exist, return end()
+  iterator find(const key_type& pKey);
+
+  /// find - finds an element with key pKey, constant version
+  //  If the element does not exist, return end()
+  const_iterator find(const key_type& pKey) const;
+
+  size_type count(const key_type& pKey) const;
+  
+  // -----  hash policy  ----- //
+  float load_factor() const;
+
+  /// rehash - if the load factor is larger than 75%, or the empty buckets is
+  //  less than 12.5%, the rehash the hash table
+  void rehash();
+
+  /// rehash - immediately re-new the hash table to the size pCount, and
+  //  rehash all elements.
+  void rehash(size_type pCount);
+
+  // -----  iterators  ----- //
+  iterator begin();
+  iterator end();
+
+  const_entry_iterator begin() const;
+  const_entry_iterator end() const;
+
+  chain_iterator begin(const key_type& pKey);
+  chain_iterator end(const key_type& pKey);
+  const_chain_iterator begin(const key_type& pKey) const;
+  const_chain_iterator end(const key_type& pKey) const;
+
+private:
+  EntryFactoryTy m_EntryFactory;
+
+};
+
+#include "HashTable.tcc"
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/HashTable.tcc b/include/mcld/ADT/HashTable.tcc
new file mode 100644
index 0000000..6fb05a3
--- /dev/null
+++ b/include/mcld/ADT/HashTable.tcc
@@ -0,0 +1,268 @@
+//===- HashTable.tcc ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//===--------------------------------------------------------------------===//
+// template implementation of HashTable
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::HashTable(size_type pSize)
+  : HashTableImpl<HashEntryTy, HashFunctionTy>(pSize), m_EntryFactory()
+{
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::~HashTable()
+{
+  if (BaseTy::empty())
+    return;
+
+  /** clean up **/
+  for (unsigned int i=0; i < BaseTy::m_NumOfBuckets; ++i) {
+    if (bucket_type::getEmptyBucket() != BaseTy::m_Buckets[i].Entry &&
+        bucket_type::getTombstone() != BaseTy::m_Buckets[i].Entry ) {
+      m_EntryFactory.destroy(BaseTy::m_Buckets[i].Entry);
+    }
+  }
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+void HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::clear()
+{
+  if (BaseTy::empty())
+    return;
+
+  /** clean up **/
+  for (unsigned int i=0; i < BaseTy::m_NumOfBuckets; ++i) {
+    if (bucket_type::getEmptyBucket() != BaseTy::m_Buckets[i].Entry ) {
+      if (bucket_type::getTombstone() != BaseTy::m_Buckets[i].Entry ) {
+        m_EntryFactory.destroy(BaseTy::m_Buckets[i].Entry);
+      }
+      BaseTy::m_Buckets[i].Entry = bucket_type::getEmptyBucket();
+    }
+  }
+  BaseTy::m_NumOfEntries = 0;
+  BaseTy::m_NumOfTombstones = 0;
+}
+
+/// insert - insert a new element to the container. If the element already
+//  exist, return the element.
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::entry_type*
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::insert(
+  const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey,
+  bool& pExist)
+{
+  unsigned int index = BaseTy::lookUpBucketFor(pKey);
+  bucket_type& bucket = BaseTy::m_Buckets[index];
+  entry_type* entry = bucket.Entry;
+  if (bucket_type::getEmptyBucket() != entry &&
+      bucket_type::getTombstone() != entry) {
+    // Already exist in the table
+    pExist = true;
+    return entry;
+  }
+
+  // find a tombstone
+  if (bucket_type::getTombstone() == entry)
+    --BaseTy::m_NumOfTombstones;
+
+  entry = bucket.Entry = m_EntryFactory.produce(pKey);
+  ++BaseTy::m_NumOfEntries;
+  BaseTy::mayRehash();
+  pExist = false;
+  return entry;
+}
+
+/// erase - remove the elements with the pKey
+//  @return the number of removed elements.
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::size_type
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::erase(
+        const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey)
+{
+  int index;
+  if (-1 == (index = BaseTy::findKey(pKey)))
+    return 0;
+
+  bucket_type& bucket = BaseTy::m_Buckets[index];
+  m_EntryFactory.destroy(bucket.Entry);
+  bucket.Entry = bucket_type::getTombstone();
+
+  --BaseTy::m_NumOfEntries;
+  ++BaseTy::m_NumOfTombstones;
+  BaseTy::mayRehash();
+  return 1;
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::iterator
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::find(
+  const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey)
+{
+  int index;
+  if (-1 == (index = BaseTy::findKey(pKey)))
+    return end();
+  return iterator(this, index);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::const_iterator
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::find(
+  const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey) const
+{
+  int index;
+  if (-1 == (index = BaseTy::findKey(pKey)))
+    return end();
+  return const_iterator(this, index);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::size_type
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::count(
+  const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey) const
+{
+  const_chain_iterator bucket, bEnd = end(pKey);
+  size_type count = 0;
+  for (bucket = begin(pKey); bucket != bEnd; ++bucket)
+    ++count;
+  return count;
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+float HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::load_factor() const
+{
+  return ((float)BaseTy::m_NumOfEntries/(float)BaseTy::m_NumOfBuckets);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+void
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::rehash()
+{
+  BaseTy::mayRehash();
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+void
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::rehash(
+       typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::size_type pCount)
+{
+  BaseTy::doRehash(pCount);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::iterator
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::begin()
+{
+  if (BaseTy::empty())
+    return iterator(this, 0);
+  unsigned int index = 0;
+  while (bucket_type::getTombstone() == BaseTy::m_Buckets[index].Entry ||
+         bucket_type::getEmptyBucket() == BaseTy::m_Buckets[index].Entry) {
+    ++index;
+  }
+  return iterator(this, index);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::iterator
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::end()
+{
+  return iterator(NULL, 0);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::const_iterator
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::begin() const
+{
+  if (BaseTy::empty())
+    return const_iterator(this, 0);
+  unsigned int index = 0;
+  while (bucket_type::getTombstone() == BaseTy::m_Buckets[index].Entry ||
+         bucket_type::getEmptyBucket() == BaseTy::m_Buckets[index].Entry) {
+    ++index;
+  }
+  return const_iterator(this, index);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::const_iterator
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::end() const
+{
+  return const_iterator(NULL, 0);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::chain_iterator
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::begin(
+    const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey)
+{
+  return chain_iterator(this, pKey, 0x0);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::chain_iterator
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::end(
+    const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey)
+{
+  return chain_iterator();
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::const_chain_iterator
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::begin(
+  const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey) const
+{
+  return const_chain_iterator(this, pKey, 0x0);
+}
+
+template<typename HashEntryTy,
+         typename HashFunctionTy,
+         typename EntryFactoryTy>
+typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::const_chain_iterator
+HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::end(
+  const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey) const
+{
+  return const_chain_iterator();
+}
+
diff --git a/include/mcld/ADT/SizeTraits.h b/include/mcld/ADT/SizeTraits.h
new file mode 100644
index 0000000..8d307bd
--- /dev/null
+++ b/include/mcld/ADT/SizeTraits.h
@@ -0,0 +1,102 @@
+//===- SizeTraits.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SIZE_TRAITS_H
+#define MCLD_SIZE_TRAITS_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/Support/DataTypes.h>
+
+namespace mcld
+{
+
+template<size_t SIZE>
+struct SizeTraits;
+
+template<>
+class SizeTraits<32>
+{
+  typedef uint32_t Address;
+  typedef uint32_t Offset;
+  typedef uint32_t Word;
+  typedef int32_t  SWord;
+};
+
+template<>
+class SizeTraits<64>
+{
+  typedef uint64_t Address;
+  typedef uint64_t Offset;
+  typedef uint64_t Word;
+  typedef int64_t  SWord;
+};
+
+/// alignAddress - helper function to align an address with given alignment
+/// constraint
+///
+/// @param pAddr - the address to be aligned
+/// @param pAlignConstraint - the alignment used to align the given address
+inline void alignAddress(uint64_t& pAddr, uint64_t pAlignConstraint)
+{
+  if (pAlignConstraint != 0)
+    pAddr = (pAddr + pAlignConstraint - 1) &~ (pAlignConstraint - 1);
+}
+
+template<size_t Constraint>
+uint64_t Align(uint64_t pAddress);
+
+template<>
+inline uint64_t Align<32>(uint64_t pAddress)
+{
+  return (pAddress + 0x1F) & (~0x1F);
+}
+
+template<>
+inline uint64_t Align<64>(uint64_t pAddress)
+{
+  return (pAddress + 0x3F) & (~0x3F);
+}
+
+/// bswap16 - byte swap 16-bit version
+/// @ref binary utilities - elfcpp_swap
+inline uint16_t bswap16(uint16_t pData)
+{
+   return ((pData >> 8) & 0xFF) | ((pData & 0xFF) << 8);
+}
+
+/// bswap32 - byte swap 32-bit version
+/// @ref elfcpp_swap
+inline uint32_t bswap32(uint32_t pData)
+{
+   return (((pData & 0xFF000000) >> 24) |
+           ((pData & 0x00FF0000) >>  8) |
+           ((pData & 0x0000FF00) <<  8) |
+           ((pData & 0x000000FF) << 24));
+
+}
+
+/// bswap64 - byte swap 64-bit version
+/// @ref binary utilities - elfcpp_swap
+inline uint64_t bswap64(uint64_t pData)
+{
+   return (((pData & 0xFF00000000000000ULL) >> 56) |
+           ((pData & 0x00FF000000000000ULL) >> 40) |
+           ((pData & 0x0000FF0000000000ULL) >> 24) |
+           ((pData & 0x000000FF00000000ULL) >>  8) |
+           ((pData & 0x00000000FF000000ULL) <<  8) |
+           ((pData & 0x0000000000FF0000ULL) << 24) |
+           ((pData & 0x000000000000FF00ULL) << 40) |
+           ((pData & 0x00000000000000FFULL) << 56));
+}
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/StringHash.h b/include/mcld/ADT/StringHash.h
new file mode 100644
index 0000000..f100a49
--- /dev/null
+++ b/include/mcld/ADT/StringHash.h
@@ -0,0 +1,289 @@
+//===- StringHash.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_STRING_HASH_FUNCTION_H
+#define MCLD_STRING_HASH_FUNCTION_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/ADT/StringRef.h>
+#include <llvm/Support/ErrorHandling.h>
+#include <functional>
+
+namespace mcld
+{
+
+enum StringHashType
+{
+  RS,
+  JS,
+  PJW,
+  ELF,
+  BKDR,
+  SDBM,
+  DJB,
+  DEK,
+  BP,
+  FNV,
+  AP
+};
+
+/** \class template<size_t TYPE> StringHash
+ *  \brief the template StringHash class, for specification
+ */
+template<size_t TYPE>
+struct StringHash : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    llvm::report_fatal_error("Undefined StringHash function.\n");
+  }
+};
+
+/** \class StringHash<RSHash>
+ *  \brief RS StringHash funciton
+ */
+template<>
+struct StringHash<RS> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    const unsigned int b = 378551;
+    size_t a = 63689;
+    size_t hash_val = 0;
+
+    for(unsigned int i = 0; i < pKey.size(); ++i) {
+      hash_val = hash_val * a + pKey[i];
+      a = a * b;
+    }
+    return hash_val;
+  }
+};
+
+/** \class StringHash<JSHash>
+ *  \brief JS hash funciton
+ */
+template<>
+struct StringHash<JS> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    size_t hash_val = 1315423911;
+
+    for(unsigned int i = 0; i < pKey.size(); ++i) {
+       hash_val ^= ((hash_val << 5) + pKey[i] + (hash_val >> 2));
+    } 
+    return hash_val;
+  }
+};
+
+/** \class StringHash<PJW>
+ *  \brief P.J. Weinberger hash function
+ */
+template<>
+struct StringHash<PJW> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    const unsigned int BitsInUnsignedInt = (unsigned int)(sizeof(unsigned int) * 8);
+    const unsigned int ThreeQuarters     = (unsigned int)((BitsInUnsignedInt  * 3) / 4);
+    const unsigned int OneEighth         = (unsigned int)(BitsInUnsignedInt / 8);
+    const unsigned int HighBits          = (unsigned int)(0xFFFFFFFF) << (BitsInUnsignedInt - OneEighth);
+    size_t hash_val = 0;
+    size_t test = 0;
+
+    for(unsigned int i = 0; i < pKey.size(); ++i) {
+      hash_val = (hash_val << OneEighth) + pKey[i];
+
+      if((test = hash_val & HighBits) != 0) {
+        hash_val = (( hash_val ^ (test >> ThreeQuarters)) & (~HighBits));
+      }
+    }
+    return hash_val;
+  }
+};
+
+/** \class StringHash<ELF>
+ *  \brief ELF hash function.
+ */
+template<>
+struct StringHash<ELF> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    size_t hash_val = 0;
+    size_t x = 0;
+
+    for (unsigned int i = 0; i < pKey.size(); ++i) {
+      hash_val = (hash_val << 4) + pKey[i];
+      if((x = hash_val & 0xF0000000L) != 0)
+        hash_val ^= (x >> 24); 
+      hash_val &= ~x;
+    }
+    return hash_val;
+  }
+};
+
+/** \class StringHash<BKDR>
+ *  \brief BKDR hash function
+ */
+template<>
+struct StringHash<BKDR> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    const size_t seed = 131;
+    size_t hash_val = 0;
+      
+    for(size_t i = 0; i < pKey.size(); ++i)
+      hash_val = (hash_val * seed) + pKey[i];
+    return hash_val;
+  }
+};
+
+
+/** \class StringHash<SDBM>
+ *  \brief SDBM hash function
+ *  0.049s in 100000 test
+ */
+template<>
+struct StringHash<SDBM> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    size_t hash_val = 0;
+
+    for(size_t i = 0; i < pKey.size(); ++i)
+      hash_val = pKey[i] + (hash_val << 6) + (hash_val << 16) - hash_val;
+    return hash_val;
+  }
+};
+
+/** \class StringHash<DJB>
+ *  \brief DJB hash function
+ *  0.057s in 100000 test
+ */
+template<>
+struct StringHash<DJB> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    size_t hash_val = 5381;
+
+    for(size_t i = 0; i < pKey.size(); ++i)
+      hash_val = ((hash_val << 5) + hash_val) + pKey[i];
+
+    return hash_val;
+  }
+};
+
+/** \class StringHash<DEK>
+ *  \brief DEK hash function
+ *  0.60s
+ */
+template<>
+struct StringHash<DEK> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    size_t hash_val = pKey.size();
+
+    for(size_t i = 0; i < pKey.size(); ++i)
+      hash_val = ((hash_val << 5) ^ (hash_val >> 27)) ^ pKey[i];
+
+    return hash_val;
+  }
+};
+
+/** \class StringHash<BP>
+ *  \brief BP hash function
+ *  0.057s
+ */
+template<>
+struct StringHash<BP> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    size_t hash_val = 0;
+    for(size_t i = 0; i < pKey.size(); ++i)
+      hash_val = hash_val << 7 ^ pKey[i];
+
+    return hash_val;
+  }
+};
+
+/** \class StringHash<FNV>
+ *  \brief FNV hash function
+ *  0.058s
+ */
+template<>
+struct StringHash<FNV> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    const size_t fnv_prime = 0x811C9DC5;
+    size_t hash_val = 0;
+    for(size_t i = 0; i < pKey.size(); ++i) {
+      hash_val *= fnv_prime;
+      hash_val ^= pKey[i];
+    }
+
+    return hash_val;
+  }
+};
+
+/** \class StringHash<AP>
+ *  \brief AP hash function
+ *  0.060s
+ */
+template<>
+struct StringHash<AP> : public std::unary_function<const llvm::StringRef&, size_t>
+{
+  size_t operator()(const llvm::StringRef& pKey) const
+  {
+    unsigned int hash_val = 0xAAAAAAAA;
+   
+    for(size_t i = 0; i < pKey.size(); ++i) {  
+      hash_val ^= ((i & 1) == 0)?
+                          ((hash_val <<  7) ^ pKey[i] * (hash_val >> 3)):
+                          (~((hash_val << 11) + (pKey[i] ^ (hash_val >> 5))));
+    }
+   
+    return hash_val;
+  }
+};
+
+/** \class template<size_t TYPE> StringCompare
+ *  \brief the template StringCompare class, for specification
+ */
+template<typename STRING_TYPE>
+struct StringCompare : public std::binary_function<const STRING_TYPE&, const STRING_TYPE&, bool>
+{
+  bool operator()(const STRING_TYPE& X, const STRING_TYPE& Y) const
+  { return X == Y; }
+};
+
+template<>
+struct StringCompare<const char*> : public std::binary_function<const char*, const char*, bool>
+{
+  bool operator()(const char* X, const char* Y) const
+  { return (0 == std::strcmp(X, Y)); }
+};
+
+template<>
+struct StringCompare<char*> : public std::binary_function<const char*, const char*, bool>
+{
+  bool operator()(const char* X, const char* Y) const
+  { return (0 == std::strcmp(X, Y)); }
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/TreeAllocator.h b/include/mcld/ADT/TreeAllocator.h
new file mode 100644
index 0000000..899896c
--- /dev/null
+++ b/include/mcld/ADT/TreeAllocator.h
@@ -0,0 +1,98 @@
+//===- TreeAllocator.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_TREE_ALLOCATOR_H
+#define MCLD_TREE_ALLOCATOR_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <set>
+#include "mcld/Support/GCFactory.h"
+#include "mcld/ADT/TreeBase.h"
+
+namespace mcld
+{
+
+/** \class NodeFactory
+ *  \brief NodeFactory manages the creation and destruction of mcld::Node.
+ *
+ *  NodeFactory guarantees all allocated memory are released finally. When
+ *  the destructor of NodeFactory is called, all allocated memory are freed.
+ *
+ *  NodeFactory provides delegation of memory. Sometimes, we have to merge two
+ *  NodeFactories, and NodeFactory::delegate() can move the memory from one
+ *  NodeFactories to another.
+ *  
+ *  @see LinearAllocator
+ */
+template<typename DataType>
+class NodeFactory : public GCFactory<Node<DataType>, 64>
+{
+private:
+  typedef GCFactory<Node<DataType>, 64> Alloc;
+
+public:
+  typedef Node<DataType>                 NodeType;
+  typedef typename Alloc::iterator       iterator;
+  typedef typename Alloc::const_iterator const_iterator;
+
+public:
+  /// produce - produce a node, add it under control
+  NodeType* produce() {
+    NodeType* result = Alloc::allocate();
+    Alloc::construct(result);
+    return result;
+  }
+
+  /// delegate - get the control of chunks owned by the client
+  //  after calling delegate(), client will renouce its control
+  //  of memory space.
+  void delegate(NodeFactory& pClient) {
+    if (this == &pClient)
+      return;
+
+    if (pClient.empty())
+      return;
+
+    if (Alloc::empty()) {
+      replace(pClient);
+      pClient.renounce();
+      return;
+    }
+
+    // neither me nor client is empty
+    concatenate(pClient);
+    pClient.renounce();
+  }
+
+private:
+  /// renounce - give up the control of all chunks
+  void renounce()
+  { Alloc::reset(); }
+
+  /// replace - be the agent of client.
+  void replace(NodeFactory& pClient) {
+    Alloc::m_pRoot = pClient.Alloc::m_pRoot;
+    Alloc::m_pCurrent = pClient.Alloc::m_pCurrent;
+    Alloc::m_AllocatedNum = pClient.Alloc::m_AllocatedNum;
+    Alloc::m_NumAllocData = pClient.Alloc::m_NumAllocData;
+  }
+
+  /// concatenate - conncet two factories
+  void concatenate(NodeFactory& pClient) {
+    Alloc::m_pCurrent->next = pClient.Alloc::m_pRoot;
+    Alloc::m_pCurrent = pClient.Alloc::m_pCurrent;
+    Alloc::m_AllocatedNum += pClient.Alloc::m_AllocatedNum;
+    Alloc::m_NumAllocData += pClient.Alloc::m_NumAllocData;
+  }
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/TreeBase.h b/include/mcld/ADT/TreeBase.h
new file mode 100644
index 0000000..c518975
--- /dev/null
+++ b/include/mcld/ADT/TreeBase.h
@@ -0,0 +1,127 @@
+//===- TreeBase.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_TREE_BASE_H
+#define MCLD_TREE_BASE_H
+#include "mcld/ADT/TypeTraits.h"
+
+namespace mcld
+{
+
+class NodeBase
+{
+public:
+  NodeBase *left;
+  NodeBase *right;
+
+public:
+  NodeBase()
+  : left(0), right(0)
+  { }
+};
+
+namespace proxy
+{
+  template<size_t DIRECT>
+  inline void move(NodeBase *&X)
+  { assert(0 && "not allowed"); }
+
+  template<size_t DIRECT>
+  inline void hook(NodeBase *X, const NodeBase *Y)
+  { assert(0 && "not allowed"); }
+
+} // namespace of template proxy
+
+struct TreeIteratorBase
+{
+public:
+  enum Direct {
+    Leftward,
+    Rightward
+  };
+
+  typedef size_t                          size_type;
+  typedef ptrdiff_t                       difference_type;
+  typedef std::bidirectional_iterator_tag iterator_category;
+
+public:
+  NodeBase* m_pNode;
+
+public:
+  TreeIteratorBase()
+  : m_pNode(0)
+  { }
+
+  TreeIteratorBase(NodeBase *X)
+  : m_pNode(X)
+  { }
+
+  virtual ~TreeIteratorBase(){};
+
+  template<size_t DIRECT>
+  inline void move() {
+    proxy::move<DIRECT>(m_pNode);
+  }
+
+  bool hasRightChild() const
+  { return ((m_pNode->right) != (m_pNode->right->right)); }
+
+  bool hasLeftChild() const
+  { return ((m_pNode->left) != (m_pNode->left->right)); }
+
+  bool operator==(const TreeIteratorBase& y) const
+  { return this->m_pNode == y.m_pNode; }
+
+  bool operator!=(const TreeIteratorBase& y) const
+  { return this->m_pNode != y.m_pNode; }
+};
+
+namespace proxy
+{
+  template<>
+  inline void move<TreeIteratorBase::Leftward>(NodeBase *&X) 
+  { X = X->left; }
+
+  template<>
+  inline void move<TreeIteratorBase::Rightward>(NodeBase *&X)
+  { X = X->right; }
+
+  template<>
+  inline void hook<TreeIteratorBase::Leftward>(NodeBase *X, const NodeBase *Y)
+  { X->left = const_cast<NodeBase*>(Y); }
+
+  template<>
+  inline void hook<TreeIteratorBase::Rightward>(NodeBase* X, const NodeBase* Y)
+  { X->right = const_cast<NodeBase*>(Y); }
+
+} //namespace of template proxy
+
+template<typename DataType>
+class Node : public NodeBase
+{
+public:
+  typedef DataType        value_type;
+
+public:
+  value_type* data;
+
+public:
+  Node()
+  : NodeBase(), data(0)
+  { }
+
+  Node(const value_type& pValue)
+  : NodeBase(), data(&pValue)
+  { }
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/TypeTraits.h b/include/mcld/ADT/TypeTraits.h
new file mode 100644
index 0000000..90b2224
--- /dev/null
+++ b/include/mcld/ADT/TypeTraits.h
@@ -0,0 +1,71 @@
+//===- TypeTraits.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_TYPE_TRAITS_H
+#define MCLD_TYPE_TRAITS_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <cstdlib>
+
+namespace mcld
+{
+template<typename DataType>
+struct NonConstTraits;
+
+template<typename DataType>
+struct ConstTraits
+{
+  typedef DataType                 value_type;
+  typedef const DataType*          pointer;
+  typedef const DataType&          reference;
+  typedef size_t                   size_type;
+  typedef ConstTraits<DataType>    const_traits;
+  typedef NonConstTraits<DataType> nonconst_traits;
+};
+
+template<typename DataType>
+struct NonConstTraits
+{
+  typedef DataType                 value_type;
+  typedef DataType*                pointer;
+  typedef DataType&                reference;
+  typedef size_t                   size_type;
+  typedef ConstTraits<DataType>    const_traits;
+  typedef NonConstTraits<DataType> nonconst_traits;
+};
+
+template<typename DataType>
+struct ConstIteratorTraits
+{
+  typedef DataType                          value_type;
+  typedef const DataType*                   pointer;
+  typedef const DataType&                   reference;
+  typedef size_t                            size_type;
+  typedef ConstTraits<DataType>             const_traits;
+  typedef NonConstTraits<DataType>          nonconst_traits;
+  typedef typename DataType::const_iterator iterator;
+};
+
+template<typename DataType>
+struct NonConstIteratorTraits
+{
+  typedef DataType                    value_type;
+  typedef DataType*                   pointer;
+  typedef DataType&                   reference;
+  typedef size_t                      size_type;
+  typedef ConstTraits<DataType>       const_traits;
+  typedef NonConstTraits<DataType>    nonconst_traits;
+  typedef typename DataType::iterator iterator;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/ADT/Uncopyable.h b/include/mcld/ADT/Uncopyable.h
new file mode 100644
index 0000000..7ddfbe3
--- /dev/null
+++ b/include/mcld/ADT/Uncopyable.h
@@ -0,0 +1,36 @@
+//===- Uncopyable.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_UNCOPYABLE_H
+#define MCLD_UNCOPYABLE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+namespace mcld
+{
+
+/** \class Uncopyable
+ *  \brief Uncopyable provides the base class to forbit copy operations.
+ *
+ */
+class Uncopyable
+{
+protected:
+  Uncopyable() { }
+  ~Uncopyable() { }
+
+private:
+  Uncopyable(const Uncopyable&); /// NOT TO IMPLEMENT
+  Uncopyable& operator=(const Uncopyable&); /// NOT TO IMPLEMENT
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/CodeGen/SectLinker.h b/include/mcld/CodeGen/SectLinker.h
new file mode 100644
index 0000000..31fae4a
--- /dev/null
+++ b/include/mcld/CodeGen/SectLinker.h
@@ -0,0 +1,107 @@
+//===- SectLinker.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//SectLinker is a base class inherited by target specific linker.
+//This class primarily handles common functionality used by all linkers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SECTION_LINKER_H
+#define SECTION_LINKER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/CodeGen/MachineFunctionPass.h>
+#include <mcld/Support/PositionDependentOption.h>
+#include <vector>
+
+namespace llvm
+{
+  class Module;
+  class MachineFunction;
+} // namespace of llvm
+
+namespace mcld
+{
+  class MCLDFile;
+  class MCLDDriver;
+  class TargetLDBackend;
+  class AttributeFactory;
+  class SectLinkerOption;
+
+  /** \class SectLinker
+   *  \brief SectLinker provides a linking pass for standard compilation flow
+   *
+   *  SectLinker is responded for
+   *  - provide an interface for target-specific SectLinekr
+   *  - set up environment for MCLDDriver
+   *  - control AsmPrinter, make sure AsmPrinter has already prepared
+   *    all MCSectionDatas for linking
+   *
+   *  SectLinker resolves the absolue paths of input arguments.
+   *
+   *  @see MachineFunctionPass MCLDDriver
+   */
+  class SectLinker : public llvm::MachineFunctionPass
+  {
+  protected:
+    // Constructor. Although SectLinker has only two arguments,
+    // TargetSectLinker should handle
+    // - enabled attributes
+    // - the default attribute
+    // - the default link script
+    // - the standard symbols
+    SectLinker(SectLinkerOption &pOption,
+               TargetLDBackend &pLDBackend);
+
+  public:
+    virtual ~SectLinker();
+
+    /// addTargetOptions - target SectLinker can hook this function to add
+    /// target-specific inputs
+    virtual void addTargetOptions(llvm::Module &pM,
+                                  SectLinkerOption &pOption)
+    { }
+
+    /// doInitialization - Read all parameters and set up the AsmPrinter.
+    /// If your pass overrides this, it must make sure to explicitly call
+    /// this implementation.
+    virtual bool doInitialization(llvm::Module &pM);
+
+    /// doFinalization - Shut down the AsmPrinter, and do really linking.
+    /// If you override this in your pass, you must make sure to call it
+    /// explicitly.
+    virtual bool doFinalization(llvm::Module &pM);
+
+    /// runOnMachineFunction
+    /// redirect to AsmPrinter
+    virtual bool runOnMachineFunction(llvm::MachineFunction& pMFn);
+
+  protected:
+    void initializeInputTree(const PositionDependentOptions &pOptions) const;
+
+    AttributeFactory* attrFactory()
+    { return m_pAttrFactory; }
+
+  private:
+    SectLinkerOption *m_pOption;
+
+  protected:
+    TargetLDBackend *m_pLDBackend;
+    MCLDDriver *m_pLDDriver;
+    AttributeFactory *m_pAttrFactory;
+
+  private:
+    static char m_ID;
+  };
+
+} // namespace of MC Linker
+
+#endif
+
diff --git a/include/mcld/CodeGen/SectLinkerOption.h b/include/mcld/CodeGen/SectLinkerOption.h
new file mode 100644
index 0000000..b3e3327
--- /dev/null
+++ b/include/mcld/CodeGen/SectLinkerOption.h
@@ -0,0 +1,57 @@
+//===- SectLinkerOption.h ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SECTLINKERDATA_H
+#define MCLD_SECTLINKERDATA_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/MC/MCLDInfo.h"
+#include "mcld/Support/PositionDependentOption.h"
+
+#include <string>
+
+namespace mcld
+{
+  class PositionDependentOption;
+
+  /** \class SectLinkerOption
+   *  \brief This file collects inputs to linker.
+   */
+  class SectLinkerOption
+  {
+  public:
+    // Constructor.
+    SectLinkerOption(MCLDInfo &pLDInfo);
+
+    // -----  Position-dependent Options  ----- //
+    inline void appendOption(PositionDependentOption *pOption)
+    { m_PosDepOptions.push_back(pOption); }
+
+    inline void prependOption(PositionDependentOption *pOption)
+    { m_PosDepOptions.insert(m_PosDepOptions.begin(), pOption); }
+
+    inline const PositionDependentOptions &pos_dep_options() const
+    { return m_PosDepOptions; }
+    inline PositionDependentOptions &pos_dep_options()
+    { return m_PosDepOptions; }
+
+    inline const MCLDInfo &info() const { return *m_pLDInfo; }
+    inline MCLDInfo &info() { return *m_pLDInfo; }
+
+    ~SectLinkerOption();
+
+  private:
+    MCLDInfo *m_pLDInfo;
+    PositionDependentOptions m_PosDepOptions;
+  };
+
+} // namespace of mcld
+
+#endif
diff --git a/include/mcld/Config/Config.h b/include/mcld/Config/Config.h
new file mode 100644
index 0000000..362b076
--- /dev/null
+++ b/include/mcld/Config/Config.h
@@ -0,0 +1,26 @@
+//===- Config.h.in --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Hand-coded for Android build
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_CONFIG_H
+#define MCLD_CONFIG_H
+
+namespace mcld {
+namespace internal {
+
+static const char* version="0.2.10.1-18peaks";
+
+} // namespace of internal
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Config/Config.h.in b/include/mcld/Config/Config.h.in
new file mode 100644
index 0000000..6d428c0
--- /dev/null
+++ b/include/mcld/Config/Config.h.in
@@ -0,0 +1,21 @@
+//===- Config.h.in --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_CONFIG_H
+#define MCLD_CONFIG_H
+
+namespace mcld {
+namespace internal {
+
+static const char* version="@MCLD_VERSION@";
+
+} // namespace of internal
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Config/Linkers.def b/include/mcld/Config/Linkers.def
new file mode 100644
index 0000000..2781461
--- /dev/null
+++ b/include/mcld/Config/Linkers.def
@@ -0,0 +1,33 @@
+//===- llvm/Config/Linkers.def - LLVM Linkers -------------------*- C++ -*-===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file enumerates all of the linkers supported by this build of LLVM.
+// Clients of this file should define the LLVM_LINKER macro to be a function-like
+// macro with a single parameter (the name of the target whose exe/dso can be
+// generated); including this file will then enumerate all of the targets with
+// linkers.
+//
+// The set of targets supported by LLVM is generated at configuration
+// time, at which point this header is generated. Do not modify this
+// header directly.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Hand-coded for Android build
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LINKER
+#  error Please define the macro LLVM_LINKER(TargetName)
+#endif
+
+#define LLVM_TARGET LLVM_LINKER
+#include <llvm/Config/Targets.def>
+
+#undef LLVM_LINKER
diff --git a/include/mcld/Config/Linkers.def.in b/include/mcld/Config/Linkers.def.in
new file mode 100644
index 0000000..0e09040
--- /dev/null
+++ b/include/mcld/Config/Linkers.def.in
@@ -0,0 +1,28 @@
+//===- llvm/Config/Linkers.def - LLVM Linkers -------------------*- C++ -*-===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file enumerates all of the linkers supported by this build of LLVM. 
+// Clients of this file should define the LLVM_LINKER macro to be a function-like 
+// macro with a single parameter (the name of the target whose exe/dso can be
+// generated); including this file will then enumerate all of the targets with
+// linkers.
+//
+// The set of targets supported by LLVM is generated at configuration
+// time, at which point this header is generated. Do not modify this
+// header directly.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LINKER
+#  error Please define the macro LLVM_LINKER(TargetName)
+#endif
+
+@LLVM_ENUM_LINKERS@
+
+#undef LLVM_LINKER
diff --git a/include/mcld/Config/Targets.def b/include/mcld/Config/Targets.def
new file mode 100644
index 0000000..a0981d6
--- /dev/null
+++ b/include/mcld/Config/Targets.def
@@ -0,0 +1,32 @@
+/*===- llvm/Config/Targets.def - LLVM Target Architectures ------*- C++ -*-===*\
+|*                                                                            *|
+|*                     The MCLinker Project                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This file enumerates all of the target architectures supported by          *|
+|* this build of LLVM. Clients of this file should define the                 *|
+|* LLVM_TARGET macro to be a function-like macro with a single                *|
+|* parameter (the name of the target); including this file will then          *|
+|* enumerate all of the targets.                                              *|
+|*                                                                            *|
+|* The set of targets supported by LLVM is generated at configuration         *|
+|* time, at which point this header is generated. Do not modify this          *|
+|* header directly.                                                           *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+//===----------------------------------------------------------------------===//
+// Hand-coded for Android build
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET
+#  error Please define the macro LLVM_TARGET(TargetName)
+#endif
+
+#include <llvm/Config/Targets.def>
+
+#undef LLVM_TARGET
diff --git a/include/mcld/Config/Targets.def.in b/include/mcld/Config/Targets.def.in
new file mode 100644
index 0000000..a73b9b7
--- /dev/null
+++ b/include/mcld/Config/Targets.def.in
@@ -0,0 +1,28 @@
+/*===- llvm/Config/Targets.def - LLVM Target Architectures ------*- C++ -*-===*\
+|*                                                                            *|
+|*                     The MCLinker Project                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This file enumerates all of the target architectures supported by          *|
+|* this build of LLVM. Clients of this file should define the                 *|
+|* LLVM_TARGET macro to be a function-like macro with a single                *|
+|* parameter (the name of the target); including this file will then          *|
+|* enumerate all of the targets.                                              *|
+|*                                                                            *|
+|* The set of targets supported by LLVM is generated at configuration         *|
+|* time, at which point this header is generated. Do not modify this          *|
+|* header directly.                                                           *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_TARGET
+#  error Please define the macro LLVM_TARGET(TargetName)
+#endif
+
+@LLVM_ENUM_TARGETS@
+
+#undef LLVM_TARGET
diff --git a/include/mcld/LD/ArchiveReader.h b/include/mcld/LD/ArchiveReader.h
new file mode 100644
index 0000000..99db0db
--- /dev/null
+++ b/include/mcld/LD/ArchiveReader.h
@@ -0,0 +1,39 @@
+//===- ArchiveReader.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ARCHIVE_READER_INTERFACE_H
+#define MCLD_ARCHIVE_READER_INTERFACE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/LD/LDReader.h"
+
+namespace mcld
+{
+
+class Input;
+class InputTree;
+
+/** \class ArchiveReader
+ *  \brief ArchiveReader provides an common interface for all archive readers.
+ *
+ *  ArchiveReader also reads the target-independent parts of an archive file.
+ */
+class ArchiveReader : public LDReader
+{
+public:
+  ArchiveReader();
+  virtual ~ArchiveReader();
+
+  virtual InputTree *readArchive(Input &input) = 0;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/BSDArchiveReader.h b/include/mcld/LD/BSDArchiveReader.h
new file mode 100644
index 0000000..a275621
--- /dev/null
+++ b/include/mcld/LD/BSDArchiveReader.h
@@ -0,0 +1,39 @@
+//===- BSDArchiveReader.h -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_BSD_ARCHIVE_READER_H
+#define MCLD_BSD_ARCHIVE_READER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/LD/ArchiveReader.h"
+
+namespace mcld
+{
+
+class Input;
+class InputTree;
+
+/** \class BSDArchiveReader
+ *  \brief BSDArchiveReader reads BSD-variant archive files.
+ *
+ */
+class BSDArchiveReader : public ArchiveReader
+{
+public:
+  BSDArchiveReader();
+  ~BSDArchiveReader();
+
+  InputTree *readArchive(Input &input);
+  bool isMyFormat(Input& pInput) const;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/BranchIsland.h b/include/mcld/LD/BranchIsland.h
new file mode 100644
index 0000000..8e5cf9c
--- /dev/null
+++ b/include/mcld/LD/BranchIsland.h
@@ -0,0 +1,30 @@
+//===- BranchIsland.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef BRANCHISLAND_H
+#define BRANCHISLAND_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+namespace mcld
+{
+
+/** \class BranchIsland
+ *  \brief BranchIsland is a collection of stubs
+ *
+ */
+class BranchIsland
+{
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/DynObjFileFormat.h b/include/mcld/LD/DynObjFileFormat.h
new file mode 100644
index 0000000..7b1626d
--- /dev/null
+++ b/include/mcld/LD/DynObjFileFormat.h
@@ -0,0 +1,29 @@
+//===- header.h -----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef DYNOBJFORMAT_H
+#define DYNOBJFORMAT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+namespace mcld
+{
+
+/** \class DynObjFormat
+ *  \brief DynObjFormat describes the file format for dynamic objects.
+ */
+class DynObjFormat : public LDFileFormat
+{
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/DynObjReader.h b/include/mcld/LD/DynObjReader.h
new file mode 100644
index 0000000..0900109
--- /dev/null
+++ b/include/mcld/LD/DynObjReader.h
@@ -0,0 +1,45 @@
+//===- DynObjReader.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_DYNAMIC_SHARED_OBJECT_READER_H
+#define MCLD_DYNAMIC_SHARED_OBJECT_READER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/LD/LDReader.h"
+#include <llvm/Support/system_error.h>
+
+namespace mcld
+{
+
+class TargetLDBackend;
+class Input;
+
+/** \class DynObjReader
+ *  \brief DynObjReader provides an common interface for different object
+ *  formats.
+ */
+class DynObjReader : public LDReader
+{
+protected:
+  DynObjReader()
+  { }
+
+public:
+  virtual ~DynObjReader() { }
+
+  virtual bool readDSO(Input& pFile) = 0;
+
+  virtual bool readSymbols(Input& pFile) = 0;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/DynObjWriter.h b/include/mcld/LD/DynObjWriter.h
new file mode 100644
index 0000000..1c77bd4
--- /dev/null
+++ b/include/mcld/LD/DynObjWriter.h
@@ -0,0 +1,41 @@
+//===- DynObjWriter.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_DYNAMIC_SHARED_OBJECT_WRITER_H
+#define MCLD_DYNAMIC_SHARED_OBJECT_WRITER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/MC/MCLDOutput.h>
+#include <mcld/LD/LDWriter.h>
+#include <llvm/Support/system_error.h>
+
+namespace mcld
+{
+
+/** \class DynObjWriter
+ *  \brief DynObjWriter provides an common interface for different object
+ *  formats.
+ */
+class DynObjWriter : public LDWriter
+{
+protected:
+  // force to have a TargetLDBackend
+  DynObjWriter(TargetLDBackend& pLDBackend)
+  { }
+
+public:
+  virtual ~DynObjWriter() { }
+
+  virtual llvm::error_code writeDynObj(Output& pOutput) = 0;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFDynObjFileFormat.h b/include/mcld/LD/ELFDynObjFileFormat.h
new file mode 100644
index 0000000..9b77e91
--- /dev/null
+++ b/include/mcld/LD/ELFDynObjFileFormat.h
@@ -0,0 +1,38 @@
+//===- ELFDynObjFileFormat.h ----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_DYNAMIC_OBJECT_FILE_FROMAT_H
+#define MCLD_ELF_DYNAMIC_OBJECT_FILE_FROMAT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/LD/ELFFileFormat.h>
+
+namespace mcld
+{
+
+class GNULDBackend;
+class MCLinker;
+
+/** \class ELFDynObjFileFormat
+ *  \brief ELFDynObjFileFormat describes the format for ELF dynamic objects.
+ */
+class ELFDynObjFileFormat : public ELFFileFormat
+{
+public:
+  ELFDynObjFileFormat(GNULDBackend& pBackend) : ELFFileFormat(pBackend)
+  {}
+
+  void initObjectType(MCLinker& pLinker);
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFDynObjReader.h b/include/mcld/LD/ELFDynObjReader.h
new file mode 100644
index 0000000..72a3336
--- /dev/null
+++ b/include/mcld/LD/ELFDynObjReader.h
@@ -0,0 +1,51 @@
+//===- ELFDynObjReader.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_DYNAMIC_SHARED_OBJECT_READER_H
+#define MCLD_ELF_DYNAMIC_SHARED_OBJECT_READER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/LD/DynObjReader.h>
+#include <llvm/Support/system_error.h>
+
+namespace mcld
+{
+
+class Input;
+class MCLinker;
+class GNULDBackend;
+class ELFReaderIF;
+
+/** \class ELFDynObjReader
+ *  \brief ELFDynObjReader reads ELF dynamic shared objects.
+ *
+ */
+class ELFDynObjReader : public DynObjReader
+{
+public:
+  ELFDynObjReader(GNULDBackend& pBackend, MCLinker& pLinker);
+  ~ELFDynObjReader();
+
+  // -----  observers  ----- //
+  bool isMyFormat(Input &pFile) const;
+
+  // -----  readers  ----- //
+  bool readDSO(Input& pFile);
+
+  bool readSymbols(Input& pInput);
+
+private:
+  ELFReaderIF *m_pELFReader;
+  MCLinker& m_Linker;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFDynObjWriter.h b/include/mcld/LD/ELFDynObjWriter.h
new file mode 100644
index 0000000..dc0e37b
--- /dev/null
+++ b/include/mcld/LD/ELFDynObjWriter.h
@@ -0,0 +1,53 @@
+//===- ELFDynObjWriter.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_DYNAMIC_SHARED_OBJECT_WRITER_H
+#define MCLD_ELF_DYNAMIC_SHARED_OBJECT_WRITER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/ADT/DenseMap.h>
+#include <llvm/Support/ELF.h>
+#include <mcld/LD/DynObjWriter.h>
+#include <mcld/LD/ELFWriter.h>
+#include <mcld/LD/LDContext.h>
+#include <mcld/LD/LDSection.h>
+#include <mcld/Support/MemoryArea.h>
+#include <vector>
+#include <utility>
+
+
+namespace mcld
+{
+
+class GNULDBackend;
+class MCLinker;
+
+/** \class ELFDynObjWriter
+ *  \brief ELFDynObjWriter writes the dynamic sections.
+ */
+class ELFDynObjWriter : public DynObjWriter, private ELFWriter
+{
+public:
+  typedef ELFWriter::FileOffset FileOffset;
+
+public:
+  ELFDynObjWriter(GNULDBackend& pBackend, MCLinker& pLinker);
+  ~ELFDynObjWriter();
+
+  llvm::error_code writeDynObj(Output& pOutput);
+
+private:
+  GNULDBackend& m_Backend;
+  MCLinker& m_Linker;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFExecFileFormat.h b/include/mcld/LD/ELFExecFileFormat.h
new file mode 100644
index 0000000..315300a
--- /dev/null
+++ b/include/mcld/LD/ELFExecFileFormat.h
@@ -0,0 +1,38 @@
+//===- ELFExecFileFormat.h ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_EXEC_FILE_FORMAT_H
+#define MCLD_ELF_EXEC_FILE_FORMAT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/LD/ELFFileFormat.h>
+
+namespace mcld
+{
+
+class GNULDBackend;
+class MCLinker;
+
+/** \class ELFExecFileFormat
+ *  \brief ELFExecFileFormat describes the format for ELF dynamic objects.
+ */
+class ELFExecFileFormat : public ELFFileFormat
+{
+public:
+  ELFExecFileFormat(GNULDBackend& pBackend) : ELFFileFormat(pBackend)
+  {}
+
+  void initObjectType(MCLinker& pLinker)
+  { /** TODO **/ }
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFFileFormat.h b/include/mcld/LD/ELFFileFormat.h
new file mode 100644
index 0000000..94d3df3
--- /dev/null
+++ b/include/mcld/LD/ELFFileFormat.h
@@ -0,0 +1,654 @@
+//===- LDFileFormat.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_FILE_FORMAT_H
+#define MCLD_ELF_FILE_FORMAT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/LD/LDFileFormat.h>
+#include <mcld/LD/LDSection.h>
+
+namespace mcld
+{
+
+class GNULDBackend;
+class MCLinker;
+
+/** \class ELFFileFormat
+ *  \brief ELFFileFormat describes the common file formats in ELF.
+ *  LDFileFormats control the formats of the output file.
+ *
+ *  @ref "Object Files," Ch. 4, in System V Application Binary Interface,
+ *  Fourth Edition.
+ *
+ *  @ref "Object Format," Ch. 10, in ISO/IEC 23360 Part 1:2010(E), Linux
+ *  Standard Base Core Specification 4.1.
+ */
+class ELFFileFormat : public LDFileFormat
+{
+public:
+  ELFFileFormat(GNULDBackend& pBackend);
+
+  virtual ~ELFFileFormat();
+
+  virtual void initObjectFormat(MCLinker& pLinker);
+
+  virtual void initObjectType(MCLinker& pLinker) = 0;
+
+  // -----  capacity  ----- //
+  /// @ref Special Sections, Ch. 4.17, System V ABI, 4th edition.
+  bool hasNULLSection() const
+  { return (NULL != f_pNULLSection) && (0 != f_pNULLSection->size()); }
+
+  bool hasGOT() const
+  { return (NULL != f_pGOT) && (0 != f_pGOT->size()); }
+
+  bool hasPLT() const
+  { return (NULL != f_pPLT) && (0 != f_pPLT->size()); }
+
+  bool hasRelDyn() const
+  { return (NULL != f_pRelDyn) && (0 != f_pRelDyn->size()); }
+
+  bool hasRelPlt() const
+  { return (NULL != f_pRelPlt) && (0 != f_pRelPlt->size()); }
+
+  bool hasRelaDyn() const
+  { return (NULL != f_pRelaDyn) && (0 != f_pRelaDyn->size()); }
+
+  bool hasRelaPlt() const
+  { return (NULL != f_pRelaPlt) && (0 != f_pRelaPlt->size()); }
+
+  /// @ref 10.3.1.1, ISO/IEC 23360, Part 1:2010(E), p. 21.
+  bool hasComment() const
+  { return (NULL != f_pComment) && (0 != f_pComment->size()); }
+
+  bool hasData1() const
+  { return (NULL != f_pData1) && (0 != f_pData1->size()); }
+
+  bool hasDebug() const
+  { return (NULL != f_pDebug) && (0 != f_pDebug->size()); }
+
+  bool hasDynamic() const
+  { return (NULL != f_pDynamic) && (0 != f_pDynamic->size()); }
+
+  bool hasDynStrTab() const
+  { return (NULL != f_pDynStrTab) && (0 != f_pDynStrTab->size()); }
+
+  bool hasDynSymTab() const
+  { return (NULL != f_pDynSymTab) && (0 != f_pDynSymTab->size()); }
+
+  bool hasFini() const
+  { return (NULL != f_pFini) && (0 != f_pFini->size()); }
+
+  bool hasFiniArray() const
+  { return (NULL != f_pFiniArray) && (0 != f_pFiniArray->size()); }
+
+  bool hasHashTab() const
+  { return (NULL != f_pHashTab) && (0 != f_pHashTab->size()); }
+
+  bool hasInit() const
+  { return (NULL != f_pInit) && (0 != f_pInit->size()); }
+
+  bool hasInitArray() const
+  { return (NULL != f_pInitArray) && (0 != f_pInitArray->size()); }
+
+  bool hasInterp() const
+  { return (NULL != f_pInterp) && (0 != f_pInterp->size()); }
+
+  bool hasLine() const
+  { return (NULL != f_pLine) && (0 != f_pLine->size()); }
+
+  bool hasNote() const
+  { return (NULL != f_pNote) && (0 != f_pNote->size()); }
+
+  bool hasPreInitArray() const
+  { return (NULL != f_pPreInitArray) && (0 != f_pPreInitArray->size()); }
+
+  bool hasROData1() const
+  { return (NULL != f_pROData1) && (0 != f_pROData1->size()); }
+
+  bool hasShStrTab() const
+  { return (NULL != f_pShStrTab) && (0 != f_pShStrTab->size()); }
+
+  bool hasStrTab() const
+  { return (NULL != f_pStrTab) && (0 != f_pStrTab->size()); }
+
+  bool hasSymTab() const
+  { return (NULL != f_pSymTab) && (0 != f_pSymTab->size()); }
+
+  bool hasTBSS() const
+  { return (NULL != f_pTBSS) && (0 != f_pTBSS->size()); }
+
+  bool hasTData() const
+  { return (NULL != f_pTData) && (0 != f_pTData->size()); }
+
+  /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24.
+  bool hasCtors() const
+  { return (NULL != f_pCtors) && (0 != f_pCtors->size()); }
+
+  bool hasDataRelRo() const
+  { return (NULL != f_pDataRelRo) && (0 != f_pDataRelRo->size()); }
+
+  bool hasDtors() const
+  { return (NULL != f_pDtors) && (0 != f_pDtors->size()); }
+
+  bool hasEhFrame() const
+  { return (NULL != f_pEhFrame) && (0 != f_pEhFrame->size()); }
+
+  bool hasEhFrameHdr() const
+  { return (NULL != f_pEhFrameHdr) && (0 != f_pEhFrameHdr->size()); }
+
+  bool hasGCCExceptTable() const
+  { return (NULL != f_pGCCExceptTable) && (0 != f_pGCCExceptTable->size()); }
+
+  bool hasGNUVersion() const
+  { return (NULL != f_pGNUVersion) && (0 != f_pGNUVersion->size()); }
+
+  bool hasGNUVersionD() const
+  { return (NULL != f_pGNUVersionD) && (0 != f_pGNUVersionD->size()); }
+
+  bool hasGNUVersionR() const
+  { return (NULL != f_pGNUVersionR) && (0 != f_pGNUVersionR->size()); }
+
+  bool hasGOTPLT() const
+  { return (NULL != f_pGOTPLT) && (0 != f_pGOTPLT->size()); }
+
+  bool hasJCR() const
+  { return (NULL != f_pJCR) && (0 != f_pJCR->size()); }
+
+  bool hasNoteABITag() const
+  { return (NULL != f_pNoteABITag) && (0 != f_pNoteABITag->size()); }
+
+  bool hasStab() const
+  { return (NULL != f_pStab) && (0 != f_pStab->size()); }
+
+  bool hasStabStr() const
+  { return (NULL != f_pStabStr) && (0 != f_pStabStr->size()); }
+
+  // -----  access functions  ----- //
+  /// @ref Special Sections, Ch. 4.17, System V ABI, 4th edition.
+  LDSection& getNULLSection() {
+    assert(NULL != f_pNULLSection);
+    return *f_pNULLSection;
+  }
+
+  const LDSection& getNULLSection() const {
+    assert(NULL != f_pNULLSection);
+    return *f_pNULLSection;
+  }
+
+  LDSection& getGOT() {
+    assert(NULL != f_pGOT);
+    return *f_pGOT;
+  }
+
+  const LDSection& getGOT() const {
+    assert(NULL != f_pGOT);
+    return *f_pGOT;
+  }
+
+  LDSection& getPLT() {
+    assert(NULL != f_pPLT);
+    return *f_pPLT;
+  }
+
+  const LDSection& getPLT() const {
+    assert(NULL != f_pPLT);
+    return *f_pPLT;
+  }
+
+  LDSection& getRelDyn() {
+    assert(NULL != f_pRelDyn);
+    return *f_pRelDyn;
+  }
+
+  const LDSection& getRelDyn() const {
+    assert(NULL != f_pRelDyn);
+    return *f_pRelDyn;
+  }
+
+  LDSection& getRelPlt() {
+    assert(NULL != f_pRelPlt);
+    return *f_pRelPlt;
+  }
+
+  const LDSection& getRelPlt() const {
+    assert(NULL != f_pRelPlt);
+    return *f_pRelPlt;
+  }
+
+  LDSection& getRelaDyn() {
+    assert(NULL != f_pRelaDyn);
+    return *f_pRelaDyn;
+  }
+
+  const LDSection& getRelaDyn() const {
+    assert(NULL != f_pRelaDyn);
+    return *f_pRelaDyn;
+  }
+
+  LDSection& getRelaPlt() {
+    assert(NULL != f_pRelaPlt);
+    return *f_pRelaPlt;
+  }
+
+  const LDSection& getRelaPlt() const {
+    assert(NULL != f_pRelaPlt);
+    return *f_pRelaPlt;
+  }
+
+  LDSection& getComment() {
+    assert(NULL != f_pComment);
+    return *f_pComment;
+  }
+
+  /// @ref 10.3.1.1, ISO/IEC 23360, Part 1:2010(E), p. 21.
+  const LDSection& getComment() const {
+    assert(NULL != f_pComment);
+    return *f_pComment;
+  }
+
+  LDSection& getData1() {
+    assert(NULL != f_pData1);
+    return *f_pData1;
+  }
+
+  const LDSection& getData1() const {
+    assert(NULL != f_pData1);
+    return *f_pData1;
+  }
+
+  LDSection& getDebug() {
+    assert(NULL != f_pDebug);
+    return *f_pDebug;
+  }
+
+  const LDSection& getDebug() const {
+    assert(NULL != f_pDebug);
+    return *f_pDebug;
+  }
+
+  LDSection& getDynamic() {
+    assert(NULL != f_pDynamic);
+    return *f_pDynamic;
+  }
+
+  const LDSection& getDynamic() const {
+    assert(NULL != f_pDynamic);
+    return *f_pDynamic;
+  }
+
+  LDSection& getDynStrTab() {
+    assert(NULL != f_pDynStrTab);
+    return *f_pDynStrTab;
+  }
+
+  const LDSection& getDynStrTab() const {
+    assert(NULL != f_pDynStrTab);
+    return *f_pDynStrTab;
+  }
+
+  LDSection& getDynSymTab() {
+    assert(NULL != f_pDynSymTab);
+    return *f_pDynSymTab;
+  }
+
+  const LDSection& getDynSymTab() const {
+    assert(NULL != f_pDynSymTab);
+    return *f_pDynSymTab;
+  }
+
+  LDSection& getFini() {
+    assert(NULL != f_pFini);
+    return *f_pFini;
+  }
+
+  const LDSection& getFini() const {
+    assert(NULL != f_pFini);
+    return *f_pFini;
+  }
+
+  LDSection& getFiniArray() {
+    assert(NULL != f_pFiniArray);
+    return *f_pFiniArray;
+  }
+
+  const LDSection& getFiniArray() const {
+    assert(NULL != f_pFiniArray);
+    return *f_pFiniArray;
+  }
+
+  LDSection& getHashTab() {
+    assert(NULL != f_pHashTab);
+    return *f_pHashTab;
+  }
+
+  const LDSection& getHashTab() const {
+    assert(NULL != f_pHashTab);
+    return *f_pHashTab;
+  }
+
+  LDSection& getInit() {
+    assert(NULL != f_pInit);
+    return *f_pInit;
+  }
+
+  const LDSection& getInit() const {
+    assert(NULL != f_pInit);
+    return *f_pInit;
+  }
+
+  LDSection& getInitArray() {
+    assert(NULL != f_pInitArray);
+    return *f_pInitArray;
+  }
+
+  const LDSection& getInitArray() const {
+    assert(NULL != f_pInitArray);
+    return *f_pInitArray;
+  }
+
+  LDSection& getInterp() {
+    assert(NULL != f_pInterp);
+    return *f_pInterp;
+  }
+
+  const LDSection& getInterp() const {
+    assert(NULL != f_pInterp);
+    return *f_pInterp;
+  }
+
+  LDSection& getLine() {
+    assert(NULL != f_pLine);
+    return *f_pLine;
+  }
+
+  const LDSection& getLine() const {
+    assert(NULL != f_pLine);
+    return *f_pLine;
+  }
+
+  LDSection& getNote() {
+    assert(NULL != f_pNote);
+    return *f_pNote;
+  }
+
+  const LDSection& getNote() const {
+    assert(NULL != f_pNote);
+    return *f_pNote;
+  }
+
+  LDSection& getPreInitArray() {
+    assert(NULL != f_pPreInitArray);
+    return *f_pPreInitArray;
+  }
+
+  const LDSection& getPreInitArray() const {
+    assert(NULL != f_pPreInitArray);
+    return *f_pPreInitArray;
+  }
+
+  LDSection& getROData1() {
+    assert(NULL != f_pROData1);
+    return *f_pROData1;
+  }
+
+  const LDSection& getROData1() const {
+    assert(NULL != f_pROData1);
+    return *f_pROData1;
+  }
+
+  LDSection& getShStrTab() {
+    assert(NULL != f_pShStrTab);
+    return *f_pShStrTab;
+  }
+
+  const LDSection& getShStrTab() const {
+    assert(NULL != f_pShStrTab);
+    return *f_pShStrTab;
+  }
+
+  LDSection& getStrTab() {
+    assert(NULL != f_pStrTab);
+    return *f_pStrTab;
+  }
+
+  const LDSection& getStrTab() const {
+    assert(NULL != f_pStrTab);
+    return *f_pStrTab;
+  }
+
+  LDSection& getSymTab() {
+    assert(NULL != f_pSymTab);
+    return *f_pSymTab;
+  }
+
+  const LDSection& getSymTab() const {
+    assert(NULL != f_pSymTab);
+    return *f_pSymTab;
+  }
+
+  LDSection& getTBSS() {
+    assert(NULL != f_pTBSS);
+    return *f_pTBSS;
+  }
+
+  const LDSection& getTBSS() const {
+    assert(NULL != f_pTBSS);
+    return *f_pTBSS;
+  }
+
+  LDSection& getTData() {
+    assert(NULL != f_pTData);
+    return *f_pTData;
+  }
+
+  const LDSection& getTData() const {
+    assert(NULL != f_pTData);
+    return *f_pTData;
+  }
+
+  /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24.
+  LDSection& getCtors() {
+    assert(NULL != f_pCtors);
+    return *f_pCtors;
+  }
+
+  const LDSection& getCtors() const {
+    assert(NULL != f_pCtors);
+    return *f_pCtors;
+  }
+
+  LDSection& getDataRelRo() {
+    assert(NULL != f_pDataRelRo);
+    return *f_pDataRelRo;
+  }
+
+  const LDSection& getDataRelRo() const {
+    assert(NULL != f_pDataRelRo);
+    return *f_pDataRelRo;
+  }
+
+  LDSection& getDtors() {
+    assert(NULL != f_pDtors);
+    return *f_pDtors;
+  }
+
+  const LDSection& getDtors() const {
+    assert(NULL != f_pDtors);
+    return *f_pDtors;
+  }
+
+  LDSection& getEhFrame() {
+    assert(NULL != f_pEhFrame);
+    return *f_pEhFrame;
+  }
+
+  const LDSection& getEhFrame() const {
+    assert(NULL != f_pEhFrame);
+    return *f_pEhFrame;
+  }
+
+  LDSection& getEhFrameHdr() {
+    assert(NULL != f_pEhFrameHdr);
+    return *f_pEhFrameHdr;
+  }
+
+  const LDSection& getEhFrameHdr() const {
+    assert(NULL != f_pEhFrameHdr);
+    return *f_pEhFrameHdr;
+  }
+
+  LDSection& getGCCExceptTable() {
+    assert(NULL != f_pGCCExceptTable);
+    return *f_pGCCExceptTable;
+  }
+
+  const LDSection& getGCCExceptTable() const {
+    assert(NULL != f_pGCCExceptTable);
+    return *f_pGCCExceptTable;
+  }
+
+  LDSection& getGNUVersion() {
+    assert(NULL != f_pGNUVersion);
+    return *f_pGNUVersion;
+  }
+
+  const LDSection& getGNUVersion() const {
+    assert(NULL != f_pGNUVersion);
+    return *f_pGNUVersion;
+  }
+
+  LDSection& getGNUVersionD() {
+    assert(NULL != f_pGNUVersionD);
+    return *f_pGNUVersionD;
+  }
+
+  const LDSection& getGNUVersionD() const {
+    assert(NULL != f_pGNUVersionD);
+    return *f_pGNUVersionD;
+  }
+
+  LDSection& getGNUVersionR() {
+    assert(NULL != f_pGNUVersionR);
+    return *f_pGNUVersionR;
+  }
+
+  const LDSection& getGNUVersionR() const {
+    assert(NULL != f_pGNUVersionR);
+    return *f_pGNUVersionR;
+  }
+
+  LDSection& getGOTPLT() {
+    assert(NULL != f_pGOTPLT);
+    return *f_pGOTPLT;
+  }
+
+  const LDSection& getGOTPLT() const {
+    assert(NULL != f_pGOTPLT);
+    return *f_pGOTPLT;
+  }
+
+  LDSection& getJCR() {
+    assert(NULL != f_pJCR);
+    return *f_pJCR;
+  }
+
+  const LDSection& getJCR() const {
+    assert(NULL != f_pJCR);
+    return *f_pJCR;
+  }
+
+  LDSection& getNoteABITag() {
+    assert(NULL != f_pNoteABITag);
+    return *f_pNoteABITag;
+  }
+
+  const LDSection& getNoteABITag() const {
+    assert(NULL != f_pNoteABITag);
+    return *f_pNoteABITag;
+  }
+
+  LDSection& getStab() {
+    assert(NULL != f_pStab);
+    return *f_pStab;
+  }
+
+  const LDSection& getStab() const {
+    assert(NULL != f_pStab);
+    return *f_pStab;
+  }
+
+  LDSection& getStabStr() {
+    assert(NULL != f_pStabStr);
+    return *f_pStabStr;
+  }
+
+  const LDSection& getStabStr() const {
+    assert(NULL != f_pStabStr);
+    return *f_pStabStr;
+  }
+
+protected:
+  GNULDBackend& f_Backend;
+
+  //         variable name         :  ELF
+  /// @ref Special Sections, Ch. 4.17, System V ABI, 4th edition.
+  LDSection* f_pNULLSection;
+  LDSection* f_pGOT;               // .got
+  LDSection* f_pPLT;               // .plt
+  LDSection* f_pRelDyn;            // .rel.dyn
+  LDSection* f_pRelPlt;            // .rel.plt
+  LDSection* f_pRelaDyn;           // .rela.dyn
+  LDSection* f_pRelaPlt;           // .rela.plt
+
+  /// @ref 10.3.1.1, ISO/IEC 23360, Part 1:2010(E), p. 21.
+  LDSection* f_pComment;           // .comment
+  LDSection* f_pData1;             // .data1
+  LDSection* f_pDebug;             // .debug
+  LDSection* f_pDynamic;           // .dynamic
+  LDSection* f_pDynStrTab;         // .dynstr
+  LDSection* f_pDynSymTab;         // .dynsym
+  LDSection* f_pFini;              // .fini
+  LDSection* f_pFiniArray;         // .fini_array
+  LDSection* f_pHashTab;           // .hash
+  LDSection* f_pInit;              // .init
+  LDSection* f_pInitArray;         // .init_array
+  LDSection* f_pInterp;            // .interp
+  LDSection* f_pLine;              // .line
+  LDSection* f_pNote;              // .note
+  LDSection* f_pPreInitArray;      // .preinit_array
+  LDSection* f_pROData1;           // .rodata1
+  LDSection* f_pShStrTab;          // .shstrtab
+  LDSection* f_pStrTab;            // .strtab
+  LDSection* f_pSymTab;            // .symtab
+  LDSection* f_pTBSS;              // .tbss
+  LDSection* f_pTData;             // .tdata
+
+  /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24.
+  LDSection* f_pCtors;             // .ctors
+  LDSection* f_pDataRelRo;         // .data.rel.ro
+  LDSection* f_pDtors;             // .dtors
+  LDSection* f_pEhFrame;           // .eh_frame
+  LDSection* f_pEhFrameHdr;        // .eh_frame_hdr
+  LDSection* f_pGCCExceptTable;    // .gcc_except_table
+  LDSection* f_pGNUVersion;        // .gnu.version
+  LDSection* f_pGNUVersionD;       // .gnu.version_d
+  LDSection* f_pGNUVersionR;       // .gnu.version_r
+  LDSection* f_pGOTPLT;            // .got.plt
+  LDSection* f_pJCR;               // .jcr
+  LDSection* f_pNoteABITag;        // .note.ABI-tag
+  LDSection* f_pStab;              // .stab
+  LDSection* f_pStabStr;           // .stabstr
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFObjectReader.h b/include/mcld/LD/ELFObjectReader.h
new file mode 100644
index 0000000..ac11261
--- /dev/null
+++ b/include/mcld/LD/ELFObjectReader.h
@@ -0,0 +1,59 @@
+//===- ELFObjectReader.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_OBJECT_READER_H
+#define MCLD_ELF_OBJECT_READER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/LD/ObjectReader.h>
+#include <llvm/Support/system_error.h>
+
+namespace mcld
+{
+
+class Input;
+class MCLinker;
+class GNULDBackend;
+class ELFReaderIF;
+
+/** \lclass ELFObjectReader
+ *  \brief ELFObjectReader reads target-independent parts of ELF object file
+ */
+class ELFObjectReader : public ObjectReader
+{
+public:
+  ELFObjectReader(GNULDBackend& pBackend, MCLinker& pLinker);
+
+  ~ELFObjectReader();
+
+  // -----  observers  ----- //
+  bool isMyFormat(Input &pFile) const;
+
+  // -----  readers  ----- //
+  bool readObject(Input& pFile);
+
+  virtual bool readSections(Input& pFile);
+
+  virtual bool readSymbols(Input& pFile);
+
+  /// readRelocations - read relocation sections
+  ///
+  /// This function should be called after symbol resolution.
+  virtual bool readRelocations(Input& pFile);
+
+private:
+  ELFReaderIF* m_pELFReader;
+  MCLinker& m_Linker;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFObjectWriter.h b/include/mcld/LD/ELFObjectWriter.h
new file mode 100644
index 0000000..a6b9a87
--- /dev/null
+++ b/include/mcld/LD/ELFObjectWriter.h
@@ -0,0 +1,47 @@
+//===- ELFObjectWriter.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_OBJECT_WRITER_H
+#define MCLD_ELF_OBJECT_WRITER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/Support/system_error.h>
+#include <mcld/LD/ObjectWriter.h>
+#include <mcld/LD/ELFWriter.h>
+
+namespace mcld
+{
+
+class Input;
+class MCLinker;
+class GNULDBackend;
+
+/** \class ELFObjectWriter
+ *  \brief ELFObjectWriter writes the target-independent parts of object files.
+ *  ELFObjectWriter reads a MCLDFile and writes into raw_ostream
+ *
+ */
+class ELFObjectWriter : public ObjectWriter, protected ELFWriter
+{
+public:
+  ELFObjectWriter(GNULDBackend& pBackend, MCLinker& pLinker);
+
+  ~ELFObjectWriter();
+
+  llvm::error_code writeObject(Output& pOutput)
+  { return llvm::make_error_code(llvm::errc::not_supported); }
+
+private:
+  MCLinker& m_Linker;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFReader.h b/include/mcld/LD/ELFReader.h
new file mode 100644
index 0000000..cac0175
--- /dev/null
+++ b/include/mcld/LD/ELFReader.h
@@ -0,0 +1,224 @@
+//===- ELFReader.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_READER_INTERFACE_H
+#define MCLD_ELF_READER_INTERFACE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/ADT/StringRef.h>
+#include <llvm/Support/ELF.h>
+#include <llvm/Support/Host.h>
+#include <llvm/MC/MCAssembler.h>
+#include <mcld/MC/MCLDInfo.h>
+#include <mcld/MC/MCLDInput.h>
+#include <mcld/MC/MCLinker.h>
+#include <mcld/MC/MCRegionFragment.h>
+#include <mcld/LD/ResolveInfo.h>
+#include <mcld/LD/LDContext.h>
+#include <mcld/Target/GNULDBackend.h>
+#include <mcld/Support/MemoryRegion.h>
+
+namespace mcld
+{
+
+/** \class ELFReaderIF
+ *  \brief ELFReaderIF provides common interface for all kind of ELF readers.
+ */
+class ELFReaderIF
+{
+public:
+  ELFReaderIF(GNULDBackend& pBackend)
+    : m_Backend(pBackend)
+  { }
+
+  virtual ~ELFReaderIF() { }
+
+  /// ELFHeaderSize - return the size of the ELFHeader
+  virtual size_t getELFHeaderSize() const = 0;
+
+  /// isELF - is this a ELF file
+  virtual bool isELF(void* pELFHeader) const = 0;
+
+  /// isMyEndian - is this ELF file in the same endian to me?
+  virtual bool isMyEndian(void* pELFHeader) const = 0;
+
+  /// isMyMachine - is this ELF file generated for the same machine.
+  virtual bool isMyMachine(void* pELFHeader) const = 0;
+
+  /// fileType - the file type of this file
+  virtual MCLDFile::Type fileType(void* pELFHeader) const = 0;
+
+  /// target - the target backend
+  GNULDBackend& target()
+  { return m_Backend; }
+
+  /// target - the target backend
+  const GNULDBackend& target() const
+  { return m_Backend; }
+
+  /// readSectionHeaders - read ELF section header table and create LDSections
+  virtual bool readSectionHeaders(Input& pInput,
+                                  MCLinker& pLinker,
+                                  void* pELFHeader) const = 0;
+
+  /// readRegularSection - read a regular section and create fragments.
+  virtual bool readRegularSection(Input& pInput,
+                                  MCLinker& pLinker,
+                                  LDSection& pSectHdr) const = 0;
+
+  /// readRegularSection - read a target section and create fragments.
+  virtual bool readTargetSection(Input& pInput,
+                                 MCLinker& pLinker,
+                                 LDSection& pSectHdr) = 0;
+
+  /// readSymbols - read ELF symbols and create LDSymbol
+  virtual bool readSymbols(Input& pInput,
+                           MCLinker& pLinker,
+                           const MemoryRegion& pRegion,
+                           const char* StrTab) const = 0;
+
+  /// readSymbol - read a symbol from the given Input and index in symtab
+  virtual ResolveInfo* readSymbol(Input& pInput,
+                                  LDSection& pSymTab,
+                                  MCLDInfo& pLDInfo,
+                                  uint32_t pSymIdx) const = 0;
+
+  /// readRela - read ELF rela and create Relocation
+  virtual bool readRela(Input& pInput,
+                        MCLinker& pLinker,
+                        LDSection& pSection,
+                        const MemoryRegion& pRegion) const = 0;
+
+  /// readRel - read ELF rel and create Relocation
+  virtual bool readRel(Input& pInput,
+                       MCLinker& pLinker,
+                       LDSection& pSection,
+                       const MemoryRegion& pRegion) const = 0;
+protected:
+  /// LinkInfo - some section needs sh_link and sh_info, remember them.
+  struct LinkInfo {
+    LDSection* section;
+    uint32_t sh_link;
+    uint32_t sh_info;
+  };
+
+  typedef std::vector<LinkInfo> LinkInfoList;
+
+protected:
+  LDFileFormat::Kind getLDSectionKind(uint32_t pType, const char* pName) const;
+
+  ResolveInfo::Desc getSymDesc(uint16_t pShndx, const Input& pInput) const;
+
+  ResolveInfo::Binding getSymBinding(uint8_t pBinding,
+                                     uint16_t pShndx,
+                                     uint8_t pVisibility) const;
+
+  uint64_t getSymValue(uint64_t pValue,
+                       uint16_t pShndx,
+                       const Input& pInput) const;
+
+  MCFragmentRef* getSymFragmentRef(Input& pInput,
+                                   MCLinker& pLinker,
+                                   uint16_t pShndx,
+                                   uint32_t pOffset) const;
+
+  ResolveInfo::Visibility getSymVisibility(uint8_t pVis) const;
+
+private:
+  GNULDBackend& m_Backend;
+};
+
+/** \class ELFReader
+ *  \brief ELFReader is a template scaffolding for partial specification.
+ */
+template<size_t BIT, bool LITTLEENDIAN>
+class ELFReader
+{ };
+
+/** \class ELFReader<32, true>
+ *  \brief ELFReader<32, true> is a 32-bit, little endian ELFReader.
+ */
+template<>
+class ELFReader<32, true> : public ELFReaderIF
+{
+public:
+  typedef llvm::ELF::Elf32_Ehdr ELFHeader;
+  typedef llvm::ELF::Elf32_Shdr SectionHeader;
+  typedef llvm::ELF::Elf32_Sym  Symbol;
+  typedef llvm::ELF::Elf32_Rel  Rel;
+  typedef llvm::ELF::Elf32_Rela Rela;
+
+public:
+  inline ELFReader(GNULDBackend& pBackend);
+
+  inline ~ELFReader();
+
+  /// ELFHeaderSize - return the size of the ELFHeader
+  inline size_t getELFHeaderSize() const
+  { return sizeof(ELFHeader); }
+
+  /// isELF - is this a ELF file
+  inline bool isELF(void* pELFHeader) const;
+
+  /// isMyEndian - is this ELF file in the same endian to me?
+  inline bool isMyEndian(void* pELFHeader) const;
+
+  /// isMyMachine - is this ELF file generated for the same machine.
+  inline bool isMyMachine(void* pELFHeader) const;
+
+  /// fileType - the file type of this file
+  inline MCLDFile::Type fileType(void* pELFHeader) const;
+
+  /// readSectionHeaders - read ELF section header table and create LDSections
+  inline bool readSectionHeaders(Input& pInput,
+                          MCLinker& pLinker,
+                          void* pELFHeader) const;
+
+  /// readRegularSection - read a regular section and create fragments.
+  inline bool readRegularSection(Input& pInput,
+                                 MCLinker& pLinker,
+                                 LDSection& pInputSectHdr) const;
+
+  /// readRegularSection - read a target section and create fragments.
+  inline bool readTargetSection(Input& pInput,
+                                MCLinker& pLinker,
+                                LDSection& pInputSectHdr);
+
+  /// readSymbols - read ELF symbols and create LDSymbol
+  inline bool readSymbols(Input& pInput,
+                          MCLinker& pLinker,
+                          const MemoryRegion& pRegion,
+                          const char* StrTab) const;
+
+  /// readSymbol - read a symbol from the given Input and index in symtab
+  inline ResolveInfo* readSymbol(Input& pInput,
+                                 LDSection& pSymTab,
+                                 MCLDInfo& pLDInfo,
+                                 uint32_t pSymIdx) const;
+
+  /// readRela - read ELF rela and create Relocation
+  inline bool readRela(Input& pInput,
+                       MCLinker& pLinker,
+                       LDSection& pSection,
+                       const MemoryRegion& pRegion) const;
+
+  /// readRel - read ELF rel and create Relocation
+  inline bool readRel(Input& pInput,
+                      MCLinker& pLinker,
+                      LDSection& pSection,
+                      const MemoryRegion& pRegion) const;
+};
+
+#include "ELFReader.tcc"
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFReader.tcc b/include/mcld/LD/ELFReader.tcc
new file mode 100644
index 0000000..693a780
--- /dev/null
+++ b/include/mcld/LD/ELFReader.tcc
@@ -0,0 +1,532 @@
+//===- ELFReader.tcc ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file is the template implemenation of ELFReaders
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// ELFReader<32, true>
+#include <cstring>
+#include <vector>
+
+/// constructor
+ELFReader<32, true>::ELFReader(GNULDBackend& pBackend)
+  : ELFReaderIF(pBackend) {
+}
+
+/// destructor
+ELFReader<32, true>::~ELFReader()
+{
+}
+
+/// isELF - is this a ELF file
+bool ELFReader<32, true>::isELF(void* pELFHeader) const
+{
+  llvm::ELF::Elf32_Ehdr* hdr =
+                          reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader);
+  if (0 == memcmp(llvm::ELF::ElfMagic, hdr, 4))
+    return true;
+  return false;
+}
+
+/// isMyEndian - is this ELF file in the same endian to me?
+bool ELFReader<32, true>::isMyEndian(void* pELFHeader) const
+{
+  llvm::ELF::Elf32_Ehdr* hdr =
+                          reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader);
+
+  return (hdr->e_ident[llvm::ELF::EI_DATA] == llvm::ELF::ELFDATA2LSB);
+}
+
+/// isMyMachine - is this ELF file generated for the same machine.
+bool ELFReader<32, true>::isMyMachine(void* pELFHeader) const
+{
+  llvm::ELF::Elf32_Ehdr* hdr =
+                          reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader);
+
+  if (llvm::sys::isLittleEndianHost())
+    return (hdr->e_machine == target().machine());
+  return (bswap16(hdr->e_machine) == target().machine());
+}
+
+/// fileType - return the file type
+MCLDFile::Type ELFReader<32, true>::fileType(void* pELFHeader) const
+{
+  llvm::ELF::Elf32_Ehdr* hdr =
+                          reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader);
+  uint32_t type = 0x0;
+  if (llvm::sys::isLittleEndianHost())
+    type = hdr->e_type;
+  else
+    type = bswap16(hdr->e_type);
+
+  switch(type) {
+  case llvm::ELF::ET_REL:
+    return MCLDFile::Object;
+  case llvm::ELF::ET_EXEC:
+    return MCLDFile::Exec;
+  case llvm::ELF::ET_DYN:
+    return MCLDFile::DynObj;
+  case llvm::ELF::ET_CORE:
+    return MCLDFile::CoreFile;
+  case llvm::ELF::ET_NONE:
+  default:
+    return MCLDFile::Unknown;
+  }
+}
+
+/// readSectionHeaders - read ELF section header table and create LDSections
+bool ELFReader<32, true>::readSectionHeaders(Input& pInput,
+                                             MCLinker& pLinker,
+                                             void* pELFHeader) const
+{
+  llvm::ELF::Elf32_Ehdr* ehdr =
+                          reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader);
+
+  uint32_t shoff     = 0x0;
+  uint16_t shentsize = 0x0;
+  uint16_t shnum     = 0x0;
+  uint16_t shstrtab  = 0x0;
+
+  if (llvm::sys::isLittleEndianHost()) {
+    shoff     = ehdr->e_shoff;
+    shentsize = ehdr->e_shentsize;
+    shnum     = ehdr->e_shnum;
+    shstrtab  = ehdr->e_shstrndx;
+  }
+  else {
+    shoff     = bswap32(ehdr->e_shoff);
+    shentsize = bswap16(ehdr->e_shentsize);
+    shnum     = bswap16(ehdr->e_shnum);
+    shstrtab  = bswap16(ehdr->e_shstrndx);
+  }
+
+  // If the file has no section header table, e_shoff holds zero.
+  if (0x0 == shoff)
+    return true;
+
+  MemoryRegion* shdr_region = pInput.memArea()->request(shoff, shnum*shentsize);
+  llvm::ELF::Elf32_Shdr* shdrTab =
+                reinterpret_cast<llvm::ELF::Elf32_Shdr*>(shdr_region->start());
+
+  uint32_t sh_name      = 0x0;
+  uint32_t sh_type      = 0x0;
+  uint32_t sh_flags     = 0x0;
+  uint32_t sh_offset    = 0x0;
+  uint32_t sh_size      = 0x0;
+  uint32_t sh_link      = 0x0;
+  uint32_t sh_info      = 0x0;
+  uint32_t sh_addralign = 0x0;
+
+  // get .shstrtab first
+  llvm::ELF::Elf32_Shdr* shdr = &shdrTab[shstrtab];
+  if (llvm::sys::isLittleEndianHost()) {
+    sh_offset = shdr->sh_offset;
+    sh_size   = shdr->sh_size;
+  }
+  else {
+    sh_offset = bswap32(shdr->sh_offset);
+    sh_size   = bswap32(shdr->sh_size);
+  }
+
+  MemoryRegion* sect_name_region = pInput.memArea()->request(sh_offset, sh_size);
+  const char* sect_name = reinterpret_cast<const char*>(sect_name_region->start());
+
+  LinkInfoList link_info_list;
+
+  // create all LDSections
+  for (size_t idx = 0; idx < shnum; ++idx) {
+    if (llvm::sys::isLittleEndianHost()) {
+      sh_name      = shdrTab[idx].sh_name;
+      sh_type      = shdrTab[idx].sh_type;
+      sh_flags     = shdrTab[idx].sh_flags;
+      sh_offset    = shdrTab[idx].sh_offset;
+      sh_size      = shdrTab[idx].sh_size;
+      sh_link      = shdrTab[idx].sh_link;
+      sh_info      = shdrTab[idx].sh_info;
+      sh_addralign = shdrTab[idx].sh_addralign;
+    }
+    else {
+      sh_name      = bswap32(shdrTab[idx].sh_name);
+      sh_type      = bswap32(shdrTab[idx].sh_type);
+      sh_flags     = bswap32(shdrTab[idx].sh_flags);
+      sh_offset    = bswap32(shdrTab[idx].sh_offset);
+      sh_size      = bswap32(shdrTab[idx].sh_size);
+      sh_link      = bswap32(shdrTab[idx].sh_link);
+      sh_info      = bswap32(shdrTab[idx].sh_info);
+      sh_addralign = bswap32(shdrTab[idx].sh_addralign);
+    }
+
+    LDFileFormat::Kind kind = getLDSectionKind(sh_type,
+                                               sect_name+sh_name);
+
+    LDSection& section = pLinker.createSectHdr(sect_name+sh_name,
+                                               kind,
+                                               sh_type,
+                                               sh_flags);
+
+    section.setSize(sh_size);
+    section.setOffset(sh_offset);
+    section.setIndex(pInput.context()->numOfSections());
+    section.setInfo(sh_info);
+    section.setAlign(sh_addralign);
+
+    if (sh_link != 0x0 || sh_info != 0x0) {
+      LinkInfo link_info = { &section, sh_link, sh_info };
+      link_info_list.push_back(link_info);
+    }
+
+    pInput.context()->getSectionTable().push_back(&section);
+  } // end of for
+
+  // set up InfoLink
+  LinkInfoList::iterator info, infoEnd = link_info_list.end();
+  for (info = link_info_list.begin(); info != infoEnd; ++info) {
+    if (LDFileFormat::NamePool == info->section->kind() ||
+        LDFileFormat::Group == info->section->kind()) {
+      info->section->setLink(pInput.context()->getSection(info->sh_link));
+      continue;
+    }
+    if (LDFileFormat::Relocation == info->section->kind()) {
+      info->section->setLink(pInput.context()->getSection(info->sh_info));
+      continue;
+    }
+  }
+
+  pInput.memArea()->release(shdr_region);
+  pInput.memArea()->release(sect_name_region);
+
+  return true;
+}
+
+/// readRegularSection - read a regular section and create fragments.
+bool ELFReader<32, true>::readRegularSection(Input& pInput,
+                                             MCLinker& pLinker,
+                                             LDSection& pInputSectHdr) const
+{
+  LDSection& out_sect = pLinker.getOrCreateOutputSectHdr(pInputSectHdr.name(),
+                                                         pInputSectHdr.kind(),
+                                                         pInputSectHdr.type(),
+                                                         pInputSectHdr.flag());
+
+  MemoryRegion* region = pInput.memArea()->request(pInputSectHdr.offset(),
+                                                   pInputSectHdr.size());
+
+  llvm::MCSectionData& sect_data = pLinker.getOrCreateSectData(pInputSectHdr);
+
+  llvm::MCFragment* frag = NULL;
+  if (NULL == region) {
+    // If the input section's size is zero, we got a NULL region.
+    // use a virtual fill fragment
+    frag = new llvm::MCFillFragment(0x0, 0, 0);
+  }
+  else
+    frag = new MCRegionFragment(*region);
+
+  uint64_t size = pLinker.getLayout().appendFragment(*frag,
+                                                     sect_data,
+                                                     pInputSectHdr.align());
+
+  out_sect.setSize(out_sect.size() + size);
+  return true;
+}
+
+/// readRegularSection - read a target section and create fragments.
+bool ELFReader<32, true>::readTargetSection(Input& pInput,
+                                            MCLinker& pLinker,
+                                            LDSection& pInputSectHdr)
+{
+  return target().readSection(pInput, pLinker, pInputSectHdr);
+}
+
+/// readSymbols - read ELF symbols and create LDSymbol
+bool ELFReader<32, true>::readSymbols(Input& pInput,
+                                      MCLinker& pLinker,
+                                      const MemoryRegion& pRegion,
+                                      const char* pStrTab) const
+{
+  // get number of symbols
+  size_t entsize = pRegion.size()/sizeof(llvm::ELF::Elf32_Sym);
+  llvm::ELF::Elf32_Sym* symtab =
+                      reinterpret_cast<llvm::ELF::Elf32_Sym*>(pRegion.start());
+
+  uint32_t st_name  = 0x0;
+  uint32_t st_value = 0x0;
+  uint32_t st_size  = 0x0;
+  uint8_t  st_info  = 0x0;
+  uint8_t  st_other = 0x0;
+  uint16_t st_shndx = 0x0;
+  // skip the first NULL symbol
+  pInput.context()->addSymbol(NULL);
+
+  for (size_t idx = 1; idx < entsize; ++idx) {
+    st_info  = symtab[idx].st_info;
+    st_other = symtab[idx].st_other;
+
+    if (llvm::sys::isLittleEndianHost()) {
+      st_name  = symtab[idx].st_name;
+      st_value = symtab[idx].st_value;
+      st_size  = symtab[idx].st_size;
+      st_shndx = symtab[idx].st_shndx;
+    }
+    else {
+      st_name  = bswap32(symtab[idx].st_name);
+      st_value = bswap32(symtab[idx].st_value);
+      st_size  = bswap32(symtab[idx].st_size);
+      st_shndx = bswap16(symtab[idx].st_shndx);
+    }
+
+    // If the section should not be included, set the st_shndx SHN_UNDEF
+    // - A section in interrelated groups are not included.
+    if (pInput.type() == Input::Object &&
+        st_shndx < llvm::ELF::SHN_LORESERVE &&
+        st_shndx != llvm::ELF::SHN_UNDEF) {
+      if (NULL == pInput.context()->getSection(st_shndx))
+        st_shndx = llvm::ELF::SHN_UNDEF;
+    }
+
+    // get ld_name
+    llvm::StringRef ld_name(pStrTab + st_name);
+
+    // get ld_type
+    ResolveInfo::Type ld_type = static_cast<ResolveInfo::Type>(st_info & 0xF);
+
+    // get ld_desc
+    ResolveInfo::Desc ld_desc = getSymDesc(st_shndx, pInput);
+
+    // get ld_binding
+    ResolveInfo::Binding ld_binding = getSymBinding((st_info >> 4), st_shndx, st_other);
+
+    // get ld_value - ld_value must be section relative.
+    uint64_t ld_value = getSymValue(st_value, st_shndx, pInput);
+
+    // get the input fragment
+    MCFragmentRef* ld_frag_ref = getSymFragmentRef(pInput,
+                                                   pLinker,
+                                                   st_shndx,
+                                                   ld_value);
+
+    // get ld_vis
+    ResolveInfo::Visibility ld_vis = getSymVisibility(st_other);
+
+    // push into MCLinker
+    LDSymbol* input_sym = NULL;
+
+    if (pInput.type() == Input::Object) {
+      input_sym = pLinker.addSymbol<Input::Object>(ld_name,
+                                                   ld_type,
+                                                   ld_desc,
+                                                   ld_binding,
+                                                   st_size,
+                                                   ld_value,
+                                                   ld_frag_ref,
+                                                   ld_vis);
+      // push into the input file
+      pInput.context()->addSymbol(input_sym);
+      continue;
+    }
+    else if (pInput.type() == Input::DynObj) {
+      input_sym = pLinker.addSymbol<Input::DynObj>(ld_name,
+                                                   ld_type,
+                                                   ld_desc,
+                                                   ld_binding,
+                                                   st_size,
+                                                   ld_value,
+                                                   ld_frag_ref,
+                                                   ld_vis);
+      continue;
+    }
+
+  } // end of for loop
+  return true;
+}
+
+/// readSymbol - read a symbol from the given Input and index in symtab
+ResolveInfo* ELFReader<32, true>::readSymbol(Input& pInput,
+                                             LDSection& pSymTab,
+                                             MCLDInfo& pLDInfo,
+                                             uint32_t pSymIdx) const
+{
+  LDSection* symtab = &pSymTab;
+  LDSection* strtab = symtab->getLink();
+  assert(NULL != symtab && NULL != strtab);
+
+  uint32_t offset = symtab->offset() + sizeof(llvm::ELF::Elf32_Sym) * pSymIdx;
+  MemoryRegion* symbol_region =
+                pInput.memArea()->request(offset, sizeof(llvm::ELF::Elf32_Sym));
+  llvm::ELF::Elf32_Sym* entry =
+                reinterpret_cast<llvm::ELF::Elf32_Sym*>(symbol_region->start());
+
+  uint32_t st_name  = 0x0;
+  uint32_t st_value = 0x0;
+  uint32_t st_size  = 0x0;
+  uint8_t  st_info  = 0x0;
+  uint8_t  st_other = 0x0;
+  uint16_t st_shndx = 0x0;
+  st_info  = entry->st_info;
+  st_other = entry->st_other;
+  if (llvm::sys::isLittleEndianHost()) {
+    st_name  = entry->st_name;
+    st_value = entry->st_value;
+    st_size  = entry->st_size;
+    st_shndx = entry->st_shndx;
+  }
+  else {
+    st_name  = bswap32(entry->st_name);
+    st_value = bswap32(entry->st_value);
+    st_size  = bswap32(entry->st_size);
+    st_shndx = bswap16(entry->st_shndx);
+  }
+
+  MemoryRegion* strtab_region =
+                    pInput.memArea()->request(strtab->offset(), strtab->size());
+
+  // get ld_name
+  llvm::StringRef ld_name(reinterpret_cast<char*>(strtab_region->start() + st_name));
+
+  // get ld_type
+  ResolveInfo::Type ld_type = static_cast<ResolveInfo::Type>(st_info & 0xF);
+
+  // get ld_desc
+  ResolveInfo::Desc ld_desc = getSymDesc(st_shndx, pInput);
+
+  // get ld_binding
+  ResolveInfo::Binding ld_binding = getSymBinding((st_info >> 4), st_shndx, st_other);
+
+  // get ld_vis
+  ResolveInfo::Visibility ld_vis = getSymVisibility(st_other);
+
+  ResolveInfo* result =
+         pLDInfo.getStrSymPool().createSymbol(ld_name,
+                                              pInput.type() == Input::DynObj,
+                                              ld_type,
+                                              ld_desc,
+                                              ld_binding,
+                                              st_size,
+                                              ld_vis);
+  // release regions
+  pInput.memArea()->release(symbol_region);
+  pInput.memArea()->release(strtab_region);
+
+  return result;
+}
+
+/// readRela - read ELF rela and create Relocation
+bool ELFReader<32, true>::readRela(Input& pInput,
+                                   MCLinker& pLinker,
+                                   LDSection& pSection,
+                                   const MemoryRegion& pRegion) const
+{
+  // get the number of rela
+  size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf32_Rela);
+  llvm::ELF::Elf32_Rela* relaTab =
+                     reinterpret_cast<llvm::ELF::Elf32_Rela*>(pRegion.start());
+
+  for (size_t idx=0; idx < entsize; ++idx) {
+    uint32_t r_offset = 0x0;
+    uint32_t r_info   = 0x0;
+    int32_t  r_addend = 0;
+    if (llvm::sys::isLittleEndianHost()) {
+      r_offset = relaTab[idx].r_offset;
+      r_info   = relaTab[idx].r_info;
+      r_addend = relaTab[idx].r_addend;
+    }
+    else {
+      r_offset = bswap32(relaTab[idx].r_offset);
+      r_info   = bswap32(relaTab[idx].r_info);
+      r_addend = bswap32(relaTab[idx].r_addend);
+    }
+
+    uint8_t  r_type = static_cast<unsigned char>(r_info);
+    uint32_t r_sym  = (r_info >> 8);
+    LDSymbol* symbol = pInput.context()->getSymbol(r_sym);
+    if (NULL == symbol) {
+      llvm::report_fatal_error(llvm::Twine("invalid symbol index :") +
+                               llvm::Twine(r_sym) +
+                               llvm::Twine(" in file `") +
+                               pInput.path().native() +
+                               llvm::Twine("'.\n"));
+    }
+
+    ResolveInfo* resolve_info = symbol->resolveInfo();
+
+    MCFragmentRef* frag_ref =
+         pLinker.getLayout().getFragmentRef(*pSection.getLink(), r_offset);
+
+    if (NULL == frag_ref) {
+      llvm::report_fatal_error(llvm::Twine("invalid sh_info: ") +
+                               llvm::Twine(pSection.getLink()->index()) +
+                               llvm::Twine(" of the relocation section `") +
+                               pSection.name() +
+                               llvm::Twine("' in file `") +
+                               pInput.path().native() +
+                               llvm::Twine(".\n"));
+    }
+
+    pLinker.addRelocation(r_type, *symbol,  *resolve_info, *frag_ref, r_addend);
+  }
+  return true;
+}
+
+/// readRel - read ELF rel and create Relocation
+bool ELFReader<32, true>::readRel(Input& pInput,
+                                  MCLinker& pLinker,
+                                  LDSection& pSection,
+                                  const MemoryRegion& pRegion) const
+{
+  // get the number of rel
+  size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf32_Rel);
+  llvm::ELF::Elf32_Rel* relTab =
+                      reinterpret_cast<llvm::ELF::Elf32_Rel*>(pRegion.start());
+
+  for (size_t idx=0; idx < entsize; ++idx) {
+    uint32_t r_offset = 0x0;
+    uint32_t r_info   = 0x0;
+    if (llvm::sys::isLittleEndianHost()) {
+      r_offset = relTab[idx].r_offset;
+      r_info   = relTab[idx].r_info;
+    }
+    else {
+      r_offset = bswap32(relTab[idx].r_offset);
+      r_info   = bswap32(relTab[idx].r_info);
+    }
+
+    uint8_t  r_type = static_cast<unsigned char>(r_info);
+    uint32_t r_sym  = (r_info >> 8);
+
+    LDSymbol* symbol = pInput.context()->getSymbol(r_sym);
+    if (NULL == symbol) {
+      llvm::report_fatal_error(llvm::Twine("invalid symbol index :") +
+                               llvm::Twine(r_sym) +
+                               llvm::Twine(" in file `") +
+                               pInput.path().native() +
+                               llvm::Twine("'.\n"));
+    }
+
+    ResolveInfo* resolve_info = symbol->resolveInfo();
+
+    MCFragmentRef* frag_ref =
+         pLinker.getLayout().getFragmentRef(*pSection.getLink(), r_offset);
+
+    if (NULL == frag_ref) {
+      llvm::report_fatal_error(llvm::Twine("invalid sh_info: ") +
+                               llvm::Twine(pSection.getLink()->index()) +
+                               llvm::Twine(" of the relocation section `") +
+                               pSection.name() +
+                               llvm::Twine("' in file `") +
+                               pInput.path().native() +
+                               llvm::Twine(".\n"));
+    }
+
+    pLinker.addRelocation(r_type, *symbol, *resolve_info, *frag_ref);
+  }
+  return true;
+}
+
diff --git a/include/mcld/LD/ELFSegment.h b/include/mcld/LD/ELFSegment.h
new file mode 100644
index 0000000..24f9458
--- /dev/null
+++ b/include/mcld/LD/ELFSegment.h
@@ -0,0 +1,163 @@
+//===- ELFSegment.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_SEGMENT_H
+#define MCLD_ELF_SEGMENT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/Support/ELF.h>
+#include <llvm/Support/DataTypes.h>
+#include <mcld/LD/LDSection.h>
+#include <cassert>
+#include <vector>
+
+namespace mcld
+{
+
+/** \class ELFSegment
+ *  \brief decribe the program header for ELF executable or shared object
+ */
+class ELFSegment
+{
+public:
+  typedef std::vector<LDSection*>::iterator sect_iterator;
+  typedef std::vector<LDSection*>::const_iterator const_sect_iterator;
+public:
+  ELFSegment(uint32_t pType,
+             uint32_t pFlag = llvm::ELF::PF_R,
+             uint64_t pOffset = 0,
+             uint64_t pVaddr = 0,
+             uint64_t pPaddr = 0,
+             uint64_t pFilesz = 0,
+             uint64_t pMemsz = 0,
+             uint64_t pAlign = 0);
+  ~ELFSegment();
+
+  ///  -----  iterators  -----  ///
+  sect_iterator sectBegin()
+  { return m_SectionList.begin(); }
+
+  sect_iterator sectEnd()
+  { return m_SectionList.end(); }
+
+  const_sect_iterator sectBegin() const
+  { return m_SectionList.begin(); }
+
+  const_sect_iterator sectEnd() const
+  { return m_SectionList.end(); }
+
+  const LDSection* getFirstSection()
+  {
+    if (0 == m_SectionList.size())
+      return NULL;
+    return m_SectionList[0];
+  }
+
+  const LDSection* getLastSection()
+  {
+    size_t size = m_SectionList.size();
+    if (0 == size)
+      return NULL;
+    return m_SectionList[size - 1];
+  }
+
+  const LDSection* getFirstSection() const
+  {
+    if (0 == m_SectionList.size())
+      return NULL;
+    return m_SectionList[0];
+  }
+
+  const LDSection* getLastSection() const
+  {
+    size_t size = m_SectionList.size();
+    if (0 == size)
+      return NULL;
+    return m_SectionList[size - 1];
+  }
+
+  ///  -----  observers  -----  ///
+  uint32_t type() const
+  { return m_Type; }
+
+  uint64_t offset() const
+  { return m_Offset; }
+
+  uint64_t vaddr() const
+  { return m_Vaddr; }
+
+  uint64_t paddr() const
+  { return m_Paddr; }
+
+  uint64_t filesz() const
+  { return m_Filesz; }
+
+  uint64_t memsz() const
+  { return m_Memsz; }
+
+  uint32_t flag() const
+  { return m_Flag; }
+
+  uint64_t align() const
+  { return m_Align; }
+
+  size_t numOfSections() const
+  { return m_SectionList.size(); }
+
+  ///  -----  modifiers  -----  ///
+  void setOffset(uint64_t pOffset)
+  { m_Offset = pOffset; }
+
+  void setVaddr(uint64_t pVaddr)
+  { m_Vaddr = pVaddr; }
+
+  void setPaddr(uint64_t pPaddr)
+  { m_Paddr = pPaddr; }
+
+  void setFilesz(uint64_t pFilesz)
+  { m_Filesz = pFilesz; }
+
+  void setMemsz(uint64_t pMemsz)
+  { m_Memsz = pMemsz; }
+
+  void setFlag(uint32_t pFlag)
+  { m_Flag = pFlag; }
+
+  void updateFlag(uint32_t pFlag)
+  {
+    // PT_TLS segment should be PF_R
+    if (llvm::ELF::PT_TLS != m_Type)
+      m_Flag |= pFlag;
+  }
+
+  void setAlign(uint64_t pAlign)
+  { m_Align = pAlign; }
+
+  void addSection(LDSection* pSection)
+  {
+    assert(NULL != pSection);
+    m_SectionList.push_back(pSection);
+  }
+
+private:
+  uint32_t m_Type;    // Type of segment
+  uint32_t m_Flag;    // Segment flags
+  uint64_t m_Offset;  // File offset where segment is located, in bytes
+  uint64_t m_Vaddr;   // Virtual address of beginning of segment
+  uint64_t m_Paddr;   // Physical address of beginning of segment (OS-specific)
+  uint64_t m_Filesz;  // Num. of bytes in file image of segment (may be zero)
+  uint64_t m_Memsz;   // Num. of bytes in mem image of segment (may be zero)
+  uint64_t m_Align;   // Segment alignment constraint
+  std::vector<LDSection*> m_SectionList;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFSegmentFactory.h b/include/mcld/LD/ELFSegmentFactory.h
new file mode 100644
index 0000000..5dd55cb
--- /dev/null
+++ b/include/mcld/LD/ELFSegmentFactory.h
@@ -0,0 +1,43 @@
+//===- ELFSegmentFactory.h ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELFSEGMENT_FACTORY_H
+#define MCLD_ELFSEGMENT_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/Support/GCFactory.h>
+#include <mcld/LD/ELFSegment.h>
+
+namespace mcld
+{
+
+/** \class ELFSegmentFactory
+ *  \brief provide the interface to create and delete an ELFSegment
+ */
+class ELFSegmentFactory : public GCFactory<ELFSegment, 0>
+{
+public:
+  /// ELFSegmentFactory - the factory of ELFSegment
+  /// pNum is the magic number of the ELF segments in the output
+  ELFSegmentFactory(size_t pNum);
+  ~ELFSegmentFactory();
+
+  /// produce - produce an empty ELF segment information.
+  /// this function will create an ELF segment
+  /// @param pType - p_type in ELF program header
+  ELFSegment* produce(uint32_t pType);
+
+  /// destroy - destruct the ELF segment
+  void destroy(ELFSegment*& pSegment);
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ELFWriter.h b/include/mcld/LD/ELFWriter.h
new file mode 100644
index 0000000..e9db7f5
--- /dev/null
+++ b/include/mcld/LD/ELFWriter.h
@@ -0,0 +1,122 @@
+//===- ELFWriter.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_WRITER_H
+#define MCLD_ELF_WRITER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/Support/ELF.h>
+#include <mcld/MC/MCLDOutput.h>
+
+namespace llvm {
+class MCSectionData;
+}
+
+namespace mcld
+{
+
+class MCLDInfo;
+class Layout;
+class GNULDBackend;
+class Relocation;
+class LDSection;
+
+/** \class ELFWriter
+ *  \brief ELFWriter provides basic functions to write ELF sections, symbols,
+ *  and so on.
+ */
+class ELFWriter
+{
+public:
+  typedef uint64_t FileOffset;
+
+protected:
+  ELFWriter(GNULDBackend& pBackend)
+  : f_Backend(pBackend) {
+  }
+
+public:
+  virtual ~ELFWriter() { }
+
+  GNULDBackend& target()
+  { return f_Backend; }
+
+  const GNULDBackend& target() const
+  { return f_Backend; }
+
+  virtual void writeELF32Header(const MCLDInfo& pInfo,
+                                const Layout& pLayout,
+                                const GNULDBackend& pBackend,
+                                Output& pOutput) const;
+
+  virtual void writeELF64Header(const MCLDInfo& pInfo,
+                                const Layout& pLayout,
+                                const GNULDBackend& pBackend,
+                                Output& pOutput) const;
+
+  virtual uint64_t getEntryPoint(const MCLDInfo& pInfo,
+                                 const Layout& pLayout,
+                                 const GNULDBackend& pBackend,
+                                 const Output& pOutput) const;
+
+protected:
+  void emitELF32SectionHeader(Output& pOutput, MCLinker& pLinker) const;
+
+  void emitELF64SectionHeader(Output& pOutput, MCLinker& pLinker) const;
+
+  // emitShStrTab - emit .shstrtab
+  void emitELF32ShStrTab(Output& pOutput, MCLinker& pLinker) const;
+
+  void emitELF64ShStrTab(Output& pOutput, MCLinker& pLinker) const;
+
+  void emitSectionData(const Layout& pLayout,
+                       const LDSection& pSection,
+                       MemoryRegion& pRegion) const;
+
+  void emitRelocation(const Layout& pLayout,
+                      const Output& pOutput,
+                      const LDSection& pSection,
+                      MemoryRegion& pRegion) const;
+
+  void emitRel(const Layout& pLayout,
+               const Output& pOutput,
+               const llvm::MCSectionData& pSectionData,
+               MemoryRegion& pRegion) const;
+
+  void emitRela(const Layout& pLayout,
+                const Output& pOutput,
+                const llvm::MCSectionData& pSectionData,
+                MemoryRegion& pRegion) const;
+
+private:
+  // getSectEntrySize - compute ElfXX_Shdr::sh_entsize
+  uint64_t getELF32SectEntrySize(const LDSection& pSection) const;
+
+  // getSectEntrySize - compute ElfXX_Shdr::sh_entsize
+  uint64_t getELF64SectEntrySize(const LDSection& pSection) const;
+
+  // getSectEntrySize - compute ElfXX_Shdr::sh_link
+  uint64_t getSectLink(const LDSection& pSection, const Output& pOutput) const;
+
+  // getSectEntrySize - compute ElfXX_Shdr::sh_info
+  uint64_t getSectInfo(const LDSection& pSection, const Output& pOutput) const;
+
+  uint64_t getELF32LastStartOffset(const Output& pOutput) const;
+
+  uint64_t getELF64LastStartOffset(const Output& pOutput) const;
+
+protected:
+  GNULDBackend& f_Backend;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/GNUArchiveReader.h b/include/mcld/LD/GNUArchiveReader.h
new file mode 100644
index 0000000..57aee10
--- /dev/null
+++ b/include/mcld/LD/GNUArchiveReader.h
@@ -0,0 +1,86 @@
+//===- GNUArchiveReader.h -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_GNU_ARCHIVE_READER_H
+#define MCLD_GNU_ARCHIVE_READER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/LD/ArchiveReader.h"
+#include "mcld/Support/Path.h"
+#include <llvm/ADT/OwningPtr.h>
+
+#include <vector>
+#include <string>
+
+namespace llvm
+{
+class MemoryBuffer;
+
+}
+
+namespace mcld
+{
+class MCLDInfo;
+class Input;
+class InputTree;
+
+/** \class GNUArchiveReader
+ *  \brief GNUArchiveReader reads GNU archive files.
+ */
+class GNUArchiveReader : public ArchiveReader
+{
+private:
+  struct ArchiveMemberHeader;
+  struct SymbolTableEntry;
+
+public:
+  explicit GNUArchiveReader(MCLDInfo &pLDInfo, LDReader::Endian endian)
+  : m_pLDInfo(pLDInfo),
+    m_endian(endian)
+  { }
+
+  ~GNUArchiveReader()
+  { }
+
+  /// Read an archive and extract each member in.
+  /// Construct the coresponding Input for each member.
+  InputTree *readArchive(Input &input);
+
+  bool isMyFormat(Input &input) const;
+
+  LDReader::Endian endian(Input& pFile) const;
+
+private:
+  /// set up the archive, including
+  /// first, read symbol table
+  /// second, read extended file name which is used in thin archive
+  InputTree *setupNewArchive(Input &pInput, size_t off);
+
+  /// parse the archive header, and return the member size
+  size_t parseMemberHeader(llvm::OwningPtr<llvm::MemoryBuffer> &mapFile,
+                   off_t off,
+                   std::string *p_Name,
+                   off_t *nestedOff,
+                   std::string &p_ExtendedName);
+
+  void readSymbolTable(llvm::OwningPtr<llvm::MemoryBuffer> &mapFile,
+                      std::vector<SymbolTableEntry> &pSymbolTable,
+                      off_t start,
+                      size_t size);
+
+private:
+  MCLDInfo &m_pLDInfo;
+  LDReader::Endian m_endian;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/Group.h b/include/mcld/LD/Group.h
new file mode 100644
index 0000000..31c4a68
--- /dev/null
+++ b/include/mcld/LD/Group.h
@@ -0,0 +1,28 @@
+//===- Group.h ------------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LD_GROUP_H
+#define LD_GROUP_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+namespace mcld
+{
+
+/** \class Group
+ *  \brief Group records the grouping of all regions
+ */
+class Group
+{
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/InputSymbolTable.h b/include/mcld/LD/InputSymbolTable.h
new file mode 100644
index 0000000..c5e3864
--- /dev/null
+++ b/include/mcld/LD/InputSymbolTable.h
@@ -0,0 +1,46 @@
+//===- InputSymbolTable.h -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef INPUTSYMBOLTABLE_H
+#define INPUTSYMBOLTABLE_H
+#include <llvm/ADT/StringRef.h>
+#include "mcld/LD/SymbolTableIF.h"
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+namespace mcld
+{
+
+class LDSymbol;
+
+/** \class InputSymbolTable
+ *  \brief Input symbol table, for MCLDInput.
+ *
+ *  \see
+ */
+class InputSymbolTable : public SymbolTableIF
+{
+  /* draft. */
+  friend class SymbolTableFactory;
+private:
+  InputSymbolTable(StrSymPool &pStrSymPool,
+                   size_t pNumOfSymbols,
+                   StringTable &pEntireStringTable,
+                   StringTable &pDynamicStringTable);
+private:
+  virtual void doInsertSymbol(LDSymbol *);
+  virtual void doMerge(const SymbolTableIF &);
+public:
+  virtual ~InputSymbolTable();
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/LDContext.h b/include/mcld/LD/LDContext.h
new file mode 100644
index 0000000..878ba8d
--- /dev/null
+++ b/include/mcld/LD/LDContext.h
@@ -0,0 +1,105 @@
+//===- LDContext.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_LDCONTEXT_H
+#define MCLD_LDCONTEXT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <vector>
+#include <mcld/LD/LDFileFormat.h>
+#include <llvm/Support/DataTypes.h>
+#include <string>
+#include <cassert>
+
+namespace llvm {
+class StringRef;
+}
+
+namespace mcld
+{
+
+class LDSymbol;
+class LDSection;
+
+/** \class LDContext
+ *  \brief LDContext stores the data which a object file should has
+ */
+class LDContext
+{
+public:
+  typedef std::vector<LDSection*> SectionTable;
+  typedef SectionTable::iterator sect_iterator;
+  typedef SectionTable::const_iterator const_sect_iterator;
+
+  typedef std::vector<LDSymbol*> SymbolTable;
+  typedef SymbolTable::iterator sym_iterator;
+  typedef SymbolTable::const_iterator const_sym_iterator;
+
+public:
+  LDContext();
+
+  ~LDContext();
+
+  // -----  sections  ----- //
+  SectionTable& getSectionTable()
+  { return m_SectionTable; }
+
+  const SectionTable& getSectionTable() const
+  { return m_SectionTable; }
+
+  sect_iterator sectBegin()
+  { return m_SectionTable.begin(); }
+
+  sect_iterator sectEnd()
+  { return m_SectionTable.end(); }
+
+  const_sect_iterator sectBegin() const
+  { return m_SectionTable.begin(); }
+
+  const_sect_iterator sectEnd() const
+  { return m_SectionTable.end(); }
+
+  LDSection* getSection(unsigned int pIdx);
+
+  const LDSection* getSection(unsigned int pIdx) const;
+
+  LDSection* getSection(const std::string& pName);
+
+  const LDSection* getSection(const std::string& pName) const;
+
+  size_t getSectionIdx(const std::string& pName) const;
+
+  size_t numOfSections() const
+  { return m_SectionTable.size(); }
+
+  // -----  symbols  ----- //
+  LDSymbol* getSymbol(unsigned int pIdx);
+
+  const LDSymbol* getSymbol(unsigned int pIdx) const;
+
+  LDSymbol* getSymbol(const llvm::StringRef& pName);
+
+  const LDSymbol* getSymbol(const llvm::StringRef& pName) const;
+
+  void addSymbol(LDSymbol* pSym)
+  { m_SymTab.push_back(pSym); }
+
+private:
+  SectionTable m_SectionTable;
+  SymbolTable m_SymTab;
+
+  // FIXME : maintain a map<section name, section index>
+};
+
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/LDFileFormat.h b/include/mcld/LD/LDFileFormat.h
new file mode 100644
index 0000000..df80f67
--- /dev/null
+++ b/include/mcld/LD/LDFileFormat.h
@@ -0,0 +1,113 @@
+//===- LDFileFormat.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_LDFILE_FORMAT_H
+#define MCLD_LDFILE_FORMAT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <cstdio>
+#include <cassert>
+
+namespace mcld
+{
+
+class MCLinker;
+class LDSection;
+
+/** \class LDFileFormat
+ *  \brief LDFileFormat describes the common file formats.
+ */
+class LDFileFormat
+{
+public:
+  enum Kind {
+    Null,
+    Regular,
+    BSS,
+    NamePool,
+    Relocation,
+    Debug,
+    Target,
+    Exception,
+    Version,
+    Note,
+    MetaData,
+    Group,
+  };
+
+protected:
+  LDFileFormat();
+
+public:
+  virtual ~LDFileFormat();
+
+  /// initStdSections - initialize all standard sections.
+  void initStdSections(MCLinker& pLinker);
+
+  /// initObjectFormat - different format, such as ELF and MachO, should
+  /// implement this
+  virtual void initObjectFormat(MCLinker& pLinker) = 0;
+
+  /// initObjectType - different types, such as shared object, executable
+  /// files, should implement this
+  virtual void initObjectType(MCLinker& pLinker) = 0;
+
+  // -----  access functions  ----- //
+  LDSection& getText() {
+    assert(NULL != f_pTextSection);
+    return *f_pTextSection;
+  }
+
+  const LDSection& getText() const {
+    assert(NULL != f_pTextSection);
+    return *f_pTextSection;
+  }
+
+  LDSection& getData() {
+    assert(NULL != f_pDataSection);
+    return *f_pDataSection;
+  }
+
+  const LDSection& getData() const {
+    assert(NULL != f_pDataSection);
+    return *f_pDataSection;
+  }
+
+  LDSection& getBSS() {
+    assert(NULL != f_pBSSSection);
+    return *f_pBSSSection;
+  }
+
+  const LDSection& getBSS() const {
+    assert(NULL != f_pBSSSection);
+    return *f_pBSSSection;
+  }
+
+  LDSection& getReadOnly() {
+    assert(NULL != f_pReadOnlySection);
+    return *f_pReadOnlySection;
+  }
+
+  const LDSection& getReadOnly() const {
+    assert(NULL != f_pReadOnlySection);
+    return *f_pReadOnlySection;
+  }
+protected:
+  //         variable name         :  ELF               MachO
+  LDSection* f_pTextSection;       // .text             __text
+  LDSection* f_pDataSection;       // .data             __data
+  LDSection* f_pBSSSection;        // .bss              __bss
+  LDSection* f_pReadOnlySection;   // .rodata           __const
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/LDReader.h b/include/mcld/LD/LDReader.h
new file mode 100644
index 0000000..4fde9f0
--- /dev/null
+++ b/include/mcld/LD/LDReader.h
@@ -0,0 +1,47 @@
+//===- LDReader.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_READER_INTERFACE_H
+#define MCLD_READER_INTERFACE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/Support/DataTypes.h>
+
+namespace mcld
+{
+
+class Input;
+
+/** \class LDReader
+ *  \brief LDReader provides the basic interfaces for all readers. It also
+ *  provides basic functions to read data stream.
+ */
+class LDReader
+{
+public:
+  enum Endian {
+    LittleEndian,
+    BigEndian
+  };
+
+protected:
+  LDReader() { }
+
+public:
+  virtual ~LDReader() { }
+
+  virtual bool isMyFormat(Input& pInput) const = 0;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/LDSection.h b/include/mcld/LD/LDSection.h
new file mode 100644
index 0000000..4c793de
--- /dev/null
+++ b/include/mcld/LD/LDSection.h
@@ -0,0 +1,205 @@
+//===- LDSection.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_LD_LDSECTION_H
+#define MCLD_LD_LDSECTION_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/MC/MCSection.h>
+#include <llvm/MC/MCAssembler.h>
+#include <llvm/ADT/StringRef.h>
+#include <llvm/Support/DataTypes.h>
+#include <mcld/LD/LDFileFormat.h>
+#include <string>
+
+namespace llvm {
+
+class MCAsmInfo;
+class raw_ostream;
+
+} // namespace of llvm
+
+namespace mcld {
+/** \class LDSection
+ *  \brief LDSection represents a section header entry. It is a unified
+ *  abstraction for various file formats.
+ *
+ *  LDSection contains both the format-dependent data and LLVM specific data.
+ *
+ */
+class LDSection : public llvm::MCSection
+{
+public:
+  LDSection(const std::string& pName,
+            LDFileFormat::Kind pKind,
+            uint32_t pType,
+            uint32_t pFlag,
+            uint64_t pSize = 0,
+            uint64_t pOffset = 0,
+            uint64_t pAddr = 0);
+
+  /// name - the name of this section.
+  const std::string& name() const
+  { return m_Name; }
+
+  /// kind - the kind of this section, such as Text, BSS, GOT, and so on.
+  /// from LDFileFormat::Kind
+  LDFileFormat::Kind kind() const
+  { return m_Kind; }
+
+  /// type - The categorizes the section's contents and semantics. It's
+  /// different from llvm::SectionKind. Type is format-dependent, but
+  /// llvm::SectionKind is format independent and is used for bit-code.
+  ///   In ELF, it is sh_type
+  ///   In MachO, it's type field of struct section::flags
+  uint32_t type() const
+  { return m_Type; }
+
+  /// flag - An integer describes miscellaneous attributes.
+  ///   In ELF, it is sh_flags.
+  ///   In MachO, it's attribute field of struct section::flags
+  uint32_t flag() const
+  { return m_Flag; }
+
+  /// size - An integer specifying the size in bytes of the virtual memory
+  /// occupied by this section.
+  ///   In ELF, if the type() is SHT_NOBITS, this function return zero.
+  ///   Before layouting, output's LDSection::size() should return zero.
+  uint64_t size() const
+  { return m_Size; }
+
+  /// offset - An integer specifying the offset of this section in the file.
+  ///   Before layouting, output's LDSection::offset() should return zero.
+  uint64_t offset() const
+  { return m_Offset; }
+
+  /// addr - An integer specifying the virtual address of this section in the
+  /// virtual image.
+  ///   Before layouting, output's LDSection::offset() should return zero.
+  ///   ELF uses sh_addralign to set alignment constraints. In LLVM, alignment
+  ///   constraint is set in MCSectionData::setAlignment. addr() contains the
+  ///   original ELF::sh_addr. Modulo sh_addr by sh_addralign is not necessary.
+  ///   MachO uses the same scenario.
+  ///
+  ///   Because addr() in output is changing during linking, MCLinker does not
+  ///   store the address of the output here. The address is in Layout
+  uint64_t addr() const
+  { return m_Addr; }
+
+  /// align - An integer specifying the align of this section in the file.
+  ///   Before layouting, output's LDSection::align() should return zero.
+  uint32_t align() const
+  { return m_Align; }
+
+  size_t index() const
+  { return m_Index; }
+
+  /// getLink - return the Link. When a section A needs the other section B
+  /// during linking or loading, we say B is A's Link section.
+  /// In ELF, InfoLink section control the ElfNN_Shdr::sh_link and sh_info.
+  ///
+  /// @return if the section needs no other sections, return NULL
+  LDSection* getLink()
+  { return m_pLink; }
+
+  const LDSection* getLink() const
+  { return m_pLink; }
+
+  size_t getInfo() const
+  { return m_Info; }
+
+  void setKind(LDFileFormat::Kind pKind)
+  { m_Kind = pKind; }
+
+  void setSize(uint64_t size)
+  { m_Size = size; }
+
+  void setOffset(uint64_t Offset)
+  { m_Offset = Offset; }
+
+  void setAddr(uint64_t addr)
+  { m_Addr = addr; }
+
+  void setAlign(uint32_t align)
+  { m_Align = align; }
+
+  void setFlag(uint32_t flag)
+  { m_Flag = flag; }
+
+  void setType(uint32_t type)
+  { m_Type = type; }
+
+  static bool classof(const MCSection *S)
+  { return S->getVariant() == SV_LDContext; }
+
+  static bool classof(const LDSection *)
+  { return true; }
+
+  // -----  methods for adapt to llvm::MCSection  ----- //
+  void PrintSwitchToSection(const llvm::MCAsmInfo &MAI,
+                            llvm::raw_ostream &OS) const
+  { }
+
+  bool UseCodeAlign() const
+  { return true; }
+
+  bool isVirtualSection() const
+  { return false; }
+
+  llvm::MCSectionData* getSectionData()
+  { return m_pSectionData; }
+
+  const llvm::MCSectionData* getSectionData() const
+  { return m_pSectionData; }
+
+  void setSectionData(llvm::MCSectionData* pSD)
+  { m_pSectionData = pSD; }
+
+  bool hasSectionData() const
+  { return (NULL != m_pSectionData); }
+
+  /// setLink - set the sections should link with.
+  /// if pLink is NULL, no Link section is set.
+  void setLink(LDSection* pLink)
+  { m_pLink = pLink; }
+
+  void setInfo(size_t pInfo)
+  { m_Info = pInfo; }
+
+  void setIndex(size_t pIndex)
+  { m_Index = pIndex; }
+
+private:
+  std::string m_Name;
+  LDFileFormat::Kind m_Kind;
+  uint32_t m_Type;
+  uint32_t m_Flag;
+
+  uint64_t m_Size;
+  uint64_t m_Offset;
+  uint64_t m_Addr;
+  uint32_t m_Align;
+
+  size_t m_Info;
+  LDSection* m_pLink;
+
+  // pointer to MCSectionData.
+  llvm::MCSectionData* m_pSectionData;
+
+  // the index of the file
+  size_t m_Index;
+
+}; // end of LDSection
+
+} // end namespace mcld
+
+#endif
+
diff --git a/include/mcld/LD/LDSectionFactory.h b/include/mcld/LD/LDSectionFactory.h
new file mode 100644
index 0000000..49b11c7
--- /dev/null
+++ b/include/mcld/LD/LDSectionFactory.h
@@ -0,0 +1,58 @@
+//===- LDSectionFactory.h -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_LDSECTION_FACTORY_H
+#define MCLD_LDSECTION_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/Support/GCFactory.h>
+#include <mcld/LD/LDSection.h>
+#include <mcld/LD/LDFileFormat.h>
+#include <string>
+
+namespace mcld
+{
+
+/** \class LDSectionFactory
+ *  \brief provide the interface to create and delete section data for output
+ */
+class LDSectionFactory : public GCFactory<LDSection, 0>
+{
+public:
+  /// LDSectionFactory - the factory of LDSection
+  /// pNum is the average number of the LDSections in the system.
+  LDSectionFactory(size_t pNum);
+  ~LDSectionFactory();
+
+  /// produce - produce an empty section information.
+  /// This function will create an empty MCSectionData and its LDSection.
+  /// @param pName - The name of the section.
+  /// @param pKind - The kind of the section. Used to create default section map
+  /// @param pType - sh_type in ELF.
+  /// @param pFlag - is the same as sh_flags.
+  LDSection* produce(const std::string& pName,
+                     LDFileFormat::Kind pKind,
+                     uint32_t pType,
+                     uint32_t pFlag);
+
+  /// destroy - destruct the LDSection.
+  /// @oaram - the reference of the pointer to the destructed LDSection.
+  ///          after the destruction, the pointer is set to zero.
+  void destroy(LDSection*& pSD);
+
+  /// find - find the LDSection* in factory from the given section name.
+  ///        return NULL if not found.
+  /// @param pName - the name of section
+  LDSection* find(const std::string& pName);
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/LDSymbol.h b/include/mcld/LD/LDSymbol.h
new file mode 100644
index 0000000..45c0b75
--- /dev/null
+++ b/include/mcld/LD/LDSymbol.h
@@ -0,0 +1,128 @@
+//===- LDSymbol.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_LD_SYMBOL_H
+#define MCLD_LD_SYMBOL_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/ADT/Uncopyable.h"
+#include "mcld/LD/ResolveInfo.h"
+#include "mcld/MC/MCFragmentRef.h"
+#include <llvm/MC/MCAssembler.h>
+#include <assert.h>
+
+namespace mcld
+{
+
+/** \class LDSymbol
+ *  \brief LDSymbol provides a consistent abstraction for different formats
+ *  in different targets.
+ */
+class LDSymbol
+{
+public:
+  // FIXME: use SizeTrait<32> or SizeTrait<64> instead of big type
+  typedef ResolveInfo::SizeType SizeType;
+  typedef uint64_t ValueType;
+  typedef MCFragmentRef::Offset Offset;
+
+public:
+  LDSymbol();
+  LDSymbol(const LDSymbol& pCopy);
+  LDSymbol& operator=(const LDSymbol& pCopy);
+  ~LDSymbol();
+
+  // -----  observers  ----- //
+  const char* name() const {
+    assert(NULL != m_pResolveInfo);
+    return m_pResolveInfo->name();
+  }
+
+  unsigned int nameSize() const {
+    assert(NULL != m_pResolveInfo);
+    return m_pResolveInfo->nameSize();
+  }
+
+  llvm::StringRef str() const {
+    assert(NULL != m_pResolveInfo);
+    return llvm::StringRef(m_pResolveInfo->name(), m_pResolveInfo->nameSize());
+  }
+
+  bool isDyn() const {
+    assert(NULL != m_pResolveInfo);
+    return m_pResolveInfo->isDyn();
+  }
+
+  unsigned int type() const {
+    assert(NULL != m_pResolveInfo);
+    return m_pResolveInfo->type();
+  }
+ unsigned int desc() const {
+    assert(NULL != m_pResolveInfo);
+    return m_pResolveInfo->desc();
+  }
+  unsigned int binding() const {
+    assert(NULL != m_pResolveInfo);
+    return m_pResolveInfo->binding();
+  }
+
+  uint8_t other() const {
+    assert(NULL != m_pResolveInfo);
+    return m_pResolveInfo->other();
+  }
+
+  uint8_t visibility() const {
+    assert(NULL != m_pResolveInfo);
+    return m_pResolveInfo->other();
+  }
+
+  ValueType value() const
+  { return m_Value; }
+
+  const MCFragmentRef* fragRef() const
+  { return m_pFragRef; }
+
+  SizeType size() const
+  { return m_pResolveInfo->size(); }
+
+  ResolveInfo* resolveInfo()
+  { return m_pResolveInfo; }
+
+  const ResolveInfo* resolveInfo() const 
+  { return m_pResolveInfo; }
+
+  bool hasFragRef() const
+  { return (NULL != m_pFragRef); }
+
+  // -----  modifiers  ----- //
+  void setSize(SizeType pSize) {
+    assert(NULL != m_pResolveInfo);
+    m_pResolveInfo->setSize(pSize);
+  }
+
+  void setValue(ValueType pValue)
+  { m_Value = pValue; }
+ 
+  void setFragmentRef(MCFragmentRef* pFragmentRef);
+
+  void setResolveInfo(const ResolveInfo& pInfo);
+
+private:
+  // -----  Symbol's fields  ----- //
+  ResolveInfo* m_pResolveInfo;
+  MCFragmentRef* m_pFragRef;
+  ValueType m_Value;
+
+};
+
+} // namespace mcld
+
+#endif
+
diff --git a/include/mcld/LD/LDWriter.h b/include/mcld/LD/LDWriter.h
new file mode 100644
index 0000000..78c2871
--- /dev/null
+++ b/include/mcld/LD/LDWriter.h
@@ -0,0 +1,41 @@
+//===- LDWriter.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  LDWriter provides an interface used by MCLinker,
+//  which writes the result of linking into a .so file or a executable.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_WRITER_INTERFACE_H
+#define MCLD_WRITER_INTERFACE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/Target/TargetLDBackend.h>
+
+namespace mcld
+{
+
+/** \class LDWriter
+ *  \brief LDWriter provides the basic interfaces for all writers.
+ *  (ObjectWriter, DynObjWriter, and EXEObjWriter)
+ */
+class LDWriter
+{
+protected:
+  LDWriter() { }
+
+public:
+  virtual ~LDWriter() { }
+
+};
+
+} //end namespace
+
+#endif
+
diff --git a/include/mcld/LD/Layout.h b/include/mcld/LD/Layout.h
new file mode 100644
index 0000000..28f2d83
--- /dev/null
+++ b/include/mcld/LD/Layout.h
@@ -0,0 +1,270 @@
+//===- Layout.h -----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_LAYOUT_H
+#define MCLD_LAYOUT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/ADT/ilist.h>
+#include <llvm/ADT/ilist_node.h>
+#include <llvm/ADT/DenseMap.h>
+#include <llvm/MC/MCAssembler.h>
+#include <mcld/MC/MCFragmentRef.h>
+#include <mcld/Support/GCFactory.h>
+#include <mcld/LD/LDSection.h>
+#include <map>
+
+namespace mcld
+{
+class MCLinker;
+class Output;
+class TargetLDBackend;
+
+/** \class Layout
+ *  \brief Layout maintains the mapping between sections and fragments.
+ *
+ *  MCLinker is a fragment-based linker. But readers and target backends
+ *  still need section information. Layout is used to maintain the mapping
+ *  between sections and fragments. Layout helps readers and target backends
+ *  get the input or output section information from a fragment.
+ */
+class Layout
+{
+public:
+  typedef std::vector<LDSection*> SectionOrder;
+  typedef SectionOrder::iterator sect_iterator;
+  typedef SectionOrder::const_iterator const_sect_iterator;
+
+public:
+  /// constructor
+  Layout();
+
+  /// destructor
+  ~Layout();
+
+  /// getInputLDSection - give a MCFragment, return the corresponding input
+  /// LDSection*
+  ///
+  /// @return return NULL if the fragment is not found in input
+  LDSection* getInputLDSection(const llvm::MCFragment& pFrag);
+
+  /// getInputLDSection - give a MCFragment, return the corresponding input
+  /// LDSection*
+  ///
+  /// @return return NULL if the fragment is not found in input
+  const LDSection* getInputLDSection(const llvm::MCFragment& pFrag) const;
+
+  /// getFragmentRef - give a LDSection in input file and an offset, return
+  /// the fragment reference.
+  ///
+  /// @param pInputSection - the given input section
+  /// @param pOffset - the offset, cannot be larger than this input section.
+  /// @return if found, return the fragment. Otherwise, return NULL.
+  MCFragmentRef*
+  getFragmentRef(const LDSection& pInputSection, uint64_t pOffset);
+
+  /// getFragmentRef - give a fragment and a big offset, return the fragment
+  /// reference in the section data.
+  ///
+  /// @param pFrag - the given fragment
+  /// @param pBigOffset - the offset, can be larger than the fragment, but can
+  ///                     not larger than this input section.
+  /// @return if found, return the fragment. Otherwise, return NULL.
+  MCFragmentRef*
+  getFragmentRef(const llvm::MCFragment& pFrag, uint64_t pBigOffset);
+
+  /// getOutputOffset - Get the offset of the given fragment inside the
+  /// the output's MCSectionData.
+  uint64_t getOutputOffset(const llvm::MCFragment& pFrag);
+
+  /// getOutputOffset - Get the offset of the given fragment inside the
+  /// the output's MCSectionData.
+  uint64_t getOutputOffset(const llvm::MCFragment& pFrag) const;
+
+  /// getOutputOffset - Get the offset of the given fragment inside
+  /// the output's MCSectionData.
+  ///
+  /// @return return -1 if the fragment is not found in output's MCSectionData.
+
+  uint64_t getOutputOffset(const MCFragmentRef& pFragRef);
+  /// getOutputOffset - Get the offset of the given fragment inside
+  /// the output's MCSectionData.
+  ///
+  /// @return return -1 if the fragment is not found in output's MCSectionData.
+  uint64_t getOutputOffset(const MCFragmentRef& pFragRef) const;
+
+  /// getOutputLDSection - give a MCFragment, return the corresponding output
+  /// LDSection*
+  ///
+  /// @return return NULL if the fragment is not found in the output
+  LDSection* getOutputLDSection(const llvm::MCFragment& pFrag);
+
+  /// getOutputLDSection - give a MCFragment, return the corresponding output
+  /// LDSection*
+  ///
+  /// @return return NULL if the fragment is not found in the output
+  const LDSection* getOutputLDSection(const llvm::MCFragment& pFrag) const;
+
+  // -----  modifiers  ----- //
+  bool layout(Output& pOutput, const TargetLDBackend& pBackend);
+
+  /// addInputRange
+  void addInputRange(const llvm::MCSectionData& pSD,
+                     const LDSection& pInputHdr);
+
+  /// appendFragment - append the given MCFragment to the given MCSectionData,
+  /// and insert a MCAlignFragment to preserve the required align constraint if
+  /// needed
+  /// @return return the inserted size, i.e., the size of pFrag and alignment
+  /// size if any
+  uint64_t appendFragment(llvm::MCFragment& pFrag,
+                          llvm::MCSectionData& pSD,
+                          uint32_t pAlignConstraint = 1);
+private:
+  /** \class Range
+   *  \brief Range is a <input's LDSection, previous rear fragment> pair
+   */
+  struct Range : public llvm::ilist_node<Range>
+  {
+  public:
+    Range();
+    Range(const LDSection& pHeader);
+    ~Range();
+
+  public:
+    LDSection* header;
+    llvm::MCFragment* prevRear;
+  };
+
+  typedef llvm::iplist<Range> RangeList;
+
+  typedef std::map<const llvm::MCSectionData*, RangeList*> SDRangeMap;
+
+  typedef GCFactory<MCFragmentRef, 0> FragRefFactory;
+
+private:
+  inline bool isFirstRange(const Range& pRange) const
+  { return (NULL == pRange.prevRear); }
+
+  inline bool isLastRange(const Range& pRange) const
+  { return (NULL == pRange.getNextNode()); }
+
+  inline bool isEmptyRange(const Range& pRange) const
+  {
+    if (isFirstRange(pRange)) {
+      if (!pRange.header->hasSectionData() ||
+          pRange.header->getSectionData()->getFragmentList().empty())
+        return true;
+      else
+        return false;
+    }
+    return (NULL == pRange.prevRear->getNextNode());
+  }
+
+  // get the front fragment in the range.
+  inline llvm::MCFragment* getFront(Range& pRange) const
+  {
+    if (!pRange.header->hasSectionData())
+      return NULL;
+    if (pRange.header->getSectionData()->getFragmentList().empty())
+      return NULL;
+
+    if (isFirstRange(pRange))
+      return &pRange.header->getSectionData()->getFragmentList().front();
+
+    if (isEmptyRange(pRange))
+      return NULL;
+
+    return pRange.prevRear->getNextNode();
+  }
+
+  inline const llvm::MCFragment* getFront(const Range& pRange) const
+  {
+    if (!pRange.header->hasSectionData())
+      return NULL;
+    if (pRange.header->getSectionData()->getFragmentList().empty())
+      return NULL;
+
+    if (isFirstRange(pRange))
+      return &pRange.header->getSectionData()->getFragmentList().front();
+
+    if (isEmptyRange(pRange))
+      return NULL;
+
+    return pRange.prevRear->getNextNode();
+  }
+
+  // get the rear fragment in the range.
+  inline llvm::MCFragment* getRear(Range& pRange) const
+  {
+    if (!pRange.header->hasSectionData())
+      return NULL;
+    if (pRange.header->getSectionData()->getFragmentList().empty())
+      return NULL;
+
+    if (isLastRange(pRange)) {
+      if (isEmptyRange(pRange))
+        return NULL;
+      return &pRange.header->getSectionData()->getFragmentList().back();
+    }
+    return pRange.getNextNode()->prevRear;
+  }
+
+  inline const llvm::MCFragment* getRear(const Range& pRange) const
+  {
+    if (!pRange.header->hasSectionData())
+      return NULL;
+    if (pRange.header->getSectionData()->getFragmentList().empty())
+      return NULL;
+
+    if (isLastRange(pRange)) {
+      if (isEmptyRange(pRange))
+        return NULL;
+      return &pRange.header->getSectionData()->getFragmentList().back();
+    }
+    return pRange.getNextNode()->prevRear;
+  }
+
+  MCFragmentRef* getFragmentRef(Range &pRange, uint64_t pOffset);
+
+  MCFragmentRef* getFragmentRef(llvm::MCFragment& pFront,
+                                llvm::MCFragment& pRear,
+                                uint64_t pOffset);
+
+  bool hasLayoutOrder(const llvm::MCFragment& pFragment) const
+  { return (pFragment.getLayoutOrder() != ~(0U)); }
+
+  bool hasLayoutOffset(const llvm::MCFragment& pFragment) const
+  { return (pFragment.Offset != ~UINT64_C(0)); }
+
+  bool isValidOffset(const llvm::MCFragment& pFrag, uint64_t pTargetOffset) const;
+
+  void setFragmentLayoutOrder(llvm::MCFragment* pFragment);
+
+  void setFragmentLayoutOffset(llvm::MCFragment* pFragment);
+
+  /// sortSectionOrder - perform sorting on m_SectionOrder to get final layout
+  /// ordering
+  void sortSectionOrder(const Output& pOutput,
+                        const TargetLDBackend& pBackend);
+
+private:
+  /// a vector to describe the order of sections
+  SectionOrder m_SectionOrder;
+
+  /// the map from MCSectionData* to its own RangeList.
+  SDRangeMap m_SDRangeMap;
+
+  FragRefFactory m_FragRefFactory;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ObjectReader.h b/include/mcld/LD/ObjectReader.h
new file mode 100644
index 0000000..9dbe9ac
--- /dev/null
+++ b/include/mcld/LD/ObjectReader.h
@@ -0,0 +1,69 @@
+//===- ObjectReader.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_OBJECT_READER_H
+#define MCLD_OBJECT_READER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/LD/LDReader.h"
+#include <llvm/Support/system_error.h>
+#include <mcld/ADT/HashTable.h>
+#include <mcld/ADT/StringHash.h>
+#include <mcld/LD/ResolveInfo.h>
+#include <mcld/LD/ResolveInfoFactory.h>
+
+namespace mcld
+{
+
+class Input;
+
+/** \class ObjectReader
+ *  \brief ObjectReader provides an common interface for different object
+ *  formats.
+ */
+class ObjectReader : public LDReader
+{
+protected:
+  typedef HashTable<ResolveInfo,
+                    StringHash<ELF>,
+                    ResolveInfoFactory> GroupSignatureMap;
+
+protected:
+  ObjectReader()
+  { }
+
+public:
+  virtual ~ObjectReader() { }
+
+  virtual bool readObject(Input& pFile) = 0;
+
+  virtual bool readSymbols(Input& pFile) = 0;
+
+  virtual bool readSections(Input& pFile) = 0;
+
+  /// readRelocations - read relocation sections
+  ///
+  /// This function should be called after symbol resolution.
+  virtual bool readRelocations(Input& pFile) = 0;
+
+  GroupSignatureMap& signatures()
+  { return f_GroupSignatureMap; }
+
+  const GroupSignatureMap& signatures() const
+  { return f_GroupSignatureMap; }
+
+protected:
+  GroupSignatureMap f_GroupSignatureMap;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ObjectWriter.h b/include/mcld/LD/ObjectWriter.h
new file mode 100644
index 0000000..0c48723
--- /dev/null
+++ b/include/mcld/LD/ObjectWriter.h
@@ -0,0 +1,39 @@
+//===- ObjectWriter.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_OBJECT_WRITER_INTERFACE_H
+#define MCLD_OBJECT_WRITER_INTERFACE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/Support/system_error.h>
+
+namespace mcld
+{
+
+class Output;
+class GNULDBackend;
+
+/** \class ObjectWriter
+ *  \brief ObjectWriter provides a common interface for object file writers.
+ */
+class ObjectWriter
+{
+protected:
+  ObjectWriter(GNULDBackend& pBackend);
+
+public:
+  virtual ~ObjectWriter();
+
+  virtual llvm::error_code writeObject(Output& pOutput) = 0;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/OutputSymbolTable.h b/include/mcld/LD/OutputSymbolTable.h
new file mode 100644
index 0000000..fdcf0bc
--- /dev/null
+++ b/include/mcld/LD/OutputSymbolTable.h
@@ -0,0 +1,44 @@
+//===- OutputSymbolTable.h ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef OUTPUTSYMBOLTABLE_H
+#define OUTPUTSYMBOLTABLE_H
+#include <llvm/ADT/StringRef.h>
+#include "mcld/LD/SymbolTableIF.h"
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+namespace mcld
+{
+
+class LDSymbol;
+
+/** \class OutputSymbolTable
+ *  \brief Output symbol table, for MCLDOutput.
+ *
+ *  \see
+ */
+class OutputSymbolTable : public SymbolTableIF
+{
+  /* draft. */
+  friend class SymbolTableFactory;
+private:
+  OutputSymbolTable(StrSymPool &pStrSymPool,
+                    size_t pNumOfSymbols,
+                    StringTable &pEntireStringTable,
+                    StringTable &pDynamicStringTable);
+private:
+  virtual void doInsertSymbol(LDSymbol *);
+  virtual void doMerge(const SymbolTableIF &);
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/Relocation.h b/include/mcld/LD/Relocation.h
new file mode 100644
index 0000000..09ff6e4
--- /dev/null
+++ b/include/mcld/LD/Relocation.h
@@ -0,0 +1,115 @@
+//===- Relocation.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LD_RELOCATION_H
+#define LD_RELOCATION_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/ADT/ilist_node.h>
+#include <llvm/Support/DataTypes.h>
+#include <mcld/MC/MCFragmentRef.h>
+#include <mcld/LD/ResolveInfo.h>
+#include <mcld/LD/LDSymbol.h>
+
+
+namespace mcld
+{
+class Layout;
+class RelocationFactory;
+class MCLDInfo;
+
+class Relocation : public llvm::MCFragment
+{
+friend class RelocationFactory;
+
+public:
+  typedef uint64_t Address; // FIXME: use SizeTrait<T>::Address instead
+  typedef uint64_t DWord; // FIXME: use SizeTrait<T>::Word instead
+  typedef uint8_t Type;
+
+private:
+  Relocation(Type pType,
+             MCFragmentRef* pTargetRef,
+             Address pAddend,
+             DWord pTargetData);
+
+public:
+  ~Relocation();
+
+  /// type - relocation type
+  Type type() const
+  { return m_Type; }
+
+  /// symValue - S value - the symbol address
+  Address symValue() const;
+
+  /// addend - A value
+  Address addend() const
+  { return m_Addend; }
+
+  /// place - P value - address of the place being relocated
+  Address place(const Layout& pLayout) const;
+
+  /// symbol info - binding, type
+  const ResolveInfo* symInfo() const
+  { return m_pSymInfo; }
+
+  /// symbol info - binding, type
+  ResolveInfo* symInfo()
+  { return m_pSymInfo; }
+
+  /// target - the target data to relocate
+  DWord& target();
+
+  /// target - the target data to relocate
+  const DWord& target() const;
+
+  /// targetRef - the reference of the target data
+  MCFragmentRef& targetRef()
+  { return m_TargetAddress; }
+
+  /// targetRef - the reference of the target data
+  const MCFragmentRef& targetRef() const
+  { return m_TargetAddress; }
+
+  void apply(RelocationFactory& pRelocFactory, const MCLDInfo& pLDInfo);
+
+  /// ----- modifiers ----- ///
+  void setType(Type pType);
+
+  void setAddend(Address pAddend);
+
+  void setSymInfo(ResolveInfo* pSym);
+
+  // Relocation is a kind of MCFragment with type of FT_Reloc
+  static bool classof(const MCFragment *F)
+  { return F->getKind() == MCFragment::FT_Reloc;}
+  static bool classof(const Relocation *) { return true; }
+
+private:
+  /// m_Type - the type of the relocation entries
+  Type m_Type;
+
+  /// m_TargetData - target data of the place being relocated
+  DWord m_TargetData;
+
+  /// m_pSymInfo - resolved symbol info of relocation target symbol
+  ResolveInfo* m_pSymInfo;
+
+  /// m_TargetAddress - MCFragmentRef of the place being relocated
+  MCFragmentRef m_TargetAddress;
+
+  /// m_Addend - the addend
+  Address m_Addend;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/RelocationFactory.h b/include/mcld/LD/RelocationFactory.h
new file mode 100644
index 0000000..eed3eae
--- /dev/null
+++ b/include/mcld/LD/RelocationFactory.h
@@ -0,0 +1,81 @@
+//===- Relocation.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LD_RELOCATION_FACTORY_H
+#define LD_RELOCATION_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/Support/GCFactory.h>
+#include <mcld/LD/Relocation.h>
+
+namespace mcld
+{
+
+class LDSymbol;
+class ResolveInfo;
+class MCFragmentRef;
+class Layout;
+class GOT;
+class TargetLDBackend;
+class MCLDInfo;
+
+/** \class RelocationFactory
+ *  \brief RelocationFactory provides the interface for generating target
+ *  relocation
+ *
+ */
+class RelocationFactory : public GCFactory<Relocation, 0>
+{
+public:
+  typedef Relocation::Type Type;
+  typedef Relocation::Address Address;
+  typedef Relocation::DWord DWord;
+
+public:
+  explicit RelocationFactory(size_t pNum);
+
+  virtual ~RelocationFactory();
+
+  /// apply - general apply function
+  virtual void applyRelocation(Relocation& pRelocation,
+                               const MCLDInfo& pLDInfo) = 0;
+
+  // ----- production ----- //
+  /// produce - produce a relocation entry
+  /// @param pType - the type of the relocation entry
+  /// @param pFragRef - the place to apply the relocation
+  /// @param pAddend - the addend of the relocation entry
+  Relocation* produce(Type pType,
+                      MCFragmentRef& pFragRef,
+                      Address pAddend = 0);
+
+  /// produceEmptyEntry - produce an empty relocation which
+  /// occupied memory space but all contents set to zero.
+  Relocation* produceEmptyEntry();
+
+  void destroy(Relocation* pRelocation);
+
+  void setLayout(const Layout& pLayout);
+
+  // ------ observers -----//
+  const Layout& getLayout() const;
+
+  virtual TargetLDBackend& getTarget() = 0;
+
+  virtual const TargetLDBackend& getTarget() const = 0;
+
+private:
+  const Layout* m_pLayout;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ResolveInfo.h b/include/mcld/LD/ResolveInfo.h
new file mode 100644
index 0000000..f48f1c2
--- /dev/null
+++ b/include/mcld/LD/ResolveInfo.h
@@ -0,0 +1,279 @@
+//===- ResolveInfo.h ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_RESOLVE_INFO_H
+#define MCLD_RESOLVE_INFO_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/Support/DataTypes.h>
+#include <llvm/ADT/StringRef.h>
+
+namespace mcld
+{
+
+class LDSymbol;
+
+/** \class ResolveInfo
+ *  \brief ResolveInfo records the information about how to resolve a symbol.
+ *
+ *  A symbol must have some `attributes':
+ *  - Desc - Defined, Reference, Common or Indirect
+ *  - Binding - Global, Local, Weak
+ *  - IsDyn - appear in dynamic objects or regular objects
+ *  - Type - what the symbol points to
+ *  - Size  - the size of the symbol point to
+ *  - Value - the pointer to another LDSymbol
+ *  In order to save the memory and speed up the performance, MCLinker uses
+ *  a bit field to store all attributes.
+ *
+ *  The maximum string length is (2^16 - 1)
+ */
+class ResolveInfo
+{
+friend class ResolveInfoFactory;
+friend class MCLinker;
+public:
+  typedef uint64_t SizeType;
+
+  /** \enum Type
+   *  \brief What the symbol stand for
+   *
+   *  It is like ELF32_ST_TYPE
+   *  MachO does not need this, and can not jump between Thumb and ARM code.
+   */
+  enum Type {
+    NoType        = 0,
+    Object        = 1,
+    Function      = 2,
+    Section       = 3,
+    File          = 4,
+    CommonBlock   = 5,
+    ThreadLocal    = 6,
+    LoProc        = 13,
+    HiProc        = 15
+  };
+
+  /** \enum Desc
+   *  \brief Description of the symbols.
+   *
+   *   Follow the naming in MachO. Like MachO nlist::n_desc
+   *   In ELF, is a part of st_shndx
+   */
+  enum Desc {
+    Undefined    = 0,
+    Define       = 1,
+    Common       = 2,
+    Indirect     = 3,
+    NoneDesc
+  };
+
+  enum Binding {
+    Global       = 0,
+    Weak         = 1,
+    Local        = 2,
+    Absolute     = 3,
+    NoneBinding
+  };
+
+  enum Visibility {
+    Default      = 0,
+    Internal     = 1,
+    Hidden       = 2,
+    Protected    = 3
+  };
+
+  // -----  For HashTable  ----- //
+  typedef llvm::StringRef key_type;
+
+public:
+  // -----  modifiers  ----- //
+  /// setRegular - set the source of the file is a regular object
+  void setRegular();
+
+  /// setDynamic - set the source of the file is a dynamic object
+  void setDynamic();
+
+  /// setSource - set the source of the file
+  /// @param pIsDyn is the source from a dynamic object?
+  void setSource(bool pIsDyn);
+
+  void setType(uint32_t pType);
+
+  void setDesc(uint32_t pDesc);
+
+  void setBinding(uint32_t pBinding);
+
+  void setOther(uint32_t pOther);
+
+  void setVisibility(Visibility pVisibility);
+
+  void setIsSymbol(bool pIsSymbol);
+
+  void setReserved(uint32_t pReserved);
+
+  void setSize(SizeType pSize)
+  { m_Size = pSize; }
+
+  void override(const ResolveInfo& pForm);
+
+  void overrideAttributes(const ResolveInfo& pFrom);
+
+  void overrideVisibility(const ResolveInfo& pFrom);
+
+  void setSymPtr(const LDSymbol* pSymPtr)
+  { m_Ptr.sym_ptr = const_cast<LDSymbol*>(pSymPtr); }
+
+  void setLink(const ResolveInfo* pTarget) {
+    m_Ptr.info_ptr = const_cast<ResolveInfo*>(pTarget);
+    m_BitField |= indirect_flag;
+  }
+
+
+  // -----  observers  ----- //
+  bool isSymbol() const;
+
+  bool isString() const;
+
+  bool isGlobal() const;
+
+  bool isWeak() const;
+
+  bool isLocal() const;
+
+  bool isAbsolute() const;
+
+  bool isDefine() const;
+
+  bool isUndef() const;
+
+  bool isDyn() const;
+
+  bool isCommon() const;
+
+  bool isIndirect() const;
+
+  uint32_t type() const;
+
+  uint32_t desc() const;
+
+  uint32_t binding() const;
+
+  uint32_t reserved() const;
+
+  uint8_t other() const
+  { return (uint8_t)visibility(); }
+
+  Visibility visibility() const;
+
+  LDSymbol* outSymbol()
+  { return m_Ptr.sym_ptr; }
+
+  const LDSymbol* outSymbol() const
+  { return m_Ptr.sym_ptr; }
+
+  ResolveInfo* link()
+  { return m_Ptr.info_ptr; }
+
+  const ResolveInfo* link() const
+  { return m_Ptr.info_ptr; }
+
+  SizeType size() const
+  { return m_Size; }
+
+  const char* name() const
+  { return m_Name; }
+
+  unsigned int nameSize() const
+  { return (m_BitField >> NAME_LENGTH_OFFSET); }
+
+  uint32_t info() const
+  { return (m_BitField & INFO_MASK); }
+
+  uint32_t bitfield() const
+  { return m_BitField; }
+
+  // -----  For HashTable  ----- //
+  bool compare(const key_type& pKey);
+
+private:
+  static const uint32_t GLOBAL_OFFSET      = 0;
+  static const uint32_t GLOBAL_MASK        = 1;
+
+  static const uint32_t DYN_OFFSET         = 1;
+  static const uint32_t DYN_MASK           = 1   << DYN_OFFSET;
+
+  static const uint32_t DESC_OFFSET        = 2;
+  static const uint32_t DESC_MASK          = 0x3 << DESC_OFFSET;
+
+  static const uint32_t LOCAL_OFFSET       = 4;
+  static const uint32_t LOCAL_MASK         = 1   << LOCAL_OFFSET;
+
+  static const uint32_t BINDING_MASK       = GLOBAL_MASK | LOCAL_MASK;
+
+  static const uint32_t VISIBILITY_OFFSET  = 5;
+  static const uint32_t VISIBILITY_MASK    = 0x3 << VISIBILITY_OFFSET;
+
+  static const uint32_t TYPE_OFFSET        = 7;
+  static const uint32_t TYPE_MASK          = 0xF << TYPE_OFFSET;
+
+  static const uint32_t SYMBOL_OFFSET      = 11;
+  static const uint32_t SYMBOL_MASK        = 1   << SYMBOL_OFFSET;
+
+  static const uint32_t RESERVED_OFFSET    = 12;
+  static const uint32_t RESERVED_MASK      = 0xF << RESERVED_OFFSET;
+  static const uint32_t NAME_LENGTH_OFFSET = 16;
+  static const uint32_t INFO_MASK          = 0xF;
+  static const uint32_t RESOLVE_MASK       = 0xFFFF;
+
+  union SymOrInfo {
+    LDSymbol*    sym_ptr;
+    ResolveInfo* info_ptr;
+  };
+
+public:
+  static const uint32_t global_flag    = 0        << GLOBAL_OFFSET;
+  static const uint32_t weak_flag      = 1        << GLOBAL_OFFSET;
+  static const uint32_t regular_flag   = 0        << DYN_OFFSET;
+  static const uint32_t dynamic_flag   = 1        << DYN_OFFSET;
+  static const uint32_t undefine_flag  = 0        << DESC_OFFSET;
+  static const uint32_t define_flag    = 1        << DESC_OFFSET;
+  static const uint32_t common_flag    = 2        << DESC_OFFSET;
+  static const uint32_t indirect_flag  = 3        << DESC_OFFSET;
+  static const uint32_t local_flag     = 1        << LOCAL_OFFSET;
+  static const uint32_t absolute_flag  = BINDING_MASK;
+  static const uint32_t object_flag    = Object   << TYPE_OFFSET;
+  static const uint32_t function_flag  = Function << TYPE_OFFSET;
+  static const uint32_t section_flag   = Section  << TYPE_OFFSET;
+  static const uint32_t file_flag      = File     << TYPE_OFFSET;
+  static const uint32_t string_flag    = 0        << SYMBOL_OFFSET;
+  static const uint32_t symbol_flag    = 1        << SYMBOL_OFFSET;
+
+private:
+  ResolveInfo();
+  ResolveInfo(const ResolveInfo& pCopy);
+  ResolveInfo& operator=(const ResolveInfo& pCopy);
+  ~ResolveInfo();
+
+private:
+  SizeType m_Size;
+  SymOrInfo m_Ptr;
+
+  /** m_BitField
+   *  31     ...    16 15    12 11     10..7 6      ..    5 4     3   2   1   0
+   * |length of m_Name|reserved|Symbol|Type |ELF visibility|Local|Com|Def|Dyn|Weak|
+   */
+  uint32_t m_BitField;
+  char m_Name[0];
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/ResolveInfoFactory.h b/include/mcld/LD/ResolveInfoFactory.h
new file mode 100644
index 0000000..fcadf48
--- /dev/null
+++ b/include/mcld/LD/ResolveInfoFactory.h
@@ -0,0 +1,37 @@
+//===- ResolveInfoFactory.h -----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_RESOLVE_INFO_FACTORY_H
+#define MCLD_RESOLVE_INFO_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/LD/ResolveInfo.h"
+
+namespace mcld
+{
+
+/** \class ResolveInfoFactory
+ *  \brief ResolveInfoFactory creates ResolveInfos.
+ */
+class ResolveInfoFactory
+{
+public:
+  typedef ResolveInfo           entry_type;
+  typedef ResolveInfo::key_type key_type;
+
+public:
+  entry_type* produce(const key_type& pKey);
+  void destroy(entry_type* pEntry);
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/Resolver.h b/include/mcld/LD/Resolver.h
new file mode 100644
index 0000000..98dfe2c
--- /dev/null
+++ b/include/mcld/LD/Resolver.h
@@ -0,0 +1,100 @@
+//===- Resolver.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SYMBOL_RESOLVER_H
+#define MCLD_SYMBOL_RESOLVER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <string>
+#include <utility>
+
+namespace mcld
+{
+
+class ResolveInfo;
+class StrSymPool;
+
+/** \class Resolver
+ *  \brief Resolver binds a symbol reference from one file to a symbol
+ *   definition of another file.
+ *
+ *  Resolver seals up the algorithm of symbol resolution. The resolution of
+ *  two symbols depends on their type, binding and whether it is belonging to
+ *  a shared object.
+ */
+class Resolver
+{
+public:
+  enum Action {
+    Success,
+    Warning,
+    Abort,
+    LastAction
+  };
+
+  /** \class Resolver::Result
+   *  \brief the result of symbol resolution
+   *   - info, the pointer to overrided info
+   *   - existent, if true, the info is existent
+   *   - overriden, if true, the info is being overriden.
+   */
+  struct Result {
+    ResolveInfo* info;
+    bool existent;
+    bool overriden;
+  };
+
+public:
+  Resolver();
+
+  Resolver(const Resolver& pCopy);
+
+  virtual ~Resolver();
+
+  /// shouldOverride - Can resolver override the symbol pOld by the symbol pNew?
+  /// @return the action should be taken.
+  /// @param pOld the symbol which may be overridden.
+  /// @param pNew the symbol which is used to replace pOld
+  virtual unsigned int resolve(ResolveInfo & __restrict__ pOld,
+                               const ResolveInfo & __restrict__ pNew,
+                               bool &pOverride) = 0;
+
+  /// resolveAgain - Can override by derived classes.
+  /// @return the pointer to resolved ResolveInfo
+  /// @return is the symbol existent?
+  virtual void resolveAgain(StrSymPool& pStrSymPool,
+                              unsigned int pAction,
+                              ResolveInfo& __restrict__ pOld,
+                              const ResolveInfo& __restrict__ pNew,
+                              Result& pResult) {
+    pResult.info = NULL;
+    pResult.existent = false;
+    pResult.overriden = false;
+  }
+
+  const std::string& mesg() const
+  { return m_Mesg; }
+
+  void clearMesg();
+
+  Resolver* clone() const {
+    return doClone();
+  }
+
+protected:
+  std::string m_Mesg;
+
+private:
+  virtual Resolver* doClone() const = 0;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/SectionMap.h b/include/mcld/LD/SectionMap.h
new file mode 100644
index 0000000..424d785
--- /dev/null
+++ b/include/mcld/LD/SectionMap.h
@@ -0,0 +1,105 @@
+//===- SectionMap.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SECTION_MAP_H
+#define MCLD_SECTION_MAP_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/Support/DataTypes.h>
+#include <vector>
+#include <string>
+
+namespace mcld
+{
+
+/** \class SectionMap
+ *  \brief descirbe the mappings of input section's name (or prefix) to
+ *         its associated output section's name and offset
+ */
+class SectionMap
+{
+public:
+  // a mapping in SectionMap is the triple of
+  // {input substr, output section's name, output section's offset}
+  struct Mapping {
+    std::string inputSubStr;
+    std::string outputStr;
+    uint64_t offset;
+  };
+
+  typedef std::vector<struct Mapping> SectionMappingTy;
+
+  typedef SectionMappingTy::iterator iterator;
+  typedef SectionMappingTy::const_iterator const_iterator;
+
+public:
+  SectionMap();
+  ~SectionMap();
+
+  // get the possible output section name based on the mapping table
+  // return NULL if not found
+  const std::string& getOutputSectName(const std::string& pInput);
+
+  // add a mapping from input substr to output name and offset.
+  bool push_back(const std::string& pInput,
+                 const std::string& pOutput,
+                 const uint64_t pOffset = 0);
+
+  // find - return the iterator to the mapping
+  iterator find(const std::string& pInput);
+
+  // at - return the pointer to the mapping
+  Mapping* at(const std::string& pInput);
+
+  // -----  observers  ----- //
+  bool empty() const
+  { return m_SectMap.empty(); }
+
+  size_t size() const
+  { return m_SectMap.size(); }
+
+  size_t capacity () const
+  { return m_SectMap.capacity(); }
+
+  // -----  iterators  ----- //
+  iterator begin()
+  { return m_SectMap.begin(); }
+
+  iterator end()
+  { return m_SectMap.end(); }
+
+  const_iterator begin() const
+  { return m_SectMap.begin(); }
+
+  const_iterator end() const
+  { return m_SectMap.end(); }
+
+  // initStdSectionMap - add common mappings of ELF and other formats
+  // to SectionMap
+  bool initStdSectionMap();
+
+private:
+  struct SectionNameMapping {
+    const char* from;
+    const char* to;
+  };
+
+  // used to store common mappings of ELF and other formants
+  static const SectionNameMapping m_StdSectionMap[];
+
+  static const int m_StdSectionMapSize;
+
+  SectionMappingTy m_SectMap;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/SectionMerger.h b/include/mcld/LD/SectionMerger.h
new file mode 100644
index 0000000..40f1453
--- /dev/null
+++ b/include/mcld/LD/SectionMerger.h
@@ -0,0 +1,98 @@
+//===- SectionMerger.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SECTION_MERGER_H
+#define MCLD_SECTION_MERGER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <vector>
+#include <string>
+#include <llvm/MC/MCAssembler.h>
+#include <mcld/LD/LDSection.h>
+#include <mcld/LD/LDContext.h>
+#include <mcld/LD/SectionMap.h>
+
+namespace mcld
+{
+class MCLinker;
+
+/** \class SectionMerger
+ *  \brief maintain the mappings of substr of input section name to associated
+ *         output section (data)
+ */
+class SectionMerger
+{
+public:
+  struct Mapping {
+    std::string inputSubStr;
+    LDSection* outputSection;
+  };
+  typedef std::vector<Mapping> LDSectionMapTy;
+
+  typedef LDSectionMapTy::iterator iterator;
+  typedef LDSectionMapTy::const_iterator const_iterator;
+
+public:
+  SectionMerger(SectionMap& pSectionMap, LDContext& pContext);
+  ~SectionMerger();
+
+  /// getOutputSectHdr - return a associated output section header
+  LDSection* getOutputSectHdr(const std::string& pName);
+
+  /// getOutputSectData - return a associated output section data
+  llvm::MCSectionData* getOutputSectData(const std::string& pName);
+
+  /// addMapping - add a mapping as creating one new output LDSection
+  /// @param pName - a input section name
+  /// @param pSection - the output LDSection*
+  bool addMapping(const std::string& pName, LDSection* pSection);
+
+  // -----  observers  ----- //
+  bool empty() const
+  { return m_LDSectionMap.empty(); }
+
+  size_t size() const
+  { return m_LDSectionMap.size(); }
+
+  size_t capacity () const
+  { return m_LDSectionMap.capacity(); }
+
+  // -----  iterators  ----- //
+  iterator find(const std::string& pName);
+
+  iterator begin()
+  { return m_LDSectionMap.begin(); }
+
+  iterator end()
+  { return m_LDSectionMap.end(); }
+
+  const_iterator begin() const
+  { return m_LDSectionMap.begin(); }
+
+  const_iterator end() const
+  { return m_LDSectionMap.end(); }
+
+private:
+  /// initOutputSectMap - initialize the map from input substr to associated
+  /// output LDSection*
+  void initOutputSectMap();
+
+private:
+  SectionMap& m_SectionNameMap;
+
+  LDContext& m_Output;
+
+  LDSectionMapTy m_LDSectionMap;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/StaticResolver.h b/include/mcld/LD/StaticResolver.h
new file mode 100644
index 0000000..5bf5c5d
--- /dev/null
+++ b/include/mcld/LD/StaticResolver.h
@@ -0,0 +1,145 @@
+//===- StaticResolver.h ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_STATIC_SYMBOL_RESOLVER_H
+#define MCLD_STATIC_SYMBOL_RESOLVER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <string>
+#include <mcld/LD/Resolver.h>
+#include <mcld/LD/ResolveInfo.h>
+
+namespace mcld
+{
+
+class StrSymPool;
+
+/** \class StaticResolver
+ */
+class StaticResolver : public Resolver
+{
+public:
+  /** \enum LinkAction
+   *  LinkAction follows BFD:linker.c (binary file descriptor).
+   *  List all actions to take in the state table
+   */
+  enum LinkAction
+  {
+    FAIL,         /* abort.  */
+    NOACT,        /* no action.  */
+    UND,          /* override by symbol undefined symbol.  */
+    WEAK,         /* override by symbol weak undefined.  */
+    DEF,          /* override by symbol defined.  */
+    DEFW,         /* override by symbol weak defined.  */
+    DEFD,         /* override by symbol dynamic defined.  */
+    DEFWD,        /* override by symbol dynamic weak defined.  */
+    MDEFD,        /* mark symbol dynamic defined.  */
+    MDEFWD,       /* mark symbol dynamic weak defined.  */
+    DUND,         /* override dynamic defined symbol by undefined one.  */
+    DUNDW,        /* oevrride dynamic defined symbol by weak undefined one.  */
+    COM,          /* override by symbol common.  */
+    CREF,         /* Possibly warn about common reference to defined symbol.  */
+    CDEF,         /* redefine existing common symbol.  */
+    BIG,          /* override by symbol common using largest size.  */
+    MBIG,         /* mark common symbol by larger size.  */
+    IND,          /* override by indirect symbol.  */
+    CIND,         /* mark indirect symbol from existing common symbol.  */
+    MDEF,         /* multiple definition error.  */
+    MIND,         /* multiple indirect symbols.  */
+    REFC          /* Mark indirect symbol referenced and then CYCLE.  */
+  };
+
+private:
+  // These are the values generated by the bit codes.
+  /** Encoding:
+   *  D -> define
+   *  U -> undefine
+   *  d -> dynamic
+   *  w -> weak
+   *  C -> common
+   *  I -> indirect
+   */
+  enum
+  {
+    U    = ResolveInfo::global_flag | ResolveInfo::regular_flag | ResolveInfo::undefine_flag,
+    w_U  = ResolveInfo::weak_flag   | ResolveInfo::regular_flag | ResolveInfo::undefine_flag,
+    d_U  = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::undefine_flag,
+    wd_U = ResolveInfo::weak_flag   | ResolveInfo::dynamic_flag | ResolveInfo::undefine_flag,
+    D    = ResolveInfo::global_flag | ResolveInfo::regular_flag | ResolveInfo::define_flag,
+    w_D  = ResolveInfo::weak_flag   | ResolveInfo::regular_flag | ResolveInfo::define_flag,
+    d_D  = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::define_flag,
+    wd_D = ResolveInfo::weak_flag   | ResolveInfo::dynamic_flag | ResolveInfo::define_flag,
+    C    = ResolveInfo::global_flag | ResolveInfo::regular_flag | ResolveInfo::common_flag, 
+    w_C  = ResolveInfo::weak_flag   | ResolveInfo::regular_flag | ResolveInfo::common_flag,
+    d_C  = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::common_flag,
+    wd_C = ResolveInfo::weak_flag   | ResolveInfo::dynamic_flag | ResolveInfo::common_flag,
+    I    = ResolveInfo::global_flag | ResolveInfo::regular_flag | ResolveInfo::indirect_flag,
+    w_I  = ResolveInfo::weak_flag   | ResolveInfo::regular_flag | ResolveInfo::indirect_flag,
+    d_I  = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::indirect_flag,
+    wd_I = ResolveInfo::weak_flag   | ResolveInfo::dynamic_flag | ResolveInfo::indirect_flag
+  };
+
+  enum ORDINATE
+  {
+    U_ORD,
+    w_U_ORD,
+    d_U_ORD,
+    wd_U_ORD,
+    D_ORD,
+    w_D_ORD,
+    d_D_ORD,
+    wd_D_ORD,
+    C_ORD,
+    w_C_ORD,
+    Cs_ORD,
+    Is_ORD,
+    LAST_ORD
+  };
+
+public:
+  StaticResolver();
+
+  StaticResolver(const StaticResolver& pCopy);
+
+  virtual ~StaticResolver();
+
+  /// shouldOverride - Can resolver override the symbol pOld by the symbol pNew?
+  /// @return the action should be taken.
+  /// @param pOld the symbol which may be overridden.
+  /// @param pNew the symbol which is used to replace pOld
+  virtual unsigned int resolve(ResolveInfo & __restrict__ pOld,
+                               const ResolveInfo & __restrict__ pNew,
+                               bool &pOverride);
+
+  StaticResolver* doClone() const {
+    return new StaticResolver(*this);
+  }
+
+private:
+  inline unsigned int getOrdinate(const ResolveInfo& pInfo) const {
+    if (pInfo.isAbsolute() && pInfo.isDyn())
+      return d_D_ORD;
+    if (pInfo.isAbsolute())
+      return D_ORD;
+    if (pInfo.isCommon() && pInfo.isDyn())
+      return Cs_ORD;
+    if (pInfo.isCommon() && pInfo.isDefine())
+      return C_ORD;
+    if (pInfo.isCommon() && pInfo.isWeak())
+      return w_C_ORD;
+    if (pInfo.isIndirect())
+      return Is_ORD;
+    return pInfo.info();
+  }
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/StrSymPool.h b/include/mcld/LD/StrSymPool.h
new file mode 100644
index 0000000..da5ed1f
--- /dev/null
+++ b/include/mcld/LD/StrSymPool.h
@@ -0,0 +1,111 @@
+//===- StrSymPool.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_STRING_SYMBOL_POOL_H
+#define MCLD_STRING_SYMBOL_POOL_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/ADT/StringRef.h>
+#include <mcld/ADT/HashTable.h>
+#include <mcld/ADT/StringHash.h>
+#include <mcld/ADT/Uncopyable.h>
+#include <mcld/LD/ResolveInfo.h>
+#include <mcld/LD/Resolver.h>
+#include <mcld/LD/ResolveInfoFactory.h>
+#include <utility>
+
+namespace llvm
+{
+  class MCSectionData;
+}
+
+namespace mcld
+{
+
+class Resolver;
+class StringTable;
+class SymbolTableIF;
+
+/** \class StrSymPool
+ *  \brief Store symbol and search symbol by name. Can help symbol resolution.
+ *
+ *  - MCLinker is responsed for creating StrSymPool.
+ */
+class StrSymPool : private Uncopyable
+{
+public:
+  typedef HashTable<ResolveInfo, StringHash<ELF>, ResolveInfoFactory> Table;
+  typedef size_t size_type;
+
+public:
+  StrSymPool(const Resolver& pResolver, size_type pSize = 3);
+  ~StrSymPool();
+
+  // -----  modifiers  ----- //
+  /// createSymbol - create a symbol but do not insert into the pool.
+  ResolveInfo* createSymbol(const llvm::StringRef& pName,
+                            bool pIsDyn,
+                            ResolveInfo::Type pType,
+                            ResolveInfo::Desc pDesc,
+                            ResolveInfo::Binding pBinding,
+                            ResolveInfo::SizeType pSize,
+                            ResolveInfo::Visibility pVisibility = ResolveInfo::Default);
+  
+  /// insertSymbol - insert a symbol and resolve the symbol immediately
+  /// @param pOldInfo - if pOldInfo is not NULL, the old ResolveInfo being
+  ///                   overriden is kept in pOldInfo.
+  /// @param pResult the result of symbol resultion.
+  /// @note pResult.override is true if the output LDSymbol also need to be
+  ///       overriden
+  void insertSymbol(const llvm::StringRef& pName,
+                    bool pIsDyn,
+                    ResolveInfo::Type pType,
+                    ResolveInfo::Desc pDesc,
+                    ResolveInfo::Binding pBinding,
+                    ResolveInfo::SizeType pSize,
+                    ResolveInfo::Visibility pVisibility,
+                    ResolveInfo* pOldInfo,
+                    Resolver::Result& pResult);
+
+  /// findSymbol - find the resolved output LDSymbol
+  LDSymbol* findSymbol(const llvm::StringRef& pName);
+  const LDSymbol* findSymbol(const llvm::StringRef& pName) const;
+
+  /// findInfo - find the resolved ResolveInfo
+  ResolveInfo* findInfo(const llvm::StringRef& pName);
+  const ResolveInfo* findInfo(const llvm::StringRef& pName) const;
+
+  /// insertString - insert a string
+  /// if the string has existed, modify pString to the existing string
+  /// @return the StringRef points to the hash table
+  llvm::StringRef insertString(const llvm::StringRef& pString);
+
+  // -----  observers  ----- //
+  size_type size() const
+  { return m_Table.numOfEntries(); }
+
+  bool empty() const
+  { return m_Table.empty(); }
+
+  // -----  capacity  ----- //
+  void reserve(size_type pN);
+
+  size_type capacity() const;
+
+private:
+  Resolver* m_pResolver;
+  Table m_Table;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/StringUnorderedMap.h b/include/mcld/LD/StringUnorderedMap.h
new file mode 100644
index 0000000..05788aa
--- /dev/null
+++ b/include/mcld/LD/StringUnorderedMap.h
@@ -0,0 +1,225 @@
+//===- StringUnorderedMap.h -----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SEARCH_TABLE_H
+#define MCLD_SEARCH_TABLE_H
+#include <vector>
+// For std::allocate.
+#include <memory>
+// For uint32_t.
+#include <stdint.h>
+#include <cassert>
+// For memset.
+#include <cstring>
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+/* FIXME: Move StringUnorderedMap under ADT. */
+
+namespace mcld
+{
+
+struct StringUnorderedMapDefaultHash
+{
+  size_t operator()(const char *pStr) {
+    size_t hashVal = 31;
+    while (*pStr)
+      hashVal = hashVal * 131 + (*pStr++);
+    return hashVal;
+  }
+};
+
+template<typename ValueType,
+         typename KeyType>
+struct StringUnorderedMapEntryInit
+{
+  template <typename InitType>
+  void operator()(KeyType &pKey, ValueType &pValue,
+                  const KeyType &pStr, InitType pInitVal) {
+    ::new ((void*)&pKey) KeyStorageType(pStr);
+    ::new ((void*)&pValue) ValueType(pInitVal);
+  }
+};
+
+uint32_t findNextPrime(uint32_t x);
+
+/** \class StringUnorderedMap
+ *  \brief The most simple hash of linked list version.
+ *
+ *  \see
+ */
+template<typename KeyType,
+         typename ValueType,
+         typename KeyCompareFunctor,
+         typename HashFunction = StringUnorderedMapDefaultHash,
+         typename Allocator = std::allocator<std::pair<KeyType, ValueType> > >
+class StringUnorderedMap
+{
+public:
+  explicit StringUnorderedMap(size_t pCapacity = 17)
+  : m_Impl(pCapacity)
+  {}
+
+  ~StringUnorderedMap();
+
+  void reserve(size_t pCapacity);
+
+  ValueType &getOrCreate(const KeyType &pStr, const ValueType &pInitVal);
+
+  ValueType &getOrCreate(const KeyType &pStr);
+
+  bool empty()
+  { return m_Size == 0; }
+
+  size_t capacity() const
+  { return m_Capacity; }
+
+  void clear();
+
+private:
+  struct HashEntry {
+    size_t hashVal;
+    std::pair<KeyType, ValueType>
+    HashEntry *next;
+  };
+  typedef Allocator::template rebind<HashEntry>::other HashEntryAllocator;
+  void rehash(size_t pCapacity);
+
+private:
+  size_t m_Capacity;
+  size_t m_Size;
+  // array of pointers to hash entries
+  HashEntry **m_HashTable;
+  HashEntryAllocator m_HashEntryAllocator;
+};
+
+
+// =================================implementation============================
+// StringUnorderedMap::StringUnorderedMapImpl
+template<typename ValueType,
+         typename KeyStorageType,
+         typename HashFunction,
+         typename Allocator>
+StringUnorderedMap<ValueType, KeyStorageType, HashFunction, Allocator>::
+StringUnorderedMapImpl::StringUnorderedMapImpl(size_t pCapacity)
+  : m_Capacity(0), m_Size(0), m_HashTable(0)
+{
+  this->reserve(pCapacity);
+}
+
+template<typename ValueType,
+         typename KeyStorageType,
+         typename HashFunction,
+         typename Allocator>
+void
+StringUnorderedMap<ValueType, KeyStorageType, HashFunction, Allocator>::
+StringUnorderedMapImpl::reserve(size_t pCapacity)
+{
+  if (pCapacity < this->m_Capacity)
+    return;
+  size_t nextSize = findNextPrime(static_cast<uint32_t>(pCapacity));
+  // FIXME: Error handling.
+  assert(nextSize > this->m_Capacity && "findNextPrime error.");
+  if (this->m_Capacity != nextSize)
+    this->rehash(nextSize);
+}
+
+template<typename ValueType,
+         typename KeyStorageType,
+         typename HashFunction,
+         typename Allocator>
+void
+StringUnorderedMap<ValueType, KeyStorageType, HashFunction, Allocator>::
+StringUnorderedMapImpl::rehash(size_t pCapacity)
+{
+  HashEntry **tmpTable = new HashEntry*[pCapacity];
+  std::memset(tmpTable, 0, pCapacity * sizeof(HashEntry*));
+  if (this->m_HashTable) {
+    for (size_t i = 0; i < this->m_Capacity; ++i)
+      for (HashEntry *j = this->m_HashTable[i]; j != 0; ) {
+        HashEntry *nextJ = j->next;
+        j->next = tmpTable[j->hashVal % pCapacity];
+        tmpTable[j->hashVal % pCapacity] = j;
+        j = nextJ;
+      }
+    delete[] m_HashTable;
+  }
+  this->m_Capacity = pCapacity;
+  this->m_HashTable = tmpTable;
+}
+
+template<typename ValueType,
+         typename KeyStorageType,
+         typename HashFunction,
+         typename Allocator>
+template<typename InitType>
+ValueType &
+StringUnorderedMap<ValueType, KeyStorageType, HashFunction, Allocator>::
+StringUnorderedMapImpl::getOrCreate(const KeyType &pStr, ValueType &pInitVal)
+{
+  HashFunction hash;
+  size_t hashVal = hash(pStr);
+  HashEntry *&head =  this->m_HashTable[hashVal % this->m_Capacity];
+
+  HashEntry *ans = 0;
+  for(HashEntry *ptr = head; ptr != 0; ptr = ptr->next)
+    if(hashVal == ptr->hashVal && pStr.equals(ptr->str)) {
+      ans = ptr;
+      break;
+    }
+  if (ans == 0) {
+    ans = this->allocate(1);
+    ans->hashVal = hashVal;
+    StringUnorderedMapEntryInit<ValueType, KeyStorageType> init;
+    init(ans->str, ans->value, pStr, pInitVal);
+    ans->next = head;
+    head = ans;
+    ++m_Size;
+    if(this->m_Size * 4LL >= this->m_Capacity * 3LL) // load factor = 0.75
+      this->reserve(this->m_Capacity+1);
+  }
+
+  return ans->value;
+}
+
+template<typename ValueType,
+         typename KeyStorageType,
+         typename HashFunction,
+         typename Allocator>
+void
+StringUnorderedMap<ValueType, KeyStorageType, HashFunction, Allocator>::
+StringUnorderedMapImpl::clear()
+{
+  if (this->m_HashTable) {
+    for (size_t i = 0; i < this->m_Capacity; ++i)
+      for (HashEntry *j = this->m_HashTable[i]; j != 0; ) {
+        HashEntry *nextJ = j->next;
+        this->destroy(j);
+        this->deallocate(j, 1);
+        j = nextJ;
+      }
+    delete[] m_HashTable;
+  }
+}
+
+
+template<typename ValueType,
+         typename KeyStorageType,
+         typename HashFunction,
+         typename Allocator>
+StringUnorderedMap<ValueType, KeyStorageType, HashFunction, Allocator>::
+StringUnorderedMapImpl::~StringUnorderedMapImpl()
+{
+  this->clear();
+}
+
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/LD/SymbolTableFactory.h b/include/mcld/LD/SymbolTableFactory.h
new file mode 100644
index 0000000..cc02241
--- /dev/null
+++ b/include/mcld/LD/SymbolTableFactory.h
@@ -0,0 +1,73 @@
+//===- SymbolTableFactory.h -----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SYMBOL_TABLE_FACTORY_H
+#define MCLD_SYMBOL_TABLE_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/LD/InputSymbolTable.h"
+#include "mcld/LD/OutputSymbolTable.h"
+
+namespace mcld
+{
+
+class StringTable;
+class StrSymPool;
+
+/** \class SymbolTableFactory
+ *  \brief SymbolTableFactory manages SymbolTableIFs.
+ *
+ *  SymbolTableFactory is responsed for construction and destruction of 
+ *  SymbolTableIF. Since different MCLDFiles have different type of 
+ *  SymbolTableIF, SymbolTableFactory separates the construction of 
+ *  SymbolTableIF into createInputTable() and createOutputTable().
+ *
+ *  @see SymbolTableIF InputSymbolTable OutputSymbolTable
+ */
+class SymbolTableFactory
+{
+public:
+  /// SymbolTableFactory - constructor
+  //  @param pNumOfSymbolTables is the most appropriate number of created 
+  //  symbol tables.
+  //  @param pStorage the real storage of created symbols
+  explicit SymbolTableFactory(size_t pNumOfSymbolTables,
+                              StrSymPool& pStrSymPool);
+  /// ~SymbolTableFactory - destructor
+  //  destructor destroys all created symbol tables.
+  ~SymbolTableFactory();
+
+  /// createInputTable - create a symbol table for an input file
+  //  @param pEntireStringTable the string table of created Symbols.
+  //  @param pDynamicStringTable the string table of created Dynamic Symbols.
+  //  @param pReserve Created symbol table must reserve pReserve number of 
+  //  storages of symbol for creating symbols.
+  SymbolTableIF *createInputTable(StringTable &pEntireStringTable,
+                                  StringTable &pDynamicStringTable,
+                                  size_t pReserve=256);
+
+  /// createOutputTable - create a symbol table for an output file
+  //  @param pEntireStringTable the string table of created Symbols.
+  //  @param pDynamicStringTable the string table of created Dynamic Symbols.
+  //  @param pReserve Created symbol table must reserve pReserve number of 
+  //  storages of symbol for creating symbols.
+  SymbolTableIF *createOutputTable(StringTable &pEntireStringTable,
+                                   StringTable &pDynamicStringTable,
+                                   size_t pReserve=256);
+private:
+  StrSymPool &m_StrSymPool;
+  GCFactory<InputSymbolTable, 0> m_InputFactory;
+  GCFactory<OutputSymbolTable, 0> m_OutputFactory;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/AttributeFactory.h b/include/mcld/MC/AttributeFactory.h
new file mode 100644
index 0000000..eb4368b
--- /dev/null
+++ b/include/mcld/MC/AttributeFactory.h
@@ -0,0 +1,99 @@
+//===- AttributeFactory.h -------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ATTRIBUTE_FACTORY_H
+#define MCLD_ATTRIBUTE_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/ADT/Uncopyable.h"
+#include "mcld/MC/MCLDAttribute.h"
+
+namespace mcld
+{
+
+/** \class AttributeFactory
+ *  \brief AttributeFactory contructs the AttributeProxys.
+ *
+ *  Since the number of AttributeProxys is usually small, sequential search
+ *  on a small vector is enough.
+ */
+class AttributeFactory : private Uncopyable
+{
+private:
+  typedef std::vector<Attribute*> AttrSet;
+
+public:
+  typedef AttrSet::iterator iterator;
+  typedef AttrSet::const_iterator const_iterator;
+
+public:
+  AttributeFactory();
+  explicit AttributeFactory(size_t pNum);
+  ~AttributeFactory();
+
+  // reserve - reserve the memory space for attributes
+  // @param pNum the number of reserved attributes
+  void reserve(size_t pNum);
+
+  // predefined - return the predefined attribute
+  Attribute& predefined();
+  const Attribute& predefined() const;
+  
+  // constraint - return the constraint of attributes
+  AttrConstraint& constraint()
+  { return m_Constraint; }
+
+  const AttrConstraint& constraint() const
+  { return m_Constraint; }
+
+  // produce - produce a attribute, but do not record it yet.
+  // the produced attribute is identical to the pre-defined attribute.
+  AttributeProxy* produce();
+
+  // last - the last touched attribute.
+  AttributeProxy& last();
+  const AttributeProxy& last() const;
+
+  // exists- return the recorded attribute whose content is identical to the
+  // input attribute.
+  Attribute *exists(const Attribute& pAttr) const;
+
+  // record - record the attribute no mater if it has been recorded.
+  void record(Attribute& pAttr);
+
+  // -----  observers  ----- //
+  size_t size() const
+  { return m_AttrSet.size(); }
+
+  bool empty() const
+  { return m_AttrSet.empty(); }
+
+  // -----  iterators  ----- //
+  iterator begin()
+  { return m_AttrSet.begin(); }
+
+  iterator end()
+  { return m_AttrSet.end(); }
+
+  const_iterator begin() const
+  { return m_AttrSet.begin(); }
+
+  const_iterator end() const
+  { return m_AttrSet.end(); }
+
+private:
+  AttrSet m_AttrSet;
+  AttrConstraint m_Constraint;
+  AttributeProxy *m_pLast;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/ContextFactory.h b/include/mcld/MC/ContextFactory.h
new file mode 100644
index 0000000..1ae0d45
--- /dev/null
+++ b/include/mcld/MC/ContextFactory.h
@@ -0,0 +1,47 @@
+//===- ContextFactory.h ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_CONTEXT_FACTORY_H
+#define MCLD_CONTEXT_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/LD/LDContext.h>
+#include <mcld/Support/UniqueGCFactory.h>
+#include <mcld/Support/Path.h>
+
+namespace mcld
+{
+/** \class ContextFactory
+ *  \brief ContextFactory avoids the duplicated LDContext of the same file.
+ *
+ *  MCLinker is designed for efficient memory usage. Because user can give
+ *  MCLinker the same input file many times on the command line, MCLinker must
+ *  avoid opening identical file twice.
+ *
+ *  ContextFactory is the guard to prevent redundant opening. MCLinker does not
+ *  create LDContext directly. Instead, it creates LDContext by ContextFactory.
+ *  ContextFactory returns the identical reference of LDContext if it's openend.
+ *
+ *  @see LDContext
+ *  @see UniqueGCFactoryBase
+ */
+class ContextFactory : public UniqueGCFactoryBase<sys::fs::Path, LDContext, 0>
+{
+public:
+  explicit ContextFactory(size_t pNum);
+  ~ContextFactory();
+
+  LDContext* produce(const sys::fs::Path& pPath);
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/InputFactory.h b/include/mcld/MC/InputFactory.h
new file mode 100644
index 0000000..5dc99c4
--- /dev/null
+++ b/include/mcld/MC/InputFactory.h
@@ -0,0 +1,56 @@
+//===- InputFactory.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_INPUT_FACTORY_H
+#define MCLD_INPUT_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/Support/GCFactory.h"
+#include "mcld/MC/MCLDInput.h"
+
+namespace mcld
+{
+
+class AttributeFactory;
+
+/** \class InputFactory
+ *  \brief InputFactory controls the production and destruction of
+ *  MCLDInput.
+ *
+ *  All MCLDFiles created by MCLDFileFactory are guaranteed to be destructed
+ *  while MCLDFileFactory is destructed.
+ *
+ *  FIXME: the number of the Inputs should be passed in by Target or any
+ *  target specific class.
+ *
+ *  \see llvm::sys::Path
+ */
+class InputFactory : public GCFactory<Input,0>
+{
+public:
+  typedef GCFactory<Input, 0> Alloc;
+
+public:
+  InputFactory(size_t pNum, AttributeFactory& pAttrFactory);
+  ~InputFactory();
+
+  // -----  production  ----- //
+  Input* produce(llvm::StringRef pName,
+                 const sys::fs::Path& pPath,
+                 unsigned int pType = Input::Unknown,
+                 off_t pFileOffset = 0);
+
+private:
+  AttributeFactory &m_AttrFactory;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCBitcodeInterceptor.h b/include/mcld/MC/MCBitcodeInterceptor.h
new file mode 100644
index 0000000..182b157
--- /dev/null
+++ b/include/mcld/MC/MCBitcodeInterceptor.h
@@ -0,0 +1,75 @@
+//===- MCBitcodeInterceptor.h ---------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_BITCODE_INTERCEPTOR_H
+#define MCLD_BITCODE_INTERCEPTOR_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/MC/MCObjectWriter.h>
+
+
+namespace llvm
+{
+  class MCStreamer;
+  class MCObjectStreamer;
+  class MCAsmLayout;
+  class MCAssembler;
+  class MCFixup;
+  class MCFragment;
+  class MCSymbol;
+  class MCSymbolData;
+  class MCSymbolRefExpr;
+  class MCValue;
+  class raw_ostream;
+} // namespace of llvm
+
+namespace mcld
+{
+
+class MCLDInfo;
+class TargetLDBackend;
+
+/** \class MCBitcodeInterceptor
+ *  \brief MCBitcodeInterceptor converts bitcode into LDContext
+ *
+ *  @see LDContext
+ *  @see MCObjectWriter
+ */
+class MCBitcodeInterceptor : public llvm::MCObjectWriter
+{
+public:
+  MCBitcodeInterceptor(llvm::MCObjectStreamer&, TargetLDBackend&, MCLDInfo&);
+  ~MCBitcodeInterceptor();
+
+  void ExecutePostLayoutBinding(llvm::MCAssembler &Asm,
+                                const llvm::MCAsmLayout &Layout);
+
+  /// RecordRelocation - record relocations
+  //  make a LDRelocation and recordds in the LDContext.
+  void RecordRelocation(const llvm::MCAssembler &Asm,
+                        const llvm::MCAsmLayout &Layout,
+                        const llvm::MCFragment *Fragment,
+                        const llvm::MCFixup &Fixup,
+                        llvm::MCValue Target,
+                        uint64_t &FixedValue);
+
+  /// WriteObject - not really write out a object. Instead, load data to
+  /// LDContext
+  void WriteObject(llvm::MCAssembler &Asm, const llvm::MCAsmLayout &Layout);
+
+private:
+  TargetLDBackend& m_Backend;
+  MCLDInfo& m_LDInfo;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCDataFragment.h b/include/mcld/MC/MCDataFragment.h
new file mode 100644
index 0000000..330c9be
--- /dev/null
+++ b/include/mcld/MC/MCDataFragment.h
@@ -0,0 +1,85 @@
+//===- MCDataFragment.h ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCDATAFRAGMENT_H
+#define MCDATAFRAGMENT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/MC/MCAssembler.h>
+#include <llvm/MC/MCInst.h>
+#include <llvm/ADT/SmallString.h>
+#include "mcld/LD/Relocation.h"
+
+namespace mcld
+{
+
+/** \class MCDataFragment
+ *  \brief MCDataFragment for mcld
+ *
+ *  \see
+ *  \author Diana Chen <[email protected]>
+ */
+class MCDataFragment : public  llvm::MCFragment
+{
+public:
+   typedef std::vector<Relocation*> RelocationsType;
+private:
+
+  ///  m_pFragment - llvm MCDataFragment for this MCDataFragment
+  llvm::MCDataFragment* m_pFragment;
+ 
+  /// m_Relocation - The list of relocations in this fragment
+  RelocationsType m_Relocations;
+
+public:
+  typedef RelocationsType::const_iterator const_relocation_iterator;
+  typedef RelocationsType::iterator relocation_iterator;
+
+public:
+  MCDataFragment(llvm::MCDataFragment& pFragment)
+    : m_pFragment(&pFragment) {
+    setParent( pFragment.getParent() );
+    setAtom( pFragment.getAtom() );
+    setLayoutOrder( pFragment.getLayoutOrder());
+  }
+  ~MCDataFragment(){}
+   
+  // ------ observers ------//
+  llvm::SmallString<32> &getContents() { return m_pFragment->getContents();  }
+  const llvm::SmallString<32> &getContents() const { return m_pFragment->getContents();  }
+
+  // relocation access
+  void addRelocation(Relocation &pReloc){  m_Relocations.push_back(&pReloc); }
+  
+  RelocationsType &getRelocations() { return m_Relocations; }
+  const RelocationsType &getRelcoations() const { return m_Relocations; }
+
+  relocation_iterator relocation_begin() { return m_Relocations.begin(); }
+  const_relocation_iterator relocation_begin() const { return m_Relocations.begin(); }
+
+  relocation_iterator relocation_end() {return m_Relocations.end();}
+  const_relocation_iterator relocation_end() const {return m_Relocations.end();}
+
+  size_t relocations_size() const { return m_Relocations.size(); }
+
+  // fragment identification
+  static bool classof(const MCFragment *pF) {
+    return pF->getKind() == llvm::MCFragment::FT_Data;
+  }
+  static bool classof(const MCDataFragment *) { return true; }
+  
+  // overwrite parent method
+  FragmentType getKind() const { return m_pFragment->getKind(); } 
+  
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCFragmentRef.h b/include/mcld/MC/MCFragmentRef.h
new file mode 100644
index 0000000..b7d94cd
--- /dev/null
+++ b/include/mcld/MC/MCFragmentRef.h
@@ -0,0 +1,85 @@
+//===- MCFragmentRef.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_MCFRAGMENT_REFERENCE_H
+#define MCLD_MCFRAGMENT_REFERENCE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/MC/MCAssembler.h>
+#include <mcld/ADT/SizeTraits.h>
+#include <mcld/ADT/TypeTraits.h>
+
+namespace mcld
+{
+
+class Layout;
+
+/// compunteFragmentSize - compute the specific MCFragment size
+uint64_t computeFragmentSize(const Layout& pLayout,
+                             const llvm::MCFragment& pFrag);
+
+/** \class MCFragmentRef
+ *  \brief MCFragmentRef is a reference of a MCFragment's contetnt.
+ *
+ */
+class MCFragmentRef
+{
+public:
+  typedef uint64_t Offset; // FIXME: use SizeTraits<T>::Offset
+  typedef NonConstTraits<unsigned char>::pointer Address;
+  typedef ConstTraits<unsigned char>::pointer ConstAddress;
+
+public:
+  MCFragmentRef();
+  MCFragmentRef(llvm::MCFragment& pFrag, Offset pOffset = 0);
+  ~MCFragmentRef();
+
+  // -----  modifiers  ----- //
+  MCFragmentRef& assign(const MCFragmentRef& pCopy);
+
+  MCFragmentRef& assign(llvm::MCFragment& pFrag, Offset pOffset = 0);
+
+  /// memcpy - copy memory
+  /// copy memory from the fragment to the pDesc.
+  /// @pDest - the destination address
+  /// @pNBytes - copies pNBytes from the fragment[offset()+pOffset]
+  /// @pOffset - additional offset. 
+  ///            the start address offset from fragment[offset()]
+  void memcpy(void* pDest, size_t pNBytes, Offset pOffset = 0) const;
+
+  // -----  observers  ----- //
+  llvm::MCFragment* frag()
+  { return m_pFragment; }
+
+  const llvm::MCFragment* frag() const
+  { return m_pFragment; }
+
+  Offset offset() const
+  { return m_Offset; }
+
+  // -----  dereference  ----- //
+  Address deref();
+
+  ConstAddress deref() const;
+
+  Address operator*()
+  { return deref(); }
+
+  ConstAddress operator*() const
+  { return deref(); }
+  
+private:
+  llvm::MCFragment* m_pFragment;
+  Offset m_Offset;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCInstFragment.h b/include/mcld/MC/MCInstFragment.h
new file mode 100644
index 0000000..8625c42
--- /dev/null
+++ b/include/mcld/MC/MCInstFragment.h
@@ -0,0 +1,95 @@
+//===- MCInstFragment.h ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCINSTFRAGMENT_H
+#define MCINSTFRAGMENT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/MC/MCAssembler.h>
+#include <llvm/MC/MCInst.h>
+#include <llvm/ADT/SmallString.h>
+#include <llvm/ADT/ilist.h>
+#include "mcld/LD/Relocation.h"
+
+
+namespace mcld
+{
+
+/** \class MCInstFragment
+ *  \brief MCInstFragment for mcld
+ *
+ *  \see
+ *  \author Diana Chen <[email protected]>
+ */
+class MCInstFragment : public  llvm::MCFragment
+{
+public:
+  typedef std::vector<Relocation*> RelocationsType;
+private:
+
+  ///  m_pFragment - llvm MCInstFragment for this MCInstFragment
+  llvm::MCInstFragment* m_pFragment;
+  
+  /// m_Relocation - The list of relocations in this fragment
+  RelocationsType m_Relocations;
+  
+public:
+  typedef RelocationsType::const_iterator const_relocation_iterator;
+  typedef RelocationsType::iterator relocation_iterator;
+
+public:
+  MCInstFragment( llvm::MCInstFragment& pFragment )
+      : m_pFragment(&pFragment){
+    setParent( pFragment.getParent() );
+    setAtom( pFragment.getAtom() );
+    setLayoutOrder( pFragment.getLayoutOrder());
+  }
+  ~MCInstFragment(){}
+   
+  // ------ observers ------//
+  llvm::SmallVectorImpl<char> &getCode() { return m_pFragment->getCode(); }
+  const llvm::SmallVectorImpl<char> &getCode() const { return m_pFragment->getCode(); }
+
+  unsigned getInstSize() const { return m_pFragment->getCode().size(); }
+
+  llvm::MCInst &getInst() { return m_pFragment->getInst(); }
+  const llvm::MCInst &getInst() const { return m_pFragment->getInst(); }
+  
+  // ----- modifiers ------//
+  void setInst(llvm::MCInst pValue) { m_pFragment->setInst(pValue); }
+
+  // relocation access
+  void addRelocation(Relocation &pReloc){  m_Relocations.push_back(&pReloc); }
+  
+  RelocationsType &getRelocations() { return m_Relocations; }
+  const RelocationsType &getRelcoations() const { return m_Relocations; }
+
+  relocation_iterator relocation_begin() { return m_Relocations.begin(); }
+  const_relocation_iterator relocation_begin() const { return m_Relocations.begin(); }
+
+  relocation_iterator relocation_end() {return m_Relocations.end();}
+  const_relocation_iterator relocation_end() const {return m_Relocations.end();}
+
+  size_t relocations_size() const { return m_Relocations.size(); }
+
+  // fragment identification
+  static bool classof(const MCFragment *pF) {
+    return pF->getKind() == llvm::MCFragment::FT_Inst;
+  }
+  static bool classof(const MCInstFragment *) { return true; }
+  
+  // overwrite parent method
+  FragmentType getKind() const { return m_pFragment->getKind(); } 
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCLDAttribute.h b/include/mcld/MC/MCLDAttribute.h
new file mode 100644
index 0000000..829cf61
--- /dev/null
+++ b/include/mcld/MC/MCLDAttribute.h
@@ -0,0 +1,247 @@
+//===- MCLDAttribute.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ATTRIBUTE_H
+#define MCLD_ATTRIBUTE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <vector>
+#include <string>
+
+namespace mcld
+{
+class AttributeFactory;
+
+/** \class AttributeBase
+ *  \brief AttributeBase provides the real storage for attributes of options.
+ *
+ *  Attributes are options affecting the link editing of input files.
+ *  Some options affects the input files mentioned on the command line after
+ *  them. For example, --whole-archive option affects archives mentioned on
+ *  the command line after the --whole-archve option. We call such options
+ *  "attributes of input files"
+ *
+ *  AttributeBase is the storage for attributes of input files. Each input
+ *  file (@see mcld::Input in MCLinker) has a pointer of an attribute. Since
+ *  most attributes of input files are identical, our design lets input files
+ *  which have identical attributes share common attribute. AttributeBase is
+ *  the shared storage for attribute.
+ */
+class AttributeBase
+{
+public:
+  AttributeBase()
+  : m_WholeArchive(false),
+    m_AsNeeded(false),
+    m_AddNeeded(true),
+    m_Static(false)
+  { }
+
+  AttributeBase(const AttributeBase& pBase)
+  : m_WholeArchive(pBase.m_WholeArchive),
+    m_AsNeeded(pBase.m_AsNeeded),
+    m_AddNeeded(pBase.m_AddNeeded),
+    m_Static(pBase.m_Static)
+  { }
+
+  virtual ~AttributeBase()
+  { }
+
+  // ----- observers  ----- //
+  // represent GNU ld --whole-archive/--no-whole-archive options
+  bool isWholeArchive() const
+  { return m_WholeArchive; }
+
+  // represent GNU ld --as-needed/--no-as-needed options
+  bool isAsNeeded() const
+  { return m_AsNeeded; }
+
+  // represent GNU ld --add-needed/--no-add-needed options
+  bool isAddNeeded() const
+  { return m_AddNeeded; }
+
+  // represent GNU ld -static option
+  bool isStatic() const
+  { return m_Static; }
+
+  // represent GNU ld -call_shared option
+  bool isDynamic() const
+  { return !m_Static; }
+public:
+  bool m_WholeArchive : 1;
+  bool m_AsNeeded : 1;
+  bool m_AddNeeded : 1;
+  bool m_Static : 1;
+};
+
+/** \class Attribute
+ *  \brief The base class of attributes. Providing the raw operations of an
+ *  attributes
+ *
+ *  For conventience and producing less bugs, we move the stoarges of attributes
+ *  onto AttributeBase, and modifiers remains with the class Attribute.
+ */
+class Attribute : public AttributeBase
+{
+public:
+  // -----  modifiers  ----- //
+  void setWholeArchive()
+  { m_WholeArchive = true; }
+
+  void unsetWholeArchive()
+  { m_WholeArchive = false; }
+
+  void setAsNeeded()
+  { m_AsNeeded = true; }
+
+  void unsetAsNeeded()
+  { m_AsNeeded = false; }
+
+  void setAddNeeded()
+  { m_AddNeeded = true; }
+
+  void unsetAddNeeded()
+  { m_AddNeeded = false; }
+
+  void setStatic()
+  { m_Static = true; }
+
+  void setDynamic()
+  { m_Static = false; }
+};
+
+/** \class AttrConstraint
+ *  \brief AttrConstarint is the constraint of a system.
+ *
+ *  Some systems can not enable certain attributes of a input file.
+ *  For example, systems which have no shared libraries can not enable
+ *  --call_shared options. We call the ability of enabling attributes
+ *  as the constraint of attributes of a system.
+ *
+ *  Systems enable attributes at the target implementation of SectLinker.
+ *
+ *  @see SectLinker
+ */
+class AttrConstraint : public AttributeBase
+{
+public:
+  void enableWholeArchive()
+  { m_WholeArchive = true; }
+
+  void disableWholeArchive()
+  { m_WholeArchive = false; }
+
+  void enableAsNeeded()
+  { m_AsNeeded = true; }
+
+  void disableAsNeeded()
+  { m_AsNeeded = false; }
+
+  void enableAddNeeded()
+  { m_AddNeeded = true; }
+
+  void disableAddNeeded()
+  { m_AddNeeded = false; }
+
+  void setSharedSystem()
+  { m_Static = false; }
+
+  void setStaticSystem()
+  { m_Static = true; }
+
+  bool isSharedSystem() const
+  { return !m_Static; }
+
+  bool isStaticSystem() const
+  { return m_Static; }
+  
+  bool isLegal(const Attribute& pAttr, std::string& pErrMesg) const;
+};
+
+/** \class AttributeProxy
+ *  \brief AttributeProxys is the illusion of private attribute of each
+ *  input file.
+ *
+ *  We designers want to hide the details of sharing common attributes
+ *  between input files. We want input files under the illusion that they
+ *  have their own private attributes to simplify the linking algorithms.
+ *
+ *  AttributeProxy hides the reality of sharing. An input file can change
+ *  its attribute without explicit searching of existing attributes
+ *  as it has a private ownership of the attribute. AttributeProxy does
+ *  the searching in the AttributeFactory and changes the pointer of
+ *  the attribute of the input file. If the searching fails, AttributeProxy
+ *  requests a new attribute from the AttributeFactory.
+ */
+class AttributeProxy
+{
+private:
+  friend class AttributeFactory;
+
+  explicit AttributeProxy(AttributeFactory& pParent, Attribute& pBase);
+  ~AttributeProxy();
+
+public:
+  // ----- observers  ----- //
+  bool isWholeArchive() const;
+
+  bool isAsNeeded() const;
+
+  bool isAddNeeded() const;
+
+  bool isStatic() const;
+
+  bool isDynamic() const;
+
+  Attribute* attr()
+  { return m_pBase; }
+
+  const Attribute* attr() const
+  { return m_pBase; }
+
+  // -----  modifiers  ----- //
+  void setWholeArchive();
+  void unsetWholeArchive();
+  void setAsNeeded();
+  void unsetAsNeeded();
+  void setAddNeeded();
+  void unsetAddNeeded();
+  void setStatic();
+  void setDynamic();
+
+private:
+  AttributeProxy* clone() const;
+
+  void change(Attribute* pBase)
+  { m_pBase = pBase; }
+
+private:
+  AttributeFactory &m_AttrPool;
+  Attribute *m_pBase;
+};
+
+
+// -----  comparisons  ----- //
+inline bool operator== (const Attribute& pLHS, const Attribute& pRHS)
+{
+  return ((pLHS.isWholeArchive() == pRHS.isWholeArchive()) &&
+    (pLHS.isAsNeeded() == pRHS.isAsNeeded()) && 
+    (pLHS.isAddNeeded() == pRHS.isAddNeeded()) && 
+    (pLHS.isStatic() == pRHS.isStatic()));
+}
+
+inline bool operator!= (const Attribute& pLHS, const Attribute& pRHS)
+{
+  return !(pLHS == pRHS);
+}
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCLDDirectory.h b/include/mcld/MC/MCLDDirectory.h
new file mode 100644
index 0000000..988f9d3
--- /dev/null
+++ b/include/mcld/MC/MCLDDirectory.h
@@ -0,0 +1,53 @@
+//===- MCLDDirectory.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_MCLDDIRECTORY_H
+#define MCLD_MCLDDIRECTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/Support/Directory.h"
+#include "mcld/Support/FileSystem.h"
+#include <llvm/ADT/StringRef.h>
+#include <string>
+
+namespace mcld
+{
+
+/** \class MCLDDirectory
+ *  \brief MCLDDirectory is an directory entry for library search.
+ *
+ */
+class MCLDDirectory : public sys::fs::Directory
+{
+public:
+  MCLDDirectory();
+  MCLDDirectory(const char* pName);
+  MCLDDirectory(const std::string& pName);
+  MCLDDirectory(llvm::StringRef pName);
+  virtual ~MCLDDirectory();
+
+public:
+  MCLDDirectory &assign(llvm::StringRef pName);
+  bool isInSysroot() const;
+
+  /// setSysroot - if MCLDDirectory is in sysroot, modify the path.
+  void setSysroot(const sys::fs::Path& pPath);
+
+  const std::string& name() const
+  { return m_Name; }
+
+private:
+  std::string m_Name;
+  bool m_bInSysroot;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCLDDriver.h b/include/mcld/MC/MCLDDriver.h
new file mode 100644
index 0000000..b4a7288
--- /dev/null
+++ b/include/mcld/MC/MCLDDriver.h
@@ -0,0 +1,117 @@
+//===- MCLDDriver.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// MCLDDriver plays the same role as GNU collect2 to prepare all implicit
+// parameters for MCLinker.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_LDDRIVER_H
+#define MCLD_LDDRIVER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/LD/SectionMap.h>
+namespace mcld
+{
+
+class MCLinker;
+class MCLDInfo;
+class TargetLDBackend;
+
+//===----------------------------------------------------------------------===//
+/// MCLDDriver - MCLDDriver prepares parameters for MCLinker.
+///
+class MCLDDriver
+{
+public:
+  MCLDDriver(MCLDInfo& pLDInfo, TargetLDBackend& pLDBackend);
+  ~MCLDDriver();
+
+  /// normalize - normalize the input files
+  void normalize();
+
+  /// linkable - check the linkability of current MCLDInfo
+  ///  Check list:
+  ///  - check the Attributes are not violate the constaint
+  ///  - check every Input has a correct Attribute
+  bool linkable() const;
+
+  /// initMCLinker - initialize MCLinker
+  ///  Connect all components in MCLinker
+  bool initMCLinker();
+
+  /// readSections - read all input section headers
+  bool readSections();
+
+  /// mergeSections - put allinput sections into output sections
+  bool mergeSections();
+
+  /// readSymbolTables - read symbol tables from the input files.
+  ///  for each input file, loads its symbol table from file.
+  bool readSymbolTables();
+
+  /// mergeSymbolTables - merge the symbol tables of input files into the
+  /// output's symbol table.
+  bool mergeSymbolTables();
+
+  /// 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();
+
+  /// readRelocations - read all relocation entries
+  bool readRelocations();
+
+  /// 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 relocate();
+
+  /// finalizeSymbolValue - finalize the symbol value
+  bool finalizeSymbolValue();
+
+  /// emitOutput - emit the output file.
+  bool emitOutput();
+
+  /// postProcessing - do modificatiion after all processes
+  bool postProcessing();
+
+private:
+  MCLDInfo& m_LDInfo;
+  TargetLDBackend &m_LDBackend;
+  MCLinker* m_pLinker;
+  SectionMap m_SectionMap;
+};
+
+} // end namespace mcld
+#endif
diff --git a/include/mcld/MC/MCLDFile.h b/include/mcld/MC/MCLDFile.h
new file mode 100644
index 0000000..30cac7e
--- /dev/null
+++ b/include/mcld/MC/MCLDFile.h
@@ -0,0 +1,173 @@
+//===- MCLDFile.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// MCLDFile represents a file, the content of the file is stored in LDContext.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_LDFILE_H
+#define MCLD_LDFILE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/ADT/Uncopyable.h"
+#include "mcld/LD/LDContext.h"
+#include "mcld/Support/Path.h"
+#include "mcld/Support/FileSystem.h"
+#include "mcld/Support/GCFactory.h"
+#include "mcld/Support/MemoryArea.h"
+#include <llvm/ADT/StringRef.h>
+#include <string>
+#include <sys/stat.h>
+
+
+namespace mcld
+{
+class MemoryArea;
+
+/** \class MCLDFile
+ *  \brief MCLDFile represents the file being linked or produced.
+ *
+ *  MCLDFile is the storage of name, path and type
+ *  A MCLDFile just refers to LDContext, not owns it.
+ *
+ *  @see mcld::sys::fs::Path LDContext
+ */
+class MCLDFile : private Uncopyable
+{
+public:
+  enum Type {
+    Unknown,
+    Object,
+    Exec,
+    DynObj,
+    CoreFile,
+    Script,
+    Archive
+  };
+
+public:
+  MCLDFile();
+  MCLDFile(llvm::StringRef pName);
+  MCLDFile(llvm::StringRef pName,
+           const sys::fs::Path& pPath,
+           unsigned int pType = Unknown);
+
+  virtual ~MCLDFile();
+
+  // -----  modifiers  ----- //
+  void setType(unsigned int pType)
+  { m_Type = pType; }
+
+  void setContext(LDContext* pContext)
+  { m_pContext = pContext; }
+
+  void setPath(const sys::fs::Path& pPath)
+  { m_Path = pPath; }
+
+  void setMemArea(MemoryArea* pMemArea)
+  {
+    m_pMemArea = pMemArea;
+  }
+
+  /// setSOName - set the name of the shared object.
+  /// In ELF, this will be written in DT_SONAME
+  void setSOName(const std::string& pName);
+
+  // -----  observers  ----- //
+  unsigned int type() const
+  { return m_Type; }
+
+  const std::string& name() const
+  { return m_Name; }
+
+  const sys::fs::Path& path() const
+  { return m_Path; }
+
+  bool hasContext() const
+  { return (0 != m_pContext); }
+
+  LDContext* context()
+  { return m_pContext; }
+
+  const LDContext* context() const
+  { return m_pContext; }
+
+  bool hasMemArea() const
+  { return (0 != m_pMemArea); }
+
+  MemoryArea* memArea()
+  { return m_pMemArea; }
+
+  const MemoryArea* memArea() const
+  { return m_pMemArea; }
+
+protected:
+  unsigned int m_Type;
+  LDContext *m_pContext;
+  sys::fs::Path m_Path;
+  std::string m_Name;
+  MemoryArea* m_pMemArea;
+};
+
+/** \class MCLDFileFactory
+ *  \brief MCLDFileFactory controls the production and destruction of
+ *  MCLDFiles.
+ *
+ *  All MCLDFiles created by MCLDFileFactory are guaranteed to be destructed
+ *  while MCLDFileFactory is destructed.
+ *
+ *  MCLDFileFactory also provides the MCLCContextFactory to MCLDFile.
+ *  MCLDFile is responsed for the life of LDContext, therefore, the best
+ *  idea is let MCLDFile control the life of LDContext. Since SectLinker
+ *  has the need to count the number of LDContext, we give a central factory
+ *  for LDContext.
+ *
+ *  \see llvm::sys::Path
+ */
+template<size_t NUM>
+class MCLDFileFactory : public GCFactory<MCLDFile, NUM>
+{
+public:
+  typedef GCFactory<MCLDFile, NUM> Alloc;
+
+public:
+  // -----  production  ----- //
+  MCLDFile* produce(llvm::StringRef pName,
+                    const sys::fs::Path& pPath,
+                    unsigned int pType = MCLDFile::Unknown);
+
+  MCLDFile* produce();
+};
+
+} // namespace of mcld
+
+//===----------------------------------------------------------------------===//
+// MCLDFileFactory
+template<size_t NUM>
+mcld::MCLDFile* mcld::MCLDFileFactory<NUM>::produce(llvm::StringRef pName,
+                                   const mcld::sys::fs::Path& pPath,
+                                   unsigned int pType)
+{
+    mcld::MCLDFile* result = Alloc::allocate();
+    new (result) mcld::MCLDFile(pName, pPath, pType);
+    return result;
+}
+
+template<size_t NUM>
+mcld::MCLDFile* mcld::MCLDFileFactory<NUM>::produce()
+{
+    mcld::MCLDFile* result = Alloc::allocate();
+    new (result) mcld::MCLDFile();
+    return result;
+}
+
+#endif
+
diff --git a/include/mcld/MC/MCLDInfo.h b/include/mcld/MC/MCLDInfo.h
new file mode 100644
index 0000000..15e70ff
--- /dev/null
+++ b/include/mcld/MC/MCLDInfo.h
@@ -0,0 +1,138 @@
+//===- MCLDInfo.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_LDINFO_H
+#define MCLD_LDINFO_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/ADT/Triple.h>
+
+#include <mcld/Support/FileSystem.h>
+#include <mcld/Support/MemoryAreaFactory.h>
+#include <mcld/MC/MCLDOutput.h>
+#include <mcld/MC/MCLDOptions.h>
+#include <mcld/MC/MCLDInputTree.h>
+#include <mcld/MC/AttributeFactory.h>
+#include <mcld/MC/ContextFactory.h>
+#include <mcld/LD/StrSymPool.h>
+
+#include <string>
+#include <cassert>
+
+namespace mcld
+{
+
+/** \class MCLDInfo
+ *  \brief MCLDInfo is composed of argumments of MCLinker.
+ *   options()        - the general options.
+ *   inputs()         - the tree of inputs
+ *   bitcode()        - the bitcode being linked
+ *   output()         - the output file
+ *   inputFactory()   - the list of all inputs
+ *   attrFactory()    - the list of all attributes
+ *   contextFactory() - the list of all contexts.
+ *   memAreaFactory() - the list of all MemoryAreas.
+ */
+class MCLDInfo
+{
+public:
+  explicit MCLDInfo(const std::string &pTripleString,
+                    size_t pAttrNum,
+                    size_t InputSize);
+
+  virtual ~MCLDInfo();
+
+  GeneralOptions& options()
+  { return m_Options; }
+
+  const GeneralOptions& options() const
+  { return m_Options; }
+
+  void setBitcode(const Input& pInput);
+  Input& bitcode();
+  const Input& bitcode() const;
+
+  Output& output()
+  { return *m_pOutput; }
+
+  const Output& output() const
+  { return *m_pOutput; }
+
+  InputTree& inputs()
+  { return *m_pInputTree; }
+
+  const InputTree& inputs() const
+  { return *m_pInputTree; }
+
+  InputFactory& inputFactory()
+  { return *m_pInputFactory; }
+
+  const InputFactory& inputFactory() const
+  { return *m_pInputFactory; }
+
+  AttributeFactory& attrFactory()
+  { return *m_pAttrFactory; }
+
+
+  const AttributeFactory& attrFactory() const
+  { return *m_pAttrFactory; }
+
+  ContextFactory& contextFactory()
+  { return *m_pCntxtFactory; }
+
+  const ContextFactory& contextFactory() const
+  { return *m_pCntxtFactory; }
+
+  MemoryAreaFactory& memAreaFactory()
+  { return *m_pMemAreaFactory; }
+
+  const MemoryAreaFactory& memAreaFactory() const
+  { return *m_pMemAreaFactory; }
+
+  const llvm::Triple& triple() const
+  { return m_Triple; }
+
+  static const char* version();
+
+  void setNamePool(StrSymPool& pPool)
+  { m_pStrSymPool = &pPool; }
+
+  StrSymPool& getStrSymPool() {
+    assert(NULL != m_pStrSymPool);
+    return *m_pStrSymPool;
+  }
+
+  const StrSymPool& getStrSymPool() const {
+    assert(NULL != m_pStrSymPool);
+    return *m_pStrSymPool;
+  }
+
+private:
+  // -----  General Options  ----- //
+  GeneralOptions m_Options;
+  InputTree *m_pInputTree;
+  Input* m_pBitcode;
+  Output* m_pOutput;
+  llvm::Triple m_Triple;
+
+  // -----  factories  ----- //
+  InputFactory *m_pInputFactory;
+  AttributeFactory *m_pAttrFactory;
+  ContextFactory *m_pCntxtFactory;
+  MemoryAreaFactory *m_pMemAreaFactory;
+
+  // -----  string and symbols  ----- //
+  StrSymPool* m_pStrSymPool;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCLDInput.h b/include/mcld/MC/MCLDInput.h
new file mode 100644
index 0000000..097b8f6
--- /dev/null
+++ b/include/mcld/MC/MCLDInput.h
@@ -0,0 +1,86 @@
+//===- MCLDInput.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Input class inherits MCLDFile, which is used to represent a input file
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_INPUT_H
+#define MCLD_INPUT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/MC/MCLDFile.h"
+
+namespace mcld
+{
+
+class AttributeProxy;
+class Attribute;
+class InputFactory;
+
+/** \class Input
+ *  \brief Input provides the information of a input file.
+ *
+ *  @see MCLDFile
+ */
+class Input : public MCLDFile
+{
+friend class InputFactory;
+public:
+  enum Type {
+    Unknown = MCLDFile::Unknown,
+    Object = MCLDFile::Object,
+    DynObj = MCLDFile::DynObj,
+    Archive = MCLDFile::Archive,
+    Script = MCLDFile::Script
+  };
+
+private:
+  explicit Input(llvm::StringRef pName,
+                 const AttributeProxy& pAttr);
+
+  Input(llvm::StringRef pName,
+        const sys::fs::Path& pPath,
+        const AttributeProxy& pAttr,
+        unsigned int pType = Unknown,
+        off_t pFileOffset = 0);
+
+public:
+  ~Input();
+
+  bool isRecognized() const
+  { return (m_Type != Unknown); }
+
+  const Attribute* attribute() const
+  { return m_pAttr; }
+
+  bool isNeeded() const
+  { return m_bNeeded; }
+
+  void setNeeded()
+  { m_bNeeded = true; }
+
+  off_t fileOffset() const
+  { return m_fileOffset; }
+
+  void setFileOffset(off_t pFileOffset)
+  { m_fileOffset = pFileOffset; }
+
+private:
+  Attribute *m_pAttr;
+  bool m_bNeeded;
+  off_t m_fileOffset;
+};
+
+} // namespace of mcld
+ 
+#endif
+
diff --git a/include/mcld/MC/MCLDInputTree.h b/include/mcld/MC/MCLDInputTree.h
new file mode 100644
index 0000000..7d8050c
--- /dev/null
+++ b/include/mcld/MC/MCLDInputTree.h
@@ -0,0 +1,237 @@
+//===- MCLDInputTree.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_INPUT_TREE_H
+#define MCLD_INPUT_TREE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/ADT/BinTree.h"
+#include "mcld/ADT/TypeTraits.h"
+#include "mcld/MC/MCLDInput.h"
+#include "mcld/MC/InputFactory.h"
+#include "mcld/Support/FileSystem.h"
+
+#include <string>
+
+
+namespace mcld
+{
+
+/** \class template<typename Traits, typename Iterator> PolicyIterator<mcld::Input>
+ *  \brief PolicyIterator<mcld::Input> is a partially specific PolicyIterator
+ */
+template<typename Traits, typename IteratorType>
+class PolicyIterator<mcld::Input, Traits, IteratorType> : public PolicyIteratorBase<Input, Traits, IteratorType>
+{
+public:
+  typedef PolicyIterator<Input, Traits, IteratorType> Self;
+  typedef PolicyIteratorBase<Input, Traits, IteratorType> Base;
+  typedef PolicyIterator<Input, typename Traits::nonconst_traits, IteratorType> iterator;
+  typedef PolicyIterator<Input, typename Traits::const_traits, IteratorType>    const_iterator;
+
+public:
+  PolicyIterator()
+    : Base() {}
+
+  PolicyIterator(const iterator &X)
+    : Base(X.m_pNode) {}
+
+  explicit PolicyIterator(NodeBase* X)
+    : Base(X) {}
+
+  virtual ~PolicyIterator() {}
+
+  bool isGroup() const
+  { return !Base::hasData(); }
+
+  Self& operator++() {
+    IteratorType::advance();
+    if (isGroup())
+      IteratorType::advance();
+    return *this;
+  }
+
+  Self operator++(int) {
+    Self tmp(*this);
+    IteratorType::advance();
+    if (isGroup())
+      IteratorType::advance();
+    return tmp;
+  }
+};
+
+/** \class InputTree
+ *  \brief InputTree is the input tree to contains all inputs from the
+ *  command line.
+ *
+ *  InputTree, of course, is uncopyable.
+ *
+ *  @see Input
+ */
+class InputTree : public BinaryTree<Input>
+{
+private:
+  typedef BinaryTree<Input> BinTreeTy;
+
+public:
+  enum Direction {
+    Inclusive  = TreeIteratorBase::Leftward,
+    Positional = TreeIteratorBase::Rightward
+  };
+
+  typedef BinaryTree<Input>::iterator       iterator;
+  typedef BinaryTree<Input>::const_iterator const_iterator;
+
+public:
+  struct Connector {
+    virtual ~Connector() {}
+    virtual void connect(iterator& pFrom, const const_iterator& pTo) const = 0;
+    virtual void move(iterator& pNode) const = 0;
+  };
+
+  struct Succeeder : public Connector {
+    virtual void connect(iterator& pFrom, const const_iterator& pTo) const {
+      proxy::hook<Positional>(pFrom.m_pNode, pTo.m_pNode);
+    }
+
+    virtual void move(iterator& pNode) const {
+      pNode.move<Positional>();
+    }
+  };
+
+  struct Includer : public Connector {
+    virtual void connect(iterator& pFrom, const const_iterator& pTo) const {
+      proxy::hook<Inclusive>(pFrom.m_pNode, pTo.m_pNode);
+    }
+
+    virtual void move(iterator& pNode) const {
+      pNode.move<Inclusive>();
+    }
+  };
+
+public:
+  static Succeeder Afterward;
+  static Includer  Downward;
+
+public:
+
+  using BinTreeTy::merge;
+
+  InputTree(InputFactory& pInputFactory);
+  ~InputTree();
+
+  // -----  modify  ----- //
+  /// insert - create a leaf node and merge it in the tree.
+  //  This version of join determines the direction at run time.
+  //  @param position the parent node
+  //  @param value the value being pushed.
+  //  @param pConnector the direction of the connecting edge of the parent node.
+  template<size_t DIRECT>
+  InputTree& insert(iterator pPosition,
+                    const std::string& pNamespec,
+                    const sys::fs::Path& pPath,
+                    unsigned int pType = Input::Unknown);
+
+  template<size_t DIRECT>
+  InputTree& enterGroup(iterator pPosition);
+
+  template<size_t DIRECT>
+  InputTree& insert(iterator pPosition,
+                    const Input& pInput);
+
+  InputTree& merge(iterator pPosition, 
+                   const Connector& pConnector,
+                   InputTree& pTree);
+
+  InputTree& insert(iterator pPosition,
+                    const Connector& pConnector,
+                    const std::string& pNamespec,
+                    const sys::fs::Path& pPath,
+                    unsigned int pType = Input::Unknown);
+
+  InputTree& insert(iterator pPosition,
+                    const Connector& pConnector,
+                    const Input& pInput);
+
+  InputTree& enterGroup(iterator pPosition,
+                        const Connector& pConnector);
+
+  // -----  observers  ----- //
+  unsigned int numOfInputs() const
+  { return m_FileFactory.size(); }
+
+  bool hasInput() const
+  { return !m_FileFactory.empty(); }
+
+private:
+  InputFactory& m_FileFactory;
+
+};
+
+bool isGroup(const InputTree::iterator& pos);
+bool isGroup(const InputTree::const_iterator& pos);
+bool isGroup(const InputTree::dfs_iterator& pos);
+bool isGroup(const InputTree::const_dfs_iterator& pos);
+bool isGroup(const InputTree::bfs_iterator& pos);
+bool isGroup(const InputTree::const_bfs_iterator& pos);
+
+} // namespace of mcld
+
+//===----------------------------------------------------------------------===//
+// template member functions
+template<size_t DIRECT>
+mcld::InputTree&
+mcld::InputTree::insert(mcld::InputTree::iterator pPosition,
+                        const std::string& pNamespec,
+                        const mcld::sys::fs::Path& pPath,
+                        unsigned int pType)
+{
+  BinTreeTy::node_type* node = createNode();
+  node->data = m_FileFactory.produce(pNamespec, pPath, pType); 
+  if (pPosition.isRoot())
+    proxy::hook<TreeIteratorBase::Leftward>(pPosition.m_pNode,
+        const_cast<const node_type*>(node));
+  else
+    proxy::hook<DIRECT>(pPosition.m_pNode,
+        const_cast<const node_type*>(node));
+  return *this;
+}
+
+template<size_t DIRECT>
+mcld::InputTree&
+mcld::InputTree::enterGroup(mcld::InputTree::iterator pPosition)
+{
+  BinTreeTy::node_type* node = createNode(); 
+  if (pPosition.isRoot())
+    proxy::hook<TreeIteratorBase::Leftward>(pPosition.m_pNode,
+        const_cast<const node_type*>(node));
+  else
+    proxy::hook<DIRECT>(pPosition.m_pNode,
+        const_cast<const node_type*>(node));
+  return *this;
+}
+
+template<size_t DIRECT>
+mcld::InputTree& mcld::InputTree::insert(mcld::InputTree::iterator pPosition,
+	                                 const mcld::Input& pInput)
+{
+  BinTreeTy::node_type* node = createNode();
+  node->data = const_cast<mcld::Input*>(&pInput);
+  if (pPosition.isRoot())
+    proxy::hook<TreeIteratorBase::Leftward>(pPosition.m_pNode,
+                                         const_cast<const node_type*>(node));
+  else
+    proxy::hook<DIRECT>(pPosition.m_pNode,
+                        const_cast<const node_type*>(node));
+  return *this;
+}
+
+#endif
+
diff --git a/include/mcld/MC/MCLDOptions.h b/include/mcld/MC/MCLDOptions.h
new file mode 100644
index 0000000..06097aa
--- /dev/null
+++ b/include/mcld/MC/MCLDOptions.h
@@ -0,0 +1,98 @@
+//===- MCLDOptions.h ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_OPTIONS_H
+#define MCLD_OPTIONS_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/Support/RealPath.h"
+#include "mcld/MC/SearchDirs.h"
+#include "mcld/Support/FileSystem.h"
+
+namespace mcld
+{
+class Input;
+
+/** \class ScriptOptions
+ *
+ */
+class ScriptOption
+{
+};
+
+/** \class GeneralOptions
+ *  \brief GeneralOptions collects the options that not be one of the
+ *     - input files
+ *     - attribute of input files
+ *     - script options
+ */
+class GeneralOptions
+{
+public:
+  /// default link script
+  bool hasDefaultLDScript() const;
+  const char* defaultLDScript() const;
+  void setDefaultLDScript(const std::string& pFilename);
+
+  /// sysroot
+  const sys::fs::Path& sysroot() const
+  { return m_Sysroot; }
+
+  void setSysroot(const sys::fs::Path &pPath);
+
+  /// search directory
+  SearchDirs& directories()
+  { return m_SearchDirs; }
+
+  const SearchDirs& directories() const
+  { return m_SearchDirs; }
+
+  /// trace
+  void setTrace(bool pEnableTrace = true)
+  { m_bTrace = pEnableTrace; }
+
+  bool trace() const
+  { return m_bTrace; }
+
+  void setVerbose(bool pVerbose = true)
+  { m_bVerbose = pVerbose; }
+
+  bool verbose() const
+  { return m_bVerbose; }
+
+  void setBsymbolic(bool pBsymbolic = false)
+  { m_Bsymbolic = pBsymbolic; }
+
+  bool Bsymbolic() const
+  { return m_Bsymbolic; }
+
+  bool hasEntry() const
+  { return !m_Entry.empty(); }
+
+  void setEntry(const std::string& pEntry)
+  { m_Entry = pEntry; }
+
+  const std::string& entry() const
+  { return m_Entry; }
+
+private:
+  Input* m_pDefaultBitcode;
+  std::string m_DefaultLDScript;
+  sys::fs::RealPath m_Sysroot;
+  SearchDirs m_SearchDirs;
+  bool m_bTrace;
+  bool m_bVerbose;
+  bool m_Bsymbolic;
+  std::string m_Entry;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCLDOutput.h b/include/mcld/MC/MCLDOutput.h
new file mode 100644
index 0000000..14768ce
--- /dev/null
+++ b/include/mcld/MC/MCLDOutput.h
@@ -0,0 +1,52 @@
+//===- MCLDOutput.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Output class inherits MCLDFile, which is used to represent a output file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_OUTPUT_H
+#define MCLD_OUTPUT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/MC/MCLDFile.h>
+#include <mcld/Support/RealPath.h>
+#include <string>
+
+namespace mcld
+{
+
+/** \class MCLDOutput
+ *  \brief MCLDOutput provides the information about the output.
+ *
+ *  @see MCLDFile
+ */
+class Output : public MCLDFile
+{
+public:
+  enum Type {
+    Object = MCLDFile::Object,
+    DynObj = MCLDFile::DynObj,
+    Exec   = MCLDFile::Exec
+  };
+
+public:
+  Output();
+  explicit Output(const sys::fs::Path& pRealPath,
+                  Type pType);
+
+  ~Output();
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCLinker.h b/include/mcld/MC/MCLinker.h
new file mode 100644
index 0000000..8de7148
--- /dev/null
+++ b/include/mcld/MC/MCLinker.h
@@ -0,0 +1,279 @@
+//===- MCLinker.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a number of APIs used by SectLinker.
+// These APIs do the things which a linker should do.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_MCLINKER_H
+#define MCLD_MCLINKER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/ADT/ilist.h>
+#include <llvm/MC/MCAssembler.h>
+#include <mcld/LD/StrSymPool.h>
+#include <mcld/LD/StaticResolver.h>
+#include <mcld/LD/LDSectionFactory.h>
+#include <mcld/LD/LDFileFormat.h>
+#include <mcld/LD/LDContext.h>
+#include <mcld/LD/Relocation.h>
+#include <mcld/LD/SectionMerger.h>
+#include <mcld/LD/Layout.h>
+#include <mcld/MC/MCLDInput.h>
+#include <mcld/MC/SymbolCategory.h>
+#include <mcld/Support/GCFactory.h>
+#include <mcld/Support/GCFactoryListTraits.h>
+#include <set>
+#include <string>
+
+namespace mcld {
+
+class TargetLDBackend;
+class MCLDInfo;
+class LDSection;
+class LDSectionFactory;
+class SectionMap;
+class Output;
+
+/** \class MCLinker
+ *  \brief MCLinker provides a pass to link object files.
+ */
+class MCLinker
+{
+public:
+  enum DefinePolicy
+  {
+    Force,
+    AsRefered
+  };
+
+  enum ResolvePolicy
+  {
+    Unresolve,
+    Resolve
+  };
+
+public:
+  MCLinker(TargetLDBackend& pBackend,
+           MCLDInfo& pLDInfo,
+           LDContext& pContext,
+           SectionMap& pSectionMap,
+           const Resolver& pResolver = StaticResolver());
+  ~MCLinker();
+
+  // ----- about symbols  ----- //
+  /// addDynSymbol - add a symbol and resolve it immediately
+  template<Input::Type FROM>
+  LDSymbol* addSymbol(const llvm::StringRef& pName,
+                      ResolveInfo::Type pType,
+                      ResolveInfo::Desc pDesc,
+                      ResolveInfo::Binding pBinding,
+                      ResolveInfo::SizeType pSize,
+                      LDSymbol::ValueType pValue,
+                      MCFragmentRef* pFragmentRef,
+                      ResolveInfo::Visibility pVisibility = ResolveInfo::Default);
+
+  /// defineSymbol - add a symbol
+  /// defineSymbol define a output symbol
+  ///
+  /// @tparam POLICY idicate how to define the symbol.
+  ///   - Force
+  ///     - Define the symbol forcefully. If the symbol has existed, override
+  ///       it. Otherwise, define it.
+  ///   - AsRefered
+  ///     - If the symbol has existed, override it. Otherwise, return NULL
+  ///       immediately.
+  ///
+  /// @tparam RESOLVE indicate whether to resolve the symbol or not.
+  ///   - Unresolve
+  ///      - Do not resolve the symbol, and override the symbol immediately.
+  ///   - Resolve
+  ///      - Resolve the defined symbol.
+  ///
+  /// @return If the output symbol has existed, return it. Otherwise, create
+  ///         a new symbol and return the new one.
+  template<DefinePolicy POLICY, ResolvePolicy RESOLVE>
+  LDSymbol* defineSymbol(const llvm::StringRef& pName,
+                         bool pIsDyn,
+                         ResolveInfo::Type pType,
+                         ResolveInfo::Desc pDesc,
+                         ResolveInfo::Binding pBinding,
+                         ResolveInfo::SizeType pSize,
+                         LDSymbol::ValueType pValue,
+                         MCFragmentRef* pFragmentRef,
+                         ResolveInfo::Visibility pVisibility = ResolveInfo::Default);
+
+  /// mergeSymbolTable - merge the symbol table and resolve symbols.
+  ///   Since in current design, MCLinker resolves symbols when reading symbol
+  ///   tables, this function do nothing.
+  bool mergeSymbolTable(Input& pInput)
+  { return true; }
+
+  bool finalizeSymbols();
+
+  // -----  sections  ----- //
+  /// getSectionMap - getSectionMap to change the behavior of SectionMerger
+  /// SectionMap& getSectionMap()
+  /// { return m_SectionMap; }
+
+  /// createSectHdr - for reader and standard/target format to create a section
+  /// header. This function will create a new LDSection and return it. If the
+  /// output has no related LDSection, this function will also create one and
+  /// push into the output.
+  LDSection& createSectHdr(const std::string& pName,
+                           LDFileFormat::Kind pKind,
+                           uint32_t pType,
+                           uint32_t pFlag);
+
+  /// getOrCreateOutputSectHdr - for reader and standard/target format to get
+  /// or create the output's section header
+  LDSection& getOrCreateOutputSectHdr(const std::string& pName,
+                                      LDFileFormat::Kind pKind,
+                                      uint32_t pType,
+                                      uint32_t pFlag,
+                                      uint32_t pAlign = 0x0);
+
+  /// getOrCreateSectData - for reader to map and perform section merging immediately
+  llvm::MCSectionData& getOrCreateSectData(LDSection& pSection);
+
+  // -----  relocations ----- //
+  /// addRelocation - add a relocation entry in MCLinker (only for object file)
+  /// @param pType - the type of the relocation
+  /// @param pResolveInfo - the symbol should be the symbol in the input file. MCLinker
+  ///                  computes the real applied address by the output symbol.
+  /// @param pFragmentRef - the fragment reference of the applied address.
+  /// @param pAddend - the addend value for applying relocation
+  Relocation* addRelocation(Relocation::Type pType,
+                            const LDSymbol& pSym,
+                            ResolveInfo& pResolveInfo,
+                            MCFragmentRef& pFragmentRef,
+                            Relocation::Address pAddend = 0);
+
+  /// applyRelocations - apply all relocation enties.
+  bool applyRelocations();
+
+  /// syncRelocationResult - After applying relocation, write back relocation target
+  /// data to output file.
+  void syncRelocationResult();
+
+  // -----  layout  ----- //
+  Layout& getLayout()
+  { return m_Layout; }
+
+  const Layout& getLayout() const
+  { return m_Layout; }
+
+  bool layout();
+
+  // -----  output symbols  ----- //
+  SymbolCategory& getOutputSymbols()
+  { return m_OutputSymbols; }
+
+  const SymbolCategory& getOutputSymbols() const
+  { return m_OutputSymbols; }
+
+  // -----  capacity  ----- //
+  MCLDInfo& getLDInfo()
+  { return m_Info; }
+
+  const MCLDInfo& getLDInfo() const
+  { return m_Info; }
+
+private:
+  LDSymbol* defineSymbolForcefully(const llvm::StringRef& pName,
+                                   bool pIsDyn,
+                                   ResolveInfo::Type pType,
+                                   ResolveInfo::Desc pDesc,
+                                   ResolveInfo::Binding pBinding,
+                                   ResolveInfo::SizeType pSize,
+                                   LDSymbol::ValueType pValue,
+                                   MCFragmentRef* pFragmentRef,
+                                   ResolveInfo::Visibility pVisibility);
+
+  LDSymbol* defineAndResolveSymbolForcefully(const llvm::StringRef& pName,
+                                             bool pIsDyn,
+                                             ResolveInfo::Type pType,
+                                             ResolveInfo::Desc pDesc,
+                                             ResolveInfo::Binding pBinding,
+                                             ResolveInfo::SizeType pSize,
+                                             LDSymbol::ValueType pValue,
+                                             MCFragmentRef* pFragmentRef,
+                                             ResolveInfo::Visibility pVisibility);
+
+  LDSymbol* defineSymbolAsRefered(const llvm::StringRef& pName,
+                                  bool pIsDyn,
+                                  ResolveInfo::Type pType,
+                                  ResolveInfo::Desc pDesc,
+                                  ResolveInfo::Binding pBinding,
+                                  ResolveInfo::SizeType pSize,
+                                  LDSymbol::ValueType pValue,
+                                  MCFragmentRef* pFragmentRef,
+                                  ResolveInfo::Visibility pVisibility);
+
+  LDSymbol* defineAndResolveSymbolAsRefered(const llvm::StringRef& pName,
+                                            bool pIsDyn,
+                                            ResolveInfo::Type pType,
+                                            ResolveInfo::Desc pDesc,
+                                            ResolveInfo::Binding pBinding,
+                                            ResolveInfo::SizeType pSize,
+                                            LDSymbol::ValueType pValue,
+                                            MCFragmentRef* pFragmentRef,
+                                            ResolveInfo::Visibility pVisibility);
+
+  bool shouldForceLocal(const ResolveInfo& pInfo) const;
+
+  LDSymbol* addSymbolFromDynObj(const llvm::StringRef& pName,
+                                ResolveInfo::Type pType,
+                                ResolveInfo::Desc pDesc,
+                                ResolveInfo::Binding pBinding,
+                                ResolveInfo::SizeType pSize,
+                                LDSymbol::ValueType pValue,
+                                MCFragmentRef* pFragmentRef,
+                                ResolveInfo::Visibility pVisibility);
+
+  LDSymbol* addSymbolFromObject(const llvm::StringRef& pName,
+                                ResolveInfo::Type pType,
+                                ResolveInfo::Desc pDesc,
+                                ResolveInfo::Binding pBinding,
+                                ResolveInfo::SizeType pSize,
+                                LDSymbol::ValueType pValue,
+                                MCFragmentRef* pFragmentRef,
+                                ResolveInfo::Visibility pVisibility);
+private:
+  typedef GCFactory<LDSymbol, 0> LDSymbolFactory;
+  typedef GCFactory<llvm::MCSectionData, 0> LDSectionDataFactory;
+  typedef llvm::iplist<llvm::MCFragment,
+                       GCFactoryListTraits<llvm::MCFragment> > RelocationListType;
+  typedef std::set<LDSymbol*> ForceLocalSymbolTable;
+  typedef std::vector<LDSymbol*> OutputSymbolTable;
+
+private:
+  TargetLDBackend& m_Backend;
+  MCLDInfo& m_Info;
+  LDContext& m_Output;
+  SectionMap& m_SectionMap;
+  LDSymbolFactory m_LDSymbolFactory;
+  LDSectionFactory m_LDSectHdrFactory;
+  LDSectionDataFactory m_LDSectDataFactory;
+  SectionMerger m_SectionMerger;
+  StrSymPool m_StrSymPool;
+  Layout m_Layout;
+  RelocationListType m_RelocationList;
+  SymbolCategory m_OutputSymbols;
+
+};
+
+#include "MCLinker.tcc"
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCLinker.tcc b/include/mcld/MC/MCLinker.tcc
new file mode 100644
index 0000000..19a83ec
--- /dev/null
+++ b/include/mcld/MC/MCLinker.tcc
@@ -0,0 +1,105 @@
+//===- MCLinker.tcc -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+/// addSymbol - add a symbol and resolve it immediately
+template<Input::Type FROM>
+LDSymbol* MCLinker::addSymbol(const llvm::StringRef& pName,
+                              ResolveInfo::Type pType,
+                              ResolveInfo::Desc pDesc,
+                              ResolveInfo::Binding pBinding,
+                              ResolveInfo::SizeType pSize,
+                              LDSymbol::ValueType pValue,
+                              MCFragmentRef* pFragmentRef,
+                              ResolveInfo::Visibility pVisibility)
+{
+  // These if/else should be optimized by compiler.
+  // This function is defined for clarity.
+  if (FROM == Input::DynObj)
+    return addSymbolFromDynObj(pName,
+                               pType,
+                               pDesc,
+                               pBinding,
+                               pSize,
+                               pValue,
+                               pFragmentRef,
+                               pVisibility);
+
+  if (FROM == Input::Object)
+    return addSymbolFromObject(pName,
+                               pType,
+                               pDesc,
+                               pBinding,
+                               pSize,
+                               pValue,
+                               pFragmentRef,
+                               pVisibility);
+
+  llvm::report_fatal_error("add a symbol from unknown file type.\n");
+  return NULL;
+}
+
+// defineSymbol - define a new symbol
+template<MCLinker::DefinePolicy POLICY, MCLinker::ResolvePolicy RESOLVE>
+LDSymbol* MCLinker::defineSymbol(const llvm::StringRef& pName,
+                                 bool pIsDyn,
+                                 ResolveInfo::Type pType,
+                                 ResolveInfo::Desc pDesc,
+                                 ResolveInfo::Binding pBinding,
+                                 ResolveInfo::SizeType pSize,
+                                 LDSymbol::ValueType pValue,
+                                 MCFragmentRef* pFragmentRef,
+                                 ResolveInfo::Visibility pVisibility)
+{
+  // These if/return should be optimized by compiler.
+  // This function is defined for clarity.
+  if (MCLinker::Force == POLICY && MCLinker::Unresolve == RESOLVE)
+    return defineSymbolForcefully(pName,
+                                  pIsDyn,
+                                  pType,
+                                  pDesc,
+                                  pBinding,
+                                  pSize,
+                                  pValue,
+                                  pFragmentRef,
+                                  pVisibility);
+
+  if (MCLinker::AsRefered == POLICY && MCLinker::Unresolve == RESOLVE)
+    return defineSymbolAsRefered(pName,
+                                 pIsDyn,
+                                 pType,
+                                 pDesc,
+                                 pBinding,
+                                 pSize,
+                                 pValue,
+                                 pFragmentRef,
+                                 pVisibility);
+
+  if (MCLinker::Force == POLICY && MCLinker::Resolve == RESOLVE)
+    return defineAndResolveSymbolForcefully(pName,
+                                            pIsDyn,
+                                            pType,
+                                            pDesc,
+                                            pBinding,
+                                            pSize,
+                                            pValue,
+                                            pFragmentRef,
+                                            pVisibility);
+
+  if (MCLinker::AsRefered == POLICY && MCLinker::Resolve == RESOLVE)
+    return defineAndResolveSymbolAsRefered(pName,
+                                           pIsDyn,
+                                           pType,
+                                           pDesc,
+                                           pBinding,
+                                           pSize,
+                                           pValue,
+                                           pFragmentRef,
+                                           pVisibility);
+}
+
diff --git a/include/mcld/MC/MCRegionFragment.h b/include/mcld/MC/MCRegionFragment.h
new file mode 100644
index 0000000..7dd088b
--- /dev/null
+++ b/include/mcld/MC/MCRegionFragment.h
@@ -0,0 +1,53 @@
+//===- MCRegionFragment.h - MCFragment containing MemoryRegion ------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_REGION_FRAGMENT_H
+#define MCLD_REGION_FRAGMENT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/Support/MemoryRegion.h>
+#include <llvm/MC/MCAssembler.h>
+
+namespace mcld
+{
+
+/** \class MCRegionFragment
+ *  \brief MCRegionFragment is a kind of MCFragment containing 
+ *  mcld::MemoryRegion
+ */
+class MCRegionFragment : public llvm::MCFragment
+{
+public:
+  MCRegionFragment(MemoryRegion& pRegion, llvm::MCSectionData* pSD = 0);
+  ~MCRegionFragment();
+
+  MemoryRegion& getRegion()
+  { return m_Region; }
+
+  const MemoryRegion& getRegion() const
+  { return m_Region; }
+
+  static bool classof(const MCFragment *F)
+  { return F->getKind() == llvm::MCFragment::FT_Region; }
+
+  static bool classof(const MCRegionFragment *)
+  { return true; }
+
+private:
+  MemoryRegion& m_Region;
+  llvm::MCSectionData* m_pSectionData;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/MCTargetFragment.h b/include/mcld/MC/MCTargetFragment.h
new file mode 100644
index 0000000..4050708
--- /dev/null
+++ b/include/mcld/MC/MCTargetFragment.h
@@ -0,0 +1,48 @@
+//===- MCTargetFragment.h - MCFragment containing MemoryRegion ------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_TARGET_FRAGMENT_H
+#define MCLD_TARGET_FRAGMENT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/MC/MCAssembler.h>
+
+namespace mcld
+{
+
+/** \class MCTargetFragment
+ *  \brief MCTargetFragment is a kind of MCFragment inherited by
+ *  target-depedent MCFragment.
+ */
+class MCTargetFragment : public llvm::MCFragment
+{
+protected:
+  MCTargetFragment(llvm::MCFragment::FragmentType pKind,
+                   llvm::MCSectionData* pSD = 0) :
+                   llvm::MCFragment(pKind, pSD) {}
+
+public:
+  virtual ~MCTargetFragment() {}
+
+  virtual size_t getSize() const = 0;
+
+public:
+  static bool classof(const MCFragment *F)
+  { return F->getKind() == llvm::MCFragment::FT_Target; }
+
+  static bool classof(const MCTargetFragment *)
+  { return true; }
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/SearchDirs.h b/include/mcld/MC/SearchDirs.h
new file mode 100644
index 0000000..1a22cf4
--- /dev/null
+++ b/include/mcld/MC/SearchDirs.h
@@ -0,0 +1,76 @@
+//===- SearchDirs.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef SEARCHDIRS_H
+#define SEARCHDIRS_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/ADT/StringRef.h>
+#include "mcld/ADT/Uncopyable.h"
+#include "mcld/MC/MCLDInput.h"
+
+namespace mcld
+{
+
+class MCLDFile;
+class MCLDDirectory;
+
+namespace sys {
+namespace fs {
+class Path;
+} // namespace of fs
+} // namespace of sys
+
+/** \class SearchDirs
+ *  \brief SearchDirs contains the list of paths that MCLinker will search for
+ *  archive libraries and control scripts.
+ *
+ *  SearchDirs is customized for linking. It handles -L on the command line
+ *  and SEARCH_DIR macro in the link script.
+ *
+ *  @see MCLDDirectory.
+ */
+class SearchDirs : private Uncopyable
+{
+public:
+  typedef std::vector<MCLDDirectory*> DirList;
+  typedef DirList::iterator iterator;
+  typedef DirList::const_iterator const_iterator;
+
+public:
+  SearchDirs();
+  ~SearchDirs();
+
+  /// find - give a namespec, return a real path of the shared object.
+  sys::fs::Path* find(const std::string& pNamespec, mcld::Input::Type pType);
+
+  // -----  iterators  ----- //
+  iterator begin()
+  { return m_DirList.begin(); }
+
+  iterator end()
+  { return m_DirList.end(); }
+
+  const_iterator begin() const
+  { return m_DirList.begin(); }
+
+  const_iterator end() const
+  { return m_DirList.end(); }
+
+  // -----  modifiers  ----- //
+  void add(const MCLDDirectory& pDirectory);
+
+private:
+  DirList m_DirList;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/MC/SymbolCategory.h b/include/mcld/MC/SymbolCategory.h
new file mode 100644
index 0000000..9432c2a
--- /dev/null
+++ b/include/mcld/MC/SymbolCategory.h
@@ -0,0 +1,158 @@
+//===- SymbolCategory.h ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_SYMBOL_CATEGORY_H
+#define MCLD_SYMBOL_CATEGORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/ADT/TypeTraits.h>
+#include <vector>
+
+namespace mcld
+{
+
+class LDSymbol;
+class ResolveInfo;
+/** \class SymbolCategory
+ *  \brief SymbolCategory groups output LDSymbol into different categories.
+ */
+class SymbolCategory
+{
+private:
+  typedef std::vector<LDSymbol*> OutputSymbols;
+
+public:
+  typedef OutputSymbols::iterator iterator;
+  typedef OutputSymbols::const_iterator const_iterator;
+
+public:
+  SymbolCategory();
+
+  ~SymbolCategory();
+
+  // -----  modifiers  ----- //
+  SymbolCategory& add(LDSymbol& pSymbol);
+
+  SymbolCategory& forceLocal(LDSymbol& pSymbol);
+
+  SymbolCategory& arrange(LDSymbol& pSymbol, const ResolveInfo& pSourceInfo);
+
+  SymbolCategory& changeCommonsToGlobal();
+
+  // -----  access  ----- //
+  LDSymbol& at(size_t pPosition)
+  { return *m_OutputSymbols.at(pPosition); }
+
+  const LDSymbol& at(size_t pPosition) const
+  { return *m_OutputSymbols.at(pPosition); }
+
+  LDSymbol& operator[](size_t pPosition)
+  { return *m_OutputSymbols[pPosition]; }
+
+  const LDSymbol& operator[](size_t pPosition) const
+  { return *m_OutputSymbols[pPosition]; }
+
+  // -----  observers  ----- //
+  size_t numOfSymbols() const;
+
+  size_t numOfLocals() const;
+
+  size_t numOfCommons() const;
+
+  size_t numOfRegulars() const;
+
+  bool empty() const;
+
+  bool emptyLocals() const;
+  
+  bool emptyCommons() const;
+
+  bool emptyRegulars() const;
+
+  // -----  iterators  ----- //
+  iterator begin();
+  iterator end();
+  const_iterator begin() const;
+  const_iterator end() const;
+
+  iterator localBegin();
+  iterator localEnd();
+  const_iterator localBegin() const;
+  const_iterator localEnd() const;
+
+  iterator commonBegin();
+  iterator commonEnd();
+  const_iterator commonBegin() const;
+  const_iterator commonEnd() const;
+
+  iterator regularBegin();
+  iterator regularEnd();
+  const_iterator regularBegin() const;
+  const_iterator regularEnd() const;
+
+private:
+  class Category
+  {
+  public:
+    enum Type {
+      File,
+      Local,
+      Common,
+      Weak,
+      Global
+    };
+
+  public:
+    Type type;
+
+    size_t begin;
+    size_t end;
+
+    Category* prev;
+    Category* next;
+
+  public:
+    Category(Type pType)
+      : type(pType),
+        begin(0),
+        end(0),
+        prev(NULL),
+        next(NULL) {
+    }
+
+    size_t size() const
+    { return (end - begin); }
+
+    bool empty() const
+    { return (begin == end); }
+
+    bool isFirst() const
+    { return (NULL == prev); }
+
+    bool isLast() const
+    { return (NULL == next); }
+
+    static Type categorize(const ResolveInfo& pInfo);
+
+  };
+
+private:
+  OutputSymbols m_OutputSymbols;
+
+  Category* m_pFile;
+  Category* m_pLocal;
+  Category* m_pCommon;
+  Category* m_pWeak;
+  Category* m_pGlobal;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/Allocators.h b/include/mcld/Support/Allocators.h
new file mode 100644
index 0000000..962c900
--- /dev/null
+++ b/include/mcld/Support/Allocators.h
@@ -0,0 +1,439 @@
+//===- Allocators.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ALLOCATORS_H
+#define LLVM_ALLOCATORS_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/ADT/Uncopyable.h"
+#include "mcld/ADT/TypeTraits.h"
+#include "mcld/LD/LDContext.h"
+#include <cstdlib>
+
+namespace mcld
+{
+
+/** \class Chunk
+ *  \brief Chunk is the basic unit of the storage of the LinearAllocator
+ *
+ *  @see LinearAllocator
+ */
+template<typename DataType, size_t ChunkSize>
+struct Chunk
+{
+public:
+  typedef DataType value_type;
+public:
+  Chunk()
+  : next(0), bound(0)
+  { }
+
+  static size_t size() { return ChunkSize; }
+
+public:
+  Chunk* next;
+  size_t bound;
+  DataType data[ChunkSize];
+};
+
+template<typename DataType>
+struct Chunk<DataType, 0>
+{
+public:
+  typedef DataType value_type;
+
+public:
+  Chunk()
+  : next(0), bound(0) {
+    if (0 != m_Size)
+      data = (DataType*)malloc(sizeof(DataType)*m_Size);
+    else
+      data = 0;
+  }
+
+  ~Chunk() {
+    if (data)
+      free(data);
+  }
+
+  static size_t size()              { return m_Size; }
+  static void setSize(size_t pSize) { m_Size = pSize; }
+
+public:
+  Chunk* next;
+  size_t bound;
+  DataType *data;
+  static size_t m_Size;
+};
+
+template<typename DataType>
+size_t Chunk<DataType, 0>::m_Size = 0;
+
+template<typename ChunkType>
+class LinearAllocatorBase : private Uncopyable
+{
+public:
+  typedef ChunkType                             chunk_type;
+  typedef typename ChunkType::value_type        value_type;
+  typedef typename ChunkType::value_type*       pointer;
+  typedef typename ChunkType::value_type&       reference;
+  typedef const typename ChunkType::value_type* const_pointer;
+  typedef const typename ChunkType::value_type& const_reference;
+  typedef size_t                                size_type;
+  typedef ptrdiff_t                             difference_type;
+  typedef unsigned char                         byte_type;
+
+protected:
+  LinearAllocatorBase()
+    : m_pRoot(0),
+      m_pCurrent(0),
+      m_AllocatedNum(0) {
+  }
+
+  // LinearAllocatorBase does NOT mean to destroy the allocated memory.
+  // If you want a memory allocator to release memory at destruction, please
+  // use GCFactory series.
+  virtual ~LinearAllocatorBase()
+  { }
+
+public:
+  pointer address(reference X) const
+  { return &X; }
+
+  const_pointer address(const_reference X) const
+  { return &X; }
+
+  /// standard construct - constructing an object on the location pointed by
+  //  pPtr, and using its copy constructor to initialized its value to pValue.
+  //
+  //  @param pPtr the address where the object to be constructed
+  //  @param pValue the value to be constructed
+  void construct(pointer pPtr, const_reference pValue)
+  { new (pPtr) value_type(pValue); }
+
+  /// default construct - constructing an object on the location pointed by
+  //  pPtr, and using its default constructor to initialized its value to
+  //  pValue.
+  //
+  //  @param pPtr the address where the object to be constructed
+  void construct(pointer pPtr)
+  { new (pPtr) value_type(); }
+
+  /// standard destroy - destroy data on arbitrary address
+  //  @para pPtr the address where the data to be destruected.
+  void destroy(pointer pPtr)
+  { pPtr->~value_type(); }
+
+  /// allocate - allocate N data in order.
+  //  - Disallow to allocate a chunk whose size is bigger than a chunk.
+  //
+  //  @param N the number of allocated data.
+  //  @return the start address of the allocated memory
+  pointer allocate(size_type N) {
+    if (0 == N || N > chunk_type::size())
+      return 0;
+
+    if (empty())
+      initialize();
+
+    size_type rest_num_elem = chunk_type::size() - m_pCurrent->bound;
+    pointer result = 0;
+    if (N > rest_num_elem)
+      createChunk();
+    result = const_cast<pointer>(&(m_pCurrent->data[m_pCurrent->bound]));
+    m_pCurrent->bound += N;
+    return result;
+  }
+
+  /// allocate - clone function of allocating one datum.
+  pointer allocate() {
+    if (empty())
+      initialize();
+
+    pointer result = 0;
+    if (chunk_type::size() == m_pCurrent->bound)
+      createChunk();
+    result = const_cast<pointer>(&(m_pCurrent->data[m_pCurrent->bound]));
+    ++m_pCurrent->bound;
+    return result;
+  }
+
+  /// deallocate - deallocate N data from the pPtr
+  //  - if we can simply release some memory, then do it. Otherwise, do
+  //    nothing.
+  void deallocate(pointer &pPtr, size_type N) {
+    if (0 == N ||
+        N > chunk_type::size() ||
+        0 == m_pCurrent->bound ||
+        N >= m_pCurrent->bound)
+      return;
+    if (!isAvailable(pPtr))
+      return;
+    m_pCurrent->bound -= N;
+    pPtr = 0;
+  }
+
+  /// deallocate - clone function of deallocating one datum
+  void deallocate(pointer &pPtr) {
+    if (0 == m_pCurrent->bound)
+      return;
+    if (!isAvailable(pPtr))
+      return;
+    m_pCurrent->bound -= 1;
+    pPtr = 0;
+  }
+
+  /// isIn - whether the pPtr is in the current chunk?
+  bool isIn(pointer pPtr) const {
+    if (pPtr >= &(m_pCurrent->data[0]) &&
+        pPtr <= &(m_pCurrent->data[chunk_type::size()-1]))
+      return true;
+    return false;
+  }
+
+  /// isIn - whether the pPtr is allocated, and can be constructed.
+  bool isAvailable(pointer pPtr) const {
+    if (pPtr >= &(m_pCurrent->data[m_pCurrent->bound]) &&
+        pPtr <= &(m_pCurrent->data[chunk_type::size()-1]))
+      return true;
+    return false;
+  }
+
+  void reset() {
+    m_pRoot = 0;
+    m_pCurrent = 0;
+    m_AllocatedNum = 0;
+  }
+
+  /// clear - clear all chunks
+  void clear() {
+    chunk_type *cur = m_pRoot, *prev;
+    while (0 != cur) {
+      unsigned int idx=0;
+      prev = cur;
+      cur = cur->next;
+      while (idx != prev->bound) {
+        destroy(&prev->data[idx]);
+        ++idx;
+      }
+      delete prev;
+    }
+    reset();
+  }
+
+  // -----  observers  ----- //
+  bool empty() const {
+    return (0 == m_pRoot);
+  }
+
+  size_type max_size() const
+  { return m_AllocatedNum; }
+
+protected:
+  inline void initialize() {
+    m_pRoot = new chunk_type();
+    m_pCurrent = m_pRoot;
+    m_AllocatedNum += chunk_type::size();
+  }
+
+  inline chunk_type *createChunk() {
+    chunk_type *result = new chunk_type();
+    m_pCurrent->next = result;
+    m_pCurrent = result;
+    m_AllocatedNum += chunk_type::size();
+    return result;
+  }
+
+protected:
+  chunk_type *m_pRoot;
+  chunk_type *m_pCurrent;
+  size_type   m_AllocatedNum;
+};
+
+/** \class LinearAllocator
+ *  \brief LinearAllocator is another bump pointer allocator which should be
+ *  limited in use of two-phase memory allocation.
+ *
+ *  Two-phase memory allocation clear separates the use of memory into 'claim'
+ *  and 'release' phases. There are no interleaving allocation and
+ *  deallocation. Interleaving 'allocate' and 'deallocate' increases the size
+ *  of allocated memory, and causes bad locality.
+ *
+ *  The underlying concept of LinearAllocator is a memory pool. LinearAllocator
+ *  is a simple implementation of boost::pool's ordered_malloc() and
+ *  ordered_free().
+ *
+ *  template argument DataType is the DataType to be allocated
+ *  template argument ChunkSize is the number of bytes of a chunk
+ */
+template<typename DataType, size_t ChunkSize>
+class LinearAllocator : public LinearAllocatorBase<Chunk<DataType, ChunkSize> >
+{
+public:
+  template<typename NewDataType>
+  struct rebind {
+    typedef LinearAllocator<NewDataType, ChunkSize> other;
+  };
+
+public:
+  LinearAllocator()
+    : LinearAllocatorBase<Chunk<DataType, ChunkSize> >() {
+  }
+
+  virtual ~LinearAllocator()
+  { }
+};
+
+template<typename DataType>
+class LinearAllocator<DataType, 0> : public LinearAllocatorBase<Chunk<DataType, 0> >
+{
+public:
+  template<typename NewDataType>
+  struct rebind {
+    typedef LinearAllocator<NewDataType, 0> other;
+  };
+
+public:
+  explicit LinearAllocator(size_t pNum)
+    : LinearAllocatorBase<Chunk<DataType, 0> >() {
+    Chunk<DataType, 0>::setSize(pNum);
+  }
+
+  virtual ~LinearAllocator()
+  { }
+};
+
+template<typename DataType>
+class MallocAllocator
+{
+public:
+  typedef size_t          size_type;
+  typedef ptrdiff_t       difference_type;
+  typedef DataType*       pointer;
+  typedef const DataType* const_pointer;
+  typedef DataType&       reference;
+  typedef const DataType& const_reference;
+  typedef DataType        value_type;
+
+  template<typename OtherDataType>
+  struct rebind
+  {
+    typedef MallocAllocator<OtherDataType> other;
+  };
+
+public:
+  MallocAllocator() throw()
+  { }
+
+  MallocAllocator(const MallocAllocator&) throw()
+  { }
+
+  ~MallocAllocator() throw()
+  { }
+
+  pointer address(reference X) const
+  { return &X; }
+
+  const_pointer address(const_reference X) const
+  { return &X; }
+
+  pointer allocate(size_type pNumOfElements, const void* = 0)
+  {
+    return static_cast<DataType*>(
+                       std::malloc(pNumOfElements*sizeof(DataType)));
+  }
+
+  void deallocate(pointer pObject, size_type)
+  { std::free(static_cast<void*>(pObject)); }
+
+  size_type max_size() const throw()
+  { return size_t(-1) / sizeof(DataType); }
+
+  void construct(pointer pObject, const DataType& pValue)
+  { ::new((void *)pObject) value_type(pValue); }
+
+  void destroy(pointer pObject)
+  { pObject->~DataType(); }
+
+};
+
+template<>
+class MallocAllocator<void>
+{
+public:
+  typedef size_t      size_type;
+  typedef ptrdiff_t   difference_type;
+  typedef void*       pointer;
+  typedef const void* const_pointer;
+  typedef void*       reference;
+  typedef const void* const_reference;
+  typedef void*       value_type;
+
+  template<typename OtherDataType>
+  struct rebind
+  {
+    typedef MallocAllocator<OtherDataType> other;
+  };
+
+public:
+  MallocAllocator() throw()
+  { }
+
+  MallocAllocator(const MallocAllocator&) throw()
+  { }
+
+  ~MallocAllocator() throw()
+  { }
+
+  size_type max_size() const throw()
+  { return size_t(-1) / sizeof(void*); }
+
+  pointer address(reference X) const
+  { return X; }
+
+  const_pointer address(const_reference X) const
+  { return X; }
+
+  template<typename DataType>
+  DataType* allocate(size_type pNumOfElements, const void* = 0) {
+    return static_cast<DataType*>(
+                       std::malloc(pNumOfElements*sizeof(DataType)));
+  }
+
+  pointer allocate(size_type pNumOfElements, const void* = 0) {
+    return std::malloc(pNumOfElements);
+  }
+
+  template<typename DataType>
+  void deallocate(DataType* pObject, size_type)
+  { std::free(static_cast<void*>(pObject)); }
+
+  void deallocate(pointer pObject, size_type)
+  { std::free(pObject); }
+
+  template<typename DataType>
+  void construct(DataType* pObject, const DataType& pValue)
+  { /* do nothing */ }
+
+  void construct(pointer pObject, const_reference pValue)
+  { /* do nothing */ }
+
+  template<typename DataType>
+  void destroy(DataType* pObject)
+  { /* do nothing */ }
+
+  void destroy(pointer pObject)
+  { /* do nothing */ }
+};
+
+} // namespace mcld
+
+#endif
+
diff --git a/include/mcld/Support/CommandLine.h b/include/mcld/Support/CommandLine.h
new file mode 100644
index 0000000..e52c4a3
--- /dev/null
+++ b/include/mcld/Support/CommandLine.h
@@ -0,0 +1,63 @@
+//===- CommandLine.h ------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_COMMANDLINE_H
+#define MCLD_COMMANDLINE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/ADT/StringRef.h>
+#include <llvm/Support/CommandLine.h>
+#include "mcld/Support/FileSystem.h"
+#include "mcld/MC/MCLDDirectory.h"
+
+//--------------------------------------------------
+// parser<mcld::sys::fs::Path>
+//
+namespace llvm {
+namespace cl {
+
+template<>
+class parser<mcld::sys::fs::Path> : public basic_parser<mcld::sys::fs::Path>
+{
+public:
+  bool parse(Option &O,
+             StringRef ArgName,
+             StringRef Arg,
+             mcld::sys::fs::Path &Val);
+
+  virtual const char *getValueName() const { return "path"; }
+  void printOptionDiff(const Option &O,
+                       const mcld::sys::fs::Path &V,
+                       OptVal Default,
+                       size_t GlobalWidth) const;
+  virtual void anchor();
+};
+
+//--------------------------------------------------
+// parser<mcld::MCLDDirectory>
+//
+template<>
+class parser<mcld::MCLDDirectory> : public llvm::cl::basic_parser<mcld::MCLDDirectory>
+{
+public:
+  bool parse(Option &O, StringRef ArgName, StringRef Arg, mcld::MCLDDirectory &Val);
+
+  virtual const char *getValueName() const { return "directory"; }
+  void printOptionDiff(const Option &O,
+                       const mcld::MCLDDirectory &V,
+                       OptVal Default,
+                       size_t GlobalWidth) const;
+  virtual void anchor();
+};
+
+} // namespace of cl
+} // namespace of llvm
+
+#endif
+
diff --git a/include/mcld/Support/DerivedPositionDependentOptions.h b/include/mcld/Support/DerivedPositionDependentOptions.h
new file mode 100644
index 0000000..2254a5f
--- /dev/null
+++ b/include/mcld/Support/DerivedPositionDependentOptions.h
@@ -0,0 +1,137 @@
+//===- DerivedPositionDependentOptions.h ----------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_DERIVEDPOSITIONDEPENDENTOPTIONS_H
+#define MCLD_DERIVEDPOSITIONDEPENDENTOPTIONS_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <string>
+
+#include "mcld/Support/RealPath.h"
+#include "mcld/Support/PositionDependentOption.h"
+
+namespace mcld
+{
+
+  /** \class DerivedPositionDependentOptions
+   *  \brief This file contains the declarations of classes derived from PositionDependentOption.
+   */
+
+  class FileOption : public PositionDependentOption {
+  private:
+    sys::fs::RealPath m_Path;
+
+  protected:
+    FileOption(unsigned pPosition, Type pType, const sys::fs::Path &pPath)
+      : PositionDependentOption(pPosition, pType)
+    { m_Path.assign(pPath); }
+
+  public:
+    inline const sys::fs::Path *path() const { return &m_Path; }
+  };
+
+  class NamespecOption : public PositionDependentOption {
+  private:
+    std::string m_pNamespec;
+
+  public:
+    NamespecOption(unsigned pPosition, const std::string &pNamespec)
+      : PositionDependentOption(pPosition, PositionDependentOption::NAMESPEC),
+        m_pNamespec(pNamespec) { }
+
+    inline const std::string &namespec() const { return m_pNamespec; }
+  };
+
+  class BitcodeOption : public FileOption {
+  public:
+    BitcodeOption(unsigned pPosition, const sys::fs::Path &pPath)
+      : FileOption(pPosition, PositionDependentOption::BITCODE, pPath) { }
+  };
+
+  class StartGroupOption : public PositionDependentOption {
+  public:
+    StartGroupOption(unsigned pPosition)
+      : PositionDependentOption(pPosition,
+                                PositionDependentOption::START_GROUP) { }
+  };
+
+  class EndGroupOption : public PositionDependentOption {
+  public:
+    EndGroupOption(unsigned pPosition)
+      : PositionDependentOption(pPosition,
+                                PositionDependentOption::END_GROUP) { }
+  };
+
+  class InputFileOption : public FileOption {
+  public:
+    InputFileOption(unsigned pPosition, const sys::fs::Path &pPath)
+      : FileOption(pPosition, PositionDependentOption::INPUT_FILE, pPath) { }
+  };
+
+  class WholeArchiveOption : public PositionDependentOption {
+  public:
+    WholeArchiveOption(unsigned pPosition)
+      : PositionDependentOption(pPosition,
+                                PositionDependentOption::WHOLE_ARCHIVE) { }
+  };
+
+  class NoWholeArchiveOption : public PositionDependentOption {
+  public:
+    NoWholeArchiveOption(unsigned pPosition)
+      : PositionDependentOption(pPosition,
+                                PositionDependentOption::NO_WHOLE_ARCHIVE) { }
+  };
+
+  class AsNeededOption : public PositionDependentOption {
+  public:
+    AsNeededOption(unsigned pPosition)
+      : PositionDependentOption(pPosition,
+                                PositionDependentOption::AS_NEEDED) { }
+  };
+
+  class NoAsNeededOption : public PositionDependentOption {
+  public:
+    NoAsNeededOption(unsigned pPosition)
+      : PositionDependentOption(pPosition,
+                                PositionDependentOption::NO_AS_NEEDED) { }
+  };
+
+  class AddNeededOption : public PositionDependentOption {
+  public:
+    AddNeededOption(unsigned pPosition)
+      : PositionDependentOption(pPosition,
+                                PositionDependentOption::ADD_NEEDED) { }
+  };
+
+  class NoAddNeededOption : public PositionDependentOption {
+  public:
+    NoAddNeededOption(unsigned pPosition)
+      : PositionDependentOption(pPosition,
+                                PositionDependentOption::NO_ADD_NEEDED) { }
+  };
+
+  class BDynamicOption : public PositionDependentOption {
+  public:
+    BDynamicOption(unsigned pPosition)
+      : PositionDependentOption(pPosition,
+                                PositionDependentOption::BDYNAMIC) { }
+  };
+
+  class BStaticOption : public PositionDependentOption {
+  public:
+    BStaticOption(unsigned pPosition)
+      : PositionDependentOption(pPosition,
+                                PositionDependentOption::BSTATIC) { }
+  };
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/Directory.h b/include/mcld/Support/Directory.h
new file mode 100644
index 0000000..8383e9e
--- /dev/null
+++ b/include/mcld/Support/Directory.h
@@ -0,0 +1,153 @@
+//===- Directory.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_DIRECTORY_H
+#define MCLD_DIRECTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/ADT/TypeTraits.h"
+#include "mcld/Support/FileSystem.h"
+#include "mcld/Support/Path.h"
+#include "mcld/Support/PathCache.h"
+#include <llvm/Support/Allocator.h>
+
+
+namespace mcld {
+namespace sys {
+namespace fs {
+
+class DirIterator;
+
+/** \class Directory
+ *  \brief A Directory object stores a Path object, a FileStatus object for
+ *   non-symbolic link status, and a FileStatus object for symbolic link
+ *   status. The FileStatus objects act as value caches.
+ */
+class Directory
+{
+friend mcld::sys::fs::PathCache::entry_type* detail::bring_one_into_cache(DirIterator& pIter);
+friend void detail::open_dir(Directory& pDir);
+friend void detail::close_dir(Directory& pDir);
+private:
+  friend class DirIterator;
+
+public:
+  typedef DirIterator iterator;
+
+public:
+  /// default constructor
+  Directory();
+
+  /// constructor - a directory whose path is pPath
+  explicit Directory(const Path& pPath,
+                     FileStatus st = FileStatus(),
+                     FileStatus symlink_st = FileStatus());
+
+  /// copy constructor
+  /// when a copying construction happens, the cache is not copied.
+  Directory(const Directory& pCopy);
+
+  /// assignment
+  /// When an assignment occurs, the cache is clear.
+  Directory& operator=(const Directory& pCopy);
+
+  /// destructor, inheritable.
+  virtual ~Directory();
+
+  /// Since we have default construtor, we must provide assign.
+  void assign(const Path& pPath,
+              FileStatus st = FileStatus(),
+              FileStatus symlink_st = FileStatus());
+
+  /// clear - clear the cache and close the directory handler
+  void clear();
+
+  bool isGood() const;
+
+  /// path - the path of the directory
+  const Path& path() const
+  { return m_Path; }
+
+  FileStatus status() const;
+  FileStatus symlinkStatus() const;
+
+  // -----  iterators  ----- //
+  // While the iterators move, the direcotry is modified.
+  // Thus, we only provide non-constant iterator.
+  iterator begin();
+  iterator end();
+
+protected:
+  mcld::sys::fs::Path m_Path;
+  mutable FileStatus m_FileStatus;
+  mutable FileStatus m_SymLinkStatus;
+  intptr_t m_Handler;
+  // the cache of directory
+  mcld::sys::fs::PathCache m_Cache;
+  bool m_CacheFull;
+};
+
+/** \class DirIterator
+ *  \brief A DirIterator object can traverse all entries in a Directory
+ *
+ *  DirIterator will open the directory and add entry into Directory::m_Cache
+ *  DirIterator() is the end of a directory.
+ *  If the end of the directory elements is reached, the iterator becomes
+ *  equal to the end iterator value - DirIterator().
+ *
+ *  @see Directory
+ */
+class DirIterator
+{
+friend mcld::sys::fs::PathCache::entry_type* detail::bring_one_into_cache(DirIterator& pIter);
+friend class Directory;
+public:
+  typedef mcld::sys::fs::PathCache            DirCache;
+
+public:
+  typedef Directory                       value_type;
+  typedef ConstTraits<Directory>          const_traits;
+  typedef NonConstTraits<Directory>       non_const_traits;
+  typedef std::input_iterator_tag         iterator_category;
+  typedef size_t                          size_type;
+  typedef ptrdiff_t                       difference_type;
+
+private:
+  explicit DirIterator(Directory* pParent,
+                       const DirCache::iterator& pIter);
+
+public:
+  // Since StringMapIterator has no default constructor, we also have none.
+  DirIterator(const DirIterator &X);
+  ~DirIterator();
+  DirIterator& operator=(const DirIterator& pCopy);
+
+  DirIterator& operator++();
+  DirIterator operator++(int);
+
+  Path* generic_path();
+
+  Path* path();
+  const Path* path() const;
+
+  bool operator==(const DirIterator& y) const;
+  bool operator!=(const DirIterator& y) const;
+
+private:
+  Directory* m_pParent; // get handler
+  DirCache::iterator m_Iter; // for full situation
+  DirCache::entry_type* m_pEntry;
+};
+
+} // namespace of fs
+} // namespace of sys
+} // namespace of mcld
+
+#endif
diff --git a/include/mcld/Support/FileSystem.h b/include/mcld/Support/FileSystem.h
new file mode 100644
index 0000000..28dc563
--- /dev/null
+++ b/include/mcld/Support/FileSystem.h
@@ -0,0 +1,119 @@
+//===- FileSystem.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// This file declares the mcld::sys::fs:: namespace. It follows TR2/boost
+// filesystem (v3), but modified to remove exception handling and the
+// path class.
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_FILE_SYSTEM_H
+#define MCLD_FILE_SYSTEM_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/Support/PathCache.h"
+#include <string>
+#include <iosfwd>
+#include <locale>
+
+namespace mcld {
+namespace sys {
+namespace fs {
+
+enum FileType
+{
+  StatusError,
+  StatusUnknown = StatusError,
+  FileNotFound,
+  RegularFile,
+  DirectoryFile,
+  SymlinkFile,
+  BlockFile,
+  CharacterFile,
+  FifoFile,
+  SocketFile,
+  ReparseFile,
+  TypeUnknown,
+  StatusKnown,
+  IsSymLink
+};
+
+/** \class FileStatus
+ *  \brief FileStatus
+ */
+class FileStatus
+{
+public:
+  FileStatus()
+    : m_Value(StatusError) {}
+
+  explicit FileStatus(FileType v)
+    : m_Value(v) {}
+
+  void setType(FileType v)   { m_Value = v; }
+  FileType type() const   { return m_Value; }
+
+private:
+  FileType m_Value;
+};
+
+inline bool operator==(const FileStatus& rhs, const FileStatus& lhs) {
+  return rhs.type() == lhs.type();
+}
+
+inline bool operator!=(const FileStatus& rhs, const FileStatus& lhs ) {
+  return !(rhs == lhs);
+}
+
+class Path;
+class DirIterator;
+class Directory;
+
+bool exists(const Path &pPath);
+bool is_directory(const Path &pPath);
+
+inline static bool exists(FileStatus f) {
+  return (f.type() != StatusError)&&(f.type() != FileNotFound);
+}
+
+inline static bool is_directory(FileStatus f) {
+  return f.type() == mcld::sys::fs::DirectoryFile;
+}
+
+namespace detail
+{
+
+typedef unsigned char* Address;
+typedef off_t Offset;
+extern std::string static_library_extension;
+extern std::string shared_library_extension;
+extern std::string executable_extension;
+extern std::string relocatable_extension;
+extern std::string assembly_extension;
+extern std::string bitcode_extension;
+
+size_t canonicalize(std::string& pPathName);
+bool not_found_error(int perrno);
+void status(const Path& p, FileStatus& pFileStatus);
+void symlink_status(const Path& p, FileStatus& pFileStatus);
+mcld::sys::fs::PathCache::entry_type* bring_one_into_cache(DirIterator& pIter);
+void open_dir(Directory& pDir);
+void close_dir(Directory& pDir);
+void get_pwd(std::string& pPWD);
+size_t pread(int pFD, Address pBuf, size_t pCount, off_t pOffset);
+size_t pwrite(int pFD, const Address pBuf, size_t pCount, off_t pOffset);
+char *strerror(int pErrnum);
+
+} // namespace of detail
+} // namespace of fs
+} // namespace of sys
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/GCFactory.h b/include/mcld/Support/GCFactory.h
new file mode 100644
index 0000000..103188e
--- /dev/null
+++ b/include/mcld/Support/GCFactory.h
@@ -0,0 +1,230 @@
+//===- GCFactory.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_GC_FACTORY_H
+#define MCLD_GC_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/ADT/TypeTraits.h"
+#include "mcld/Support/Allocators.h"
+
+#include <assert.h>
+#include <iterator>
+
+namespace mcld
+{
+
+/** \class DataIteratorBase
+ *  \brief DataIteratorBase provides the basic functions of DataIterator
+ *  @see DataIterator
+ */
+template<typename ChunkType>
+struct DataIteratorBase
+{
+public:
+  ChunkType* m_pChunk;
+  unsigned int m_Pos;
+
+public:
+  DataIteratorBase(ChunkType* X, unsigned int pPos)
+  : m_pChunk(X), m_Pos(pPos)
+  { }
+
+  inline void advance() {
+    ++m_Pos;
+    if ((m_Pos == m_pChunk->bound) && (0 == m_pChunk->next))
+      return;
+    if (m_Pos == m_pChunk->bound) {
+      m_pChunk = m_pChunk->next;
+      m_Pos = 0;
+    }
+  }
+
+  bool operator==(const DataIteratorBase& y) const
+  { return ((this->m_pChunk == y.m_pChunk) && (this->m_Pos == y.m_Pos)); }
+
+  bool operator!=(const DataIteratorBase& y) const
+  { return ((this->m_pChunk != y.m_pChunk) || (this->m_Pos != y.m_Pos)); }
+};
+
+/** \class DataIterator
+ *  \brief DataIterator provides STL compatible iterator for allocators
+ */
+template<typename ChunkType, class Traits>
+class DataIterator : public DataIteratorBase<ChunkType>
+{
+public:
+  typedef typename ChunkType::value_type  value_type;
+  typedef Traits                          traits;
+  typedef typename traits::pointer        pointer;
+  typedef typename traits::reference      reference;
+  typedef DataIterator<ChunkType, Traits> Self;
+  typedef DataIteratorBase<ChunkType>     Base;
+
+  typedef typename traits::nonconst_traits         nonconst_traits;
+  typedef DataIterator<ChunkType, nonconst_traits> iterator;
+  typedef typename traits::const_traits            const_traits;
+  typedef DataIterator<ChunkType, const_traits>    const_iterator;
+  typedef std::forward_iterator_tag                iterator_category;
+  typedef size_t                                   size_type;
+  typedef ptrdiff_t                                difference_type;
+
+public:
+  DataIterator()
+  : Base(0, 0)
+  { }
+
+  DataIterator(ChunkType* pChunk, unsigned int pPos)
+  : Base(pChunk, pPos)
+  { }
+
+  DataIterator(const DataIterator& pCopy)
+  : Base(pCopy.m_pChunk, pCopy.m_Pos)
+  { }
+
+  ~DataIterator()
+  { }
+
+  // -----  operators  ----- //
+  reference operator*() {
+    if (0 == this->m_pChunk)
+      assert(0 && "data iterator goes to a invalid position");
+    return this->m_pChunk->data[Base::m_Pos];
+  }
+
+  Self& operator++() {
+    this->Base::advance();
+    return *this;
+  }
+
+  Self operator++(int) {
+    Self tmp = *this;
+    this->Base::advance();
+    return tmp;
+  }
+};
+
+template<typename Alloc>
+class GCFactoryBase : public Alloc
+{
+public:
+  typedef DataIterator<typename Alloc::chunk_type,
+                       NonConstTraits<
+                         typename Alloc::value_type> > iterator;
+  typedef DataIterator<typename Alloc::chunk_type,
+                       ConstTraits<
+                         typename Alloc::value_type> > const_iterator;
+
+  typedef typename Alloc::value_type value_type;
+  typedef typename Alloc::pointer    pointer;
+  typedef typename Alloc::reference  reference;
+  typedef typename Alloc::size_type  size_type;
+
+protected:
+  GCFactoryBase()
+  : Alloc(), m_NumAllocData(0)
+  { }
+
+  GCFactoryBase(size_t pNum)
+  : Alloc(pNum), m_NumAllocData(0)
+  { }
+
+public:
+  virtual ~GCFactoryBase()
+  { Alloc::clear(); }
+
+  // -----  modifiers  ----- //
+  value_type* allocate(size_t N) {
+    value_type* result = Alloc::allocate(N);
+    if (0 != result)
+      m_NumAllocData += N;
+    return result;
+  }
+
+  value_type* allocate() {
+    ++m_NumAllocData;
+    return Alloc::allocate();
+  }
+
+  void deallocate(pointer &pPtr, size_type N) {
+    Alloc::deallocate(pPtr, N);
+    if (0 == pPtr)
+      m_NumAllocData -= N;
+  }
+
+  void deallocate(pointer &pPtr) {
+    Alloc::deallocate(pPtr);
+    if (0 == pPtr)
+      --m_NumAllocData;
+  }
+
+  void reset() {
+    Alloc::reset();
+    m_NumAllocData = 0;
+  }
+
+  // -----  iterators  ----- //
+  iterator begin()
+  { return iterator(Alloc::m_pRoot, 0); }
+
+  const_iterator begin() const
+  { return const_iterator(Alloc::m_pRoot, 0); }
+
+  iterator end() {
+    return (0 == Alloc::m_pCurrent)? 
+             begin():
+             iterator(Alloc::m_pCurrent, Alloc::m_pCurrent->bound);
+  }
+
+  const_iterator end() const {
+    return (0 == Alloc::m_pCurrent)? 
+             begin():
+             const_iterator(Alloc::m_pCurrent, Alloc::m_pCurrent->bound);
+  }
+
+  // -----  observers  ----- //
+  bool empty() const
+  { return Alloc::empty(); }
+
+  unsigned int capacity() const
+  { return Alloc::max_size(); }
+
+  unsigned int size() const
+  { return m_NumAllocData; }
+
+protected:
+  unsigned int m_NumAllocData;
+};
+
+/** \class GCFactory
+ *  \brief GCFactory provides a factory that guaratees to remove all allocated
+ *  data.
+ */
+template<typename DataType, size_t ChunkSize>
+class GCFactory : public GCFactoryBase<LinearAllocator<DataType, ChunkSize> >
+{
+public:
+  GCFactory()
+  : GCFactoryBase<LinearAllocator<DataType, ChunkSize> >()
+  { }
+};
+
+template<typename DataType>
+class GCFactory<DataType, 0> : public GCFactoryBase<LinearAllocator<DataType, 0> >
+{
+public:
+  GCFactory(size_t pNum)
+  : GCFactoryBase<LinearAllocator<DataType, 0> >(pNum)
+  { }
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/GCFactoryListTraits.h b/include/mcld/Support/GCFactoryListTraits.h
new file mode 100644
index 0000000..418ec57
--- /dev/null
+++ b/include/mcld/Support/GCFactoryListTraits.h
@@ -0,0 +1,65 @@
+//===- GCFactoryListTraits.h ----------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_GC_FACTORY_LIST_TRAITS_H
+#define MCLD_GC_FACTORY_LIST_TRAITS_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/ADT/ilist_node.h>
+#include <llvm/ADT/ilist.h>
+
+#include <assert.h>
+
+namespace mcld
+{
+
+/** \class GCFactoryListTraits
+ *  \brief GCFactoryListTraits provides trait class for llvm::iplist when
+ *  the nodes in the list is produced by GCFactory.
+ */
+template<typename DataType>
+class GCFactoryListTraits : public llvm::ilist_default_traits<DataType> {
+private:
+  class SentinelNode : public llvm::ilist_node<DataType> {
+  public:
+    SentinelNode() : llvm::ilist_node<DataType>() { }
+  };
+
+public:
+  // override the traits provided in llvm::ilist_sentinel_traits since we've
+  // defined our own sentinel.
+  DataType *createSentinel() const
+  { return reinterpret_cast<DataType*>(&mSentinel); }
+
+  static void destroySentinel(DataType*) { }
+
+  DataType *provideInitialHead() const
+  { return createSentinel(); }
+
+  DataType *ensureHead(DataType*) const
+  { return createSentinel(); }
+
+  static void noteHead(DataType*, DataType*) { }
+
+  // override the traits provided in llvm::ilist_node_traits since
+  static DataType *createNode(const DataType &V) {
+    assert(false && "Only GCFactory knows how to create a node.");
+  }
+  static void deleteNode(DataType *V) {
+    // No action. GCFactory will handle it by itself.
+  }
+
+private:
+  mutable SentinelNode mSentinel;
+};
+
+} // namespace of mcld
+
+#endif
diff --git a/include/mcld/Support/LEB128.h b/include/mcld/Support/LEB128.h
new file mode 100644
index 0000000..816ed72
--- /dev/null
+++ b/include/mcld/Support/LEB128.h
@@ -0,0 +1,117 @@
+//===- LEB128.h -----------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_LEB128_H
+#define MCLD_LEB128_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <stdint.h>
+#include <sys/types.h>
+
+namespace mcld {
+
+namespace leb128 {
+
+typedef unsigned char ByteType;
+
+/* Forward declarations */
+template<typename IntType>
+size_t encode(ByteType *&pBuf, IntType pValue);
+
+template<typename IntType>
+IntType decode(const ByteType *pBuf, size_t &pSize);
+
+template<typename IntType>
+IntType decode(const ByteType *&pBuf);
+
+/*
+ * Given an integer, this function returns the number of bytes required to
+ * encode it in ULEB128 format.
+ */
+template<typename IntType>
+size_t size(IntType pValue) {
+  size_t size = 1;
+  while (pValue > 0x80) {
+    pValue >>= 7;
+    ++size;
+  }
+  return size;
+}
+
+/*
+ * Write an unsigned integer in ULEB128 to the given buffer. The client should
+ * ensure there's enough space in the buffer to hold the result. Update the
+ * given buffer pointer to the point just past the end of the write value and
+ * return the number of bytes being written.
+ */
+template<>
+size_t encode<uint64_t>(ByteType *&pBuf, uint64_t pValue);
+
+template<>
+size_t encode<uint32_t>(ByteType *&pBuf, uint32_t pValue);
+
+/*
+ * Encoding functions for signed LEB128.
+ */
+template<>
+size_t encode<int64_t>(ByteType *&pBuf, int64_t pValue);
+
+template<>
+size_t encode<int32_t>(ByteType *&pBuf, int32_t pValue);
+
+/*
+ * Read an integer encoded in ULEB128 format from the given buffer. pSize will
+ * contain the number of bytes used in the buffer to encode the returned
+ * integer.
+ */
+template<>
+uint64_t decode<uint64_t>(const ByteType *pBuf, size_t &pSize);
+
+/*
+ * Read an integer encoded in ULEB128 format from the given buffer. Update the
+ * given buffer pointer to the point just past the end of the read value.
+ */
+template<>
+uint64_t decode<uint64_t>(const ByteType *&pBuf);
+
+/*
+ * Decoding functions for signed LEB128.
+ */
+template<>
+int64_t decode<int64_t>(const ByteType *pBuf, size_t &pSize);
+
+template<>
+int64_t decode<int64_t>(const ByteType *&pBuf);
+
+/*
+ * The functions below handle the signed byte stream. This helps the user to get
+ * rid of annoying type conversions when using the LEB128 encoding/decoding APIs
+ * defined above.
+ */
+template<typename IntType>
+size_t encode(char *&pBuf, IntType pValue) {
+  return encode<IntType>(reinterpret_cast<ByteType*&>(pBuf), pValue);
+}
+
+template<typename IntType>
+IntType decode(const char *pBuf, size_t &pSize) {
+  return decode<IntType>(reinterpret_cast<const ByteType*>(pBuf), pSize);
+}
+
+template<typename IntType>
+IntType decode(const char *&pBuf) {
+  return decode<IntType>(reinterpret_cast<const ByteType*&>(pBuf));
+}
+
+} // namespace of leb128
+} // namespace of mcld
+
+#endif
diff --git a/include/mcld/Support/MemoryArea.h b/include/mcld/Support/MemoryArea.h
new file mode 100644
index 0000000..2c04aff
--- /dev/null
+++ b/include/mcld/Support/MemoryArea.h
@@ -0,0 +1,260 @@
+//===- MemoryArea.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_MEMORY_AREA_H
+#define MCLD_MEMORY_AREA_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/ADT/Uncopyable.h"
+#include "mcld/Support/FileSystem.h"
+#include "mcld/Support/Path.h"
+#include <llvm/ADT/ilist.h>
+#include <llvm/ADT/ilist_node.h>
+#include <fcntl.h>
+#include <string>
+#include <list>
+
+#if defined(ENABLE_UNITTEST)
+namespace mcldtest
+{
+  class MemoryAreaTest;
+} // namespace of mcldtest
+
+#endif
+namespace mcld
+{
+
+class MemoryRegion;
+class RegionFactory;
+
+/** \class MemoryArea
+ *  \brief MemoryArea is used to manage distinct MemoryRegions of address space.
+ *
+ *  Good linkers must well manipulate memory mapped I/O and dynamic memory.
+ *  In MCLinker, MemoryArea is the decision-maker to use memory mapped I/O or
+ *  dynamic memory. When a client requests MemoryArea for a piece of memory
+ *  to hold a part of a file, MemoryArea is going to see whether the requested
+ *  part of the file is already in any existing memory which is requested
+ *  before. If it is, MemoryArea creates a new MemoryRegion within the memory
+ *  requested before. Otherwise, MemoryArea uses memory mapped I/O or dynamic
+ *  memory to load the file.
+ *
+ *  If the part a file being loaded is larger than 3/4 pages, MemoryArea uses
+ *  memory mapped I/O to load the file. Otherwise, MemoryArea uses dynamic
+ *  memory to read the content of file into the memory space.
+ */
+class MemoryArea : private Uncopyable
+{
+#if defined(ENABLE_UNITTEST)
+friend class mcldtest::MemoryAreaTest;
+#endif
+public:
+  enum IOState
+  {
+    GoodBit    = 0,
+    BadBit     = 1L << 0,
+    EOFBit     = 1L << 1,
+    FailBit    = 1L << 2,
+    IOStateEnd = 1L << 16
+  };
+
+  enum AccessMode
+  {
+    ReadOnly = O_RDONLY,
+    WriteOnly = O_WRONLY,
+    ReadWrite = O_RDWR,
+    AccessMask = O_ACCMODE
+  };
+
+private:
+  typedef sys::fs::detail::Address Address;
+
+  friend class MemoryRegion;
+  friend class RegionFactory;
+  struct Space : public llvm::ilist_node<Space>
+  {
+  public:
+    enum Type
+    {
+      ALLOCATED_ARRAY,
+      MMAPED,
+      UNALLOCATED
+    };
+
+  public:
+    Space()
+    : m_pParent(NULL),
+      type(UNALLOCATED),
+      file_offset(0),
+      size(0),
+      data(0),
+      region_num(0)
+    { }
+
+    Space(MemoryArea* pParent, size_t pOffset, size_t pLength)
+    : m_pParent(pParent),
+      type(UNALLOCATED),
+      file_offset(pOffset),
+      size(pLength),
+      data(0),
+      region_num(0)
+    { }
+
+    ~Space()
+    { }
+
+    void sync()
+    { m_pParent->write(*this); }
+
+  private:
+    MemoryArea* m_pParent;
+
+  public:
+    Type type;
+    size_t file_offset;
+    size_t size;
+    sys::fs::detail::Address data;
+    size_t region_num;
+  };
+
+  friend class Space;
+  typedef llvm::iplist<Space> SpaceList;
+
+public:
+  // constructor
+  // @param pRegionFactory the factory to manage MemoryRegions
+  MemoryArea(RegionFactory& pRegionFactory);
+
+  // destructor
+  ~MemoryArea();
+
+  // request - create a MemoryRegion within a sufficient space
+  // find an existing space to hold the MemoryRegion.
+  // if MemoryArea does not find such space, then it creates a new space and
+  // assign a MemoryRegion into the space.
+  MemoryRegion* request(size_t pOffset, size_t pLength);
+
+  // release - release a MemoryRegion.
+  // release a MemoryRegion does not cause
+  void release(MemoryRegion* pRegion);
+
+  // clean - release all MemoryRegion and unmap all spaces.
+  void clean();
+
+  // sync - sync all MemoryRegion
+  void sync();
+
+  // map - open the file pPath and mapped it onto MemoryArea
+  // @param flags see man 2 open
+  void map(const sys::fs::Path& pPath, int flags);
+
+  // map - open the file pPath and mapped it onto MemoryArea
+  // @param flags see man 2 open
+  // @param mode see man 2 open
+  void map(const sys::fs::Path& pPath, int flags, int mode);
+
+  // unmap - close the opened file and unmap the MemoryArea
+  void unmap();
+
+  // path - the path of the mapped file.
+  const sys::fs::Path& path() const
+  { return m_FilePath; }
+
+  // size - the real size of the mapped file.
+  size_t size() const
+  { return m_FileSize; }
+
+  // isMapped - check if MemoryArea is mapped to a file
+  bool isMapped() const;
+
+  // isGood - check if the state of the opened area is good for read/write
+  // operations
+  bool isGood() const;
+
+  // isBad - check if an error causes the loss of integrity of the memory space
+  bool isBad() const;
+
+  // isFailed - check if an error related to the internal logic of the operation
+  // itself occurs
+  bool isFailed() const;
+
+  // isEOF - check if we reach the end of the file
+  bool isEOF() const;
+
+  // isReadable - check if the memory area is readable
+  bool isReadable() const;
+
+  // isWriteable - check if the memory area is writable
+  bool isWritable() const;
+
+  // rdstate - get error state flags
+  // Returns the current internal error state flags of the stream
+  int rdstate() const;
+
+  // setState - set error state flag
+  void setState(IOState pState);
+
+  // clear - set error state flag
+  void clear(IOState pState = GoodBit);
+
+private:
+  // readToBuffer - read data from the file behind this MemorySpace and store
+  // those bytes in pBuf. Return the number of byte read or -1 on error.
+  ssize_t readToBuffer(sys::fs::detail::Address pBuf,
+                       size_t pSize, size_t pOffset);
+
+private:
+  // find - first fit search
+  Space* find(size_t pOffset, size_t pLength);
+
+  // release a Space, but does not remove it from space list
+  void release(Space* pSpace);
+
+  // read - read data from mapped file into virtual memroy of pSpace. Return
+  // false on error.
+  bool read(Space& pSpace);
+
+  // write - write back the virtual memory of pSpace into mapped file.
+  void write(const Space& pSpace);
+
+  // truncate - truncate the file size to length.
+  void truncate(size_t pLength);
+
+  // policy - decide whehter to use dynamic memory or memory mapped I/O
+  Space::Type policy(off_t pOffset, size_t pLength);
+
+  // the size of one page
+  static const off_t PageSize = 4096;
+
+  // page_boundary - Given a file size, return the size to read integral pages.
+  // return the first page boundary after pFileOffset
+  static off_t page_boundary(off_t pFileOffset)
+  { return (pFileOffset + (PageSize - 1)) & ~ (PageSize - 1); }
+
+  // Given a file offset, return the page offset.
+  // return the first page boundary before pFileOffset
+  static off_t page_offset(off_t pFileOffset)
+  { return pFileOffset & ~ (PageSize - 1); }
+
+private:
+  RegionFactory& m_RegionFactory;
+  sys::fs::Path m_FilePath;
+  int m_FileDescriptor;
+  size_t m_FileSize;
+  int m_AccessFlags;
+  int m_State;
+
+  SpaceList m_SpaceList;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/MemoryAreaFactory.h b/include/mcld/Support/MemoryAreaFactory.h
new file mode 100644
index 0000000..f9ffa6e
--- /dev/null
+++ b/include/mcld/Support/MemoryAreaFactory.h
@@ -0,0 +1,64 @@
+//===- MemoryAreaFactory.h ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_MEMORY_AREA_FACTORY_H
+#define MCLD_MEMORY_AREA_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/Support/UniqueGCFactory.h"
+#include "mcld/Support/MemoryArea.h"
+#include "mcld/Support/Path.h"
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+namespace mcld
+{
+
+class RegionFactory;
+/** \class MemoryAreaFactory
+ *  \brief MemoryAreaFactory avoids creating duplicated MemoryAreas of the
+ *   same file.
+ *
+ *  Users can give duplicated input files on the command line. In order to 
+ *  prevent opening the same file twice, and create redundant MemoryRegions,
+ *  mcld::Input should not create MemoryArea directly. Instead, it should ask
+ *  MemoryAreaFactory and get the unique MemoryArea.
+ *
+ *  The timing of opening and closing files is not strictly bound to the
+ *  constructor and destructor of MCLDFile. For mcld::Output, MCLinker
+ *  opens the file rather after assigning offset to sections. On the other
+ *  aside, mcld::Input opens the file at constructor. In order to hide the
+ *  file operations, MemoryAreaFactory actually open the file untill the first
+ *  MemoryRegion is requested.
+ *
+ *  @see MemoryRegion
+ *  @see UniqueGCFactoryBase
+ */
+class MemoryAreaFactory : public UniqueGCFactoryBase<sys::fs::Path, MemoryArea, 0>
+{
+public:
+  explicit MemoryAreaFactory(size_t pNum);
+  ~MemoryAreaFactory();
+
+  // produce - create a MemoryArea and open its file
+  // If the file fails to be opened, the returned MemoryArea::isMapped() 
+  // should be false
+  MemoryArea* produce(const sys::fs::Path& pPath, int pFlags);
+  MemoryArea* produce(const sys::fs::Path& pPath, int pFlags, mode_t pMode);
+
+private:
+  RegionFactory* m_pRegionFactory;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/MemoryRegion.h b/include/mcld/Support/MemoryRegion.h
new file mode 100644
index 0000000..49f5fda
--- /dev/null
+++ b/include/mcld/Support/MemoryRegion.h
@@ -0,0 +1,97 @@
+//===- MemoryRegion.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LD_MEMORY_REGION_H
+#define LD_MEMORY_REGION_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/ADT/Uncopyable.h>
+#include <mcld/ADT/SizeTraits.h>
+#include <mcld/ADT/TypeTraits.h>
+#include <mcld/Support/FileSystem.h>
+#include <mcld/Support/MemoryArea.h>
+#include <llvm/ADT/ilist.h>
+#include <llvm/ADT/StringRef.h>
+
+namespace mcld
+{
+
+/** \class MemoryRegion
+ *  \brief MemoryRegion is a range of virtual memory which is mapped onto a
+ *  range of files which is opened by MemoryArea.
+ *
+ *  MemoryArea maps a file onto virtual memory. Clients can get a range of
+ *  mapped memory space by requesting a MemoryRegion from MemoryArea, and
+ *  read/write the mapped file through the MemoryRegion.
+ *
+ *  When two different MemoryRegion may overlap memory space, race condition
+ *  may occurs. Clients must call MemoryRegion::sync() explicit to tell the
+ *  MemoryArea when to synchronize the virtual memory space with the mapped
+ *  file.
+ */
+class MemoryRegion : private Uncopyable
+{
+friend class RegionFactory;
+friend class MemoryArea;
+
+public:
+typedef NonConstTraits<mcld::sys::fs::detail::Address>::value_type Address;
+typedef ConstTraits<mcld::sys::fs::detail::Address>::value_type    ConstAddress;
+typedef NonConstTraits<mcld::sys::fs::detail::Offset>::value_type  Offset;
+typedef ConstTraits<mcld::sys::fs::detail::Offset>::value_type     ConstOffset;
+
+private:
+  MemoryRegion(MemoryArea::Space* pParentSpace,
+               const Address pVMAStart,
+               size_t pSize);
+
+  // drift - leave parent space
+  void drift();
+
+  MemoryArea::Space* parent()
+  { return m_pParentSpace; }
+
+  const MemoryArea::Space* parent() const
+  { return m_pParentSpace; }
+
+public:
+  ~MemoryRegion();
+
+  Address start()
+  { return m_VMAStart; }
+
+  ConstAddress start() const
+  { return m_VMAStart; }
+
+  Address end()
+  { return m_VMAStart+m_Length; }
+
+  ConstAddress end() const
+  { return m_VMAStart+m_Length; }
+
+  size_t size() const
+  { return m_Length; }
+
+  Address getBuffer(Offset pOffset = 0)
+  { return m_VMAStart+pOffset; }
+
+  ConstAddress getBuffer(Offset pOffset = 0) const
+  { return m_VMAStart+pOffset; }
+ 
+private:
+  MemoryArea::Space* m_pParentSpace;
+  Address m_VMAStart;
+  size_t m_Length;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/Path.h b/include/mcld/Support/Path.h
new file mode 100644
index 0000000..f5ee56c
--- /dev/null
+++ b/include/mcld/Support/Path.h
@@ -0,0 +1,179 @@
+//===- Path.h -------------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// This file declares the mcld::sys::fs:: namespace. It follows TR2/boost
+// filesystem (v3), but modified to remove exception handling and the
+// path class.
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_PATH_H
+#define MCLD_PATH_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/Support/raw_ostream.h>
+#include <functional>
+#include <string>
+
+//#include "mcld/Support/Directory.h"
+namespace mcld {
+namespace sys  {
+namespace fs   {
+
+#ifdef LLVM_ON_WIN32
+const wchar_t       separator = L'\\';
+const wchar_t       preferred_separator = L'\\';
+#else
+const char          separator = '/';
+const char          preferred_separator = '/';
+#endif
+
+/** \class Path
+ *  \brief Path provides an abstraction for the path to a file or directory in
+ *   the operating system's filesystem.
+ *
+ *  FIXME: current Path library only support UTF-8 chararcter set.
+ *
+ */
+class Path
+{
+public:
+#ifdef LLVM_ON_WIN32
+  typedef wchar_t                            ValueType;
+#else
+  typedef char                               ValueType;
+#endif
+  typedef std::basic_string<ValueType>       StringType;
+
+public:
+  Path();
+  Path(const ValueType* s);
+  Path(const StringType &s);
+  Path(const Path& pCopy);
+  virtual ~Path();
+
+  // -----  assignments  ----- //
+  template <class InputIterator>
+  Path& assign(InputIterator begin, InputIterator end);
+  Path& assign(const StringType &s);
+  Path& assign(const ValueType* s, unsigned int length);
+
+  //  -----  appends  ----- //
+  template <class InputIterator>
+  Path& append(InputIterator begin, InputIterator end);
+  Path& append(const Path& pPath);
+
+  //  -----  observers  ----- //
+  bool empty() const;
+
+  bool isFromRoot() const;
+  bool isFromPWD() const;
+
+  const StringType &native() const
+  { return m_PathName; }
+
+  StringType &native()
+  { return m_PathName; }
+
+  const ValueType* c_str() const
+  { return m_PathName.c_str(); }
+
+  std::string string() const;
+
+  // -----  decomposition  ----- //
+  Path stem() const;
+  Path extension() const;
+
+  // -----  generic form observers  ----- //
+  StringType generic_string() const;
+  bool canonicalize();
+
+public:
+  StringType::size_type m_append_separator_if_needed();
+  void m_erase_redundant_separator(StringType::size_type sep_pos);
+
+protected:
+  StringType m_PathName;
+};
+
+bool operator==(const Path& pLHS,const Path& pRHS);
+bool operator!=(const Path& pLHS,const Path& pRHS);
+
+//--------------------------------------------------------------------------//
+//                              non-member functions                        //
+//--------------------------------------------------------------------------//
+
+/// is_separator - is the given character a separator of a path.
+// @param value a character
+// @result true if \a value is a path separator character on the host OS
+//bool status_known(FileStatus f) { return f.type() != StatusError; }
+
+bool is_separator(char value);
+
+bool exists(const Path &pPath);
+
+bool is_directory(const Path &pPath);
+
+
+std::ostream &operator<<(std::ostream& pOS, const Path& pPath);
+
+std::istream &operator>>(std::istream& pOS, Path& pPath);
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Path &pPath);
+
+
+//--------------------------------------------------------------------------------------//
+//                     class path member template implementation                        //
+//--------------------------------------------------------------------------------------//
+template <class InputIterator>
+Path& Path::assign(InputIterator begin, InputIterator end)
+{
+  m_PathName.clear();
+  if (begin != end)
+    m_PathName.append<InputIterator>(begin, end);
+  return *this;
+}
+
+template <class InputIterator>
+Path& Path::append(InputIterator begin, InputIterator end)
+{
+  if (begin == end)
+    return *this;
+  StringType::size_type sep_pos(m_append_separator_if_needed());
+  m_PathName.append<InputIterator>(begin, end);
+  if (sep_pos)
+    m_erase_redundant_separator(sep_pos);
+  return *this;
+}
+
+} // namespace of fs
+} // namespace of sys
+} // namespace of mcld
+
+//-------------------------------------------------------------------------//
+//                              STL compatible functions                   //
+//-------------------------------------------------------------------------//
+namespace std {
+
+template<>
+struct less<mcld::sys::fs::Path> : public binary_function<mcld::sys::fs::Path,
+                                                         mcld::sys::fs::Path,
+                                                         bool>
+{
+  bool operator() (const mcld::sys::fs::Path& pX,const mcld::sys::fs::Path& pY) const {
+    if (pX.generic_string().size() < pY.generic_string().size())
+      return true;
+    return (pX.generic_string() < pY.generic_string());
+  }
+};
+
+} // namespace of std
+
+#endif
+
diff --git a/include/mcld/Support/PathCache.h b/include/mcld/Support/PathCache.h
new file mode 100644
index 0000000..89ec513
--- /dev/null
+++ b/include/mcld/Support/PathCache.h
@@ -0,0 +1,38 @@
+//===- PathCache.h --------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCLD_PATHCACHE_H
+#define MCLD_PATHCACHE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/ADT/HashEntry.h"
+#include "mcld/ADT/HashTable.h"
+#include "mcld/ADT/StringHash.h"
+#include "mcld/Support/Path.h"
+
+namespace mcld {
+namespace sys  {
+namespace fs   {
+
+namespace {
+  typedef HashEntry<llvm::StringRef,
+                    mcld::sys::fs::Path*,
+                    StringCompare<llvm::StringRef> > HashEntryType;
+} // anonymous namespace
+
+typedef HashTable<HashEntryType, StringHash<BKDR>, EntryFactory<HashEntryType> > PathCache;
+
+} // namespace of fs
+} // namespace of sys
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/PositionDependentOption.h b/include/mcld/Support/PositionDependentOption.h
new file mode 100644
index 0000000..b5d60e8
--- /dev/null
+++ b/include/mcld/Support/PositionDependentOption.h
@@ -0,0 +1,63 @@
+//===- PositionDependentOption.h ------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_POSITIONDEPENDENTOPTION_H
+#define MCLD_POSITIONDEPENDENTOPTION_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <vector>
+
+namespace mcld
+{
+
+  /** \class PositionDependentOption
+   *  \brief PositionDependentOptions converts LLVM options into MCLDInfo
+   */
+  class PositionDependentOption
+  {
+  public:
+    enum Type {
+      BITCODE,
+      NAMESPEC,
+      INPUT_FILE,
+      START_GROUP,
+      END_GROUP,
+      WHOLE_ARCHIVE,
+      NO_WHOLE_ARCHIVE,
+      AS_NEEDED,
+      NO_AS_NEEDED,
+      ADD_NEEDED,
+      NO_ADD_NEEDED,
+      BDYNAMIC,
+      BSTATIC
+    };
+
+  protected:
+    PositionDependentOption(unsigned pPosition, Type pType)
+      : m_Type(pType),
+        m_Position(pPosition) {}
+
+  public:
+    inline const Type& type() const
+    { return m_Type; }
+
+    inline unsigned position() const
+    { return m_Position; }
+
+  private:
+    Type m_Type;
+    unsigned m_Position;
+  };
+
+  typedef std::vector<PositionDependentOption*> PositionDependentOptions;
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/RealPath.h b/include/mcld/Support/RealPath.h
new file mode 100644
index 0000000..6c0cd40
--- /dev/null
+++ b/include/mcld/Support/RealPath.h
@@ -0,0 +1,72 @@
+//===- RealPath.h ---------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_REAL_PATH_H
+#define MCLD_REAL_PATH_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/Support/Path.h"
+#include <string>
+
+namespace mcld {
+namespace sys  {
+namespace fs   {
+
+/** \class RealPath
+ *  \brief The canonicalized absolute pathname.
+ *
+ */
+class RealPath : public Path
+{
+public:
+  typedef Path::ValueType  ValueType;
+  typedef Path::StringType StringType;
+
+public:
+  RealPath();
+  explicit RealPath(const ValueType* s );
+  explicit RealPath(const StringType &s );
+  explicit RealPath(const Path& pPath);
+
+  ~RealPath();
+
+  RealPath& assign(const Path& pPath);
+
+protected:
+  void initialize();
+};
+
+} // namespace of fs
+} // namespace of sys
+} // namespace of mcld
+
+//-------------------------------------------------------------------------//
+//                              STL compatible functions                   //
+//-------------------------------------------------------------------------//
+namespace std {
+
+template<>
+struct less<mcld::sys::fs::RealPath> : public binary_function<
+                                                     mcld::sys::fs::RealPath,
+                                                     mcld::sys::fs::RealPath,
+                                                     bool>
+{
+  bool operator() (const mcld::sys::fs::RealPath& pX,
+                   const mcld::sys::fs::RealPath& pY) const {
+    if (pX.native().size() < pY.native().size())
+      return true;
+    return (pX.native() < pY.native());
+  }
+};
+
+} // namespace of std
+
+
+#endif
+
diff --git a/include/mcld/Support/RegionFactory.h b/include/mcld/Support/RegionFactory.h
new file mode 100644
index 0000000..ba9a88d
--- /dev/null
+++ b/include/mcld/Support/RegionFactory.h
@@ -0,0 +1,48 @@
+//===- RegionFactory.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_REGION_FACTORY_H
+#define MCLD_REGION_FACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/Support/GCFactory.h"
+#include "mcld/Support/MemoryRegion.h"
+#include "mcld/Support/MemoryArea.h"
+#include "mcld/Support/FileSystem.h"
+
+namespace mcld
+{
+
+class MemoryArea;
+
+/** \class RegionFactory
+ *  \brief RegionFactory produces and destroys MemoryRegions
+ *
+ */
+class RegionFactory : public GCFactory<MemoryRegion, 0>
+{
+public:
+  typedef GCFactory<MemoryRegion, 0> Alloc;
+
+public:
+  RegionFactory(size_t pNum);
+  ~RegionFactory();
+
+  // ----- production ----- //
+  MemoryRegion* produce(MemoryArea::Space* pSpace,
+                        const sys::fs::detail::Address pVMAStart,
+                        size_t pSize);
+
+  void destruct(MemoryRegion* pRegion);
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/TargetRegistry.h b/include/mcld/Support/TargetRegistry.h
new file mode 100644
index 0000000..a9ad875
--- /dev/null
+++ b/include/mcld/Support/TargetRegistry.h
@@ -0,0 +1,230 @@
+//===- TargetRegistry.h ---------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef TARGET_REGISTRY_H
+#define TARGET_REGISTRY_H
+#include <llvm/Support/TargetRegistry.h>
+#include <string>
+#include <list>
+
+namespace llvm {
+class TargetMachine;
+class MCCodeEmitter;
+class MCContext;
+class AsmPrinter;
+} // namespace of llvm
+
+namespace mcld {
+class LLVMTargetMachine;
+class TargetRegistry;
+class SectLinker;
+class SectLinkerOption;
+class TargetLDBackend;
+class AttributeFactory;
+class InputFactory;
+class ContextFactory;
+
+//===----------------------------------------------------------------------===//
+/// Target - mcld::Target is an object adapter of llvm::Target
+///
+class Target
+{
+  friend class mcld::LLVMTargetMachine;
+  friend class mcld::TargetRegistry;
+public:
+  typedef mcld::LLVMTargetMachine *(*TargetMachineCtorTy)(const mcld::Target &,
+                                                          llvm::TargetMachine &,
+                                                          const std::string&);
+
+  typedef SectLinker *(*SectLinkerCtorTy)(const std::string& pTriple,
+                                          SectLinkerOption &,
+                                          TargetLDBackend&);
+
+  typedef TargetLDBackend  *(*TargetLDBackendCtorTy)(const llvm::Target&,
+                                                     const std::string&);
+
+private:
+  TargetMachineCtorTy TargetMachineCtorFn;
+  SectLinkerCtorTy SectLinkerCtorFn;
+  TargetLDBackendCtorTy TargetLDBackendCtorFn;
+
+public:
+  Target();
+
+  void setTarget(const llvm::Target& pTarget) {
+    m_pT = &pTarget;
+  }
+
+  mcld::LLVMTargetMachine *createTargetMachine(const std::string &pTriple,
+                          const std::string &pCPU, const std::string &pFeatures,
+                          const llvm::TargetOptions &Options,
+                          llvm::Reloc::Model RM = llvm::Reloc::Default,
+                          llvm::CodeModel::Model CM = llvm::CodeModel::Default,
+                          llvm::CodeGenOpt::Level OL = llvm::CodeGenOpt::Default) const {
+    if (TargetMachineCtorFn && m_pT) {
+      llvm::TargetMachine *tm = m_pT->createTargetMachine(pTriple, pCPU, pFeatures, Options, RM, CM, OL);
+      if (tm)
+        return TargetMachineCtorFn(*this, *tm, pTriple);
+    }
+    return 0;
+  }
+
+  /// createSectLinker - create target-specific SectLinker
+  ///
+  /// @return created SectLinker
+  SectLinker *createSectLinker(const std::string &pTriple,
+                               SectLinkerOption &pOption,
+                               TargetLDBackend &pLDBackend) const {
+    if (!SectLinkerCtorFn)
+      return 0;
+    return SectLinkerCtorFn(pTriple,
+                            pOption,
+                            pLDBackend);
+  }
+
+  /// createLDBackend - create target-specific LDBackend
+  ///
+  /// @return created TargetLDBackend
+  TargetLDBackend *createLDBackend(const llvm::Target& T, const std::string& Triple) const {
+    if (!TargetLDBackendCtorFn)
+      return 0;
+    return TargetLDBackendCtorFn(T, Triple);
+  }
+
+  const llvm::Target* get() const {
+    return m_pT;
+  }
+
+private:
+  const llvm::Target* m_pT;
+};
+
+//===----------------------------------------------------------------------===//
+/// TargetRegistry - mcld::TargetRegistry is an object adapter of
+/// llvm::TargetRegistry
+///
+class TargetRegistry
+{
+public:
+  typedef std::list<mcld::Target*> TargetListTy;
+  typedef TargetListTy::iterator iterator;
+
+private:
+  static TargetListTy s_TargetList;
+
+public:
+  static iterator begin() { return s_TargetList.begin(); }
+  static iterator end() { return s_TargetList.end(); }
+
+  static size_t size() { return s_TargetList.size(); }
+  static bool empty() { return s_TargetList.empty(); }
+
+  /// RegisterTarget - Register the given target. Attempts to register a
+  /// target which has already been registered will be ignored.
+  ///
+  /// Clients are responsible for ensuring that registration doesn't occur
+  /// while another thread is attempting to access the registry. Typically
+  /// this is done by initializing all targets at program startup.
+  ///
+  /// @param T - The target being registered.
+  static void RegisterTarget(mcld::Target &T);
+
+  /// RegisterTargetMachine - Register a TargetMachine implementation for the
+  /// given target.
+  ///
+  /// @param T - The target being registered.
+  /// @param Fn - A function to construct a TargetMachine for the target.
+  static void RegisterTargetMachine(mcld::Target &T, mcld::Target::TargetMachineCtorTy Fn) {
+    // Ignore duplicate registration.
+    if (!T.TargetMachineCtorFn)
+      T.TargetMachineCtorFn = Fn;
+  }
+
+  /// RegisterSectLinker - Register a SectLinker implementation for the given
+  /// target.
+  ///
+  /// @param T - the target being registered
+  /// @param Fn - A function to create SectLinker for the target
+  static void RegisterSectLinker(mcld::Target &T, mcld::Target::SectLinkerCtorTy Fn) {
+    if (!T.SectLinkerCtorFn)
+      T.SectLinkerCtorFn = Fn;
+  }
+
+  /// RegisterTargetLDBackend - Register a TargetLDBackend implementation for
+  /// the given target.
+  ///
+  /// @param T - The target being registered
+  /// @param Fn - A function to create TargetLDBackend for the target
+  static void RegisterTargetLDBackend(mcld::Target &T, mcld::Target::TargetLDBackendCtorTy Fn) {
+    if (!T.TargetLDBackendCtorFn)
+      T.TargetLDBackendCtorFn = Fn;
+  }
+
+  /// lookupTarget - Lookup a target based on a llvm::Target.
+  ///
+  /// @param T - The llvm::Target to find
+  static const mcld::Target *lookupTarget(const llvm::Target& T);
+
+  /// lookupTarget - function wrapper of llvm::TargetRegistry::lookupTarget
+  ///
+  /// @param Triple - The Triple string
+  /// @param Error  - The returned error message
+  static const mcld::Target *lookupTarget(const std::string &Triple,
+                                          std::string &Error);
+};
+
+/// RegisterTarget - Helper function for registering a target, for use in the
+/// target's initialization function. Usage:
+///
+/// Target TheFooTarget; // The global target instance.
+///
+/// extern "C" void LLVMInitializeFooTargetInfo() {
+///   RegisterTarget X(TheFooTarget, "foo", "Foo description");
+/// }
+struct RegisterTarget
+{
+  RegisterTarget(mcld::Target &T, const char *Name) {
+    llvm::TargetRegistry::iterator TIter, TEnd = llvm::TargetRegistry::end();
+    // lookup llvm::Target
+    for( TIter=llvm::TargetRegistry::begin(); TIter!=TEnd; ++TIter ) {
+      if( 0==strcmp(TIter->getName(), Name) )
+        break;
+    }
+    T.setTarget(*TIter);
+
+    TargetRegistry::RegisterTarget(T);
+  }
+};
+
+/// RegisterTargetMachine - Helper template for registering a target machine
+/// implementation, for use in the target machine initialization
+/// function. Usage:
+///
+/// extern "C" void LLVMInitializeFooTarget() {
+///   extern mcld::Target TheFooTarget;
+///   RegisterTargetMachine<mcld::FooTargetMachine> X(TheFooTarget);
+/// }
+template<class TargetMachineImpl>
+struct RegisterTargetMachine
+{
+  RegisterTargetMachine(mcld::Target &T) {
+    TargetRegistry::RegisterTargetMachine(T, &Allocator);
+  }
+
+private:
+  static mcld::LLVMTargetMachine *Allocator(const mcld::Target &T,
+                                            llvm::TargetMachine& TM,
+                                            const std::string &Triple) {
+    return new TargetMachineImpl(TM, T, Triple);
+  }
+};
+
+} //end namespace mcld
+
+#endif
+
diff --git a/include/mcld/Support/TargetSelect.h b/include/mcld/Support/TargetSelect.h
new file mode 100644
index 0000000..e040ae2
--- /dev/null
+++ b/include/mcld/Support/TargetSelect.h
@@ -0,0 +1,77 @@
+//===- TargetSelect.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef TARGETSELECT_H
+#define TARGETSELECT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+extern "C" {
+  // Declare all of the target-initialization functions that are available.
+#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##LDTargetInfo();
+#include "mcld/Config/Targets.def"
+
+  // Declare all of the target-dependent functions that are available.
+#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##LDTarget();
+#include "mcld/Config/Targets.def"
+
+  // Declare all of the target-depedent linker information
+#define LLVM_LINKER(TargetName) void LLVMInitialize##TargetName##LDInfo();
+#include "mcld/Config/Linkers.def"
+
+  // Declare all of the available linker environment.
+#define LLVM_LINKER(TargetName) void LLVMInitialize##TargetName##SectLinker();
+#include "mcld/Config/Linkers.def"
+
+  // Declare all of the available target-specific linker
+#define LLVM_LINKER(TargetName) void LLVMInitialize##TargetName##LDBackend();
+#include "mcld/Config/Linkers.def"
+} // extern "C"
+
+namespace mcld
+{
+  /// InitializeAllTargetInfos - The main program should call this function if
+  /// it wants access to all available targets that LLVM is configured to
+  /// support, to make them available via the TargetRegistry.
+  ///
+  /// It is legal for a client to make multiple calls to this function.
+  inline void InitializeAllTargetInfos() {
+#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##LDTargetInfo();
+#include "mcld/Config/Targets.def"
+  }
+
+  /// InitializeAllTargets - The main program should call this function if it
+  /// wants access to all available target machines that LLVM is configured to
+  /// support, to make them available via the TargetRegistry.
+  ///
+  /// It is legal for a client to make multiple calls to this function.
+  inline void InitializeAllTargets() {
+    mcld::InitializeAllTargetInfos();
+
+#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##LDTarget();
+#include "mcld/Config/Targets.def"
+  }
+
+  /// InitializeAllLinkers - The main program should call this function if it
+  /// wants all linkers that LLVM is configured to support, to make them
+  /// available via the TargetRegistry.
+  ///
+  /// It is legal for a client to make multiple calls to this function.
+  inline void InitializeAllLinkers() {
+#define LLVM_LINKER(TargetName) LLVMInitialize##TargetName##SectLinker();
+#include "mcld/Config/Linkers.def"
+
+#define LLVM_LINKER(TargetName) LLVMInitialize##TargetName##LDBackend();
+#include "mcld/Config/Linkers.def"
+  }
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Support/UniqueGCFactory.h b/include/mcld/Support/UniqueGCFactory.h
new file mode 100644
index 0000000..3147bab
--- /dev/null
+++ b/include/mcld/Support/UniqueGCFactory.h
@@ -0,0 +1,94 @@
+//===- UniqueGCFactory.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_UNIQUE_GCFACTORY_H
+#define MCLD_UNIQUE_GCFACTORY_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include "mcld/Support/GCFactory.h"
+#include <map>
+#include <utility>
+
+namespace mcld
+{
+
+/** \class UniqueGCFactoryBase
+ *  \brief UniqueGCFactories are unique associative factories, meaning that
+ *  no two elements have the same key.
+ */
+template<typename KeyType, typename DataType, size_t ChunkSize>
+class UniqueGCFactoryBase : public GCFactoryBase<LinearAllocator<DataType, ChunkSize> >
+{
+protected:
+  typedef GCFactoryBase<LinearAllocator<DataType, ChunkSize> > Alloc;
+  typedef std::map<KeyType, DataType*> KeyMap;
+
+protected:
+  UniqueGCFactoryBase()
+  : GCFactoryBase<LinearAllocator<DataType, ChunkSize> >()
+  { }
+
+  UniqueGCFactoryBase(size_t pNum)
+  : GCFactoryBase<LinearAllocator<DataType, ChunkSize> >(pNum)
+  { }
+
+public:
+  virtual ~UniqueGCFactoryBase()
+  { f_KeyMap.clear(); }
+
+  DataType* find(const KeyType& pKey) {
+    typename KeyMap::iterator dataIter = f_KeyMap.find(pKey);
+    if (dataIter != f_KeyMap.end())
+      return dataIter->second;
+    return 0;
+  }
+
+  const DataType* find(const KeyType& pKey) const {
+    typename KeyMap::const_iterator dataIter = f_KeyMap.find(pKey);
+    if (dataIter != f_KeyMap.end())
+      return dataIter->second;
+    return 0;
+  }
+
+  DataType* produce(const KeyType& pKey, bool& pExist) {
+    typename KeyMap::iterator dataIter = f_KeyMap.find(pKey);
+    if (dataIter != f_KeyMap.end()) {
+      pExist = true;
+      return dataIter->second;
+    }
+    DataType* data = Alloc::allocate();
+    construct(data);
+    f_KeyMap.insert(std::make_pair(pKey, data));
+    pExist = false;
+    return data;
+  }
+
+  DataType* produce(const KeyType& pKey, const DataType& pValue, bool& pExist) {
+    typename KeyMap::iterator dataIter = f_KeyMap.find(pKey);
+    if (dataIter != f_KeyMap.end()) {
+      pExist = true;
+      return dataIter->second;
+    }
+    DataType* data = Alloc::allocate();
+    construct(data, pValue);
+    f_KeyMap.insert(std::make_pair(pKey, data));
+    pExist = false;
+    return data;
+  }
+
+protected:
+  KeyMap f_KeyMap;
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Target/AndroidSectLinker.h b/include/mcld/Target/AndroidSectLinker.h
new file mode 100644
index 0000000..dd68ff2
--- /dev/null
+++ b/include/mcld/Target/AndroidSectLinker.h
@@ -0,0 +1,42 @@
+//===- AndroidSectLinker.h ------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// AndroidSectLinker is a customized linker pass for Android platform.
+// This pass set up default parameters for Android.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ANDROID_SECTLINKER_H
+#define ANDROID_SECTLINKER_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <mcld/CodeGen/SectLinker.h>
+
+namespace mcld
+{
+
+class AndroidSectLinker : public SectLinker
+{
+public:
+  AndroidSectLinker(SectLinkerOption &pOption,
+                    mcld::TargetLDBackend &pLDBackend);
+
+  virtual ~AndroidSectLinker();
+
+  // addTargetInputs - add Android-specific linker options
+  virtual void addTargetOptions(llvm::Module &pM,
+                                SectLinkerOption &pOption);
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Target/DarwinLDBackend.h b/include/mcld/Target/DarwinLDBackend.h
new file mode 100644
index 0000000..d55055a
--- /dev/null
+++ b/include/mcld/Target/DarwinLDBackend.h
@@ -0,0 +1,31 @@
+//===- DarwinLDBackend.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef DARWINLDBACKEND_H
+#define DARWINLDBACKEND_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+namespace mcld
+{
+
+/** \class DarwinLDBackend
+ *  \brief DarwinLDBackend provides a common interface for all Darwin OS LDBackend.
+ *
+ *  \see
+ */
+class DarwinLDBackend
+{
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Target/ELFDynamic.h b/include/mcld/Target/ELFDynamic.h
new file mode 100644
index 0000000..ed18dc0
--- /dev/null
+++ b/include/mcld/Target/ELFDynamic.h
@@ -0,0 +1,174 @@
+//===- ELFDynamic.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_ELF_DYNAMIC_SECTION_H
+#define MCLD_ELF_DYNAMIC_SECTION_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/Support/ELF.h>
+#include <mcld/LD/LDSection.h>
+#include <vector>
+#include <cstring>
+
+namespace mcld
+{
+
+class GNULDBackend;
+class ELFFileFormat;
+class MCLDInfo;
+class MemoryRegion;
+
+namespace elf_dynamic {
+
+/** \class EntryIF
+*  \brief EntryIF provides a common interface for one entry in the dynamic
+*  section
+*/
+class EntryIF
+{
+protected:
+  EntryIF();
+
+public:
+  virtual ~EntryIF(); 
+
+  virtual EntryIF* clone() const = 0;
+  virtual size_t size() const = 0;
+  virtual size_t symbolSize() const = 0;
+  virtual size_t relSize() const = 0;
+  virtual size_t relaSize() const = 0;
+  virtual size_t emit(uint8_t* pAddress) const = 0;
+  virtual void setValue(uint64_t pTag, uint64_t pValue) = 0;
+};
+
+template<size_t BITNUMBER, bool LITTLEENDIAN>
+class Entry
+{ };
+
+template<>
+class Entry<32, true> : public EntryIF
+{
+public:
+  typedef llvm::ELF::Elf32_Dyn  Pair;
+  typedef llvm::ELF::Elf32_Sym  Symbol;
+  typedef llvm::ELF::Elf32_Rel  Rel;
+  typedef llvm::ELF::Elf32_Rela Rela;
+
+public:
+  inline Entry();
+
+  inline ~Entry();
+
+  Entry* clone() const
+  { return new Entry(); }
+
+  size_t size() const
+  { return sizeof(Pair); }
+
+  size_t symbolSize() const
+  { return sizeof(Symbol); }
+
+  size_t relSize() const
+  { return sizeof(Rel); }
+
+  size_t relaSize() const
+  { return sizeof(Rela); }
+
+  inline void setValue(uint64_t pTag, uint64_t pValue);
+
+  inline size_t emit(uint8_t* pAddress) const;
+
+private:
+  Pair m_Pair;
+}; 
+
+#include "ELFDynamic.tcc"
+
+} // namespace of elf_dynamic
+
+/** \class ELFDynamic
+ *  \brief ELFDynamic is the .dynamic section in ELF shared and executable
+ *  files.
+ */
+class ELFDynamic
+{
+public:
+  typedef std::vector<elf_dynamic::EntryIF*> EntryListType;
+  typedef EntryListType::iterator iterator;
+  typedef EntryListType::const_iterator const_iterator;
+
+public:
+  ELFDynamic(const GNULDBackend& pParent);
+
+  virtual ~ELFDynamic();
+
+  size_t size() const;
+
+  size_t entrySize() const;
+
+  size_t numOfBytes() const;
+
+  /// reserveEntries - reserve entries
+  void reserveEntries(const MCLDInfo& pInfo,
+                      const ELFFileFormat& pFormat);
+
+  /// reserveNeedEntry - reserve on DT_NEED entry.
+  void reserveNeedEntry();
+  
+  /// applyEntries - apply entries
+  void applyEntries(const MCLDInfo& pInfo,
+                    const ELFFileFormat& pFormat);
+
+  void applySoname(uint64_t pStrTabIdx);
+
+  iterator needBegin()
+  { return m_NeedList.begin(); }
+
+  iterator needEnd()
+  { return m_NeedList.end(); }
+
+  const_iterator needBegin() const
+  { return m_NeedList.begin(); }
+
+  const_iterator needEnd() const
+  { return m_NeedList.end(); }
+
+  /// emit
+  void emit(const LDSection& pSection, MemoryRegion& pRegion) const;
+
+protected:
+  /// reserveTargetEntries - reserve target dependent entries
+  virtual void reserveTargetEntries(const ELFFileFormat& pFormat) = 0;
+
+  /// applyTargetEntries - apply target-dependant
+  virtual void applyTargetEntries(const ELFFileFormat& pFormat) = 0;
+
+protected:
+  void reserveOne(uint64_t pTag);
+
+  void applyOne(uint64_t pTag, uint64_t pValue);
+
+  size_t symbolSize() const;
+
+private:
+  EntryListType m_EntryList;
+  EntryListType m_NeedList;
+  elf_dynamic::EntryIF* m_pEntryFactory;
+
+  // The entry reserved and the entry being applied are not must matched.
+  // For better performance, we use a simple counter and apply entry one-by-one
+  // by the counter. m_Idx is the counter indicating to the entry being applied.
+  size_t m_Idx;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Target/ELFDynamic.tcc b/include/mcld/Target/ELFDynamic.tcc
new file mode 100644
index 0000000..8b04651
--- /dev/null
+++ b/include/mcld/Target/ELFDynamic.tcc
@@ -0,0 +1,33 @@
+//===- ELFDynamic.h -------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+Entry<32, true>::Entry()
+{
+  m_Pair.d_tag = 0;
+  m_Pair.d_un.d_val = 0;
+}
+
+Entry<32, true>::~Entry()
+{
+}
+
+void Entry<32, true>::setValue(uint64_t pTag, uint64_t pValue)
+{
+  m_Pair.d_tag = pTag;
+  m_Pair.d_un.d_val = pValue;
+}
+
+size_t Entry<32, true>::emit(uint8_t* pAddress) const
+{
+  memcpy(reinterpret_cast<void*>(pAddress),
+         reinterpret_cast<const void*>(&m_Pair),
+         sizeof(Pair));
+  return sizeof(Pair);
+}
+
diff --git a/include/mcld/Target/GNULDBackend.h b/include/mcld/Target/GNULDBackend.h
new file mode 100644
index 0000000..7f51448
--- /dev/null
+++ b/include/mcld/Target/GNULDBackend.h
@@ -0,0 +1,322 @@
+//===- GNULDBackend.h -----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_TARGET_GNU_LDBACKEND_H
+#define MCLD_TARGET_GNU_LDBACKEND_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/Support/ELF.h>
+#include <mcld/ADT/HashTable.h>
+#include <mcld/ADT/HashEntry.h>
+#include <mcld/LD/ELFDynObjReader.h>
+#include <mcld/LD/ELFDynObjWriter.h>
+#include <mcld/LD/ELFObjectReader.h>
+#include <mcld/LD/ELFObjectWriter.h>
+#include <mcld/LD/ELFDynObjFileFormat.h>
+#include <mcld/LD/ELFExecFileFormat.h>
+#include <mcld/LD/ELFSegment.h>
+#include <mcld/LD/GNUArchiveReader.h>
+#include <mcld/Support/GCFactory.h>
+#include <mcld/Target/ELFDynamic.h>
+#include <mcld/Target/TargetLDBackend.h>
+#include <mcld/LD/ELFSegmentFactory.h>
+
+namespace mcld
+{
+
+struct SymCompare
+{
+  bool operator()(const LDSymbol* X, const LDSymbol* Y) const
+  { return (X==Y); }
+};
+
+struct PtrHash
+{
+  size_t operator()(const LDSymbol* pKey) const
+  {
+    return (unsigned((uintptr_t)pKey) >> 4) ^
+           (unsigned((uintptr_t)pKey) >> 9);
+  }
+};
+
+class MCLDInfo;
+class Layout;
+class SymbolCategory;
+
+/** \class GNULDBackend
+ *  \brief GNULDBackend provides a common interface for all GNU Unix-OS
+ *  LDBackend.
+ */
+class GNULDBackend : public TargetLDBackend
+{
+  // These dynamic section tags are GNU extension.
+  enum {
+    DT_RELACOUNT  = 0x6ffffff9,
+    DT_RELCOUNT   = 0x6ffffffa,
+    DT_FLAGS_1    = 0x6ffffffb,
+    DT_VERDEF     = 0x6ffffffc,
+    DT_VERDEFNUM  = 0x6ffffffd,
+    DT_VERNEED    = 0x6ffffffe,
+    DT_VERNEEDNUM = 0x6fffffff
+  };
+
+protected:
+  // Based on Kind in LDFileFormat to define basic section orders for ELF, and
+  // refer gold linker to add more enumerations to handle Regular and BSS kind
+  enum SectionOrder {
+    SHO_INTERP = 1,          // .interp
+    SHO_RO_NOTE,             // .note.ABI-tag, .note.gnu.build-id
+    SHO_NAMEPOOL,            // *.hash, .dynsym, .dynstr
+    SHO_RELOCATION,          // .rel.*, .rela.*
+    SHO_REL_PLT,             // .rel.plt should come after other .rel.*
+    SHO_INIT,                // .init
+    SHO_PLT,                 // .plt
+    SHO_TEXT,                // .text
+    SHO_FINI,                // .fini
+    SHO_RO,                  // .rodata
+    SHO_EHFRAME,             // .eh_frame_hdr, .eh_frame
+    SHO_TLS_DATA,            // .tdata
+    SHO_TLS_BSS,             // .tbss
+    SHO_RELRO_LOCAL,         // .data.rel.ro.local
+    SHO_RELRO,               // .data.rel.ro,
+    SHO_RELRO_LAST,          // for x86 to adjust .got if needed
+    SHO_NON_RELRO_FIRST,     // for x86 to adjust .got.plt if needed
+    SHO_DATA,                // .data
+    SHO_LARGE_DATA,          // .ldata
+    SHO_RW_NOTE,             //
+    SHO_SMALL_DATA,          // .sdata
+    SHO_SMALL_BSS,           // .sbss
+    SHO_BSS,                 // .bss
+    SHO_LARGE_BSS,           // .lbss
+    SHO_UNDEFINED = ~(0U)    // default order
+  };
+
+protected:
+  GNULDBackend();
+
+public:
+  virtual ~GNULDBackend();
+
+  bool initArchiveReader(MCLinker& pLinker, MCLDInfo& pInfo);
+  bool initObjectReader(MCLinker& pLinker);
+  bool initDynObjReader(MCLinker& pLinker);
+  bool initObjectWriter(MCLinker& pLinker);
+  bool initDynObjWriter(MCLinker& pLinker);
+
+  bool initExecSections(MCLinker& pMCLinker);
+  bool initDynObjSections(MCLinker& pMCLinker);
+
+  bool initStandardSymbols(MCLinker& pLinker);
+
+  GNUArchiveReader *getArchiveReader();
+  GNUArchiveReader *getArchiveReader() const;
+
+  ELFObjectReader *getObjectReader();
+  ELFObjectReader *getObjectReader() const;
+
+  ELFDynObjReader *getDynObjReader();
+  ELFDynObjReader *getDynObjReader() const;
+
+  ELFObjectWriter *getObjectWriter();
+  ELFObjectWriter *getObjectWriter() const;
+
+  ELFDynObjWriter *getDynObjWriter();
+  ELFDynObjWriter *getDynObjWriter() const;
+
+  ELFDynObjFileFormat* getDynObjFileFormat();
+  ELFDynObjFileFormat* getDynObjFileFormat() const;
+
+  ELFExecFileFormat* getExecFileFormat();
+  ELFExecFileFormat* getExecFileFormat() const;
+
+  size_t sectionStartOffset() const;
+
+  /// The return value of machine() it the same as e_machine in the ELF header*/
+  virtual uint32_t machine() const = 0;
+
+  /// ELFVersion - the value of e_ident[EI_VERSION]
+  virtual uint8_t ELFVersion() const
+  { return llvm::ELF::EV_CURRENT; }
+
+  /// OSABI - the value of e_ident[EI_OSABI]
+  virtual uint8_t OSABI() const = 0;
+
+  /// ABIVersion - the value of e_ident[EI_ABIVRESION]
+  virtual uint8_t ABIVersion() const = 0;
+
+  /// flags - the value of ElfXX_Ehdr::e_flags
+  virtual uint64_t flags() const = 0;
+
+  /// entry - the symbol name of the entry point
+  virtual const char* entry() const
+  { return "_start"; }
+
+  /// sizeNamePools - compute the size of regular name pools
+  /// In ELF executable files, regular name pools are .symtab, .strtab.,
+  /// .dynsym, .dynstr, and .hash
+  virtual void sizeNamePools(const Output& pOutput,
+                             const SymbolCategory& pSymbols,
+                             const MCLDInfo& pLDInfo);
+
+  /// emitSectionData - emit target-dependent section data
+  virtual uint64_t emitSectionData(const Output& pOutput,
+                                   const LDSection& pSection,
+                                   const MCLDInfo& pInfo,
+                                   MemoryRegion& pRegion) const = 0;
+
+  /// emitRegNamePools - emit regular name pools - .symtab, .strtab
+  virtual void emitRegNamePools(Output& pOutput,
+                                SymbolCategory& pSymbols,
+                                const Layout& pLayout,
+                                const MCLDInfo& pLDInfo);
+
+  /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
+  virtual void emitDynNamePools(Output& pOutput,
+                                SymbolCategory& pSymbols,
+                                const Layout& pLayout,
+                                const MCLDInfo& pLDInfo);
+
+  /// getSectionOrder - compute the layout order of the section
+  /// Layout calls this function to get the default order of the pSectHdr.
+  /// If the pSectHdr.type() is LDFileFormat::Target, then getSectionOrder()
+  /// will call getTargetSectionOrder().
+  ///
+  /// If targets favors certain order for general sections, please override
+  /// this function.
+  ///
+  /// @see getTargetSectionOrder
+  virtual unsigned int getSectionOrder(const Output& pOutput,
+                                       const LDSection& pSectHdr) const;
+
+  /// getTargetSectionOrder - compute the layout order of target section
+  /// If the target favors certain order for the given gSectHdr, please
+  /// override this function.
+  ///
+  /// By default, this function returns the maximun order, and pSectHdr
+  /// will be the last section to be laid out.
+  virtual unsigned int
+  getTargetSectionOrder(const Output& pOutput, const LDSection& pSectHdr) const
+  { return (unsigned int)-1; }
+
+  /// emitProgramHdrs - emit ELF program headers
+  /// if the target favors other ways to emit program header, please override
+  /// this function
+  virtual void emitProgramHdrs(Output& pOutput);
+
+  /// numOfSegments - return the number of segments
+  /// if the target favors other ways to emit program header, please override
+  /// this function
+  virtual unsigned int numOfSegments() const
+  { return m_ELFSegmentTable.size(); }
+
+  /// pagesize - the page size of the target machine, we set it to 4K here.
+  /// If target favors tht different size of page, please override this function
+  virtual unsigned int pagesize() const
+  { return 0x1000; }
+
+  /// getSymbolIdx - get the symbol index of ouput symbol table
+  size_t getSymbolIdx(LDSymbol* pSymbol) const;
+
+private:
+  /// createProgramHdrs - base on output sections to create the program headers
+  void createProgramHdrs(LDContext& pContext);
+
+  /// writeELF32ProgramHdrs - write out the ELF32 program headers
+  void writeELF32ProgramHdrs(Output& pOutput);
+
+  /// writeELF64ProgramHdrs - write out the ELF64 program headers
+  void writeELF64ProgramHdrs(Output& pOutput);
+
+  /// getSegmentFlag - give a section flag and return the corresponding segment
+  /// flag
+  inline uint32_t getSegmentFlag(const uint32_t pSectionFlag)
+  {
+    uint32_t flag = llvm::ELF::PF_R;
+    if (0 != (pSectionFlag & llvm::ELF::SHF_WRITE))
+      flag |= llvm::ELF::PF_W;
+    if (0 != (pSectionFlag & llvm::ELF::SHF_EXECINSTR))
+      flag |= llvm::ELF::PF_X;
+    return flag;
+  }
+
+  /// preLayout - Backend can do any needed modification before layout
+  void preLayout(const Output& pOutput,
+                 const MCLDInfo& pInfo,
+                 MCLinker& pLinker);
+
+  /// postLayout -Backend can do any needed modification after layout
+  void postLayout(const Output& pOutput,
+                 const MCLDInfo& pInfo,
+                 MCLinker& pLinker);
+
+protected:
+  uint64_t getSymbolSize(const LDSymbol& pSymbol) const;
+
+  uint64_t getSymbolInfo(const LDSymbol& pSymbol) const;
+
+  uint64_t getSymbolValue(const LDSymbol& pSymbol) const;
+
+  uint64_t getSymbolShndx(const LDSymbol& pSymbol, const Layout& pLayout) const;
+
+private:
+  /// preLayout - Backend can do any needed modification before layout
+  virtual void doPreLayout(const Output& pOutput,
+                         const MCLDInfo& pInfo,
+                         MCLinker& pLinker) = 0;
+
+  /// postLayout -Backend can do any needed modification after layout
+  virtual void doPostLayout(const Output& pOutput,
+                          const MCLDInfo& pInfo,
+                          MCLinker& pLinker) = 0;
+
+  /// dynamic - the dynamic section of the target machine.
+  virtual ELFDynamic& dynamic() = 0;
+
+  /// dynamic - the dynamic section of the target machine.
+  virtual const ELFDynamic& dynamic() const = 0;
+
+protected:
+  // ----- readers and writers ----- //
+  GNUArchiveReader* m_pArchiveReader;
+  ELFObjectReader* m_pObjectReader;
+  ELFDynObjReader* m_pDynObjReader;
+  ELFObjectWriter* m_pObjectWriter;
+  ELFDynObjWriter* m_pDynObjWriter;
+
+  // -----  file formats  ----- //
+  ELFDynObjFileFormat* m_pDynObjFileFormat;
+  ELFExecFileFormat* m_pExecFileFormat;
+
+  // -----  ELF segment factory  ----- //
+  ELFSegmentFactory m_ELFSegmentTable;
+
+  // -----  ELF special sections  ----- //
+
+protected:
+  /// getHashBucketCount - calculate hash bucket count.
+  /// @ref Google gold linker, dynobj.cc:791
+  static unsigned getHashBucketCount(unsigned pNumOfSymbols, bool pIsGNUStyle);
+
+  /// isDynamicSymbol
+  /// @ref Google gold linker: symtab.cc:311
+  static bool isDynamicSymbol(const LDSymbol& pSymbol, const Output& pOutput);
+
+protected:
+  typedef HashEntry<LDSymbol*, size_t, SymCompare> HashEntryType;
+  typedef HashTable<HashEntryType, PtrHash, EntryFactory<HashEntryType> > HashTableType;
+
+  /// m_pSymIndexMap - Map the LDSymbol to its index in the output symbol table
+  HashTableType* m_pSymIndexMap;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Target/GOT.h b/include/mcld/Target/GOT.h
new file mode 100644
index 0000000..eb0873a
--- /dev/null
+++ b/include/mcld/Target/GOT.h
@@ -0,0 +1,106 @@
+//===- GOT.h --------------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_GOT_H
+#define MCLD_GOT_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/LD/LDSection.h>
+#include <mcld/MC/MCTargetFragment.h>
+
+namespace mcld
+{
+
+class GOT;
+class ResolveInfo;
+
+/** \class GOTEntry
+ *  \brief The entry of Global Offset Table
+ */
+class GOTEntry : public MCTargetFragment
+{
+public:
+  explicit GOTEntry(uint64_t pContent, size_t pEntrySize,
+                    llvm::MCSectionData* pParent);
+
+  virtual ~GOTEntry();
+
+  uint64_t& getContent()
+  { return f_Content; }
+
+  uint64_t getContent() const
+  { return f_Content; }
+
+  void setContent(uint64_t pValue)
+  { f_Content = pValue; }
+
+  static bool classof(const MCFragment *pFrag)
+  { return pFrag->getKind() == llvm::MCFragment::FT_Target; }
+
+  static bool classof(const GOTEntry* pFrag)
+  { return true; }
+
+  // Override pure virtual function
+  size_t getSize() const
+  { return m_EntrySize; }
+
+protected:
+  uint64_t f_Content;
+  size_t m_EntrySize;
+};
+
+/** \class GOT
+ *  \brief The Global Offset Table
+ */
+class GOT
+{
+protected:
+  GOT(LDSection& pSection,
+      llvm::MCSectionData& pSectionData,
+      size_t pEntrySize);
+
+public:
+  virtual ~GOT();
+
+  /// entrySize - the number of bytes per entry
+  size_t getEntrySize() const;
+
+  const LDSection& getSection() const
+  { return m_Section; }
+
+  llvm::MCSectionData& getSectionData()
+  { return m_SectionData; }
+
+  const llvm::MCSectionData& getSectionData() const
+  { return m_SectionData; }
+
+public:
+  /// reserveEntry - reseve number of pNum of empty entries
+  /// Before layout, we scan all relocations to determine if GOT entries are
+  /// needed. If an entry is needed, the empty entry is reserved for layout
+  /// to adjust the fragment offset. After that, we fill up the entries when
+  /// applying relocations.
+  virtual void reserveEntry(size_t pNum = 1) = 0;
+
+  /// getEntry - get an empty entry or an exitsted filled entry with pSymbol.
+  /// @param pSymbol - the target symbol
+  /// @param pExist - ture if a filled entry with pSymbol existed, otherwise false.
+  virtual GOTEntry* getEntry(const ResolveInfo& pSymbol, bool& pExist) = 0;
+
+protected:
+  LDSection& m_Section;
+  llvm::MCSectionData& m_SectionData;
+  size_t f_EntrySize;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Target/OutputRelocSection.h b/include/mcld/Target/OutputRelocSection.h
new file mode 100644
index 0000000..c0cb5ca
--- /dev/null
+++ b/include/mcld/Target/OutputRelocSection.h
@@ -0,0 +1,71 @@
+//===- OutputRelocSection.h --------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef OUTPUTRELOCSECTION_H
+#define OUTPUTRELOCSECTION_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <llvm/MC/MCAssembler.h>
+#include <llvm/ADT/DenseMap.h>
+#include <mcld/LD/RelocationFactory.h>
+
+namespace mcld
+{
+
+class ResolveInfo;
+class Relocation;
+
+/** \class OutputRelocSection
+ *  \brief Dynamic relocation section for ARM .rel.dyn and .rel.plt
+ */
+class OutputRelocSection
+{
+public:
+  typedef llvm::DenseMap<const ResolveInfo*, Relocation*> SymRelMapType;
+  typedef SymRelMapType::iterator SymRelMapIterator;
+
+  typedef llvm::MCSectionData::iterator MCFragmentIterator;
+
+public:
+  OutputRelocSection(LDSection& pSection,
+                   llvm::MCSectionData& pSectionData,
+                   unsigned int pEntrySize);
+  ~OutputRelocSection();
+
+  void reserveEntry(RelocationFactory& pRelFactory, size_t pNum=1);
+
+  Relocation* getEntry(const ResolveInfo& pSymbol,
+                       bool isForGOT,
+                       bool& pExist);
+
+private:
+  /// m_pSection - LDSection of this Section
+  LDSection* m_pSection;
+
+  /// m_SectionData - MCSectionData which contains the dynamic relocations
+  llvm::MCSectionData* m_pSectionData;
+
+  /// m_EntryBytes - size of a relocation entry
+  unsigned int m_EntryBytes;
+
+  /// m_isVisit - First time visit the function getEntry() or not
+  bool m_isVisit ;
+
+  /// m_ValidEntryIterator - point to the first valid entry
+  MCFragmentIterator m_ValidEntryIterator;
+
+  /// m_SymRelMap - map the resolved symbol to the Relocation entry
+  SymRelMapType m_SymRelMap;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Target/PLT.h b/include/mcld/Target/PLT.h
new file mode 100644
index 0000000..6a7522a
--- /dev/null
+++ b/include/mcld/Target/PLT.h
@@ -0,0 +1,86 @@
+//===- PLT.h --------------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef PROCEDURE_LINKAGE_TABLE_H
+#define PROCEDURE_LINKAGE_TABLE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/LD/LDSection.h>
+#include <mcld/MC/MCTargetFragment.h>
+#include <llvm/ADT/ilist.h>
+
+namespace mcld
+{
+
+class ResolveInfo;
+
+/** \class PLTEntry
+ */
+class PLTEntry : public MCTargetFragment
+{
+public:
+  PLTEntry(size_t pSize, llvm::MCSectionData* pParent);
+  virtual ~PLTEntry();
+
+  size_t getEntrySize() const
+  { return m_EntrySize; }
+
+  void setContent(unsigned char* pContent)
+  { m_pContent = pContent; }
+
+  const unsigned char* getContent() const
+  { return m_pContent; }
+
+  //Used by llvm::cast<>.
+  static bool classof(const MCFragment *O)
+  { return true; }
+
+  size_t getSize() const
+  { return m_EntrySize; }
+
+protected:
+  size_t m_EntrySize;
+  unsigned char* m_pContent;
+};
+
+/** \class PLT
+ *  \brief Procedure linkage table
+ */
+class PLT
+{
+public:
+  PLT(LDSection& pSection, llvm::MCSectionData& pSectionData);
+  virtual ~PLT();
+
+  const LDSection& getSection() const
+  { return m_Section; }
+
+  const llvm::MCSectionData& getSectionData() const
+  { return m_SectionData; }
+
+public:
+  /// reserveEntry - reseve the number of pNum of empty entries
+  /// The empty entris are reserved for layout to adjust the fragment offset.
+  virtual void reserveEntry(size_t pNum = 1) = 0;
+
+  /// getPLTEntry - get an empty entry or an exitsted filled entry with pSymbol.
+  /// @param pSymbol - the target symbol
+  /// @param pExist - ture if the a filled entry with pSymbol existed, otherwise false.
+  virtual PLTEntry* getPLTEntry(const ResolveInfo& pSymbol, bool& pExist) = 0;
+
+protected:
+  LDSection& m_Section;
+  llvm::MCSectionData& m_SectionData;
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Target/Stub.h b/include/mcld/Target/Stub.h
new file mode 100644
index 0000000..3bc778f
--- /dev/null
+++ b/include/mcld/Target/Stub.h
@@ -0,0 +1,30 @@
+//===- Stub.h -------------------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LD_STUB_H
+#define LD_STUB_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include "mcld/LD/Relocation.h"
+
+namespace mcld
+{
+
+/** \class Stub
+ *  \brief Stub is a piece of jumpping code.
+ */
+class Stub
+{
+
+};
+
+} // namespace of mcld
+
+#endif
+
diff --git a/include/mcld/Target/TargetLDBackend.h b/include/mcld/Target/TargetLDBackend.h
new file mode 100644
index 0000000..781b86f
--- /dev/null
+++ b/include/mcld/Target/TargetLDBackend.h
@@ -0,0 +1,146 @@
+//===-- llvm/Target/TargetLDBackend.h - Target LD Backend -----*- C++ -*-===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_TARGET_TARGETLDBACKEND_H
+#define LLVM_TARGET_TARGETLDBACKEND_H
+
+#include <llvm/Support/DataTypes.h>
+#include <mcld/MC/MCLDOutput.h>
+
+namespace mcld {
+
+class MCLinker;
+class Relocation;
+class RelocationFactory;
+class Layout;
+class ArchiveReader;
+class ObjectReader;
+class DynObjReader;
+class ObjectWriter;
+class DynObjWriter;
+class LDContext;
+class SectionMap;
+class Output;
+class MCLDInfo;
+class SymbolCategory;
+class Input;
+class LDFileFormat;
+class GOT;
+
+//===----------------------------------------------------------------------===//
+/// TargetLDBackend - Generic interface to target specific assembler backends.
+///
+class TargetLDBackend
+{
+  TargetLDBackend(const TargetLDBackend &);   // DO NOT IMPLEMENT
+  void operator=(const TargetLDBackend &);  // DO NOT IMPLEMENT
+
+protected:
+  TargetLDBackend();
+
+public:
+  virtual ~TargetLDBackend();
+
+  // -----  target dependent  ----- //
+  virtual bool initTargetSectionMap(SectionMap& pSectionMap) { return true;}
+  virtual void initTargetSegments(MCLinker& pLinker) { }
+  virtual void initTargetSections(MCLinker& pLinker) { }
+  virtual void initTargetSymbols(MCLinker& pLinker) { }
+  virtual void initTargetRelocation(MCLinker& pLinker) { }
+  virtual bool initStandardSymbols(MCLinker& pLinker) = 0;
+  virtual bool initRelocFactory(const MCLinker& pLinker) = 0;
+
+  virtual RelocationFactory* getRelocFactory() = 0;
+
+  /// scanRelocation - When read in relocations, backend can do any modification
+  /// to relocation and generate empty entries, such as GOT, dynamic relocation
+  /// entries and other target dependent entries. These entries are generated
+  /// for layout to adjust the ouput offset.
+  /// @param pReloc - a read in relocation entry
+  /// @param pInputSym - the input LDSymbol of relocation target symbol
+  /// @param pOutput - the ouput file
+  virtual void scanRelocation(Relocation& pReloc,
+                              const LDSymbol& pInputSym,
+                              MCLinker& pLinker,
+                              const MCLDInfo& pLDInfo,
+                              const Output& pOutput) = 0;
+
+  // -----  format dependent  ----- //
+  virtual bool initArchiveReader(MCLinker&, MCLDInfo&) = 0;
+  virtual bool initObjectReader(MCLinker&) = 0;
+  virtual bool initDynObjReader(MCLinker&) = 0;
+  virtual bool initObjectWriter(MCLinker&) = 0;
+  virtual bool initDynObjWriter(MCLinker&) = 0;
+
+  virtual bool initExecSections(MCLinker&) = 0;
+  virtual bool initDynObjSections(MCLinker&) = 0;
+
+  virtual ArchiveReader *getArchiveReader() = 0;
+  virtual ObjectReader *getObjectReader() = 0;
+  virtual DynObjReader *getDynObjReader() = 0;
+  virtual ObjectWriter *getObjectWriter() = 0;
+  virtual DynObjWriter *getDynObjWriter() = 0;
+
+  virtual LDFileFormat* getDynObjFileFormat() = 0;
+  virtual LDFileFormat* getExecFileFormat() = 0;
+
+  /// preLayout - Backend can do any needed modification before layout
+  virtual void preLayout(const Output& pOutput,
+                         const MCLDInfo& pInfo,
+                         MCLinker& pLinker) = 0;
+
+  /// postLayout -Backend can do any needed modification after layout
+  virtual void postLayout(const Output& pOutput,
+                          const MCLDInfo& pInfo,
+                          MCLinker& pLinker) = 0;
+
+  /// Is the target machine little endian? **/
+  virtual bool isLittleEndian() const = 0;
+
+  /// bit class. the bit length of the target machine, 32 or 64 **/
+  virtual unsigned int bitclass() const = 0;
+
+  /// the page size of the target machine
+  virtual unsigned int pagesize() const = 0;
+
+  /// section start offset in the output file
+  virtual size_t sectionStartOffset() const = 0;
+
+  /// computeSectionOrder - compute the layout order of the given section
+  virtual unsigned int getSectionOrder(const Output& pOutput,
+                                       const LDSection& pSectHdr) const = 0;
+
+  /// sizeNamePools - compute the size of regular name pools
+  /// In ELF executable files, regular name pools are .symtab, .strtab.,
+  /// .dynsym, .dynstr, and .hash
+  virtual void
+  sizeNamePools(const Output& pOutput,
+                const SymbolCategory& pSymbols,
+                const MCLDInfo& pLDInfo) = 0;
+
+  /// finalizeSymbol - Linker checks pSymbol.reserved() if it's not zero,
+  /// then it will ask backend to finalize the symbol value.
+  /// @return ture - if backend set the symbol value sucessfully
+  /// @return false - if backend do not recognize the symbol
+  virtual bool finalizeSymbol(LDSymbol& pSymbol) const = 0;
+
+  /// allocateCommonSymbols - allocate common symbols in the corresponding
+  /// sections.
+  virtual bool allocateCommonSymbols(const MCLDInfo& pLDInfo, MCLinker& pLinker) const = 0;
+
+  /// readSection - read a target dependent section
+  virtual bool readSection(Input& pInput,
+                           MCLinker& pLinker,
+                           LDSection& pInputSectHdr)
+  { return true; }
+
+};
+
+} // End mcld namespace
+
+#endif
diff --git a/include/mcld/Target/TargetMachine.h b/include/mcld/Target/TargetMachine.h
new file mode 100644
index 0000000..438edfd
--- /dev/null
+++ b/include/mcld/Target/TargetMachine.h
@@ -0,0 +1,127 @@
+//===- TargetMachine.h ----------------------------------------------------===//
+//
+//                     The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_TARGET_MACHINE_H
+#define MCLD_TARGET_MACHINE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+#include <llvm/Target/TargetMachine.h>
+#include <string>
+#include "mcld/MC/MCLDFile.h"
+
+namespace llvm
+{
+class Target;
+class TargetData;
+class TargetMachine;
+class PassManagerBase;
+class formatted_raw_ostream;
+
+} // namespace of llvm
+
+namespace mcld
+{
+
+class Target;
+class MCLDInfo;
+class SectLinkerOption;
+using namespace llvm;
+
+enum CodeGenFileType {
+  CGFT_ASMFile,
+  CGFT_OBJFile,
+  CGFT_ARCFile,
+  CGFT_DSOFile,
+  CGFT_EXEFile,
+  CGFT_NULLFile
+};
+
+
+/** \class mcld::LLVMTargetMachine
+ *  \brief mcld::LLVMTargetMachine is a object adapter of
+ *  llvm::LLVMTargetMachine.
+ *
+ *  mcld::LLVMTargetMachine is also in charge of MCLDInfo.
+ *
+ *  @see MCLDInfo
+ */
+class LLVMTargetMachine
+{
+public:
+  /// Adapter of llvm::TargetMachine
+  ///
+  LLVMTargetMachine(llvm::TargetMachine &pTM,
+                    const mcld::Target &pTarget,
+                    const std::string &pTriple);
+  virtual ~LLVMTargetMachine();
+
+  /// getTarget - adapt llvm::TargetMachine::getTarget
+  const mcld::Target& getTarget() const;
+
+  /// getTM - return adapted the llvm::TargetMachine.
+  const llvm::TargetMachine& getTM() const { return m_TM; }
+  llvm::TargetMachine& getTM() { return m_TM; }
+
+  /// getLDInfo - return the mcld::MCLDInfo
+  virtual mcld::MCLDInfo& getLDInfo() = 0;
+  virtual const mcld::MCLDInfo& getLDInfo() const = 0;
+
+  /// appPassesToEmitFile - The target function which we has to modify as
+  /// upstreaming.
+  bool addPassesToEmitFile(PassManagerBase &,
+                           formatted_raw_ostream &Out,
+                           const std::string &pOutputFilename,
+                           mcld::CodeGenFileType,
+                           CodeGenOpt::Level,
+                           SectLinkerOption *pLinkerOpt = NULL,
+                           bool DisableVerify = true);
+
+  /// getTargetData
+  const TargetData *getTargetData() const { return m_TM.getTargetData(); }
+
+  /// setAsmVerbosityDefault
+  static void setAsmVerbosityDefault(bool pAsmVerbose) {
+    llvm::TargetMachine::setAsmVerbosityDefault(pAsmVerbose);
+  }
+
+private:
+  /// addCommonCodeGenPasses - Add standard LLVM codegen passes used for
+  /// both emitting to assembly files or machine code output.
+  bool addCommonCodeGenPasses(PassManagerBase &,
+                              mcld::CodeGenFileType,
+                              CodeGenOpt::Level,
+                              bool DisableVerify,
+                              llvm::MCContext *&OutCtx);
+
+  bool addCompilerPasses(PassManagerBase &,
+                         formatted_raw_ostream &Out,
+                         const std::string& pOutputFilename,
+                         llvm::MCContext *&OutCtx);
+
+  bool addAssemblerPasses(PassManagerBase &,
+                          formatted_raw_ostream &Out,
+                          const std::string& pOutputFilename,
+                          llvm::MCContext *&OutCtx);
+
+  bool addLinkerPasses(PassManagerBase &,
+                       SectLinkerOption *pLinkerOpt,
+                       const std::string& pOutputFilename,
+                       MCLDFile::Type pOutputLinkType,
+                       llvm::MCContext *&OutCtx);
+
+private:
+  llvm::TargetMachine &m_TM;
+  const mcld::Target *m_pTarget;
+  const std::string& m_Triple;
+};
+
+} // namespace of mcld
+
+#endif
+